-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FEATURE: support for referenced diagrams
- Loading branch information
1 parent
6e1b14b
commit 4e71ae9
Showing
15 changed files
with
409 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
namespace Sandstorm\MxGraph; | ||
|
||
use Neos\ContentRepository\Domain\Model\NodeInterface; | ||
use Neos\Neos\Ui\NodeCreationHandler\NodeCreationHandlerInterface; | ||
use Sandstorm\MxGraph\Domain\Model\Diagram; | ||
|
||
class DiagramCreationHandler implements NodeCreationHandlerInterface | ||
{ | ||
public function handle(NodeInterface $node, array $data) | ||
{ | ||
$node->setProperty('diagramIdentifier', 'Diagram ' . date('Y-m-d H:i')); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<?php | ||
|
||
namespace Sandstorm\MxGraph; | ||
|
||
use Neos\Flow\Annotations as Flow; | ||
use Neos\ContentRepository\Domain\Model\NodeInterface; | ||
use Neos\Flow\I18n\Translator; | ||
use Neos\Neos\Service\DataSource\AbstractDataSource; | ||
use Sandstorm\LazyDataSource\LazyDataSourceTrait; | ||
|
||
class DiagramIdentifierDataSource extends AbstractDataSource | ||
{ | ||
|
||
use LazyDataSourceTrait; | ||
|
||
static protected $identifier = 'drawio-diagram-identifier'; | ||
|
||
/** | ||
* @Flow\Inject | ||
* @var Translator | ||
*/ | ||
protected $translator; | ||
|
||
/** | ||
* @Flow\Inject | ||
* @var DiagramIdentifierSearchService | ||
*/ | ||
protected $diagramIdentifierSearchService; | ||
|
||
protected function getDataForIdentifiers(array $identifiers, NodeInterface $node = null, array $arguments = []) | ||
{ | ||
// all identifiers will be returned as is (with a label containing usage count) | ||
$options = []; | ||
foreach ($identifiers as $id) { | ||
$options[$id] = ['label' => $this->getLabelFor($id, $node)]; | ||
} | ||
return $options; | ||
} | ||
|
||
protected function searchData(string $searchTerm, NodeInterface $node = null, array $arguments = []) | ||
{ | ||
$options = []; | ||
if ($node !== null) { | ||
$diagramIdentifiers = $this->diagramIdentifierSearchService->findInIdentifier($searchTerm, $node); | ||
foreach ($diagramIdentifiers as $diagramIdentifier) { | ||
$options[$diagramIdentifier] = ['label' => $this->getLabelFor($diagramIdentifier, $node)]; | ||
} | ||
} | ||
|
||
$options[$searchTerm] = ['label' => $searchTerm, 'icon' => 'plus']; | ||
return $options; | ||
} | ||
|
||
protected function getLabelFor(string $diagramIdentifier, $node): string | ||
{ | ||
$relatedCount = count($this->diagramIdentifierSearchService->findRelatedDiagramsWithIdentifierExcludingOwn($diagramIdentifier, $node)); | ||
$label = $diagramIdentifier; | ||
if ($relatedCount > 0) { | ||
$label .= $this->translator->translateById('diagramIdentifierUsageLabel', [$relatedCount+1], null, null, 'Main', 'Sandstorm.MxGraph'); | ||
} | ||
return $label; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
<?php | ||
|
||
namespace Sandstorm\MxGraph; | ||
|
||
|
||
use Neos\ContentRepository\Domain\Model\NodeInterface; | ||
use Neos\Flow\Annotations as Flow; | ||
use Neos\Neos\Domain\Service\NodeSearchServiceInterface; | ||
|
||
/** | ||
* @Flow\Scope("singleton") | ||
*/ | ||
class DiagramIdentifierSearchService | ||
{ | ||
|
||
/** | ||
* @Flow\Inject | ||
* @var NodeSearchServiceInterface | ||
*/ | ||
protected $nodeSearchService; | ||
|
||
/** | ||
* @param string $query | ||
* @param NodeInterface $node | ||
* @return string[] | ||
*/ | ||
public function findInIdentifier(string $searchTerm, NodeInterface $node): array | ||
{ | ||
$results = []; | ||
$possibleResults = $this->nodeSearchService->findByProperties($searchTerm, ['Sandstorm.MxGraph:Diagram'], $node->getContext()); | ||
foreach ($possibleResults as $possibleResult) { | ||
assert($possibleResult instanceof NodeInterface); | ||
|
||
// we include the diagram identifier if it contains the $searchTerm (case-insensitively) | ||
$possibleDiagramIdentifier = $possibleResult->getProperty('diagramIdentifier'); | ||
if (str_contains(strtolower($possibleDiagramIdentifier), strtolower($searchTerm))) { | ||
if (!isset($results[$possibleDiagramIdentifier])) { | ||
$results[$possibleDiagramIdentifier] = $possibleDiagramIdentifier; | ||
} | ||
} | ||
} | ||
|
||
return array_values($results); | ||
} | ||
|
||
/** | ||
* @param string $diagramIdentifier | ||
* @return NodeInterface[] | ||
*/ | ||
public function findRelatedDiagramsWithIdentifierExcludingOwn(string $diagramIdentifier, NodeInterface $contextNode): array | ||
{ | ||
$results = []; | ||
$possibleResults = $this->nodeSearchService->findByProperties($diagramIdentifier, ['Sandstorm.MxGraph:Diagram'], $contextNode->getContext()); | ||
foreach ($possibleResults as $node) { | ||
assert($node instanceof NodeInterface); | ||
if ($contextNode->getContextPath() === $node->getContextPath()) { | ||
// we skip ourselves | ||
continue; | ||
} | ||
|
||
// we still need to check for exact DiagramIdentifier, because nodeSearchService finds across **ALL** properties | ||
// and with wildcards. | ||
if ($node->getProperty('diagramIdentifier') === $diagramIdentifier) { | ||
$results[] = $node; | ||
} | ||
} | ||
|
||
return $results; | ||
} | ||
|
||
/** | ||
* @param string $diagramIdentifier | ||
* @param NodeInterface $contextNode | ||
* @return NodeInterface|null | ||
*/ | ||
public function findMostRecentDiagramWithIdentifierExcludingOwn(string $diagramIdentifier, NodeInterface $contextNode): ?NodeInterface | ||
{ | ||
$relatedDiagramNodes = $this->findRelatedDiagramsWithIdentifierExcludingOwn($diagramIdentifier, $contextNode); | ||
|
||
uasort($relatedDiagramNodes, function(NodeInterface $a, NodeInterface $b) { | ||
if (method_exists($a, 'getLastModificationDateTime') && method_exists($b, 'getLastModificationDateTime')) { | ||
return $b->getLastModificationDateTime() <=> $a->getLastModificationDateTime(); | ||
} | ||
|
||
return 0; | ||
}); | ||
|
||
if (count($relatedDiagramNodes) > 0) { | ||
// the 1st element is the one with the latest modification time. | ||
return reset($relatedDiagramNodes); | ||
} | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?php | ||
|
||
namespace Sandstorm\MxGraph; | ||
|
||
use Neos\Flow\Annotations as Flow; | ||
use Neos\ContentRepository\Domain\Model\NodeInterface; | ||
|
||
class DiagramNodeHandler | ||
{ | ||
/** | ||
* @Flow\Inject | ||
* @var DiagramIdentifierSearchService | ||
*/ | ||
protected $diagramIdentifierSearchService; | ||
|
||
/** | ||
* Signals that the property of a node was changed. | ||
* | ||
* @Flow\Signal | ||
* @param NodeInterface $node | ||
* @param string $propertyName name of the property that has been changed/added | ||
* @param mixed $oldValue the property value before it was changed or NULL if the property is new | ||
* @param mixed $newValue the new property value | ||
* @return void | ||
*/ | ||
public function nodePropertyChanged(NodeInterface $node, $propertyName, $oldValue, $newValue) | ||
{ | ||
if (!$node->getNodeType()->isOfType('Sandstorm.MxGraph:Diagram')) { | ||
return; | ||
} | ||
|
||
if ($propertyName !== 'diagramIdentifier') { | ||
return; | ||
} | ||
|
||
if ($oldValue === $newValue) { | ||
return; | ||
} | ||
|
||
if (empty($newValue)) { | ||
return; | ||
} | ||
|
||
$sourceDiagramNode = $this->diagramIdentifierSearchService->findMostRecentDiagramWithIdentifierExcludingOwn($newValue, $node); | ||
if ($sourceDiagramNode) { | ||
$node->setProperty('diagramSource', $sourceDiagramNode->getProperty('diagramSource')); | ||
$node->setProperty('diagramSvgText', $sourceDiagramNode->getProperty('diagramSvgText')); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
namespace Sandstorm\MxGraph; | ||
|
||
use Neos\Flow\Core\Bootstrap; | ||
use Neos\Flow\Package\Package as BasePackage; | ||
use Neos\ContentRepository\Domain\Model\Node; | ||
|
||
class Package extends BasePackage | ||
{ | ||
/** | ||
* @param Bootstrap $bootstrap The current bootstrap | ||
* @return void | ||
*/ | ||
public function boot(Bootstrap $bootstrap) | ||
{ | ||
$dispatcher = $bootstrap->getSignalSlotDispatcher(); | ||
|
||
$dispatcher->connect(Node::class, 'nodePropertyChanged', DiagramNodeHandler::class, 'nodePropertyChanged'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Draw.io - Reusable Diagrams | ||
|
||
## Goal | ||
|
||
Diagrams should be **referenceable** by different pages, instead of being **copied**. | ||
|
||
## Idea 1: attach to **ImageInterface** | ||
|
||
Benefits: | ||
- **Asset Usage** can be used to track duplicates. | ||
|
||
Notes: | ||
- There is a workflow to replace assets, by "Replace Asset Resource", BUT this will DIRECTLY | ||
replace the LIVE WORKSPACE ASSET; so it will break workspace encapsulation. | ||
|
||
## Idea 1a: via separate domain model | ||
|
||
This was the original idea; but using a subclass of Image or Asset would be even more convenient I think. | ||
|
||
## Idea 2: Custom referencing, manual updates | ||
|
||
Assume we have a property "identifier" on the Diagram node, with the following rules: | ||
|
||
- when updating the diagram, we update the diagram on **all nodes with the same identifier** | ||
- when updating the identifier, you get an autocomplete for existing identifiers in the system. | ||
- we can use https://github.com/sandstorm/LazyDataSource here for this (for server side search) | ||
- ... and a new entry "create new" (or s.th. like it) | ||
- If the identifier changes TO ANOTHER EXISTING identifier, we copy the other diagram over to this node. | ||
- If there are multiple with the same identifier, we use the **newest** one. | ||
- `nodePropertyChanged` event | ||
|
||
- You get an indicator how often this identifier is used. With NodeType View?? | ||
|
||
|
||
## ToDo | ||
|
||
- [x] Autocomplete for identifier | ||
- [x] LazyDataSource | ||
- [ ] some issues in re-rendering in LazyDataSource | ||
- [x] if Identifier changed and you press APPLY, the diagram is updated. | ||
- [WONT] if Identifier changed and you open the diagram editor, the other diagram is shown | ||
- !!! we don't do this, as it is too easy to accidentally overwrite stuff. | ||
- [x] when saving a diagram with non-empty identifier, update all diagram targets | ||
- [x] a new identifier is generated on creation | ||
- [ ] display number of references |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2"> | ||
<file original="" product-name="Sandstorm.MxGraph" source-language="en" datatype="plaintext"> | ||
<body> | ||
<trans-unit id="diagramIdentifierUsageLabel" xml:space="preserve"> | ||
<source> ({0} mal verwendet)</source> | ||
</trans-unit> | ||
</body> | ||
</file> | ||
</xliff> |
Oops, something went wrong.