diff --git a/core/modules/system/src/Form/ModulesListForm.php b/core/modules/system/src/Form/ModulesListForm.php
index 5f85624..f0b2853 100644
--- a/core/modules/system/src/Form/ModulesListForm.php
+++ b/core/modules/system/src/Form/ModulesListForm.php
@@ -7,6 +7,7 @@
namespace Drupal\system\Form;
+use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Controller\TitleResolverInterface;
@@ -195,19 +196,22 @@ public function buildForm(array $form, FormStateInterface $form_state) {
// Add a wrapper around every package.
foreach (Element::children($form['modules']) as $package) {
- $form['modules'][$package] += array(
- '#type' => 'details',
- '#title' => $this->t($package),
- '#open' => TRUE,
- '#theme' => 'system_modules_details',
+ $table = array(
+ '#type' => 'table',
'#header' => array(
array('data' => $this->t('Installed'), 'class' => array('checkbox', 'visually-hidden')),
array('data' => $this->t('Name'), 'class' => array('name', 'visually-hidden')),
array('data' => $this->t('Description'), 'class' => array('description', 'visually-hidden', RESPONSIVE_PRIORITY_LOW)),
),
- '#attributes' => array('class' => array('package-listing')),
+ ) + $form['modules'][$package];
+ $form['modules'][$package] = array(
+ '#type' => 'details',
+ '#title' => $this->t($package),
+ '#open' => TRUE,
// Ensure that the "Core" package comes first.
'#weight' => $package == 'Core' ? -10 : NULL,
+ '#attributes' => ['class' => ['package-listing']],
+ 'table' => $table,
);
}
@@ -244,31 +248,33 @@ public function buildForm(array $form, FormStateInterface $form_state) {
*/
protected function buildRow(array $modules, Extension $module, $distribution) {
// Set the basic properties.
- $row['#required'] = array();
+ $row['#version'] = $module->info['version'];
$row['#requires'] = array();
$row['#required_by'] = array();
- $row['name']['#markup'] = $module->info['name'];
- $row['description']['#markup'] = $this->t($module->info['description']);
- $row['version']['#markup'] = $module->info['version'];
-
// Generate link for module's help page, if there is one.
- $row['links']['help'] = array();
+ $row_links['help'] = array();
if ($this->moduleHandler->moduleExists('help') && $module->status && in_array($module->getName(), $this->moduleHandler->getImplementations('help'))) {
if ($this->moduleHandler->invoke($module->getName(), 'help', array('help.page.' . $module->getName(), $this->routeMatch))) {
- $row['links']['help'] = array(
+ $row_links['help'] = array(
'#type' => 'link',
'#title' => $this->t('Help'),
'#url' => Url::fromRoute('help.page', ['name' => $module->getName()]),
- '#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => $this->t('Help'))),
+ '#options' => array(
+ 'attributes' => array(
+ 'id' => 'edit-modules-core-' . $module->getName() . '-links-help',
+ 'class' => ['module-link', 'module-link-help'],
+ 'title' => $this->t('Help'),
+ ),
+ ),
);
}
}
// Generate link for module's permission, if the user has access to it.
- $row['links']['permissions'] = array();
+ $row_links['permissions'] = array();
if ($module->status && \Drupal::currentUser()->hasPermission('administer permissions') && in_array($module->getName(), $this->moduleHandler->getImplementations('permission'))) {
- $row['links']['permissions'] = array(
+ $row_links['permissions'] = array(
'#type' => 'link',
'#title' => $this->t('Permissions'),
'#url' => Url::fromRoute('user.admin_permissions'),
@@ -277,7 +283,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) {
}
// Generate link for module's configuration page, if it has one.
- $row['links']['configure'] = array();
+ $row_links['configure'] = array();
if ($module->status && isset($module->info['configure'])) {
$route_parameters = isset($module->info['configure_parameters']) ? $module->info['configure_parameters'] : array();
if ($this->accessManager->checkNamedRoute($module->info['configure'], $route_parameters, $this->currentUser)) {
@@ -299,7 +305,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) {
$description = $this->titleResolver->getTitle($request, $route_object);
}
- $row['links']['configure'] = array(
+ $row_links['configure'] = array(
'#type' => 'link',
'#title' => $this->t('Configure'),
'#url' => Url::fromRoute($module->info['configure'], $route_parameters),
@@ -316,7 +322,7 @@ protected function buildRow(array $modules, Extension $module, $distribution) {
// Present a checkbox for installing and indicating the status of a module.
$row['enable'] = array(
'#type' => 'checkbox',
- '#title' => $this->t('Install'),
+ '#wrapper_attributes' => ['class' => ['checkbox']],
'#default_value' => (bool) $module->status,
'#disabled' => (bool) $module->status,
);
@@ -410,6 +416,63 @@ protected function buildRow(array $modules, Extension $module, $distribution) {
}
}
+ // Set id for checkbox here so module label can reference it.
+ $id = Html::getClass('edit-modules-' . $module->info['package'] . '-' . $module->getName() . '-enable');
+
+ $row['enable'] += array(
+ '#id' => $id,
+ '#parents' => ['modules', $module->info['package'], $module->getName(), 'enable'],
+ );
+
+ // Add the module label and expand/collapse functionality.
+ $row['name'] = array(
+ '#type' => 'inline_template',
+ '#template' => '',
+ '#context' => array(
+ 'machine_name' => $module->getName(),
+ 'label_id' => $id,
+ 'module_name' => $module->info['name'],
+ ),
+ '#wrapper_attributes' => ['class' => ['module']],
+ );
+
+ // Add the description, along with any modules it requires.
+ $description = '';
+ $description .= '
';
+ $description .= '
' . $this->t('Machine name: !key', array('!key' => $module->getName())) . '
';
+ if ($module->info['version'] || $row['#requires'] || $row['#required_by']) {
+ if ($module->info['version']) {
+ $description .= '
' . $this->t('Version: !module-version', array('!module-version' => $module->info['version'])) . '
';
+ }
+ if ($row['#requires']) {
+ $description .= '
' . $this->t('Requires: !module-list', array('!module-list' => implode(', ', $row['#requires']))) . '
';
+ }
+ if ($row['#required_by']) {
+ $description .= '
' . $this->t('Required by: !module-list', array('!module-list' => implode(', ', $row['#required_by']))) . '
';
+ }
+ }
+ $description .= '
';
+
+ $links = '';
+ foreach (['help', 'permissions', 'configure'] as $key) {
+ $links .= (isset($row_links[$key]) ? drupal_render($row_links[$key]) : '');
+ }
+
+ if ($links) {
+ $description .= ' ';
+ $description .= $links;
+ $description .= '
';
+ }
+
+ $row['description'] = array(
+ '#type' => 'details',
+ '#title' => $this->t(' ' . $module->info['description'] . ''),
+ '#attributes' => array('id' => $id . '-description'),
+ '#description' => $description,
+ '#collapsed' => TRUE,
+ '#wrapper_attributes' => ['class' => ['description', 'expand']]
+ );
+
return $row;
}
@@ -442,6 +505,7 @@ protected function buildModuleList(FormStateInterface $form_state) {
// First, build a list of all modules that were selected.
foreach ($packages as $items) {
+ unset($items['table']);
foreach ($items as $name => $checkbox) {
if ($checkbox['enable'] && !$this->moduleHandler->moduleExists($name)) {
$modules['install'][$name] = $data[$name]->info['name'];
diff --git a/core/modules/system/src/Form/ModulesUninstallForm.php b/core/modules/system/src/Form/ModulesUninstallForm.php
index 4285956..6b20ef0 100644
--- a/core/modules/system/src/Form/ModulesUninstallForm.php
+++ b/core/modules/system/src/Form/ModulesUninstallForm.php
@@ -98,7 +98,22 @@ public function buildForm(array $form, FormStateInterface $form_state) {
),
);
- $form['modules'] = array();
+ $profile = drupal_get_profile();
+
+ // Sort all modules by their name.
+ if(!empty($uninstallable)) {
+ uasort($uninstallable, 'system_sort_modules_by_info_name');
+ }
+
+ $form['uninstall'] = array(
+ '#type' => 'table',
+ '#header' => array(
+ 'title' => array('data' => $this->t('Name')),
+ 'description' => array('data' => $this->t('Description')),
+ ),
+ '#empty' => $this->t('There are no items available to uninstall.'),
+ '#tableselect' => TRUE,
+ );
// Only build the rest of the form if there are any modules available to
// uninstall;
@@ -106,34 +121,40 @@ public function buildForm(array $form, FormStateInterface $form_state) {
return $form;
}
- $profile = drupal_get_profile();
-
- // Sort all modules by their name.
- uasort($uninstallable, 'system_sort_modules_by_info_name');
-
- $form['uninstall'] = array('#tree' => TRUE);
foreach ($uninstallable as $module) {
- $name = $module->info['name'] ?: $module->getName();
- $form['modules'][$module->getName()]['#module_name'] = $name;
- $form['modules'][$module->getName()]['name']['#markup'] = $name;
- $form['modules'][$module->getName()]['description']['#markup'] = $this->t($module->info['description']);
-
- $form['uninstall'][$module->getName()] = array(
- '#type' => 'checkbox',
- '#title' => $this->t('Uninstall @module module', array('@module' => $name)),
- '#title_display' => 'invisible',
+ // Define