diff --git a/app/Console/Commands/GetConfig.php b/app/Console/Commands/GetConfig.php
new file mode 100644
index 00000000..dbfbbf7b
--- /dev/null
+++ b/app/Console/Commands/GetConfig.php
@@ -0,0 +1,43 @@
+info(json_encode(SettingsHelper::getConfig(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
+ }
+}
diff --git a/app/Console/Commands/SetSlackWebhook.php b/app/Console/Commands/SetSlackWebhook.php
new file mode 100644
index 00000000..f1fe25de
--- /dev/null
+++ b/app/Console/Commands/SetSlackWebhook.php
@@ -0,0 +1,47 @@
+argument('webhook');
+
+ SettingsHelper::set('slack_webhook', $webhook);
+
+ $this->info('Slack webhook updated');
+ }
+}
diff --git a/app/Console/Commands/SetTelegramOptions.php b/app/Console/Commands/SetTelegramOptions.php
new file mode 100644
index 00000000..c32715d1
--- /dev/null
+++ b/app/Console/Commands/SetTelegramOptions.php
@@ -0,0 +1,51 @@
+option('bot');
+ $chat = $this->option('chat');
+
+ SettingsHelper::set('telegram_bot_token', $bot);
+ SettingsHelper::set('telegram_chat_id', $chat);
+
+ $this->info('Telegram options updated');
+ }
+}
diff --git a/app/Console/Commands/TestNotification.php b/app/Console/Commands/TestNotification.php
new file mode 100644
index 00000000..c1796762
--- /dev/null
+++ b/app/Console/Commands/TestNotification.php
@@ -0,0 +1,43 @@
+agents = $agents;
+ }
+
+ /**
+ * Get the channels the event should broadcast on.
+ *
+ * @return \Illuminate\Broadcasting\Channel|array
+ */
+ public function broadcastOn()
+ {
+ return new PrivateChannel('channel-name');
+ }
+}
diff --git a/app/Helpers/SettingsHelper.php b/app/Helpers/SettingsHelper.php
index 801622f2..67803b53 100644
--- a/app/Helpers/SettingsHelper.php
+++ b/app/Helpers/SettingsHelper.php
@@ -2,6 +2,7 @@
namespace App\Helpers;
+use App\Events\TestNotificationEvent;
use App\Setting;
use Carbon\Carbon;
@@ -38,10 +39,11 @@ class SettingsHelper {
{
$setting = SettingsHelper::get($name);
+ if($value == false) {
+ $value = "0";
+ }
+
if($setting !== false) {
- if($value == false) {
- $value = "0";
- }
$setting->value = $value;
$setting->save();
} else {
@@ -74,4 +76,75 @@ class SettingsHelper {
}
return $base;
}
+
+ /**
+ * Check whether a setting is defined in ENV vars or through DB
+ *
+ * @param string $key
+ * @return boolean
+ */
+ public static function settingIsEditable(string $key)
+ {
+ // Try exact key
+ $val = exec('echo $' . $key);
+
+ if($val == "") {
+ return true;
+ }
+
+ // Try key all caps
+ $val = exec('echo $' . strtoupper($key));
+
+ if($val == "") {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the application config
+ *
+ * @return array
+ */
+ public static function getConfig()
+ {
+ return [
+ 'base' => SettingsHelper::getBase(),
+ 'graphs' => [
+ 'download_upload_graph_enabled' => SettingsHelper::get('download_upload_graph_enabled'),
+ 'download_upload_graph_width' => SettingsHelper::get('download_upload_graph_width'),
+ 'ping_graph_enabled' => SettingsHelper::get('ping_graph_enabled'),
+ 'ping_graph_width' => SettingsHelper::get('ping_graph_width'),
+ 'failure_graph_enabled' => SettingsHelper::get('failure_graph_enabled'),
+ 'failure_graph_width' => SettingsHelper::get('failure_graph_width'),
+ ],
+ 'editable' => [
+ 'slack_webhook' => SettingsHelper::settingIsEditable('slack_webhook'),
+ 'telegram_bot_token' => SettingsHelper::settingIsEditable('telegram_bot_token'),
+ 'telegram_chat_id' => SettingsHelper::settingIsEditable('telegram_chat_id'),
+ ]
+ ];
+ }
+
+ /**
+ * Send test notification to agents
+ *
+ * @param boolean|string $agent
+ * @return void
+ */
+ public static function testNotification($agent = true)
+ {
+ $agents = [ 'slack', 'telegram' ];
+
+ if($agent === true) {
+ event(new TestNotificationEvent($agents));
+ return true;
+ }
+
+ if(in_array($agent, $agents)) {
+ event(new TestNotificationEvent([ $agent ]));
+ return true;
+ }
+ }
}
diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php
index bcfd9a72..7ac38c97 100644
--- a/app/Http/Controllers/SettingsController.php
+++ b/app/Http/Controllers/SettingsController.php
@@ -6,6 +6,7 @@ use App\Helpers\SettingsHelper;
use App\Rules\Cron;
use App\Setting;
use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
class SettingsController extends Controller
@@ -100,7 +101,17 @@ class SettingsController extends Controller
], 422);
}
}
- $setting = SettingsHelper::set($d['name'], $d['value']);
+
+ $setting = SettingsHelper::get($d['name']);
+
+ if($setting == false) {
+ $setting = SettingsHelper::set($d['name'], $d['value']);
+ } else if($setting->editable == true) {
+ $setting = SettingsHelper::set($d['name'], $d['value']);
+ } else {
+ continue;
+ }
+
array_push($settings, $setting);
}
@@ -117,18 +128,15 @@ class SettingsController extends Controller
*/
public function config()
{
+ return SettingsHelper::getConfig();
+ }
+ public function testNotification()
+ {
+ SettingsHelper::testNotification();
- $config = [
- 'base' => SettingsHelper::getBase(),
- 'download_upload_graph_enabled' => SettingsHelper::get('download_upload_graph_enabled'),
- 'download_upload_graph_width' => SettingsHelper::get('download_upload_graph_width'),
- 'ping_graph_enabled' => SettingsHelper::get('ping_graph_enabled'),
- 'ping_graph_width' => SettingsHelper::get('ping_graph_width'),
- 'failure_graph_enabled' => SettingsHelper::get('failure_graph_enabled'),
- 'failure_graph_width' => SettingsHelper::get('failure_graph_width'),
- ];
-
- return $config;
+ return response()->json([
+ 'method' => 'test notificaiton agents'
+ ], 200);
}
}
diff --git a/app/Jobs/SpeedtestJob.php b/app/Jobs/SpeedtestJob.php
index b1669ff7..8ed0e1bf 100644
--- a/app/Jobs/SpeedtestJob.php
+++ b/app/Jobs/SpeedtestJob.php
@@ -37,9 +37,7 @@ class SpeedtestJob implements ShouldQueue
{
$output = SpeedtestHelper::output();
$speedtest = SpeedtestHelper::runSpeedtest($output, $this->scheduled);
- Log::info($speedtest);
if($speedtest == false) {
- Log::info('speedtest == false');
event(new SpeedtestFailedEvent());
} else {
event(new SpeedtestCompleteEvent($speedtest));
diff --git a/app/Listeners/SpeedtestCompleteListener.php b/app/Listeners/SpeedtestCompleteListener.php
index fddcdd65..47323746 100644
--- a/app/Listeners/SpeedtestCompleteListener.php
+++ b/app/Listeners/SpeedtestCompleteListener.php
@@ -34,9 +34,9 @@ class SpeedtestCompleteListener
{
if(SettingsHelper::get('speedtest_notifications')->value == true) {
$data = $event->speedtest;
- if(env('SLACK_WEBHOOK')) {
+ if(SettingsHelper::get('slack_webhook')) {
try {
- Notification::route('slack', env('SLACK_WEBHOOK'))
+ Notification::route('slack', SettingsHelper::get('slack_webhook')->value)
->notify(new SpeedtestCompleteSlack($data));
} catch(Exception $e) {
Log::notice('Your sleck webhook is invalid');
@@ -44,9 +44,10 @@ class SpeedtestCompleteListener
}
}
- if(env('TELEGRAM_BOT_TOKEN') && env('TELEGRAM_CHAT_ID')) {
+ if(SettingsHelper::get('telegram_bot_token') && SettingsHelper::get('telegram_chat_id')) {
try {
- Notification::route(TelegramChannel::class, env('TELEGRAM_CHAT_ID'))
+ config([ 'services.telegram-bot-api' => [ 'token' => SettingsHelper::get('telegram_bot_token')->value ] ]);
+ Notification::route(TelegramChannel::class, SettingsHelper::get('telegram_chat_id')->value)
->notify(new SpeedtestCompleteTelegram($data));
} catch(Exception $e) {
Log::notice('Your telegram settings are invalid');
diff --git a/app/Listeners/SpeedtestFailedListener.php b/app/Listeners/SpeedtestFailedListener.php
index 0a0ae6cc..8175d7b0 100644
--- a/app/Listeners/SpeedtestFailedListener.php
+++ b/app/Listeners/SpeedtestFailedListener.php
@@ -31,9 +31,9 @@ class SpeedtestFailedListener
*/
public function handle($event)
{
- if(env('SLACK_WEBHOOK')) {
+ if(SettingsHelper::get('slack_webhook')) {
try {
- Notification::route('slack', env('SLACK_WEBHOOK'))
+ Notification::route('slack', SettingsHelper::get('slack_webhook')->value)
->notify(new SpeedtestFailedSlack());
} catch(Exception $e) {
Log::notice('Your sleck webhook is invalid');
@@ -41,9 +41,10 @@ class SpeedtestFailedListener
}
}
- if(env('TELEGRAM_BOT_TOKEN') && env('TELEGRAM_CHAT_ID')) {
+ if(SettingsHelper::get('telegram_bot_token') && SettingsHelper::get('telegram_chat_id')) {
try {
- Notification::route(TelegramChannel::class, env('TELEGRAM_CHAT_ID'))
+ config([ 'services.telegram-bot-api' => [ 'token' => SettingsHelper::get('telegram_bot_token')->value ] ]);
+ Notification::route(TelegramChannel::class, SettingsHelper::get('telegram_chat_id')->value)
->notify(new SpeedtestFailedTelegram());
} catch(Exception $e) {
Log::notice('Your telegram settings are invalid');
diff --git a/app/Listeners/SpeedtestOverviewListener.php b/app/Listeners/SpeedtestOverviewListener.php
index cd293d2e..7a67857b 100644
--- a/app/Listeners/SpeedtestOverviewListener.php
+++ b/app/Listeners/SpeedtestOverviewListener.php
@@ -35,9 +35,9 @@ class SpeedtestOverviewListener
{
if(SettingsHelper::get('speedtest_overview_notification')->value == true) {
$data = SpeedtestHelper::last24Hours();
- if(env('SLACK_WEBHOOK')) {
+ if(SettingsHelper::get('slack_webhook')) {
try {
- Notification::route('slack', env('SLACK_WEBHOOK'))
+ Notification::route('slack', SettingsHelper::get('slack_webhook')->value)
->notify(new SpeedtestOverviewSlack($data));
} catch(Exception $e) {
Log::notice('Your sleck webhook is invalid');
@@ -45,9 +45,10 @@ class SpeedtestOverviewListener
}
}
- if(env('TELEGRAM_BOT_TOKEN') && env('TELEGRAM_CHAT_ID')) {
+ if(SettingsHelper::get('telegram_bot_token') && SettingsHelper::get('telegram_chat_id')) {
try {
- Notification::route(TelegramChannel::class, env('TELEGRAM_CHAT_ID'))
+ config([ 'services.telegram-bot-api' => [ 'token' => SettingsHelper::get('telegram_bot_token')->value ] ]);
+ Notification::route(TelegramChannel::class, SettingsHelper::get('telegram_chat_id')->value)
->notify(new SpeedtestOverviewTelegram($data));
} catch(Exception $e) {
Log::notice('Your telegram settings are invalid');
diff --git a/app/Listeners/TestNotificationListener.php b/app/Listeners/TestNotificationListener.php
new file mode 100644
index 00000000..ba5a1f02
--- /dev/null
+++ b/app/Listeners/TestNotificationListener.php
@@ -0,0 +1,84 @@
+agents as $agent) {
+ if($agent == 'slack') {
+ $this->slackNotification();
+ }
+
+ if($agent == 'telegram') {
+ $this->telegramNotification();
+ }
+ }
+ }
+
+ /**
+ * Send a slack notification
+ *
+ * @return void
+ */
+ private function slackNotification()
+ {
+ if(SettingsHelper::get('slack_webhook')) {
+ try {
+ Notification::route('slack', SettingsHelper::get('slack_webhook')->value)
+ ->notify(new TestSlackNotification());
+ } catch(Exception $e) {
+ Log::notice('Your sleck webhook is invalid');
+ Log::notice($e);
+ }
+ }
+ }
+
+ /**
+ * Send a telegram notification
+ *
+ * @return void
+ */
+ private function telegramNotification()
+ {
+ if(SettingsHelper::get('telegram_bot_token') && SettingsHelper::get('telegram_chat_id')) {
+ try {
+ config([ 'services.telegram-bot-api' => [ 'token' => SettingsHelper::get('telegram_bot_token')->value ] ]);
+ Notification::route(TelegramChannel::class, SettingsHelper::get('telegram_bot_token')->value)
+ ->notify(new TestTelegramNotification());
+ } catch(Exception $e) {
+ Log::notice('Your telegram settings are invalid');
+ Log::notice($e);
+ }
+ }
+ }
+}
diff --git a/app/Notifications/SpeedtestCompleteTelegram.php b/app/Notifications/SpeedtestCompleteTelegram.php
index b7cff04c..591d1117 100644
--- a/app/Notifications/SpeedtestCompleteTelegram.php
+++ b/app/Notifications/SpeedtestCompleteTelegram.php
@@ -2,6 +2,7 @@
namespace App\Notifications;
+use App\Helpers\SettingsHelper;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -40,7 +41,7 @@ class SpeedtestCompleteTelegram extends Notification
}
/**
- * Format tekegram notification
+ * Format telegram notification
*
* @param mixed $notifiable
* @return TelegramMessage
@@ -53,7 +54,7 @@ Ping: *$speedtest->ping*
Download: *$speedtest->download*
Upload: *$speedtest->upload*";
return TelegramMessage::create()
- ->to(env('TELEGRAM_CHAT_ID'))
+ ->to(SettingsHelper::get('telegram_chat_id')->value)
->content($msg)
->options(['parse_mode' => 'Markdown']);
}
diff --git a/app/Notifications/SpeedtestFailedTelegram.php b/app/Notifications/SpeedtestFailedTelegram.php
index a521e28e..46443345 100644
--- a/app/Notifications/SpeedtestFailedTelegram.php
+++ b/app/Notifications/SpeedtestFailedTelegram.php
@@ -2,6 +2,7 @@
namespace App\Notifications;
+use App\Helpers\SettingsHelper;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -40,7 +41,7 @@ class SpeedtestFailedTelegram extends Notification implements ShouldQueue
{
$msg = "Error: something went wrong running your speedtest";
return TelegramMessage::create()
- ->to(env('TELEGRAM_CHAT_ID'))
+ ->to(SettingsHelper::get('telegram_chat_id')->value)
->content($msg)
->options(['parse_mode' => 'Markdown']);
}
diff --git a/app/Notifications/SpeedtestOverviewTelegram.php b/app/Notifications/SpeedtestOverviewTelegram.php
index c0d51298..3a8a2964 100644
--- a/app/Notifications/SpeedtestOverviewTelegram.php
+++ b/app/Notifications/SpeedtestOverviewTelegram.php
@@ -2,6 +2,7 @@
namespace App\Notifications;
+use App\Helpers\SettingsHelper;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
@@ -53,7 +54,7 @@ Average ping: *".$data["ping"]."*
Average download: *".$data["download"]."*
Average upload: *".$data["upload"]."*";
return TelegramMessage::create()
- ->to(env('TELEGRAM_CHAT_ID'))
+ ->to(SettingsHelper::get('telegram_chat_id')->value)
->content($msg)
->options(['parse_mode' => 'Markdown']);
}
diff --git a/app/Notifications/TestSlackNotification.php b/app/Notifications/TestSlackNotification.php
new file mode 100644
index 00000000..808f178a
--- /dev/null
+++ b/app/Notifications/TestSlackNotification.php
@@ -0,0 +1,65 @@
+warning()
+ ->attachment(function ($attachment) {
+ $attachment->title('Test notification');
+ });
+ }
+
+ /**
+ * Get the array representation of the notification.
+ *
+ * @param mixed $notifiable
+ * @return array
+ */
+ public function toArray($notifiable)
+ {
+ return [
+ //
+ ];
+ }
+}
diff --git a/app/Notifications/TestTelegramNotification.php b/app/Notifications/TestTelegramNotification.php
new file mode 100644
index 00000000..59980543
--- /dev/null
+++ b/app/Notifications/TestTelegramNotification.php
@@ -0,0 +1,67 @@
+to(SettingsHelper::get('telegram_chat_id')->value)
+ ->content($msg)
+ ->options(['parse_mode' => 'Markdown']);
+ }
+
+ /**
+ * Get the array representation of the notification.
+ *
+ * @param mixed $notifiable
+ * @return array
+ */
+ public function toArray($notifiable)
+ {
+ return [
+ //
+ ];
+ }
+}
diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php
index e34e5a20..b33e65d5 100644
--- a/app/Providers/EventServiceProvider.php
+++ b/app/Providers/EventServiceProvider.php
@@ -5,9 +5,11 @@ namespace App\Providers;
use App\Events\SpeedtestCompleteEvent;
use App\Events\SpeedtestFailedEvent;
use App\Events\SpeedtestOverviewEvent;
+use App\Events\TestNotificationEvent;
use App\Listeners\SpeedtestCompleteListener;
use App\Listeners\SpeedtestFailedListener;
use App\Listeners\SpeedtestOverviewListener;
+use App\Listeners\TestNotificationListener;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
@@ -33,6 +35,9 @@ class EventServiceProvider extends ServiceProvider
SpeedtestFailedEvent::class => [
SpeedtestFailedListener::class
],
+ TestNotificationEvent::class => [
+ TestNotificationListener::class
+ ]
];
/**
diff --git a/app/Setting.php b/app/Setting.php
index 259965fc..d3ceb8db 100644
--- a/app/Setting.php
+++ b/app/Setting.php
@@ -2,6 +2,7 @@
namespace App;
+use App\Helpers\SettingsHelper;
use Illuminate\Database\Eloquent\Model;
class Setting extends Model
@@ -16,4 +17,11 @@ class Setting extends Model
];
protected $table = 'settings';
+
+ protected $attributes = [ 'editable' ];
+
+ public function getEditableAttribute()
+ {
+ return SettingsHelper::settingIsEditable($this->name);
+ }
}
diff --git a/public/css/main.css b/public/css/main.css
index 686715a4..433574e4 100644
--- a/public/css/main.css
+++ b/public/css/main.css
@@ -59,3 +59,7 @@
.home-graph {
height: 480px;
}
+
+.form-control:disabled {
+ cursor: not-allowed;
+}
diff --git a/public/js/app.js b/public/js/app.js
index d55e7ffa..6b9d12a0 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -129337,8 +129337,7 @@ var HistoryGraph = /*#__PURE__*/function (_Component) {
_defineProperty(_assertThisInitialized(_this), "getData", function () {
var days = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.state.days;
axios__WEBPACK_IMPORTED_MODULE_2___default.a.get('api/settings/config').then(function (resp) {
- var data = resp.data;
- console.log(data);
+ var data = resp.data.graphs;
_this.setState({
graph_ul_dl_enabled: Boolean(Number(data.download_upload_graph_enabled.value)),
@@ -129412,10 +129411,6 @@ var HistoryGraph = /*#__PURE__*/function (_Component) {
var failData = this.state.failData;
var failOptions = this.state.failOptions;
var days = this.state.days;
- console.log(failData);
- console.log(failOptions);
- console.log(pingData);
- console.log(pingOptions);
var graph_ul_dl_enabled = this.state.graph_ul_dl_enabled;
var graph_ul_dl_width = this.state.graph_ul_dl_width;
var graph_ping_enabled = this.state.graph_ping_enabled;
@@ -130629,7 +130624,9 @@ var SettingWithModal = /*#__PURE__*/function (_Component) {
axios__WEBPACK_IMPORTED_MODULE_3___default.a.post(url, data).then(function (resp) {
react_toastify__WEBPACK_IMPORTED_MODULE_4__["toast"].success(_this.state.title + ' updated');
- _this.toggleShow();
+ if (_this.state.autoClose) {
+ _this.toggleShow();
+ }
})["catch"](function (err) {
if (err.response.status == 422) {
react_toastify__WEBPACK_IMPORTED_MODULE_4__["toast"].error('Your input was invalid');
@@ -130682,7 +130679,8 @@ var SettingWithModal = /*#__PURE__*/function (_Component) {
title: _this.props.title,
description: _this.props.description,
settings: _this.props.settings,
- show: false
+ show: false,
+ autoClose: _this.props.autoClose
};
return _this;
}
@@ -130716,71 +130714,125 @@ var SettingWithModal = /*#__PURE__*/function (_Component) {
name[0] = _this2.ucfirst(name[0]);
name = name.join(' ');
+ if (e.obj.description == null) {
+ var sm = {
+ span: 12
+ };
+ var md = {
+ span: 12
+ };
+ } else {
+ var sm = {
+ span: 12
+ };
+ var md = {
+ span: 6
+ };
+ }
+
+ var readonly = false;
+
+ if (window.config.editable[e.obj.name] == false) {
+ readonly = true;
+ }
+
if (e.type == 'checkbox') {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Row"], {
key: e.obj.id,
className: "d-flex align-items-center"
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
- md: {
- span: 6
- },
- sm: {
- span: 12
- }
+ md: md,
+ sm: sm
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Group, {
controlId: e.obj.name
- }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Check, {
+ }, readonly ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Check, {
+ type: "checkbox",
+ disabled: true,
+ label: name,
+ defaultChecked: Boolean(Number(e.obj.value)),
+ onInput: _this2.updateValue
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Text, {
+ className: "text-muted"
+ }, "This setting is defined as an env variable and is not editable.")) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Check, {
type: "checkbox",
label: name,
defaultChecked: Boolean(Number(e.obj.value)),
onInput: _this2.updateValue
- }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
- md: {
- span: 6
- },
- sm: {
- span: 12
- }
+ }))), e.description == null && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
+ md: md,
+ sm: sm
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", null, e.obj.description)));
} else if (e.type == 'number') {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Row"], {
key: e.obj.id
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
- md: {
- span: 6
- },
- sm: {
- span: 12
- }
+ md: md,
+ sm: sm
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Group, {
controlId: e.obj.name
- }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Label, null, name), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Control, {
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Label, null, name), readonly ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Control, {
+ type: "number",
+ disabled: true,
+ min: e.min,
+ max: e.max,
+ defaultValue: e.obj.value,
+ onInput: _this2.updateValue
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Text, {
+ className: "text-muted"
+ }, "This setting is defined as an env variable and is not editable.")) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Control, {
type: "number",
min: e.min,
max: e.max,
defaultValue: e.obj.value,
onInput: _this2.updateValue
- }))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
- md: {
- span: 6
- },
- sm: {
- span: 12
- }
+ }))), e.description == null && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
+ md: md,
+ sm: sm
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", null, e.obj.description)));
+ } else if (e.type == 'text') {
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Row"], {
+ key: e.obj.id
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
+ md: md,
+ sm: sm
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Group, {
+ controlId: e.obj.name
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Label, null, name), readonly ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Control, {
+ type: "text",
+ disabled: true,
+ defaultValue: e.obj.value,
+ onInput: _this2.updateValue
+ }), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Text, {
+ className: "text-muted"
+ }, "This setting is defined as an env variable and is not editable.")) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Control, {
+ type: "text",
+ defaultValue: e.obj.value,
+ onInput: _this2.updateValue
+ }))), e.description == null && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
+ md: md,
+ sm: sm
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", null, e.obj.description)));
} else if (e.type == 'select') {
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Row"], {
key: e.obj.id
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
- md: {
- span: 6
- },
- sm: {
- span: 12
- }
+ md: md,
+ sm: sm
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Group, {
controlId: e.obj.name
- }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Label, null, name), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Control, {
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Label, null, name), readonly ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Control, {
+ as: "select",
+ disabled: true,
+ defaultValue: e.obj.value,
+ onInput: _this2.updateValue
+ }, e.options.map(function (e, i) {
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("option", {
+ key: i,
+ value: e.value
+ }, e.name);
+ })), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Text, {
+ className: "text-muted"
+ }, "This setting is defined as an env variable and is not editable.")) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Form"].Control, {
as: "select",
defaultValue: e.obj.value,
onInput: _this2.updateValue
@@ -130789,13 +130841,23 @@ var SettingWithModal = /*#__PURE__*/function (_Component) {
key: i,
value: e.value
}, e.name);
- })))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
- md: {
- span: 6
- },
- sm: {
- span: 12
+ })))), e.description == null && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
+ md: md,
+ sm: sm
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", null, e.obj.description)));
+ } else if (e.type == 'button-get') {
+ return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Row"], {
+ key: e.obj.id
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
+ md: md,
+ sm: sm
+ }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", null, name), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Button"], {
+ onClick: function onClick() {
+ axios__WEBPACK_IMPORTED_MODULE_3___default.a.get(e.url);
}
+ }, name)), e.description == null && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], {
+ md: md,
+ sm: sm
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("p", null, e.obj.description)));
}
}), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Button"], {
@@ -130952,6 +131014,7 @@ var Settings = /*#__PURE__*/function (_Component) {
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_SettingWithModal__WEBPACK_IMPORTED_MODULE_6__["default"], {
title: "Graph settings",
description: "Control settings for the graphs.",
+ autoClose: true,
settings: [{
obj: e.download_upload_graph_enabled,
type: 'checkbox'
@@ -131005,7 +131068,25 @@ var Settings = /*#__PURE__*/function (_Component) {
}, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_SettingWithModal__WEBPACK_IMPORTED_MODULE_6__["default"], {
title: "Notification settings",
description: "Control which types of notifications the server sends.",
+ autoClose: false,
settings: [{
+ obj: e.slack_webhook,
+ type: 'text'
+ }, {
+ obj: e.telegram_bot_token,
+ type: 'text'
+ }, {
+ obj: e.telegram_chat_id,
+ type: 'text'
+ }, {
+ obj: {
+ id: Math.floor(Math.random() * 10000) + 1,
+ name: "Test notifications",
+ description: "After saving your updated notification settings, use this to check your settings are correct."
+ },
+ type: 'button-get',
+ url: 'api/settings/test-notification'
+ }, {
obj: e.speedtest_notifications,
type: 'checkbox'
}, {
diff --git a/resources/js/components/Graphics/HistoryGraph.js b/resources/js/components/Graphics/HistoryGraph.js
index 2762a8f7..0893f02e 100644
--- a/resources/js/components/Graphics/HistoryGraph.js
+++ b/resources/js/components/Graphics/HistoryGraph.js
@@ -225,8 +225,7 @@ export default class HistoryGraph extends Component {
getData = (days = this.state.days) => {
Axios.get('api/settings/config')
.then((resp) => {
- var data = resp.data;
- console.log(data)
+ var data = resp.data.graphs;
this.setState({
graph_ul_dl_enabled: Boolean(Number(data.download_upload_graph_enabled.value)),
graph_ul_dl_width: data.download_upload_graph_width.value,
@@ -274,11 +273,6 @@ export default class HistoryGraph extends Component {
var failOptions = this.state.failOptions;
var days = this.state.days;
- console.log(failData);
- console.log(failOptions);
- console.log(pingData);
- console.log(pingOptions);
-
var graph_ul_dl_enabled = this.state.graph_ul_dl_enabled;
var graph_ul_dl_width = this.state.graph_ul_dl_width;
var graph_ping_enabled = this.state.graph_ping_enabled;
diff --git a/resources/js/components/Home/SettingWithModal.js b/resources/js/components/Home/SettingWithModal.js
index 28ba5b0a..891cda6c 100644
--- a/resources/js/components/Home/SettingWithModal.js
+++ b/resources/js/components/Home/SettingWithModal.js
@@ -12,7 +12,8 @@ export default class SettingWithModal extends Component {
title: this.props.title,
description: this.props.description,
settings: this.props.settings,
- show: false
+ show: false,
+ autoClose: this.props.autoClose
}
}
@@ -40,7 +41,9 @@ export default class SettingWithModal extends Component {
Axios.post(url, data)
.then((resp) => {
toast.success(this.state.title + ' updated');
- this.toggleShow();
+ if(this.state.autoClose) {
+ this.toggleShow();
+ }
})
.catch((err) => {
if(err.response.status == 422) {
@@ -111,51 +114,135 @@ export default class SettingWithModal extends Component {
var name = e.obj.name.split('_');
name[0] = this.ucfirst(name[0]);
name = name.join(' ');
+
+ if(e.obj.description == null) {
+ var sm = { span: 12 };
+ var md = { span: 12 };
+ } else {
+ var sm = { span: 12 };
+ var md = { span: 6 };
+ }
+
+ var readonly = false;
+ if(window.config.editable[e.obj.name] == false) {
+ readonly = true;
+ }
+
if(e.type == 'checkbox') {
return (
{e.obj.description} {e.obj.description} {e.obj.description} {e.obj.description} {e.obj.description} {e.obj.description} {e.obj.description} {name} {e.obj.description}