mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Added support for user timezones and user browser timezone by default (incomplete) (#13626)
* Added support for user timezones and user browser timezone byt default * Formatting fixes * Use the timezone for alert log display also added validation for the timezone because it's being used in SQL. * Formatting fixes * Added return type * Formatting" * Update the latency graphs to use the user timezone * Simplify the web routes config * Update phpstan to ignore type error * Fixed up the phpstan config * Reverse phpstan change * Re-apply phpstan override * Remove the option to unset the session timezone * Formatting fix * Update outge and event logs to use session timezone * Fix route for the timezone control * Made the timezone more dynamic * Fix a logic error that was stopping the timezone from being set automatically on login * Prevent getPref from being called twice * again prevent getPref double call * getPref double call * Fixed typo made during merge * Fixed merge error in phpstan-baseline.neon * Change spaces to tabs in phpstan-baseline.neon * Update error count --------- Co-authored-by: Tony Murray <murraytony@gmail.com>
This commit is contained in:
@@ -561,9 +561,9 @@ class Rrd extends BaseDatastore
|
||||
*
|
||||
* @throws \LibreNMS\Exceptions\RrdGraphException
|
||||
*/
|
||||
public function graph(string $options): string
|
||||
public function graph(string $options, array $env = null): string
|
||||
{
|
||||
$process = new Process([Config::get('rrdtool', 'rrdtool'), '-'], $this->rrd_dir);
|
||||
$process = new Process([Config::get('rrdtool', 'rrdtool'), '-'], $this->rrd_dir, $env);
|
||||
$process->setTimeout(300);
|
||||
$process->setIdleTimeout(300);
|
||||
|
||||
|
||||
55
app/Http/Controllers/Ajax/TimezoneController.php
Normal file
55
app/Http/Controllers/Ajax/TimezoneController.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* TimezoneController.php
|
||||
*
|
||||
* -Description-
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @link https://www.librenms.org
|
||||
*
|
||||
* @copyright 2021 Steven Wilton
|
||||
* @author Steven Wilton <swilton@fluentit.com.au>
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Ajax;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TimezoneController extends Controller
|
||||
{
|
||||
public function set(Request $request): string
|
||||
{
|
||||
session([
|
||||
'timezone_static' => $request->boolean('static'),
|
||||
]);
|
||||
|
||||
// laravel session
|
||||
if ($request->timezone) {
|
||||
// Only accept valid timezones
|
||||
if (! in_array($request->timezone, timezone_identifiers_list())) {
|
||||
return session('timezone');
|
||||
}
|
||||
|
||||
session([
|
||||
'timezone' => $request->timezone,
|
||||
]);
|
||||
|
||||
return $request->timezone;
|
||||
}
|
||||
|
||||
return session('timezone');
|
||||
}
|
||||
}
|
||||
@@ -58,10 +58,13 @@ class LatencyController implements DeviceTab
|
||||
|
||||
public function data(Device $device): array
|
||||
{
|
||||
$from = Request::get('dtpickerfrom', Carbon::now()->subDays(2)->format(Config::get('dateformat.byminute')));
|
||||
$to = Request::get('dtpickerto', Carbon::now()->format(Config::get('dateformat.byminute')));
|
||||
$from = Request::get('dtpickerfrom', Carbon::now(session('timezone'))->subDays(2)->format(Config::get('dateformat.byminute')));
|
||||
$to = Request::get('dtpickerto', Carbon::now(session('timezone'))->format(Config::get('dateformat.byminute')));
|
||||
|
||||
$perf = $this->fetchPerfData($device, $from, $to);
|
||||
$dbfrom = Carbon::createFromFormat(Config::get('dateformat.byminute'), $from)->setTimezone(date_default_timezone_get())->format(Config::get('dateformat.byminute'));
|
||||
$dbto = Carbon::createFromFormat(Config::get('dateformat.byminute'), $to)->setTimezone(date_default_timezone_get())->format(Config::get('dateformat.byminute'));
|
||||
|
||||
$perf = $this->fetchPerfData($device, $dbfrom, $dbto);
|
||||
|
||||
$duration = $perf && $perf->isNotEmpty()
|
||||
? abs(strtotime($perf->first()->date) - strtotime($perf->last()->date)) * 1000
|
||||
@@ -91,7 +94,7 @@ class LatencyController implements DeviceTab
|
||||
return DB::table('device_perf')
|
||||
->where('device_id', $device->device_id)
|
||||
->whereBetween('timestamp', [$from, $to])
|
||||
->select(DB::raw("DATE_FORMAT(timestamp, '%Y-%m-%d %H:%i') date,xmt,rcv,loss,min,max,avg"))
|
||||
->selectRaw("DATE_FORMAT(IFNULL(CONVERT_TZ(timestamp, @@global.time_zone, ?), timestamp), '%Y-%m-%d %H:%i') date,xmt,rcv,loss,min,max,avg", [session('timezone')])
|
||||
->get();
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ class EventlogController extends TableController
|
||||
$output = "<span class='alert-status ";
|
||||
$output .= $this->severityLabel($eventlog->severity);
|
||||
$output .= " eventlog-status'></span><span style='display:inline;'>";
|
||||
$output .= (new Carbon($eventlog->datetime))->format(Config::get('dateformat.compact'));
|
||||
$output .= (new Carbon($eventlog->datetime))->setTimezone(session('timezone'))->format(Config::get('dateformat.compact'));
|
||||
$output .= '</span>';
|
||||
|
||||
return $output;
|
||||
|
||||
@@ -64,10 +64,10 @@ class OutagesController extends TableController
|
||||
return DeviceOutage::hasAccess($request->user())
|
||||
->with('device')
|
||||
->when($request->from, function ($query) use ($request) {
|
||||
$query->where('going_down', '>=', strtotime($request->from));
|
||||
$query->where('going_down', '>=', Carbon::parse($request->from, session('timezone'))->getTimestamp());
|
||||
})
|
||||
->when($request->to, function ($query) use ($request) {
|
||||
$query->where('going_down', '<=', strtotime($request->to));
|
||||
$query->where('going_down', '<=', Carbon::parse($request->to, session('timezone'))->getTimestamp());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ class OutagesController extends TableController
|
||||
}
|
||||
|
||||
$output = "<span style='display:inline;'>";
|
||||
$output .= Carbon::createFromTimestamp($timestamp)->format(Config::get('dateformat.compact')); // Convert epoch to local time
|
||||
$output .= Carbon::createFromTimestamp($timestamp, session('timezone'))->format(Config::get('dateformat.compact')); // Convert epoch to local time
|
||||
$output .= '</span>';
|
||||
|
||||
return $output;
|
||||
|
||||
@@ -80,6 +80,7 @@ class UserController extends Controller
|
||||
'user' => $tmp_user,
|
||||
'dashboard' => null,
|
||||
'dashboards' => Dashboard::allAvailable($tmp_user)->get(),
|
||||
'timezone' => 'default',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -100,6 +101,7 @@ class UserController extends Controller
|
||||
$user->setPassword($request->new_password);
|
||||
$user->auth_id = (string) LegacyAuth::get()->getUserid($user->username) ?: $user->user_id;
|
||||
$this->updateDashboard($user, $request->get('dashboard'));
|
||||
$this->updateTimezone($user, $request->get('timezone'));
|
||||
|
||||
if ($user->save()) {
|
||||
$flasher->addSuccess(__('User :username created', ['username' => $user->username]));
|
||||
@@ -143,6 +145,7 @@ class UserController extends Controller
|
||||
'user' => $user,
|
||||
'dashboard' => UserPref::getPref($user, 'dashboard'),
|
||||
'dashboards' => Dashboard::allAvailable($user)->get(),
|
||||
'timezone' => UserPref::getPref($user, 'timezone') ?: 'default',
|
||||
];
|
||||
|
||||
if (Config::get('twofactor')) {
|
||||
@@ -186,6 +189,14 @@ class UserController extends Controller
|
||||
$flasher->addSuccess(__('Updated dashboard for :username', ['username' => $user->username]));
|
||||
}
|
||||
|
||||
if ($request->has('timezone') && $this->updateTimezone($user, $request->get('timezone'))) {
|
||||
if ($request->get('timezone') != 'default') {
|
||||
$flasher->addSuccess(__('Updated timezone for :username', ['username' => $user->username]));
|
||||
} else {
|
||||
$flasher->addSuccess(__('Cleared timezone for :username', ['username' => $user->username]));
|
||||
}
|
||||
}
|
||||
|
||||
if ($user->save()) {
|
||||
$flasher->addSuccess(__('User :username updated', ['username' => $user->username]));
|
||||
|
||||
@@ -233,6 +244,35 @@ class UserController extends Controller
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param User $user
|
||||
* @param string $timezone
|
||||
* @return bool
|
||||
*/
|
||||
protected function updateTimezone(User $user, $timezone)
|
||||
{
|
||||
$existing = UserPref::getPref($user, 'timezone');
|
||||
if ($timezone != 'default') {
|
||||
if (! in_array($timezone, timezone_identifiers_list())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($timezone != $existing) {
|
||||
UserPref::setPref($user, 'timezone', $timezone);
|
||||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if ($existing != '') {
|
||||
UserPref::forgetPref($user, 'timezone');
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function authlog()
|
||||
{
|
||||
$this->authorize('manage', User::class);
|
||||
|
||||
@@ -73,6 +73,7 @@ class UserPreferencesController extends Controller
|
||||
'site_style' => UserPref::getPref($user, 'site_style'),
|
||||
'site_style_default' => $styles[$default_style] ?? $default_style,
|
||||
'site_styles' => $styles,
|
||||
'timezone' => UserPref::getPref($user, 'timezone'),
|
||||
'hide_dashboard_editor' => UserPref::getPref($user, 'hide_dashboard_editor') ?? 0,
|
||||
];
|
||||
|
||||
@@ -110,6 +111,10 @@ class UserPreferencesController extends Controller
|
||||
'required',
|
||||
Rule::in(array_merge(['default'], array_keys($this->getValidStyles()))),
|
||||
],
|
||||
'timezone' => [
|
||||
'required',
|
||||
Rule::in(array_merge(['default'], timezone_identifiers_list())),
|
||||
],
|
||||
'hide_dashboard_editor' => 'required|integer',
|
||||
];
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\UserPref;
|
||||
use DB;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Contracts\Auth\UserProvider;
|
||||
@@ -130,6 +131,13 @@ class LegacyUserProvider implements UserProvider
|
||||
throw new AuthenticationException();
|
||||
}
|
||||
|
||||
if ($tz = UserPref::getPref($user, 'timezone')) {
|
||||
session([
|
||||
'timezone' => $tz,
|
||||
'timezone_static' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (AuthenticationException $ae) {
|
||||
$auth_message = $ae->getMessage();
|
||||
|
||||
@@ -72,6 +72,22 @@ function submitCustomRange(frmdata) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function updateTimezone(tz, static)
|
||||
{
|
||||
$.post(ajax_url + '/set_timezone',
|
||||
{
|
||||
timezone: tz,
|
||||
static: static
|
||||
},
|
||||
function(data) {
|
||||
if(data === tz) {
|
||||
location.reload();
|
||||
}
|
||||
},
|
||||
'text'
|
||||
);
|
||||
}
|
||||
|
||||
function updateResolution(refresh)
|
||||
{
|
||||
$.post(ajax_url + '/set_resolution',
|
||||
|
||||
@@ -33,6 +33,11 @@ $nototal = ! $graph_params->visible('total');
|
||||
$nodetails = ! $graph_params->visible('details');
|
||||
$noagg = ! $graph_params->visible('aggregate');
|
||||
$rrd_options = '';
|
||||
$env = [];
|
||||
|
||||
if (session('timezone')) {
|
||||
$env['TZ'] = session('timezone');
|
||||
}
|
||||
|
||||
require Config::get('install_dir') . "/includes/html/graphs/$type/auth.inc.php";
|
||||
|
||||
@@ -62,7 +67,7 @@ if (! empty($command_only)) {
|
||||
echo escapeshellcmd('rrdtool ' . Rrd::buildCommand('graph', Config::get('temp_dir') . '/' . strgen(), $rrd_options));
|
||||
echo '</pre>';
|
||||
try {
|
||||
Rrd::graph($rrd_options);
|
||||
Rrd::graph($rrd_options, $env);
|
||||
} catch (\LibreNMS\Exceptions\RrdGraphException $e) {
|
||||
echo "<p style='font-size: 16px; font-weight: bold;'>RRDTool Output</p>";
|
||||
echo "<pre class='rrd-pre'>";
|
||||
@@ -82,7 +87,7 @@ if (empty($rrd_options)) {
|
||||
|
||||
// Generating the graph!
|
||||
try {
|
||||
$image_data = Rrd::graph($rrd_options);
|
||||
$image_data = Rrd::graph($rrd_options, $env);
|
||||
|
||||
// output the graph
|
||||
if (\LibreNMS\Util\Debug::isEnabled()) {
|
||||
|
||||
@@ -78,7 +78,7 @@ $pagetitle[] = 'Outages';
|
||||
clear: 'fa fa-trash-o',
|
||||
close: 'fa fa-close'
|
||||
},
|
||||
defaultDate: '<?php echo Carbon::now()->subMonth()->format(Config::get('dateformat.byminute', 'Y-m-d H:i')); ?>'
|
||||
defaultDate: '<?php echo Carbon::now(session('timezone'))->subMonth()->format(Config::get('dateformat.byminute', 'Y-m-d H:i')); ?>'
|
||||
});
|
||||
$("#dtpickerfrom").on("dp.change", function (e) {
|
||||
$("#dtpickerto").data("DateTimePicker").minDate(e.date);
|
||||
@@ -95,7 +95,7 @@ $pagetitle[] = 'Outages';
|
||||
clear: 'fa fa-trash-o',
|
||||
close: 'fa fa-close'
|
||||
},
|
||||
defaultDate: '<?php echo Carbon::now()->format(Config::get('dateformat.byminute', 'Y-m-d H:i')); ?>'
|
||||
defaultDate: '<?php echo Carbon::now(session('timezone'))->format(Config::get('dateformat.byminute', 'Y-m-d H:i')); ?>'
|
||||
});
|
||||
$("#dtpickerto").on("dp.change", function (e) {
|
||||
$("#dtpickerfrom").data("DateTimePicker").maxDate(e.date);
|
||||
@@ -106,7 +106,7 @@ $pagetitle[] = 'Outages';
|
||||
if ($("#dtpickerto").val() != "") {
|
||||
$("#dtpickerfrom").data("DateTimePicker").maxDate($("#dtpickerto").val());
|
||||
} else {
|
||||
$("#dtpickerto").data("DateTimePicker").maxDate('<?php echo Carbon::now()->format(Config::get('dateformat.byminute', 'Y-m-d H:i')); ?>');
|
||||
$("#dtpickerto").data("DateTimePicker").maxDate('<?php echo Carbon::now(session('timezone'))->format(Config::get('dateformat.byminute', 'Y-m-d H:i')); ?>');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -82,7 +82,12 @@ if ($rowCount != -1) {
|
||||
$sql .= " LIMIT $limit_low,$limit_high";
|
||||
}
|
||||
|
||||
$sql = "SELECT R.severity, D.device_id,name AS alert,rule_id, state,time_logged,DATE_FORMAT(time_logged, '" . \LibreNMS\Config::get('dateformat.mysql.compact') . "') as humandate,details $sql";
|
||||
if (session('timezone')) {
|
||||
$sql = "SELECT R.severity, D.device_id,name AS alert,rule_id,state,time_logged,DATE_FORMAT(IFNULL(CONVERT_TZ(time_logged, @@global.time_zone, ?),time_logged), '" . \LibreNMS\Config::get('dateformat.mysql.compact') . "') as humandate,details $sql";
|
||||
$param = array_merge([session('timezone')], $param);
|
||||
} else {
|
||||
$sql = "SELECT R.severity, D.device_id,name AS alert,rule_id,state,time_logged,DATE_FORMAT(time_logged, '" . \LibreNMS\Config::get('dateformat.mysql.compact') . "') as humandate,details $sql";
|
||||
}
|
||||
|
||||
$rulei = 0;
|
||||
foreach (dbFetchRows($sql, $param) as $alertlog) {
|
||||
|
||||
@@ -113,7 +113,12 @@ if ($rowCount != -1) {
|
||||
$sql .= " LIMIT $limit_low,$limit_high";
|
||||
}
|
||||
|
||||
$sql = "SELECT `alerts`.*, `devices`.`hostname`, `devices`.`sysName`, `devices`.`display`, `devices`.`os`, `devices`.`hardware`, `locations`.`location`, `alert_rules`.`rule`, `alert_rules`.`name`, `alert_rules`.`severity` $sql";
|
||||
if (session('timezone')) {
|
||||
$sql = "SELECT `alerts`.*, IFNULL(CONVERT_TZ(`alerts`.`timestamp`, @@global.time_zone, ?),`alerts`.`timestamp`) AS timestamp_display, `devices`.`hostname`, `devices`.`sysName`, `devices`.`display`, `devices`.`os`, `devices`.`hardware`, `locations`.`location`, `alert_rules`.`rule`, `alert_rules`.`name`, `alert_rules`.`severity` $sql";
|
||||
$param = array_merge([session('timezone')], $param);
|
||||
} else {
|
||||
$sql = "SELECT `alerts`.*, `alerts`.`timestamp` AS timestamp_display, `devices`.`hostname`, `devices`.`sysName`, `devices`.`display`, `devices`.`os`, `devices`.`hardware`, `locations`.`location`, `alert_rules`.`rule`, `alert_rules`.`name`, `alert_rules`.`severity` $sql";
|
||||
}
|
||||
|
||||
$rulei = 0;
|
||||
$format = $vars['format'];
|
||||
@@ -190,7 +195,7 @@ foreach (dbFetchRows($sql, $param) as $alert) {
|
||||
'verbose_details' => "<button type='button' class='btn btn-alert-details command-alert-details' aria-label='Details' id='alert-details' data-alert_log_id='{$alert_log_id}'><i class='fa-solid fa-circle-info'></i></button>",
|
||||
'hostname' => $hostname,
|
||||
'location' => generate_link($alert['location'], ['page' => 'devices', 'location' => $alert['location']]),
|
||||
'timestamp' => ($alert['timestamp'] ? $alert['timestamp'] : 'N/A'),
|
||||
'timestamp' => ($alert['timestamp_display'] ? $alert['timestamp_display'] : 'N/A'),
|
||||
'severity' => $severity_ico,
|
||||
'state' => $alert['state'],
|
||||
'alert_id' => $alert['id'],
|
||||
|
||||
@@ -359,3 +359,8 @@ parameters:
|
||||
message: "#^Parameter \\#1 \\$new_location of method App\\\\Models\\\\Device\\:\\:setLocation\\(\\) expects App\\\\Models\\\\Location\\|string, null given\\.$#"
|
||||
count: 1
|
||||
path: tests/Unit/LocationTest.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$user of static method App\\\\Models\\\\UserPref\\:\\:getPref\\(\\) expects App\\\\Models\\\\User, Illuminate\\\\Contracts\\\\Auth\\\\Authenticatable given\\.$#"
|
||||
count: 1
|
||||
path: app/Providers/LegacyUserProvider.php
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
});
|
||||
var ajax_url = "{{ url('/ajax') }}";
|
||||
</script>
|
||||
<script src="{{ asset('js/librenms.js?ver=10272021') }}"></script>
|
||||
<script src="{{ asset('js/librenms.js?ver=01112022') }}"></script>
|
||||
<script type="text/javascript" src="{{ asset('js/overlib_mini.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ asset('js/flasher.min.js?ver=0.6.1') }}"></script>
|
||||
<script type="text/javascript" src="{{ asset('js/toastr.min.js?ver=05072021') }}"></script>
|
||||
@@ -89,6 +89,16 @@
|
||||
document.documentElement.classList.remove('tw-dark')
|
||||
}
|
||||
</script>
|
||||
@if(session('timezone_static') == null || ! session('timezone_static'))
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var tz = window.Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
if(tz !== '{{ session('timezone') }}') {
|
||||
updateTimezone(tz, false);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endif
|
||||
@auth
|
||||
<script src="{{ asset('js/register-service-worker.js') }}" defer></script>
|
||||
@endauth
|
||||
|
||||
@@ -86,6 +86,19 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="form-group @if($errors->has('timezone')) has-error @endif">
|
||||
<label for="timezone" class="control-label col-sm-3">{{ __('Timezone') }}</label>
|
||||
<div class="col-sm-9">
|
||||
<select id="timezone" name="timezone" class="form-control">
|
||||
<option value="default">Browser Timezone</option>
|
||||
@foreach(timezone_identifiers_list() as $tz)
|
||||
<option value="{{ $tz }}" @if(old('timezone', $timezone) == $tz) selected @endif>{{ $tz }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<span class="help-block">{{ $errors->first('timezone') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$("[type='checkbox']").bootstrapSwitch();
|
||||
</script>
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
<th data-column-id="realname" data-formatter="text">{{ __('Real Name') }}</th>
|
||||
<th data-column-id="level" data-formatter="level" data-type="numeric">{{ __('Access') }}</th>
|
||||
<th data-column-id="auth_type" data-visible="{{ $multiauth ? 'true' : 'false' }}">{{ __('auth.title') }}</th>
|
||||
<th data-column-id="email" data-formatter="text">{{ __('Email') }}</th>
|
||||
<th data-column-id="email">{{ __('Email') }}</th>
|
||||
<th data-column-id="timezone">{{ __('Timezone') }}</th>
|
||||
@if(\LibreNMS\Authentication\LegacyAuth::getType() == 'mysql')
|
||||
<th data-column-id="enabled" data-formatter="enabled">{{ __('Enabled') }}</th>
|
||||
@endif
|
||||
@@ -38,6 +39,7 @@
|
||||
<td>{{ $user->level }}</td>
|
||||
<td>{{ $user->auth_type }}</td>
|
||||
<td>{{ $user->email }}</td>
|
||||
<td>{{ \App\Models\UserPref::getPref($user, 'timezone') ?: "Browser Timezone" }}</td>
|
||||
@if(\LibreNMS\Authentication\LegacyAuth::getType() == 'mysql')
|
||||
<td>{{ $user->enabled }}</td>
|
||||
@endif
|
||||
|
||||
@@ -92,6 +92,17 @@
|
||||
<small>* {{ __('Translation not fully supported') }}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="timezone" class="col-sm-4 control-label">{{ __('Timezone') }}</label>
|
||||
<div class="col-sm-4">
|
||||
<select class="form-control ajax-select" name="timezone" data-pref="timezone" data-previous="{{ $timezone }}">
|
||||
<option value="default">Browser Timezone</option>
|
||||
@foreach(timezone_identifiers_list() as $tz)
|
||||
<option value="{{ $tz }}" @if($timezone == $tz) selected @endif>{{ $tz }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="notetodevice" class="col-sm-4 control-label">{{ __('Add schedule notes to devices notes') }}</label>
|
||||
<div class="col-sm-4">
|
||||
@@ -238,6 +249,14 @@
|
||||
if (pref === 'site_style') {
|
||||
location.reload();
|
||||
}
|
||||
if (pref === 'timezone') {
|
||||
if(value === 'default') {
|
||||
var tz = window.Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
updateTimezone(tz, false);
|
||||
} else {
|
||||
updateTimezone(value, true);
|
||||
}
|
||||
}
|
||||
|
||||
$this.data('previous', value);
|
||||
$this.closest('.form-group').addClass('has-success');
|
||||
|
||||
@@ -230,6 +230,11 @@ Route::middleware(['auth'])->group(function () {
|
||||
Route::permanentRedirect('demo', '/');
|
||||
});
|
||||
|
||||
// routes that don't need authentication
|
||||
Route::group(['prefix' => 'ajax', 'namespace' => 'Ajax'], function () {
|
||||
Route::post('set_timezone', 'TimezoneController@set');
|
||||
});
|
||||
|
||||
// installation routes
|
||||
Route::prefix('install')->namespace('Install')->group(function () {
|
||||
Route::get('/', 'InstallationController@redirectToFirst')->name('install');
|
||||
|
||||
Reference in New Issue
Block a user