Skip to content

Commit

Permalink
feat: move add existing to context menus
Browse files Browse the repository at this point in the history
fixes #8
  • Loading branch information
Severin Hauser committed Mar 22, 2023
1 parent 6f255f4 commit a8c2579
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 52 deletions.
5 changes: 5 additions & 0 deletions client/css/TreeView.css
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,11 @@
fill: #008A00;
}

.add-existing-search-results > .add-existing-search-items {
margin-left: 0;
margin-right: 0;
}

/**
* Dialog
*/
Expand Down
52 changes: 45 additions & 7 deletions client/javascript/TreeView.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
this.addLabel = function(label) {
this.$menu.append("<li class='header'>" + label + '</li>');
};
this.addAddExistingButton = function(label, onClick = function() {}) {
var $li = $("<li class='treeview-menu__add-existing font-icon-search'>" + label + "</li>");
$li.click(onClick);
this.$menu.append($li);
}
this.addItem = function(type, label, onClick = function() {}) {
var $li = $("<li data-type='" + type + "'>" + label + '</li>');
$li.click(onClick);
Expand Down Expand Up @@ -162,7 +167,11 @@
'.add-existing-search-dialog-treeview .add-existing-search-items a'
).entwine({
onclick: function() {
var link = this.closest('.add-existing-search-items').data('add-link');
var items = this.closest('.add-existing-search-items');
var link = items.data('add-link');
var parents = items.data('add-parents');
var itemId = items.data('add-item-id');
var sort = items.data('add-sort');
var id = this.data('id');

var dialog = this.closest('.add-existing-search-dialog-treeview')
Expand All @@ -176,6 +185,18 @@
{
name: 'id',
value: id
},
{
name: 'parents',
value: parents || []
},
{
name: 'itemId',
value: itemId || null
},
{
name: 'sort',
value: sort
}
]
},
Expand Down Expand Up @@ -282,8 +303,7 @@
var name = $treeView.data('name');
var url = $treeView.data('url');

// Setup find existing button
$treeView.find('button[name=action_FindExisting]').click(function() {
function showFindExistingDialog(parents, itemId, sort) {
var dialog = $('<div></div>')
.appendTo('body')
.dialog({
Expand All @@ -298,14 +318,21 @@
.remove();
}
});

var url = $.get($treeView.data('url') + '/search');
var search = new URLSearchParams();
search.append('parents', JSON.stringify(parents));
if (sort) {
search.append('sort', sort);
}
if (itemId) {
search.append('itemId', itemId);
}
var url = $.get($treeView.data('url') + '/search?' + search.toString());
dialog
.addClass('add-existing-search-dialog-treeview')
.data('treeview', $treeView)
.data('origUrl', url)
.loadDialog(url);
});
}

// Add new button at the very top
$treeView
Expand All @@ -324,6 +351,10 @@
menu.addLabel(
ss.i18n._t('PageSections.TreeView.AddAChild', 'Add a child')
);
menu.addAddExistingButton(ss.i18n._t('PageSection.TreeView.FindExisting', 'Find existing'), function() {
showFindExistingDialog([], null, 1);
menu.remove();
});
$.each(elems, function(key, value) {
menu.addItem(key, value, function() {
$treeView.addItem([], null, key, 1);
Expand Down Expand Up @@ -405,6 +436,10 @@
menu.addLabel(
ss.i18n._t('PageSections.TreeView.AddAChild', 'Add a child')
);
menu.addAddExistingButton(ss.i18n._t('PageSection.TreeView.FindExisting', 'Find existing'), function() {
showFindExistingDialog(parents, itemId, 1);
menu.remove();
});
$.each(elems, function(key, value) {
menu.addItem(key, value, function() {
$treeView.addItem(parents, itemId, key, 1);
Expand Down Expand Up @@ -432,7 +467,10 @@
'Add new element'
)
);

menu.addAddExistingButton(ss.i18n._t('PageSection.TreeView.FindExisting', 'Find existing'), function() {
showFindExistingDialog(parents.slice(0, parents.length - 1), parents[parents.length - 1], $item.data('sort') + 1);
menu.remove();
});
$.each(elems, function(key, value) {
menu.addItem(key, value, function() {
$treeView.addItem(
Expand Down
3 changes: 2 additions & 1 deletion client/javascript/lang/de.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') {
console.error('Class ss.i18n not defined'); // eslint-disable-line no-console
}
} else {
ss.i18n.addDictionary('en', {
ss.i18n.addDictionary('de', {
"PageSections.GridField.FindExisting": "Bestehendes Element suchen",
"PageSections.GridField.AddAChild": "Unterelement hinzufügen",
"PageSections.GridField.Delete": "Löschen",
"PageSections.GridField.DeleteAChild": "Endgültig löschen",
Expand Down
1 change: 1 addition & 0 deletions client/javascript/lang/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') {
}
} else {
ss.i18n.addDictionary('en', {
"PageSections.GridField.FindExisting": "Find existing",
"PageSections.GridField.AddAChild": "Add a child",
"PageSections.GridField.Delete": "Delete",
"PageSections.GridField.DeleteAChild": "Finally delete",
Expand Down
123 changes: 81 additions & 42 deletions src/TreeView.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class TreeView extends FormField
*/
protected $sortField = 'SortOrder';
protected $parent = null;
/**
* @var \SilverStripe\ORM\Search\SearchContext
*/
protected $context = null;
protected $opens = null;

Expand Down Expand Up @@ -280,53 +283,58 @@ public function add($request)

// If we have an id then add an existing item...
if (isset($data["id"])) {
$element = PageElement::get()->byID($data["id"]);
if (!$element) {
$existing = true;
$child = PageElement::get()->byID($data["id"]);
if (!$child) {
Controller::curr()->getResponse()->setStatusCode(
400,
"Could not find PageElement with id " . $data['id']
);
return $this->FieldHolder();
}

$this->getItems()->Add($element);
$type = $child->ClassName;
} else {
// ...otherwise add a completely new item
$itemId = isset($data["itemId"]) ? intval($data["itemId"]) : null;
$existing = false;
$type = $data["type"];

$child = $type::create();
$child->Name = "New " . $child->singular_name();

$sort = isset($data["sort"]) ? intval($data["sort"]) : 0;
$sortBy = $this->getSortField();
$sortArr = [$sortBy => $sort];

// If we have an itemId then we're adding to another element
// otherwise we're adding to the root
if ($itemId) {
$parents = array_values(array_filter(explode(",", $data["parents"]), 'strlen'));
$path = array_merge($parents, [$itemId]);

$item = PageElement::get()->byID($itemId);
if (!in_array($type, $item->getAllowedPageElements())) {
Controller::curr()->getResponse()->setStatusCode(
400,
"The type " . $type . " is not allowed as a child of " . $item->ClassName
);
return $this->FieldHolder();
}
}

$itemId = isset($data["itemId"]) ? intval($data["itemId"]) : null;
$sort = isset($data["sort"]) ? intval($data["sort"]) : 0;
$sortBy = $this->getSortField();
$sortArr = [$sortBy => $sort];

// If we have an itemId then we're adding to another element
// otherwise we're adding to the root
if ($itemId) {
$parents = array_values(array_filter(explode(",", $data["parents"]), 'strlen'));
$path = array_merge($parents, [$itemId]);

$item = PageElement::get()->byID($itemId);
if (!in_array($type, $item->getAllowedPageElements())) {
Controller::curr()->getResponse()->setStatusCode(
400,
"The type " . $type . " is not allowed as a child of " . $item->ClassName
);
return $this->FieldHolder();
}

if (!$existing) {
$child->write();
$item->Children()->Add($child, $sortArr);
$item->write();
}
$item->Children()->Add($child, $sortArr);
$item->write();

// Make sure we can see the child
$this->openItem(array_merge($path, [$item->ID]));
} else {
// Make sure we can see the child (an its children)
$this->openRecursive($child, [$item]);
} else {
if ($existing) {
$child->write();
$this->getItems()->Add($child, $sortArr);
$this->openRecursive($child);
}
$this->getItems()->Add($child, $sortArr);
}

return $this->FieldHolder();
Expand Down Expand Up @@ -413,13 +421,37 @@ public function delete($request)
return $this->FieldHolder();
}

protected function getTarget($itemId)
{
$target = $this->section;
if ($itemId && $targetElement = PageElement::get()->byID($itemId)) {
$target = $targetElement;
}
return $target;
}

/**
* This action is called when the find existing dialog is shown.
* @param \SilverStripe\Control\HTTPRequest $request
* @return string
*/
public function search($request)
{
$parents = $request->getVar('parents') ?? [];
$itemId = $request->getVar('itemId');
$sort = $request->getVar('sort') ?? 9999;
$target = $this->getTarget($itemId);

$fields = $this->context->getFields();
if ($classField = $fields->fieldByName('ClassName')) {
$allowed = $target->getAllowedPageElements();
$classField->setSource(array_combine($allowed, $allowed));
}

$fields->push(HiddenField::create('parents', 'parents', $parents));
$fields->push(HiddenField::create('itemId', 'itemId', $itemId));
$fields->push(HiddenField::create('sort', 'sort', $sort));

$form = Form::create(
$this,
'search',
Expand All @@ -435,7 +467,11 @@ public function search($request)

// Check if we're requesting the form for the first time (we return the template)
// or if this is a submission (we return the form, so it calls the submitted action)
if (count($request->requestVars()) === 0) {
$extraRequestVars = array_filter($request->requestVars(), function ($name) {
return !in_array($name, ['parents', 'sort', 'itemId']);
}, ARRAY_FILTER_USE_KEY);

if (count($extraRequestVars) === 0) {
return $form->forAjaxTemplate();
}
return $form;
Expand All @@ -448,14 +484,24 @@ public function search($request)
*/
public function doSearch($data, $form)
{
$list = $this->context->getQuery($data, false, false);
$allowed = $this->section->getAllowedPageElements();
$list = $this->context->getQuery([
'ClassName' => $data['ClassName'],
'Name' => $data['Name'],
], false, false);
$allowed = $this->getTarget($data['itemId'])->getAllowedPageElements();
// Remove all disallowed classes
$list = $list->filter("ClassName", $allowed);
$list = $list->filter(["ClassName" => $allowed, "Name:not" => [null, '']]);
$sql = $list->dataQuery()->getFinalisedQuery()->sql($parameters);

$list = new PaginatedList($list, $data);
$data = $this->customise([
'SearchForm' => $form,
'Items' => $list,
'AddArguments' => [
'Parents' => $data['parents'],
'ItemID' => $data['itemId'],
'Sort' => $data['sort'],
],
]);
return $data->renderWith("FLXLabs\PageSections\TreeViewFindExistingForm");
}
Expand Down Expand Up @@ -585,8 +631,6 @@ public function doSave($data, $form)
public function getItems()
{
return $this->section->Elements();
/*return $this->parent->ClassName == PageSection::class ?
$this->parent->Elements() : $this->parent->Children();*/
}

/**
Expand Down Expand Up @@ -642,11 +686,6 @@ public function FieldHolder($properties = array())
$content .= ArrayData::create([
"Button" => $addButton,
])->renderWith("\FLXLabs\PageSections\TreeViewAddNewButton");

// Create the find existing button
$findExisting = TreeViewFormAction::create($this, 'FindExisting', 'Find existing');
$findExisting->addExtraClass("btn font-icon-search tree-actions-findexisting");
$content .= $findExisting->forTemplate();
}

$content .= "</div>";
Expand Down
4 changes: 2 additions & 2 deletions templates/FLXLabs/PageSections/TreeViewFindExistingForm.ss
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ $SearchForm
<h3><%t GridFieldExtensions.RESULTS "Results" %></h3>
<div class="add-existing-search-results">
<% if $Items %>
<ul class="list-group add-existing-search-items" data-add-link="$Link('add')">
<ul class="list-group add-existing-search-items" data-add-link="$Link('add')" data-add-parents="$AddArguments.Parents" data-add-item-id="$AddArguments.ItemID" data-add-sort="$AddArguments.Sort">
<% loop $Items %>
<li class="$EvenOdd list-group-item list-group-item-action">
<a href="#" data-id="$ID">$Title</a>
<a href="#" data-id="$ID">$Title</a> ($ClassName)
</li>
<% end_loop %>
</ul>
Expand Down

0 comments on commit a8c2579

Please sign in to comment.