Skip to content

Commit

Permalink
Add various extension points for security updates
Browse files Browse the repository at this point in the history
In order to display information from
`bringyourownideas/silverstripe-composer-security-updates` we need to be
able to add various information to the summary, and badges which were
previously 'not a thing'. This commit makes badges 'a thing', makes them
extensible, and provides a rudimentary way to alter the summary
information for the on scren report.

Also added were namespaces for the GridFieldComponents, but this should
affect nothing (should not affect anything).
  • Loading branch information
Dylan Wagstaff committed May 30, 2018
1 parent d4cdf17 commit 3e724b2
Show file tree
Hide file tree
Showing 14 changed files with 305 additions and 96 deletions.
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

[*{.yml,.js}]
indent_size = 2
indent_style = space

[{*.yml,package.json}]
indent_size = 2

Expand Down
68 changes: 43 additions & 25 deletions css/sitesummary.css
Original file line number Diff line number Diff line change
@@ -1,44 +1,62 @@
.package-summary{
margin-top: 0;
.site-summary {
margin-top: 0;
}

.package-summary .message {
margin-left: 0;
margin-right: 0;
margin-top: 0;
.site-summary.message,
.site-summary .message {
margin-left: 0;
margin-right: 0;
margin-top: 0;
}

.package-summary .grid-refresh-button {
margin-bottom: 0;
}

.package-summary__title {
display:block;
.site-summary .grid-refresh-button {
margin-bottom: 0;
}

/* Due to a rule applied to `.cms .ss-gridfield > div` we have to be specific here */
.cms .ss-gridfield > div.site-summary__clearfix {
margin: 0;
clear: both;
margin: 0;
clear: both;
}

.gridfield-button-link {
margin-bottom: 12px;
}

.package-summary table.ss-gridfield-table tr td.col-Summary {
padding: 0;
margin-bottom: 12px;
}

a.package-summary__anchor {
color: inherit;
text-decoration: inherit;
display: block;
padding: 8px;
color: inherit;
text-decoration: inherit;
display: block;
padding: 0 8px;
margin: 0 -8px;
}

a.package-summary__anchor:hover,
a.package-summary__anchor:active {
color: inherit;
text-decoration: inherit;
color: inherit;
text-decoration: inherit;
}

.package-summary__badge {
font-size: 0.8em;
padding: 3px 5px;
background: grey;
border-radius: 2px;
color: white;
position: relative;
top: -1px;
}
/* Colours for badge classes */
.package-summary__badge--good {
background: #3fa142;
}
.package-summary__badge--warning {
background: #ff7f22;
}
.package-summary__badge--bad {
background: #d40404;
}

.package-summary__description {
display:block;
}
124 changes: 62 additions & 62 deletions javascript/CheckForUpdates.js
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
(function ($) {
$.entwine('ss', function ($) {
// p tag that holds button
$('#checkForUpdates').entwine({
// Magically set by the magic get/set{thisMemberProperty} (see poll function below)
PollTimeout: null,
onclick: function () {
this.setLoading();
},
onmatch: function () {
// Poll the current job and update the front end status
if (this.getButton(true).length) {
this.setLoading();
}
},
setLoading: function () {
// Add warning message (set as data attribute on GridFieldRefreshButton) before
// first button row
$('.ss-gridfield-buttonrow').first().prepend(
'<p class="message warning">' +
this.getButton().data('message') +
'</p>'
);
this.poll();
},
poll: function () {
var self = this;
$.ajax({
url: self.getButton().data('check'),
async: true,
success: function (data) {
self.clearLoading(JSON.parse(data));
},
error: function (error) {
if (typeof console !== 'undefined') {
console.log(error);
}
}
});
},
getButton: function (disabled) {
let button = 'button';
if (disabled) {
button += ':disabled';
}
return this.children(button).first();
},
clearLoading: function (hasRunningJob) {
$.entwine('ss', function ($) {
// p tag that holds button
$('#checkForUpdates').entwine({
// Magically set by the magic get/set{thisMemberProperty} (see poll function below)
PollTimeout: null,
onclick: function () {
this.setLoading();
},
onmatch: function () {
// Poll the current job and update the front end status
if (this.getButton(true).length) {
this.setLoading();
}
},
setLoading: function () {
// Add warning message (set as data attribute on GridFieldRefreshButton) before
// first button row
$('.ss-gridfield-buttonrow').first().prepend(
'<p class="message warning">' +
this.getButton().data('message') +
'</p>'
);
this.poll();
},
poll: function () {
var self = this;
$.ajax({
url: self.getButton().data('check'),
async: true,
success: function (data) {
self.clearLoading(JSON.parse(data));
},
error: function (error) {
if (typeof console !== 'undefined') {
console.log(error);
}
}
});
},
getButton: function (disabled) {
let button = 'button';
if (disabled) {
button += ':disabled';
}
return this.children(button).first();
},
clearLoading: function (hasRunningJob) {

if (hasRunningJob === false) {
this.closest('fieldset.ss-gridfield').reload();
return;
}
if (hasRunningJob === false) {
this.closest('fieldset.ss-gridfield').reload();
return;
}

// Ensure the regular poll method is run
// Kill any existing timeout
clearTimeout(this.getPollTimeout());
// Ensure the regular poll method is run
// Kill any existing timeout
clearTimeout(this.getPollTimeout());

this.setPollTimeout(setTimeout(
function () {
$('#checkForUpdates').poll();
},
5000
));
}
});
this.setPollTimeout(setTimeout(
function () {
$('#checkForUpdates').poll();
},
5000
));
}
});
});
}(jQuery));
5 changes: 4 additions & 1 deletion src/Forms/GridFieldHtmlFragment.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
<?php

namespace BringYourOwnIdeas\Maintenance\Forms;

use GridField_HTMLProvider;

/**
* Facilitates adding arbitrary HTML to grid fields
*
* @package forms
* @subpackage fields-gridfield
*/

class GridFieldHtmlFragment implements GridField_HTMLProvider
{
/**
Expand Down
8 changes: 6 additions & 2 deletions src/Forms/GridFieldLinkButton.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
<?php

namespace BringYourOwnIdeas\Maintenance\Forms;

use ArrayData;
use GridField_HTMLProvider;

/**
* A button that contains a link to an URL.
*
* @package forms
* @subpackage fields-gridfield
*/

class GridFieldLinkButton implements GridField_HTMLProvider
{
/**
Expand Down Expand Up @@ -43,7 +47,7 @@ public function getHTMLFragments($gridField)
$fragment = ArrayData::create([
'Link' => $this->link,
'Caption' => _t('GridFieldLinkButton.LINK_TO_ADDONS', 'Explore Addons')
])->renderWith(__CLASS__);
])->renderWith('GridFieldLinkButton');

return [$this->targetFragment => $fragment];
}
Expand Down
21 changes: 19 additions & 2 deletions src/Forms/GridFieldRefreshButton.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
<?php

namespace BringYourOwnIdeas\Maintenance\Forms;

use ArrayData;
use CheckForUpdatesJob;
use Convert;
use GridField;
use GridField_ActionProvider;
use GridField_FormAction;
use GridField_HTMLProvider;
use GridField_URLHandler;
use Injector;
use QueuedJob;
use QueuedJobService;
use Requirements;

/**
* Adds a "Refresh" button to the bottom or top of a GridField.
*
* @package forms
* @subpackage fields-gridfield
*/

class GridFieldRefreshButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler
{
/**
Expand Down Expand Up @@ -60,7 +75,9 @@ public function getHTMLFragments($gridField)
}

return [
$this->targetFragment => ArrayData::create(['Button' => $button->Field()])->renderWith(__CLASS__)
$this->targetFragment => ArrayData::create([
'Button' => $button->Field()
])->renderWith('GridFieldRefreshButton')
];
}

Expand Down
60 changes: 59 additions & 1 deletion src/Model/Package.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ class Package extends DataObject
'Version' => 'Version',
];

/**
* @var array badge definitions - a keyed array in the format of [Title => Type] {@see getBadges()}
*/
protected $badges = [];

/**
* Strips vendor and 'silverstripe-' prefix from Name property
* @return string More easily digestable module name for human consumers
Expand All @@ -34,7 +39,60 @@ public function getTitle()
*/
public function getSummary()
{
return $this->renderWith('Package_summary');
$summary = $this->renderWith('Package_summary');
$this->extend('updateSummary', $summary);
return $summary;
}

/**
* Gives the summary template {@see getSummary()} a list of badges to show against a package
*
* badgeDefinitions are in the format [$title => $type] where:
* title is the unique string to display
* type is an optional class attribute (applied as a BEM modifier, by default)
*
* @return ArrayList
*/
public function getBadges()
{
$badgeDefinitions = $this->badges;
$badges = ArrayList::create();
foreach ($badgeDefinitions as $title => $type) {
$badges->push(ArrayData::create([
'Title' => $title,
'Type' => $type,
]));
}

$this->extend('updateBadges', $badgeDefinitions);
return $badges;
}

/**
* Adds a badge to the list of badges {@see $badges}
*
* @param string $title
* @param string $type
*
* @return $this
*/
public function addBadge($title, $type)
{
$this->badges[$title] = $type;
return $this;
}

/**
* Replaces the list of badges
*
* @param array $badges {@see $badges}
*
* @return $this
*/
public function setBadges($badges)
{
$this->badges = $badges;
return $this;
}

/**
Expand Down
Loading

0 comments on commit 3e724b2

Please sign in to comment.