Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Classes/Domain/Model/Changes/AbstractStructuralChange.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,12 @@ protected function finish(Node $node)
$this->getParentDomAddress()->getContextPath() ===
NodeAddress::fromNode($parentNode)->toJson()
) {
// Include nested node information which is in the case of copying not available in the ui as only the root copied element is serialized to the ui.
$updateNestedNodeInfo = new UpdateNodeInfo();
$updateNestedNodeInfo->setNode($node);
$updateNestedNodeInfo->recursive();
$this->feedbackCollection->add($updateNestedNodeInfo);

$renderContentOutOfBand = new RenderContentOutOfBand();
$renderContentOutOfBand->setNode($node);
$renderContentOutOfBand->setParentDomAddress($this->getParentDomAddress());
Expand Down
28 changes: 24 additions & 4 deletions Classes/Domain/Model/Feedback/Operations/UpdateNodeInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class UpdateNodeInfo extends AbstractFeedback
*/
protected $contentRepositoryRegistry;

protected bool $isRecursive = false;

protected ?string $baseNodeType = null;

public function setBaseNodeType(?string $baseNodeType): void
Expand All @@ -58,6 +60,14 @@ public function setNode(Node $node): void
$this->node = $node;
}

/**
* Update node infos recursively
*/
public function recursive(): void
{
$this->isRecursive = true;
}

public function getNode(): Node
{
return $this->node;
Expand Down Expand Up @@ -93,7 +103,7 @@ public function isSimilarTo(FeedbackInterface $feedback): bool
public function serializePayload(ControllerContext $controllerContext): array
{
return [
'byContextPath' => $this->serializeNode($this->node, $controllerContext->getRequest())
'byContextPath' => $this->serializeNodeRecursively($this->node, $controllerContext->getRequest())
];
}

Expand All @@ -102,13 +112,23 @@ public function serializePayload(ControllerContext $controllerContext): array
*
* @return array<string,?array<string,mixed>>
*/
private function serializeNode(Node $node, ActionRequest $actionRequest): array
private function serializeNodeRecursively(Node $node, ActionRequest $actionRequest): array
{
return [
NodeAddress::fromNode($node)->toJson() => $this->nodeInfoHelper->renderNodeWithPropertiesAndChildrenInformation(
$result = [
NodeAddress::fromNode($node)->toJson()
=> $this->nodeInfoHelper->renderNodeWithPropertiesAndChildrenInformation(
$node,
$actionRequest
)
];

if ($this->isRecursive === true) {
$subgraph = $this->contentRepositoryRegistry->subgraphForNode($node);
foreach ($subgraph->findChildNodes($node->aggregateId, FindChildNodesFilter::create()) as $childNode) {
$result = array_merge($result, $this->serializeNodeRecursively($childNode, $actionRequest));
}
}

return $result;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Selector} from 'testcafe';
import {ReactSelector} from 'testcafe-react-selectors';
import {beforeEach, subSection, checkPropTypes} from './../../utils.js';
import {beforeEach, subSection, checkPropTypes, typeTextInline} from './../../utils.js';
import {Page} from './../../pageModel';

/* global fixture:true */
Expand All @@ -10,26 +10,52 @@ fixture`Create new nodes`
.afterEach(() => checkPropTypes());

test('Create a text node in a new container element at the correct position', async t => {
await t.switchToMainWindow();
await t.click(Selector('#neos-ContentTree-ToggleContentTree'));

subSection('Create content collection node');
await t
.click(Selector('#neos-ContentTree-ToggleContentTree'))
.click(Page.treeNode.withText('Content Collection (main)'))
.click(Selector('#neos-ContentTree-AddNode'))
.click(ReactSelector('NodeTypeItem').find('button>span>span').withText('Container_Test'));
.click(ReactSelector('NodeTypeItem').find('button').withExactText('Container_Test'));
await Page.waitForIframeLoading(t);

subSection('Create text node in container');
await t
.click(Page.treeNode.withText('Container'))
.click(Page.treeNode.withExactText('Container_Test'))
.click(Selector('#neos-ContentTree-AddNode'))
.click(Selector('#into'))
.click(ReactSelector('NodeTypeItem').find('button>span>span').withText('Text_Test'));
.click(ReactSelector('NodeTypeItem').find('button').withExactText('Text_Test'));
await Page.waitForIframeLoading(t);

await t.expect(Page.treeNode.withExactText('Text_Test').exists).ok();

await t.switchToIframe('[name="neos-content-main"]');

await t.expect(Selector('.test-text').count).eql(1)
const textIsInWrap = Selector('.test-container .test-text').parent().hasClass('test-container__inner-wrap');
await t.expect(textIsInWrap).ok();
await t.switchToMainWindow();

subSection('Edit new text node inline in container');
await typeTextInline(t, '.test-text [contenteditable="true"]', 'my text', 'p');
await t.expect(Selector('.test-text').innerText).eql('my text')
await t.switchToMainWindow();

subSection('Copy container with new text node');
await t
.click(Page.treeNode.withExactText('Container_Test'))
.click(Selector('#neos-ContentTree-CopySelectedNode'))
.click(Selector('#neos-ContentTree-PasteClipBoardNode'))
.click(Selector('#neos-InsertModeDialog button#after'))
.click(Selector('#neos-InsertModeModal-apply'))
await Page.waitForIframeLoading(t);

await t.expect(Page.treeNode.withExactText('Container_Test').count).eql(2);
await t.expect(Page.treeNode.withExactText('Text_Test').count).eql(2);

subSection('Edit copied text node inline');
await typeTextInline(t, '.test-container:last-child .test-text [contenteditable="true"]', 'my copied text', 'p');
await t.expect(Selector('.test-container:last-child .test-text').innerText).eql('my copied text');
await t.expect(Selector('.test-container .test-text').innerText).eql('my text');
await t.switchToMainWindow();
});
Loading