Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete references using custom relation types #13389

Conversation

bjarnef
Copy link
Contributor

@bjarnef bjarnef commented Nov 13, 2022

Prerequisites

  • I have added steps to test this contribution in the description below

If there's an existing issue for this PR then this fixes #13364

Description

When implementing GetReferences() method in a property editor using UmbracoEntityReference this didn't work for custom relation types, where it tries to insert records which already exists and doesn't remove any previous saved relations after removing items from picker.

An example with a custom property editor using contentpicker property editor and myCustomRelation:

using Umbraco.Cms.Core;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Editors;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Strings;

namespace Umbraco.Cms.Web.UI.Editors;

[DataEditor(
    name: "Product Picker",
    alias: "productPicker",
    view: "contentpicker",
    Icon = "icon-tag",
    ValueType = ValueTypes.Text,
    Group = Umbraco.Cms.Core.Constants.PropertyEditors.Groups.Pickers)]
public class ProductPickerPropertyEditor : DataEditor
{
    private readonly IEditorConfigurationParser _editorConfigurationParser;
    private readonly IIOHelper _ioHelper;
    private readonly IJsonSerializer _jsonSerializer;

    public ProductPickerPropertyEditor(
        IDataValueEditorFactory dataValueEditorFactory,
        IIOHelper ioHelper,
        IJsonSerializer jsonSerializer,
        IEditorConfigurationParser editorConfigurationParser,
        EditorType type = EditorType.PropertyValue)
        : base(dataValueEditorFactory, type)
    {
        _ioHelper = ioHelper;
        _jsonSerializer = jsonSerializer;
        _editorConfigurationParser = editorConfigurationParser;
        SupportsReadOnly = true;
    }

    /// <inheritdoc />
    protected override IConfigurationEditor CreateConfigurationEditor() =>
        new MultiNodePickerConfigurationEditor(_ioHelper, _editorConfigurationParser);

    /// <inheritdoc />
    //protected override IDataValueEditor CreateValueEditor() =>
    //    DataValueEditorFactory.Create<MultipleValueEditor>(Attribute!);

    protected override IDataValueEditor CreateValueEditor() =>
        DataValueEditorFactory.Create<ProductPickerPropertyValueEditor>(Attribute!);

    public class ProductPickerPropertyValueEditor : DataValueEditor, IDataValueReferenceFactory, IDataValueReference
    {
        public ProductPickerPropertyValueEditor(
            ILocalizedTextService localizedTextService,
            IShortStringHelper shortStringHelper,
            IJsonSerializer jsonSerializer,
            IIOHelper ioHelper,
            DataEditorAttribute attribute)
            : base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute)
        {

        }

        public IDataValueReference GetDataValueReference() => this;

        public bool IsForEditor(IDataEditor? dataEditor) => dataEditor?.Alias == "productPicker";

        public IEnumerable<UmbracoEntityReference> GetReferences(object? value)
        {
            var asString = value == null ? string.Empty : value is string str ? str : value.ToString();

            if (string.IsNullOrEmpty(asString))
            {
                yield break;
            }

            var udiPaths = asString!.Split(',');

            foreach (var udiPath in udiPaths)
            {
                if (UdiParser.TryParse(udiPath, out Udi? udi))
                {
                    yield return new UmbracoEntityReference(udi, "myCustomRelation");
                }
            }
        }
    }
}
chrome_Niz0VkXzZK.mp4

After including changes in this PR it both get tracked references of type umbDocument, umbMedia and myCustomRelation which are deleted before inserting new/updated relations.

chrome_uvrCl9GxvW.mp4

Maybe the AutomaticRelationTypes constant should be marked as obsolete as it isn't used now? Not sure if it makes sense to have this when developers can implement references of own relation types, so it most likely would need to handle more than these two when it is possible to extend.

Maybe we also need to adjust RelationRepository.DeleteByParent(parentId, relationTypeAliases) with another method to delete for specific child ids e.g. RelationRepository.DeleteByParent(parentId, childIds, relationTypeAliases)

Currently it delete all relations by parent id and afterwards save the new relations, but it also seems to trigger Deliting and Deleted notifications for references which wasn't removed (just deleted and re-created).

var udiToGuids = trackedRelations.Select(x => x.Udi as GuidUdi)
      .ToDictionary(x => (Udi)x!, x => x!.Guid);

// lookup in the DB all INT ids for the GUIDs and chuck into a dictionary
var keyToIds = Database.Fetch<NodeIdKey>(Sql()
    .Select<NodeDto>(x => x.NodeId, x => x.UniqueId)
    .From<NodeDto>()
    .WhereIn<NodeDto>(x => x.UniqueId, udiToGuids.Values))
    .ToDictionary(x => x.UniqueId, x => x.NodeId);

Maybe we could do something like this, so it only delete relations which not exists in trackedRelations collection and saved afterwards again:

var keyToIds = Database.Fetch<NodeIdKey>(Sql()
    .Select<NodeDto>(x => x.NodeId, x => x.UniqueId)
    .From<NodeDto>()
    .WhereIn<NodeDto>(x => x.UniqueId, udiToGuids.Values))
    .ToDictionary(x => x.UniqueId, x => x.NodeId);

var childsToDelete = trackedRelations.Where(x => keyToIds.Any(y => y.Key == x.Udi.AsGuid()));

RelationRepository.DeleteByParent(entity.Id, childsToDelete, relationTypeAliases);

@bjarnef bjarnef changed the title Delete references custom relation types Delete references using custom relation types Nov 13, 2022
@bjarnef
Copy link
Contributor Author

bjarnef commented Nov 14, 2022

I also think Umbraco need to support more than relations for just umbDocument and umbMedia. Although Umbraco currently doesn't support relations to members in e.g. MNTP and Member Picker (and there is no umbMember relation type), it should be possible in custom property editors to create the relations using a custom relation type, but currently as originally mentioned it will cause the duplicate references.

I have target the PR for v11, but it would be great to fix in v10 as well, but other enhancements like relations to members in core pickers could be handed in v11, v12 etc.

Copy link
Contributor

@nikolajlauridsen nikolajlauridsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @bjarnef just had a look at this and it looks good to me, and tests out good as well.

It makes sense that we should delete the references from the _dataValueReferenceFactories, since these are really automatic relations types 👍 So great work, and thanks as always 🎉

I took the liberty of obsoleting the old constant like you mentioned 😉

In regards to the other enhancements like the member relations and stuff, I think maybe it makes sense to make this a separate feature request, or maybe or discussion or something 😄

@nikolajlauridsen nikolajlauridsen merged commit a500ef9 into umbraco:v11/contrib Nov 23, 2022
nikolajlauridsen pushed a commit that referenced this pull request Nov 23, 2022
@bjarnef bjarnef deleted the v11/bug/delete-references-custom-relation-types branch November 23, 2022 15:11
@bjarnef
Copy link
Contributor Author

bjarnef commented Nov 23, 2022

@nikolajlauridsen great, thanks 👍
However I also wonder if it actually should delete all relations first and re-create them afterwards since it seems to trigger the Deleting and Deleted relation notifications even though the items wasn't removed from an UI/UX point of view?

e.g. if I have item A, B and C and remove item B, it also notify about A and C in the Deleting and Deleted relation notifications.

@nikolajlauridsen
Copy link
Contributor

That's a good question, imo it kind of makes sense, from a system point of view, since the relations are in fact deleted, and then created again, so imo the notifications are telling the truth in this regard.

Of course if this becomes problematic for people maybe we should consider fixing this aspect.

@bjarnef
Copy link
Contributor Author

bjarnef commented Nov 23, 2022

Yeah, not sure if it makes sense to notify about all entities, eg. 10 items in Deleting / Deleted notifications. I think it is the same with Saving / Saved notifications in this context, so it is difficult to tell which was changed, new, deleted.

And yes the member relations would be great to make a discussion about this feature. Currently there is also node id on page level. However with Block List and Block Grid editor mayve there's a need to store a reference to the block guid as well. The relations haven't changed much during the years, but I wonder if guid would be better than the int ids in future.

@nikolajlauridsen
Copy link
Contributor

I just realised last night that I might have been a bit too fast to merge this, since there is an issue with this solution.

The problem is that we're relying on the tracked relations themselves to give us the relation type alias. This means that if you try to remove a relation entirely, it won't be deleted.

For instance, if you pick a node with the content picker, then save, and then later remove the picked node and hit save again.

The first time we'll have created a relation since it was added to the trackedRelations, however, the second time around it won't be deleted, since there will be no tracked relation to get the alias from.

Trying to think of how we can fix this, I think one solution would be to extend the IDataValueReference interface with a new method IEnumerable<string> GetReferenceTypeAliases() this way you can implement this to always return the aliases that we need to delete, regardless if anything is picked.

And I see your point with the deleting, however I don't think that the notifications themselves are the issue, the issue is that we're deleting everything to then create it again, however I also think that it has been this way for a long time, and it's really a separate issue to this in my opinion. But yes in general relations seems like they could use a bit of love 😄

@nikolajlauridsen
Copy link
Contributor

nikolajlauridsen commented Nov 24, 2022

And I've created a PR with the proposed changes #13470, will get someone from the core team to have a look at reviewing it 😄

@bjarnef
Copy link
Contributor Author

bjarnef commented Nov 24, 2022

@nikolajlauridsen okay, the second time when removing the item from the picker, doesn't the relation still exists, where it fetched the alias from the tracked references and afterwards delete the relation?

Yeah, the relations haven't changed much the last 10 years until the tracked references were implemented. Now with Umbraco Cloud, Deploy, Forms in database (similar to content nodes), etc. I think relations are more important than ever :) and it makes it much easier to developers to check if it is safe to delete different kind of nodes.

I think the next step could be tracking member references in pickers :)

@nikolajlauridsen
Copy link
Contributor

Testing it out this was not the case, but I messed up the terminology a bit, there will be no UmbracoEntityReference returned from the IDataValueReference, since the property value is now empty, so for example this will return an empty enumerable in the contentpicker:

var asString = value == null ? string.Empty : value is string str ? str : value.ToString();

if (string.IsNullOrEmpty(asString))
{
    yield break;
}

So it will not be present in the trackedRelations list, which is where you get the alias from, so the alias will be missing 😄

Zeegaan added a commit that referenced this pull request Dec 7, 2022
* Bump version

* Add PrivateAssets="all" to mangement api project reference (#13249)

* Bump version

* Use the actual save function for saving the copy (#13066)

* Use the actual save function for saving the copy

* PR feedback

(cherry picked from commit 3802097)

* Unbreak breaking change in #13066 (#13288)

(cherry picked from commit e4741b0)

* Bump version to 10.3.2

* Parse lockId as invariant (#13284)

Co-authored-by: Zeegaan <nge@umbraco.dk>
(cherry picked from commit 272e922)

* Allow for configuration of additional languages to install and ensure one is set as default. (#13290)

* Allow for configuration of additional languages to install and ensure one is set as default.

* Amended install default language method to handle invalid ISO codes and ensure the first specified language is always made the default.

* Removed unnecessary using.

* Apply suggestions from code review

Co-authored-by: Ronald Barendse <ronald@barend.se>

* Clean up.

* Update src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs

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

Co-authored-by: Ronald Barendse <ronald@barend.se>
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>

* Updated Smidge (#13331)

* Fix casing in fileSystemBasePath (#13306)

* Add guard statement (#13340)

* Move block grid single area rendering to its own dedicated view (#13359)

* Block Grid Editor Improvements (#13282)

* remove console log

* Updated references for Forms and Deploy in JSON schema project. (#13411)

* Enable single block mode (#13216)

* Enable single block mode

* Fixes tests, and adds test for single block mode output type

* Update src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs

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

* Update src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs

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

* Fix breaking change

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

* Block Grid Editor: Removal of the forced placement feature (#13400)

* removal of the forceLeft/forceRight code

* removal of forced placement in css

* bring back removed code

* V10: AllowedUploadFiles appsetting not working (#13408)

* Add new Settings

* Use new settings instead of old ones

* Implement AllowedUploadedFiles value to be copied to AllowedUplayedFileExtensions

* Obsolete old settings

* Rename DisallowedUploadFileExtensions

* Implement same fix for DisallowedUploadFiles

* Use new settings for backoffice server variables

* Update the correct setting

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

* Feature: Media Picker drag and drop upload directly on property editor (#13393)

* prototype drag and drop upload

* Add upload image endpoint

* Add MediaPickerThreeController.cs

* Revert "Add upload image endpoint"

This reverts commit 4bb5865.

* Update IIOHelper dependency

* show preview when uploading a new media item

* open uploaded media in media entry editor

* map data from uploaded media entry to support cropper

* add crop data to uploaded media item

* remove media library buttons for media entries not created in the media library

* Implement temp images save & add to media picker 3

* Implement ITemporaryImageService

* Remove save logic from MediaPicker3PropertyEditor

* Dont use a TempImageDto

* Add GetByAlias endpoint

* Add additonal xml doc

* Refactor to take array of aliases

* Add FromQuery attribute

* Formatting

* add resource to get media types by alias

* validate file size and file type based on server variables

* Update OpenApi.json
Add media picker three to BackOfficeServerVariables

* rename endpoint to upload media

* Use baseurl Method

* Dont upload in rte folder

* pass params correctly to end point

* queue files before uploading

* handle invalid files

* progress bar design adjustments

* only create data url for images

* disable edit and name buttons when uploading

* fix missing error messages for invalid files

* add temp location to media entry

* Add startNode to TemporaryImageService.cs

* Refactor get by alias

* Rename to GetAllFiltered

* use getAllFiltered method

* remove autoselect option

* fix missing alias when selecting media type

* fix file filter

* don't overwrite invalid entries from dropping new files

* add disallowed files to filter

* remove console.log

* move media uploader logic to reusable function

* fix missing tmp location

* attach media type alias to the mediaEntry

* support readonly mode

* show discard changes when files has been dropped

* add disabled prop to button group

* emit events when upload queue starts and ends

* pass node to media picker property editor

* add service to keep track of all uploads in progress

* add upload in progress to uploadTracker when the queue starts and ends

* disabled buttons when any upload is in progress

* return a subscription to align with eventsService

* Fix up cases where StartNodeId was null

* scope css

* Show filename in dialog for selecting media type

* reuse translation from media library dropzone

* Don't check for only images

* Remove composer

* Add mediaTypeAlias to TemporaryImageService

* Rename ITemporaryImageService to ITemporaryMediaService

* prefix client side only props with $ so we don't send unnecessary data to the server

* use prefixed dataURL in media entry editor

* render icon for non images

* fix auto select media type

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

* V10: merge v8 blobstorage file deletion fix (#13415)

* Implement fix from v8 #11998

* Clean-up

Co-authored-by: Elitsa Marinovska <elm@umbraco.dk>

* Bump socket.io-parser from 4.0.4 to 4.0.5 in /src/Umbraco.Web.UI.Client

Bumps [socket.io-parser](https://github.com/socketio/socket.io-parser) from 4.0.4 to 4.0.5.
- [Release notes](https://github.com/socketio/socket.io-parser/releases)
- [Changelog](https://github.com/socketio/socket.io-parser/blob/main/CHANGELOG.md)
- [Commits](socketio/socket.io-parser@4.0.4...4.0.5)

---
updated-dependencies:
- dependency-name: socket.io-parser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* update block grid panel name (#13325)

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>

* Bump async from 2.6.3 to 2.6.4 in /src/Umbraco.Web.UI.Client

Bumps [async](https://github.com/caolan/async) from 2.6.3 to 2.6.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](caolan/async@v2.6.3...v2.6.4)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump minimist from 1.2.5 to 1.2.7 in /src/Umbraco.Web.UI.Client

Bumps [minimist](https://github.com/minimistjs/minimist) from 1.2.5 to 1.2.7.
- [Release notes](https://github.com/minimistjs/minimist/releases)
- [Changelog](https://github.com/minimistjs/minimist/blob/main/CHANGELOG.md)
- [Commits](minimistjs/minimist@v1.2.5...v1.2.7)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump eventsource from 1.1.0 to 1.1.2 in /src/Umbraco.Web.UI.Client

Bumps [eventsource](https://github.com/EventSource/eventsource) from 1.1.0 to 1.1.2.
- [Release notes](https://github.com/EventSource/eventsource/releases)
- [Changelog](https://github.com/EventSource/eventsource/blob/master/HISTORY.md)
- [Commits](EventSource/eventsource@v1.1.0...v1.1.2)

---
updated-dependencies:
- dependency-name: eventsource
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* updated package-lock

* Bump minimatch from 3.0.4 to 3.1.2 in /src/Umbraco.Web.UI.Client

Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](isaacs/minimatch@v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* Block Grid Editor sorting directive (#13391)

* make sure area border is on top of block views.

* rename class to avoid confusion

* change witch UI goes on top on hover

* Description informing all blocks are allowed when none is configured.

* add 'When empty'

* Sort mode

* ability to switch out property actions

* enter and exit sortmode from property actions

* gridsortblock

* rename block class to use sortblock

* Sort mode styling

* remove unused css selector

* fixing style for inline-creat button to appear above and not when hovering contextbar

* work on block grid inline editor

* use uui-button + enable installing demo blocks when its not the first dataType of this kind.

* improvements to inline editing POC

* update title of area config overlay editor

* reset columnSpan if no column span options is defined.

* Inline editing

* remove html comment

* remove code for transfer of stylesheets

* ability to hide label from directive

* inline editing using slots to render the umb-property in light dom

* remove property editor proxies when moving a block to a new area/block/context

* minor adjustments to custom views

* use individual slots for each area.

* Inline editing

* a little smaller rte min-height

* fire Custom focus/blur event for Block Grid Editor to catch for focus imitation

* disable inline editing prevalue field when custom view is set

* Fix scroll parent block into view

* initial work on sorter directive

* remove mediaBlock controller

* initial notes and structure

* further concept work

* remove consol log

* CSS for getting bigger areas

* removal of the forceLeft/forceRight code

* proven concept

* fix grid space detection. vertical/horizontal

* clean up and notes

* move into inner containers as well

* use last available index pr default

* boundary selector, for improved choise of dropping into an area

* hide last inline create button when dragging around

* remove console.log

* removal of forced placement in css

* default config and clean up

* notes

* bring back removed code

* show area ui when in dragging mode

* more specific selector

* drop allowance + clean up

* notes and clean up

* auto scroll

* turn --umb-block-grid--dragging-mode into conditional CSS Custom Property

* auto scroll

* refactoring

* fix condition mistake

* scope.config.resolveVerticalDirection

* wrap up simple setDragImage solution

* bring back vm.notifyVisualUpdate and clean up

* make draggableSelector optional, fallback to element

* implement umb-block-grid-sorter for Area PreValue editor

* remove sortableJS dependency

* remove sortableJs from dependencies

* wups, bring back the comma

* removed sortablejs from package-lock

* finished implementation of sorter for PreValue Block Areas

* fix for FireFox shadowDom issue, contains temprorary code.

* stop auto scroll

* make full thing dragable

* fix firefox issue (applying translateZ)

* comment

* make block fit in context columns

* revert element to where it came from if sync could not succeed + clean up

* ensure block does not push the amount of columns, this occourse when dragging item around.

* take horizontalPlaceAfter into account

* implement horizontalPlaceAfter in Areas Prevalue editor

* clean up dependencies

* Shift related el to first in row or last in row when there is no horizontal room

* clean up and correct calculation

* remove unused attribute

* revert to using el.getBoundingClientRect(), as the config.draggableSelector is not available for the placeholder item.

* bind model via dedicated binding to ensure it stay connected with the source model

* Update src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-area-editor.html

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>

* fix eslint issues

* ensure missingColumnWidth is above 0

* Do not allow dragging something thats not found in the model.

* remove as this is not an error.

* update to Flexbox solution

* as the complex model does not change we can use single way binding

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>

* Block Grid Editor adjust while sorting (#13442)

* make sure area border is on top of block views.

* rename class to avoid confusion

* change witch UI goes on top on hover

* Description informing all blocks are allowed when none is configured.

* add 'When empty'

* Sort mode

* ability to switch out property actions

* enter and exit sortmode from property actions

* gridsortblock

* rename block class to use sortblock

* Sort mode styling

* remove unused css selector

* fixing style for inline-creat button to appear above and not when hovering contextbar

* work on block grid inline editor

* use uui-button + enable installing demo blocks when its not the first dataType of this kind.

* improvements to inline editing POC

* update title of area config overlay editor

* reset columnSpan if no column span options is defined.

* Inline editing

* remove html comment

* remove code for transfer of stylesheets

* ability to hide label from directive

* inline editing using slots to render the umb-property in light dom

* remove property editor proxies when moving a block to a new area/block/context

* minor adjustments to custom views

* use individual slots for each area.

* Inline editing

* a little smaller rte min-height

* fire Custom focus/blur event for Block Grid Editor to catch for focus imitation

* disable inline editing prevalue field when custom view is set

* Fix scroll parent block into view

* initial work on sorter directive

* remove mediaBlock controller

* initial notes and structure

* further concept work

* remove consol log

* CSS for getting bigger areas

* removal of the forceLeft/forceRight code

* proven concept

* fix grid space detection. vertical/horizontal

* clean up and notes

* move into inner containers as well

* use last available index pr default

* boundary selector, for improved choise of dropping into an area

* hide last inline create button when dragging around

* remove console.log

* removal of forced placement in css

* default config and clean up

* notes

* bring back removed code

* show area ui when in dragging mode

* more specific selector

* drop allowance + clean up

* notes and clean up

* auto scroll

* turn --umb-block-grid--dragging-mode into conditional CSS Custom Property

* auto scroll

* refactoring

* fix condition mistake

* scope.config.resolveVerticalDirection

* wrap up simple setDragImage solution

* bring back vm.notifyVisualUpdate and clean up

* make draggableSelector optional, fallback to element

* implement umb-block-grid-sorter for Area PreValue editor

* remove sortableJS dependency

* remove sortableJs from dependencies

* wups, bring back the comma

* removed sortablejs from package-lock

* finished implementation of sorter for PreValue Block Areas

* fix for FireFox shadowDom issue, contains temprorary code.

* stop auto scroll

* make full thing dragable

* fix firefox issue (applying translateZ)

* comment

* make block fit in context columns

* revert element to where it came from if sync could not succeed + clean up

* ensure block does not push the amount of columns, this occourse when dragging item around.

* take horizontalPlaceAfter into account

* implement horizontalPlaceAfter in Areas Prevalue editor

* clean up dependencies

* Shift related el to first in row or last in row when there is no horizontal room

* clean up and correct calculation

* remove unused attribute

* revert to using el.getBoundingClientRect(), as the config.draggableSelector is not available for the placeholder item.

* bind model via dedicated binding to ensure it stay connected with the source model

* Update src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-area-editor.html

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>

* fix eslint issues

* ensure missingColumnWidth is above 0

* Do not allow dragging something thats not found in the model.

* remove as this is not an error.

* update to Flexbox solution

* as the complex model does not change we can use single way binding

* Adjust columnSpan to context container, keep start columnSpan as the target for the calculation.

* change let to const

* Revert "change let to const"

This reverts commit fe19f8c.

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>

* Block Grid Editor - make prevalue overlay medium sized (#13443)

* make sure area border is on top of block views.

* rename class to avoid confusion

* change witch UI goes on top on hover

* Description informing all blocks are allowed when none is configured.

* add 'When empty'

* Sort mode

* ability to switch out property actions

* enter and exit sortmode from property actions

* gridsortblock

* rename block class to use sortblock

* Sort mode styling

* remove unused css selector

* fixing style for inline-creat button to appear above and not when hovering contextbar

* work on block grid inline editor

* use uui-button + enable installing demo blocks when its not the first dataType of this kind.

* improvements to inline editing POC

* update title of area config overlay editor

* reset columnSpan if no column span options is defined.

* Inline editing

* remove html comment

* remove code for transfer of stylesheets

* ability to hide label from directive

* inline editing using slots to render the umb-property in light dom

* remove property editor proxies when moving a block to a new area/block/context

* minor adjustments to custom views

* use individual slots for each area.

* Inline editing

* a little smaller rte min-height

* fire Custom focus/blur event for Block Grid Editor to catch for focus imitation

* disable inline editing prevalue field when custom view is set

* Fix scroll parent block into view

* initial work on sorter directive

* remove mediaBlock controller

* initial notes and structure

* further concept work

* remove consol log

* CSS for getting bigger areas

* removal of the forceLeft/forceRight code

* proven concept

* fix grid space detection. vertical/horizontal

* clean up and notes

* move into inner containers as well

* use last available index pr default

* boundary selector, for improved choise of dropping into an area

* hide last inline create button when dragging around

* remove console.log

* removal of forced placement in css

* default config and clean up

* notes

* bring back removed code

* show area ui when in dragging mode

* more specific selector

* drop allowance + clean up

* notes and clean up

* auto scroll

* turn --umb-block-grid--dragging-mode into conditional CSS Custom Property

* auto scroll

* refactoring

* fix condition mistake

* scope.config.resolveVerticalDirection

* wrap up simple setDragImage solution

* bring back vm.notifyVisualUpdate and clean up

* make draggableSelector optional, fallback to element

* implement umb-block-grid-sorter for Area PreValue editor

* remove sortableJS dependency

* remove sortableJs from dependencies

* wups, bring back the comma

* removed sortablejs from package-lock

* finished implementation of sorter for PreValue Block Areas

* fix for FireFox shadowDom issue, contains temprorary code.

* stop auto scroll

* make full thing dragable

* fix firefox issue (applying translateZ)

* comment

* make block fit in context columns

* revert element to where it came from if sync could not succeed + clean up

* ensure block does not push the amount of columns, this occourse when dragging item around.

* take horizontalPlaceAfter into account

* implement horizontalPlaceAfter in Areas Prevalue editor

* clean up dependencies

* Shift related el to first in row or last in row when there is no horizontal room

* clean up and correct calculation

* remove unused attribute

* revert to using el.getBoundingClientRect(), as the config.draggableSelector is not available for the placeholder item.

* bind model via dedicated binding to ensure it stay connected with the source model

* Update src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-area-editor.html

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>

* fix eslint issues

* ensure missingColumnWidth is above 0

* Do not allow dragging something thats not found in the model.

* remove as this is not an error.

* update to Flexbox solution

* as the complex model does not change we can use single way binding

* Adjust columnSpan to context container, keep start columnSpan as the target for the calculation.

* make prevalue editor overlay medium size

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>

* block grid editor visual adjustments (#13446)

* make sure area border is on top of block views.

* rename class to avoid confusion

* change witch UI goes on top on hover

* Description informing all blocks are allowed when none is configured.

* add 'When empty'

* Sort mode

* ability to switch out property actions

* enter and exit sortmode from property actions

* gridsortblock

* rename block class to use sortblock

* Sort mode styling

* remove unused css selector

* fixing style for inline-creat button to appear above and not when hovering contextbar

* work on block grid inline editor

* use uui-button + enable installing demo blocks when its not the first dataType of this kind.

* improvements to inline editing POC

* update title of area config overlay editor

* reset columnSpan if no column span options is defined.

* Inline editing

* remove html comment

* remove code for transfer of stylesheets

* ability to hide label from directive

* inline editing using slots to render the umb-property in light dom

* remove property editor proxies when moving a block to a new area/block/context

* minor adjustments to custom views

* use individual slots for each area.

* Inline editing

* a little smaller rte min-height

* fire Custom focus/blur event for Block Grid Editor to catch for focus imitation

* disable inline editing prevalue field when custom view is set

* Fix scroll parent block into view

* initial work on sorter directive

* remove mediaBlock controller

* initial notes and structure

* further concept work

* remove consol log

* CSS for getting bigger areas

* removal of the forceLeft/forceRight code

* proven concept

* fix grid space detection. vertical/horizontal

* clean up and notes

* move into inner containers as well

* use last available index pr default

* boundary selector, for improved choise of dropping into an area

* hide last inline create button when dragging around

* remove console.log

* removal of forced placement in css

* default config and clean up

* notes

* bring back removed code

* show area ui when in dragging mode

* more specific selector

* drop allowance + clean up

* notes and clean up

* auto scroll

* turn --umb-block-grid--dragging-mode into conditional CSS Custom Property

* auto scroll

* refactoring

* fix condition mistake

* scope.config.resolveVerticalDirection

* wrap up simple setDragImage solution

* bring back vm.notifyVisualUpdate and clean up

* make draggableSelector optional, fallback to element

* implement umb-block-grid-sorter for Area PreValue editor

* remove sortableJS dependency

* remove sortableJs from dependencies

* wups, bring back the comma

* removed sortablejs from package-lock

* finished implementation of sorter for PreValue Block Areas

* fix for FireFox shadowDom issue, contains temprorary code.

* stop auto scroll

* make full thing dragable

* fix firefox issue (applying translateZ)

* comment

* make block fit in context columns

* revert element to where it came from if sync could not succeed + clean up

* ensure block does not push the amount of columns, this occourse when dragging item around.

* take horizontalPlaceAfter into account

* implement horizontalPlaceAfter in Areas Prevalue editor

* clean up dependencies

* Shift related el to first in row or last in row when there is no horizontal room

* clean up and correct calculation

* remove unused attribute

* revert to using el.getBoundingClientRect(), as the config.draggableSelector is not available for the placeholder item.

* bind model via dedicated binding to ensure it stay connected with the source model

* Update src/Umbraco.Web.UI.Client/src/views/propertyeditors/blockgrid/prevalue/umb-block-grid-area-editor.html

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>

* fix eslint issues

* ensure missingColumnWidth is above 0

* Do not allow dragging something thats not found in the model.

* remove as this is not an error.

* update to Flexbox solution

* as the complex model does not change we can use single way binding

* Adjust columnSpan to context container, keep start columnSpan as the target for the calculation.

* make prevalue editor overlay medium size

* more white borders on UI

* move Catalogue appearance to Advanced

Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>

* Display media trashed state on custom view for image demo block (#13448)

* Block Grid Editor translations and Area size keyboard navigation (#13450)

* use custom prop for calculated width (#13451)

* Bump engine.io and socket.io in /src/Umbraco.Web.UI.Client

Bumps [engine.io](https://github.com/socketio/engine.io) and [socket.io](https://github.com/socketio/socket.io). These dependencies needed to be updated together.

Updates `engine.io` from 6.1.3 to 6.2.1
- [Release notes](https://github.com/socketio/engine.io/releases)
- [Changelog](https://github.com/socketio/engine.io/blob/main/CHANGELOG.md)
- [Commits](socketio/engine.io@6.1.3...6.2.1)

Updates `socket.io` from 4.4.1 to 4.5.3
- [Release notes](https://github.com/socketio/socket.io/releases)
- [Changelog](https://github.com/socketio/socket.io/blob/main/CHANGELOG.md)
- [Commits](socketio/socket.io@4.4.1...4.5.3)

---
updated-dependencies:
- dependency-name: engine.io
  dependency-type: indirect
- dependency-name: socket.io
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* Cherry pick #13373 to v10/dev

* remove the hidding of catelouge appearance as its not located under advance (#13456)

* Fix preview issue for new (empty) variants (#13455)

* Fix save and preview for new (unsaved) variants

* Rework & simplify

* Rollback improvements (#13452)

* Rollback improvements - hide draft version, allow rolling back to last published version

* UX improvements to rollback, revert some overly complex logic in favor of better UX

* Ensure title update when changing rollback version

* Clean up

* Fix rollback playwright text

* Cherry pick #13404 to v10

* Delete references using custom relation types (#13389)

undefined

* V11: Fix ordering by published in list of content (#13474)

* Update sort statement to use published field for invariant content

* Order by published if invariant

* Add support for tags in block editors and nested content (#13412)

* feat: add tags extension points and remove hardcoded tags handling

* feat: allow tags editor in nested content and block editors

* Update src/Umbraco.Infrastructure/PropertyEditors/TagsPropertyEditor.cs

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

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

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

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

* Ensure that all automatic relation types are updated (#13470)

* Make sure contexbar fits within the available space (#13467)

* Make sure contexbar fits within the available space

* Ensuring context bar moves above, no matter size of it.

* Fixing apperance of connection-fixers

* do not set layout gaps (#13496)

* V10/feature/fixing flaky acceptance test (#13473)

* Updated Forms dependency for JSON schema to the latest version. (#13505)

* Accessibility - Fix Packages - Modal - Empty buttons (#13114)

* Changing the way we create the temp file for SQLite file (#13439)

* Fix concurrency issue in UmbracoMapper (#13524)

* Add logging to UmbracoMapper

* Add NullLogger to tests

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

* Allow indexing variant nodes when not all variants are published - fixes issues 11383. (#12669)

* This fixes issues 11383.
The introduction of the new Examine library caused an unintended consequence that it stopped indexing of nodes with language variants on them when one of the variants was unpublished.

These changes align ValueSetValidationStatus.Filtered to indicate that a node is intended as filtered out of a search, not that parts of its contents had been excluded from the result.

This brings it inline with how it is used in Umbraco.Examine.Lucene/UmbracoContentIndex

Unit tests changed to indicate the intent of ValueSetValidationStatus.Filtered

Change to UmbracoViewPage to make model variable nullable (because the solution wouldn't build otherwise on 2022)

* revert to use explicit type instead of var

Co-authored-by: Nathan Woulfe <nathan@nathanw.com.au>
Co-authored-by: Bjarke Berg <mail@bergmania.dk>

* V11/feature/flaky test work (#13513) (#13527)

* Removed all the DeleteAllContent since I delete the doctypes in the before and after each functions which also deletes the content.

* fixed the test so it selects the specific button!

* I was dumb and forgot to remove the out commented code

* Added additional timeout so the pipeline has more time

* Removed language in settings because it was a duplicate of languages / languages

* Fixed the tests so they now check if each individual language that was created actually exists instead of checking for how many languages there are which could be flaky if another test touching the languages failed

* Bumped version

* Added a better locator for the buttons and increased timeouts

Signed-off-by: Zeegaan <nge@umbraco.dk>

Signed-off-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>

* Fix for issue 13017 - BeginUmbracoForm doesn't work with custom umbraco routes (#13103)

* Fix issue with custom Umbraco routes not working after submitting to a Surface controller

* Added comments

* Fixed breaking changes

* Fixed test by using correct new ctor

* Fixed initializtion of UmbracoRouteValueTransformer due to ambiguous ctor

Co-authored-by: Bjarke Berg <mail@bergmania.dk>

* Rollback project imports

* Remove duplicated lines in translations

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch>
Co-authored-by: patrickdemooij9 <patrickdemooij98@hotmail.com>
Co-authored-by: Sebastiaan Janssen <sebastiaan@umbraco.com>
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
Co-authored-by: Andy Butland <abutland73@gmail.com>
Co-authored-by: Ronald Barendse <ronald@barend.se>
Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>
Co-authored-by: Niels Lyngsø <nsl@umbraco.dk>
Co-authored-by: Niels Lyngsø <niels.lyngso@gmail.com>
Co-authored-by: Søren Kottal <sk@ecreo.dk>
Co-authored-by: Zeegaan <nge@umbraco.dk>
Co-authored-by: Mads Rasmussen <madsr@hey.com>
Co-authored-by: Elitsa Marinovska <elm@umbraco.dk>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Blake Watt <bkclerke@users.noreply.github.com>
Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com>
Co-authored-by: niekvanderreest <niekvanderreest@hotmail.com>
Co-authored-by: Bjarne Fyrstenborg <bjarne_fyrstenborg@hotmail.com>
Co-authored-by: Rasmus John Pedersen <mail@rjp.dk>
Co-authored-by: Andreas Zerbst <73799582+andr317c@users.noreply.github.com>
Co-authored-by: Jan Skovgaard <1932158+BatJan@users.noreply.github.com>
Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com>
Co-authored-by: Jonny Muir <jonnymoo@hotmail.com>
Co-authored-by: Nathan Woulfe <nathan@nathanw.com.au>
Co-authored-by: Justin Neville <67802060+justin-nevitech@users.noreply.github.com>
@bjarnef
Copy link
Contributor Author

bjarnef commented Jan 18, 2023

@nikolajlauridsen I have upgraded our project to Umbraco v10.4.0, but I still get this error without this notification handler.

public class CourseCategorySavingNotificationHandler : INotificationHandler<ContentSavingNotification>
{
    private readonly IRelationService _relationService;

    public CourseCategorySavingNotificationHandler(
        IRelationService relationService)
    {
        _relationService = relationService;
    }

    public void Handle(ContentSavingNotification notification)
    {
        var relationType = _relationService.GetRelationTypeByAlias(Constants.RelationTypes.RelatedCourseAlias);
        if (relationType == null)
            return;

        foreach (var node in notification.SavedEntities)
        {
            if (node.ContentType.Alias.Equals(Course.ModelTypeAlias) || node.ContentType.Alias.Equals(Category.ModelTypeAlias))
            {
                // Umbraco currently doesn't remove relations using custom relation type, when using UmbracoEntityReference in property editor,
                // so we need to remove these before saved.

                var relations = _relationService.GetByParentId(node.Id, Constants.RelationTypes.RelatedCourseAlias);

                if (relations != null)
                {
                    foreach (var relation in relations)
                    {
                        _relationService.Delete(relation);
                    }
                }
            }
        }
    }
}

image

The property editor is pretty identical with MNTP - only difference is that it use a custom relation type.

[DataEditor(
    name: "Category Relation Picker",
    alias: Constants.PropertyEditors.Aliases.CategoryRelationPicker,
    view: "~/App_Plugins/CategoryRelationPicker/views/categoryrelationpicker.html",
    Icon = "icon-mindmap",
    ValueType = ValueTypes.Text,
    Group = Umbraco.Cms.Core.Constants.PropertyEditors.Groups.Pickers)]
public class CategoryRelationPickerPropertyEditor : DataEditor
{
    private readonly IEditorConfigurationParser _editorConfigurationParser;
    private readonly IIOHelper _ioHelper;
    private readonly IJsonSerializer _jsonSerializer;

    public CategoryRelationPickerPropertyEditor(
        IDataValueEditorFactory dataValueEditorFactory,
        IIOHelper ioHelper,
        IJsonSerializer jsonSerializer,
        IEditorConfigurationParser editorConfigurationParser,
        EditorType type = EditorType.PropertyValue)
        : base(dataValueEditorFactory, type)
    {
        _ioHelper = ioHelper;
        _jsonSerializer = jsonSerializer;
        _editorConfigurationParser = editorConfigurationParser;
        SupportsReadOnly = true;
    }

    /// <inheritdoc />
    protected override IConfigurationEditor CreateConfigurationEditor() =>
        new CategoryRelationPickerConfigurationEditor(_ioHelper, _jsonSerializer, _editorConfigurationParser);

    /// <inheritdoc />
    //protected override IDataValueEditor CreateValueEditor() =>
    //    DataValueEditorFactory.Create<MultipleValueEditor>(Attribute!);

    protected override IDataValueEditor CreateValueEditor() =>
        DataValueEditorFactory.Create<CategoryRelationPickerPropertyValueEditor>(Attribute!);

    public class CategoryRelationPickerPropertyValueEditor : DataValueEditor, IDataValueReferenceFactory, IDataValueReference
    {
        public CategoryRelationPickerPropertyValueEditor(
            ILocalizedTextService localizedTextService,
            IShortStringHelper shortStringHelper,
            IJsonSerializer jsonSerializer,
            IIOHelper ioHelper,
            DataEditorAttribute attribute)
            : base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute)
        {

        }

        public IDataValueReference GetDataValueReference() => this;

        public bool IsForEditor(IDataEditor? dataEditor) => dataEditor?.Alias == Constants.PropertyEditors.Aliases.CategoryRelationPicker;

        public IEnumerable<UmbracoEntityReference> GetReferences(object? value)
        {
            var asString = value == null ? string.Empty : value is string str ? str : value.ToString();

            if (string.IsNullOrEmpty(asString))
            {
                yield break;
            }

            var udiPaths = asString!.Split(',');

            foreach (var udiPath in udiPaths)
            {
                if (UdiParser.TryParse(udiPath, out Udi? udi))
                {
                    yield return new UmbracoEntityReference(udi, Constants.RelationTypes.RelatedCourseAlias);
                }
            }
        }
    }

@nikolajlauridsen
Copy link
Contributor

nikolajlauridsen commented Jan 18, 2023

You have to implement GetAutomaticRelationTypesAliases as mentioned in #13470 😄

@bjarnef
Copy link
Contributor Author

bjarnef commented Jan 18, 2023

@nikolajlauridsen okay, I though it was picked up from registered property editors.. missed that part 😊

Works now 👍

Not sure if it can be done globally in case one have multiple pickers and want to use same relation type for each of these.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Relations not updated/removed after updating picker references
3 participants