Skip to content

Commit 6167c9e

Browse files
ENH Add link to toast when moving block (#1400)
Add the new edit link for the block when moving a block to a new parent. This makes it easy to go make sure it's in the right order etc.
1 parent 304651f commit 6167c9e

7 files changed

Lines changed: 70 additions & 11 deletions

File tree

client/dist/js/bundle.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/lang/src/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"ElementHeader.STATE_DRAFT": "Item has not been published yet",
1616
"ElementHeader.STATE_MODIFIED": "Item has unpublished changes",
1717
"ElementList.ADD_BLOCKS": "Add blocks to place your content",
18+
"ElementMoveAction.EDIT_LINK": "Go to edit form for new block parent",
1819
"ElementMoveAction.FAILED": "Failed to move element",
1920
"ElementMoveAction.MODAL_TITLE": "Move block {title}",
2021
"ElementMoveAction.MOVE": "Move",

client/src/components/ElementActions/MoveAction.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const MoveAction = (MenuComponent) => (props) => {
2626
setModalIsOpen(true);
2727
};
2828

29-
const handleSuccess = (elementalAreaId) => {
29+
const handleSuccess = ({ elementalAreaId, newEditLink }) => {
3030
setModalIsOpen(false);
3131
fetchElements();
3232
// If we have the ID of the new elemental area, we should refetch that as well.
@@ -37,10 +37,22 @@ const MoveAction = (MenuComponent) => (props) => {
3737
i18n._t('ElementHeader.NOTITLE', 'Untitled {type} block'),
3838
{ type: props.type.title }
3939
);
40-
actions.toasts.success(i18n.inject(
40+
const successMessage = i18n.inject(
4141
i18n._t('ElementMoveAction.SUCCESS', 'Moved block "{title}" successfully'),
4242
{ title: elementTitle }
43-
));
43+
);
44+
if (newEditLink) {
45+
actions.toasts.display({
46+
text: successMessage,
47+
type: 'success',
48+
actions: [{
49+
label: i18n._t('ElementMoveAction.EDIT_LINK', 'Go to edit form for new block parent'),
50+
href: newEditLink,
51+
}],
52+
});
53+
} else {
54+
actions.toasts.success(successMessage);
55+
}
4456
};
4557

4658
const disabled = formDirty;

client/src/components/MoveModal/MoveModal.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,14 @@ const MoveModal = ({
4444
// Throw a toast here - but let our formbuilder stuff handle populating the form with the error messages.
4545
actions.toasts.error(i18n._t('Admin.VALIDATIONERROR', 'Validation Error'));
4646
} else {
47-
// Pass the ElementalAreaID which is added through ElementalAreaController::moveElement().
48-
// This is used to know which elemental area needs to be updated if moving the block between
47+
// Pass the elementalAreaId and/or NewEditLink which are added through ElementalAreaController::moveElement().
48+
// ElementalAreaID is used to know which elemental area needs to be updated if moving the block between
4949
// elemental areas on the same parent.
50-
onSuccess(formSchema.state.fields.find((field) => field.name === 'ElementalAreaID')?.value);
50+
// NewEditLink is used to add a link to the new edit form for the block when moving to a new parent.
51+
onSuccess({
52+
elementalAreaId: formSchema.state.fields.find((field) => field.name === 'ElementalAreaID')?.value,
53+
newEditLink: formSchema.state.fields.find((field) => field.name === 'NewEditLink')?.value,
54+
});
5155
}
5256
return Promise.resolve();
5357
};

src/Controllers/ElementalAreaController.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,14 +443,19 @@ public function moveElement(array $data, Form $form): HTTPResponse
443443
));
444444
}
445445

446+
$oldParent = $element->getPage();
446447
$element->moveTo($elementalArea);
447448

448449
// Add elemental area ID to form so it can be used in the response
449450
// but only if it belongs to the same parent record as the old one.
450451
// This allows us to reload the new elemental area so we can see the block there.
451-
$oldParent = $element->getPage();
452452
if ($parentID === $oldParent->ID && is_a($oldParent, $parentClass)) {
453453
$form->Fields()->add(HiddenField::create('ElementalAreaID')->setValue($elementalArea->ID));
454+
} else {
455+
// If moved to a different parent record, add the edit URL to the form
456+
// so it can be included in the response and added to the success toast.
457+
$editLink = $newParent->getCMSEditLink();
458+
$form->Fields()->add(HiddenField::create('NewEditLink')->setValue($editLink));
454459
}
455460
// Create and send FormSchema JSON response
456461
$schemaID = $form->FormAction();

src/Models/BaseElement.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ public function moveTo(ElementalArea $elementalArea)
363363
$this->doUnpublish();
364364
$this->Sort = null;
365365
$this->ParentID = $elementalArea->ID;
366+
$this->cacheData = [];
366367
// Invoke the hook before writing so extensions don't have to trigger a second write
367368
$this->extend('onAfterMoveTo', $elementalArea);
368369
// No validation, because if field values already stored in the block itself aren't valid

tests/Behat/features/move-element.feature

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Feature: Move elements in the CMS
99
# This allows us to validate that page subclasses get boiled down to just "Page" as the hierarchical base.
1010
Given a "SilverStripe\FrameworkTest\Elemental\Model\MultiElementalBehatTestObject" "Blocks Object1"
1111
And a "SilverStripe\FrameworkTest\Elemental\Model\MultiElementalBehatTestObject" "Blocks Object2"
12+
And a "SilverStripe\FrameworkTest\Elemental\Model\ElementalBehatTestObject" "Blocks Object3"
1213
And a "Page" "Non-elemental page"
1314
And a "BasicElementalPage" "Blocks Page1" with a "Block A" content element with "Some content" content
1415
And the "BasicElementalPage" "Blocks Page1" has a "Block B" content element with "Some content II" content
@@ -64,8 +65,7 @@ Feature: Move elements in the CMS
6465
And I should not see a "ElementalAreaRelation" field
6566
And the "input[name=ElementalAreaRelation]" element "value" attribute should be "ElementalArea"
6667
When I press the "Move" button
67-
Then I should see a "Moved block 'Block B' successfully" success toast
68-
68+
Then I should see a "Moved block 'Block B' successfully" success toast with these actions: Go to edit form for new block parent
6969
# Check the other page now shows the block
7070
Given I left click on "Blocks Page2" in the tree
7171
Then I should see "Block B"
@@ -110,7 +110,43 @@ Feature: Move elements in the CMS
110110

111111
# Move the block and check it has visible moved
112112
When I press the "Move" button
113-
Then I should see a "Moved block 'Lorem' successfully" success toast
113+
# We shouldn't see the action, since we're staying on the same record.
114+
Then I should see a "Moved block 'Lorem' successfully" success toast with no actions
114115
Then I should not see "Lorem" in the "#Form_ItemEditForm_ElementalArea1" element
115116
And I should see "Lorem" in the "#Form_ItemEditForm_ElementalArea2" element
116117
And I should see "Draft" in the "#Form_ItemEditForm_ElementalArea2 .element-editor__element .element-editor-header__info .badge" element
118+
119+
Scenario: I can move a block between different non-SiteTree DataObject parents
120+
Given I go to "/admin/multi-elemental-behat-test-admin"
121+
And I click "Blocks Object1" in the ".ss-gridfield-items" element
122+
# Create elemental block first - can't use fixtures which rely on the relation named explicitly "ElementalArea"
123+
And I click on the "#Form_ItemEditForm_ElementalArea1 .element-editor__toolbar button" element
124+
And I click "Content" in the ".popover-option-set__button-container" element
125+
And I click on the caret button for block 1
126+
And I fill in "Lorem" for "Title" for block 1
127+
And I press the "View actions" button for block 1
128+
And I press the "Publish" button
129+
Then I should see a "Published 'Lorem' successfully" success toast
130+
131+
# Open move modal, select the new parent class, and move the block
132+
When I press the "View actions" button for block 1
133+
And I press the "Move" button
134+
And I select "SilverStripe\FrameworkTest\Elemental\Model\ElementalBehatTestObject" from "ParentClass"
135+
# we can skip selecting the parent record itself because there's only one, so it's pre-selected
136+
When I press the "Move" button
137+
# The ElementalBehatTestObject class returns null for getCMSEditLink, so we shouldn't provide a link
138+
And I should see a "Moved block 'Lorem' successfully" success toast with no actions
139+
140+
# Move the block back again
141+
Given I go to "/admin/elemental-behat-test-admin"
142+
And I click "Blocks Object3" in the ".ss-gridfield-items" element
143+
When I click on the caret button for block 1
144+
Then the "Title" field for block 1 should contain "Lorem"
145+
When I press the "View actions" button for block 1
146+
And I press the "Move" button
147+
And I select "SilverStripe\FrameworkTest\Elemental\Model\MultiElementalBehatTestObject" from "ParentClass"
148+
And I click on the "#Form_ElementForm_3_move_ParentID" element
149+
And I click on the ".ss-searchable-dropdown-field__option:nth-of-type(2)" element
150+
And I select "ElementalArea2" from "ElementalAreaRelation"
151+
And I press the "Move" button
152+
And I should see a "Moved block 'Lorem' successfully" success toast with these actions: Go to edit form for new block parent

0 commit comments

Comments
 (0)