Split dashboard into widgets. Add build errors widget.
This commit is contained in:
parent
257aabc113
commit
11f58d7c2b
24 changed files with 793 additions and 328 deletions
|
|
@ -1,153 +1,29 @@
|
|||
<?php
|
||||
|
||||
use PHPCensor\Helper\Lang;
|
||||
use PHPCensor\Model\Build;
|
||||
|
||||
/**
|
||||
* @var Build[] $builds
|
||||
* @var array $widgets
|
||||
*/
|
||||
|
||||
$all_widgets = array_merge(array_keys($widgets['left']), array_keys($widgets['right']));
|
||||
foreach($all_widgets as $widget) {
|
||||
?><script src="<?= APP_URL ?>assets/js/dashboard-widgets/<?= $widget ?>.js" type="text/javascript"></script><?php
|
||||
}
|
||||
?>
|
||||
<script>
|
||||
var DASHBOARD = true;
|
||||
</script>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-5">
|
||||
<?php foreach ($groups as $group): ?>
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title"><?php print $group['title']; ?></h3>
|
||||
<div class="box-tools pull-right">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse" data-toggle="tooltip" title="Collapse">
|
||||
<i class="fa fa-minus"></i>
|
||||
</button>
|
||||
</div>
|
||||
<?php foreach ($widgets['left'] as $widget => $params) { ?>
|
||||
<div id="widget-<?= $widget ?>-container">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
<?php print $group['summary']; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($widgets['right'])) { ?>
|
||||
<div class="col-sm-7 pull-left">
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title"><?php Lang::out('latest_builds'); ?></h3>
|
||||
<?php foreach ($widgets['right'] as $widget => $params) { ?>
|
||||
<div id="widget-<?= $widget ?>-container">
|
||||
<div class="loader"></div>
|
||||
</div>
|
||||
|
||||
<div class="box-body" id="timeline-box">
|
||||
<ul class="timeline">
|
||||
<?php $last = new \DateTime('-1 Year'); ?>
|
||||
|
||||
<?php
|
||||
foreach ($builds as $build):
|
||||
$environment = $build->getEnvironment();
|
||||
$branches = $build->getExtra('branches');
|
||||
|
||||
switch ($build->getStatus()) {
|
||||
case Build::STATUS_PENDING:
|
||||
$updated = $build->getCreateDate();
|
||||
$label = Lang::get('pending');
|
||||
$color = 'blue';
|
||||
break;
|
||||
|
||||
case Build::STATUS_RUNNING:
|
||||
$updated = $build->getStartDate();
|
||||
$label = Lang::get('running');
|
||||
$color = 'yellow';
|
||||
break;
|
||||
|
||||
case Build::STATUS_SUCCESS:
|
||||
$updated = $build->getFinishDate();
|
||||
$label = Lang::get('success');
|
||||
$color = 'green';
|
||||
break;
|
||||
|
||||
case Build::STATUS_FAILED:
|
||||
$updated = $build->getFinishDate();
|
||||
$label = Lang::get('failed');
|
||||
$color = 'red';
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$updated) {
|
||||
$updated = $build->getCreateDate();
|
||||
}
|
||||
|
||||
if ($updated->format('Y-m-d') != $last->format('Y-m-d')): $last = $updated;
|
||||
?>
|
||||
<li class="time-label">
|
||||
<span class="bg-gray">
|
||||
<?= $last->format('Y-m-d'); ?>
|
||||
</span>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- /.timeline-label -->
|
||||
<!-- timeline item -->
|
||||
<li>
|
||||
<i class="fa fa-<?php print $build->getProject()->getIcon(); ?> bg-<?php print $color; ?>"></i>
|
||||
<div class="timeline-item">
|
||||
<span class="time"><i class="fa fa-clock-o"></i>
|
||||
<?php
|
||||
echo $updated->format('H:i:s');
|
||||
if ($build->getStatus() != Build::STATUS_PENDING) {
|
||||
echo ' — ' . $build->getDuration(); ?> <?= Lang::get('seconds');
|
||||
}
|
||||
?>
|
||||
</span>
|
||||
<h3 class="timeline-header">
|
||||
<a href="<?= APP_URL; ?>project/view/<?= $build->getProjectId(); ?>">
|
||||
<?= $build->getProject()->getTitle(); ?>
|
||||
</a>
|
||||
<span><?= $environment; ?></span>
|
||||
—
|
||||
<a href="<?= APP_URL; ?>build/view/<?= $build->getId(); ?>">
|
||||
Build #<?= $build->getId(); ?>
|
||||
</a>
|
||||
—
|
||||
<?php Lang::out($build->getSourceHumanize()); ?>
|
||||
</h3>
|
||||
|
||||
<div class="timeline-body">
|
||||
<a href="<?= $build->getBranchLink();?>"><i class="fa fa-code-fork"></i> <?php echo $build->getBranch(); ?></a>
|
||||
<?= $branches ? ' + '.implode(', ', $branches) : ''; ?>
|
||||
<?php if ($tag = $build->getTag()): ?> /
|
||||
<a href="<?= $build->getTagLink(); ?>" target="_blank">
|
||||
<i class="fa fa-tag"></i> <?= $tag; ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
if (!empty($build->getCommitId())) {
|
||||
echo ' — ';
|
||||
echo sprintf(
|
||||
'<a href="%s" target="_blank">%s %s</a>',
|
||||
$build->getCommitLink(),
|
||||
substr($build->getCommitId(), 0, 7),
|
||||
$build->getCommitterEmail() ? ('(' . $build->getCommitterEmail() . ')') : ''
|
||||
);
|
||||
if (!empty($build->getCommitMessage())) {
|
||||
echo ' — ';
|
||||
print $build->getCommitMessage();
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<!-- END timeline item -->
|
||||
|
||||
<?php endforeach; ?>
|
||||
|
||||
<li>
|
||||
<i class="fa fa-clock-o"></i>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
|
|
|||
15
src/PHPCensor/View/WidgetAllProjects/index.phtml
Normal file
15
src/PHPCensor/View/WidgetAllProjects/index.phtml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php foreach ($groups as $group): ?>
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title"><?php print $group['title']; ?></h3>
|
||||
<div class="box-tools pull-right">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse" data-toggle="tooltip" title="Collapse">
|
||||
<i class="fa fa-minus"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<?php print $group['summary']; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
13
src/PHPCensor/View/WidgetBuildErrors/index.phtml
Normal file
13
src/PHPCensor/View/WidgetBuildErrors/index.phtml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
use PHPCensor\Helper\Lang;
|
||||
|
||||
?>
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title"><?= Lang::out('projects_with_build_errors') ?></h3>
|
||||
</div>
|
||||
<div class="box-body" id="dashboard-build-errors">
|
||||
<?= $projects ?>
|
||||
</div>
|
||||
</div>
|
||||
157
src/PHPCensor/View/WidgetBuildErrors/update.phtml
Normal file
157
src/PHPCensor/View/WidgetBuildErrors/update.phtml
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
|
||||
use PHPCensor\Helper\Lang;
|
||||
use PHPCensor\Model\Build;
|
||||
|
||||
/**
|
||||
* @var Build[] $builds
|
||||
*/
|
||||
|
||||
foreach($builds as $project_id => $project_envs):
|
||||
if (!isset($projects[$project_id])) {
|
||||
echo '<!-- project '.$project_id.' not set -->';
|
||||
continue;
|
||||
}
|
||||
$project = $projects[$project_id];
|
||||
foreach($project_envs as $environment => $project_env):
|
||||
$statuses = [];
|
||||
$failures = 0;
|
||||
$subcls = 'gray';
|
||||
$cls = '';
|
||||
$success = null;
|
||||
$failure = null;
|
||||
|
||||
// Get the most recent build status to determine the main block colour.
|
||||
$last_build = $project_env['latest'][0];
|
||||
$status = $last_build->getStatus();
|
||||
switch($status) {
|
||||
case 0:
|
||||
$subcls = 'blue';
|
||||
break;
|
||||
case 1:
|
||||
$subcls = 'yellow';
|
||||
break;
|
||||
case 2:
|
||||
$subcls = 'green';
|
||||
break;
|
||||
case 3:
|
||||
$subcls = 'red';
|
||||
break;
|
||||
}
|
||||
// Use the last 5 builds to determine project health:
|
||||
$failures = 0;
|
||||
|
||||
foreach ($project_env['latest'] as $build) {
|
||||
switch ($build->getStatus()) {
|
||||
case 0:
|
||||
$statuses[] = 'pending';
|
||||
break;
|
||||
case 1:
|
||||
$statuses[] = 'running';
|
||||
break;
|
||||
case 2:
|
||||
$statuses[] = 'ok';
|
||||
$success = is_null($success) && !is_null($build->getFinishDate()) ? $build->getFinishDate()->format('Y-m-d H:i:s') : $success;
|
||||
break;
|
||||
case 3:
|
||||
$failures++;
|
||||
$statuses[] = 'failed';
|
||||
$failure = is_null($failure) && !is_null($build->getFinishDate()) ? $build->getFinishDate()->format('Y-m-d H:i:s') : $failure;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$buildCount = count($project_env['latest']);
|
||||
$lastSuccess = $project_env['success'];
|
||||
$lastFailure = $project_env['failed'];
|
||||
$message = Lang::get('no_builds_yet');
|
||||
$shortMessage = Lang::get('no_builds_yet');
|
||||
|
||||
if ($buildCount > 0) {
|
||||
if ($failures > 0) {
|
||||
$shortMessage = Lang::get('x_of_x_failed_short', $failures, $buildCount);
|
||||
$message = Lang::get('x_of_x_failed', $failures, $buildCount);
|
||||
|
||||
if (!is_null($lastSuccess) && !is_null($lastSuccess->getFinishDate())) {
|
||||
$message .= Lang::get('last_successful_build', $lastSuccess->getFinishDate()->format('Y-m-d H:i:s'));
|
||||
} else {
|
||||
$message .= Lang::get('never_built_successfully');
|
||||
}
|
||||
} else {
|
||||
$message = Lang::get('all_builds_passed', $buildCount);
|
||||
$shortMessage = Lang::get('all_builds_passed_short', $buildCount, $buildCount);
|
||||
|
||||
if (!is_null($lastFailure) && !is_null($lastFailure->getFinishDate())) {
|
||||
$message .= Lang::get('last_failed_build', $lastFailure->getFinishDate()->format('Y-m-d H:i:s'));
|
||||
} else {
|
||||
$message .= Lang::get('never_failed_build');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="project-box">
|
||||
<div class="small-box small-box-full bg-<?= $subcls; ?>">
|
||||
|
||||
<div class="inner">
|
||||
<h3>
|
||||
<a href="<?= APP_URL; ?>project/view/<?= $project->getId(); ?>">
|
||||
<?= $project->getTitle(); ?>
|
||||
</a>
|
||||
<?php if (!empty($environment)) { ?>
|
||||
<sup title="<?php Lang::out('environment'); ?>"><?= $environment ?></sup>
|
||||
<?php } ?>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
<?= $message; ?>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<div class="icon">
|
||||
<i class="fa fa-<?php print $project->getIcon(); ?>"></i>
|
||||
</div>
|
||||
<a href="<?= APP_URL; ?>project/view/<?= $project->getId(); ?>" class="small-box-footer small-box-footer-project">
|
||||
<div class="pull-left" style="margin-left: 10px">
|
||||
<?php if ($project->getAllowPublicStatus()): ?>
|
||||
<i class="fa fa-unlock"></i>
|
||||
<?php else: ?>
|
||||
<i class="fa fa-lock"></i>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php Lang::out('view_project'); ?> <i class="fa fa-arrow-circle-right"></i>
|
||||
</a>
|
||||
|
||||
<?php for ($idx=0; $idx < 5; $idx++) {
|
||||
if (empty($project_env['latest'][$idx])) {
|
||||
echo '<span class="small-box-footer-build small-box-footer bg-gray"><i class="fa fa-minus"></i></span>';
|
||||
} else {
|
||||
$build = $project_env['latest'][$idx];
|
||||
$link = APP_URL . 'build/view/' . $build->id;
|
||||
switch ($build->getStatus()) {
|
||||
case 0:
|
||||
$class = 'bg-blue';
|
||||
$icon = 'fa-clock-o';
|
||||
break;
|
||||
case 1:
|
||||
$class = 'bg-yellow';
|
||||
$icon = 'fa-cogs';
|
||||
break;
|
||||
case 2:
|
||||
$class = 'bg-green';
|
||||
$icon = 'fa-check';
|
||||
break;
|
||||
case 3:
|
||||
$class = 'bg-red';
|
||||
$icon = 'fa-times';
|
||||
break;
|
||||
}
|
||||
echo '<a href="' . $link .'" class="small-box-footer-build small-box-footer ' . $class . '"><i class="fa ' . $icon . '"></i></a>';
|
||||
}
|
||||
} ?>
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php endforeach; ?>
|
||||
<?php endforeach; ?>
|
||||
13
src/PHPCensor/View/WidgetLastBuilds/index.phtml
Normal file
13
src/PHPCensor/View/WidgetLastBuilds/index.phtml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
use PHPCensor\Helper\Lang;
|
||||
|
||||
?>
|
||||
<div class="box">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title"><?php Lang::out('latest_builds'); ?></h3>
|
||||
</div>
|
||||
<div class="box-body" id="timeline-box">
|
||||
<?= $timeline ?>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue