mirror of
https://github.com/CachetHQ/Cachet.git
synced 2025-01-17 21:49:01 +01:00
commit
d205338514
71
app/Composers/ModuleComposer.php
Normal file
71
app/Composers/ModuleComposer.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Composers;
|
||||
|
||||
use CachetHQ\Cachet\Services\Modules\Manager;
|
||||
use Illuminate\Contracts\Foundation\Application;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
class ModuleComposer
|
||||
{
|
||||
/**
|
||||
* The application instance.
|
||||
*
|
||||
* @var \Illuminate\Contracts\Foundation\Application
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* The modules manager instance.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Services\Modules\Manager
|
||||
*/
|
||||
protected $manager;
|
||||
|
||||
/**
|
||||
* Create a new modules composer.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Foundation\Application $app
|
||||
* @param \CachetHQ\Cachet\Services\Modules\Manager $manager
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Application $app, Manager $manager)
|
||||
{
|
||||
$this->app = $app;
|
||||
$this->manager = $manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind data to the view.
|
||||
*
|
||||
* @param \Illuminate\Contracts\View\View $view
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function compose(View $view)
|
||||
{
|
||||
$key = $view->getName();
|
||||
|
||||
$view->with('view', $key);
|
||||
|
||||
$modules = "view.modules: {$key}";
|
||||
$groups = "view.groups: {$key}";
|
||||
|
||||
$modules = $this->app->bound($modules) ? $this->app[$modules] : [];
|
||||
$groups = $this->app->bound($groups) ? $this->app[$groups] : [];
|
||||
|
||||
$modules = $this->manager->groupModules($modules, $groups);
|
||||
|
||||
$view->withModules($modules);
|
||||
}
|
||||
}
|
@ -9,40 +9,20 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Composers;
|
||||
namespace CachetHQ\Cachet\Composers\Modules;
|
||||
|
||||
use CachetHQ\Cachet\Integrations\Core\System;
|
||||
use CachetHQ\Cachet\Models\Component;
|
||||
use CachetHQ\Cachet\Models\ComponentGroup;
|
||||
use CachetHQ\Cachet\Models\Incident;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
/**
|
||||
* This is the status page composer.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
* @author Connor S. Parks <connor@connorvg.tv>
|
||||
*/
|
||||
class StatusPageComposer
|
||||
class ComponentsComposer
|
||||
{
|
||||
/**
|
||||
* The system instance.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Integrations\Contracts\System
|
||||
*/
|
||||
protected $system;
|
||||
|
||||
/**
|
||||
* Create a new status page composer instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Integrations\Contracts\System $system
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(System $system)
|
||||
{
|
||||
$this->system = $system;
|
||||
}
|
||||
|
||||
/**
|
||||
* Index page view composer.
|
||||
*
|
||||
@ -52,19 +32,12 @@ class StatusPageComposer
|
||||
*/
|
||||
public function compose(View $view)
|
||||
{
|
||||
$status = $this->system->getStatus();
|
||||
|
||||
// Scheduled maintenance code.
|
||||
$scheduledMaintenance = Incident::scheduled()->orderBy('scheduled_at')->get();
|
||||
|
||||
// Component & Component Group lists.
|
||||
$usedComponentGroups = Component::enabled()->where('group_id', '>', 0)->groupBy('group_id')->pluck('group_id');
|
||||
$componentGroups = ComponentGroup::whereIn('id', $usedComponentGroups)->orderBy('order')->get();
|
||||
$ungroupedComponents = Component::enabled()->where('group_id', 0)->orderBy('order')->orderBy('created_at')->get();
|
||||
|
||||
$view->with($status)
|
||||
->withComponentGroups($componentGroups)
|
||||
->withUngroupedComponents($ungroupedComponents)
|
||||
->withScheduledMaintenance($scheduledMaintenance);
|
||||
$view->withComponentGroups($componentGroups)
|
||||
->withUngroupedComponents($ungroupedComponents);
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Composers;
|
||||
namespace CachetHQ\Cachet\Composers\Modules;
|
||||
|
||||
use CachetHQ\Cachet\Models\Metric;
|
||||
use Illuminate\Contracts\Config\Repository;
|
38
app/Composers/Modules/ScheduledComposer.php
Normal file
38
app/Composers/Modules/ScheduledComposer.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Composers\Modules;
|
||||
|
||||
use CachetHQ\Cachet\Models\Incident;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
/**
|
||||
* This is the status page composer.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
* @author Connor S. Parks <connor@connorvg.tv>
|
||||
*/
|
||||
class ScheduledComposer
|
||||
{
|
||||
/**
|
||||
* Index page view composer.
|
||||
*
|
||||
* @param \Illuminate\Contracts\View\View $view
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function compose(View $view)
|
||||
{
|
||||
$scheduledMaintenance = Incident::scheduled()->orderBy('scheduled_at')->get();
|
||||
|
||||
$view->withScheduledMaintenance($scheduledMaintenance);
|
||||
}
|
||||
}
|
55
app/Composers/Modules/StatusComposer.php
Normal file
55
app/Composers/Modules/StatusComposer.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Composers\Modules;
|
||||
|
||||
use CachetHQ\Cachet\Integrations\Contracts\System;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
/**
|
||||
* This is the status page composer.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
* @author Connor S. Parks <connor@connorvg.tv>
|
||||
*/
|
||||
class StatusComposer
|
||||
{
|
||||
/**
|
||||
* The system instance.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Integrations\Contracts\System
|
||||
*/
|
||||
protected $system;
|
||||
|
||||
/**
|
||||
* Create a new status page composer instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Integrations\Contracts\System $system
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(System $system)
|
||||
{
|
||||
$this->system = $system;
|
||||
}
|
||||
|
||||
/**
|
||||
* Index page view composer.
|
||||
*
|
||||
* @param \Illuminate\Contracts\View\View $view
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function compose(View $view)
|
||||
{
|
||||
$view->with($this->system->getStatus());
|
||||
}
|
||||
}
|
35
app/Composers/Modules/TimelineComposer.php
Normal file
35
app/Composers/Modules/TimelineComposer.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Composers\Modules;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
/**
|
||||
* This is the status page composer.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
* @author Connor S. Parks <connor@connorvg.tv>
|
||||
*/
|
||||
class TimelineComposer
|
||||
{
|
||||
/**
|
||||
* Index page view composer.
|
||||
*
|
||||
* @param \Illuminate\Contracts\View\View $view
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function compose(View $view)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
@ -14,8 +14,12 @@ namespace CachetHQ\Cachet\Foundation\Providers;
|
||||
use CachetHQ\Cachet\Composers\AppComposer;
|
||||
use CachetHQ\Cachet\Composers\CurrentUserComposer;
|
||||
use CachetHQ\Cachet\Composers\DashboardComposer;
|
||||
use CachetHQ\Cachet\Composers\MetricsComposer;
|
||||
use CachetHQ\Cachet\Composers\StatusPageComposer;
|
||||
use CachetHQ\Cachet\Composers\ModuleComposer;
|
||||
use CachetHQ\Cachet\Composers\Modules\ComponentsComposer as ComponentsModuleComposer;
|
||||
use CachetHQ\Cachet\Composers\Modules\MetricsComposer as MetricsModuleComposer;
|
||||
use CachetHQ\Cachet\Composers\Modules\ScheduledComposer as ScheduledModuleComposer;
|
||||
use CachetHQ\Cachet\Composers\Modules\StatusComposer as StatusModuleComposer;
|
||||
use CachetHQ\Cachet\Composers\Modules\TimelineComposer as TimelineModuleComposer;
|
||||
use CachetHQ\Cachet\Composers\ThemeComposer;
|
||||
use CachetHQ\Cachet\Composers\TimezoneLocaleComposer;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
@ -32,11 +36,16 @@ class ComposerServiceProvider extends ServiceProvider
|
||||
{
|
||||
$factory->composer('*', AppComposer::class);
|
||||
$factory->composer('*', CurrentUserComposer::class);
|
||||
$factory->composer(['index'], MetricsComposer::class);
|
||||
$factory->composer(['index', 'single-incident', 'subscribe', 'signup'], StatusPageComposer::class);
|
||||
$factory->composer(['index', 'single-incident', 'subscribe.*', 'signup', 'dashboard.settings.theme', 'emails.*'], ThemeComposer::class);
|
||||
$factory->composer('dashboard.*', DashboardComposer::class);
|
||||
$factory->composer(['setup', 'dashboard.settings.localization'], TimezoneLocaleComposer::class);
|
||||
|
||||
$factory->composer('*', ModuleComposer::class);
|
||||
$factory->composer('partials.modules.components', ComponentsModuleComposer::class);
|
||||
$factory->composer('partials.modules.metrics', MetricsModuleComposer::class);
|
||||
$factory->composer('partials.modules.scheduled', ScheduledModuleComposer::class);
|
||||
$factory->composer('partials.modules.status', StatusModuleComposer::class);
|
||||
$factory->composer('partials.modules.timeline', TimelineModuleComposer::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
93
app/Foundation/Providers/ModuleServiceProvider.php
Normal file
93
app/Foundation/Providers/ModuleServiceProvider.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Foundation\Providers;
|
||||
|
||||
use CachetHQ\Cachet\Services\Modules\Renderer as ModulesRenderer;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\View\Compilers\BladeCompiler;
|
||||
|
||||
class ModuleServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The module definitions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $modules = [
|
||||
'index' => [
|
||||
['group' => 'messages', 'partial' => 'partials.modules.messages'],
|
||||
['group' => 'status', 'partial' => 'partials.modules.status'],
|
||||
['group' => 'components', 'partial' => 'partials.modules.components'],
|
||||
['group' => 'metrics', 'partial' => 'partials.modules.metrics'],
|
||||
['group' => 'scheduled', 'partial' => 'partials.modules.scheduled'],
|
||||
['group' => 'timeline', 'partial' => 'partials.modules.timeline'],
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The group definitions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $groups = [
|
||||
'index' => [
|
||||
'messages' => 10000,
|
||||
'status' => 20000,
|
||||
'components' => 30000,
|
||||
'metrics' => 40000,
|
||||
'scheduled' => 50000,
|
||||
'timeline' => 60000,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Boot the service provider.
|
||||
*
|
||||
* @param \Illuminate\View\Compilers\BladeCompiler $blade
|
||||
*/
|
||||
public function boot(BladeCompiler $blade)
|
||||
{
|
||||
$blade->directive('modules', function ($group = null) {
|
||||
return sprintf(
|
||||
'<?php echo $app->call(\'%s@%s\', [
|
||||
\'factory\' => $__env,
|
||||
\'data\' => array_except(get_defined_vars(), array(\'__data\', \'__path\')),
|
||||
\'modules\' => $modules,
|
||||
\'group\' => %s,
|
||||
]); ?>',
|
||||
ModulesRenderer::class,
|
||||
'renderModules',
|
||||
$group === null ? 'null' : $group
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
foreach ($this->modules as $key => $modules) {
|
||||
$this->app->singleton("view.modules: {$key}", function () use ($modules) {
|
||||
return $modules;
|
||||
});
|
||||
}
|
||||
|
||||
foreach ($this->groups as $key => $groups) {
|
||||
$this->app->singleton("view.groups: {$key}", function () use ($groups) {
|
||||
return $groups;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
80
app/Services/Modules/Manager.php
Normal file
80
app/Services/Modules/Manager.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Services\Modules;
|
||||
|
||||
/**
|
||||
* This is the module manager class.
|
||||
*
|
||||
* @author Connor S. Parks <connor@connorvg.tv>
|
||||
*/
|
||||
class Manager
|
||||
{
|
||||
/**
|
||||
* Groups the modules.
|
||||
*
|
||||
* @param array $modules
|
||||
* @param array $groups
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function groupModules(array $modules, array $groups = [])
|
||||
{
|
||||
$grouped = [];
|
||||
$length = count($modules);
|
||||
foreach ($modules as $order => $module) {
|
||||
if (!is_array($module) || empty($module['group'])) {
|
||||
$order = array_get($module, 'order', PHP_INT_MAX - $length + $order);
|
||||
|
||||
$grouped[] = [$module, 'order' => $order];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$group = $module['group'];
|
||||
if (empty($grouped[$group])) {
|
||||
$grouped[$group] = [$module];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$grouped[$group][] = $module;
|
||||
}
|
||||
|
||||
foreach ($groups as $group => $order) {
|
||||
if (empty($grouped[$group])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$grouped[$group]['order'] = $order;
|
||||
}
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Orders the modules.
|
||||
*
|
||||
* @param array $modules
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function orderModules($modules)
|
||||
{
|
||||
$modules = array_numeric_sort($modules);
|
||||
|
||||
foreach ($modules as $group => $subModules) {
|
||||
$modules[$group] = array_numeric_sort($subModules);
|
||||
}
|
||||
|
||||
return $modules;
|
||||
}
|
||||
}
|
75
app/Services/Modules/Renderer.php
Normal file
75
app/Services/Modules/Renderer.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Services\Modules;
|
||||
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
|
||||
/**
|
||||
* This is the module renderer class.
|
||||
*
|
||||
* @author Connor S. Parks <connor@connorvg.tv>
|
||||
*/
|
||||
class Renderer
|
||||
{
|
||||
/**
|
||||
* Render the modules.
|
||||
*
|
||||
* @param \Illuminate\Contracts\View\Factory $factory
|
||||
* @param array $data
|
||||
* @param array $modules
|
||||
* @param string|null $group
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderModules(Factory $factory, array $data, array $modules, $group = null)
|
||||
{
|
||||
if ($group !== null) {
|
||||
if (empty($modules[$group])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->renderModulesGroup($factory, $data, $modules[$group]);
|
||||
}
|
||||
|
||||
return array_reduce(
|
||||
array_numeric_sort($modules),
|
||||
function ($reduce, $module) use ($factory, $data) {
|
||||
return $reduce.$this->renderModulesGroup($factory, $data, $module);
|
||||
},
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a group of modules.
|
||||
*
|
||||
* @param \Illuminate\Contracts\View\Factory $factory
|
||||
* @param array $data
|
||||
* @param array $modules
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function renderModulesGroup(Factory $factory, array $data, array $modules)
|
||||
{
|
||||
return array_reduce(
|
||||
array_numeric_sort($modules),
|
||||
function ($reduce, $module) use ($factory, $data) {
|
||||
if (empty($module['partial'])) {
|
||||
return $reduce;
|
||||
}
|
||||
|
||||
return $reduce.$factory->make($module['partial'], $data)->render();
|
||||
},
|
||||
''
|
||||
);
|
||||
}
|
||||
}
|
@ -115,3 +115,27 @@ if (!function_exists('color_contrast')) {
|
||||
return ($yiq >= 128) ? 'black' : 'white';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('array_numeric_sort')) {
|
||||
/**
|
||||
* Numerically sort an array based on a specific key.
|
||||
*
|
||||
* @param array $array
|
||||
* @param string $key
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function array_numeric_sort(array $array = [], $key = 'order')
|
||||
{
|
||||
uasort($array, function ($a, $b) use ($key) {
|
||||
$a = array_get($a, $key, PHP_INT_MAX);
|
||||
$b = array_get($b, $key, PHP_INT_MAX);
|
||||
|
||||
$default = PHP_MAJOR_VERSION < 7 ? 1 : 0;
|
||||
|
||||
return $a < $b ? -1 : ($a === $b ? $default : 1);
|
||||
});
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
@ -184,8 +184,9 @@ return [
|
||||
'CachetHQ\Cachet\Foundation\Providers\ComposerServiceProvider',
|
||||
'CachetHQ\Cachet\Foundation\Providers\ConsoleServiceProvider',
|
||||
'CachetHQ\Cachet\Foundation\Providers\ConfigServiceProvider',
|
||||
'CachetHQ\Cachet\Foundation\Providers\IntegrationServiceProvider',
|
||||
'CachetHQ\Cachet\Foundation\Providers\EventServiceProvider',
|
||||
'CachetHQ\Cachet\Foundation\Providers\IntegrationServiceProvider',
|
||||
'CachetHQ\Cachet\Foundation\Providers\ModuleServiceProvider',
|
||||
'CachetHQ\Cachet\Foundation\Providers\RepositoryServiceProvider',
|
||||
'CachetHQ\Cachet\Foundation\Providers\RouteServiceProvider',
|
||||
|
||||
|
@ -1,60 +1,5 @@
|
||||
@extends('layout.master')
|
||||
|
||||
@section('content')
|
||||
<div class="section-messages">
|
||||
@include('dashboard.partials.errors')
|
||||
</div>
|
||||
|
||||
<div class="section-status">
|
||||
<div class="alert alert-{{ $system_status }}">{{ $system_message }}</div>
|
||||
</div>
|
||||
|
||||
@include('partials.about-app')
|
||||
|
||||
@if(!$component_groups->isEmpty() || !$ungrouped_components->isEmpty())
|
||||
<div class="section-components">
|
||||
@include('partials.components')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($display_metrics && $app_graphs)
|
||||
<div class="section-metrics">
|
||||
@include('partials.metrics')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if(!$scheduled_maintenance->isEmpty())
|
||||
<div class="section-scheduled">
|
||||
@include('partials.schedule')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($days_to_show > 0)
|
||||
<div class="section-timeline">
|
||||
<h1>{{ trans('cachet.incidents.past') }}</h1>
|
||||
@foreach($all_incidents as $date => $incidents)
|
||||
@include('partials.incidents', [compact($date), compact($incidents)])
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<ul class="pager">
|
||||
@if($can_page_backward)
|
||||
<li class="previous">
|
||||
<a href="{{ route('status-page') }}?start_date={{ $previous_date }}" class="links">
|
||||
<span aria-hidden="true">←</span> {{ trans('cachet.incidents.previous_week') }}
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@if($can_page_forward)
|
||||
<li class="next">
|
||||
<a href="{{ route('status-page') }}?start_date={{ $next_date }}" class="links">
|
||||
{{ trans('cachet.incidents.next_week') }} <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
||||
|
||||
@modules
|
||||
@stop
|
||||
|
5
resources/views/partials/modules/components.blade.php
Normal file
5
resources/views/partials/modules/components.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@if(!$component_groups->isEmpty() || !$ungrouped_components->isEmpty())
|
||||
<div class="section-components">
|
||||
@include('partials.components')
|
||||
</div>
|
||||
@endif
|
3
resources/views/partials/modules/messages.blade.php
Normal file
3
resources/views/partials/modules/messages.blade.php
Normal file
@ -0,0 +1,3 @@
|
||||
<div class="section-messages">
|
||||
@include('dashboard.partials.errors')
|
||||
</div>
|
5
resources/views/partials/modules/metrics.blade.php
Normal file
5
resources/views/partials/modules/metrics.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@if($display_metrics && $app_graphs)
|
||||
<div class="section-metrics">
|
||||
@include('partials.metrics')
|
||||
</div>
|
||||
@endif
|
5
resources/views/partials/modules/scheduled.blade.php
Normal file
5
resources/views/partials/modules/scheduled.blade.php
Normal file
@ -0,0 +1,5 @@
|
||||
@if(!$scheduled_maintenance->isEmpty())
|
||||
<div class="section-scheduled">
|
||||
@include('partials.schedule')
|
||||
</div>
|
||||
@endif
|
3
resources/views/partials/modules/status.blade.php
Normal file
3
resources/views/partials/modules/status.blade.php
Normal file
@ -0,0 +1,3 @@
|
||||
<div class="section-status">
|
||||
<div class="alert alert-{{ $system_status }}">{{ $system_message }}</div>
|
||||
</div>
|
27
resources/views/partials/modules/timeline.blade.php
Normal file
27
resources/views/partials/modules/timeline.blade.php
Normal file
@ -0,0 +1,27 @@
|
||||
@if($days_to_show > 0)
|
||||
<div class="section-timeline">
|
||||
<h1>{{ trans('cachet.incidents.past') }}</h1>
|
||||
@foreach($all_incidents as $date => $incidents)
|
||||
@include('partials.incidents', [compact($date), compact($incidents)])
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<ul class="pager">
|
||||
@if($can_page_backward)
|
||||
<li class="previous">
|
||||
<a href="{{ route('status-page') }}?start_date={{ $previous_date }}" class="links">
|
||||
<span aria-hidden="true">←</span> {{ trans('cachet.incidents.previous_week') }}
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@if($can_page_forward)
|
||||
<li class="next">
|
||||
<a href="{{ route('status-page') }}?start_date={{ $next_date }}" class="links">
|
||||
{{ trans('cachet.incidents.next_week') }} <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
25
tests/Foundation/Providers/ModuleServiceProviderTest.php
Normal file
25
tests/Foundation/Providers/ModuleServiceProviderTest.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Tests\Cachet\Foundation\Providers;
|
||||
|
||||
use AltThree\TestBench\ServiceProviderTrait;
|
||||
use CachetHQ\Tests\Cachet\AbstractTestCase;
|
||||
|
||||
/**
|
||||
* This is the composer service provider test class.
|
||||
*
|
||||
* @author Connor S. Parks <connor@connorvg.tv>
|
||||
*/
|
||||
class ModuleServiceProviderTest extends AbstractTestCase
|
||||
{
|
||||
use ServiceProviderTrait;
|
||||
}
|
166
tests/Services/Modules/ManagerTest.php
Normal file
166
tests/Services/Modules/ManagerTest.php
Normal file
@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Tests\Cachet\Services\Modules;
|
||||
|
||||
use CachetHQ\Tests\Cachet\AbstractTestCase;
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* This is the modules manager service test class.
|
||||
*
|
||||
* @author Connor S. Parks <connor@connorvg.tv>
|
||||
*/
|
||||
class ManagerTest extends AbstractTestCase
|
||||
{
|
||||
public function testGroupNoModules()
|
||||
{
|
||||
$manager = m::mock('CachetHQ\Cachet\Services\Modules\Manager[groupModules]');
|
||||
$manager->shouldReceive('groupModules')->once()->passthru();
|
||||
|
||||
$grouped = $manager->groupModules([]);
|
||||
|
||||
$this->assertSame([], $grouped);
|
||||
}
|
||||
|
||||
public function testGroupModulesNoGroups()
|
||||
{
|
||||
$manager = m::mock('CachetHQ\Cachet\Services\Modules\Manager[groupModules]');
|
||||
$manager->shouldReceive('groupModules')->once()->passthru();
|
||||
|
||||
$grouped = $manager->groupModules($this->getModules(), []);
|
||||
|
||||
$this->assertSame($this->getGroupedModules(), $grouped);
|
||||
}
|
||||
|
||||
public function testGroupModules()
|
||||
{
|
||||
$manager = m::mock('CachetHQ\Cachet\Services\Modules\Manager[groupModules]');
|
||||
$manager->shouldReceive('groupModules')->once()->passthru();
|
||||
|
||||
$grouped = $manager->groupModules($this->getModules(), $this->getGroups());
|
||||
|
||||
$this->assertSame($this->getGroupedModulesWithOrders(), $grouped);
|
||||
}
|
||||
|
||||
public function testOrderModules()
|
||||
{
|
||||
$manager = m::mock('CachetHQ\Cachet\Services\Modules\Manager[orderModules]');
|
||||
$manager->shouldReceive('orderModules')->once()->passthru();
|
||||
|
||||
$ordered = $manager->orderModules($this->getGroupedModules());
|
||||
|
||||
$this->assertSame($this->getOrderedModules(), $ordered);
|
||||
}
|
||||
|
||||
public function testOrderModulesWithOrders()
|
||||
{
|
||||
$manager = m::mock('CachetHQ\Cachet\Services\Modules\Manager[orderModules]');
|
||||
$manager->shouldReceive('orderModules')->once()->passthru();
|
||||
|
||||
$ordered = $manager->orderModules($this->getGroupedModulesWithOrders());
|
||||
|
||||
$this->assertSame($this->getOrderedModulesWithOrders(), $ordered);
|
||||
}
|
||||
|
||||
protected function getModules()
|
||||
{
|
||||
return [
|
||||
['group' => 'two', 'partial' => 'partials.two.a'],
|
||||
['partial' => 'partials.a', 'order' => 8],
|
||||
['group' => 'one', 'partial' => 'partials.one.c'],
|
||||
['partial' => 'partials.c'],
|
||||
['group' => 'one', 'partial' => 'partials.one.a', 'order' => 1],
|
||||
['group' => 'one', 'partial' => 'partials.one.b', 'order' => 2],
|
||||
['partial' => 'partials.b', 'order' => 15],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getGroups()
|
||||
{
|
||||
return [
|
||||
'one' => 1,
|
||||
'two' => 2,
|
||||
];
|
||||
}
|
||||
|
||||
protected function getGroupedModules()
|
||||
{
|
||||
return [
|
||||
'two' => [
|
||||
['group' => 'two', 'partial' => 'partials.two.a'],
|
||||
],
|
||||
[['partial' => 'partials.a', 'order' => 8], 'order' => 8],
|
||||
'one' => [
|
||||
['group' => 'one', 'partial' => 'partials.one.c'],
|
||||
['group' => 'one', 'partial' => 'partials.one.a', 'order' => 1],
|
||||
['group' => 'one', 'partial' => 'partials.one.b', 'order' => 2],
|
||||
],
|
||||
[['partial' => 'partials.c'], 'order' => PHP_INT_MAX - 4],
|
||||
[['partial' => 'partials.b', 'order' => 15], 'order' => 15],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getGroupedModulesWithOrders()
|
||||
{
|
||||
return [
|
||||
'two' => [
|
||||
['group' => 'two', 'partial' => 'partials.two.a'],
|
||||
'order' => 2,
|
||||
],
|
||||
[['partial' => 'partials.a', 'order' => 8], 'order' => 8],
|
||||
'one' => [
|
||||
['group' => 'one', 'partial' => 'partials.one.c'],
|
||||
['group' => 'one', 'partial' => 'partials.one.a', 'order' => 1],
|
||||
['group' => 'one', 'partial' => 'partials.one.b', 'order' => 2],
|
||||
'order' => 1,
|
||||
],
|
||||
[['partial' => 'partials.c'], 'order' => PHP_INT_MAX - 4],
|
||||
[['partial' => 'partials.b', 'order' => 15], 'order' => 15],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getOrderedModules()
|
||||
{
|
||||
return [
|
||||
[['partial' => 'partials.a', 'order' => 8], 'order' => 8],
|
||||
2 => [['partial' => 'partials.b', 'order' => 15], 'order' => 15],
|
||||
1 => [['partial' => 'partials.c'], 'order' => PHP_INT_MAX - 4],
|
||||
'two' => [
|
||||
['group' => 'two', 'partial' => 'partials.two.a'],
|
||||
],
|
||||
'one' => [
|
||||
1 => ['group' => 'one', 'partial' => 'partials.one.a', 'order' => 1],
|
||||
2 => ['group' => 'one', 'partial' => 'partials.one.b', 'order' => 2],
|
||||
0 => ['group' => 'one', 'partial' => 'partials.one.c'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getOrderedModulesWithOrders()
|
||||
{
|
||||
return [
|
||||
'one' => [
|
||||
1 => ['group' => 'one', 'partial' => 'partials.one.a', 'order' => 1],
|
||||
2 => ['group' => 'one', 'partial' => 'partials.one.b', 'order' => 2],
|
||||
0 => ['group' => 'one', 'partial' => 'partials.one.c'],
|
||||
'order' => 1,
|
||||
],
|
||||
'two' => [
|
||||
['group' => 'two', 'partial' => 'partials.two.a'],
|
||||
'order' => 2,
|
||||
],
|
||||
[['partial' => 'partials.a', 'order' => 8], 'order' => 8],
|
||||
2 => [['partial' => 'partials.b', 'order' => 15], 'order' => 15],
|
||||
1 => [['partial' => 'partials.c'], 'order' => PHP_INT_MAX - 4],
|
||||
];
|
||||
}
|
||||
}
|
143
tests/Services/Modules/RendererTest.php
Normal file
143
tests/Services/Modules/RendererTest.php
Normal file
@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Cachet.
|
||||
*
|
||||
* (c) Alt Three Services Limited
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Tests\Cachet\Services\Modules;
|
||||
|
||||
use CachetHQ\Tests\Cachet\AbstractTestCase;
|
||||
use Mockery as m;
|
||||
|
||||
/**
|
||||
* This is the modules renderer service test class.
|
||||
*
|
||||
* @author Connor S. Parks <connor@connorvg.tv>
|
||||
*/
|
||||
class RendererTest extends AbstractTestCase
|
||||
{
|
||||
public function testRenderNoModules()
|
||||
{
|
||||
$renderer = m::mock('CachetHQ\Cachet\Services\Modules\Renderer[renderModules]');
|
||||
$renderer->shouldReceive('renderModules')->once()->passthru();
|
||||
|
||||
$output = $renderer->renderModules(
|
||||
$this->getFactory(),
|
||||
[],
|
||||
[],
|
||||
null
|
||||
);
|
||||
|
||||
$this->assertSame('', $output);
|
||||
}
|
||||
|
||||
public function testRenderNonExistentModulesGroup()
|
||||
{
|
||||
$renderer = m::mock('CachetHQ\Cachet\Services\Modules\Renderer[renderModules]');
|
||||
$renderer->shouldReceive('renderModules')->once()->passthru();
|
||||
|
||||
$output = $renderer->renderModules(
|
||||
$this->getFactory(),
|
||||
[],
|
||||
$this->getModules(),
|
||||
'non-existent group'
|
||||
);
|
||||
|
||||
$this->assertSame('', $output);
|
||||
}
|
||||
|
||||
public function testRenderModules()
|
||||
{
|
||||
$renderer = m::mock('CachetHQ\Cachet\Services\Modules\Renderer[renderModules]');
|
||||
$renderer->shouldReceive('renderModules')->once()->passthru();
|
||||
|
||||
$factory = $this->getFactory([
|
||||
'partial.a', 'partial.b', 'partial.c',
|
||||
'partial.one.a', 'partial.one.b', 'partial.one.c',
|
||||
'partial.two.a',
|
||||
'partial.three.a', 'partial.three.b',
|
||||
]);
|
||||
|
||||
$output = $renderer->renderModules(
|
||||
$factory,
|
||||
['a' => 'b', 'c' => 'd'],
|
||||
$this->getModules(),
|
||||
null
|
||||
);
|
||||
|
||||
$this->assertSame('partial.apartial.one.apartial.one.bpartial.one.cpartial.two.apartial.bpartial.cpartial.three.apartial.three.b', $output);
|
||||
}
|
||||
|
||||
public function testRenderModuleGroups()
|
||||
{
|
||||
$renderer = m::mock('CachetHQ\Cachet\Services\Modules\Renderer[renderModules]');
|
||||
$renderer->shouldReceive('renderModules')->once()->passthru();
|
||||
|
||||
$factory = $this->getFactory([
|
||||
'partial.one.a', 'partial.one.b', 'partial.one.c',
|
||||
]);
|
||||
|
||||
$output = $renderer->renderModules(
|
||||
$factory,
|
||||
['a' => 'b', 'c' => 'd'],
|
||||
$this->getModules(),
|
||||
'one'
|
||||
);
|
||||
|
||||
$this->assertSame('partial.one.apartial.one.bpartial.one.c', $output);
|
||||
}
|
||||
|
||||
protected function getModules()
|
||||
{
|
||||
return [
|
||||
'two' => [
|
||||
'order' => 3,
|
||||
['partial' => 'partial.two.a'],
|
||||
],
|
||||
[
|
||||
['partial' => 'partial.c'],
|
||||
['partial' => 'partial.b', 'order' => 1],
|
||||
],
|
||||
[
|
||||
'order' => 1,
|
||||
['partial' => 'partial.a'],
|
||||
],
|
||||
'one' => [
|
||||
'order' => 2,
|
||||
['partial' => 'partial.one.c'],
|
||||
['partial' => 'partial.one.a', 'order' => 1],
|
||||
['partial' => 'partial.one.b', 'order' => 2],
|
||||
],
|
||||
'three' => [
|
||||
['partial' => 'partial.three.a'],
|
||||
['partial' => 'partial.three.b'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getFactory($views = [])
|
||||
{
|
||||
$factory = m::mock('Illuminate\View\Factory[make]', $this->getFactoryArgs());
|
||||
|
||||
foreach ($views as $view) {
|
||||
$factory->shouldReceive('make')->once()->with($view, ['a' => 'b', 'c' => 'd'])->andReturn($mockView = m::mock('StdClass'));
|
||||
$mockView->shouldReceive('render')->once()->andReturn($view);
|
||||
}
|
||||
|
||||
return $factory;
|
||||
}
|
||||
|
||||
protected function getFactoryArgs()
|
||||
{
|
||||
return [
|
||||
m::mock('Illuminate\View\Engines\EngineResolver'),
|
||||
m::mock('Illuminate\View\ViewFinderInterface'),
|
||||
m::mock('Illuminate\Contracts\Events\Dispatcher'),
|
||||
];
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user