Commit 31c604da authored by Gábor Hojtsy's avatar Gábor Hojtsy
Browse files

Issue #3165122 by Gábor Hojtsy: Add summary at the top with Analyze/Act/Relax columns

parent 2775422b
......@@ -11,6 +11,23 @@
margin-right: 0;
}
.upgrade-status-overview tr:hover {
color: inherit;
background-color: inherit;
}
.upgrade-status-overview th {
background-color: #f5f5f2;
border-bottom: 1px solid #ccc;
width: 33%;
}
.upgrade-status-overview td {
vertical-align: top;
}
.upgrade-status-overview td .item-list ul li {
list-style-type: none;
margin-left: 0;
}
.upgrade-status-summary > summary,
.upgrade-status-summary-environment > summary {
background-color: #f5f5f2;
......@@ -125,6 +142,29 @@
margin-bottom: 1em;
}
.upgrade-status-summary-label {
padding: 3px 5px;
border-radius: 3px;
white-space: nowrap;
}
.upgrade-status-summary-label-relax {
background-color: #f3faef;
color: #325e1c;
}
.upgrade-status-summary-label-update,
.upgrade-status-summary-label-remove {
background-color: #fdf8ed;
color: #734c00;
}
.upgrade-status-summary-label-rector,
.upgrade-status-summary-label-manual {
background-color: #fcf4f2;
color: #a51b00;
}
.upgrade-status-summary-label-collaborate {
background-color: #f0f8ff;
color: #000;
}
.upgrade-status-ok-label,
.upgrade-status-error-label {
......
......@@ -191,25 +191,7 @@ class UpgradeStatusForm extends FormBase {
$this->messenger()->addError($e->getMessage());
}
$last = $this->state->get('update.last_check') ?: 0;
if ($last == 0) {
$last_checked = '<strong>' . $this->t('Available update data not available.') . '</strong>';
}
else {
$time = $this->dateFormatter->formatTimeDiffSince($last);
$last_checked = $this->t('Available update data last checked: @time ago.', ['@time' => $time]);
}
$form['update_time'] = [
[
'#type' => 'markup',
'#markup' => $last_checked . ' ',
],
[
'#type' => 'link',
'#title' => '(' . $this->t('Check manually') . ')',
'#url' => Url::fromRoute('update.manual_status', [], ['query' => $this->destination->getAsArray()]),
],
];
$form['summary'] = $this->buildResultSummary();
$form['environment'] = [
'#type' => 'details',
......@@ -462,6 +444,90 @@ class UpgradeStatusForm extends FormBase {
return $build;
}
/**
* Build a result summary table for quick overview display to users.
*/
protected function buildResultSummary() {
$projects = $this->projectCollector->collectProjects();
$next_steps = $this->projectCollector->getNextStepInfo();
$last = $this->state->get('update.last_check') ?: 0;
if ($last == 0) {
$last_checked = '<strong>' . $this->t('Never checked.') . '</strong>';
}
else {
$time = $this->dateFormatter->formatTimeDiffSince($last);
$last_checked = $this->t('Last checked @time ago.', ['@time' => $time]);
}
$update_time = [
[
'#type' => 'link',
'#title' => $this->t('Check available updates.'),
'#url' => Url::fromRoute('update.manual_status', [], ['query' => $this->destination->getAsArray()]),
],
[
'#type' => 'markup',
'#markup' => ' ' . $last_checked,
],
];
$header = [
ProjectCollector::SUMMARY_ANALYZE => ['data' => $this->t('Analyze'), 'class' => 'summary-' . ProjectCollector::SUMMARY_ANALYZE],
ProjectCollector::SUMMARY_ACT => ['data' => $this->t('Act'), 'class' => 'status-' . ProjectCollector::SUMMARY_ACT],
ProjectCollector::SUMMARY_RELAX => ['data' => $this->t('Relax'), 'class' => 'status-' . ProjectCollector::SUMMARY_RELAX],
];
$build = [
'#type' => 'table',
'#attributes' => ['class' => ['upgrade-status-overview']],
'#header' => $header,
'#rows' => [
[
'data' => [
ProjectCollector::SUMMARY_ANALYZE => ['data' => []],
ProjectCollector::SUMMARY_ACT => ['data' => []],
ProjectCollector::SUMMARY_RELAX => ['data' => []],
]
]
],
];
foreach ($header as $key => $value) {
$cell_data = $cell_items = [];
if ($key == ProjectCollector::SUMMARY_ANALYZE) {
$cell_items[] = $update_time;
}
foreach($next_steps as $next_step => $step_label) {
// If this next step summary belongs in this table cell, collect it.
if ($step_label[2] == $key) {
foreach ($projects as $name => $project) {
if ($project->info['upgrade_status_next'] == $next_step) {
$cell_data[$next_step]++;
}
}
}
}
if (count($cell_data)) {
foreach ($cell_data as $next_step => $count) {
$cell_items[] = [
'#markup' => '<a href="#edit-' . $next_step . '" class="upgrade-status-summary-label upgrade-status-summary-label-' . $next_step . '">' . $this->formatPlural($count, '@type: 1 project', '@type: @count projects', ['@type' => $next_steps[$next_step][0]]) . '</a>',
];
}
}
if (count($cell_items)) {
$build['#rows'][0]['data'][$key]['data'] = [
'#theme' => 'item_list',
'#items' => $cell_items,
];
}
else {
$build['#rows'][0]['data'][$key]['data'] = [
'#type' => 'markup',
'#markup' => $this->t('N/A'),
];
}
}
return $build;
}
/**
* Builds a list of environment checks.
*
......
......@@ -123,6 +123,21 @@ class ProjectCollector {
*/
const NEXT_MANUAL = 'manual';
/**
* Summary category for things to analyze.
*/
const SUMMARY_ANALYZE = 'analyze';
/**
* Summary category for things to act on.
*/
const SUMMARY_ACT = 'act';
/**
* Summary category for things to act on.
*/
const SUMMARY_RELAX = 'relax';
/**
* Constructs a \Drupal\upgrade_status\ProjectCollector.
*
......@@ -407,25 +422,39 @@ class ProjectCollector {
public function getNextStepInfo() {
return [
ProjectCollector::NEXT_REMOVE => [
$this->t('Remove projects'), $this->t('The likely best action is to remove projects that are uninstalled. Why invest in updating them to be compatible if you are not using them?'),
$this->t('Remove'),
$this->t('The likely best action is to remove projects that are uninstalled. Why invest in updating them to be compatible if you are not using them?'),
ProjectCollector::SUMMARY_ACT,
],
ProjectCollector::NEXT_UPDATE => [
$this->t('Update projects'), $this->t('There is an update available. Even if that is not fully Drupal 9 compatible, it may be more compatible than what you have, so best to start with updating first.'),
$this->t('Update'),
$this->t('There is an update available. Even if that is not fully Drupal 9 compatible, it may be more compatible than what you have, so best to start with updating first.'),
ProjectCollector::SUMMARY_ACT,
],
ProjectCollector::NEXT_SCAN => [
$this->t('Scan projects'), $this->t('Status of this project cannot be determined without scanning the source code here. Use this form to run a scan on these.'),
$this->t('Scan'),
$this->t('Status of this project cannot be determined without scanning the source code here. Use this form to run a scan on these.'),
ProjectCollector::SUMMARY_ANALYZE,
],
ProjectCollector::NEXT_COLLABORATE => [
$this->t('Collaborate with project maintainers'), $this->t('There are likely Drupal.org issues by contributors or even <a href=":drupal-bot">the Project Update Bot</a>. Work with the maintainer to get them committed, provide feedback if they worked.', [':drupal-bot' => 'https://www.drupal.org/u/project-update-bot']),
$this->t('Collaborate with maintainers'),
$this->t('There are likely Drupal.org issues by contributors or even <a href=":drupal-bot">the Project Update Bot</a>. Work with the maintainer to get them committed, provide feedback if they worked.', [':drupal-bot' => 'https://www.drupal.org/u/project-update-bot']),
ProjectCollector::SUMMARY_ACT,
],
ProjectCollector::NEXT_RECTOR => [
$this->t('Fix projects with rector'), $this->t('Some or all problems found can be fixed automatically with <a href=":drupal-rector">drupal-rector</a>. Make the machine do the work.', [':drupal-rector' => 'https://www.drupal.org/project/rector']),
$this->t('Fix with rector'),
$this->t('Some or all problems found can be fixed automatically with <a href=":drupal-rector">drupal-rector</a>. Make the machine do the work.', [':drupal-rector' => 'https://www.drupal.org/project/rector']),
ProjectCollector::SUMMARY_ACT,
],
ProjectCollector::NEXT_MANUAL => [
$this->t('Fix projects manually'), $this->t('It looks like there is no automated fixes for either problems found. Check the report for pointers on how to fix.'),
$this->t('Fix manually'),
$this->t('It looks like there is no automated fixes for either problems found. Check the report for pointers on how to fix.'),
ProjectCollector::SUMMARY_ACT,
],
ProjectCollector::NEXT_RELAX => [
$this->t('Relax'), $this->t('Already Drupal 9 compatible. Congrats!'),
$this->t('Drupal 9 compatible'),
$this->t('Well done. Congrats! Let\'s get everything else here!'),
ProjectCollector::SUMMARY_RELAX,
],
];
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment