mirror of
https://github.com/CachetHQ/Cachet.git
synced 2025-04-22 08:22:33 +02:00
Rewrite the entire scheduled maintenance implementation
This commit is contained in:
parent
a2cded299d
commit
ebed68a7d8
@ -1,73 +0,0 @@
|
||||
<?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\Bus\Commands\Incident;
|
||||
|
||||
final class ReportMaintenanceCommand
|
||||
{
|
||||
/**
|
||||
* The maintenance name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* The maintenance message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* Whether to notify about the maintenance or not.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $notify;
|
||||
|
||||
/**
|
||||
* Timestamp of when the maintenance is due to start.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $timestamp;
|
||||
|
||||
/**
|
||||
* The validation rules.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $rules = [
|
||||
'name' => 'required|string',
|
||||
'message' => 'required|string',
|
||||
'notify' => 'nullable|bool',
|
||||
'timestamp' => 'required|string',
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new report maintenance command instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $message
|
||||
* @param bool $notify
|
||||
* @param string $timestamp
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($name, $message, $notify, $timestamp)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->message = $message;
|
||||
$this->notify = $notify;
|
||||
$this->timestamp = $timestamp;
|
||||
}
|
||||
}
|
98
app/Bus/Commands/Schedule/CreateScheduleCommand.php
Normal file
98
app/Bus/Commands/Schedule/CreateScheduleCommand.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?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\Bus\Commands\Schedule;
|
||||
|
||||
/**
|
||||
* This is the create schedule command.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
final class CreateScheduleCommand
|
||||
{
|
||||
/**
|
||||
* The schedule name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* The schedule message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* The schedule status.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $status;
|
||||
|
||||
/**
|
||||
* The schedule date.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $scheduled_at;
|
||||
|
||||
/**
|
||||
* The completed at date.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $completed_at;
|
||||
|
||||
/**
|
||||
* The components affected by the schedule.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $components;
|
||||
|
||||
/**
|
||||
* The validation rules.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $rules = [
|
||||
'name' => 'required|string',
|
||||
'message' => 'nullable|string',
|
||||
'status' => 'required|int|min:0|max:2',
|
||||
'scheduled_at' => 'required|string',
|
||||
'completed_at' => 'nullable|string',
|
||||
'components' => 'required|array',
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new create schedule command instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $message
|
||||
* @param int $status
|
||||
* @param string $scheduled_at
|
||||
* @param string $completed_at
|
||||
* @param array $components
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($name, $message, $status, $scheduled_at, $completed_at, array $components)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->message = $message;
|
||||
$this->status = $status;
|
||||
$this->scheduled_at = $scheduled_at;
|
||||
$this->completed_at = $completed_at;
|
||||
$this->components = $components;
|
||||
}
|
||||
}
|
50
app/Bus/Commands/Schedule/DeleteScheduleCommand.php
Normal file
50
app/Bus/Commands/Schedule/DeleteScheduleCommand.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?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\Bus\Commands\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
|
||||
/**
|
||||
* This is the delete schedule command.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
final class DeleteScheduleCommand
|
||||
{
|
||||
/**
|
||||
* The schedule to delete.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Models\Schedule
|
||||
*/
|
||||
public $schedule;
|
||||
|
||||
/**
|
||||
* The validation rules.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $rules = [
|
||||
'schedule' => 'required',
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new delete schedule command instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Schedule $schedule)
|
||||
{
|
||||
$this->schedule = $schedule;
|
||||
}
|
||||
}
|
110
app/Bus/Commands/Schedule/UpdateScheduleCommand.php
Normal file
110
app/Bus/Commands/Schedule/UpdateScheduleCommand.php
Normal file
@ -0,0 +1,110 @@
|
||||
<?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\Bus\Commands\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
|
||||
/**
|
||||
* This is the update schedule command.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
final class UpdateScheduleCommand
|
||||
{
|
||||
/**
|
||||
* The schedule to update.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Schedule
|
||||
*/
|
||||
public $schedule;
|
||||
|
||||
/**
|
||||
* The schedule name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* The schedule message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $message;
|
||||
|
||||
/**
|
||||
* The schedule status.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $status;
|
||||
|
||||
/**
|
||||
* The schedule date.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $scheduled_at;
|
||||
|
||||
/**
|
||||
* The completed at date.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $completed_at;
|
||||
|
||||
/**
|
||||
* The components affected by the schedule.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $components;
|
||||
|
||||
/**
|
||||
* The validation rules.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $rules = [
|
||||
'schedule' => 'required',
|
||||
'name' => 'nullable|string',
|
||||
'message' => 'nullable|string',
|
||||
'status' => 'nullable|int|min:0|max:2',
|
||||
'scheduled_at' => 'nullable|string',
|
||||
'completed_at' => 'nullable|string',
|
||||
'components' => 'nullable|array',
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new update schedule command instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
* @param string $name
|
||||
* @param string $message
|
||||
* @param int $status
|
||||
* @param string $scheduled_at
|
||||
* @param string $completed_at
|
||||
* @param array $components
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Schedule $schedule, $name, $message, $status, $scheduled_at, $completed_at, array $components = [])
|
||||
{
|
||||
$this->schedule = $schedule;
|
||||
$this->name = $name;
|
||||
$this->message = $message;
|
||||
$this->status = $status;
|
||||
$this->scheduled_at = $scheduled_at;
|
||||
$this->completed_at = $completed_at;
|
||||
$this->components = $components;
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?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\Bus\Events\Incident;
|
||||
|
||||
use CachetHQ\Cachet\Models\Incident;
|
||||
|
||||
final class MaintenanceWasScheduledEvent implements IncidentEventInterface
|
||||
{
|
||||
/**
|
||||
* The incident that has been reported.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Models\Incident
|
||||
*/
|
||||
public $incident;
|
||||
|
||||
/**
|
||||
* Create a new maintenance has scheduled event instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Incident $incident
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Incident $incident)
|
||||
{
|
||||
$this->incident = $incident;
|
||||
}
|
||||
}
|
24
app/Bus/Events/Schedule/ScheduleEventInterface.php
Normal file
24
app/Bus/Events/Schedule/ScheduleEventInterface.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?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\Bus\Events\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Bus\Events\EventInterface;
|
||||
|
||||
/**
|
||||
* This is the schedule event interface.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
interface ScheduleEventInterface extends EventInterface
|
||||
{
|
||||
//
|
||||
}
|
41
app/Bus/Events/Schedule/ScheduleWasCreatedEvent.php
Normal file
41
app/Bus/Events/Schedule/ScheduleWasCreatedEvent.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?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\Bus\Events\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
|
||||
/**
|
||||
* This is the schedule was created event class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
final class ScheduleWasCreatedEvent implements ScheduleEventInterface
|
||||
{
|
||||
/**
|
||||
* The schedule that has been created.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Models\Schedule
|
||||
*/
|
||||
public $schedule;
|
||||
|
||||
/**
|
||||
* Create a new schedule was created event instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Schedule $schedule)
|
||||
{
|
||||
$this->schedule = $schedule;
|
||||
}
|
||||
}
|
41
app/Bus/Events/Schedule/ScheduleWasRemovedEvent.php
Normal file
41
app/Bus/Events/Schedule/ScheduleWasRemovedEvent.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?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\Bus\Events\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
|
||||
/**
|
||||
* This is the schedule was removed event class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
final class ScheduleWasRemovedEvent implements ScheduleEventInterface
|
||||
{
|
||||
/**
|
||||
* The schedule that has been removed.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Models\Schedule
|
||||
*/
|
||||
public $schedule;
|
||||
|
||||
/**
|
||||
* Create a new schedule was removed event instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Schedule $schedule)
|
||||
{
|
||||
$this->schedule = $schedule;
|
||||
}
|
||||
}
|
41
app/Bus/Events/Schedule/ScheduleWasUpdatedEvent.php
Normal file
41
app/Bus/Events/Schedule/ScheduleWasUpdatedEvent.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?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\Bus\Events\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
|
||||
/**
|
||||
* This is the schedule was updated event class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
final class ScheduleWasUpdatedEvent implements ScheduleEventInterface
|
||||
{
|
||||
/**
|
||||
* The schedule that has been updated.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Models\Schedule
|
||||
*/
|
||||
public $schedule;
|
||||
|
||||
/**
|
||||
* Create a new schedule was updated event instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Schedule $schedule)
|
||||
{
|
||||
$this->schedule = $schedule;
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
<?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\Bus\Handlers\Commands\Incident;
|
||||
|
||||
use CachetHQ\Cachet\Bus\Commands\Incident\ReportMaintenanceCommand;
|
||||
use CachetHQ\Cachet\Bus\Events\Incident\MaintenanceWasScheduledEvent;
|
||||
use CachetHQ\Cachet\Dates\DateFactory;
|
||||
use CachetHQ\Cachet\Models\Incident;
|
||||
|
||||
class ReportMaintenanceCommandHandler
|
||||
{
|
||||
/**
|
||||
* The date factory instance.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Dates\DateFactory
|
||||
*/
|
||||
protected $dates;
|
||||
|
||||
/**
|
||||
* Create a new report maintenance command handler instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Dates\DateFactory $dates
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(DateFactory $dates)
|
||||
{
|
||||
$this->dates = $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the report maintenance command.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Bus\Commands\Incident\ReportMaintenanceCommand $command
|
||||
*
|
||||
* @return \CachetHQ\Cachet\Models\Incident
|
||||
*/
|
||||
public function handle(ReportMaintenanceCommand $command)
|
||||
{
|
||||
$scheduledAt = $this->dates->create('d/m/Y H:i', $command->timestamp);
|
||||
|
||||
$maintenanceEvent = Incident::create([
|
||||
'name' => $command->name,
|
||||
'message' => $command->message,
|
||||
'scheduled_at' => $scheduledAt,
|
||||
'status' => 0,
|
||||
'visible' => 1,
|
||||
'stickied' => false,
|
||||
]);
|
||||
|
||||
$maintenanceEvent->notify = (bool) $command->notify;
|
||||
|
||||
event(new MaintenanceWasScheduledEvent($maintenanceEvent));
|
||||
|
||||
return $maintenanceEvent;
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
<?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\Bus\Handlers\Commands\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\CreateScheduleCommand;
|
||||
use CachetHQ\Cachet\Bus\Events\Schedule\ScheduleWasCreatedEvent;
|
||||
use CachetHQ\Cachet\Dates\DateFactory;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
|
||||
/**
|
||||
* This is the create schedule command handler.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class CreateScheduleCommandHandler
|
||||
{
|
||||
/**
|
||||
* The date factory instance.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Dates\DateFactory
|
||||
*/
|
||||
protected $dates;
|
||||
|
||||
/**
|
||||
* Create a new update schedule command handler instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Dates\DateFactory $dates
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(DateFactory $dates)
|
||||
{
|
||||
$this->dates = $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the create schedule command.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Bus\Commands\Schedule\CreateScheduleCommand $command
|
||||
*
|
||||
* @return \CachetHQ\Cachet\Models\Schedule
|
||||
*/
|
||||
public function handle(CreateScheduleCommand $command)
|
||||
{
|
||||
$schedule = Schedule::create($this->filter($command));
|
||||
|
||||
event(new ScheduleWasCreatedEvent($schedule));
|
||||
|
||||
return $schedule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the command data.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Bus\Commands\Schedule\CreateScheduleCommand $command
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function filter(CreateScheduleCommand $command)
|
||||
{
|
||||
$scheduledAt = $this->dates->create('Y-m-d H:i', $command->scheduled_at);
|
||||
|
||||
if ($completedAt = $command->completed_at) {
|
||||
$completedAt = $this->dates->create('Y-m-d H:i', $command->completed_at);
|
||||
}
|
||||
|
||||
$params = [
|
||||
'name' => $command->name,
|
||||
'message' => $command->message,
|
||||
'status' => $command->status,
|
||||
'scheduled_at' => $scheduledAt,
|
||||
'completed_at' => $completedAt,
|
||||
];
|
||||
|
||||
$availableParams = array_filter($params, function ($val) {
|
||||
return $val !== null;
|
||||
});
|
||||
|
||||
return $availableParams;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
<?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\Bus\Handlers\Commands\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\DeleteScheduleCommand;
|
||||
use CachetHQ\Cachet\Bus\Events\Schedule\ScheduleWasRemovedEvent;
|
||||
|
||||
/**
|
||||
* This is the delete schedule command handler.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class DeleteScheduleCommandHandler
|
||||
{
|
||||
/**
|
||||
* Handle the delete schedule command.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Bus\Commands\Schedule\DeleteScheduleCommand $command
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(DeleteScheduleCommand $command)
|
||||
{
|
||||
$schedule = $command->schedule;
|
||||
|
||||
event(new ScheduleWasRemovedEvent($schedule));
|
||||
|
||||
$schedule->delete();
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
<?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\Bus\Handlers\Commands\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\UpdateScheduleCommand;
|
||||
use CachetHQ\Cachet\Bus\Events\Schedule\ScheduleWasUpdatedEvent;
|
||||
use CachetHQ\Cachet\Dates\DateFactory;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
|
||||
/**
|
||||
* This is the update schedule command handler.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class UpdateScheduleCommandHandler
|
||||
{
|
||||
/**
|
||||
* The date factory instance.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Dates\DateFactory
|
||||
*/
|
||||
protected $dates;
|
||||
|
||||
/**
|
||||
* Create a new update schedule command handler instance.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Dates\DateFactory $dates
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(DateFactory $dates)
|
||||
{
|
||||
$this->dates = $dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the update schedule command.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Bus\Commands\Schedule\UpdateScheduleCommand $command
|
||||
*
|
||||
* @return \CachetHQ\Cachet\Models\Schedule
|
||||
*/
|
||||
public function handle(UpdateScheduleCommand $command)
|
||||
{
|
||||
$schedule = $command->schedule;
|
||||
|
||||
$schedule->update($this->filter($command));
|
||||
|
||||
event(new ScheduleWasUpdatedEvent($schedule));
|
||||
|
||||
return $schedule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the command data.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Bus\Commands\Schedule\UpdateScheduleCommand $command
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function filter(UpdateScheduleCommand $command)
|
||||
{
|
||||
$params = [
|
||||
'name' => $command->name,
|
||||
'message' => $command->message,
|
||||
'status' => $command->status,
|
||||
];
|
||||
|
||||
if ($scheduleddAt = $command->scheduled_at) {
|
||||
$params['scheduled_at'] = $this->dates->create('Y-m-d H:i', $scheduledAt);
|
||||
}
|
||||
|
||||
if ($completedAt = $command->completed_at) {
|
||||
$params['completed_at'] = $this->dates->create('Y-m-d H:i', $completedAt);
|
||||
}
|
||||
|
||||
$availableParams = array_filter($params, function ($val) {
|
||||
return $val !== null;
|
||||
});
|
||||
|
||||
return $availableParams;
|
||||
}
|
||||
}
|
@ -9,15 +9,20 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace CachetHQ\Cachet\Bus\Handlers\Events\Incident;
|
||||
namespace CachetHQ\Cachet\Bus\Handlers\Events\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Bus\Events\Incident\MaintenanceWasScheduledEvent;
|
||||
use CachetHQ\Cachet\Bus\Events\Schedule\ScheduleEventInterface;
|
||||
use CachetHQ\Cachet\Models\Subscriber;
|
||||
use Illuminate\Contracts\Mail\MailQueue;
|
||||
use Illuminate\Mail\Message;
|
||||
use McCool\LaravelAutoPresenter\Facades\AutoPresenter;
|
||||
|
||||
class SendMaintenanceEmailNotificationHandler
|
||||
/**
|
||||
* This is the send schedule event notification handler.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class SendScheduleEmailNotificationHandler
|
||||
{
|
||||
/**
|
||||
* The mailer instance.
|
||||
@ -50,21 +55,12 @@ class SendMaintenanceEmailNotificationHandler
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Bus\Events\MaintenanceWasScheduledEvent $event
|
||||
* @param \CachetHQ\Cachet\Bus\Events\Schedule\ScheduleEventInterface $event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(MaintenanceWasScheduledEvent $event)
|
||||
public function handle(ScheduleEventInterface $event)
|
||||
{
|
||||
if (!$event->incident->notify) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only send emails for public incidents.
|
||||
if ($event->incident->visible === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// First notify all global subscribers.
|
||||
$globalSubscribers = $this->subscriber->isVerified()->isGlobal()->get();
|
||||
|
||||
@ -72,10 +68,6 @@ class SendMaintenanceEmailNotificationHandler
|
||||
$this->notify($event, $subscriber);
|
||||
}
|
||||
|
||||
if (!$event->incident->component) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notified = $globalSubscribers->pluck('id')->all();
|
||||
|
||||
// Notify the remaining component specific subscribers.
|
||||
@ -95,12 +87,12 @@ class SendMaintenanceEmailNotificationHandler
|
||||
/**
|
||||
* Send notification to subscriber.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Bus\Events\MaintenanceWasScheduledEvent $event
|
||||
* @param \CachetHQ\Cachet\Models\Subscriber $subscriber
|
||||
* @param \CachetHQ\Cachet\Bus\Events\Schedule\ScheduleEventInterface $event
|
||||
* @param \CachetHQ\Cachet\Models\Subscriber $subscriber
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Collection
|
||||
*/
|
||||
public function notify(MaintenanceWasScheduledEvent $event, $subscriber)
|
||||
public function notify(ScheduleEventInterface $event, $subscriber)
|
||||
{
|
||||
$incident = AutoPresenter::decorate($event->incident);
|
||||
$component = AutoPresenter::decorate($event->incident->component);
|
@ -14,6 +14,7 @@ namespace CachetHQ\Cachet\Composers;
|
||||
use CachetHQ\Cachet\Models\Component;
|
||||
use CachetHQ\Cachet\Models\Incident;
|
||||
use CachetHQ\Cachet\Models\IncidentTemplate;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
use CachetHQ\Cachet\Models\Subscriber;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
@ -34,9 +35,10 @@ class DashboardComposer
|
||||
*/
|
||||
public function compose(View $view)
|
||||
{
|
||||
$view->withIncidentCount(Incident::notScheduled()->count());
|
||||
$view->withComponentCount(Component::count());
|
||||
$view->withIncidentCount(Incident::count());
|
||||
$view->withIncidentTemplateCount(IncidentTemplate::count());
|
||||
$view->withComponentCount(Component::all()->count());
|
||||
$view->withScheduleCount(Schedule::count());
|
||||
$view->withSubscriberCount(Subscriber::isVerified()->count());
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace CachetHQ\Cachet\Composers\Modules;
|
||||
|
||||
use CachetHQ\Cachet\Models\Incident;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
/**
|
||||
@ -31,7 +31,7 @@ class ScheduledComposer
|
||||
*/
|
||||
public function compose(View $view)
|
||||
{
|
||||
$scheduledMaintenance = Incident::scheduled()->orderBy('scheduled_at')->get();
|
||||
$scheduledMaintenance = Schedule::futureSchedules()->orderBy('scheduled_at')->get();
|
||||
|
||||
$view->withScheduledMaintenance($scheduledMaintenance);
|
||||
}
|
||||
|
@ -33,9 +33,10 @@ class StickiedComposer
|
||||
*/
|
||||
public function compose(View $view)
|
||||
{
|
||||
$stickiedIncidents = Incident::stickied()->orderBy('scheduled_at', 'desc')->orderBy('occurred_at', 'desc')->get()->groupBy(function (Incident $incident) {
|
||||
$stickiedIncidents = Incident::stickied()->orderBy('occurred_at', 'desc')->get()->groupBy(function (Incident $incident) {
|
||||
return app(DateFactory::class)->make($incident->is_scheduled ? $incident->scheduled_at : $incident->occurred_at)->toDateString();
|
||||
});
|
||||
|
||||
$view->withStickiedIncidents($stickiedIncidents);
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ use CachetHQ\Cachet\Models\IncidentTemplate;
|
||||
use CachetHQ\Cachet\Models\IncidentUpdate;
|
||||
use CachetHQ\Cachet\Models\Metric;
|
||||
use CachetHQ\Cachet\Models\MetricPoint;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
use CachetHQ\Cachet\Models\Subscriber;
|
||||
use CachetHQ\Cachet\Models\User;
|
||||
use CachetHQ\Cachet\Settings\Repository;
|
||||
@ -89,6 +90,7 @@ class DemoSeederCommand extends Command
|
||||
$this->seedIncidentTemplates();
|
||||
$this->seedMetricPoints();
|
||||
$this->seedMetrics();
|
||||
$this->seedSchedules();
|
||||
$this->seedSettings();
|
||||
$this->seedSubscribers();
|
||||
$this->seedUsers();
|
||||
@ -207,7 +209,6 @@ EINCIDENT;
|
||||
'message' => 'We\'re investigating an issue with our monkeys not performing as they should be.',
|
||||
'status' => Incident::INVESTIGATING,
|
||||
'component_id' => 0,
|
||||
'scheduled_at' => null,
|
||||
'visible' => 1,
|
||||
'stickied' => false,
|
||||
'occurred_at' => Carbon::now(),
|
||||
@ -217,7 +218,6 @@ EINCIDENT;
|
||||
'message' => 'Unresolved incidents are left without a **Fixed** update.',
|
||||
'status' => Incident::INVESTIGATING,
|
||||
'component_id' => 0,
|
||||
'scheduled_at' => null,
|
||||
'visible' => 1,
|
||||
'stickied' => false,
|
||||
'occurred_at' => Carbon::now(),
|
||||
@ -332,6 +332,27 @@ EINCIDENT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Seed the schedules table.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function seedSchedules()
|
||||
{
|
||||
$defaultSchedules = [
|
||||
[
|
||||
'name' => 'Demo resets every half hour!',
|
||||
'message' => 'You can schedule downtime for _your_ service!',
|
||||
'status' => Schedule::UPCOMING,
|
||||
'scheduled_at' => (new DateTime())->add(new DateInterval('PT2H')),
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($defaultSchedules as $schedule) {
|
||||
Schedule::create($schedule);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Seed the settings table.
|
||||
*
|
||||
|
@ -69,9 +69,6 @@ class EventServiceProvider extends ServiceProvider
|
||||
'CachetHQ\Cachet\Bus\Events\Incident\IncidentWasRemovedEvent' => [
|
||||
//
|
||||
],
|
||||
'CachetHQ\Cachet\Bus\Events\Incident\MaintenanceWasScheduledEvent' => [
|
||||
'CachetHQ\Cachet\Bus\Handlers\Events\Incident\SendMaintenanceEmailNotificationHandler',
|
||||
],
|
||||
'CachetHQ\Cachet\Bus\Events\Invite\InviteWasClaimedEvent' => [
|
||||
//
|
||||
],
|
||||
@ -93,6 +90,15 @@ class EventServiceProvider extends ServiceProvider
|
||||
'CachetHQ\Cachet\Bus\Events\Metric\MetricWasUpdatedEvent' => [
|
||||
//
|
||||
],
|
||||
'CachetHQ\Cachet\Bus\Events\Schedule\ScheduleWasCreatedEvent' => [
|
||||
// 'CachetHQ\Cachet\Bus\Handlers\Events\Schedule\SendScheduleEmailNotificationHandler',
|
||||
],
|
||||
'CachetHQ\Cachet\Bus\Events\Schedule\ScheduleWasRemovedEvent' => [
|
||||
//
|
||||
],
|
||||
'CachetHQ\Cachet\Bus\Events\Schedule\ScheduleWasUpdatedEvent' => [
|
||||
//
|
||||
],
|
||||
'CachetHQ\Cachet\Bus\Events\Subscriber\SubscriberHasSubscribedEvent' => [
|
||||
'CachetHQ\Cachet\Bus\Handlers\Events\Subscriber\SendSubscriberVerificationEmailHandler',
|
||||
],
|
||||
|
@ -69,6 +69,7 @@ class RouteServiceProvider extends ServiceProvider
|
||||
$router->model('incident_update', 'CachetHQ\Cachet\Models\IncidentUpdate');
|
||||
$router->model('metric', 'CachetHQ\Cachet\Models\Metric');
|
||||
$router->model('metric_point', 'CachetHQ\Cachet\Models\MetricPoint');
|
||||
$router->model('schedule', 'CachetHQ\Cachet\Models\Schedule');
|
||||
$router->model('setting', 'CachetHQ\Cachet\Models\Setting');
|
||||
$router->model('subscriber', 'CachetHQ\Cachet\Models\Subscriber');
|
||||
$router->model('subscription', 'CachetHQ\Cachet\Models\Subscription');
|
||||
|
128
app/Http/Controllers/Api/ScheduleController.php
Normal file
128
app/Http/Controllers/Api/ScheduleController.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?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\Http\Controllers\Api;
|
||||
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\CreateScheduleCommand;
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\DeleteScheduleCommand;
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\UpdateScheduleCommand;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
use GrahamCampbell\Binput\Facades\Binput;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||
|
||||
/**
|
||||
* This is the schedule controller.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class ScheduleController extends AbstractApiController
|
||||
{
|
||||
/**
|
||||
* Return all schedules.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getSchedules()
|
||||
{
|
||||
$schedule = Schedule::whereRaw('1 = 1');
|
||||
|
||||
if ($sortBy = Binput::get('sort')) {
|
||||
$direction = Binput::has('order') && Binput::get('order') == 'desc';
|
||||
|
||||
$schedule->sort($sortBy, $direction);
|
||||
}
|
||||
|
||||
$schedule = $schedule->paginate(Binput::get('per_page', 20));
|
||||
|
||||
return $this->paginator($schedule, Request::instance());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a single schedule.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function getSchedule(Schedule $schedule)
|
||||
{
|
||||
return $this->item($schedule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new schedule.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function postSchedule()
|
||||
{
|
||||
try {
|
||||
$schedule = dispatch(new CreateScheduleCommand(
|
||||
Binput::get('name'),
|
||||
Binput::get('message'),
|
||||
Binput::get('status'),
|
||||
Binput::get('scheduled_at'),
|
||||
Binput::get('completed_at'),
|
||||
Binput::get('components', [])
|
||||
));
|
||||
} catch (QueryException $e) {
|
||||
throw new BadRequestHttpException();
|
||||
}
|
||||
|
||||
return $this->item($schedule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a schedule.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function putSchedule(Schedule $schedule)
|
||||
{
|
||||
try {
|
||||
$schedule = dispatch(new UpdateScheduleCommand(
|
||||
$schedule,
|
||||
Binput::get('name'),
|
||||
Binput::get('message'),
|
||||
Binput::get('status'),
|
||||
Binput::get('scheduled_at'),
|
||||
Binput::get('completed_at'),
|
||||
Binput::get('components', [])
|
||||
));
|
||||
} catch (QueryException $e) {
|
||||
throw new BadRequestHttpException();
|
||||
}
|
||||
|
||||
return $this->item($schedule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a schedule.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function deleteSchedule(Schedule $schedule)
|
||||
{
|
||||
try {
|
||||
dispatch(new DeleteScheduleCommand($schedule));
|
||||
} catch (QueryException $e) {
|
||||
throw new BadRequestHttpException();
|
||||
}
|
||||
|
||||
return $this->noContent();
|
||||
}
|
||||
}
|
@ -127,7 +127,7 @@ class DashboardController extends Controller
|
||||
*/
|
||||
protected function getIncidents()
|
||||
{
|
||||
$allIncidents = Incident::notScheduled()->whereBetween('occurred_at', [
|
||||
$allIncidents = Incident::whereBetween('occurred_at', [
|
||||
$this->startDate->copy()->subDays(30)->format('Y-m-d').' 00:00:00',
|
||||
$this->startDate->format('Y-m-d').' 23:59:59',
|
||||
])->orderBy('occurred_at', 'desc')->get()->groupBy(function (Incident $incident) {
|
||||
|
@ -57,22 +57,6 @@ class IncidentController extends Controller
|
||||
{
|
||||
$this->auth = $auth;
|
||||
|
||||
$this->subMenu = [
|
||||
'incidents' => [
|
||||
'title' => trans('dashboard.incidents.incidents'),
|
||||
'url' => cachet_route('dashboard.incidents'),
|
||||
'icon' => 'ion-android-checkmark-circle',
|
||||
'active' => true,
|
||||
],
|
||||
'schedule' => [
|
||||
'title' => trans('dashboard.schedule.schedule'),
|
||||
'url' => cachet_route('dashboard.schedule'),
|
||||
'icon' => 'ion-android-calendar',
|
||||
'active' => false,
|
||||
],
|
||||
];
|
||||
|
||||
View::share('sub_menu', $this->subMenu);
|
||||
View::share('sub_title', trans('dashboard.incidents.title'));
|
||||
}
|
||||
|
||||
@ -83,7 +67,7 @@ class IncidentController extends Controller
|
||||
*/
|
||||
public function showIncidents()
|
||||
{
|
||||
$incidents = Incident::notScheduled()->orderBy('created_at', 'desc')->get();
|
||||
$incidents = Incident::orderBy('created_at', 'desc')->get();
|
||||
|
||||
return View::make('dashboard.incidents.index')
|
||||
->withPageTitle(trans('dashboard.incidents.incidents').' - '.trans('dashboard.dashboard'))
|
||||
|
@ -12,16 +12,20 @@
|
||||
namespace CachetHQ\Cachet\Http\Controllers\Dashboard;
|
||||
|
||||
use AltThree\Validator\ValidationException;
|
||||
use CachetHQ\Cachet\Bus\Commands\Incident\ReportMaintenanceCommand;
|
||||
use CachetHQ\Cachet\Dates\DateFactory;
|
||||
use CachetHQ\Cachet\Models\Incident;
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\CreateScheduleCommand;
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\DeleteScheduleCommand;
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\UpdateScheduleCommand;
|
||||
use CachetHQ\Cachet\Models\IncidentTemplate;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
use GrahamCampbell\Binput\Facades\Binput;
|
||||
use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\MessageBag;
|
||||
use Jenssegers\Date\Date;
|
||||
|
||||
/**
|
||||
* This is the schedule controller class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class ScheduleController extends Controller
|
||||
{
|
||||
/**
|
||||
@ -38,23 +42,7 @@ class ScheduleController extends Controller
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->subMenu = [
|
||||
'incidents' => [
|
||||
'title' => trans('dashboard.incidents.incidents'),
|
||||
'url' => cachet_route('dashboard.incidents'),
|
||||
'icon' => 'ion-android-checkmark-circle',
|
||||
'active' => false,
|
||||
],
|
||||
'schedule' => [
|
||||
'title' => trans('dashboard.schedule.schedule'),
|
||||
'url' => cachet_route('dashboard.schedule'),
|
||||
'icon' => 'ion-android-calendar',
|
||||
'active' => true,
|
||||
],
|
||||
];
|
||||
|
||||
View::share('sub_menu', $this->subMenu);
|
||||
View::share('sub_title', trans('dashboard.incidents.title'));
|
||||
View::share('sub_title', trans('dashboard.schedule.title'));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,7 +52,7 @@ class ScheduleController extends Controller
|
||||
*/
|
||||
public function showIndex()
|
||||
{
|
||||
$schedule = Incident::scheduled()->orderBy('created_at')->get();
|
||||
$schedule = Schedule::orderBy('created_at')->get();
|
||||
|
||||
return View::make('dashboard.schedule.index')
|
||||
->withPageTitle(trans('dashboard.schedule.schedule').' - '.trans('dashboard.dashboard'))
|
||||
@ -86,18 +74,20 @@ class ScheduleController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new scheduled maintenance "incident".
|
||||
* Creates a new scheduled maintenance.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function addScheduleAction()
|
||||
{
|
||||
try {
|
||||
$incident = dispatch(new ReportMaintenanceCommand(
|
||||
dispatch(new CreateScheduleCommand(
|
||||
Binput::get('name'),
|
||||
Binput::get('message'),
|
||||
Binput::get('notify'),
|
||||
Binput::get('scheduled_at')
|
||||
Binput::get('status', Schedule::UPCOMING),
|
||||
Binput::get('scheduled_at'),
|
||||
Binput::get('completed_at'),
|
||||
Binput::get('components', [])
|
||||
));
|
||||
} catch (ValidationException $e) {
|
||||
return cachet_redirect('dashboard.schedule.create')
|
||||
@ -113,11 +103,11 @@ class ScheduleController extends Controller
|
||||
/**
|
||||
* Shows the edit schedule maintenance form.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Incident $schedule
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showEditSchedule(Incident $schedule)
|
||||
public function showEditSchedule(Schedule $schedule)
|
||||
{
|
||||
$incidentTemplates = IncidentTemplate::all();
|
||||
|
||||
@ -130,30 +120,22 @@ class ScheduleController extends Controller
|
||||
/**
|
||||
* Updates the given incident.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Incident $schedule
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function editScheduleAction(Incident $schedule)
|
||||
public function editScheduleAction(Schedule $schedule)
|
||||
{
|
||||
$scheduleData = Binput::get('incident');
|
||||
|
||||
// Parse the schedule date.
|
||||
$scheduledAt = app(DateFactory::class)->create('d/m/Y H:i', $scheduleData['scheduled_at']);
|
||||
|
||||
if ($scheduledAt->isPast()) {
|
||||
$messageBag = new MessageBag();
|
||||
$messageBag->add('scheduled_at', trans('validation.date', ['attribute' => 'scheduled time you supplied']));
|
||||
|
||||
return cachet_redirect('dashboard.schedule.edit', [$schedule->id])->withErrors($messageBag);
|
||||
}
|
||||
|
||||
$scheduleData['scheduled_at'] = $scheduledAt;
|
||||
// Bypass the incident.status field.
|
||||
$scheduleData['status'] = 0;
|
||||
|
||||
try {
|
||||
$schedule->update($scheduleData);
|
||||
$schedule = dispatch(new UpdateScheduleCommand(
|
||||
$schedule,
|
||||
Binput::get('name', null),
|
||||
Binput::get('message', null),
|
||||
Binput::get('status', null),
|
||||
Binput::get('scheduled_at', null),
|
||||
Binput::get('completed_at', null),
|
||||
Binput::get('components', [])
|
||||
));
|
||||
} catch (ValidationException $e) {
|
||||
return cachet_redirect('dashboard.schedule.edit', [$schedule->id])
|
||||
->withInput(Binput::all())
|
||||
@ -168,13 +150,13 @@ class ScheduleController extends Controller
|
||||
/**
|
||||
* Deletes a given schedule.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Incident $schedule
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function deleteScheduleAction(Incident $schedule)
|
||||
public function deleteScheduleAction(Schedule $schedule)
|
||||
{
|
||||
$schedule->delete();
|
||||
dispatch(new DeleteScheduleCommand($schedule));
|
||||
|
||||
return cachet_redirect('dashboard.schedule')
|
||||
->withSuccess(sprintf('%s %s', trans('dashboard.notifications.awesome'), trans('dashboard.schedule.delete.success')));
|
||||
|
@ -17,6 +17,7 @@ use CachetHQ\Cachet\Http\Controllers\Api\AbstractApiController;
|
||||
use CachetHQ\Cachet\Models\Component;
|
||||
use CachetHQ\Cachet\Models\Incident;
|
||||
use CachetHQ\Cachet\Models\Metric;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
use CachetHQ\Cachet\Repositories\Metric\MetricRepository;
|
||||
use Exception;
|
||||
use GrahamCampbell\Binput\Facades\Binput;
|
||||
@ -84,11 +85,11 @@ class StatusPageController extends AbstractApiController
|
||||
|
||||
$incidentVisibility = Auth::check() ? 0 : 1;
|
||||
|
||||
$allIncidents = Incident::notScheduled()->where('visible', '>=', $incidentVisibility)->whereBetween('occurred_at', [
|
||||
$allIncidents = Incident::where('visible', '>=', $incidentVisibility)->whereBetween('occurred_at', [
|
||||
$startDate->copy()->subDays($daysToShow)->format('Y-m-d').' 00:00:00',
|
||||
$startDate->format('Y-m-d').' 23:59:59',
|
||||
])->orderBy('scheduled_at', 'desc')->orderBy('occurred_at', 'desc')->get()->groupBy(function (Incident $incident) {
|
||||
return app(DateFactory::class)->make($incident->is_scheduled ? $incident->scheduled_at : $incident->occurred_at)->toDateString();
|
||||
])->orderBy('occurred_at', 'desc')->get()->groupBy(function (Incident $incident) {
|
||||
return app(DateFactory::class)->make($incident->occurred_at)->toDateString();
|
||||
});
|
||||
|
||||
// Add in days that have no incidents
|
||||
@ -111,7 +112,7 @@ class StatusPageController extends AbstractApiController
|
||||
->withDaysToShow($daysToShow)
|
||||
->withAllIncidents($allIncidents)
|
||||
->withCanPageForward((bool) $today->gt($startDate))
|
||||
->withCanPageBackward(Incident::notScheduled()->where('occurred_at', '<', $startDate->format('Y-m-d'))->count() > 0)
|
||||
->withCanPageBackward(Incident::where('occurred_at', '<', $startDate->format('Y-m-d'))->count() > 0)
|
||||
->withPreviousDate($startDate->copy()->subDays($daysToShow)->toDateString())
|
||||
->withNextDate($startDate->copy()->addDays($daysToShow)->toDateString());
|
||||
}
|
||||
@ -125,8 +126,19 @@ class StatusPageController extends AbstractApiController
|
||||
*/
|
||||
public function showIncident(Incident $incident)
|
||||
{
|
||||
return View::make('single-incident')
|
||||
->withIncident($incident);
|
||||
return View::make('single-incident')->withIncident($incident);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a single schedule.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $schedule
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showSchedule(Schedule $schedule)
|
||||
{
|
||||
return View::make('single-schedule')->withSchedule($schedule);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,6 +59,9 @@ class ApiRoutes
|
||||
$router->get('metrics', 'MetricController@getMetrics');
|
||||
$router->get('metrics/{metric}', 'MetricController@getMetric');
|
||||
$router->get('metrics/{metric}/points', 'MetricController@getMetricPoints');
|
||||
|
||||
$router->get('schedules', 'ScheduleController@getSchedules');
|
||||
$router->get('schedules/{schedule}', 'ScheduleController@getSchedule');
|
||||
});
|
||||
|
||||
$router->group(['middleware' => ['auth.api:true']], function (Registrar $router) {
|
||||
@ -70,6 +73,7 @@ class ApiRoutes
|
||||
$router->post('incidents/{incident}/updates', 'IncidentUpdateController@postIncidentUpdate');
|
||||
$router->post('metrics', 'MetricController@postMetrics');
|
||||
$router->post('metrics/{metric}/points', 'MetricPointController@postMetricPoints');
|
||||
$router->post('schedules', 'ScheduleController@postSchedule');
|
||||
$router->post('subscribers', 'SubscriberController@postSubscribers');
|
||||
|
||||
$router->put('components/groups/{component_group}', 'ComponentGroupController@putGroup');
|
||||
@ -78,6 +82,7 @@ class ApiRoutes
|
||||
$router->put('incidents/{incident}/updates/{update}', 'IncidentUpdateController@putIncidentUpdate');
|
||||
$router->put('metrics/{metric}', 'MetricController@putMetric');
|
||||
$router->put('metrics/{metric}/points/{metric_point}', 'MetricPointController@putMetricPoint');
|
||||
$router->put('schedules/{schedule}', 'ScheduleController@putSchedule');
|
||||
|
||||
$router->delete('components/groups/{component_group}', 'ComponentGroupController@deleteGroup');
|
||||
$router->delete('components/{component}', 'ComponentController@deleteComponent');
|
||||
@ -85,6 +90,7 @@ class ApiRoutes
|
||||
$router->delete('incidents/{incident}/updates/{update}', 'IncidentUpdateController@deleteIncidentUpdate');
|
||||
$router->delete('metrics/{metric}', 'MetricController@deleteMetric');
|
||||
$router->delete('metrics/{metric}/points/{metric_point}', 'MetricPointController@deleteMetricPoint');
|
||||
$router->delete('schedules/{schedule}', 'ScheduleController@deleteSchedule');
|
||||
$router->delete('subscribers/{subscriber}', 'SubscriberController@deleteSubscriber');
|
||||
$router->delete('subscriptions/{subscription}', 'SubscriberController@deleteSubscription');
|
||||
});
|
||||
|
@ -56,15 +56,15 @@ class ScheduleRoutes
|
||||
'uses' => 'ScheduleController@addScheduleAction',
|
||||
]);
|
||||
|
||||
$router->get('{incident}', [
|
||||
$router->get('{schedule}', [
|
||||
'as' => 'get:dashboard.schedule.edit',
|
||||
'uses' => 'ScheduleController@showEditSchedule',
|
||||
]);
|
||||
$router->post('{incident}', [
|
||||
$router->post('{schedule}', [
|
||||
'as' => 'post:dashboard.schedule.edit',
|
||||
'uses' => 'ScheduleController@editScheduleAction',
|
||||
]);
|
||||
$router->delete('{incident}', [
|
||||
$router->delete('{schedule}', [
|
||||
'as' => 'delete:dashboard.schedule.delete',
|
||||
'uses' => 'ScheduleController@deleteScheduleAction',
|
||||
]);
|
||||
|
@ -49,6 +49,11 @@ class StatusPageRoutes
|
||||
'uses' => 'StatusPageController@showIncident',
|
||||
]);
|
||||
|
||||
$router->get('schedules/{schedule}', [
|
||||
'as' => 'get:schedule',
|
||||
'uses' => 'StatusPageController@showSchedule',
|
||||
]);
|
||||
|
||||
$router->get('metrics/{metric}', [
|
||||
'as' => 'get:metric',
|
||||
'uses' => 'StatusPageController@getMetrics',
|
||||
|
@ -49,7 +49,7 @@ class System implements SystemContract
|
||||
];
|
||||
} elseif ($enabledScope->notStatus(1)->count() === 0) {
|
||||
// If all our components are ok, do we have any non-fixed incidents?
|
||||
$incidents = Incident::notScheduled()->orderBy('occurred_at', 'desc')->get()->filter(function ($incident) {
|
||||
$incidents = Incident::orderBy('occurred_at', 'desc')->get()->filter(function ($incident) {
|
||||
return $incident->status > 0;
|
||||
});
|
||||
$incidentCount = $incidents->count();
|
||||
|
@ -15,7 +15,6 @@ use AltThree\Validator\ValidatingTrait;
|
||||
use CachetHQ\Cachet\Models\Traits\SearchableTrait;
|
||||
use CachetHQ\Cachet\Models\Traits\SortableTrait;
|
||||
use CachetHQ\Cachet\Presenters\IncidentPresenter;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@ -75,11 +74,10 @@ class Incident extends Model implements HasPresenter
|
||||
* @var string[]
|
||||
*/
|
||||
protected $casts = [
|
||||
'visible' => 'int',
|
||||
'stickied' => 'bool',
|
||||
'scheduled_at' => 'date',
|
||||
'occurred_at' => 'date',
|
||||
'deleted_at' => 'date',
|
||||
'visible' => 'int',
|
||||
'stickied' => 'bool',
|
||||
'occurred_at' => 'date',
|
||||
'deleted_at' => 'date',
|
||||
];
|
||||
|
||||
/**
|
||||
@ -94,7 +92,6 @@ class Incident extends Model implements HasPresenter
|
||||
'visible',
|
||||
'stickied',
|
||||
'message',
|
||||
'scheduled_at',
|
||||
'occurred_at',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
@ -194,44 +191,6 @@ class Incident extends Model implements HasPresenter
|
||||
return $query->where('stickied', '=', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all scheduled incidents (maintenance).
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeScheduled(Builder $query)
|
||||
{
|
||||
return $query->where('status', '=', 0)->where('scheduled_at', '>=', Carbon::now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all non-scheduled incidents.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeNotScheduled(Builder $query)
|
||||
{
|
||||
return $query->where('status', '>', 0)->orWhere(function ($query) {
|
||||
$query->where('status', '=', 0)->where(function ($query) {
|
||||
$query->whereNull('scheduled_at')->orWhere('scheduled_at', '<=', Carbon::now());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the "incident" is scheduled or not.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsScheduledAttribute()
|
||||
{
|
||||
return $this->getOriginal('scheduled_at') !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the incident resolved?
|
||||
*
|
||||
|
162
app/Models/Schedule.php
Normal file
162
app/Models/Schedule.php
Normal file
@ -0,0 +1,162 @@
|
||||
<?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\Models;
|
||||
|
||||
use AltThree\Validator\ValidatingTrait;
|
||||
use CachetHQ\Cachet\Models\Traits\SearchableTrait;
|
||||
use CachetHQ\Cachet\Models\Traits\SortableTrait;
|
||||
use CachetHQ\Cachet\Presenters\SchedulePresenter;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use McCool\LaravelAutoPresenter\HasPresenter;
|
||||
|
||||
class Schedule extends Model implements HasPresenter
|
||||
{
|
||||
use SearchableTrait, SortableTrait, ValidatingTrait;
|
||||
|
||||
/**
|
||||
* The upcoming status.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const UPCOMING = 0;
|
||||
|
||||
/**
|
||||
* The in progress status.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const IN_PROGRESS = 1;
|
||||
|
||||
/**
|
||||
* The complete status.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const COMPLETE = 2;
|
||||
|
||||
/**
|
||||
* The attributes that should be casted to native types.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $casts = [
|
||||
'name' => 'string',
|
||||
'message' => 'string',
|
||||
'status' => 'int',
|
||||
'scheduled_at' => 'date',
|
||||
'completed_at' => 'date',
|
||||
];
|
||||
|
||||
/**
|
||||
* The fillable properties.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'message',
|
||||
'status',
|
||||
'scheduled_at',
|
||||
'completed_at',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/**
|
||||
* The validation rules.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $rules = [
|
||||
'name' => 'required|string',
|
||||
'message' => 'nullable|string',
|
||||
'status' => 'required|int|between:0,2',
|
||||
];
|
||||
|
||||
/**
|
||||
* The searchable fields.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $searchable = [
|
||||
'id',
|
||||
'name',
|
||||
'status',
|
||||
];
|
||||
|
||||
/**
|
||||
* The sortable fields.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $sortable = [
|
||||
'id',
|
||||
'name',
|
||||
'status',
|
||||
'scheduled_at',
|
||||
'completed_at',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/**
|
||||
* The relations to eager load on every query.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $with = ['components'];
|
||||
|
||||
/**
|
||||
* Scopes schedules to those in the future.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopeFutureSchedules($query)
|
||||
{
|
||||
return $query->whereIn('status', [self::UPCOMING, self::IN_PROGRESS])->where('scheduled_at', '>=', Carbon::now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Scopes schedules to those in the past.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public function scopePastSchedules($query)
|
||||
{
|
||||
return $query->where('status', '<', self::COMPLETE)->where('scheduled_at', '<=', Carbon::now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the components relation.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function components()
|
||||
{
|
||||
return $this->hasMany(ScheduleComponent::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the presenter class.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPresenterClass()
|
||||
{
|
||||
return SchedulePresenter::class;
|
||||
}
|
||||
}
|
73
app/Models/ScheduleComponent.php
Normal file
73
app/Models/ScheduleComponent.php
Normal file
@ -0,0 +1,73 @@
|
||||
<?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\Models;
|
||||
|
||||
use AltThree\Validator\ValidatingTrait;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ScheduleComponent extends Model
|
||||
{
|
||||
use ValidatingTrait;
|
||||
|
||||
/**
|
||||
* The attributes that should be casted to native types.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $casts = [
|
||||
'schedule_id' => 'int',
|
||||
'component_id' => 'int',
|
||||
'component_status' => 'int',
|
||||
];
|
||||
|
||||
/**
|
||||
* The fillable properties.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'schedule_id',
|
||||
'component_id',
|
||||
'component_status',
|
||||
];
|
||||
|
||||
/**
|
||||
* The validation rules.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $rules = [
|
||||
'schedule_id' => 'required|int',
|
||||
'component_id' => 'required|int',
|
||||
'component_status' => 'required|int',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the schedule relation.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function schedule()
|
||||
{
|
||||
return $this->belongsTo(Schedule::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the component relation.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||
*/
|
||||
public function component()
|
||||
{
|
||||
return $this->hasOne(Component::class);
|
||||
}
|
||||
}
|
@ -157,56 +157,6 @@ class IncidentPresenter extends BasePresenter implements Arrayable
|
||||
return $this->dates->make($this->wrappedObject->created_at)->toISO8601String();
|
||||
}
|
||||
|
||||
/**
|
||||
* Present formatted date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function scheduled_at()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->scheduled_at)->toDateTimeString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Present diff for humans date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function scheduled_at_diff()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->scheduled_at)->diffForHumans();
|
||||
}
|
||||
|
||||
/**
|
||||
* Present formatted date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function scheduled_at_formatted()
|
||||
{
|
||||
return ucfirst($this->dates->make($this->wrappedObject->scheduled_at)->format($this->incidentDateFormat()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Present formatted date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function scheduled_at_iso()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->scheduled_at)->toISO8601String();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the scheduled_at time ready to be used by bootstrap-datetimepicker.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function scheduled_at_datetimepicker()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->scheduled_at)->format('d/m/Y H:i');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted timestamp for use within the timeline.
|
||||
*
|
||||
@ -214,10 +164,6 @@ class IncidentPresenter extends BasePresenter implements Arrayable
|
||||
*/
|
||||
public function timestamp_formatted()
|
||||
{
|
||||
if ($this->wrappedObject->is_scheduled) {
|
||||
return $this->scheduled_at_formatted;
|
||||
}
|
||||
|
||||
return $this->occurred_at_formatted;
|
||||
}
|
||||
|
||||
@ -228,10 +174,6 @@ class IncidentPresenter extends BasePresenter implements Arrayable
|
||||
*/
|
||||
public function timestamp_iso()
|
||||
{
|
||||
if ($this->wrappedObject->is_scheduled) {
|
||||
return $this->scheduled_at_iso;
|
||||
}
|
||||
|
||||
return $this->occurred_at_iso;
|
||||
}
|
||||
|
||||
@ -352,7 +294,6 @@ class IncidentPresenter extends BasePresenter implements Arrayable
|
||||
'latest_icon' => $this->latest_icon(),
|
||||
'permalink' => $this->permalink(),
|
||||
'duration' => $this->duration(),
|
||||
'scheduled_at' => $this->scheduled_at(),
|
||||
'occurred_at' => $this->occurred_at(),
|
||||
'created_at' => $this->created_at(),
|
||||
'updated_at' => $this->updated_at(),
|
||||
|
261
app/Presenters/SchedulePresenter.php
Normal file
261
app/Presenters/SchedulePresenter.php
Normal file
@ -0,0 +1,261 @@
|
||||
<?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\Presenters;
|
||||
|
||||
use CachetHQ\Cachet\Dates\DateFactory;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
use CachetHQ\Cachet\Presenters\Traits\TimestampsTrait;
|
||||
use GrahamCampbell\Markdown\Facades\Markdown;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use McCool\LaravelAutoPresenter\BasePresenter;
|
||||
|
||||
/**
|
||||
* This is the schedule presenter class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class SchedulePresenter extends BasePresenter implements Arrayable
|
||||
{
|
||||
use TimestampsTrait;
|
||||
|
||||
/**
|
||||
* The date factory instance.
|
||||
*
|
||||
* @var \CachetHQ\Cachet\Dates\DateFactory
|
||||
*/
|
||||
protected $dates;
|
||||
|
||||
/**
|
||||
* Create a new presenter.
|
||||
*
|
||||
* @param \CachetHQ\Cachet\Dates\DateFactory $dates
|
||||
* @param \CachetHQ\Cachet\Models\Schedule $resource
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(DateFactory $dates, Schedule $resource)
|
||||
{
|
||||
$this->dates = $dates;
|
||||
|
||||
parent::__construct($resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the message from Markdown into HTML.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function formattedMessage()
|
||||
{
|
||||
return Markdown::convertToHtml($this->wrappedObject->message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Present diff for humans date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function created_at_diff()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->created_at)->diffForHumans();
|
||||
}
|
||||
|
||||
/**
|
||||
* Present formatted date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function created_at_formatted()
|
||||
{
|
||||
return ucfirst($this->dates->make($this->wrappedObject->created_at)->format($this->incidentDateFormat()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the created_at time ready to be used by bootstrap-datetimepicker.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function created_at_datetimepicker()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->created_at)->format('Y-m-d H:i');
|
||||
}
|
||||
|
||||
/**
|
||||
* Present formatted date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function created_at_iso()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->created_at)->toISO8601String();
|
||||
}
|
||||
|
||||
/**
|
||||
* Present formatted date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function scheduled_at()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->scheduled_at)->toDateTimeString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Present diff for humans date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function scheduled_at_diff()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->scheduled_at)->diffForHumans();
|
||||
}
|
||||
|
||||
/**
|
||||
* Present formatted date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function scheduled_at_formatted()
|
||||
{
|
||||
return ucfirst($this->dates->make($this->wrappedObject->scheduled_at)->format($this->incidentDateFormat()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Present formatted date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function scheduled_at_iso()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->scheduled_at)->toISO8601String();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the scheduled_at time ready to be used by bootstrap-datetimepicker.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function scheduled_at_datetimepicker()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->scheduled_at)->format('Y-m-d H:i');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a formatted timestamp for use within the timeline.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function timestamp_formatted()
|
||||
{
|
||||
if ($this->wrappedObject->is_scheduled) {
|
||||
return $this->scheduled_at_formatted;
|
||||
}
|
||||
|
||||
return $this->created_at_formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Present formatted date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function completed_at()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->completed_at)->toDateTimeString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Present diff for humans date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function completed_at_diff()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->completed_at)->diffForHumans();
|
||||
}
|
||||
|
||||
/**
|
||||
* Present formatted date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function completed_at_formatted()
|
||||
{
|
||||
return ucfirst($this->dates->make($this->wrappedObject->completed_at)->format($this->incidentDateFormat()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Present formatted date time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function completed_at_iso()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->completed_at)->toISO8601String();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the completed_at time ready to be used by bootstrap-datetimepicker.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function completed_at_datetimepicker()
|
||||
{
|
||||
return $this->dates->make($this->wrappedObject->completed_at)->format('Y-m-d H:i');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the iso timestamp for use within the timeline.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function timestamp_iso()
|
||||
{
|
||||
if ($this->wrappedObject->is_scheduled) {
|
||||
return $this->scheduled_at_iso;
|
||||
}
|
||||
|
||||
return $this->completed_at_iso;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human readable version of the status.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function human_status()
|
||||
{
|
||||
// return trans('cachet.incidents.status.'.$this->wrappedObject->status);
|
||||
// TODO: Refactor into translations.
|
||||
switch ($this->wrappedObject->status) {
|
||||
case 0: return 'Upcoming';
|
||||
case 1: return 'In Progress';
|
||||
case 2: return 'Complete';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the presenter instance to an array.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return array_merge($this->wrappedObject->toArray(), [
|
||||
'human_status' => $this->human_status(),
|
||||
'scheduled_at' => $this->scheduled_at(),
|
||||
'completed_at' => $this->completed_at(),
|
||||
'created_at' => $this->created_at(),
|
||||
'updated_at' => $this->updated_at(),
|
||||
]);
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ use CachetHQ\Cachet\Models\IncidentTemplate;
|
||||
use CachetHQ\Cachet\Models\IncidentUpdate;
|
||||
use CachetHQ\Cachet\Models\Metric;
|
||||
use CachetHQ\Cachet\Models\MetricPoint;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
use CachetHQ\Cachet\Models\Setting;
|
||||
use CachetHQ\Cachet\Models\Subscriber;
|
||||
use CachetHQ\Cachet\Models\Subscription;
|
||||
@ -89,6 +90,15 @@ $factory->define(MetricPoint::class, function ($faker) {
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(Schedule::class, function ($faker) {
|
||||
return [
|
||||
'name' => $faker->sentence(),
|
||||
'message' => $faker->paragraph(),
|
||||
'status' => Schedule::UPCOMING,
|
||||
'scheduled_at' => Carbon::now()->addDays(7),
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(Setting::class, function ($faker) {
|
||||
return [
|
||||
'name' => 'app_name',
|
||||
|
@ -28,6 +28,7 @@ class CreateSchedulesTable extends Migration
|
||||
$table->longText('message')->nullable()->default(null);
|
||||
$table->tinyInteger('status')->unsigned()->default(0);
|
||||
$table->timestamp('scheduled_at');
|
||||
$table->timestamp('completed_at')->nullable()->default(null);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
<?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.
|
||||
*/
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AlterTableIncidentsRemoveScheduledColumns extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
// We need a better way of handling data migrations...
|
||||
DB::update('INSERT INTO schedules (name, message, scheduled_at, created_at, updated_at) SELECT name, message, scheduled_at, created_at, updated_at FROM incidents WHERE scheduled_at IS NOT NULL');
|
||||
|
||||
DB::table('incidents')->whereNotNull('scheduled_at')->delete();
|
||||
|
||||
Schema::table('incidents', function (Blueprint $table) {
|
||||
$table->dropColumn('scheduled_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('incidents', function (Blueprint $table) {
|
||||
$table->timestamp('scheduled_at')->after('user_id')->nullable()->default(null);
|
||||
});
|
||||
}
|
||||
}
|
@ -36,7 +36,6 @@ return [
|
||||
'scheduled_at' => ', scheduled :timestamp',
|
||||
'posted' => 'Posted :timestamp',
|
||||
'status' => [
|
||||
0 => 'Scheduled', // TODO: Hopefully remove this.
|
||||
1 => 'Investigating',
|
||||
2 => 'Identified',
|
||||
3 => 'Watching',
|
||||
@ -44,6 +43,15 @@ return [
|
||||
],
|
||||
],
|
||||
|
||||
// Schedule
|
||||
'schedules' => [
|
||||
'status' => [
|
||||
0 => 'Upcoming',
|
||||
1 => 'In Progress',
|
||||
2 => 'Complete',
|
||||
],
|
||||
],
|
||||
|
||||
// Service Status
|
||||
'service' => [
|
||||
'good' => '[0,1] System operational|[2,Inf] All systems are operational',
|
||||
|
@ -51,7 +51,6 @@ return [
|
||||
'component' => 'Component',
|
||||
'message' => 'Message',
|
||||
'message-help' => 'You may also use Markdown.',
|
||||
'scheduled_at' => 'When to schedule the maintenance for?',
|
||||
'occurred_at' => 'When did this incident occur?',
|
||||
'notify_subscribers' => 'Notify subscribers?',
|
||||
'visibility' => 'Incident Visibility',
|
||||
@ -67,6 +66,20 @@ return [
|
||||
],
|
||||
],
|
||||
|
||||
'schedules' => [
|
||||
'name' => 'Name',
|
||||
'status' => 'Status',
|
||||
'message' => 'Message',
|
||||
'message-help' => 'You may also use Markdown.',
|
||||
'scheduled_at' => 'When is this maintenance scheduled for?',
|
||||
'completed_at' => 'When did this maintenance complete?',
|
||||
'templates' => [
|
||||
'name' => 'Name',
|
||||
'template' => 'Template',
|
||||
'twig' => 'Incident Templates can make use of the <a href="http://twig.sensiolabs.org/" target="_blank">Twig</a> templating language.',
|
||||
],
|
||||
],
|
||||
|
||||
// Components form fields
|
||||
'components' => [
|
||||
'name' => 'Name',
|
||||
|
@ -22,7 +22,7 @@
|
||||
<span>{{ trans('dashboard.dashboard') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li {!! set_active('dashboard/incidents*') !!} {!! set_active('dashboard/schedule*') !!}>
|
||||
<li {!! set_active('dashboard/incidents*') !!}>
|
||||
<a href="{{ cachet_route('dashboard.incidents') }}">
|
||||
<i class="ion ion-ios-information-outline"></i>
|
||||
<span>{{ trans('dashboard.incidents.incidents') }}</span>
|
||||
@ -36,6 +36,13 @@
|
||||
<span class="label label-info">{{ $incident_template_count }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li {!! set_active('dashboard/schedule*') !!}>
|
||||
<a href="{{ cachet_route('dashboard.schedule') }}">
|
||||
<i class="ion ion-android-calendar"></i>
|
||||
<span>{{ trans('dashboard.schedule.schedule') }}</span>
|
||||
<span class="label label-info">{{ $schedule_count }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li {!! set_active('dashboard/components*') !!}>
|
||||
<a href="{{ cachet_route('dashboard.components') }}">
|
||||
<i class="ion ion-ios-browsers-outline"></i>
|
||||
|
@ -16,11 +16,10 @@
|
||||
@include('dashboard.partials.errors')
|
||||
<form class="form-vertical" name="ScheduleForm" role="form" method="POST" autocomplete="off">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}">
|
||||
<input type="hidden" name="visible" value="1">
|
||||
<fieldset>
|
||||
@if($incident_templates->count() > 0)
|
||||
<div class="form-group">
|
||||
<label for="incident-template">{{ trans('forms.incidents.templates.template') }}</label>
|
||||
<label for="incident-template">{{ trans('forms.schedules.templates.template') }}</label>
|
||||
<select class="form-control" name="template">
|
||||
<option selected></option>
|
||||
@foreach($incident_templates as $tpl)
|
||||
@ -30,27 +29,32 @@
|
||||
</div>
|
||||
@endif
|
||||
<div class="form-group">
|
||||
<label for="incident-name">{{ trans('forms.incidents.name') }}</label>
|
||||
<input type="text" class="form-control" name="name" id="incident-name" required value="{{ Binput::old('incident.name') }}" placeholder="{{ trans('forms.incidents.name') }}">
|
||||
<label for="incident-name">{{ trans('forms.schedules.name') }}</label>
|
||||
<input type="text" class="form-control" name="name" id="incident-name" required value="{{ Binput::old('name') }}" placeholder="{{ trans('forms.schedules.name') }}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ trans('forms.incidents.message') }}</label>
|
||||
<label>{{ trans('forms.schedules.status') }}</label><br>
|
||||
@foreach(trans('cachet.schedules.status') as $id => $status)
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="status" value="{{ $id }}" {{ $id === 0 ? 'checked="checked"' : null }}>
|
||||
{{ $status }}
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ trans('forms.schedules.message') }}</label>
|
||||
<div class="markdown-control">
|
||||
<textarea name="message" class="form-control autosize" rows="5" required placeholder="{{ trans('forms.incidents.message') }}">{{ Binput::old('incident.message') }}</textarea>
|
||||
<textarea name="message" class="form-control autosize" rows="5" required placeholder="{{ trans('forms.schedules.message') }}">{{ Binput::old('message') }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ trans('forms.incidents.scheduled_at') }}</label>
|
||||
<input type="text" name="scheduled_at" class="form-control" rel="datepicker" required placeholder="{{ trans('forms.incidents.scheduled_at') }}">
|
||||
<label>{{ trans('forms.schedules.scheduled_at') }}</label>
|
||||
<input type="text" name="scheduled_at" class="form-control" rel="datepicker-custom" data-date-format="YYYY-MM-DD HH:mm" required placeholder="{{ trans('forms.schedules.scheduled_at') }}">
|
||||
</div>
|
||||
@if(subscribers_enabled())
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="notify" value="1" checked="{{ Binput::old('incident.message', 'checked') }}">
|
||||
{{ trans('forms.incidents.notify_subscribers') }}
|
||||
</label>
|
||||
<div class="form-group">
|
||||
<label>{{ trans('forms.schedules.scheduled_at') }}</label>
|
||||
<input type="text" name="completed_at" class="form-control" rel="datepicker-custom" data-date-format="YYYY-MM-DD HH:mm" placeholder="{{ trans('forms.schedules.scheduled_at') }}">
|
||||
</div>
|
||||
@endif
|
||||
</fieldset>
|
||||
|
||||
<div class="form-group">
|
||||
|
@ -16,11 +16,11 @@
|
||||
@include('dashboard.partials.errors')
|
||||
<form class="form-vertical" name="ScheduleForm" role="form" method='POST' autocomplete="off">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}">
|
||||
<input type="hidden" name="incident[visible]" value="1">
|
||||
<input type="hidden" name="visible" value="1">
|
||||
<fieldset>
|
||||
@if($incident_templates->count() > 0)
|
||||
<div class="form-group">
|
||||
<label for="incident-template">{{ trans('forms.incidents.templates.template') }}</label>
|
||||
<label for="incident-template">{{ trans('forms.schedules.templates.template') }}</label>
|
||||
<select class="form-control" name="template">
|
||||
<option selected></option>
|
||||
@foreach($incident_templates as $tpl)
|
||||
@ -30,18 +30,31 @@
|
||||
</div>
|
||||
@endif
|
||||
<div class="form-group">
|
||||
<label for="incident-name">{{ trans('forms.incidents.name') }}</label>
|
||||
<input type="text" class="form-control" name="incident[name]" id="incident-name" required value="{{ $schedule->name }}" placeholder="{{ trans('forms.incidents.name') }}">
|
||||
<label for="incident-name">{{ trans('forms.schedules.name') }}</label>
|
||||
<input type="text" class="form-control" name="name" id="incident-name" required value="{{ $schedule->name }}" placeholder="{{ trans('forms.schedules.name') }}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ trans('forms.incidents.message') }}</label>
|
||||
<label>{{ trans('forms.schedules.status') }}</label><br>
|
||||
@foreach(trans('cachet.schedules.status') as $id => $status)
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="status" value="{{ $id }}" {{ $id === $schedule->status ? 'checked="checked"' : null }}>
|
||||
{{ $status }}
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ trans('forms.schedules.message') }}</label>
|
||||
<div class='markdown-control'>
|
||||
<textarea name="incident[message]" class="form-control autosize" rows="5" required>{{ $schedule->message }}</textarea>
|
||||
<textarea name="message" class="form-control autosize" rows="5" required>{{ $schedule->message }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ trans('forms.incidents.scheduled_at') }}</label>
|
||||
<input type="text" name="incident[scheduled_at]" class="form-control" rel="datepicker" value="{{ $schedule->scheduled_at_datetimepicker }}" required placeholder="{{ trans('forms.incidents.scheduled_at') }}">
|
||||
<label>{{ trans('forms.schedules.scheduled_at') }}</label>
|
||||
<input type="text" name="scheduled_at" class="form-control" rel="datepicker-custom" data-date-format="YYYY-MM-DD HH:mm" value="{{ $schedule->scheduled_at_datetimepicker }}" required placeholder="{{ trans('forms.schedules.scheduled_at') }}">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{ trans('forms.schedules.completed_at') }}</label>
|
||||
<input type="text" name="completed_at" class="form-control" rel="datepicker-custom" data-date-format="YYYY-MM-DD HH:mm" value="{{ $schedule->completed_at_datetimepicker }}" placeholder="{{ trans('forms.schedules.completed_at') }}">
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
<div class="col-xs-6">
|
||||
<strong>{{ $incident->name }}</strong>
|
||||
<br>
|
||||
{{ trans('dashboard.schedule.scheduled_at', ['timestamp' => $incident->scheduled_at_iso]) }}
|
||||
{{ trans('dashboard.schedule.scheduled_at', ['timestamp' => $incident->scheduled_at_formatted]) }}
|
||||
@if($incident->message)
|
||||
<p><small>{{ Str::words($incident->message, 5) }}</small></p>
|
||||
@endif
|
||||
|
@ -1,14 +1,20 @@
|
||||
<div class="timeline schedule">
|
||||
<div class="panel panel-info">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<strong>{{ trans('cachet.incidents.scheduled') }}</strong>
|
||||
</div>
|
||||
<div class="list-group">
|
||||
@foreach($scheduled_maintenance as $schedule)
|
||||
<div class="list-group-item">
|
||||
<a href="{{ cachet_route('schedule', $schedule) }}" class="list-group-item">
|
||||
<strong>{{ $schedule->name }}</strong> <small class="date"><abbr class="timeago" data-toggle="tooltip" data-placement="right" title="{{ $schedule->scheduled_at_formatted }}" data-timeago="{{ $schedule->scheduled_at_iso }}"></abbr></small>
|
||||
{!! $schedule->formattedMessage !!}
|
||||
</div>
|
||||
@if($schedule->components->count() > 0)
|
||||
<hr>
|
||||
@foreach($schedule->components as $affected_component)
|
||||
<span class="label label-primary">{{ $affected_component->component->name }}</span>
|
||||
@endforeach
|
||||
@endif
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
35
resources/views/single-schedule.blade.php
Normal file
35
resources/views/single-schedule.blade.php
Normal file
@ -0,0 +1,35 @@
|
||||
@extends('layout.master')
|
||||
|
||||
@section('bodyClass', 'no-padding')
|
||||
|
||||
@section('outer-content')
|
||||
@include('partials.nav')
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
<h1>{{ $schedule->name }}</h1>
|
||||
|
||||
<div class="timeline">
|
||||
<div class="content-wrapper">
|
||||
<div class="moment first">
|
||||
<div class="row event clearfix">
|
||||
<div class="col-sm-1">
|
||||
<div class="status-icon status-{{ $schedule->status }}" data-toggle="tooltip" title="{{ $schedule->human_status }}" data-placement="left">
|
||||
<i class="icon ion-android-calendar"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-10 col-xs-offset-2 col-sm-11 col-sm-offset-0">
|
||||
<div class="panel panel-message incident">
|
||||
<div class="panel-heading">
|
||||
<strong>{{ $schedule->name }}</strong>{{ trans("cachet.incidents.scheduled_at", ["timestamp" => $schedule->scheduled_at_diff]) }}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{!! $schedule->formattedMessage !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
87
tests/Api/ScheduleTest.php
Normal file
87
tests/Api/ScheduleTest.php
Normal file
@ -0,0 +1,87 @@
|
||||
<?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\Api;
|
||||
|
||||
/**
|
||||
* This is the schedule test class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class ScheduleTest extends AbstractApiTestCase
|
||||
{
|
||||
public function testGetSchedules()
|
||||
{
|
||||
$schedules = factory('CachetHQ\Cachet\Models\Schedule', 3)->create();
|
||||
|
||||
$this->get('/api/v1/schedules');
|
||||
|
||||
$this->assertResponseOk();
|
||||
|
||||
$this->seeJson(['id' => $schedules[0]->id]);
|
||||
$this->seeJson(['id' => $schedules[1]->id]);
|
||||
$this->seeJson(['id' => $schedules[2]->id]);
|
||||
}
|
||||
|
||||
public function testGetSchedule()
|
||||
{
|
||||
$schedule = factory('CachetHQ\Cachet\Models\Schedule')->create();
|
||||
|
||||
$this->get('/api/v1/schedules/'.$schedule->id);
|
||||
|
||||
$this->assertResponseOk();
|
||||
|
||||
$this->seeJson($schedule->toArray());
|
||||
}
|
||||
|
||||
public function testCreateSchedule()
|
||||
{
|
||||
$this->beUser();
|
||||
|
||||
$schedule = [
|
||||
'name' => 'Test Schedule',
|
||||
'message' => 'Foo bar, baz.',
|
||||
'status' => 1,
|
||||
'scheduled_at' => date('Y-m-d H:i'),
|
||||
];
|
||||
|
||||
$this->post('/api/v1/schedules/', $schedule);
|
||||
|
||||
$this->assertResponseOk();
|
||||
|
||||
$this->seeJson(array_forget($schedule, 'scheduled_at'));
|
||||
}
|
||||
|
||||
public function testUpdateSchedule()
|
||||
{
|
||||
$this->beUser();
|
||||
|
||||
$schedule = factory('CachetHQ\Cachet\Models\Schedule')->create();
|
||||
|
||||
$this->put('/api/v1/schedules/'.$schedule->id, [
|
||||
'name' => 'Updated schedule',
|
||||
]);
|
||||
|
||||
$this->assertResponseOk();
|
||||
|
||||
$this->seeJson(['name' => 'Updated schedule']);
|
||||
}
|
||||
|
||||
public function testDeleteSchedule()
|
||||
{
|
||||
$this->beUser();
|
||||
factory('CachetHQ\Cachet\Models\Schedule')->create();
|
||||
|
||||
$this->delete('/api/v1/schedules/1');
|
||||
|
||||
$this->assertResponseStatus(204);
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
<?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\Bus\Commands\Incident;
|
||||
|
||||
use AltThree\TestBench\CommandTrait;
|
||||
use CachetHQ\Cachet\Bus\Commands\Incident\ReportMaintenanceCommand;
|
||||
use CachetHQ\Cachet\Bus\Handlers\Commands\Incident\ReportMaintenanceCommandHandler;
|
||||
use CachetHQ\Tests\Cachet\AbstractTestCase;
|
||||
|
||||
/**
|
||||
* This is the add incident command test class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
* @author Graham Campbell <graham@alt-three.com>
|
||||
*/
|
||||
class ReportMaintenanceCommandTest extends AbstractTestCase
|
||||
{
|
||||
use CommandTrait;
|
||||
|
||||
protected function getObjectAndParams()
|
||||
{
|
||||
$params = [
|
||||
'name' => 'Test',
|
||||
'message' => 'Foo bar baz',
|
||||
'notify' => false,
|
||||
'timestamp' => '2020-12-30 00:00:01',
|
||||
];
|
||||
|
||||
$object = new ReportMaintenanceCommand(
|
||||
$params['name'],
|
||||
$params['message'],
|
||||
$params['notify'],
|
||||
$params['timestamp']
|
||||
);
|
||||
|
||||
return compact('params', 'object');
|
||||
}
|
||||
|
||||
protected function objectHasRules()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getHandlerClass()
|
||||
{
|
||||
return ReportMaintenanceCommandHandler::class;
|
||||
}
|
||||
}
|
59
tests/Bus/Commands/Schedule/CreateScheduleCommandTest.php
Normal file
59
tests/Bus/Commands/Schedule/CreateScheduleCommandTest.php
Normal file
@ -0,0 +1,59 @@
|
||||
<?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\Bus\Commands\Schedule;
|
||||
|
||||
use AltThree\TestBench\CommandTrait;
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\CreateScheduleCommand;
|
||||
use CachetHQ\Cachet\Bus\Handlers\Commands\Schedule\CreateScheduleCommandHandler;
|
||||
use CachetHQ\Tests\Cachet\AbstractTestCase;
|
||||
|
||||
/**
|
||||
* This is the create schedule command test class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class CreateScheduleCommandTest extends AbstractTestCase
|
||||
{
|
||||
use CommandTrait;
|
||||
|
||||
protected function getObjectAndParams()
|
||||
{
|
||||
$params = [
|
||||
'name' => 'Test',
|
||||
'message' => 'Foo',
|
||||
'status' => 1,
|
||||
'scheduled_at' => date('Y-m-d H:i'),
|
||||
'completed_at' => date('Y-m-d H:i'),
|
||||
'components' => [],
|
||||
];
|
||||
$object = new CreateScheduleCommand(
|
||||
$params['name'],
|
||||
$params['message'],
|
||||
$params['status'],
|
||||
$params['scheduled_at'],
|
||||
$params['completed_at'],
|
||||
$params['components']
|
||||
);
|
||||
|
||||
return compact('params', 'object');
|
||||
}
|
||||
|
||||
protected function objectHasRules()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getHandlerClass()
|
||||
{
|
||||
return CreateScheduleCommandHandler::class;
|
||||
}
|
||||
}
|
50
tests/Bus/Commands/Schedule/DeleteScheduleCommandTest.php
Normal file
50
tests/Bus/Commands/Schedule/DeleteScheduleCommandTest.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?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\Bus\Commands\Schedule;
|
||||
|
||||
use AltThree\TestBench\CommandTrait;
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\DeleteScheduleCommand;
|
||||
use CachetHQ\Cachet\Bus\Handlers\Commands\Schedule\DeleteScheduleCommandHandler;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
use CachetHQ\Tests\Cachet\AbstractTestCase;
|
||||
|
||||
/**
|
||||
* This is the create schedule command test class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class DeleteScheduleCommandTest extends AbstractTestCase
|
||||
{
|
||||
use CommandTrait;
|
||||
|
||||
protected function getObjectAndParams()
|
||||
{
|
||||
$params = [
|
||||
'schedule' => new Schedule(),
|
||||
];
|
||||
$object = new DeleteScheduleCommand(
|
||||
$params['schedule']
|
||||
);
|
||||
|
||||
return compact('params', 'object');
|
||||
}
|
||||
|
||||
protected function objectHasRules()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getHandlerClass()
|
||||
{
|
||||
return DeleteScheduleCommandHandler::class;
|
||||
}
|
||||
}
|
62
tests/Bus/Commands/Schedule/UpdateScheduleCommandTest.php
Normal file
62
tests/Bus/Commands/Schedule/UpdateScheduleCommandTest.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?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\Bus\Commands\Schedule;
|
||||
|
||||
use AltThree\TestBench\CommandTrait;
|
||||
use CachetHQ\Cachet\Bus\Commands\Schedule\UpdateScheduleCommand;
|
||||
use CachetHQ\Cachet\Bus\Handlers\Commands\Schedule\UpdateScheduleCommandHandler;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
use CachetHQ\Tests\Cachet\AbstractTestCase;
|
||||
|
||||
/**
|
||||
* This is the create schedule command test class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class UpdateScheduleCommandTest extends AbstractTestCase
|
||||
{
|
||||
use CommandTrait;
|
||||
|
||||
protected function getObjectAndParams()
|
||||
{
|
||||
$params = [
|
||||
'schedule' => new Schedule(),
|
||||
'name' => 'Foo',
|
||||
'message' => 'Bar',
|
||||
'status' => 1,
|
||||
'scheduled_at' => date('Y-m-d H:i'),
|
||||
'completed_at' => date('Y-m-d H:i'),
|
||||
'components' => [],
|
||||
];
|
||||
$object = new UpdateScheduleCommand(
|
||||
$params['schedule'],
|
||||
$params['name'],
|
||||
$params['message'],
|
||||
$params['status'],
|
||||
$params['scheduled_at'],
|
||||
$params['completed_at'],
|
||||
$params['components']
|
||||
);
|
||||
|
||||
return compact('params', 'object');
|
||||
}
|
||||
|
||||
protected function objectHasRules()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getHandlerClass()
|
||||
{
|
||||
return UpdateScheduleCommandHandler::class;
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?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\Bus\Events\Incident;
|
||||
|
||||
use CachetHQ\Cachet\Bus\Events\Incident\MaintenanceWasScheduledEvent;
|
||||
use CachetHQ\Cachet\Models\Incident;
|
||||
|
||||
/**
|
||||
* This is the maintenance was scheduled event test class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class MaintenanceWasScheduledEventTest extends AbstractIncidentEventTestCase
|
||||
{
|
||||
protected function objectHasHandlers()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getObjectAndParams()
|
||||
{
|
||||
$params = ['incident' => new Incident()];
|
||||
$object = new MaintenanceWasScheduledEvent($params['incident']);
|
||||
|
||||
return compact('params', 'object');
|
||||
}
|
||||
}
|
26
tests/Bus/Events/Schedule/AbstractScheduleEventTestCase.php
Normal file
26
tests/Bus/Events/Schedule/AbstractScheduleEventTestCase.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?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\Bus\Events\Schedule;
|
||||
|
||||
use AltThree\TestBench\EventTrait;
|
||||
use CachetHQ\Cachet\Bus\Events\Schedule\ScheduleEventInterface;
|
||||
use CachetHQ\Tests\Cachet\AbstractTestCase;
|
||||
|
||||
abstract class AbstractScheduleEventTestCase extends AbstractTestCase
|
||||
{
|
||||
use EventTrait;
|
||||
|
||||
protected function getEventInterfaces()
|
||||
{
|
||||
return [ScheduleEventInterface::class];
|
||||
}
|
||||
}
|
31
tests/Bus/Events/Schedule/ScheduleWasAddedEventTest.php
Normal file
31
tests/Bus/Events/Schedule/ScheduleWasAddedEventTest.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?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\Bus\Events\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Bus\Events\Schedule\ScheduleWasCreatedEvent;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
|
||||
class ScheduleWasAddedEventTest extends AbstractScheduleEventTestCase
|
||||
{
|
||||
protected function objectHasHandlers()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getObjectAndParams()
|
||||
{
|
||||
$params = ['schedule' => new Schedule()];
|
||||
$object = new ScheduleWasCreatedEvent($params['schedule']);
|
||||
|
||||
return compact('params', 'object');
|
||||
}
|
||||
}
|
31
tests/Bus/Events/Schedule/ScheduleWasRemovedEventTest.php
Normal file
31
tests/Bus/Events/Schedule/ScheduleWasRemovedEventTest.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?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\Bus\Events\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Bus\Events\Schedule\ScheduleWasRemovedEvent;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
|
||||
class ScheduleWasRemovedEventTest extends AbstractScheduleEventTestCase
|
||||
{
|
||||
protected function objectHasHandlers()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getObjectAndParams()
|
||||
{
|
||||
$params = ['schedule' => new Schedule()];
|
||||
$object = new ScheduleWasRemovedEvent($params['schedule']);
|
||||
|
||||
return compact('params', 'object');
|
||||
}
|
||||
}
|
31
tests/Bus/Events/Schedule/ScheduleWasUpdatedEventTest.php
Normal file
31
tests/Bus/Events/Schedule/ScheduleWasUpdatedEventTest.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?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\Bus\Events\Schedule;
|
||||
|
||||
use CachetHQ\Cachet\Bus\Events\Schedule\ScheduleWasUpdatedEvent;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
|
||||
class ScheduleWasUpdatedEventTest extends AbstractScheduleEventTestCase
|
||||
{
|
||||
protected function objectHasHandlers()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function getObjectAndParams()
|
||||
{
|
||||
$params = ['schedule' => new Schedule()];
|
||||
$object = new ScheduleWasUpdatedEvent($params['schedule']);
|
||||
|
||||
return compact('params', 'object');
|
||||
}
|
||||
}
|
31
tests/Models/ScheduleComponentTest.php
Normal file
31
tests/Models/ScheduleComponentTest.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?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\Models;
|
||||
|
||||
use AltThree\TestBench\ValidationTrait;
|
||||
use CachetHQ\Cachet\Models\ScheduleComponent;
|
||||
use CachetHQ\Tests\Cachet\AbstractTestCase;
|
||||
|
||||
/**
|
||||
* This is the schedule component model test class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class ScheduleComponentTest extends AbstractTestCase
|
||||
{
|
||||
use ValidationTrait;
|
||||
|
||||
public function testValidation()
|
||||
{
|
||||
$this->checkRules(new ScheduleComponent());
|
||||
}
|
||||
}
|
31
tests/Models/ScheduleTest.php
Normal file
31
tests/Models/ScheduleTest.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?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\Models;
|
||||
|
||||
use AltThree\TestBench\ValidationTrait;
|
||||
use CachetHQ\Cachet\Models\Schedule;
|
||||
use CachetHQ\Tests\Cachet\AbstractTestCase;
|
||||
|
||||
/**
|
||||
* This is the Schedule model test class.
|
||||
*
|
||||
* @author James Brooks <james@alt-three.com>
|
||||
*/
|
||||
class ScheduleTest extends AbstractTestCase
|
||||
{
|
||||
use ValidationTrait;
|
||||
|
||||
public function testValidation()
|
||||
{
|
||||
$this->checkRules(new Schedule());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user