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

!!!FEATURE: Lock the UI and present a modal during publish/discard #3759

Merged
merged 34 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7e68f02
TASK: Replace `typedKeys` shenanigans with proper explicit exports in…
grebaldi Apr 1, 2024
da0861d
TASK: Add more precise typings to backend connector
grebaldi Apr 10, 2024
3c7f885
TASK: Introduce package `@neos-project/neos-ui-error`
grebaldi Mar 21, 2024
4747e07
TASK: Implement ReloadNodes query
grebaldi Apr 8, 2024
c24051a
TASK: Implement reloadNodes saga using the ReloadNodes query endpoint
grebaldi Apr 8, 2024
eb67bea
FEATURE: Create `<PublishDiscardDialog/>`
grebaldi Mar 19, 2024
c43a076
TASK: Add dedicated xliff translations for PublishDiscardDialog
grebaldi Mar 19, 2024
d7b19c1
TASK: Wire up the PublishDiscardDialog component with redux
grebaldi Mar 19, 2024
a3fa413
TASK: Split out `CR.Publishing` state from `CR.Workspaces`
grebaldi Mar 20, 2024
7fb442d
TASK: Rename PublishDiscardDialog -> PublishingDialog
grebaldi Mar 21, 2024
8eb9bdd
TASK: Rename PublishDiscard* -> Publishing* everywhere
grebaldi Mar 21, 2024
28c43c3
TASK: Merge publish and discard sagas
grebaldi Mar 21, 2024
065f6fc
TASK: Remove ad-hoc `NODE_HAS_BEEN_CREATED` constant and make `TypeOf…
grebaldi Mar 21, 2024
ad62a0e
TASK: Use direct responses from publish/discard endpoints rather than…
grebaldi Mar 21, 2024
ee28353
TASK: Handle errors in publishing workflow with `@neos-project/neos-u…
grebaldi Mar 21, 2024
54c3265
TASK: Switch and rename action buttons of ResultDialog in error case
grebaldi Mar 21, 2024
5275758
TASK: Implement Publishing Retry
grebaldi Mar 21, 2024
cc3b19a
TASK: Add diagram to publishing dialog to illustrate the operation
grebaldi Mar 22, 2024
4524411
TASK: Fix phpstan error
grebaldi Mar 22, 2024
b52a68c
TASK: Temporarily use `publishingBonanza` for Neos.Neos 9.0 in E2E tests
grebaldi Mar 22, 2024
5b0121e
TASK: Adjust E2E tests to new discarding behavior
grebaldi Mar 22, 2024
27dc6be
TASK: Remove legacy `<DiscardDialog/>`
grebaldi Mar 25, 2024
ced166a
TASK: Remove legacy `actions.UI.Remote` actions
grebaldi Mar 25, 2024
fba3ce9
TASK: Add `beforeunload` handler during publish/discard
grebaldi Mar 26, 2024
2901002
TASK: Convert Publishing saga to typescript
grebaldi Apr 10, 2024
6367ed2
TASK: Use `reloadNodes` saga after discard operations
grebaldi Apr 10, 2024
7fe1c46
TASK: Update WorkspaceInfo after publish/discard
grebaldi Apr 10, 2024
5f23934
BUGFIX: Fix wrong number of discarded changes in ResultDialog
grebaldi Apr 12, 2024
fd1baeb
TASK: Rename `MinimalNodeForTree::fromNode` -> `*::tryFromNode`
grebaldi Apr 17, 2024
455ff67
TASK: Use `getCurrentBaseWorkspace` of Neos.Neos' Workspace model...
grebaldi Apr 17, 2024
5916c46
TASK: Clarify comment in ReloadNodesQueryHandler
grebaldi Apr 25, 2024
72bcf7f
TASK: Always reload nodes after publish & discard
grebaldi Apr 25, 2024
8a18633
Merge branch 'feature/conflict-resolution-01/publishing-modal' of git…
grebaldi Apr 25, 2024
4c80ffa
TASK: Rename factory `makeReloadAfterDiscard` -> `makeReloadAfterPubl…
grebaldi Apr 25, 2024
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
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ trim_trailing_whitespace = true
indent_style = space
indent_size = 4

[*.{yml,yaml,json}]
[*.{yml,yaml,json,xlf}]
indent_size = 2

[*.md]
Expand Down
65 changes: 65 additions & 0 deletions Classes/Application/ReloadNodes/MinimalNodeForTree.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

/*
* This file is part of the Neos.Neos.Ui package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

declare(strict_types=1);

namespace Neos\Neos\Ui\Application\ReloadNodes;

use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\ActionRequest;
use Neos\Neos\Ui\Fusion\Helper\NodeInfoHelper;

/**
* A helper DTO containing a minimal node representation as needed for
* the document or content tree
*
* @internal for communication within the Neos UI only
*/
#[Flow\Proxy(false)]
final readonly class MinimalNodeForTree implements \JsonSerializable
{
/**
* @param array{nodeAddress:string}&array<string,mixed> $data
*/
private function __construct(private array $data)
{
}

public static function tryFromNode(
Node $node,
NodeInfoHelper $nodeInfoHelper,
ActionRequest $actionRequest
): ?self {
/** @var null|(array{nodeAddress:string}&array<string,mixed>) $data */
$data = $nodeInfoHelper
->renderNodeWithMinimalPropertiesAndChildrenInformation(
node: $node,
actionRequest: $actionRequest
);

return $data ? new self($data) : null;
}

public function getNodeAddressAsString(): string
{
return $this->data['nodeAddress'];
}

/**
* @return array<string,mixed>
*/
public function jsonSerialize(): array
{
return $this->data;
}
}
22 changes: 22 additions & 0 deletions Classes/Application/ReloadNodes/NoDocumentNodeWasFound.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/*
* This file is part of the Neos.Neos.Ui package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

declare(strict_types=1);

namespace Neos\Neos\Ui\Application\ReloadNodes;

/**
* @internal for communication within the Neos UI only
*/
final class NoDocumentNodeWasFound extends \Exception
{
}
22 changes: 22 additions & 0 deletions Classes/Application/ReloadNodes/NoSiteNodeWasFound.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

/*
* This file is part of the Neos.Neos.Ui package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

declare(strict_types=1);

namespace Neos\Neos\Ui\Application\ReloadNodes;

/**
* @internal for communication within the Neos UI only
*/
final class NoSiteNodeWasFound extends \Exception
{
}
66 changes: 66 additions & 0 deletions Classes/Application/ReloadNodes/NodeMap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

/*
* This file is part of the Neos.Neos.Ui package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

declare(strict_types=1);

namespace Neos\Neos\Ui\Application\ReloadNodes;

use Neos\ContentRepository\Core\ContentRepository;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\ActionRequest;
use Neos\Neos\FrontendRouting\NodeAddress;
use Neos\Neos\Ui\Fusion\Helper\NodeInfoHelper;

/**
* Helper DTO for collections of nodes
*
* @internal for communication within the Neos UI only
*/
#[Flow\Proxy(false)]
final readonly class NodeMap implements \JsonSerializable
{
/** @var MinimalNodeForTree[] */
private array $items;

public function __construct(MinimalNodeForTree ...$items)
{
$this->items = $items;
}

/**
* @param class-string<MinimalNodeForTree> $nodeRepresentationClass
*/
public static function builder(
string $nodeRepresentationClass,
NodeInfoHelper $nodeInfoHelper,
ActionRequest $actionRequest
): NodeMapBuilder {
return new NodeMapBuilder(
nodeRepresentationClass: $nodeRepresentationClass,
nodeInfoHelper: $nodeInfoHelper,
actionRequest: $actionRequest,
);
}

/**
* @return \stdClass|(array<string,MinimalNodeForTree>)
*/
public function jsonSerialize(): mixed
{
$result = [];
foreach ($this->items as $item) {
$result[$item->getNodeAddressAsString()] = $item;
}

return $result ? $result : new \stdClass;
}
}
60 changes: 60 additions & 0 deletions Classes/Application/ReloadNodes/NodeMapBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

/*
* This file is part of the Neos.Neos.Ui package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

declare(strict_types=1);

namespace Neos\Neos\Ui\Application\ReloadNodes;

use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\ActionRequest;
use Neos\Neos\Ui\Fusion\Helper\NodeInfoHelper;

/**
* @internal for communication within the Neos UI only
*/
#[Flow\Proxy(false)]
final class NodeMapBuilder
{
/**
* @var MinimalNodeForTree[]
*/
private array $items;

/**
* @param class-string<MinimalNodeForTree> $nodeRepresentationClass
*/
public function __construct(
private readonly string $nodeRepresentationClass,
private readonly NodeInfoHelper $nodeInfoHelper,
private readonly ActionRequest $actionRequest
) {
}

public function addNode(Node $node): void
{
$item = $this->nodeRepresentationClass::tryFromNode(
node: $node,
nodeInfoHelper: $this->nodeInfoHelper,
actionRequest: $this->actionRequest
);

if ($item !== null) {
$this->items[] = $item;
}
}

public function build(): NodeMap
{
return new NodeMap(...$this->items);
}
}
61 changes: 61 additions & 0 deletions Classes/Application/ReloadNodes/ReloadNodesQuery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

/*
* This file is part of the Neos.Neos.Ui package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

declare(strict_types=1);

namespace Neos\Neos\Ui\Application\ReloadNodes;

use Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint;
use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateIds;
use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName;
use Neos\Flow\Annotations as Flow;

/**
* The application layer level query DTO to find all nodes the UI needs
* to refresh its in-memory node cache
*
* @internal for communication within the Neos UI only
*/
#[Flow\Proxy(false)]
final readonly class ReloadNodesQuery
{
public function __construct(
public ContentRepositoryId $contentRepositoryId,
public WorkspaceName $workspaceName,
public DimensionSpacePoint $dimensionSpacePoint,
public NodeAggregateId $siteId,
public NodeAggregateId $documentId,
public NodeAggregateIds $ancestorsOfDocumentIds,
public NodeAggregateIds $toggledNodesIds,
public NodeAggregateIds $clipboardNodesIds
) {
}

/**
* @param array<mixed> $values
*/
public static function fromArray(array $values): self
{
return new self(
contentRepositoryId: ContentRepositoryId::fromString($values['contentRepositoryId']),
workspaceName: WorkspaceName::fromString($values['workspaceName']),
dimensionSpacePoint: DimensionSpacePoint::fromLegacyDimensionArray($values['dimensionSpacePoint']),
siteId: NodeAggregateId::fromString($values['siteId']),
documentId: NodeAggregateId::fromString($values['documentId']),
ancestorsOfDocumentIds: NodeAggregateIds::fromArray($values['ancestorsOfDocumentIds']),
toggledNodesIds: NodeAggregateIds::fromArray($values['toggledNodesIds']),
clipboardNodesIds: NodeAggregateIds::fromArray($values['clipboardNodesIds'])
);
}
}
Loading
Loading