Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/en/configuring.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,23 @@ php-censor:
port: 389
base_dn: 'dc=php-censor,dc=local'
mail_attribute: mail
dashboard_widgets:
all_projects:
side: left
last_builds:
side: right
```

Dashboard widgets
-----------------

* `all_projects` - all projects build status
* `last_builds` - last builds
* `build_errors` - not successful builds

Each widget can be located in the left or right column, use the `side` option for this:

```yml
all_projects:
side: left
```
21 changes: 21 additions & 0 deletions public/assets/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -599,3 +599,24 @@ h6,
.timeline > .time-label > span {
padding: 4px 8px;
}

.loader {
margin: 10px auto;
border: 8px solid #f3f3f3;
border-radius: 50%;
border-top: 8px solid #8AA4AF;
width: 32px;
height: 32px;
-webkit-animation: spin 1s linear infinite;
animation: spin 1s linear infinite;
}

@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
34 changes: 1 addition & 33 deletions public/assets/js/app.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var PHPCensor = {
intervals: {},
widgets: {},

init: function () {
$(document).ready(function () {
Expand All @@ -11,11 +12,6 @@ var PHPCensor = {
if (typeof PROJECT_ID != 'undefined') {
PHPCensor.intervals.getProjectBuilds = setInterval(PHPCensor.getProjectBuilds, 10000);
}

if (typeof DASHBOARD != 'undefined') {
PHPCensor.intervals.getDashboard = setInterval(PHPCensor.getDashboard, 10000);
PHPCensor.intervals.getTimeline = setInterval(PHPCensor.getTimeline, 10000);
}
});

$(window).on('builds-updated', function (e, data) {
Expand Down Expand Up @@ -47,34 +43,6 @@ var PHPCensor = {
});
},

getDashboard: function () {
$('.project-box').each(function (index) {
var projectId = this.id.substring(12);

$.ajax({
url: APP_URL + 'project/ajax-dashboard-project/' + projectId,

success: function (data) {
$(('#project-box-' + projectId)).html(data);
},

error: PHPCensor.handleFailedAjax
});
});
},

getTimeline: function () {
$.ajax({
url: APP_URL + 'build/ajax-timeline',

success: function (data) {
$('#timeline-box').html(data);
},

error: PHPCensor.handleFailedAjax
});
},

updateHeaderBuilds: function (data) {
$('.app-pending-list').empty();
$('.app-running-list').empty();
Expand Down
40 changes: 40 additions & 0 deletions public/assets/js/dashboard-widgets/all_projects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
PHPCensor.widgets.allProjects = {
interval: null,

init: function () {
$(document).ready(function () {
PHPCensor.widgets.allProjects.load();
});
},

load: function() {
$.ajax({
url: APP_URL + 'widget-all-projects',

success: function (data) {
$(('#widget-all_projects-container')).html(data);
PHPCensor.widgets.allProjects.interval = setInterval(PHPCensor.widgets.allProjects.update, 10000);
},

error: PHPCensor.handleFailedAjax
});
},

update: function () {
$('.project-box').each(function (index) {
var projectId = this.id.substring(12);

$.ajax({
url: APP_URL + 'widget-all-projects/update/' + projectId,

success: function (data) {
$(('#project-box-' + projectId)).html(data);
},

error: PHPCensor.handleFailedAjax
});
});
}
};

PHPCensor.widgets.allProjects.init();
36 changes: 36 additions & 0 deletions public/assets/js/dashboard-widgets/build_errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
PHPCensor.widgets.buildErrors = {
interval: null,

init: function () {
$(document).ready(function () {
PHPCensor.widgets.buildErrors.load();
});
},

load: function() {
$.ajax({
url: APP_URL + 'widget-build-errors',

success: function (data) {
$(('#widget-build_errors-container')).html(data);
PHPCensor.widgets.buildErrors.interval = setInterval(PHPCensor.widgets.buildErrors.update, 10000);
},

error: PHPCensor.handleFailedAjax
});
},

update: function () {
$.ajax({
url: APP_URL + 'widget-build-errors/update',

success: function (data) {
$(('#dashboard-build-errors')).html(data);
},

error: PHPCensor.handleFailedAjax
});
}
};

PHPCensor.widgets.buildErrors.init();
36 changes: 36 additions & 0 deletions public/assets/js/dashboard-widgets/last_builds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
PHPCensor.widgets.lastBuilds = {
interval: null,

init: function () {
$(document).ready(function () {
PHPCensor.widgets.lastBuilds.load();
});
},

load: function() {
$.ajax({
url: APP_URL + 'widget-last-builds',

success: function (data) {
$(('#widget-last_builds-container')).html(data);
PHPCensor.widgets.lastBuilds.interval = setInterval(PHPCensor.widgets.lastBuilds.update, 10000);
},

error: PHPCensor.handleFailedAjax
});
},

update: function () {
$.ajax({
url: APP_URL + 'widget-last-builds/update',

success: function (data) {
$('#timeline-box').html(data);
},

error: PHPCensor.handleFailedAjax
});
}
};

PHPCensor.widgets.lastBuilds.init();
8 changes: 8 additions & 0 deletions src/PHPCensor/Command/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,14 @@ protected function getConfigInformation(InputInterface $input, OutputInterface $
],
],
],
'dashboard_widgets' => [
'all_projects' => [
'side' => 'left',
],
'last_builds' => [
'side' => 'right',
],
],
];
}

Expand Down
16 changes: 0 additions & 16 deletions src/PHPCensor/Controller/BuildController.php
Original file line number Diff line number Diff line change
Expand Up @@ -368,20 +368,4 @@ public function ajaxQueue()

return $response;
}

public function ajaxTimeline()
{
$builds = $this->buildStore->getLatestBuilds(null, 10);
foreach ($builds as &$build) {
$build = BuildFactory::getBuild($build);
}

$view = new b8\View('Home/ajax-timeline');
$view->builds = $builds;

$this->response->disableLayout();
$this->response->setContent($view->render());

return $this->response;
}
}
112 changes: 16 additions & 96 deletions src/PHPCensor/Controller/HomeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,120 +3,40 @@
namespace PHPCensor\Controller;

use b8;
use PHPCensor\BuildFactory;
use PHPCensor\Helper\Lang;
use PHPCensor\Model\Build;
use PHPCensor\Controller;

/**
* Home Controller - Displays the Dashboard.
*
* @author Dan Cryer <dan@block8.co.uk>
*/
class HomeController extends Controller
{
/**
* @var \PHPCensor\Store\BuildStore
*/
protected $buildStore;

/**
* @var \PHPCensor\Store\ProjectStore
*/
protected $projectStore;

/**
* @var \PHPCensor\Store\ProjectGroupStore
*/
protected $groupStore;

/**
* Initialise the controller, set up stores and services.
*/
public function init()
{
$this->buildStore = b8\Store\Factory::getStore('Build');
$this->projectStore = b8\Store\Factory::getStore('Project');
$this->groupStore = b8\Store\Factory::getStore('ProjectGroup');
}

/**
* Display dashboard:
*/
public function index()
{
$this->layout->title = Lang::get('dashboard');
$builds = $this->buildStore->getLatestBuilds(null, 10);

foreach ($builds as &$build) {
$build = BuildFactory::getBuild($build);
$widgets = [
'left' => [],
'right' => [],
];
$widgets_config = b8\Config::getInstance()->get('php-censor.dashboard_widgets', [
'all_projects' => [
'side' => 'left',
],
'last_builds' => [
'side' => 'right',
],
]);
foreach($widgets_config as $name => $params) {
$side = (isset($params['side']) and ($params['side'] == 'right')) ? 'right' : 'left';
$widgets[$side][$name] = $params;
}

$this->view->builds = $builds;
$this->view->groups = $this->getGroupInfo();
$this->view->widgets = $widgets;

return $this->view->render();
}

/**
* Generate the HTML for the project overview section of the dashboard.
* @param $projects
* @return string
*/
protected function getSummaryHtml($projects)
{
$summaryBuilds = [];
$successes = [];
$failures = [];
$counts = [];

foreach ($projects as $project) {
$summaryBuilds[$project->getId()] = $this->buildStore->getLatestBuilds($project->getId());

$count = $this->buildStore->getWhere(
['project_id' => $project->getId()],
1,
0,
[],
['id' => 'DESC']
);
$counts[$project->getId()] = $count['count'];

$success = $this->buildStore->getLastBuildByStatus($project->getId(), Build::STATUS_SUCCESS);
$failure = $this->buildStore->getLastBuildByStatus($project->getId(), Build::STATUS_FAILED);

$successes[$project->getId()] = $success;
$failures[$project->getId()] = $failure;
}

$view = new b8\View('Home/dashboard-projects');
$view->projects = $projects;
$view->builds = $summaryBuilds;
$view->successful = $successes;
$view->failed = $failures;
$view->counts = $counts;

return $view->render();
}

/**
* Get a summary of the project groups we have, and what projects they have in them.
*
* @return array
*/
protected function getGroupInfo()
{
$rtn = [];
$groups = $this->groupStore->getWhere([], 100, 0, [], ['title' => 'ASC']);

foreach ($groups['items'] as $group) {
$thisGroup = ['title' => $group->getTitle()];
$projects = $this->projectStore->getByGroupId($group->getId(), false);
$thisGroup['projects'] = $projects['items'];
$thisGroup['summary'] = $this->getSummaryHtml($thisGroup['projects']);
$rtn[] = $thisGroup;
}

return $rtn;
}
}
Loading