Skip to content

Commit

Permalink
Added deep children option, improved drawing, added moving from one m…
Browse files Browse the repository at this point in the history
…odel to another
  • Loading branch information
zunnu committed Oct 18, 2022
1 parent 5f0b683 commit a293e60
Show file tree
Hide file tree
Showing 6 changed files with 502 additions and 75 deletions.
113 changes: 103 additions & 10 deletions src/Controller/AssociationsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,126 @@ public function initialize() {
$this->Gate = new Gate();
}

/**
* Index method
*/
public function index() {
$this->viewBuilder()->setLayout(false);
$conditions = [];
$showDeepChildren = false;
$search = [];
$selectedTypes = [];

// SEARCH
if ($this->request->is('get')) {
if(!empty($this->request->getQueryParams())) {
$data = $this->request->getQueryParams();
$search = !empty($data['search']) ? json_decode($data['search'], true) : [];
if(!empty($data['deepChildren'])) $showDeepChildren = filter_var($data['deepChildren'], FILTER_VALIDATE_BOOLEAN);
$conditions = $this->_parseConditions($data);

if(!empty($data['plugins']) && $data['plugins'] !== 'undefined') {
$plugins = explode(',', $data['plugins']);
$conditions['plugins'] = $plugins;
}

if(!empty($data['associationTypes']) && $data['associationTypes'] !== 'undefined') {
$associationTypes = explode(',', $data['associationTypes']);
$conditions['associationTypes'] = $associationTypes;
}
if(!empty($data['associationTypes'])) $selectedTypes = explode(',', $data['associationTypes']);
if(!empty($search)) $data = $data + $search;
}
}

$this->set('associationCollections', $this->Gate->associations($conditions)->array());
$associations = $this->Gate->associations($conditions)->array();
$associationsCollection = $this->_parseSearch($associations, $data);

$this->set('associationCollections', $associationsCollection);
$this->set('associationTypes', $this->Gate->getAssociationTypes());
$this->set('activePlugins', $this->Gate->getPlugins());
$this->set('showDeepChildren', $showDeepChildren);
$this->set('selectedTypes', $selectedTypes);

if($this->request->is('ajax')) {
$this->render('Element/associationTree');
}
}

/**
* Details methdod
* Will return more details about the selected association tree
*/
public function details() {
$this->viewBuilder()->setLayout(false);
$data = [];
$associationsCollection = [];
$conditions = [];
$showDeepChildren = false;

if($this->request->is('ajax')) {
$data = $this->request->getData();

if(!empty($this->request->getQueryParams())) {
$conditions = $this->_parseConditions($this->request->getQueryParams());
}
} elseif($this->request->is('get') && !empty($this->request->getQueryParams())) {
$data = $this->request->getQueryParams();
}

if(!empty($data)) {
$associations = $this->Gate->associations($conditions)->array();
$associationsCollection = $this->_parseSearch($associations, $data);
}

$this->set('associationCollections', $associationsCollection);
$this->set('associationTypes', $this->Gate->getAssociationTypes());
$this->set('activePlugins', $this->Gate->getPlugins());
$this->set('showDeepChildren', $showDeepChildren);

// if($this->request->is('ajax')) {
$this->render('Element/associationTree');
// }
}

private function _parseSearch($associations, $data) {
if(!empty($data['targetPlugin']) && !empty($data['targetModel'])) {
if(!empty($associations[$data['targetPlugin']][$data['targetModel']])) {
$associationsCollection = [
$data['targetPlugin'] => [
$data['targetModel'] => $associations[$data['targetPlugin']][$data['targetModel']]
]
];

$showDeepChildren = true;
}
} elseif(!empty($data['plugin']) && !empty($data['currentModel'])) {
if(!empty($associations[$data['plugin']][$data['currentModel']])) {
$associationsCollection = [
$data['plugin'] => [
$data['currentModel'] => $associations[$data['plugin']][$data['currentModel']]
]
];

$showDeepChildren = true;
}
} elseif(!empty($data['plugin']) && empty($data['currentModel'])) {
if(!empty($associations[$data['plugin']])) {
$associationsCollection = [
$data['plugin'] => $associations[$data['plugin']]
];
}
} else {
$associationsCollection = $associations;
}

return $associationsCollection;
}

private function _parseConditions($data) {
$conditions = [];

if(!empty($data['plugins']) && $data['plugins'] !== 'undefined') {
$plugins = explode(',', $data['plugins']);
$conditions['plugins'] = $plugins;
}

if(!empty($data['associationTypes']) && $data['associationTypes'] !== 'undefined') {
$associationTypes = explode(',', $data['associationTypes']);
$conditions['associationTypes'] = $associationTypes;
}

return $conditions;
}
}
53 changes: 53 additions & 0 deletions src/Gate.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public function array() {
// get associations
private function getAssociations() {
$associationsArray = [];
$modelList = [];
$plugins = $this->getConfig('plugins');

foreach ($this->getModels() as $pluginName => $models) {
Expand All @@ -109,10 +110,12 @@ private function getAssociations() {
// clean file name
$model = str_replace('.php', '', $model);
$model = str_replace('Table', '', $model);
$modelList[$model] = ['plugin' => $pluginName];
$associationsArray[$pluginName][$model] = $this->_associations($model, $pluginName);
}
}

$associationsArray = $this->_buildChildren($associationsArray, $modelList);
return $associationsArray;
}

Expand Down Expand Up @@ -162,18 +165,25 @@ private function _associations($model, $plugin = null) {
$type .= ' (' . $this->associationTypes[$type] . ')';
}

// if($target->table() == 'cars') {
// dd([$source, $target]);
// }

$associationsArray[$type][] = [
'source' => [
'table' => $source->table(),
'alias' => $source->alias(),
'connectionName' => $source->connection()->configName(),
'location' => $sourceRegistery,
'model' => $model,
],
'target' => [
'table' => $target->table(),
'alias' => $target->alias(),
'connectionName' => $target->connection()->configName(),
'location' => $targetRegistery,
'model' => $this->convertTableName($target->registryAlias()),
// 'model' => $this->convertTableName($target->entityClass()),
]
];
}
Expand Down Expand Up @@ -256,4 +266,47 @@ public function getPlugins() {

return $loadedPlugins;
}

private function _buildChildren($plugins, $models) {
foreach ($plugins as $pluginName => $plugin) {
foreach ($plugin as $modelName => $model) {
foreach ($model as $associationType => $type) {
foreach($type as $key => $association) {
// dd($association);
if(!empty($association['target']) && !empty($models[$association['target']['model']])) {
$childTypes = $plugins[$models[$association['target']['model']]['plugin']][$association['target']['model']];

if(!empty($childTypes)) {
// if source is the same as the parent model do not show
foreach($childTypes as $childTypeName => $childType) {
foreach($childType as $chK => $ch) {
if($ch['target']['model'] == $association['source']['model']) {
unset($childTypes[$childTypeName][$chK]);
continue;
}
}
}

$plugins[$pluginName][$modelName][$associationType][$key]['target']['childs'] = $childTypes;
}
}
}
}
}
}

return $plugins;
}

private function convertTableName($entityName) {
if(strpos($entityName, '.') !== false) {
$entityName = substr($entityName, strrpos($entityName, '.') + 1);
}

if(substr($entityName, -1) !== 's') {
$entityName = $entityName . 's';
}

return $entityName;
}
}
85 changes: 72 additions & 13 deletions src/Template/Associations/index.ctp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?php
use Cake\View\ViewBuilder;
use Cake\View\ViewBuilder;
?>

<head>
Expand Down Expand Up @@ -48,18 +48,64 @@ use Cake\View\ViewBuilder;
stroke: #333;
stroke-width: 1.5px;
}

/**
* Switch
*/
.switch {
display: inline-block;
position: relative;
width: 50px;
height: 25px;
border-radius: 20px;
background: #dfd9ea;
transition: background 0.28s cubic-bezier(0.4, 0, 0.2, 1);
vertical-align: middle;
cursor: pointer;
}

.switch::before {
content: '';
position: absolute;
top: 1px;
left: 2px;
width: 22px;
height: 22px;
background: #fafafa;
border-radius: 50%;
transition: left 0.28s cubic-bezier(0.4, 0, 0.2, 1), background 0.28s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}

.switch:active::before {
box-shadow: 0 2px 8px rgba(0,0,0,0.28), 0 0 0 20px rgba(128,128,128,0.1);
}

input:checked + .switch {
background: #72da67;
}

input:checked + .switch::before {
left: 27px;
background: #fff;
}

input:checked + .switch:active::before {
box-shadow: 0 2px 8px rgba(0,0,0,0.28), 0 0 0 20px rgba(0,150,136,0.2);
}
</style>

<body>
<div class="container mb-4">
<div class="row">
<?= $this->Form->control('associationTypes', ['label' => 'Association types', 'required' => false, 'options' => $associationTypes, 'multiple' => true, 'id' => 'associationTypes', 'class' => 'form-control', 'templates' => [
'inputContainer' => '<div class="form-group col-md-6 mt-4">{{content}}</div>'
<?= $this->Form->control('associationTypes', ['label' => 'Association types', 'required' => false, 'options' => $associationTypes, 'multiple' => true, 'default' => $selectedTypes, 'id' => 'associationTypes', 'class' => 'form-control', 'templates' => [
'inputContainer' => '<div class="form-group col-md-4 mt-4">{{content}}</div>'
]]); ?>

<!-- <?= $this->Form->control('plugins', ['label' => 'Plugins', 'required' => false, 'options' => $activePlugins, 'multiple' => true, 'class' => 'form-control', 'id' => 'plugins', 'templates' => [
'inputContainer' => '<div class="form-group col-md-6 mt-4">{{content}}</div>'
]]); ?> -->
<div class="form-group col-md-4 mt-4">
<span>Show deep children?</span>
<input name="deepChildren" type="checkbox" hidden="hidden" id="deep-children" <?= $showDeepChildren ? 'checked' : '' ?>>
<label class="switch mt-2" for="deep-children"></label>
</div>
</div>
</div>

Expand Down Expand Up @@ -88,7 +134,7 @@ use Cake\View\ViewBuilder;
});
}

function updateQueryStringParameter(uri, key, value) {
window.window.updateQueryStringParameter = function(uri, key, value) {
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf('?') !== -1 ? "&" : "?";

Expand All @@ -115,7 +161,7 @@ use Cake\View\ViewBuilder;
}

// refresh grid
url = updateQueryStringParameter(window.location.href, 'plugins', selected);
url = window.updateQueryStringParameter(window.location.href, 'plugins', selected);
window.history.pushState("", "", url)
var request = updateGridRequest(url);

Expand All @@ -126,22 +172,20 @@ use Cake\View\ViewBuilder;
})
});


$("#associationTypes").change(function () {
$("#associationTypes").change(function() {
var params = {};
var str = "";
var select = $('#associationTypes');
var selected = select.val();

if (select.val() != '') {
var selected = select.val();

if (select.attr('multiple')) {
selected = selected.join(',');
}
}

// refresh grid
url = updateQueryStringParameter(window.location.href, 'associationTypes', selected);
url = window.updateQueryStringParameter(window.location.href, 'associationTypes', selected);
window.history.pushState("", "", url)
var request = updateGridRequest(url);

Expand All @@ -151,6 +195,21 @@ use Cake\View\ViewBuilder;
$(document).find('#canvas').html(data);
})
});

$("#deep-children").change(function(e) {
let checked = $(this).is(':checked');

// refresh grid
url = window.updateQueryStringParameter(window.location.href, 'deepChildren', checked);
window.history.pushState("", "", url)
var request = updateGridRequest(url);

request.done(function (data) {
// clear content from grid and add new content
$(document).find('#canvas').empty();
$(document).find('#canvas').html(data);
})
})
});
</script>

Expand Down
Loading

0 comments on commit a293e60

Please sign in to comment.