From eb7afc08203360e6b11bd116966082e24ac05203 Mon Sep 17 00:00:00 2001 From: "Marco (Valandur)" Date: Tue, 12 Mar 2019 16:58:33 +0100 Subject: [PATCH] fix(archive): Fixes for deleting and archive --- javascript/TreeView.js | 245 ++++++++++-------- src/PageElement.php | 79 +++--- src/PageSection.php | 16 +- src/PageSectionsExtension.php | 2 +- src/TreeView.php | 159 ++++++------ .../PageSections/TreeViewPageElement.ss | 2 + 6 files changed, 252 insertions(+), 251 deletions(-) diff --git a/javascript/TreeView.js b/javascript/TreeView.js index 8ff88d3..db8acdd 100644 --- a/javascript/TreeView.js +++ b/javascript/TreeView.js @@ -1,23 +1,23 @@ -(function ($) { +(function($) { function TreeViewContextMenu() { - this.createDom = function (id, name) { + this.createDom = function(id, name) { this.$menu = $( "" + name + + "' class='treeview-menu' data-id='" + + id + + "'>" ); }; - this.addLabel = function (label) { + this.addLabel = function(label) { this.$menu.append("
  • " + label + '
  • '); }; - this.addItem = function (type, label, onClick = function () {}) { + this.addItem = function(type, label, onClick = function() {}) { var $li = $("
  • " + label + '
  • '); $li.click(onClick); this.$menu.append($li); }; - this.show = function (x, y) { + this.show = function(x, y) { var pos = { top: y, left: x @@ -27,7 +27,7 @@ this.$menu.css(pos); this.$menu.show(); var that = this; - window.requestAnimationFrame(function () { + window.requestAnimationFrame(function() { var wW = $(window).width(); var wH = $(window).height(); var eW = that.$menu.outerWidth(true); @@ -43,14 +43,14 @@ that.$menu.css(pos); }); }; - this.remove = function () { + this.remove = function() { this.$menu.remove(); }; } - $.entwine('ss', function ($) { + $.entwine('ss', function($) { // Hide our custom context menu when not needed - $(document).on('mousedown', function (event) { + $(document).on('mousedown', function(event) { $parents = $(event.target).parents('.treeview-menu'); if ($parents.length == 0) { $('.treeview-menu').remove(); @@ -58,7 +58,7 @@ }); $('.view-detail-dialog .gridfield-better-buttons-prevnext').entwine({ - onclick: function () { + onclick: function() { this.closest('.view-detail-dialog').loadDialog( $.get(this.prop('href')) ); @@ -67,7 +67,7 @@ }); $('.view-detail-dialog .action-detail').entwine({ - onclick: function () { + onclick: function() { const dialog = this.closest('.view-detail-dialog').loadDialog( $.get(this.prop('href')) ); @@ -77,36 +77,39 @@ }); $('.view-detail-dialog form').entwine({ - onsubmit: function () { + onsubmit: function() { var dialog = this.closest('.view-detail-dialog'); const self = this; $.ajax( - $.extend({}, { - headers: { - 'X-Pjax': 'CurrentField' - }, - type: 'POST', - url: this.prop('action'), - dataType: 'html', - data: this.serialize(), - success: function () { - if (self.hasClass('view-detail-form')) { - dialog.data('treeview').reload(); - dialog.dialog('close'); - } else { - if (dialog.data("clickedButton") === 'action_doSaveAndQuit') { - dialog.loadDialog($.get(dialog.data("origUrl"))); + $.extend( + {}, + { + headers: { + 'X-Pjax': 'CurrentField' + }, + type: 'POST', + url: this.prop('action'), + dataType: 'html', + data: this.serialize(), + success: function() { + if (self.hasClass('view-detail-form')) { + dialog.data('treeview').reload(); + dialog.dialog('close'); } else { - const url = self.prop('href') ? - self.prop('href') : - dialog.data('href'); - dialog.loadDialog($.get(url)); + if (dialog.data('clickedButton') === 'action_doSaveAndQuit') { + dialog.loadDialog($.get(dialog.data('origUrl'))); + } else { + const url = self.prop('href') + ? self.prop('href') + : dialog.data('href'); + dialog.loadDialog($.get(url)); + } } } } - }) + ) ); return false; @@ -116,13 +119,13 @@ // Show our search form after opening the search dialog // Show our detail form after opening the detail dialog $('.add-existing-search-dialog-treeview, .view-detail-dialog').entwine({ - loadDialog: function (deferred) { + loadDialog: function(deferred) { var dialog = this.addClass('loading').empty(); - deferred.done(function (data) { + deferred.done(function(data) { dialog.html(data).removeClass('loading'); - dialog.find("button[type=submit]").click(function () { - dialog.data("clickedButton", this.name); + dialog.find('button[type=submit]').click(function() { + dialog.data('clickedButton', this.name); }); }); return this; @@ -130,20 +133,22 @@ }); // Submit our search form to our own endpoint and show the results - $('.add-existing-search-dialog-treeview .add-existing-search-form').entwine({ - onsubmit: function () { - this.closest('.add-existing-search-dialog-treeview').loadDialog( - $.get(this.prop('action'), this.serialize()) - ); - return false; + $('.add-existing-search-dialog-treeview .add-existing-search-form').entwine( + { + onsubmit: function() { + this.closest('.add-existing-search-dialog-treeview').loadDialog( + $.get(this.prop('action'), this.serialize()) + ); + return false; + } } - }); + ); // Allow clicking the elements in the search form $( '.add-existing-search-dialog-treeview .add-existing-search-items .list-group-item-action' ).entwine({ - onclick: function () { + onclick: function() { if (this.children('a').length > 0) { this.children('a') .first() @@ -156,7 +161,7 @@ $( '.add-existing-search-dialog-treeview .add-existing-search-items a' ).entwine({ - onclick: function () { + onclick: function() { var link = this.closest('.add-existing-search-items').data('add-link'); var id = this.data('id'); @@ -164,14 +169,17 @@ .addClass('loading') .empty(); - dialog.data('treeview').reload({ + dialog.data('treeview').reload( + { url: link, - data: [{ - name: 'id', - value: id - }] + data: [ + { + name: 'id', + value: id + } + ] }, - function () { + function() { dialog.dialog('close'); } ); @@ -184,7 +192,7 @@ $( '.add-existing-search-dialog-treeview .add-existing-search-pagination a' ).entwine({ - onclick: function () { + onclick: function() { this.closest('.add-existing-search-dialog-treeview').loadDialog( $.get(this.prop('href')) ); @@ -210,12 +218,13 @@ // Attach data to our tree view $('.treeview-pagesections').entwine({ - addItem: function (parents, itemId, elemType, sort = 99999) { + addItem: function(parents, itemId, elemType, sort = 99999) { var $treeView = $(this); $treeView.reload({ url: $treeView.data('url') + '/add', - data: [{ + data: [ + { name: 'parents', value: parents }, @@ -234,12 +243,13 @@ ] }); }, - removeItem: function (parents, itemId) { + removeItem: function(parents, itemId) { var $treeView = $(this); $treeView.reload({ url: $treeView.data('url') + '/remove', - data: [{ + data: [ + { name: 'parents', value: parents }, @@ -250,12 +260,13 @@ ] }); }, - deleteItem: function (parents, itemId) { + deleteItem: function(parents, itemId) { var $treeView = $(this); $treeView.reload({ url: $treeView.data('url') + '/delete', - data: [{ + data: [ + { name: 'parents', value: parents }, @@ -266,13 +277,13 @@ ] }); }, - onadd: function () { + onadd: function() { var $treeView = $(this); var name = $treeView.data('name'); var url = $treeView.data('url'); // Setup find existing button - $treeView.find('button[name=action_FindExisting]').click(function () { + $treeView.find('button[name=action_FindExisting]').click(function() { var dialog = $('
    ') .appendTo('body') .dialog({ @@ -280,7 +291,7 @@ resizable: false, width: 500, height: 600, - close: function () { + close: function() { $(this) .dialog('destroy') .remove(); @@ -300,7 +311,7 @@ .find( '> .treeview-pagesections__header > .treeview-item-actions .add-button' ) - .click(function (event) { + .click(function(event) { event.preventDefault(); event.stopImmediatePropagation(); @@ -312,8 +323,8 @@ menu.addLabel( ss.i18n._t('PageSections.TreeView.AddAChild', 'Add a child') ); - $.each(elems, function (key, value) { - menu.addItem(key, value, function () { + $.each(elems, function(key, value) { + menu.addItem(key, value, function() { $treeView.addItem([], null, key, 1); menu.remove(); }); @@ -322,7 +333,7 @@ }); // Process items - $treeView.find('.treeview-item').each(function () { + $treeView.find('.treeview-item').each(function() { var $item = $(this); var itemId = $item.data('id'); var parents = $item.data('tree'); @@ -330,13 +341,14 @@ // Open an item button $item .find('> .treeview-item__panel > .treeview-item-flow .tree-button') - .click(function (event) { + .click(function(event) { event.preventDefault(); event.stopImmediatePropagation(); $treeView.reload({ url: url + '/tree', - data: [{ + data: [ + { name: 'parents', value: parents }, @@ -351,7 +363,7 @@ // Edit button $item .find('> .treeview-item__panel > .treeview-item-flow .edit-button') - .click(function () { + .click(function() { var dialog = $('
    ') .appendTo('body') .dialog({ @@ -359,7 +371,7 @@ resizable: false, width: $(window).width() * 0.9, height: $(window).height() * 0.9, - close: function () { + close: function() { $(this) .dialog('destroy') .remove(); @@ -379,7 +391,7 @@ .find( '> .treeview-item__panel > .treeview-item-actions .add-button' ) - .click(function (event) { + .click(function(event) { event.preventDefault(); event.stopImmediatePropagation(); @@ -391,8 +403,8 @@ menu.addLabel( ss.i18n._t('PageSections.TreeView.AddAChild', 'Add a child') ); - $.each(elems, function (key, value) { - menu.addItem(key, value, function () { + $.each(elems, function(key, value) { + menu.addItem(key, value, function() { $treeView.addItem(parents, itemId, key, 1); menu.remove(); }); @@ -403,7 +415,7 @@ // Add new after item button $item .find('> .treeview-item__post-actions .add-after-button') - .click(function (event) { + .click(function(event) { event.preventDefault(); event.stopImmediatePropagation(); @@ -419,8 +431,8 @@ ) ); - $.each(elems, function (key, value) { - menu.addItem(key, value, function () { + $.each(elems, function(key, value) { + menu.addItem(key, value, function() { $treeView.addItem( parents.slice(0, parents.length - 1), parents[parents.length - 1], @@ -438,11 +450,15 @@ .find( '> .treeview-item__panel > .treeview-item-flow .delete-button' ) - .click(function (event) { + .click(function(event) { event.preventDefault(); event.stopImmediatePropagation(); $target = $(event.target); + // If we clicked the span get the parent button + if ($target.prop('tagName') === 'SPAN') { + $target = $target.parent(); + } var menu = new TreeViewContextMenu(); menu.createDom(itemId, name); @@ -453,20 +469,20 @@ menu.addItem( '__REMOVE__', ss.i18n._t('PageSections.TreeView.RemoveAChild', 'Remove'), - function () { + function() { $treeView.removeItem(parents, itemId); menu.remove(); } ); - if ($target.data('used-count') < 2) { + if (Number($target.data('used-count')) <= 1) { menu.addItem( '', ss.i18n._t( 'PageSections.TreeView.DeleteAChild', 'Finally delete' ), - function () { + function() { $treeView.deleteItem(parents, itemId); menu.remove(); } @@ -474,12 +490,12 @@ var $li = $( '
  • ' + - ss.i18n._t( - 'PageSections.TreeView.DeleteAChild', - 'Finally delete' - ) + - '
  • ', - function () { + ss.i18n._t( + 'PageSections.TreeView.DeleteAChild', + 'Finally delete' + ) + + '', + function() { $treeView.deleteItem(parents, itemId); menu.remove(); } @@ -504,7 +520,7 @@ tolerance: 'pointer', greedy: true, - helper: function (event) { + helper: function(event) { var $panel = $item.find('> .treeview-item__panel'); var $helper = $("
    "); $helper @@ -527,8 +543,8 @@ return $helper; }, - start: function () { - $('.ui-droppable').each(function () { + start: function() { + $('.ui-droppable').each(function() { var $drop = $(this); var $dropItem = $drop.closest('.treeview-item'); var $parentDropItem = $dropItem @@ -548,7 +564,7 @@ // or a same id if ( $dropItem.parents(".treeview-item[data-id='" + itemId + "']") - .length + .length ) { return; } @@ -559,8 +575,8 @@ if ( ($drop.hasClass('after') || $drop.hasClass('before')) && $dropItem - .siblings(".treeview-item[data-id='" + itemId + "']") - .not($item).length + .siblings(".treeview-item[data-id='" + itemId + "']") + .not($item).length ) { return; } @@ -609,7 +625,7 @@ $drop.show(); }); }, - stop: function (event, ui) { + stop: function(event, ui) { $('.ui-droppable').css('display', ''); // Show the previous elements. If the user made an invalid movement then // we want this to show anyways. If he did something valid the treeview will @@ -625,11 +641,11 @@ }); // Dropping targets - $item.find('.treeview-item-reorder .droppable').each(function () { + $item.find('.treeview-item-reorder .droppable').each(function() { $(this).droppable({ hoverClass: 'state-active', tolerance: 'pointer', - drop: function (event, ui) { + drop: function(event, ui) { $drop = $(this); $dropItem = $drop.closest('.treeview-item'); @@ -649,15 +665,16 @@ } var newParent = - type === 'child' ? - itemId : - parents.length > 0 ? - parents[parents.length - 1] : - ''; + type === 'child' + ? itemId + : parents.length > 0 + ? parents[parents.length - 1] + : ''; $treeView.reload({ url: url + '/move', - data: [{ + data: [ + { name: 'parents', value: oldParents }, @@ -683,7 +700,7 @@ // This is copy paste from SilverStripe GridField.js, modified to work for the TreeView // It updates the gridfield by sending the specified request // and using the response as the new content for the gridfield - reload: function (ajaxOpts, successCallback) { + reload: function(ajaxOpts, successCallback) { var self = this, form = this.closest('form'), focusedElName = this.find(':input:focus').attr('name'), // Save focused element for restoring after refresh @@ -691,10 +708,12 @@ if (!ajaxOpts) ajaxOpts = {}; if (!ajaxOpts.data) ajaxOpts.data = []; - ajaxOpts.data = ajaxOpts.data.concat(data).concat([{ - name: 'state', - value: self.data('state-id') - }]); + ajaxOpts.data = ajaxOpts.data.concat(data).concat([ + { + name: 'state', + value: self.data('state-id') + } + ]); // Include any GET parameters from the current URL, as the view state might depend on it. // For example, a list prefiltered through external search criteria might be passed to GridField. @@ -708,14 +727,16 @@ form.addClass('loading'); $.ajax( - $.extend({}, { + $.extend( + {}, + { headers: { 'X-Pjax': 'CurrentField' }, type: 'POST', url: this.data('url'), dataType: 'html', - success: function (data) { + success: function(data) { // Replace the grid field with response, not the form. // TODO Only replaces all its children, to avoid replacing the current scope // of the executing method. Means that it doesn't retrigger the onmatch() on the main container. @@ -731,7 +752,7 @@ // TODO: Don't know how original SilverStripe GridField magically calls self.onadd(); }, - error: function (e) { + error: function(e) { alert(i18n._t('Admin.ERRORINTRANSACTION')); form.removeClass('loading'); } diff --git a/src/PageElement.php b/src/PageElement.php index a305443..dfba364 100755 --- a/src/PageElement.php +++ b/src/PageElement.php @@ -175,54 +175,39 @@ public function getTreeViewPreview() } /** - * Gets all parents that this PageElement is rendered on. - * - * Adds the following properties to each parent: - * __PageSection: The PageSection on the parent that the PageElement is from. - * __PageElementVersion: The version of the PageElement being used. - * __PageElementPublishedVersion: The published version of the PageElement being used. - * @return \DataObject[] - */ - public function getAllSectionParents() { - $parents = ArrayList::create(); + * Gets all places that this PageElement is shown in. + * + * Returns a list of objects with the following properties: + * Parent: The name and class name of the root parent object. + * Section: The name of the section on the root object where this element is shown. + * Path: The names of the parent PageElements that lead to this element. + * @return \SilverStripe\ORM\ArrayList An array of info objects + */ + public function getAllUses() { + $uses = ArrayList::create(); foreach ($this->PageSections() as $section) { $p = $section->Parent(); + // Skip if the parent object doesn't exist (possibly archived) if (!$p || !$p->ID) { - // If our parent doesn't have an ID it's probably deleted/archived. - $p = $archived = Versioned::get_latest_version($section->__ParentClass, $section->__ParentID); - $p->__PageSection = $section; - $p->__PageElementVersion = $section->Elements()->filter("ID", $this->ID)->First()->Version; - $p->__PageElementPublishedVersion = "Not published"; - $parents->add($p); continue; } - $stage = Versioned::get_stage(); - Versioned::set_stage(Versioned::LIVE); - $pubSection = DataObject::get_by_id($section->ClassName, $section->ID); - $pubElem = $pubSection ? $pubSection->Elements()->filter("ID", $this->ID)->First() : null; - $p->__PageSection = $section; - $p->__PageElementVersion = $section->Elements()->filter("ID", $this->ID)->First()->Version; - $p->__PageElementPublishedVersion = $pubElem ? $pubElem->Version : "Not published"; - Versioned::set_stage($stage); - $parents->add($p); + $uses->add(DataObject::create([ + "Parent" => $p->Title . " (" . $p->ClassName . ")", + "Section" => $section->__Name, + "Path" => "", + ])); } - return $parents; - } - - /** - * Recursively gets all the parents of this element, in no particular order. - * @return \FLXLabs\PageSections\PageElement[] - */ - public function getAllParents() - { - $parents = ArrayList::create($this->Parents()->toList()); foreach ($this->Parents() as $parent) { - $parents->merge($parent->getAllParents()); + foreach ($parent->getAllUses() as $use) { + $use->Path = $use->Path . " -> " . $parent->Name; + $uses->add($use); + } } - return $parents; + + return $uses; } public function getCMSFields() @@ -242,24 +227,20 @@ public function getCMSFields() "Title" ); - // Create an array of all the sections this element is on - $parents = $this->getAllSectionParents(); + // Create an array of all places this PageElement is shown + $uses = $this->getAllUses(); - if ($parents->Count() > 0) { + if ($uses->Count() > 0) { $config = GridFieldConfig_Base::create() ->removeComponentsByType(GridFieldDataColumns::class) ->addComponent($dataColumns = new GridFieldDataColumns()); $dataColumns->setDisplayFields([ - "ID" => "ID", - "ClassName" => "Type", - "Title" => "Title", - "__PageSection.__Name" => "PageSection", - "__PageElementVersion" => "Element version", - "__PageElementPublishedVersion" => "Published element version", - "getPublishState" => "Parent State", + "Parent" => "Parent", + "Section" => "Section", + "Path" => "Path", ]); - $gridField = GridField::create("Pages", "Section Parents", $parents, $config); - $fields->addFieldToTab("Root.SectionParents", $gridField); + $gridField = GridField::create("Pages", "Uses", $uses, $config); + $fields->addFieldToTab("Root.Uses", $gridField); } return $fields; diff --git a/src/PageSection.php b/src/PageSection.php index 3b19cab..9a59d59 100644 --- a/src/PageSection.php +++ b/src/PageSection.php @@ -82,21 +82,7 @@ public function forTemplate() * @return string */ public function getName() { - if ($this->__Name) { - return $this->__Name; - } - - $parent = $this->Parent(); - // TODO: Find out why this happens - if (!method_exists($parent, "getPageSectionNames")) { - return null; - } - foreach ($parent->getPageSectionNames() as $sectionName) { - if ($parent->{"PageSection" . $sectionName . "ID"} === $this->ID) { - return $sectionName; - } - } - return null; + return $this->__Name; } /** diff --git a/src/PageSectionsExtension.php b/src/PageSectionsExtension.php index cf10cd0..3a9a8d8 100755 --- a/src/PageSectionsExtension.php +++ b/src/PageSectionsExtension.php @@ -126,7 +126,7 @@ public function updateCMSFields(FieldList $fields) { $fields->removeByName($name); $fields->removeByName($name . "ID"); - if ($this->owner->ID) { + if ($this->owner->ID && $this->owner->$name->ID) { $tv = new TreeView($name, $sectionName, $this->owner->$name); $fields->addFieldToTab("Root.PageSections.{$sectionName}", $tv); } diff --git a/src/TreeView.php b/src/TreeView.php index 71998c0..3bd9c57 100644 --- a/src/TreeView.php +++ b/src/TreeView.php @@ -46,11 +46,12 @@ class TreeView extends FormField ); - public function __construct($name, $title = null, $section = null) + public function __construct($name, $title = null, $section = null, $readonly = false) { parent::__construct($name, $title, null); $this->section = $section; + $this->readonly = $readonly; $this->context = singleton(PageElement::class)->getDefaultSearchContext(); if ($section) { @@ -62,6 +63,10 @@ public function __construct($name, $title = null, $section = null) } } + public function performReadonlyTransformation() { + return new TreeView($this->name, $this->title, $this->section, $this->readonly); + } + public function setValue($value, $data = null) { $this->section = $value; return $this; @@ -232,6 +237,9 @@ public function move($request) $newParent->Children()->Add($item, $sortArr); } + // Save the parent so the relation sort order is redone + $newParent->write(); + return $this->FieldHolder(); } @@ -419,11 +427,6 @@ public function doSearch($data, $form) $allowed = $this->section->getAllowedPageElements(); // Remove all disallowed classes $list = $list->filter("ClassName", $allowed); - // If we're viewing the search list on a PageElement, - // then we have to remove all parents as possible elements - /*if ($this->parent->ClassName === PageElement::class) { - $list = $list->subtract($this->parent->getAllParents()); - }*/ $list = new PaginatedList($list, $data); $data = $this->customise([ 'SearchForm' => $form, @@ -604,28 +607,31 @@ public function FieldHolder($properties = array()) $elems[$class] = singleton($class)->singular_name(); } - // Create the add new button at the very top - $addButton = TreeViewFormAction::create( - $this, - "AddActionBase", - null, - null, - null - ); - $addButton->setAttribute("data-allowed-elements", json_encode($elems, JSON_UNESCAPED_UNICODE)); - $addButton->addExtraClass("btn add-button font-icon-plus"); - if (!count($elems)) { - $addButton->setDisabled(true); - } - $addButton->setButtonContent(' '); - $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(); + if (!$this->readonly) { + // Create the add new button at the very top + $addButton = TreeViewFormAction::create( + $this, + "AddActionBase", + null, + null, + null + ); + $addButton->setAttribute("data-allowed-elements", json_encode($elems, JSON_UNESCAPED_UNICODE)); + $addButton->addExtraClass("btn add-button font-icon-plus"); + if (!count($elems)) { + $addButton->setDisabled(true); + } + $addButton->setButtonContent(' '); + $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 .= "
    "; $list = $this->getItems()->sort($this->sortField)->toArray(); @@ -640,6 +646,7 @@ public function FieldHolder($properties = array()) 'fieldset', [ 'class' => 'treeview-pagesections pagesection-' . $this->getName(), + 'data-readonly' => $this->readonly, 'data-name' => $this->getName(), 'data-url' => $this->Link(), 'data-state-id' => $sessionId, @@ -725,7 +732,7 @@ private function renderTree($item, $parents, $opens, $isFirst) // Create a button to add a new child element // and save the allowed child classes on the button - if (count($classes)) { + if (!$this->readonly && count($classes)) { $addButton = TreeViewFormAction::create( $this, "AddAction".$item->ID, @@ -740,49 +747,52 @@ private function renderTree($item, $parents, $opens, $isFirst) } $addButton->setButtonContent(' '); } - // Create a button to add an element after - // and save the allowed child classes on the button - $addAfterButton = TreeViewFormAction::create( - $this, - "AddAfterAction".$item->ID, - null, - null, - null - ); - $addAfterButton->setAttribute("data-allowed-elements", - json_encode($parentElems, JSON_UNESCAPED_UNICODE) - ); - $addAfterButton->addExtraClass("btn add-after-button font-icon-plus"); - if (!count($parentElems)) { - $addAfterButton->setDisabled(true); - } - $addAfterButton->setButtonContent(' '); - // Create a button to delete and/or remove the element from the parent - $deleteButton = TreeViewFormAction::create( - $this, - "DeleteAction".$item->ID, - null, - null, - null - ); - $deleteButton->setAttribute( - "data-used-count", - $item->Parents()->Count() + $item->getAllSectionParents()->Count() - ); - $deleteButton->addExtraClass("btn delete-button font-icon-trash-bin"); - $deleteButton->setButtonContent('Delete'); + if (!$this->readonly) { + // Create a button to add an element after + // and save the allowed child classes on the button + $addAfterButton = TreeViewFormAction::create( + $this, + "AddAfterAction".$item->ID, + null, + null, + null + ); + $addAfterButton->setAttribute("data-allowed-elements", + json_encode($parentElems, JSON_UNESCAPED_UNICODE) + ); + $addAfterButton->addExtraClass("btn add-after-button font-icon-plus"); + if (!count($parentElems)) { + $addAfterButton->setDisabled(true); + } + $addAfterButton->setButtonContent(' '); - // Create a button to edit the record - $editButton = TreeViewFormAction::create( - $this, - "EditAction".$item->ID, - null, - null, - null - ); - $editButton->addExtraClass("btn edit-button font-icon-edit"); - $editButton->setButtonContent('Edit'); + // Create a button to delete and/or remove the element from the parent + $deleteButton = TreeViewFormAction::create( + $this, + "DeleteAction".$item->ID, + null, + null, + null + ); + $deleteButton->setAttribute( + "data-used-count", + $item->getAllUses()->Count() + ); + $deleteButton->addExtraClass("btn delete-button font-icon-trash-bin"); + $deleteButton->setButtonContent('Delete'); + + // Create a button to edit the record + $editButton = TreeViewFormAction::create( + $this, + "EditAction".$item->ID, + null, + null, + null + ); + $editButton->addExtraClass("btn edit-button font-icon-edit"); + $editButton->setButtonContent('Edit'); + } // Create the tree icon $icon = ''; @@ -807,6 +817,7 @@ private function renderTree($item, $parents, $opens, $isFirst) $treeButton->setButtonContent(' '); return ArrayData::create([ + "Readonly" => $this->readonly, "Item" => $item, "Tree" => $tree, "IsOpen" => $isOpen, @@ -816,10 +827,10 @@ private function renderTree($item, $parents, $opens, $isFirst) "AllowedElements" => json_encode($elems, JSON_UNESCAPED_UNICODE), "TreeButton" => $treeButton, "AddButton" => isset($addButton) ? $addButton : null, - "AddAfterButton" => $addAfterButton, - "EditButton" => $editButton, - "DeleteButton" => $deleteButton, - "UsedCount" => $item->Parents()->Count() + $item->getAllSectionParents()->Count(), + "AddAfterButton" => isset($addAfterButton) ? $addAfterButton : null, + "EditButton" => isset($editButton) ? $editButton : null, + "DeleteButton" => isset($deleteButton) ? $deleteButton : null, + "UsedCount" => $item->getAllUses()->Count() ])->renderWith("\FLXLabs\PageSections\TreeViewPageElement"); } diff --git a/templates/FLXLabs/PageSections/TreeViewPageElement.ss b/templates/FLXLabs/PageSections/TreeViewPageElement.ss index b4fa82f..a7f09aa 100644 --- a/templates/FLXLabs/PageSections/TreeViewPageElement.ss +++ b/templates/FLXLabs/PageSections/TreeViewPageElement.ss @@ -13,12 +13,14 @@ class="treeview-item__panel" >
    + <% if not Readonly %>
    <% if IsFirst %>
    <% end_if %>
    + <% end_if %>