protected function schedule(Schedule $schedule)
{
$schedule->command('queue:prune-failed --hours=24')->daily()->at('03:50');
- $schedule->command('job:dispatch Maintenance\\\\CleanDownloads')->dailyAt('4:00');
- $schedule->command('job:dispatch Maintenance\\\\CleanFTP')->dailyAt('4:30');
+ $schedule->command('job:dispatchNow Maintenance\\\\CleanDownloads')->dailyAt('4:00');
+ $schedule->command('job:dispatchNow Maintenance\\\\CleanFTP')->dailyAt('4:30');
+ $schedule->command('model:prune')->dailyAt('5:00');
// $schedule->command('backup:clean')->daily()->at('04:00');
// $schedule->command('backup:run')->daily()->at('05:00');
--- /dev/null
+<?php
+
+namespace App\Http\Controllers\Admin;
+
+use App\Http\Controllers\Controller;
+use App\Jobs\MarkUserNotificationsAsRead;
+use App\Models\User;
+
+class TasksController extends Controller
+{
+ public function index()
+ {
+ /** @var User $user */
+ $user = backpack_user();
+ $notifications = $user->notifications;
+ $res = view('tasks.index', ['notifications' => clone $notifications]);
+ MarkUserNotificationsAsRead::dispatchSync($user)/*->delay(now()->addSeconds(15))*/;
+ return $res;
+ }
+
+ public function countUnread()
+ {
+ return response()->json(['unread' => backpack_user()->unreadNotifications()->count()]);
+ }
+
+ public function deleteNotification($id)
+ {
+ foreach (backpack_user()->notifications as $notification) {
+ if ($notification->id === $id) {
+ $notification->delete();
+ }
+ }
+ }
+}
use App\Jobs\Base;
use Cubist\Util\Files\Files;
+use Illuminate\Support\Facades\Notification;
class CleanDownloads extends Base
{
--- /dev/null
+<?php
+
+namespace App\Jobs;
+
+use App\Models\User;
+
+class MarkUserNotificationsAsRead extends Base
+{
+ /** @var User */
+ protected $user;
+
+ public function __construct(User $user)
+ {
+ $this->user = $user;
+ }
+
+ public function handle()
+ {
+ foreach ($this->user->notifications as $notification) {
+ if ($notification->read_at === null) {
+ $notification->markAsRead();
+ }
+ }
+ }
+}
use Cubist\Scorm\Version;
use Cubist\Util\Files\VirtualDirectory;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
+
// __('!! e-Learning')
class ELearningMedia extends ToolboxModel
{
public const MEDIA_TYPES = ['audio/mpeg', 'video/mp4', 'application/pdf'];
- protected $_operations = [ImportOperation::class, PreviewOperation::class, DownloadOperation::class,ChangeownerOperation::class];
+ protected $_operations = [ImportOperation::class, PreviewOperation::class, DownloadOperation::class, ChangeownerOperation::class];
public function setFields()
{
public function preSave()
{
$file = $this->getMediaInField('file')->first();
- $spl = new \SplFileInfo($file->getPath());
-
- $this->setAttribute('type', self::getType($spl->getExtension()));
+ if ($file !== null) {
+ $spl = new \SplFileInfo($file->getPath());
+ $this->setAttribute('type', self::getType($spl->getExtension()));
+ }
return parent::preSave();
}
--- /dev/null
+<?php
+
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\MassPrunable;
+use Illuminate\Notifications\DatabaseNotification;
+
+class Notification extends DatabaseNotification
+{
+ use MassPrunable;
+
+ protected $table = 'extranet_users.notifications';
+
+ public function prunable(): Builder
+ {
+ return static::where('created_at', '<=', now()->subDays(15));
+ }
+}
+
$query->where('company', 7);
$query->orderBy('enabled', 'ASC');
$query->orderBy('id', 'ASC');
+
}
+
}
right: 80%;
}
-.user_disabled a{
+.user_disabled a {
color: #999;
text-decoration: line-through;
}
+.la-bell {
+
+ &.unread {
+ position: relative;
+
+ &:after {
+ content: "";
+ position: absolute;
+ width: 5px;
+ height: 5px;
+ border-radius: 50%;
+ top: -1px;
+ right: -1px;
+ background-color: #f00;
+ }
+ }
+}
+
@import "context-menu";
@import "loader";
--- /dev/null
+{{-- __('!! Équipe') --}}
+@extends(backpack_view('blank'))
+
+@push('after_scripts')
+ <script>
+ (function ($) {
+ $(function () {
+ $(document).on('click', '[data-button-type="delete"]', function () {
+ let $this = this;
+ $.ajax({
+ url: '{{url('tasks/notification/')}}/' + $(this).attr('data-id'),
+ method: 'post',
+ data: {_method: 'delete'},
+ success: function () {
+ $this.closest('tr').remove();
+ },
+ });
+ });
+ });
+ })(jQuery);
+ </script>
+@endpush
+
+@section('content')
+ <style>
+ .table td, .table th {
+ vertical-align: middle;
+ }
+
+ .table tr.unread td {
+ font-weight: 600;
+ }
+
+ .table tr ul {
+ list-style: none;
+ padding: 3px 0;
+ margin: 0;
+ }
+
+ .table tr ul li {
+ margin: 2px 0;
+ }
+
+ .table tr.unread i.unread {
+ background-color: #f00;
+ border-radius: 50%;
+ width: 8px;
+ height: 8px;
+ display: block;
+ }
+ </style>
+ {{-- <h2 style="margin-top: 50px">{{__('Tâches en cours')}}</h2>--}}
+ <h2 style="margin-top: 50px">{{__('Notifications')}}</h2>
+ <table id="crudTable"
+ class="bg-white table table-striped table-hover nowrap rounded shadow-xs border-xs mt-2 dataTable dtr-inline">
+ {{-- <thead>--}}
+ {{-- <tr role="row">--}}
+ {{-- <th></th>--}}
+ {{-- <th>{{__('Bulletin')}}</th>--}}
+ {{-- <th>{{__('Date')}}</th>--}}
+ {{-- <th></th>--}}
+ {{-- </tr>--}}
+ {{-- </thead>--}}
+ <tbody>
+
+ @if(!$notifications || !count($notifications))
+ {{__('Aucune notification')}}
+ @endif
+ @foreach($notifications as $id=>$notification)
+ <tr role="row" @if($notification->read_at===null) class="unread" @endif>
+ <td></td>
+ <td>{{$notification->data['subject']}}<br>
+ <ul>
+ @foreach($notification->data['actions'] as $label=>$url)
+ <li>{{$label}} : <a href="{{$url}}" target="_blank">{{$url}}</a></li>
+ @endforeach
+ </ul>
+ </td>
+ <td><i class="unread"></i></td>
+ <td>{{$notification->created_at}}</td>
+ <td>
+ <a href="#" class="btn btn-sm btn-link" data-button-type="delete" data-id="{{$notification->id}}"><i
+ class="la la-trash"></i></a>
+ </td>
+ </tr>
+ @endforeach
+ </tbody>
+ </table>
+@endsection
+
+
$state=(backpack_user()->getToolboxSetting('sidebar_'.$id,$default)=='1')?' open':'';
return 'class="nav-item nav-dropdown'.$state.'" data-sidebar-id="'.$id.'"';
}
+
@endphp
@push('after_scripts')
<script>
}, 500);
return true;
});
+
+ function checkUnread() {
+ $.ajax({
+ url: '{{url('tasks/countUnread')}}',
+ success: function (data) {
+ if (data.unread > 0) {
+ $('.la-bell').addClass('unread');
+ } else {
+ $('.la-bell').removeClass('unread');
+ }
+ },
+ });
+ }
+
+ setInterval(function () {
+ checkUnread();
+ }, 10000);
+ checkUnread();
});
</script>
@endpush
class='nav-icon la la-dashboard'></i>{{ trans('backpack::base.dashboard') }}
</a></li>
<li class="nav-item"><a class="nav-link" href="{{ backpack_url('tasks') }}"><i
- class='nav-icon la la-bell'></i>{{ __('Tâches et notifications') }}
+ class='nav-icon la la-bell'></i>{{ __('Notifications') }}
</a></li>
@can('files:read')
Route::get('fluidbookthemepreview/{id}-burger.jpg', 'FluidbookThemePreviewController@previewBurger');
Route::get('fluidbookthemepreview/{id}-menu.jpg', 'FluidbookThemePreviewController@previewMenu');
Route::get('fluidbookthemepreview/{id}.jpg', 'FluidbookThemePreviewController@preview');
+ Route::get('tasks', 'TasksController@index');
+ Route::get('tasks/countUnread', 'TasksController@countUnread');
+ Route::delete('tasks/notification/{id}', 'TasksController@deleteNotification');
});
Route::group([