View source
<?php
namespace Drupal\gridstack_ui\Controller;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Url;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Config\Entity\DraggableListBuilder;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Symfony\Component\DependencyInjection\ContainerInterface;
class GridStackListBuilder extends DraggableListBuilder {
protected $currentUser;
protected $manager;
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
$instance = new static($entity_type, $container
->get('entity_type.manager')
->getStorage($entity_type
->id()));
$instance->currentUser = $container
->get('current_user');
$instance->manager = $container
->get('gridstack.manager');
return $instance;
}
public function getFormId() {
return 'gridstack_list_form';
}
public function buildHeader() {
$header = [
'label' => $this
->t('Optionset'),
'id' => $this
->t('ID'),
'icon' => $this
->t('Icon'),
'framework' => $this
->t('Grid framework'),
'grids' => $this
->t('Grids : Nested'),
'provider' => $this
->t('Provider'),
];
return $header + parent::buildHeader();
}
public function buildRow(EntityInterface $entity) {
$icon_uri = $entity
->getIconUri();
$manager = $this->manager;
$framework = $manager
->configLoad('framework', 'gridstack.settings');
$use_framework = $framework && $entity
->getOption('use_framework');
$row['label'] = Html::escape($entity
->label());
$row['id'] = [
'#markup' => $entity
->id(),
];
$row['icon'] = [];
$row['framework'] = [];
$token_query = [
IMAGE_DERIVATIVE_TOKEN => time(),
];
$image_url = file_url_transform_relative(file_create_url($icon_uri));
$image_url .= (strpos($image_url, '?') !== FALSE ? '&' : '?') . UrlHelper::buildQuery($token_query);
if ($description = $entity
->description()) {
$row['label'] .= '<br><small>' . $description . '</small>';
}
if (!empty($icon_uri)) {
$row['icon'] = [
'#theme' => 'blazy',
'#settings' => [
'uri' => $icon_uri,
'lazy' => 'blazy',
'image_url' => $image_url,
],
'#item_attributes' => [
'width' => 140,
],
];
}
$row['framework']['#markup'] = $use_framework ? ucwords($framework) : 'GridStack/ Native';
$grids = $entity
->getLastBreakpoint();
$nested = $entity
->getLastBreakpoint('nested');
$nested = array_filter($nested);
$counts = [];
if (!empty($nested)) {
foreach ($nested as $grid) {
if (empty($grid)) {
continue;
}
if (is_string($grid)) {
$grid = Json::decode($grid);
}
$boxes = [];
foreach ($grid as $item) {
if (!isset($item['width'])) {
continue;
}
$boxes[] = $item['width'];
}
$counts = NestedArray::mergeDeep($counts, $boxes);
}
}
$nested_grids = empty($nested) ? '0' : count($counts);
$row['grids']['#markup'] = $this
->t('@grids : @nested', [
'@grids' => count($grids),
'@nested' => $nested_grids,
]);
$dependencies = $entity
->getDependencies();
$row['provider']['#markup'] = isset($dependencies['module'][0]) ? $dependencies['module'][0] : 'gridstack';
return $row + parent::buildRow($entity);
}
public function getDefaultOperations(EntityInterface $entity) {
$operations = parent::getDefaultOperations($entity);
if (isset($operations['edit'])) {
$operations['edit']['title'] = $this
->t('Configure');
}
$operations['duplicate'] = [
'title' => $this
->t('Duplicate'),
'weight' => 15,
'url' => $entity
->toUrl('duplicate-form'),
];
$defaults = [
'bootstrap',
'default',
'foundation',
'frontend',
];
if (in_array($entity
->id(), $defaults)) {
unset($operations['delete'], $operations['edit']);
}
return $operations;
}
public function render() {
$build['description'] = [
'#markup' => '<p>' . $this
->t("Manage the GridStack optionsets. Optionsets are Config Entities. Use the Operations column to edit, clone and delete optionsets.<br><br>By default, four default optionsets are created: <code>Admin, Frontend, Bootstrap, Foundation</code>. GridStack supports both one-dimensional layouts like Bootstrap, Foundation, etc. (<a href=':ui'>enable here</a>), and two-dimensional layouts via GridStack JS or native browser CSS Grid Layout, and Masonry, Packery, Isotope via <a href=':outlayer'>Outlayer</a> module. To generate icons, edit and save optionsets.<br><strong>Important!</strong><br>Avoid overriding default or sample optionsets. Any customization will be lost at the next update. Use <code>Duplicate</code> button instead, unless a module declares direct usages. <br>Use <a href=':url'>config_update</a> module to revert to stored optionsets at <code>/admin/config/development/configuration/report/module/gridstack</code>, if needed. Clearing cache is required to register the new layouts for Layout Discovery/ Layout Builder.", [
':ui' => Url::fromRoute('gridstack.settings')
->toString(),
':url' => '//drupal.org/project/config_update',
':outlayer' => '//drupal.org/project/outlayer',
]) . '</p>',
];
$build[] = parent::render();
$attachments = $this->manager
->attach([
'blazy' => TRUE,
]);
$build['#attached'] = isset($build['#attached']) ? NestedArray::mergeDeep($build['#attached'], $attachments) : $attachments;
$build['#attached']['library'][] = 'gridstack/admin';
return $build;
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form['#attributes']['class'][] = 'blazy';
$form['#attributes']['data-blazy'] = '';
return parent::buildForm($form, $form_state);
}
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$this
->messenger()
->addMessage($this
->t('The optionsets order has been updated.'));
}
}