mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 09:39:57 +00:00
Added first version of calendar (closes #42)
This commit is contained in:
parent
f7f2bf3fc0
commit
5da24d2d4f
81
controllers/CalendarController.php
Normal file
81
controllers/CalendarController.php
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Grocy\Controllers;
|
||||||
|
|
||||||
|
use \Grocy\Services\StockService;
|
||||||
|
use \Grocy\Services\TasksService;
|
||||||
|
use \Grocy\Services\ChoresService;
|
||||||
|
use \Grocy\Services\BatteriesService;
|
||||||
|
|
||||||
|
class CalendarController extends BaseController
|
||||||
|
{
|
||||||
|
public function __construct(\Slim\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
$this->StockService = new StockService();
|
||||||
|
$this->TasksService = new TasksService();
|
||||||
|
$this->ChoresService = new ChoresService();
|
||||||
|
$this->BatteriesService = new BatteriesService();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected $StockService;
|
||||||
|
protected $TasksService;
|
||||||
|
protected $ChoresService;
|
||||||
|
protected $BatteriesService;
|
||||||
|
|
||||||
|
public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
|
{
|
||||||
|
$products = $this->Database->products();
|
||||||
|
$titlePrefix = $this->LocalizationService->Localize('Product expires') . ': ';
|
||||||
|
$stockEvents = array();
|
||||||
|
foreach($this->StockService->GetCurrentStock() as $currentStockEntry)
|
||||||
|
{
|
||||||
|
$stockEvents[] = array(
|
||||||
|
'title' => $titlePrefix . FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name,
|
||||||
|
'start' => $currentStockEntry->best_before_date
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$titlePrefix = $this->LocalizationService->Localize('Task due') . ': ';
|
||||||
|
$taskEvents = array();
|
||||||
|
foreach($this->TasksService->GetCurrent() as $currentTaskEntry)
|
||||||
|
{
|
||||||
|
$taskEvents[] = array(
|
||||||
|
'title' => $titlePrefix . $currentTaskEntry->name,
|
||||||
|
'start' => $currentTaskEntry->due_date
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$chores = $this->Database->chores();
|
||||||
|
$titlePrefix = $this->LocalizationService->Localize('Chore due') . ': ';
|
||||||
|
$choreEvents = array();
|
||||||
|
foreach($this->ChoresService->GetCurrent() as $currentChoreEntry)
|
||||||
|
{
|
||||||
|
$choreEvents[] = array(
|
||||||
|
'title' => $titlePrefix . FindObjectInArrayByPropertyValue($chores, 'id', $currentChoreEntry->chore_id)->name,
|
||||||
|
'start' => $currentChoreEntry->next_estimated_execution_time
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$batteries = $this->Database->batteries();
|
||||||
|
$titlePrefix = $this->LocalizationService->Localize('Battery charge cycle due') . ': ';
|
||||||
|
$batteryEvents = array();
|
||||||
|
foreach($this->BatteriesService->GetCurrent() as $currentBatteryEntry)
|
||||||
|
{
|
||||||
|
$batteryEvents[] = array(
|
||||||
|
'title' => $titlePrefix . FindObjectInArrayByPropertyValue($batteries, 'id', $currentBatteryEntry->battery_id)->name,
|
||||||
|
'start' => $currentBatteryEntry->next_estimated_charge_time
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$fullcalendarEventSources = array();
|
||||||
|
$fullcalendarEventSources[] = $stockEvents;
|
||||||
|
$fullcalendarEventSources[] = $taskEvents;
|
||||||
|
$fullcalendarEventSources[] = $choreEvents;
|
||||||
|
$fullcalendarEventSources[] = $batteryEvents;
|
||||||
|
|
||||||
|
return $this->AppContainer->view->render($response, 'calendar', [
|
||||||
|
'fullcalendarEventSources' => $fullcalendarEventSources
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -5,5 +5,6 @@ return array(
|
|||||||
'timeago_nan' => 'NaN years ago',
|
'timeago_nan' => 'NaN years ago',
|
||||||
'moment_locale' => 'x',
|
'moment_locale' => 'x',
|
||||||
'datatables_localization' => '{"sEmptyTable":"No data available in table","sInfo":"Showing _START_ to _END_ of _TOTAL_ entries","sInfoEmpty":"Showing 0 to 0 of 0 entries","sInfoFiltered":"(filtered from _MAX_ total entries)","sInfoPostFix":"","sInfoThousands":",","sLengthMenu":"Show _MENU_ entries","sLoadingRecords":"Loading...","sProcessing":"Processing...","sSearch":"Search:","sZeroRecords":"No matching records found","oPaginate":{"sFirst":"First","sLast":"Last","sNext":"Next","sPrevious":"Previous"},"oAria":{"sSortAscending":": activate to sort column ascending","sSortDescending":": activate to sort column descending"}}',
|
'datatables_localization' => '{"sEmptyTable":"No data available in table","sInfo":"Showing _START_ to _END_ of _TOTAL_ entries","sInfoEmpty":"Showing 0 to 0 of 0 entries","sInfoFiltered":"(filtered from _MAX_ total entries)","sInfoPostFix":"","sInfoThousands":",","sLengthMenu":"Show _MENU_ entries","sLoadingRecords":"Loading...","sProcessing":"Processing...","sSearch":"Search:","sZeroRecords":"No matching records found","oPaginate":{"sFirst":"First","sLast":"Last","sNext":"Next","sPrevious":"Previous"},"oAria":{"sSortAscending":": activate to sort column ascending","sSortDescending":": activate to sort column descending"}}',
|
||||||
'summernote_locale' => 'x'
|
'summernote_locale' => 'x',
|
||||||
|
'fullcalendar_locale' => 'x'
|
||||||
);
|
);
|
||||||
|
@ -318,5 +318,9 @@ return array(
|
|||||||
'Not opened' => 'Not opened',
|
'Not opened' => 'Not opened',
|
||||||
'Opened' => 'Opened',
|
'Opened' => 'Opened',
|
||||||
'Mark #3 #1 of #2 as open' => 'Mark #3 #1 of #2 as open',
|
'Mark #3 #1 of #2 as open' => 'Mark #3 #1 of #2 as open',
|
||||||
'#1 opened' => '#1 opened'
|
'#1 opened' => '#1 opened',
|
||||||
|
'Product expires' => 'Product expires',
|
||||||
|
'Task due' => 'Task due',
|
||||||
|
'Chore due' => 'Chore due',
|
||||||
|
'Battery charge cycle due' => 'Battery charge cycle due'
|
||||||
);
|
);
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
"tagmanager": "https://github.com/max-favilli/tagmanager.git#3.0.2",
|
"tagmanager": "https://github.com/max-favilli/tagmanager.git#3.0.2",
|
||||||
"tempusdominus-bootstrap-4": "^5.1.2",
|
"tempusdominus-bootstrap-4": "^5.1.2",
|
||||||
"timeago": "^1.6.3",
|
"timeago": "^1.6.3",
|
||||||
"toastr": "^2.1.4"
|
"toastr": "^2.1.4",
|
||||||
|
"fullcalendar": "^3.9.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
11
public/viewjs/calendar.js
Normal file
11
public/viewjs/calendar.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
$("#calendar").fullCalendar({
|
||||||
|
"themeSystem": "bootstrap4",
|
||||||
|
"header": {
|
||||||
|
"left": "month,basicWeek",
|
||||||
|
"center": "title",
|
||||||
|
"right": "prev,next"
|
||||||
|
},
|
||||||
|
"weekNumbers": true,
|
||||||
|
"eventLimit": true,
|
||||||
|
"eventSources": fullcalendarEventSources
|
||||||
|
});
|
@ -68,6 +68,9 @@ $app->group('', function()
|
|||||||
$this->get('/equipment', '\Grocy\Controllers\EquipmentController:Overview');
|
$this->get('/equipment', '\Grocy\Controllers\EquipmentController:Overview');
|
||||||
$this->get('/equipment/{equipmentId}', '\Grocy\Controllers\EquipmentController:EditForm');
|
$this->get('/equipment/{equipmentId}', '\Grocy\Controllers\EquipmentController:EditForm');
|
||||||
|
|
||||||
|
// Other routes
|
||||||
|
$this->get('/calendar', '\Grocy\Controllers\CalendarController:Overview');
|
||||||
|
|
||||||
// OpenAPI routes
|
// OpenAPI routes
|
||||||
$this->get('/api', '\Grocy\Controllers\OpenApiController:DocumentationUi');
|
$this->get('/api', '\Grocy\Controllers\OpenApiController:DocumentationUi');
|
||||||
$this->get('/manageapikeys', '\Grocy\Controllers\OpenApiController:ApiKeysList');
|
$this->get('/manageapikeys', '\Grocy\Controllers\OpenApiController:ApiKeysList');
|
||||||
|
32
views/calendar.blade.php
Normal file
32
views/calendar.blade.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
@extends('layout.default')
|
||||||
|
|
||||||
|
@section('title', $L('Calendar'))
|
||||||
|
@section('activeNav', 'calendar')
|
||||||
|
@section('viewJsName', 'calendar')
|
||||||
|
|
||||||
|
@push('pageScripts')
|
||||||
|
<script src="{{ $U('/node_modules/fullcalendar/dist/fullcalendar.min.js?v=', true) }}{{ $version }}"></script>
|
||||||
|
@if(!empty($L('fullcalendar_locale')))<script src="{{ $U('/node_modules', true) }}/fullcalendar/dist/locale/{{ $L('fullcalendar_locale') }}.js?v={{ $version }}"></script>@endif
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@push('pageStyles')
|
||||||
|
<link href="{{ $U('/node_modules/fullcalendar/dist/fullcalendar.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h1>@yield('title')</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var fullcalendarEventSources = {!! json_encode($fullcalendarEventSources) !!}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div id="calendar"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@stop
|
@ -131,6 +131,12 @@
|
|||||||
<span class="nav-link-text">{{ $L('Battery tracking') }}</span>
|
<span class="nav-link-text">{{ $L('Battery tracking') }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item mt-4" data-toggle="tooltip" data-placement="right" title="{{ $L('Calendar') }}" data-nav-for-page="calendar">
|
||||||
|
<a class="nav-link discrete-link" href="{{ $U('/calendar') }}">
|
||||||
|
<i class="fas fa-calendar-alt"></i>
|
||||||
|
<span class="nav-link-text">{{ $L('Calendar') }}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li class="nav-item mt-4" data-toggle="tooltip" data-placement="right" title="{{ $L('Manage master data') }}">
|
<li class="nav-item mt-4" data-toggle="tooltip" data-placement="right" title="{{ $L('Manage master data') }}">
|
||||||
<a class="nav-link nav-link-collapse collapsed discrete-link" data-toggle="collapse" href="#top-nav-manager-master-data">
|
<a class="nav-link nav-link-collapse collapsed discrete-link" data-toggle="collapse" href="#top-nav-manager-master-data">
|
||||||
|
14
yarn.lock
14
yarn.lock
@ -11,7 +11,7 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.4.2.tgz#b2d782da69c45ea61954291e2615a8f7741c96b2"
|
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.4.2.tgz#b2d782da69c45ea61954291e2615a8f7741c96b2"
|
||||||
integrity sha512-lpruVv/4AkKUujyzHCNJ8yOceBf7Na/pFaX52ZI/BFMCYkUEwiQ1P0viZg//+WelrNNEgvMOvCMDEDaOMZ/u1w==
|
integrity sha512-lpruVv/4AkKUujyzHCNJ8yOceBf7Na/pFaX52ZI/BFMCYkUEwiQ1P0viZg//+WelrNNEgvMOvCMDEDaOMZ/u1w==
|
||||||
|
|
||||||
"TagManager@https://github.com/max-favilli/tagmanager.git#3.0.2":
|
"TagManager@https://github.com/max-favilli/tagmanager.git#3.0.2", "tagmanager@https://github.com/max-favilli/tagmanager.git#3.0.2":
|
||||||
version "3.0.1"
|
version "3.0.1"
|
||||||
resolved "https://github.com/max-favilli/tagmanager.git#df9eb9935c8585a392dfc00602f890caf233fa94"
|
resolved "https://github.com/max-favilli/tagmanager.git#df9eb9935c8585a392dfc00602f890caf233fa94"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -175,6 +175,14 @@ font-awesome@4.7.0:
|
|||||||
resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133"
|
resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133"
|
||||||
integrity sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=
|
integrity sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=
|
||||||
|
|
||||||
|
fullcalendar@^3.9.0:
|
||||||
|
version "3.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fullcalendar/-/fullcalendar-3.9.0.tgz#b608a9989f3416f0b1d526c6bdfeeaf2ac79eda5"
|
||||||
|
integrity sha512-bbALDK8+SBqluv8SKPDeVNtaSr87NYblte/pRgV5NnDJWCEARpRlQ1qQ/XEakcAXbMZov6rWYIvLOrtKwQo2Bg==
|
||||||
|
dependencies:
|
||||||
|
jquery "2 - 3"
|
||||||
|
moment "^2.20.1"
|
||||||
|
|
||||||
jquery-serializejson@^2.8.1:
|
jquery-serializejson@^2.8.1:
|
||||||
version "2.8.1"
|
version "2.8.1"
|
||||||
resolved "https://registry.yarnpkg.com/jquery-serializejson/-/jquery-serializejson-2.8.1.tgz#fc40dd11e5d9a6fd2a3614fdcba89e4af794f0a8"
|
resolved "https://registry.yarnpkg.com/jquery-serializejson/-/jquery-serializejson-2.8.1.tgz#fc40dd11e5d9a6fd2a3614fdcba89e4af794f0a8"
|
||||||
@ -195,7 +203,7 @@ jquery@1:
|
|||||||
resolved "https://registry.yarnpkg.com/jquery/-/jquery-1.12.4.tgz#01e1dfba290fe73deba77ceeacb0f9ba2fec9e0c"
|
resolved "https://registry.yarnpkg.com/jquery/-/jquery-1.12.4.tgz#01e1dfba290fe73deba77ceeacb0f9ba2fec9e0c"
|
||||||
integrity sha1-AeHfuikP5z3rp3zurLD5ui/sngw=
|
integrity sha1-AeHfuikP5z3rp3zurLD5ui/sngw=
|
||||||
|
|
||||||
jquery@3.3.1, jquery@>=1.12.0, jquery@>=1.2.3, jquery@>=1.7, jquery@^3.0, jquery@^3.3.1:
|
"jquery@2 - 3", jquery@3.3.1, jquery@>=1.12.0, jquery@>=1.2.3, jquery@>=1.7, jquery@^3.0, jquery@^3.3.1:
|
||||||
version "3.3.1"
|
version "3.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca"
|
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca"
|
||||||
integrity sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==
|
integrity sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==
|
||||||
@ -207,7 +215,7 @@ moment-timezone@^0.5.11:
|
|||||||
dependencies:
|
dependencies:
|
||||||
moment ">= 2.9.0"
|
moment ">= 2.9.0"
|
||||||
|
|
||||||
"moment@>= 2.9.0", moment@^2.10.2, moment@^2.22.2:
|
"moment@>= 2.9.0", moment@^2.10.2, moment@^2.20.1, moment@^2.22.2:
|
||||||
version "2.22.2"
|
version "2.22.2"
|
||||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66"
|
resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66"
|
||||||
integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=
|
integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=
|
||||||
|
Loading…
x
Reference in New Issue
Block a user