Skip to content

Commit

Permalink
fix(gridfield ui): display id and times used, replace context menu wi…
Browse files Browse the repository at this point in the history
…th buttons, fix reorder issues
  • Loading branch information
flxqr2 committed Mar 5, 2018
1 parent e7dca83 commit b3209ad
Show file tree
Hide file tree
Showing 9 changed files with 198 additions and 98 deletions.
73 changes: 64 additions & 9 deletions code/GridFieldPageSectionsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ class GridFieldPageSectionsExtension implements
);


public function __construct($page, $allowedParentElements = array(), $sortField = "SortOrder") {
public function __construct($page, $sortField = "SortOrder") {
$this->page = $page;
$this->allowedParentElements = $allowedParentElements;
$this->sortField = $sortField;
}

Expand Down Expand Up @@ -68,12 +67,12 @@ public function augmentColumns($gridField, &$columns) {
array_splice($columns, 0, 0, "Reorder");
}

if (!in_array("Actions", $columns)) {
array_splice($columns, 1, 0, "Actions");
if (!in_array("TreeNav", $columns)) {
array_splice($columns, 1, 0, "TreeNav");
}

if (!in_array("TreeNav", $columns)) {
array_splice($columns, 2, 0, "TreeNav");
if (!in_array("Actions", $columns)) {
array_splice($columns, 2, 0, "Actions");
}

// Insert grid state initial data
Expand Down Expand Up @@ -128,7 +127,7 @@ public function getColumnAttributes($gridField, $record, $columnName) {
// if element has no parent we need to
// know the allowed elements of the page
if (!$record->_Parent) {
$parentClasses = $this->allowedParentElements;
$parentClasses = $this->page->getAllowedPageElements();
$parentElems = array();
foreach ($parentClasses as $class) {
$parentElems[$class] = $class::$singular_name;
Expand Down Expand Up @@ -192,7 +191,10 @@ public function getColumnContent($gridField, $record, $columnName) {

return ViewableData::create()->customise(array(
"ButtonField" => $field,
"Title" => $record->i18n_singular_name(),
"ID" => $record->ID,
"UsedCount" => $record->Parents()->Count() + $record->Pages()->Count(),
"ClassName" => $record->i18n_singular_name(),
"Title" => $record->Title,
))->renderWith("GridFieldPageElement");
}

Expand All @@ -206,7 +208,60 @@ public function getColumnContent($gridField, $record, $columnName) {
);
}
$link = Controller::join_links($gridField->link(), $link);
return "<a href='$link'>Edit</a>";
$data = new ArrayData(array(
'Link' => $link
));
$editButton = $data->renderWith('GridFieldEditButton');

$classes = $record->getAllowedPageElements();
$elems = array();
foreach ($classes as $class) {
$elems[$class] = $class::$singular_name;
}
$addButton = GridField_FormAction::create(
$gridField,
"AddAction".$record->ID,
null,
null,
null
);
$addButton->setAttribute("data-allowed-elements", json_encode($elems, JSON_UNESCAPED_UNICODE));
$addButton->addExtraClass("col-actions__button add-button");
if (!count($elems)) {
$addButton->setDisabled(true);
}
$addButton->setButtonContent('<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd">
<circle fill="#488304" cx="8" cy="8" r="8"/>
<path d="M8 4v8M4 8h8" stroke="#FFF" stroke-width="2" stroke-linecap="square"/>
</g>
</svg>');

$deleteButton = GridField_FormAction::create(
$gridField,
"DeleteAction".$record->ID,
null,
null,
null
);
$deleteButton->setAttribute("data-used-count", $record->Parents()->Count() + $record->Pages()->Count());
$deleteButton->addExtraClass("col-actions__button delete-button");

$deleteButton->setButtonContent('<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd">
<circle fill="#880919" cx="8" cy="8" r="8"/>
<path d="M4 8h8" stroke="#FFF" stroke-width="2" stroke-linecap="square"/>
</g>
</svg>');

return ViewableData::create()->customise(array(
"EditButton" => $editButton,
"AddButton" => $addButton,
"DeleteButton" => $deleteButton,
"ParentID" => $record->_Parent ? $record->_Parent->ID : $this->page->ID,
))->renderWith("GridFieldPageSectionsActionColumn");

return $ret;
}
}

Expand Down
2 changes: 1 addition & 1 deletion code/PageElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function getChildrenGridField() {
->addComponent($dataColumns = new GridFieldDataColumns())
->addComponent($autoCompl)
->addComponent($addNewButton)
->addComponent(new GridFieldPageSectionsExtension($this->owner, $this->owner->getAllowedPageElements()))
->addComponent(new GridFieldPageSectionsExtension($this->owner))
->addComponent(new GridFieldDetailForm())
->addComponent(new GridFieldFooter());
$dataColumns->setFieldCasting(array('GridFieldPreview' => 'HTMLText->RAW'));
Expand Down
2 changes: 1 addition & 1 deletion code/PageSectionsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function updateCMSFields(FieldList $fields) {
->addComponent($dataColumns = new GridFieldDataColumns())
->addComponent($autoCompl)
->addComponent($addNewButton)
->addComponent(new GridFieldPageSectionsExtension($this->owner, $allowedElements))
->addComponent(new GridFieldPageSectionsExtension($this->owner))
->addComponent(new GridFieldDetailForm())
->addComponent(new GridFieldFooter());
$dataColumns = $config->getComponentByType('GridFieldDataColumns');
Expand Down
36 changes: 36 additions & 0 deletions css/GridFieldPageSectionsExtension.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@
align-items: center;
}

.cms table.ss-gridfield-table tbody td.col-treenav .col-treenav__text {
padding: 8px 8px 8px 0;
}

.cms table.ss-gridfield-table tbody td.col-treenav .col-treenav__classname {
font-size: 87%;
}

.cms table.ss-gridfield-table tbody td.col-treenav .col-treenav__title {
font-weight: bold;
}

.cms table.ss-gridfield-table tbody td.col-treenav button {
width: 2em;
height: 100%;
Expand Down Expand Up @@ -115,6 +127,30 @@
margin-left: 12em;
}

/**
* action col
*/
.cms .ss-gridfield-pagesections table.ss-gridfield-table tr td.col-actions {
width: 68px;
}

.cms .ss-gridfield-pagesections table.ss-gridfield-table tbody td.col-actions a.view-link, .cms .ss-gridfield-pagesections table.ss-gridfield-table tbody td.col-actions a.edit-link {
margin-top: -5px;
}

.cms .ss-gridfield-pagesections table.ss-gridfield-table tbody td button.col-actions__button {
margin: 2px;
}

.cms .ss-gridfield-pagesections table.ss-gridfield-table tbody td button.col-actions__button .ui-button-text {
line-height: 0;
padding: 0;
}

.cms .ss-gridfield-pagesections table.ss-gridfield-table tbody td button.col-actions__button .col-actions__button__icon svg {
display: block;
}

/**
* Orderable rows
*/
Expand Down
145 changes: 69 additions & 76 deletions javascript/GridFieldPageSectionsExtension.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,84 +18,8 @@
}
});

// Context menu click
$(document).on("click", ".treenav-menu li", function(event) {
var $this = $(this);
var $menu = $this.parents(".treenav-menu");
var $gridfield = $(".ss-gridfield-pagesections[data-id='" + $menu.data("grid-id") + "']").find("tbody");
var newType = $this.data("type");

// If we don't have a type then the user clicked a header or some random thing
if (!newType) return;

if (newType === "__REMOVE__") {
$gridfield.removeElement($menu.data("row-id"), $menu.data("parent-id"));
} else if (newType === "__DELETE__") {
if (!confirm("Are you sure you want to remove this element? All children will be orphans!"))
return;

$gridfield.deleteElement($menu.data("row-id"));
} else {
$gridfield.addElement($menu.data("row-id"), newType);
}

$this.parents(".treenav-menu").hide();
});

// Show context menu
$(".ss-gridfield-pagesections tbody").entwine({
oncontextmenu: function(event) {
$target = $(event.target);

var grid = this.getGridField();
var id = grid.data("id");
var rowId = $target.parents(".ss-gridfield-item").data("id");
var $treeNav = $target.hasClass("col-treenav") ? $target :
$target.parents(".col-treenav").first();

// If we don't have a col-treenav the user clicked on another column
if ($treeNav.length <= 0) return;
event.preventDefault();

var parentId = null;
var parentName = null;
var level = $treeNav.data("level");
if (level > 0) {
// Go up through the rows and find the first row with lower level (=parent)
$parent = $treeNav.parents(".ss-gridfield-item").prev();
while ($parent.length > 0 &&
$parent.find(".col-treenav").data("level") >= level) {
$parent = $parent.prev();
}
if ($parent != null) {
parentId = $parent.data("id");
parentName = $parent.find(".col-treenav .col-treenav__title").html();
}
}

var elems = $treeNav.data("allowed-elements");
$menu = $("<ul id='treenav-menu-" + id + "' class='treenav-menu' data-id='" + id + "'></ul>");
$menu.css({
top: event.pageY + "px",
left: event.pageX + "px"
});
$(document.body).append($menu);

$menu.data({
gridId: id,
rowId: rowId,
parentId: parentId,
});
$menu.append("<li class='header'>" + ss.i18n._t('PageSections.GridField.AddAChild','Add a child') + "</li>");
$.each(elems, function(key, value) {
$menu.append("<li data-type='" + key + "'>" + value + "</li>");
});
$menu.append("<li class='header options'>Options</li>");
$menu.append("<li data-type='__REMOVE__'>Remove from " +
(parentId ? parentName : "page") + "</li>");
$menu.append("<li data-type='__DELETE__'>Delete</li>");
$menu.show();
},
addElement: function(id, elemType) {
var grid = this.getGridField();

Expand Down Expand Up @@ -130,9 +54,78 @@
},
onadd: function() {
var grid = this.getGridField();
var thisGrid = this;

$("tr.ss-gridfield-item").each(function() {
var $this = $(this);
// actions
$this.find(".col-actions .add-button").click(function(event) {
event.preventDefault();
event.stopImmediatePropagation();
$target = $(event.target);
var elems = $target.data("allowed-elements");

var id = grid.data("id");
var rowId = $target.parents(".ss-gridfield-item").data("id");


var $menu = $("<ul id='treenav-menu-" + id + "' class='treenav-menu' data-id='" + id + "'></ul>");
$menu.css({
top: event.pageY + "px",
left: event.pageX + "px"
});
$(document.body).append($menu);

$menu.append("<li class='header'>" + ss.i18n._t('PageSections.GridField.AddAChild','Add a child') + "</li>");
$.each(elems, function(key, value) {
var $li = $("<li data-type='" + key + "'>" + value + "</li>")
$li.click(function() {
thisGrid.addElement(rowId, key);
$menu.remove();
})
$menu.append($li);
});
$menu.show();
});

$this.find(".col-actions .delete-button").click(function(event) {
event.preventDefault();
event.stopImmediatePropagation();

$target = $(event.target);

var id = grid.data("id");
var rowId = $target.parents(".ss-gridfield-item").data("id");
var parentId = $target.data("parent-id");

var $menu = $("<ul id='treenav-menu-" + id + "' class='treenav-menu' data-id='" + id + "'></ul>");
$menu.css({
top: event.pageY + "px",
left: event.pageX + "px"
});
$(document.body).append($menu);

$menu.append("<li class='header'>" + ss.i18n._t('PageSections.GridField.Delete','Delete') + "</li>");

var $li = $("<li data-type='__REMOVE__'>" + ss.i18n._t('PageSections.GridField.RemoveAChild','Remove') + "</li>")
$li.click(function() {
thisGrid.removeElement(rowId, $menu.data("parent-id"));
$menu.remove();
})
$menu.append($li);
if ($target.data("used-count") < 2) {
var $li = $("<li>" + ss.i18n._t('PageSections.GridField.DeleteAChild','Finally delete') + "</li>")
$li.click(function() {
thisGrid.deleteElement(rowId, $menu.data("parent-id"));
$menu.remove();
})
$menu.append($li);
}

$menu.show();
});

// reorder
var icon = "<svg width='20' height='15' xmlns='http://www.w3.org/2000/svg'><path d='M10.957 10.882v2.367a1.21 1.21 0 0 1-1.905.988l-8.54-6.02a1.21 1.21 0 0 1 0-1.976l8.54-6.02a1.21 1.21 0 0 1 1.906.988v2.418h7.254c.668 0 1.21.542 1.21 1.21v4.836a1.21 1.21 0 0 1-1.21 1.209h-7.255z' fill='#4A4A4A' fill-rule='evenodd'/></svg>"

$col = $this.find(".col-reorder");
Expand Down
15 changes: 9 additions & 6 deletions javascript/lang/de.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') {
if (typeof(console) !== 'undefined') { // eslint-disable-line no-console
console.error('Class ss.i18n not defined'); // eslint-disable-line no-console
}
if (typeof(console) !== 'undefined') { // eslint-disable-line no-console
console.error('Class ss.i18n not defined'); // eslint-disable-line no-console
}
} else {
ss.i18n.addDictionary('en', {
"GridField.AddAChild": "Unterelement hinzufügen",
});
ss.i18n.addDictionary('en', {
"PageSections.GridField.AddAChild": "Unterelement hinzufügen",
"PageSections.GridField.Delete": "Löschen",
"PageSections.GridField.DeleteAChild": "Endgültig löschen",
"PageSections.GridField.RemoveAChild": "Entfernen",
});
}
7 changes: 5 additions & 2 deletions javascript/lang/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ if (typeof(ss) === 'undefined' || typeof(ss.i18n) === 'undefined') {
}
} else {
ss.i18n.addDictionary('en', {
"PageSections.GridField.AddAChild": "Add a child",
});
"PageSections.GridField.AddAChild": "Add a child",
"PageSections.GridField.Delete": "Delete",
"PageSections.GridField.DeleteAChild": "Finally delete",
"PageSections.GridField.RemoveAChild": "Remove",
});
}
11 changes: 8 additions & 3 deletions templates/GridFieldPageElement.ss
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<div class="col-treenav__inner">
$ButtonField
<span class="col-treenav__title">
$Title
</span>
<div class="col-treenav__text">
<div class="col-treenav__classname">
$ClassName (ID: {$ID}, {$UsedCount}x)
</div>
<div class="col-treenav__title">
$Title
</div>
</div>
</div>
5 changes: 5 additions & 0 deletions templates/GridFieldPageSectionsActionColumn.ss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div class="col-actions__inner">
$AddButton
$DeleteButton
$EditButton
</div>

0 comments on commit b3209ad

Please sign in to comment.