diff --git a/README.md b/README.md index 777fa324..d1df9768 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,10 @@ Now go to `http:///setup` and have fun! Note: When running in production you should ensure that you enable SSL. This is commonly achieved by running Nginx with your certificates on your Docker host, service or load balancers in-front of the running container, or by adding your custom SSL certificates and configuration to the supplied Nginx configuration. +## Addons + +- [cachet-monitor](https://github.com/castawaylabs/cachet-monitor) - For url monitoring. Automatic incident updates + ## Read more about Cachet For more information on why I started developing Cachet, check out my [Cachet articles on my blog](https://james-brooks.uk/tag/cachet/?utm_source=github&utm_medium=readme&utm_campaign=github-cachet). diff --git a/app/Http/Controllers/Admin/IncidentController.php b/app/Http/Controllers/Admin/IncidentController.php index f2a10b31..57b11b6c 100644 --- a/app/Http/Controllers/Admin/IncidentController.php +++ b/app/Http/Controllers/Admin/IncidentController.php @@ -4,6 +4,7 @@ namespace CachetHQ\Cachet\Http\Controllers\Admin; use CachetHQ\Cachet\Http\Controllers\AbstractController; use CachetHQ\Cachet\Models\Component; +use CachetHQ\Cachet\Models\ComponentGroup; use CachetHQ\Cachet\Models\Incident; use CachetHQ\Cachet\Models\IncidentTemplate; use GrahamCampbell\Binput\Facades\Binput; @@ -68,10 +69,14 @@ class IncidentController extends AbstractController */ public function showAddIncident() { + $componentsInGroups = ComponentGroup::with('components')->get(); + $componentsOutGroups = Component::where('group_id', 0)->get(); + return View::make('dashboard.incidents.add')->with([ - 'pageTitle' => trans('dashboard.incidents.add.title').' - '.trans('dashboard.dashboard'), - 'components' => Component::all(), - 'incidentTemplates' => IncidentTemplate::all(), + 'pageTitle' => trans('dashboard.incidents.add.title').' - '.trans('dashboard.dashboard'), + 'componentsInGroups' => $componentsInGroups, + 'componentsOutGroups' => $componentsOutGroups, + 'incidentTemplates' => IncidentTemplate::all(), ]); } @@ -248,10 +253,14 @@ class IncidentController extends AbstractController */ public function showEditIncidentAction(Incident $incident) { + $componentsInGroups = ComponentGroup::with('components')->get(); + $componentsOutGroups = Component::where('group_id', 0)->get(); + return View::make('dashboard.incidents.edit')->with([ - 'pageTitle' => trans('dashboard.incidents.edit.title').' - '.trans('dashboard.dashboard'), - 'incident' => $incident, - 'components' => Component::all(), + 'pageTitle' => trans('dashboard.incidents.edit.title').' - '.trans('dashboard.dashboard'), + 'incident' => $incident, + 'componentsInGroups' => $componentsInGroups, + 'componentsOutGroups' => $componentsOutGroups, ]); } diff --git a/app/Http/Controllers/AtomController.php b/app/Http/Controllers/AtomController.php index 4b96666e..a0500438 100644 --- a/app/Http/Controllers/AtomController.php +++ b/app/Http/Controllers/AtomController.php @@ -12,9 +12,11 @@ class AtomController extends AbstractController /** * Generates an Atom feed of all incidents. * + * @param \CachetHQ\Cachet\Models\ComponentGroup|null $group + * * @return \Illuminate\Http\Response */ - public function feedAction() + public function feedAction(ComponentGroup $group = null) { $feed = Feed::make(); $feed->title = Setting::get('app_name'); @@ -23,23 +25,37 @@ class AtomController extends AbstractController $feed->setDateFormat('datetime'); - Incident::all()->map(function ($incident) use ($feed) { - if ($incident->component) { - $componentName = $incident->component->name; - } else { - $componentName = null; - } - - $feed->add( - $incident->name, - Setting::get('app_name'), - Setting::get('app_domain'), - $incident->created_at, - ($componentName === null ? $incident->humanStatus : $componentName.' '.$incident->humanStatus), - $incident->message - ); - }); + if ($group) { + $group->components->map(function ($component) use ($feed) { + $component->incidents->orderBy('created_at', 'desc')->map(function ($incident) use ($feed) { + $this->feedAddItem($feed, $incident); + }); + }); + } else { + Incident::orderBy('created_at', 'desc')->get()->map(function ($incident) use ($feed) { + $this->feedAddItem($feed, $incident); + }); + } return $feed->render('atom'); } + + /** + * Adds an item to the feed. + * + * @param \Thujohn\Rss\Rss $feed + * @param \CachetHQ\Cachet\Models\Incident $incident + * + * @return void + */ + private function feedAddItem(& $feed, $incident) + { + $feed->add( + $incident->name, + Setting::get('app_name'), + Setting::get('app_domain'), + $incident->created_at->toAtomString(), + $incident->message + ); + } } diff --git a/app/Http/Controllers/RssController.php b/app/Http/Controllers/RssController.php index 3b452809..6abc5445 100644 --- a/app/Http/Controllers/RssController.php +++ b/app/Http/Controllers/RssController.php @@ -10,11 +10,13 @@ use Roumen\Feed\Facades\Feed; class RssController extends AbstractController { /** - * Generates an RSS feed of all incidents. + * Generates an Atom feed of all incidents. + * + * @param \CachetHQ\Cachet\Models\ComponentGroup|null $group * * @return \Illuminate\Http\Response */ - public function feedAction() + public function feedAction(ComponentGroup $group = null) { $feed = Feed::make(); $feed->title = Setting::get('app_name'); @@ -23,23 +25,37 @@ class RssController extends AbstractController $feed->setDateFormat('datetime'); - Incident::all()->map(function ($incident) use ($feed) { - if ($incident->component) { - $componentName = $incident->component->name; - } else { - $componentName = null; - } - - $feed->add( - $incident->name, - Setting::get('app_name'), - Setting::get('app_domain'), - $incident->created_at, - ($componentName === null ? $incident->humanStatus : $componentName.' '.$incident->humanStatus), - $incident->message - ); - }); + if ($group) { + $group->components->map(function ($component) use ($feed) { + $component->incidents->orderBy('created_at', 'desc')->map(function ($incident) use ($feed) { + $this->feedAddItem($feed, $incident); + }); + }); + } else { + Incident::orderBy('created_at', 'desc')->get()->map(function ($incident) use ($feed) { + $this->feedAddItem($feed, $incident); + }); + } return $feed->render('rss'); } + + /** + * Adds an item to the feed. + * + * @param \Thujohn\Rss\Rss $feed + * @param \CachetHQ\Cachet\Models\Incident $incident + * + * @return void + */ + private function feedAddItem(& $feed, $incident) + { + $feed->add( + $incident->name, + Setting::get('app_name'), + Setting::get('app_domain'), + $incident->created_at->toAtomString(), + $incident->message + ); + } } diff --git a/app/Http/Routes/StatusPageRoutes.php b/app/Http/Routes/StatusPageRoutes.php index 197fc97b..cbdd5452 100644 --- a/app/Http/Routes/StatusPageRoutes.php +++ b/app/Http/Routes/StatusPageRoutes.php @@ -21,8 +21,8 @@ class StatusPageRoutes 'as' => 'status-page', 'uses' => 'HomeController@showIndex', ]); - $router->get('/atom', 'AtomController@feedAction'); - $router->get('/rss', 'RssController@feedAction'); + $router->get('/atom/{component_group?}', 'AtomController@feedAction'); + $router->get('/rss/{component_group?}', 'RssController@feedAction'); }); } } diff --git a/app/Models/ComponentGroup.php b/app/Models/ComponentGroup.php index 89984697..64572797 100644 --- a/app/Models/ComponentGroup.php +++ b/app/Models/ComponentGroup.php @@ -3,7 +3,6 @@ namespace CachetHQ\Cachet\Models; use Illuminate\Database\Eloquent\Model; -use Illuminate\Database\Eloquent\SoftDeletes; use Watson\Validating\ValidatingTrait; /** @@ -15,7 +14,7 @@ use Watson\Validating\ValidatingTrait; */ class ComponentGroup extends Model { - use SoftDeletes, ValidatingTrait; + use ValidatingTrait; /** * The validation rules. @@ -33,13 +32,6 @@ class ComponentGroup extends Model */ protected $fillable = ['name']; - /** - * The attributes that should be mutated to dates. - * - * @var array - */ - protected $dates = ['deleted_at']; - /** * A group can have many components. * diff --git a/app/Models/Metric.php b/app/Models/Metric.php index 23e90018..6f7e5de8 100644 --- a/app/Models/Metric.php +++ b/app/Models/Metric.php @@ -14,6 +14,8 @@ use Watson\Validating\ValidatingTrait; * @property string $name * @property string $suffix * @property string $description + * @property float $default_value + * @property int $calc_type * @property int $display_chart * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at @@ -90,6 +92,8 @@ class Metric extends Model $queryType = "sum(metric_points.value)"; } elseif ($this->calc_type === self::CALC_AVG) { $queryType = "avg(metric_points.value)"; + } else { + $queryType = "sum(metric_points.value)"; } $query = DB::select("select {$queryType} as aggregate FROM metrics JOIN metric_points ON metric_points.metric_id = metrics.id WHERE to_char(metric_points.created_at, 'YYYYMMDDHH') = :timestamp AND to_char(metric_points.created_at, 'H') = to_char(now() - interval '{$hour} hour', 'H') GROUP BY to_char(metric_points.created_at, 'H')", [ diff --git a/database/migrations/2015_01_05_201324_CreateComponentGroupsTable.php b/database/migrations/2015_01_05_201324_CreateComponentGroupsTable.php index aa555e06..2b7dfe45 100644 --- a/database/migrations/2015_01_05_201324_CreateComponentGroupsTable.php +++ b/database/migrations/2015_01_05_201324_CreateComponentGroupsTable.php @@ -17,7 +17,6 @@ class CreateComponentGroupsTable extends Migration $table->increments('id'); $table->string('name'); $table->timestamps(); - $table->softDeletes(); }); } diff --git a/resources/lang/de/cachet.php b/resources/lang/de/cachet.php index 79d45249..52cae2f9 100644 --- a/resources/lang/de/cachet.php +++ b/resources/lang/de/cachet.php @@ -19,6 +19,7 @@ return [ 'next_week' => 'nächste Woche', 'none' => 'keine Vorfälle', 'status' => [ + 0 => '', 1 => 'Untersuchung läuft', 2 => 'Problem identifiziert', 3 => 'Problem unter Beobachtung', diff --git a/resources/lang/es/cachet.php b/resources/lang/es/cachet.php index d6b2c303..b9a7d449 100644 --- a/resources/lang/es/cachet.php +++ b/resources/lang/es/cachet.php @@ -19,6 +19,7 @@ return [ 'next_week' => 'Siguiente semana', 'none' => 'No hay ninguna incidencia reportada.', 'status' => [ + 0 => '', 1 => 'Investigando', 2 => 'Identificado', 3 => 'Observando', diff --git a/resources/lang/fr/cachet.php b/resources/lang/fr/cachet.php index 3dae3f52..5c0d188a 100644 --- a/resources/lang/fr/cachet.php +++ b/resources/lang/fr/cachet.php @@ -18,10 +18,13 @@ return [ 'previous_week' => 'Semaine précédente', 'next_week' => 'Semaine suivante', 'none' => 'Rien à reporter', + 'scheduled' => 'Maintenance planifiée', + 'scheduled_at' => ', prévue à :timestamp', 'status' => [ + 0 => '', 1 => 'Enquête en cours', 2 => 'Identifié', - 3 => 'Analyse en cours', + 3 => 'Sous surveillance', 4 => 'Corrigé', ], ], @@ -37,6 +40,15 @@ return [ 'revoke' => 'Révoquer cette clé d\'API', ], + // Metrics + 'metrics' => [ + 'filter' => [ + 'hourly' => 'Par heure', + 'daily' => 'Par jour', + 'monthly' => 'Par mois', + ], + ], + // Other 'powered_by' => ':app Status Page est propulsé par Cachet.', 'about_this_site' => 'À propos de ce site', diff --git a/resources/lang/fr/dashboard.php b/resources/lang/fr/dashboard.php index 0357e7cb..bddc46ea 100644 --- a/resources/lang/fr/dashboard.php +++ b/resources/lang/fr/dashboard.php @@ -13,12 +13,12 @@ return [ 'add' => [ 'title' => 'Ajouter un incident', 'success' => 'Incident ajouté.', - 'failure' => 'Il s\'est passé quelque chose avec cet incident.', + 'failure' => 'Une erreur s\'est produite lors de l\'ajout de cet incident.', ], 'edit' => [ 'title' => 'Éditer un incident', 'success' => 'Incident mis-à-jour.', - 'failure' => 'Il s\'est passé quelque chose avec cet incident.', + 'failure' => 'Une erreur s\'est produite lors de la mise à jour de cet incident.', ], // Incident templates @@ -26,7 +26,7 @@ return [ 'add' => [ 'title' => 'Créer un modèle d\'incident', 'success' => 'Modèle créé.', - 'failure' => 'Il s\'est passé quelque chose avec ce modèle d\'incident.', + 'failure' => 'Une erreur s\'est produite lors de l\'ajout de ce modèle d\'incident.', ], 'edit' => [ 'title' => 'Modifier un modèle', @@ -36,34 +36,54 @@ return [ ], ], - // Components - 'components' => [ - 'components' => 'Composant|Composants', - 'component_statuses' => 'Statut des composants', - 'add' => [ - 'title' => 'Créer un composant', - 'message' => 'Commencez par ajouter un composant.', - 'success' => 'Composant créé.', - 'failure' => 'Il s\'est passé quelque chose avec ce composant.', + // Incident Maintenance + 'schedule' => [ + 'schedule' => 'Maintenance planifiée', + 'scheduled_at' => 'Prévue à :timestamp', + 'add' => [ + 'title' => 'Ajouter une maintenance planifiée', + 'success' => 'Maintenance ajoutée.', + 'failure' => 'Une erreur s\'est produite lors de l\'ajout de la maintenance.', ], 'edit' => [ - 'title' => 'Éditer un composant', + 'title' => 'Éditer la maintenance', + 'success' => 'Maintenance mise à jour!', + 'failure' => 'Une erreur s\'est produite lors de la modification de la maintenance.', + ], + 'delete' => [ + 'success' => 'La maintenance a été effacée et ne s\'affihera plus..', + 'failure' => 'La maintenance n\'a pu être effacée. Veuillez essayez de nouveau.', + ], + ], + + // Components + 'components' => [ + 'components' => 'Composantes', + 'component_statuses' => 'Statut des composantes', + 'add' => [ + 'title' => 'Créer une composante', + 'message' => 'Commencez par ajouter une composante.', + 'success' => 'Composante créée.', + 'failure' => 'Une erreur s\'est produite lors de l\'ajout de cette composante.', + ], + 'edit' => [ + 'title' => 'Éditer une composante', 'success' => 'Composant mis-à-jour.', - 'failure' => 'Il s\'est passé quelque chose avec ce composant.', + 'failure' => 'Une erreur s\'est produite lors de la mise à jour de cette composante.', ], // Component groups 'groups' => [ - 'groups' => 'Groupe de composants|Groupes de composants', + 'groups' => 'Groupe de composantes', 'add' => [ - 'title' => 'Ajouter un group de composants', - 'success' => 'Groupe de composants ajouté.', - 'failure' => 'Il s\'est passé quelque chose avec ce composantgroupe de composants.', + 'title' => 'Ajouter un group de composantes', + 'success' => 'Groupe de composantes ajouté.', + 'failure' => 'Une erreur s\'est produite lors de l\'ajout de ce groupe de composantes.', ], 'edit' => [ - 'title' => 'Edit a component group', - 'success' => 'Component group updated.', - 'failure' => 'Something went wrong with the component group.', + 'title' => 'Éditer un groupe de composantes', + 'success' => 'Groupe de composantes mis-à-jour.', + 'failure' => 'Une erreur s\'est produite lors de la mise à jour de ce groupe de composantes.', ], ], ], @@ -77,9 +97,9 @@ return [ 'failure' => 'Il s\'est passé quelque chose avec ce point de mesure.', ], 'edit' => [ - 'title' => 'Edit a metric', - 'success' => 'Metric updated.', - 'failure' => 'Something went wrong with the metric.', + 'title' => 'Éditer un point de mesure', + 'success' => 'Point de mesure mis-à-jour.', + 'failure' => 'Il s\'est passé quelque chose avec ce point de mesure.', ], ], @@ -88,16 +108,16 @@ return [ 'team' => 'Équipe', 'member' => 'Membre', 'profile' => 'Profil', - 'description' => 'Les membres de l\'équipe pourrons ajouter, modifier & éditer les composants et incidents.', + 'description' => 'Les membres de l\'équipe pourrons ajouter, modifier & éditer les composantes et incidents.', 'add' => [ 'title' => 'Ajouter un membre à l\'équipe', 'success' => 'Membre ajouté.', - 'failure' => 'Il s\'est passé quelque chose avec ce membre.', + 'failure' => 'Une erreur s\'est produite lors de l\'ajout de ce membre.', ], 'edit' => [ 'title' => 'Mettre à jour le profil', 'success' => 'Profil mis-à-jour.', - 'failure' => 'Il s\'est passé quelque chose en mettant à jour le profil.', + 'failure' => 'Une erreur s\'est produite lors de la mise à jour du le profil.', ], ], @@ -129,7 +149,7 @@ return [ 'login' => 'Connexion', 'logged_in' => "Vous êtes connecté.", 'welcome' => 'Re-bonjour !', - 'two-factor' => 'Please enter your token.', + 'two-factor' => 'Entrez votre jeton d\'identification.', ], // Sidebar footer @@ -140,22 +160,22 @@ return [ // Notifications 'notifications' => [ 'notifications' => 'Notifications', - 'awesome' => 'Cool.', + 'awesome' => 'Super.', 'whoops' => 'Oups.', ], // Welcome modal 'welcome' => [ - 'welcome' => 'Welcome to Cachet', - 'message' => 'Your status page is almost ready! You might want to configure these extra settings', - 'close' => 'Just go straight to my dashboard', + 'welcome' => 'Bienvenue dans Cachet', + 'message' => 'Votre page d\'état est presque prête! Vous voudrez probablement configurer ces réglages supplémentaires', + 'close' => 'Aller directement au tableau de bord', 'steps' => [ - 'component' => 'Create components', - 'incident' => 'Create incidents', - 'customize' => 'Customize your Cachet Status Page.', - 'team' => 'Add users to your team.', - 'api' => 'Generate API token.', - 'two-factor' => 'Enable Two Factor Authetication.', + 'component' => 'Créer une composante', + 'incident' => 'Créer un incident', + 'customize' => 'Configurer votre Cachet.', + 'team' => 'Ajouter des utilisateurs à votre équipe.', + 'api' => 'Générer un jeton d\'identification API.', + 'two-factor' => 'Activer l\'identification à deux étapes.', ], ], diff --git a/resources/views/dashboard/incidents/add.blade.php b/resources/views/dashboard/incidents/add.blade.php index ceea2ed2..b1523195 100644 --- a/resources/views/dashboard/incidents/add.blade.php +++ b/resources/views/dashboard/incidents/add.blade.php @@ -55,12 +55,19 @@ {{ trans('cachet.incidents.status')[4] }} - @if($components->count() > 0) + @if(!$componentsInGroups->isEmpty() || !$componentsOutGroups->isEmpty())
diff --git a/resources/views/dashboard/incidents/edit.blade.php b/resources/views/dashboard/incidents/edit.blade.php index d2433744..1b16703a 100644 --- a/resources/views/dashboard/incidents/edit.blade.php +++ b/resources/views/dashboard/incidents/edit.blade.php @@ -44,16 +44,23 @@ {{ trans('cachet.incidents.status')[4] }}
- @if($components->count() > 0) -
- - - {{ trans('forms.optional') }} + @if(!$componentsInGroups->isEmpty() || !$componentsOutGroups->isEmpty()) +
+ + + {{ trans('forms.optional') }}
diff --git a/resources/views/dashboard/incidents/templates/index.blade.php b/resources/views/dashboard/incidents/templates/index.blade.php index 92c7470f..076d0d29 100644 --- a/resources/views/dashboard/incidents/templates/index.blade.php +++ b/resources/views/dashboard/incidents/templates/index.blade.php @@ -20,7 +20,6 @@
{{ $template->name }} -

{{ $template->template }}