silverstripe / silverstripe-elemental

Create pages in Silverstripe CMS using content blocks
http://dna.co.nz
BSD 3-Clause "New" or "Revised" License
110 stars 115 forks source link

Allow blocks to be moved between pages #445

Open Hels666 opened 6 years ago

Hels666 commented 6 years ago

Similar to issue #107 but goes a bit further.

It would be nice to be able to move an existing block onto a different page or into or out of an elemental-list. This would allow existing content to be re-arranged during a website update. The current module elemental-virtual only allows a copy of the block so can't be used for a complete re-arrange.

Thank you

robbieaverill commented 6 years ago

At a high level I think this feature would need a new API, e.g. BaseElement::moveTo(DataObject $target) (where $target has the elemental extension applied), and a new UI element.

In elemental 3.x this could be a new GridFieldComponent, perhaps by default we could apply one that renders as "Move to another page" in the more actions dropdown, and devs can remove/replace/add new ones like "Move to another list" if they want to ($moveComponent->setTargetClass(ElementList::class)->setTitle('Move to another list')).

We'd also need a UI of some sort to look up the new target. Possibly TreeDropdownField or even a lazy loaded DropdownField.

@clarkepaul what do you think?

bummzack commented 6 years ago

Couldn't you just "unlink" the block from one elemental area and then add it to another area?

clarkepaul commented 6 years ago

Move to another page should be enough of an action, once it is on a page the person should be able to drag it to an Element list. Also we need to revisit the idea of a block admin (the old one was good, but needed a lot of usability improvements).

@Hels666 ls I'm going to change the title to just focus on just moving to a different page, if moving from one element list to another is not draggable after the current drag n drop improvements (about to be released) then that can be raised separately.

clarkepaul commented 6 years ago

FYI I've added it as a design task to capture something within DSM on this.

newleeland commented 5 years ago

Potential moving designs: https://projects.invisionapp.com/dsm/silver-stripe/silver-stripe/asset/components/5c05e4a05155fa0011591aed

This excludes the dragging blocks between ElementalAreas on the same view, which should follow existing designs: https://projects.invisionapp.com/dsm/silver-stripe/silver-stripe/asset/components/5b8c6cbfc5ffe300176d8e22

brynwhyman commented 5 years ago

A couple of additional thoughts needed here:

clarkepaul commented 5 years ago

Much like the Archive action, I think that the Move action is a double action in that it first unpublishes the block and then it changes to the new parent (removing the block completely from the old page, similar to the pattern when it's archived).

On the new page, the item is added as a draft and the new page is put into a modified state much like when a new block is added.

In regards to what to show in history, the block would either be there at a certain time or not—there is no need for a visible marking that a block was moved after/before the time you are currently viewing.

Within Snapshots, you can substitute "Archived" with "Moved" in this design to indicate the change (keep in mind Snapshots is not as complete as the designs) https://projects.invisionapp.com/dsm/silver-stripe/silver-stripe/asset/components/5d0b20d0b568506a9f647502

ScopeyNZ commented 5 years ago
  • If you move the block, do you expect the history to go with it?

I would recommend "no" here. Copying hundreds of records in history is mostly a bad idea imo.

clarkepaul commented 5 years ago

@ScopeyNZ Why would it need copying, don't they belong to the item anyhow? of are you meaning if we take a copying approach then the history isn't copied?

ScopeyNZ commented 5 years ago

@ScopeyNZ Why would it need copying, don't they belong to the item anyhow? of are you meaning if we take a copying approach then the history isn't copied?

Sorry, I wrote this while thinking about how we would "move history". It is possible to go back and rewrite all the historic records to the new parent I guess.

brynwhyman commented 5 years ago

We've recently talked about limiting this only to pages (not any data object..). There was also questions about how to label different elemental-areas, but we're expecting the relationship name it uses will be enough information for the user to understand which one they want to move to. We don't want to have to call getCMSFields to find out the title name for these elemental-areas.

We've also discussed handling this more as a 'copy' of a block - so the history isn't retained in the new page, that's different to how we handle archiving and a rollback.

If there are cascading relationships within the block, it seems to make sense that we also copy these cascading duplicates too. I.e a banner block with an image would have the image copied too.

We need to factor in the allowed and disallowed` elements for the area that you're moving/copying into.

newleeland commented 5 years ago

Talked to @ScopeyNZ. Would suggest to consider all versioning interactions out of scope for this story. However considerations for continuity of how block history when moving blocks will be considered by @silverstripeux in a separate story.

ScopeyNZ commented 5 years ago

Thinking about how the "area" option could work:

After writing this all down I'm wondering if hiding the "area" field by default is a good idea? Perhaps we could just disable the field when the user hasn't chosen a page yet or if the chosen page only has one area? The disabled field could still show the name of the area that the block will go into. We could just hide the field if there are no pages that have more than one area? cc @silverstripeux.

RVXD commented 3 years ago

Can anyone tell, if there is any progress on this issue/feature request?

RVXD commented 3 years ago

This module works: https://github.com/derralf/silverstripe-elemental-mover

kinglozzer commented 2 years ago

+1 to the suggestion of hiding the “area” dropdown if there’s only one area on the object.

Additional thoughts:

Given that ElementalAreas can belong to DataObjects as well as pages, do we want to support moving between types (e.g. moving a block from a page's ElementalArea to a DataObject's)? My gut instinct says no because it would preclude using a TreeDropdownField in the "move" dialog. Without that ability this would still cater for 99% of people anyway. I think that essentially means looking at the current ElementalArea’s owner - if it’s a page show a TreeDropdownField of other pages to move to, if it’s a DataObject show a flat dropdown (or disable the feature entirely depending on implementation complexity) of other instances of the same DataObject class.

There’s further complexity with this specific element types:

I would propose that, unless there’s a trivial fix/workaround, we just ignore these possible issues in the dialog, let the user pick any page, and then return an error in the GraphQL response to explain to the user why they can’t move the element there.