mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-09-19 10:53:37 +00:00
Expand UI for notifications.
This commit is contained in:
@@ -67,22 +67,24 @@ class HomeController extends Controller
|
|||||||
|
|
||||||
// admin notification settings:
|
// admin notification settings:
|
||||||
$notifications = [];
|
$notifications = [];
|
||||||
foreach (config('firefly.admin_notifications') as $item) {
|
foreach (config('notifications.notifications.owner') as $key => $info) {
|
||||||
$notifications[$item] = app('fireflyconfig')->get(sprintf('notification_%s', $item), true)->data;
|
if($info['enabled']) {
|
||||||
|
$notifications[$key] = app('fireflyconfig')->get(sprintf('notification_%s', $key), true)->data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$slackUrl = app('fireflyconfig')->get('slack_webhook_url', '')->data;
|
//
|
||||||
|
|
||||||
return view('admin.index', compact('title', 'mainTitleIcon', 'email', 'notifications', 'slackUrl'));
|
return view('admin.index', compact('title', 'mainTitleIcon', 'email', 'notifications'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function notifications(Request $request): RedirectResponse
|
public function notifications(Request $request): RedirectResponse
|
||||||
{
|
{
|
||||||
foreach (config('firefly.admin_notifications') as $item) {
|
foreach (config('notifications.notifications.owner') as $key => $info) {
|
||||||
$value = false;
|
$value = false;
|
||||||
if ($request->has(sprintf('notification_%s', $item))) {
|
if ($request->has(sprintf('notification_%s', $key))) {
|
||||||
$value = true;
|
$value = true;
|
||||||
}
|
}
|
||||||
app('fireflyconfig')->set(sprintf('notification_%s', $item), $value);
|
app('fireflyconfig')->set(sprintf('notification_%s', $key), $value);
|
||||||
}
|
}
|
||||||
$url = (string)$request->get('slackUrl');
|
$url = (string)$request->get('slackUrl');
|
||||||
if ('' === $url) {
|
if ('' === $url) {
|
||||||
|
44
app/Http/Controllers/Admin/NotificationController.php
Normal file
44
app/Http/Controllers/Admin/NotificationController.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* NotificationController.php
|
||||||
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace FireflyIII\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use FireflyIII\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
|
class NotificationController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
Log::channel('audit')->info('User visits notifications index.');
|
||||||
|
$title = (string) trans('firefly.administration');
|
||||||
|
$mainTitleIcon = 'fa-hand-spock-o';
|
||||||
|
$subTitle = (string) trans('firefly.title_owner_notifications');
|
||||||
|
$subTitleIcon = 'envelope-o';
|
||||||
|
$slackUrl = app('fireflyconfig')->get('slack_webhook_url', '')->data;
|
||||||
|
$discordUrl = app('fireflyconfig')->get('discord_webhook_url', '')->data;
|
||||||
|
$channels = config('notifications.channels');
|
||||||
|
|
||||||
|
return view('admin.notifications.index', compact('title', 'subTitle', 'mainTitleIcon', 'subTitleIcon', 'channels', 'slackUrl','discordUrl'));
|
||||||
|
}
|
||||||
|
}
|
@@ -111,6 +111,7 @@ class PreferencesController extends Controller
|
|||||||
|
|
||||||
// notification preferences (single value for each):
|
// notification preferences (single value for each):
|
||||||
$notifications = [];
|
$notifications = [];
|
||||||
|
die('fix the reference to the available notifications.');
|
||||||
foreach (config('firefly.available_notifications') as $notification) {
|
foreach (config('firefly.available_notifications') as $notification) {
|
||||||
$notifications[$notification] = app('preferences')->get(sprintf('notification_%s', $notification), true)->data;
|
$notifications[$notification] = app('preferences')->get(sprintf('notification_%s', $notification), true)->data;
|
||||||
}
|
}
|
||||||
@@ -165,6 +166,7 @@ class PreferencesController extends Controller
|
|||||||
|
|
||||||
// extract notifications:
|
// extract notifications:
|
||||||
$all = $request->all();
|
$all = $request->all();
|
||||||
|
die('fix the reference to the available notifications.');
|
||||||
foreach (config('firefly.available_notifications') as $option) {
|
foreach (config('firefly.available_notifications') as $option) {
|
||||||
$key = sprintf('notification_%s', $option);
|
$key = sprintf('notification_%s', $option);
|
||||||
if (array_key_exists($key, $all)) {
|
if (array_key_exists($key, $all)) {
|
||||||
|
@@ -147,9 +147,7 @@ return [
|
|||||||
'update_endpoint' => 'https://version.firefly-iii.org/index.json',
|
'update_endpoint' => 'https://version.firefly-iii.org/index.json',
|
||||||
'update_minimum_age' => 7,
|
'update_minimum_age' => 7,
|
||||||
|
|
||||||
// notifications
|
|
||||||
'available_notifications' => ['bill_reminder', 'new_access_token', 'transaction_creation', 'user_login', 'rule_action_failures'],
|
|
||||||
'admin_notifications' => ['admin_new_reg', 'user_new_reg', 'new_version', 'invite_created', 'invite_redeemed'],
|
|
||||||
|
|
||||||
// enabled languages
|
// enabled languages
|
||||||
'languages' => [
|
'languages' => [
|
||||||
|
54
config/notifications.php
Normal file
54
config/notifications.php
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* notifications.php
|
||||||
|
* Copyright (c) 2024 james@firefly-iii.org.
|
||||||
|
*
|
||||||
|
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
return [
|
||||||
|
'channels' => [
|
||||||
|
'email' => ['enabled' => true, 'ui_configurable' => 0,],
|
||||||
|
'slack' => ['enabled' => true, 'ui_configurable' => 1,],
|
||||||
|
'discord' => ['enabled' => true, 'ui_configurable' => 1,],
|
||||||
|
'nfty' => ['enabled' => false, 'ui_configurable' => 0,],
|
||||||
|
'pushover' => ['enabled' => false, 'ui_configurable' => 0,],
|
||||||
|
'gotify' => ['enabled' => false, 'ui_configurable' => 0,],
|
||||||
|
'pushbullet' => ['enabled' => false, 'ui_configurable' => 0,],
|
||||||
|
],
|
||||||
|
'notifications' => [
|
||||||
|
'user' => [
|
||||||
|
'some_notification' => [
|
||||||
|
'enabled' => true,
|
||||||
|
'email' => '',
|
||||||
|
'slack' => '',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'owner' => [
|
||||||
|
//'invitation_created' => ['enabled' => true],
|
||||||
|
// 'some_notification' => ['enabled' => true],
|
||||||
|
'admin_new_reg' => ['enabled' => true],
|
||||||
|
'user_new_reg' => ['enabled' => true],
|
||||||
|
'new_version' => ['enabled' => true],
|
||||||
|
'invite_created' => ['enabled' => true],
|
||||||
|
'invite_redeemed' => ['enabled' => true],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
// // notifications
|
||||||
|
// 'available_notifications' => ['bill_reminder', 'new_access_token', 'transaction_creation', 'user_login', 'rule_action_failures'],
|
||||||
|
// 'admin_notifications' => ['admin_new_reg', 'user_new_reg', 'new_version', 'invite_created', 'invite_redeemed'],
|
||||||
|
];
|
@@ -86,4 +86,7 @@ return [
|
|||||||
'mfa_enableMFA' => 'Enable multi-factor authentication',
|
'mfa_enableMFA' => 'Enable multi-factor authentication',
|
||||||
'mfa_backup_codes' => 'Backup codes',
|
'mfa_backup_codes' => 'Backup codes',
|
||||||
'mfa_disableMFA' => 'Disable multi-factor authentication',
|
'mfa_disableMFA' => 'Disable multi-factor authentication',
|
||||||
|
|
||||||
|
// notifications
|
||||||
|
'notification_index' => 'Owner notifications',
|
||||||
];
|
];
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li><a href="{{ route('admin.links.index') }}">{{ 'journal_link_configuration'|_ }}</a></li>
|
<li><a href="{{ route('admin.links.index') }}">{{ 'journal_link_configuration'|_ }}</a></li>
|
||||||
<li><a href="{{ route('admin.update-check') }}">{{ 'update_check_title'|_ }}</a></li>
|
<li><a href="{{ route('admin.update-check') }}">{{ 'update_check_title'|_ }}</a></li>
|
||||||
|
<li><a href="{{ route('admin.notifications') }}">{{ 'settings_notifications'|_ }}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -34,20 +35,20 @@
|
|||||||
<input type="hidden" name="_token" value="{{ csrf_token() }}">
|
<input type="hidden" name="_token" value="{{ csrf_token() }}">
|
||||||
<div class="box box-default">
|
<div class="box box-default">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">{{ 'admin_notifications'|_ }}</h3>
|
<h3 class="box-title">{{ 'owner_notifications'|_ }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<p>
|
<p>
|
||||||
{{ 'admin_notifications_expl'|_ }}
|
{{ 'owner_notifications_expl'|_ }}
|
||||||
</p>
|
</p>
|
||||||
{% for notification, value in notifications %}
|
{% for notification, value in notifications %}
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input value="1" {% if true == value %}checked{% endif %} type="checkbox" name="notification_{{ notification }}"> {{ trans('firefly.admin_notification_check_'~notification) }}
|
<input value="1" {% if true == value %}checked{% endif %} type="checkbox" name="notification_{{ notification }}"> {{ trans('firefly.owner_notification_check_'~notification) }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{{ ExpandedForm.text('slackUrl', slackUrl, {'label' : 'slack_url_label'|_}) }}
|
{# {{ ExpandedForm.text('slackUrl', slackUrl, {'label' : 'slack_url_label'|_}) }} #}
|
||||||
</div>
|
</div>
|
||||||
<div class="box-footer">
|
<div class="box-footer">
|
||||||
<button type="submit" class="btn btn-success">
|
<button type="submit" class="btn btn-success">
|
||||||
|
68
resources/views/admin/notifications/index.twig
Normal file
68
resources/views/admin/notifications/index.twig
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
{% extends './layout/default' %}
|
||||||
|
|
||||||
|
{% block breadcrumbs %}
|
||||||
|
{{ Breadcrumbs.render }}
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="row" xmlns="http://www.w3.org/1999/html">
|
||||||
|
<div class="col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||||
|
<form action="{{ route('admin.notification.post') }}" method="post">
|
||||||
|
<input type="hidden" name="_token" value="{{ csrf_token() }}">
|
||||||
|
<div class="box box-default">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{ 'notification_settings'|_ }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
{{ ExpandedForm.text('slackUrl', slackUrl, {'label' : 'slack_url_label'|_}) }}
|
||||||
|
{{ ExpandedForm.text('discordUrl', discordUrl, {'label' : 'discord_url_label'|_}) }}
|
||||||
|
</div>
|
||||||
|
<div class="box-footer">
|
||||||
|
<button type="submit" class="btn btn-success">
|
||||||
|
<span class="fa fa-check-circle"></span> {{ ('save_notification_settings')|_ }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<form action="{{ route('admin.notification.test') }}" method="post">
|
||||||
|
<div class="col-lg-6 col-md-12 col-sm-12 col-xs-12">
|
||||||
|
<input type="hidden" name="_token" value="{{ csrf_token() }}">
|
||||||
|
<div class="box box-default">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{ 'available_channels_title'|_ }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
<p>
|
||||||
|
{{ 'available_channels_expl'|_ }}
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
{% for name,info in channels %}
|
||||||
|
<li>
|
||||||
|
{% if info.enabled %}
|
||||||
|
☑️ {{ trans('firefly.notification_channel_name_'~name) }}
|
||||||
|
{% if 0 == info.ui_configurable %}({{ 'configure_channel_in_env'|_ }}) {% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if not info.enabled %}
|
||||||
|
⚠️ {{ trans('firefly.notification_channel_name_'~name) }} ({{ 'channel_not_available'|_ }})
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="box-footer">
|
||||||
|
<div class="btn-group">
|
||||||
|
{% for name,info in channels %}
|
||||||
|
{% if info.enabled %}
|
||||||
|
<button type="submit" name="test_submit" value="{{ name }}" class="btn btn-default">
|
||||||
|
{{ trans('firefly.test_notification_channel_name_'~name) }}
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
@@ -2,7 +2,7 @@
|
|||||||
<label for="{{ options.id }}" class="col-sm-4 control-label">{{ label }}</label>
|
<label for="{{ options.id }}" class="col-sm-4 control-label">{{ label }}</label>
|
||||||
|
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
{{ Html.select(name~"[]", list, selected).id(options.id).class('form-control').attribute('multiple').attribute('autocomplete','off').attribute('spellcheck','false').attribute('placeholder', options.placeholder) }}
|
{{ Html.multiselect(name~"[]", list, selected).id(options.id).class('form-control').attribute('autocomplete','off').attribute('spellcheck','false').attribute('placeholder', options.placeholder) }}
|
||||||
{% include 'form.help' %}
|
{% include 'form.help' %}
|
||||||
{% include 'form.feedback' %}
|
{% include 'form.feedback' %}
|
||||||
|
|
||||||
|
@@ -56,7 +56,13 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{# SINGLE INFO MESSAGE #}
|
{# SINGLE INFO MESSAGE #}
|
||||||
{% if session('info') is not iterable %}
|
{% if session('info') is not iterable %}
|
||||||
|
{% if session_has('info_url') %}
|
||||||
|
<a href="{{ session('info_url') }}">
|
||||||
|
{% endif %}
|
||||||
<strong>{{ 'flash_info'|_ }}:</strong> {{ session('info')|raw }}
|
<strong>{{ 'flash_info'|_ }}:</strong> {{ session('info')|raw }}
|
||||||
|
{% if session_has('info_url') %}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@@ -179,6 +179,15 @@ Breadcrumbs::for(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Breadcrumbs::for(
|
||||||
|
'admin.notification.index',
|
||||||
|
static function (Generator $breadcrumbs): void {
|
||||||
|
$breadcrumbs->parent('home');
|
||||||
|
$breadcrumbs->push(trans('firefly.administration'), route('admin.index'));
|
||||||
|
$breadcrumbs->push(trans('breadcrumbs.notification_index'), route('admin.notification.index'));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
Breadcrumbs::for(
|
Breadcrumbs::for(
|
||||||
'admin.users',
|
'admin.users',
|
||||||
static function (Generator $breadcrumbs): void {
|
static function (Generator $breadcrumbs): void {
|
||||||
|
@@ -1398,6 +1398,11 @@ Route::group(
|
|||||||
// FF configuration:
|
// FF configuration:
|
||||||
Route::get('configuration', ['uses' => 'ConfigurationController@index', 'as' => 'configuration.index']);
|
Route::get('configuration', ['uses' => 'ConfigurationController@index', 'as' => 'configuration.index']);
|
||||||
Route::post('configuration', ['uses' => 'ConfigurationController@postIndex', 'as' => 'configuration.index.post']);
|
Route::post('configuration', ['uses' => 'ConfigurationController@postIndex', 'as' => 'configuration.index.post']);
|
||||||
|
|
||||||
|
// routes for notifications settings.
|
||||||
|
Route::get('notifications', ['uses' => 'NotificationController@index', 'as' => 'notification.index']);
|
||||||
|
Route::post('notifications', ['uses' => 'NotificationController@postIndex', 'as' => 'notification.post']);
|
||||||
|
Route::post('notifications/test', ['uses' => 'NotificationController@testNotification', 'as' => 'notification.test']);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user