mirror of
https://github.com/grocy/grocy.git
synced 2025-04-29 09:39:57 +00:00
Refresh also habit/battery statistics on changes on overview pages (references #26)
This commit is contained in:
parent
ca3f28b615
commit
e830805443
@ -44,4 +44,9 @@ class BatteriesApiController extends BaseApiController
|
||||
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function Current(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||
{
|
||||
return $this->ApiResponse($this->BatteriesService->GetCurrent());
|
||||
}
|
||||
}
|
||||
|
@ -16,22 +16,10 @@ class BatteriesController extends BaseController
|
||||
|
||||
public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||
{
|
||||
$nextChargeTimes = array();
|
||||
foreach($this->Database->batteries() as $battery)
|
||||
{
|
||||
$nextChargeTimes[$battery->id] = $this->BatteriesService->GetNextChargeTime($battery->id);
|
||||
}
|
||||
|
||||
$nextXDays = 5;
|
||||
$countDueNextXDays = count(FindAllItemsInArrayByValue($nextChargeTimes, date('Y-m-d', strtotime("+$nextXDays days")), '<'));
|
||||
$countOverdue = count(FindAllItemsInArrayByValue($nextChargeTimes, date('Y-m-d', strtotime('-1 days')), '<'));
|
||||
return $this->AppContainer->view->render($response, 'batteriesoverview', [
|
||||
'batteries' => $this->Database->batteries()->orderBy('name'),
|
||||
'current' => $this->BatteriesService->GetCurrent(),
|
||||
'nextChargeTimes' => $nextChargeTimes,
|
||||
'nextXDays' => $nextXDays,
|
||||
'countDueNextXDays' => $countDueNextXDays - $countOverdue,
|
||||
'countOverdue' => $countOverdue
|
||||
'nextXDays' => 5
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -50,4 +50,9 @@ class HabitsApiController extends BaseApiController
|
||||
return $this->VoidApiActionResponse($response, false, 400, $ex->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function Current(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||
{
|
||||
return $this->ApiResponse($this->HabitsService->GetCurrent());
|
||||
}
|
||||
}
|
||||
|
@ -16,22 +16,10 @@ class HabitsController extends BaseController
|
||||
|
||||
public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||
{
|
||||
$nextHabitTimes = array();
|
||||
foreach($this->Database->habits() as $habit)
|
||||
{
|
||||
$nextHabitTimes[$habit->id] = $this->HabitsService->GetNextHabitTime($habit->id);
|
||||
}
|
||||
|
||||
$nextXDays = 5;
|
||||
$countDueNextXDays = count(FindAllItemsInArrayByValue($nextHabitTimes, date('Y-m-d', strtotime("+$nextXDays days")), '<'));
|
||||
$countOverdue = count(FindAllItemsInArrayByValue($nextHabitTimes, date('Y-m-d', strtotime('-1 days')), '<'));
|
||||
return $this->AppContainer->view->render($response, 'habitsoverview', [
|
||||
'habits' => $this->Database->habits()->orderBy('name'),
|
||||
'currentHabits' => $this->HabitsService->GetCurrentHabits(),
|
||||
'nextHabitTimes' => $nextHabitTimes,
|
||||
'nextXDays' => $nextXDays,
|
||||
'countDueNextXDays' => $countDueNextXDays - $countOverdue,
|
||||
'countOverdue' => $countOverdue
|
||||
'currentHabits' => $this->HabitsService->GetCurrent(),
|
||||
'nextXDays' => 5
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -568,7 +568,8 @@
|
||||
"required": false,
|
||||
"description": "The best before date of the product to add, when omitted, the current date is used",
|
||||
"schema": {
|
||||
"type": "date"
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -715,7 +716,8 @@
|
||||
"required": false,
|
||||
"description": "The best before date which applies to added products",
|
||||
"schema": {
|
||||
"type": "date"
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -842,7 +844,7 @@
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Product"
|
||||
"$ref": "#/components/schemas/CurrentStockResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1108,6 +1110,29 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/habits/get-current": {
|
||||
"get": {
|
||||
"description": "Returns all habits incl. the next estimated execution time per habit",
|
||||
"tags": [
|
||||
"Habits"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "An array of CurrentHabitResponse objects",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/CurrentHabitResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/batteries/track-charge-cycle/{batteryId}": {
|
||||
"get": {
|
||||
"description": "Tracks a charge cycle of the given battery",
|
||||
@ -1130,7 +1155,8 @@
|
||||
"required": false,
|
||||
"description": "The time of when the battery was charged, when omitted, the current time is used",
|
||||
"schema": {
|
||||
"type": "date-time"
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
],
|
||||
@ -1198,6 +1224,29 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/batteries/get-current": {
|
||||
"get": {
|
||||
"description": "Returns all batteries incl. the next estimated charge time per battery",
|
||||
"tags": [
|
||||
"Batteries"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "An array of CurrentBatteryResponse objects",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/CurrentBatteryResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
@ -1740,11 +1789,46 @@
|
||||
"type": "integer"
|
||||
},
|
||||
"best_before_date": {
|
||||
"type": "date",
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"description": "The next best before date for this product"
|
||||
}
|
||||
}
|
||||
},
|
||||
"CurrentHabitResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"habit_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"last_tracked_time": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"next_estimated_execution_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The next estimated execution time of this habit, 2999-12-31 23:59:59 when the given habit has a period_type of manually"
|
||||
}
|
||||
}
|
||||
},
|
||||
"CurrentBatteryResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"battery_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"last_tracked_time": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"next_estimated_charge_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The next estimated charge time of this battery, 2999-12-31 23:59:59 when the given battery has no charge_interval_days defined"
|
||||
}
|
||||
}
|
||||
},
|
||||
"CurrentVolatilStockResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
29
migrations/0033.sql
Normal file
29
migrations/0033.sql
Normal file
@ -0,0 +1,29 @@
|
||||
DROP VIEW habits_current;
|
||||
CREATE VIEW habits_current
|
||||
AS
|
||||
SELECT
|
||||
h.id AS habit_id,
|
||||
MAX(l.tracked_time) AS last_tracked_time,
|
||||
CASE h.period_type
|
||||
WHEN 'manually' THEN '2999-12-31 23:59:59'
|
||||
WHEN 'dynamic-regular' THEN datetime(MAX(l.tracked_time), '+' || CAST(h.period_days AS TEXT) || ' day')
|
||||
END AS next_estimated_execution_time
|
||||
FROM habits h
|
||||
LEFT JOIN habits_log l
|
||||
ON h.id = l.habit_id
|
||||
GROUP BY h.id, h.period_days;
|
||||
|
||||
DROP VIEW batteries_current;
|
||||
CREATE VIEW batteries_current
|
||||
AS
|
||||
SELECT
|
||||
b.id AS battery_id,
|
||||
MAX(l.tracked_time) AS last_tracked_time,
|
||||
CASE WHEN b.charge_interval_days = 0
|
||||
THEN '2999-12-31 23:59:59'
|
||||
ELSE datetime(MAX(l.tracked_time), '+' || CAST(b.charge_interval_days AS TEXT) || ' day')
|
||||
END AS next_estimated_charge_time
|
||||
FROM batteries b
|
||||
LEFT JOIN battery_charge_cycles l
|
||||
ON b.id = l.battery_id
|
||||
GROUP BY b.id, b.charge_interval_days;
|
@ -38,6 +38,7 @@ $(document).on('click', '.track-charge-cycle-button', function(e)
|
||||
RefreshContextualTimeago();
|
||||
|
||||
toastr.success(L('Tracked charge cylce of battery #1 on #2', batteryName, trackedTime));
|
||||
RefreshStatistics();
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
@ -45,3 +46,37 @@ $(document).on('click', '.track-charge-cycle-button', function(e)
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
function RefreshStatistics()
|
||||
{
|
||||
var nextXDays = $("#info-due-batteries").data("next-x-days");
|
||||
Grocy.Api.Get('batteries/get-current',
|
||||
function(result)
|
||||
{
|
||||
var dueCount = 0;
|
||||
var overdueCount = 0;
|
||||
var now = moment();
|
||||
var nextXDaysThreshold = moment().add(nextXDays, "days");
|
||||
result.forEach(element => {
|
||||
var date = moment(element.next_estimated_charge_time);
|
||||
if (date.isBefore(now))
|
||||
{
|
||||
overdueCount++;
|
||||
}
|
||||
else if (date.isBefore(nextXDaysThreshold))
|
||||
{
|
||||
dueCount++;
|
||||
}
|
||||
});
|
||||
|
||||
$("#info-due-batteries").text(Pluralize(dueCount, L('#1 battery is due to be charged within the next #2 days', dueCount, nextXDays), L('#1 batteries are due to be charged within the next #2 days', dueCount, nextXDays)));
|
||||
$("#info-overdue-batteries").text(Pluralize(overdueCount, L('#1 battery is overdue to be charged', overdueCount), L('#1 batteries are overdue to be charged', overdueCount)));
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
RefreshStatistics();
|
||||
|
@ -38,6 +38,7 @@ $(document).on('click', '.track-habit-button', function(e)
|
||||
RefreshContextualTimeago();
|
||||
|
||||
toastr.success(L('Tracked execution of habit #1 on #2', habitName, trackedTime));
|
||||
RefreshStatistics();
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
@ -45,3 +46,37 @@ $(document).on('click', '.track-habit-button', function(e)
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
function RefreshStatistics()
|
||||
{
|
||||
var nextXDays = $("#info-due-habits").data("next-x-days");
|
||||
Grocy.Api.Get('habits/get-current',
|
||||
function(result)
|
||||
{
|
||||
var dueCount = 0;
|
||||
var overdueCount = 0;
|
||||
var now = moment();
|
||||
var nextXDaysThreshold = moment().add(nextXDays, "days");
|
||||
result.forEach(element => {
|
||||
var date = moment(element.next_estimated_execution_time);
|
||||
if (date.isBefore(now))
|
||||
{
|
||||
overdueCount++;
|
||||
}
|
||||
else if (date.isBefore(nextXDaysThreshold))
|
||||
{
|
||||
dueCount++;
|
||||
}
|
||||
});
|
||||
|
||||
$("#info-due-habits").text(Pluralize(dueCount, L('#1 habit is due to be done within the next #2 days', dueCount, nextXDays), L('#1 habits are due to be done within the next #2 days', dueCount, nextXDays)));
|
||||
$("#info-overdue-habits").text(Pluralize(overdueCount, L('#1 habit is overdue to be done', overdueCount), L('#1 habits are overdue to be done', overdueCount)));
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
RefreshStatistics();
|
||||
|
@ -95,10 +95,12 @@ $app->group('/api', function()
|
||||
// Habits
|
||||
$this->get('/habits/track-habit-execution/{habitId}', '\Grocy\Controllers\HabitsApiController:TrackHabitExecution');
|
||||
$this->get('/habits/get-habit-details/{habitId}', '\Grocy\Controllers\HabitsApiController:HabitDetails');
|
||||
$this->get('/habits/get-current', '\Grocy\Controllers\HabitsApiController:Current');
|
||||
|
||||
// Batteries
|
||||
$this->get('/batteries/track-charge-cycle/{batteryId}', '\Grocy\Controllers\BatteriesApiController:TrackChargeCycle');
|
||||
$this->get('/batteries/get-battery-details/{batteryId}', '\Grocy\Controllers\BatteriesApiController:BatteryDetails');
|
||||
$this->get('/batteries/get-current', '\Grocy\Controllers\BatteriesApiController:Current');
|
||||
})->add(new ApiKeyAuthMiddleware($appContainer, $appContainer->LoginControllerInstance->GetSessionCookieName(), $appContainer->ApiKeyHeaderName))
|
||||
->add(JsonMiddleware::class)
|
||||
->add(new CorsMiddleware([
|
||||
|
@ -10,28 +10,6 @@ class BatteriesService extends BaseService
|
||||
return $this->DatabaseService->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||
}
|
||||
|
||||
public function GetNextChargeTime(int $batteryId)
|
||||
{
|
||||
if (!$this->BatteryExists($batteryId))
|
||||
{
|
||||
throw new \Exception('Battery does not exist');
|
||||
}
|
||||
|
||||
$battery = $this->Database->batteries($batteryId);
|
||||
$batteryLastLogRow = $this->DatabaseService->ExecuteDbQuery("SELECT * from batteries_current WHERE battery_id = $batteryId LIMIT 1")->fetch(\PDO::FETCH_OBJ);
|
||||
|
||||
if ($battery->charge_interval_days > 0)
|
||||
{
|
||||
return date('Y-m-d H:i:s', strtotime('+' . $battery->charge_interval_days . ' day', strtotime($batteryLastLogRow->last_tracked_time)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return date('2999-12-31 23:59:59');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function GetBatteryDetails(int $batteryId)
|
||||
{
|
||||
if (!$this->BatteryExists($batteryId))
|
||||
|
@ -7,33 +7,12 @@ class HabitsService extends BaseService
|
||||
const HABIT_TYPE_MANUALLY = 'manually';
|
||||
const HABIT_TYPE_DYNAMIC_REGULAR = 'dynamic-regular';
|
||||
|
||||
public function GetCurrentHabits()
|
||||
public function GetCurrent()
|
||||
{
|
||||
$sql = 'SELECT * from habits_current';
|
||||
return $this->DatabaseService->ExecuteDbQuery($sql)->fetchAll(\PDO::FETCH_OBJ);
|
||||
}
|
||||
|
||||
public function GetNextHabitTime(int $habitId)
|
||||
{
|
||||
if (!$this->HabitExists($habitId))
|
||||
{
|
||||
throw new \Exception('Habit does not exist');
|
||||
}
|
||||
|
||||
$habit = $this->Database->habits($habitId);
|
||||
$habitLastLogRow = $this->DatabaseService->ExecuteDbQuery("SELECT * from habits_current WHERE habit_id = $habitId LIMIT 1")->fetch(\PDO::FETCH_OBJ);
|
||||
|
||||
switch($habit->period_type)
|
||||
{
|
||||
case self::HABIT_TYPE_MANUALLY:
|
||||
return date('2999-12-31 23:59:59');
|
||||
case self::HABIT_TYPE_DYNAMIC_REGULAR:
|
||||
return date('Y-m-d H:i:s', strtotime('+' . $habit->period_days . ' day', strtotime($habitLastLogRow->last_tracked_time)));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function GetHabitDetails(int $habitId)
|
||||
{
|
||||
if (!$this->HabitExists($habitId))
|
||||
|
@ -12,8 +12,8 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1>@yield('title')</h1>
|
||||
<p class="btn btn-lg btn-warning no-real-button responsive-button mr-2">{{ Pluralize($countDueNextXDays, $L('#1 battery is due to be charged within the next #2 days', $countDueNextXDays, $nextXDays), $L('#1 batteries are due to be charged within the next #2 days', $countDueNextXDays, $nextXDays)) }}</p>
|
||||
<p class="btn btn-lg btn-danger no-real-button responsive-button">{{ Pluralize($countOverdue, $L('#1 battery is overdue to be charged', $countOverdue), $L('#1 batteries are overdue to be charged', $countOverdue)) }}</p>
|
||||
<p id="info-due-batteries" data-next-x-days="{{ $nextXDays }}" class="btn btn-lg btn-warning no-real-button responsive-button mr-2"></p>
|
||||
<p id="info-overdue-batteries" class="btn btn-lg btn-danger no-real-button responsive-button"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($current as $curentBatteryEntry)
|
||||
<tr class="@if(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0 && $nextChargeTimes[$curentBatteryEntry->battery_id] < date('Y-m-d H:i:s')) table-danger @elseif(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0 && $nextChargeTimes[$curentBatteryEntry->battery_id] < date('Y-m-d H:i:s', strtotime('+5 days'))) table-warning @endif">
|
||||
<tr class="@if(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0 && $curentBatteryEntry->next_estimated_charge_time < date('Y-m-d H:i:s')) table-danger @elseif(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0 && $curentBatteryEntry->next_estimated_charge_time < date('Y-m-d H:i:s', strtotime("+$nextXDays days"))) table-warning @endif">
|
||||
<td class="fit-content">
|
||||
<a class="btn btn-success btn-sm track-charge-cycle-button" href="#" title="{{ $L('Track charge cycle of battery #1', FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->name) }}"
|
||||
data-battery-id="{{ $curentBatteryEntry->battery_id }}"
|
||||
@ -54,8 +54,8 @@
|
||||
</td>
|
||||
<td>
|
||||
@if(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0)
|
||||
{{ $nextChargeTimes[$curentBatteryEntry->battery_id] }}
|
||||
<time class="timeago timeago-contextual" datetime="{{ $nextChargeTimes[$curentBatteryEntry->battery_id] }}"></time>
|
||||
{{ $curentBatteryEntry->next_estimated_charge_time }}
|
||||
<time class="timeago timeago-contextual" datetime="{{ $curentBatteryEntry->next_estimated_charge_time }}"></time>
|
||||
@else
|
||||
...
|
||||
@endif
|
||||
|
@ -12,8 +12,8 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h1>@yield('title')</h1>
|
||||
<p class="btn btn-lg btn-warning no-real-button responsive-button mr-2">{{ Pluralize($countDueNextXDays, $L('#1 habit is due to be done within the next #2 days', $countDueNextXDays, $nextXDays), $L('#1 habits are due to be done within the next #2 days', $countDueNextXDays, $nextXDays)) }}</p>
|
||||
<p class="btn btn-lg btn-danger no-real-button responsive-button">{{ Pluralize($countOverdue, $L('#1 habit is overdue to be done', $countOverdue), $L('#1 habits are overdue to be done', $countOverdue)) }}</p>
|
||||
<p id="info-due-habits" data-next-x-days="{{ $nextXDays }}" class="btn btn-lg btn-warning no-real-button responsive-button mr-2"></p>
|
||||
<p id="info-overdue-habits" class="btn btn-lg btn-danger no-real-button responsive-button"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($currentHabits as $curentHabitEntry)
|
||||
<tr class="@if(FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->period_type === \Grocy\Services\HabitsService::HABIT_TYPE_DYNAMIC_REGULAR && $nextHabitTimes[$curentHabitEntry->habit_id] < date('Y-m-d H:i:s')) table-danger @elseif(FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->period_type === \Grocy\Services\HabitsService::HABIT_TYPE_DYNAMIC_REGULAR && $nextHabitTimes[$curentHabitEntry->habit_id] < date('Y-m-d H:i:s', strtotime('+5 days'))) table-warning @endif">
|
||||
<tr class="@if(FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->period_type === \Grocy\Services\HabitsService::HABIT_TYPE_DYNAMIC_REGULAR && $curentHabitEntry->next_estimated_execution_time < date('Y-m-d H:i:s')) table-danger @elseif(FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->period_type === \Grocy\Services\HabitsService::HABIT_TYPE_DYNAMIC_REGULAR && $curentHabitEntry->next_estimated_execution_time < date('Y-m-d H:i:s', strtotime("+$nextXDays days"))) table-warning @endif">
|
||||
<td class="fit-content">
|
||||
<a class="btn btn-success btn-sm track-habit-button" href="#" title="{{ $L('Track execution of habit #1', FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->name) }}"
|
||||
data-habit-id="{{ $curentHabitEntry->habit_id }}"
|
||||
@ -53,8 +53,8 @@
|
||||
</td>
|
||||
<td>
|
||||
@if(FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->period_type === \Grocy\Services\HabitsService::HABIT_TYPE_DYNAMIC_REGULAR)
|
||||
{{ $nextHabitTimes[$curentHabitEntry->habit_id] }}
|
||||
<time class="timeago timeago-contextual" datetime="{{ $nextHabitTimes[$curentHabitEntry->habit_id] }}"></time>
|
||||
{{ $curentHabitEntry->next_estimated_execution_time }}
|
||||
<time class="timeago timeago-contextual" datetime="{{ $curentHabitEntry->next_estimated_execution_time }}"></time>
|
||||
@else
|
||||
...
|
||||
@endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user