Fixed all (or most of) the broken stuff after the dependency upgrade party

This commit is contained in:
Bernd Bestel 2018-07-11 19:43:05 +02:00
parent 71701804ea
commit 778191fd11
No known key found for this signature in database
GPG Key ID: 71BD34C0D4891300
51 changed files with 553 additions and 498 deletions

137
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "42031c0b205b7ce7efb4b6eb95a0096a", "content-hash": "131ab83ecb1ea3d1a431cc70b5092448",
"packages": [ "packages": [
{ {
"name": "container-interop/container-interop", "name": "container-interop/container-interop",
@ -158,16 +158,16 @@
}, },
{ {
"name": "illuminate/container", "name": "illuminate/container",
"version": "v5.6.17", "version": "v5.6.27",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/container.git", "url": "https://github.com/illuminate/container.git",
"reference": "4a42d667a05ec6d31f05b532cdac7e8e68e5ea2a" "reference": "1f0757cae8749400aeda730f6438a081fc3c082d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/illuminate/container/zipball/4a42d667a05ec6d31f05b532cdac7e8e68e5ea2a", "url": "https://api.github.com/repos/illuminate/container/zipball/1f0757cae8749400aeda730f6438a081fc3c082d",
"reference": "4a42d667a05ec6d31f05b532cdac7e8e68e5ea2a", "reference": "1f0757cae8749400aeda730f6438a081fc3c082d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -198,20 +198,20 @@
], ],
"description": "The Illuminate Container package.", "description": "The Illuminate Container package.",
"homepage": "https://laravel.com", "homepage": "https://laravel.com",
"time": "2018-01-21T02:13:38+00:00" "time": "2018-05-24T13:16:56+00:00"
}, },
{ {
"name": "illuminate/contracts", "name": "illuminate/contracts",
"version": "v5.6.17", "version": "v5.6.27",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/contracts.git", "url": "https://github.com/illuminate/contracts.git",
"reference": "322ec80498b3bf85bc4025d028e130a9b50242b9" "reference": "3dc639feabe0f302f574157a782ede323881a944"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/illuminate/contracts/zipball/322ec80498b3bf85bc4025d028e130a9b50242b9", "url": "https://api.github.com/repos/illuminate/contracts/zipball/3dc639feabe0f302f574157a782ede323881a944",
"reference": "322ec80498b3bf85bc4025d028e130a9b50242b9", "reference": "3dc639feabe0f302f574157a782ede323881a944",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -242,11 +242,11 @@
], ],
"description": "The Illuminate Contracts package.", "description": "The Illuminate Contracts package.",
"homepage": "https://laravel.com", "homepage": "https://laravel.com",
"time": "2018-04-07T17:05:26+00:00" "time": "2018-05-11T23:38:58+00:00"
}, },
{ {
"name": "illuminate/events", "name": "illuminate/events",
"version": "v5.6.17", "version": "v5.6.27",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/events.git", "url": "https://github.com/illuminate/events.git",
@ -291,16 +291,16 @@
}, },
{ {
"name": "illuminate/filesystem", "name": "illuminate/filesystem",
"version": "v5.6.17", "version": "v5.6.27",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/filesystem.git", "url": "https://github.com/illuminate/filesystem.git",
"reference": "c9ab9376076cedd88a374d7281d62b619634d578" "reference": "2677365f61c66fad13ff12a37cd4fa8aaeb048d2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/illuminate/filesystem/zipball/c9ab9376076cedd88a374d7281d62b619634d578", "url": "https://api.github.com/repos/illuminate/filesystem/zipball/2677365f61c66fad13ff12a37cd4fa8aaeb048d2",
"reference": "c9ab9376076cedd88a374d7281d62b619634d578", "reference": "2677365f61c66fad13ff12a37cd4fa8aaeb048d2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -339,20 +339,20 @@
], ],
"description": "The Illuminate Filesystem package.", "description": "The Illuminate Filesystem package.",
"homepage": "https://laravel.com", "homepage": "https://laravel.com",
"time": "2018-04-06T13:15:37+00:00" "time": "2018-07-07T14:54:27+00:00"
}, },
{ {
"name": "illuminate/support", "name": "illuminate/support",
"version": "v5.6.17", "version": "v5.6.27",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/support.git", "url": "https://github.com/illuminate/support.git",
"reference": "cc8d6f5cef3a901de6bb7d1b362102a6db001085" "reference": "97ca44c95392ce0a41749fa47b953734d88b94b1"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/illuminate/support/zipball/cc8d6f5cef3a901de6bb7d1b362102a6db001085", "url": "https://api.github.com/repos/illuminate/support/zipball/97ca44c95392ce0a41749fa47b953734d88b94b1",
"reference": "cc8d6f5cef3a901de6bb7d1b362102a6db001085", "reference": "97ca44c95392ce0a41749fa47b953734d88b94b1",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -367,6 +367,7 @@
}, },
"suggest": { "suggest": {
"illuminate/filesystem": "Required to use the composer class (5.6.*).", "illuminate/filesystem": "Required to use the composer class (5.6.*).",
"ramsey/uuid": "Required to use Str::uuid() (^3.7).",
"symfony/process": "Required to use the composer class (~4.0).", "symfony/process": "Required to use the composer class (~4.0).",
"symfony/var-dumper": "Required to use the dd function (~4.0)." "symfony/var-dumper": "Required to use the dd function (~4.0)."
}, },
@ -396,20 +397,20 @@
], ],
"description": "The Illuminate Support package.", "description": "The Illuminate Support package.",
"homepage": "https://laravel.com", "homepage": "https://laravel.com",
"time": "2018-04-17T12:26:47+00:00" "time": "2018-07-04T01:23:57+00:00"
}, },
{ {
"name": "illuminate/view", "name": "illuminate/view",
"version": "v5.6.17", "version": "v5.6.27",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/view.git", "url": "https://github.com/illuminate/view.git",
"reference": "54eaf45ee7946d8f8cde13d5e89c5ea2e997040d" "reference": "625c35e8942f0ecd467acb8db8daf8449390d559"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/illuminate/view/zipball/54eaf45ee7946d8f8cde13d5e89c5ea2e997040d", "url": "https://api.github.com/repos/illuminate/view/zipball/625c35e8942f0ecd467acb8db8daf8449390d559",
"reference": "54eaf45ee7946d8f8cde13d5e89c5ea2e997040d", "reference": "625c35e8942f0ecd467acb8db8daf8449390d559",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -444,7 +445,7 @@
], ],
"description": "The Illuminate View package.", "description": "The Illuminate View package.",
"homepage": "https://laravel.com", "homepage": "https://laravel.com",
"time": "2018-04-03T12:56:35+00:00" "time": "2018-07-06T14:55:12+00:00"
}, },
{ {
"name": "morris/lessql", "name": "morris/lessql",
@ -496,16 +497,16 @@
}, },
{ {
"name": "neomerx/cors-psr7", "name": "neomerx/cors-psr7",
"version": "v1.0.12", "version": "v1.0.13",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/neomerx/cors-psr7.git", "url": "https://github.com/neomerx/cors-psr7.git",
"reference": "24944f39483d1a89f66ae9d58cca9f82b8815b35" "reference": "2556e2013f16a55532c95928455257d5b6bbc6e2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/neomerx/cors-psr7/zipball/24944f39483d1a89f66ae9d58cca9f82b8815b35", "url": "https://api.github.com/repos/neomerx/cors-psr7/zipball/2556e2013f16a55532c95928455257d5b6bbc6e2",
"reference": "24944f39483d1a89f66ae9d58cca9f82b8815b35", "reference": "2556e2013f16a55532c95928455257d5b6bbc6e2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -514,7 +515,7 @@
"psr/log": "^1.0" "psr/log": "^1.0"
}, },
"require-dev": { "require-dev": {
"mockery/mockery": "^0.9.9", "mockery/mockery": "^1.0",
"phpunit/phpunit": "^5.7", "phpunit/phpunit": "^5.7",
"scrutinizer/ocular": "^1.1", "scrutinizer/ocular": "^1.1",
"squizlabs/php_codesniffer": "^3.0" "squizlabs/php_codesniffer": "^3.0"
@ -547,20 +548,20 @@
"w3.org", "w3.org",
"www.w3.org" "www.w3.org"
], ],
"time": "2017-09-03T22:31:57+00:00" "time": "2018-05-23T16:10:11+00:00"
}, },
{ {
"name": "nesbot/carbon", "name": "nesbot/carbon",
"version": "1.26.4", "version": "1.32.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/briannesbitt/Carbon.git", "url": "https://github.com/briannesbitt/Carbon.git",
"reference": "e3d9014279133a3cccc01f6a691322a2d5a6a87b" "reference": "64563e2b9f69e4db1b82a60e81efa327a30ff343"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/e3d9014279133a3cccc01f6a691322a2d5a6a87b", "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/64563e2b9f69e4db1b82a60e81efa327a30ff343",
"reference": "e3d9014279133a3cccc01f6a691322a2d5a6a87b", "reference": "64563e2b9f69e4db1b82a60e81efa327a30ff343",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -572,6 +573,13 @@
"phpunit/phpunit": "^4.8.35 || ^5.7" "phpunit/phpunit": "^4.8.35 || ^5.7"
}, },
"type": "library", "type": "library",
"extra": {
"laravel": {
"providers": [
"Carbon\\Laravel\\ServiceProvider"
]
}
},
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"": "src/" "": "src/"
@ -595,7 +603,7 @@
"datetime", "datetime",
"time" "time"
], ],
"time": "2018-04-17T15:35:42+00:00" "time": "2018-07-05T06:59:26+00:00"
}, },
{ {
"name": "nikic/fast-route", "name": "nikic/fast-route",
@ -1206,16 +1214,16 @@
}, },
{ {
"name": "symfony/debug", "name": "symfony/debug",
"version": "v4.0.8", "version": "v4.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/debug.git", "url": "https://github.com/symfony/debug.git",
"reference": "5961d02d48828671f5d8a7805e06579d692f6ede" "reference": "dbe0fad88046a755dcf9379f2964c61a02f5ae3d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/5961d02d48828671f5d8a7805e06579d692f6ede", "url": "https://api.github.com/repos/symfony/debug/zipball/dbe0fad88046a755dcf9379f2964c61a02f5ae3d",
"reference": "5961d02d48828671f5d8a7805e06579d692f6ede", "reference": "dbe0fad88046a755dcf9379f2964c61a02f5ae3d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1231,7 +1239,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "4.0-dev" "dev-master": "4.1-dev"
} }
}, },
"autoload": { "autoload": {
@ -1258,20 +1266,20 @@
], ],
"description": "Symfony Debug Component", "description": "Symfony Debug Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2018-04-03T05:24:00+00:00" "time": "2018-06-08T09:39:36+00:00"
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v4.0.8", "version": "v4.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/finder.git", "url": "https://github.com/symfony/finder.git",
"reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49" "reference": "84714b8417d19e4ba02ea78a41a975b3efaafddb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/ca27c02b7a3fef4828c998c2ff9ba7aae1641c49", "url": "https://api.github.com/repos/symfony/finder/zipball/84714b8417d19e4ba02ea78a41a975b3efaafddb",
"reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49", "reference": "84714b8417d19e4ba02ea78a41a975b3efaafddb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1280,7 +1288,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "4.0-dev" "dev-master": "4.1-dev"
} }
}, },
"autoload": { "autoload": {
@ -1307,20 +1315,20 @@
], ],
"description": "Symfony Finder Component", "description": "Symfony Finder Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2018-04-04T05:10:37+00:00" "time": "2018-06-19T21:38:16+00:00"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.7.0", "version": "v1.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b" "reference": "3296adf6a6454a050679cde90f95350ad604b171"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171",
"reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b", "reference": "3296adf6a6454a050679cde90f95350ad604b171",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1332,7 +1340,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.7-dev" "dev-master": "1.8-dev"
} }
}, },
"autoload": { "autoload": {
@ -1366,20 +1374,20 @@
"portable", "portable",
"shim" "shim"
], ],
"time": "2018-01-30T19:27:44+00:00" "time": "2018-04-26T10:06:28+00:00"
}, },
{ {
"name": "symfony/translation", "name": "symfony/translation",
"version": "v4.0.8", "version": "v4.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation.git", "url": "https://github.com/symfony/translation.git",
"reference": "e20a9b7f9f62cb33a11638b345c248e7d510c938" "reference": "b6d8164085ee0b6debcd1b7a131fd6f63bb04854"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/e20a9b7f9f62cb33a11638b345c248e7d510c938", "url": "https://api.github.com/repos/symfony/translation/zipball/b6d8164085ee0b6debcd1b7a131fd6f63bb04854",
"reference": "e20a9b7f9f62cb33a11638b345c248e7d510c938", "reference": "b6d8164085ee0b6debcd1b7a131fd6f63bb04854",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1394,20 +1402,21 @@
"require-dev": { "require-dev": {
"psr/log": "~1.0", "psr/log": "~1.0",
"symfony/config": "~3.4|~4.0", "symfony/config": "~3.4|~4.0",
"symfony/console": "~3.4|~4.0",
"symfony/dependency-injection": "~3.4|~4.0", "symfony/dependency-injection": "~3.4|~4.0",
"symfony/finder": "~2.8|~3.0|~4.0", "symfony/finder": "~2.8|~3.0|~4.0",
"symfony/intl": "~3.4|~4.0", "symfony/intl": "~3.4|~4.0",
"symfony/yaml": "~3.4|~4.0" "symfony/yaml": "~3.4|~4.0"
}, },
"suggest": { "suggest": {
"psr/log": "To use logging capability in translator", "psr/log-implementation": "To use logging capability in translator",
"symfony/config": "", "symfony/config": "",
"symfony/yaml": "" "symfony/yaml": ""
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "4.0-dev" "dev-master": "4.1-dev"
} }
}, },
"autoload": { "autoload": {
@ -1434,7 +1443,7 @@
], ],
"description": "Symfony Translation Component", "description": "Symfony Translation Component",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2018-02-22T10:50:29+00:00" "time": "2018-06-22T08:59:39+00:00"
}, },
{ {
"name": "tuupola/callable-handler", "name": "tuupola/callable-handler",
@ -1604,7 +1613,7 @@
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": ">=7.0" "php": ">=7.2"
}, },
"platform-dev": [] "platform-dev": []
} }

View File

@ -17,7 +17,7 @@ class BatteriesApiController extends BaseApiController
public function TrackChargeCycle(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function TrackChargeCycle(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
$trackedTime = date('Y-m-d H:i:s'); $trackedTime = date('Y-m-d H:i:s');
if (isset($request->getQueryParams()['tracked_time']) && !empty($request->getQueryParams()['tracked_time'])) if (isset($request->getQueryParams()['tracked_time']) && !empty($request->getQueryParams()['tracked_time']) && IsIsoDateTime($request->getQueryParams()['tracked_time']))
{ {
$trackedTime = $request->getQueryParams()['tracked_time']; $trackedTime = $request->getQueryParams()['tracked_time'];
} }

View File

@ -17,7 +17,7 @@ class HabitsApiController extends BaseApiController
public function TrackHabitExecution(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function TrackHabitExecution(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
$trackedTime = date('Y-m-d H:i:s'); $trackedTime = date('Y-m-d H:i:s');
if (isset($request->getQueryParams()['tracked_time']) && !empty($request->getQueryParams()['tracked_time'])) if (isset($request->getQueryParams()['tracked_time']) && !empty($request->getQueryParams()['tracked_time']) && IsIsoDateTime($request->getQueryParams()['tracked_time']))
{ {
$trackedTime = $request->getQueryParams()['tracked_time']; $trackedTime = $request->getQueryParams()['tracked_time'];
} }

View File

@ -29,7 +29,7 @@ class StockApiController extends BaseApiController
public function AddProduct(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function AddProduct(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
$bestBeforeDate = date('Y-m-d'); $bestBeforeDate = date('Y-m-d');
if (isset($request->getQueryParams()['bestbeforedate']) && !empty($request->getQueryParams()['bestbeforedate'])) if (isset($request->getQueryParams()['bestbeforedate']) && !empty($request->getQueryParams()['bestbeforedate']) && IsIsoDate($request->getQueryParams()['bestbeforedate']))
{ {
$bestBeforeDate = $request->getQueryParams()['bestbeforedate']; $bestBeforeDate = $request->getQueryParams()['bestbeforedate'];
} }
@ -79,7 +79,7 @@ class StockApiController extends BaseApiController
public function InventoryProduct(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args) public function InventoryProduct(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
{ {
$bestBeforeDate = date('Y-m-d'); $bestBeforeDate = date('Y-m-d');
if (isset($request->getQueryParams()['bestbeforedate']) && !empty($request->getQueryParams()['bestbeforedate'])) if (isset($request->getQueryParams()['bestbeforedate']) && !empty($request->getQueryParams()['bestbeforedate']) && IsIsoDate($request->getQueryParams()['bestbeforedate']))
{ {
$bestBeforeDate = $request->getQueryParams()['bestbeforedate']; $bestBeforeDate = $request->getQueryParams()['bestbeforedate'];
} }

View File

@ -110,3 +110,15 @@ function IsAssociativeArray(array $array)
$keys = array_keys($array); $keys = array_keys($array);
return array_keys($keys) !== $keys; return array_keys($keys) !== $keys;
} }
function IsIsoDate($dateString)
{
$d = DateTime::createFromFormat('Y-m-d', $dateString);
return $d && $d->format('Y-m-d') === $dateString;
}
function IsIsoDateTime($dateTimeString)
{
$d = DateTime::createFromFormat('Y-m-d H:i:s', $dateTimeString);
return $d && $d->format('Y-m-d H:i:s') === $dateTimeString;
}

View File

@ -132,6 +132,15 @@ return array(
'Filter by location' => 'Nach Standort filtern', 'Filter by location' => 'Nach Standort filtern',
'Search' => 'Suche', 'Search' => 'Suche',
'Not logged in' => 'Nicht angemeldet', 'Not logged in' => 'Nicht angemeldet',
'You have to select a product' => 'Ein Produkt muss ausgewählt werden',
'You have to select a habit' => 'Eine Gewohnheit muss ausgewählt werden',
'You have to select a battery' => 'Eine Batterie muss ausgewählt werden',
'A name is required' => 'Ein Name ist erforderlich',
'A location is required' => 'Ein Standort ist erforderlich',
'The amount cannot be lower than #1' => 'Die Menge darf nicht kleiner als #1 sein',
'This cannot be negative' => 'Dies darf nicht negativ sein',
'A quantity unit is required' => 'Eine Mengeneinheit muss ausgewählt werden',
'A period type is required' => 'Eine Periodentyp muss ausgewählt werden',
//Constants //Constants
'manually' => 'Manuell', 'manually' => 'Manuell',

View File

@ -2,26 +2,26 @@
"name": "grocy", "name": "grocy",
"private": true, "private": true,
"dependencies": { "dependencies": {
"bootstrap": "^4.1.1",
"startbootstrap-sb-admin": "^4.0.0",
"jquery": "^3.3.1",
"font-awesome": "^4.7.0",
"bootbox": "https://github.com/makeusabrew/bootbox.git#v5.x",
"jquery-serializejson": "^2.8.1",
"bootstrap-validator": "^0.11.9",
"bootstrap-datepicker": "^1.8.0",
"moment": "^2.18.1",
"@danielfarrell/bootstrap-combobox": "https://github.com/pallidus-fintech/bootstrap-combobox.git#enhance/boostrap_4", "@danielfarrell/bootstrap-combobox": "https://github.com/pallidus-fintech/bootstrap-combobox.git#enhance/boostrap_4",
"@fortawesome/fontawesome-free": "^5.1.0",
"TagManager": "https://github.com/max-favilli/tagmanager.git#3.0.2",
"bootbox": "https://github.com/makeusabrew/bootbox.git#v5.x",
"bootstrap": "^4.1.1",
"bootstrap-datepicker": "^1.8.0",
"bootstrap-side-navbar": "https://github.com/samrayner/bootstrap-side-navbar.git#1.0.1",
"datatables.net": "^1.10.19", "datatables.net": "^1.10.19",
"datatables.net-bs4": "^1.10.19", "datatables.net-bs4": "^1.10.19",
"datatables.net-responsive": "^2.2.3", "datatables.net-responsive": "^2.2.3",
"datatables.net-responsive-bs4": "^2.2.3", "datatables.net-responsive-bs4": "^2.2.3",
"timeago": "^1.6.1", "jquery": "^3.3.1",
"toastr": "^2.1.3", "jquery-serializejson": "^2.8.1",
"jquery-ui-dist": "^1.12.1",
"moment": "^2.22.2",
"startbootstrap-sb-admin": "^4.0.0",
"swagger-ui-dist": "^3.17.3",
"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.0.1", "tempusdominus-bootstrap-4": "^5.0.1",
"swagger-ui-dist": "^3.13.4", "timeago": "^1.6.3",
"jquery-ui-dist": "^1.12.1", "toastr": "^2.1.4"
"bootstrap-side-navbar": "https://github.com/samrayner/bootstrap-side-navbar.git#1.0.1"
} }
} }

View File

@ -45,6 +45,10 @@ a.discrete-link:focus {
background-color: #e5e5e5; background-color: #e5e5e5;
} }
.content-text .invalid-feedback {
font-size: 95%;
}
/* Navigation style customizations */ /* Navigation style customizations */
#mainNav { #mainNav {
background-color: #e5e5e5 !important; background-color: #e5e5e5 !important;
@ -139,3 +143,16 @@ td {
#toast-container > div { #toast-container > div {
box-shadow: none; box-shadow: none;
} }
/* Third party component customizations - SB Admin 2 */
#mainNav .navbar-collapse .navbar-nav > .nav-item.dropdown > .nav-link:after,
#mainNav .navbar-collapse .navbar-sidenav .nav-link-collapse:after {
font-family: 'Font Awesome 5 Free';
font-weight: 900;
}
@media (max-width:992px) {
#mainNav .navbar-collapse .navbar-sidenav > .nav-item > .nav-link {
padding: 0.8em;
}
}

View File

@ -39,6 +39,10 @@ toastr.options = {
extendedTimeOut: 5000 extendedTimeOut: 5000
}; };
window.FontAwesomeConfig = {
searchPseudoElements: true
}
Grocy.Api = { }; Grocy.Api = { };
Grocy.Api.Get = function(apiFunction, success, error) Grocy.Api.Get = function(apiFunction, success, error)
{ {
@ -100,3 +104,19 @@ Grocy.Api.Post = function(apiFunction, jsonData, success, error)
xhr.setRequestHeader('Content-type', 'application/json'); xhr.setRequestHeader('Content-type', 'application/json');
xhr.send(JSON.stringify(jsonData)); xhr.send(JSON.stringify(jsonData));
}; };
Grocy.FrontendHelpers = { };
Grocy.FrontendHelpers.ValidateForm = function(formId)
{
var form = document.getElementById(formId);
if (form.checkValidity() === true)
{
$(form).find(':submit').removeClass('disabled');
}
else
{
$(form).find(':submit').addClass('disabled');
}
$(form).addClass('was-validated');
}

View File

@ -30,6 +30,26 @@
} }
}); });
$('#battery-form input').keyup(function(event)
{
Grocy.FrontendHelpers.ValidateForm('battery-form');
});
$('#battery-form input').keydown(function(event)
{
if (event.keyCode === 13) //Enter
{
if (document.getElementById('battery-form').checkValidity() === false) //There is at least one validation error
{
event.preventDefault();
return false;
}
else
{
$('#save-battery-button').click();
}
}
});
$('#name').focus(); $('#name').focus();
$('#battery-form').validator(); Grocy.FrontendHelpers.ValidateForm('battery-form');
$('#battery-form').validator('validate');

View File

@ -7,18 +7,18 @@
Grocy.Api.Get('batteries/get-battery-details/' + jsonForm.battery_id, Grocy.Api.Get('batteries/get-battery-details/' + jsonForm.battery_id,
function (batteryDetails) function (batteryDetails)
{ {
Grocy.Api.Get('batteries/track-charge-cycle/' + jsonForm.battery_id + '?tracked_time=' + $('#tracked_time').val(), Grocy.Api.Get('batteries/track-charge-cycle/' + jsonForm.battery_id + '?tracked_time=' + $('#tracked_time').find('input').val(),
function(result) function(result)
{ {
toastr.success(L('Tracked charge cylce of battery #1 on #2', batteryDetails.battery.name, $('#tracked_time').val())); toastr.success(L('Tracked charge cylce of battery #1 on #2', batteryDetails.battery.name, $('#tracked_time').find('input').val()));
$('#battery_id').val(''); $('#battery_id').val('');
$('#battery_id_text_input').focus(); $('#battery_id_text_input').focus();
$('#battery_id_text_input').val(''); $('#battery_id_text_input').val('');
$('#tracked_time').val(moment().format('YYYY-MM-DD HH:mm:ss')); $('#tracked_time').find('input').val(moment().format('YYYY-MM-DD HH:mm:ss'));
$('#tracked_time').trigger('change'); $('#tracked_time').find('input').trigger('change');
$('#battery_id_text_input').trigger('change'); $('#battery_id_text_input').trigger('change');
$('#batterytracking-form').validator('validate'); Grocy.FrontendHelpers.ValidateForm('batterytracking-form');
}, },
function(xhr) function(xhr)
{ {
@ -40,26 +40,7 @@ $('#battery_id').on('change', function(e)
if (batteryId) if (batteryId)
{ {
Grocy.Components.BatteryCard.Refresh(batteryId); Grocy.Components.BatteryCard.Refresh(batteryId);
$('#tracked_time').focus(); $('#tracked_time').find('input').focus();
}
});
$('.datetimepicker').datetimepicker(
{
format: 'YYYY-MM-DD HH:mm:ss',
showTodayButton: true,
calendarWeeks: true,
maxDate: moment()
});
$('#tracked_time').val(moment().format('YYYY-MM-DD HH:mm:ss'));
$('#tracked_time').trigger('change');
$('#tracked_time').on('focus', function(e)
{
if ($('#battery_id_text_input').val().length === 0)
{
$('#battery_id_text_input').focus();
} }
}); });
@ -71,79 +52,31 @@ $('#battery_id').val('');
$('#battery_id_text_input').focus(); $('#battery_id_text_input').focus();
$('#battery_id_text_input').val(''); $('#battery_id_text_input').val('');
$('#battery_id_text_input').trigger('change'); $('#battery_id_text_input').trigger('change');
Grocy.FrontendHelpers.ValidateForm('batterytracking-form');
$('#batterytracking-form').validator(); $('#batterytracking-form input').keyup(function (event)
$('#batterytracking-form').validator('validate'); {
Grocy.FrontendHelpers.ValidateForm('batterytracking-form');
});
$('#batterytracking-form input').keydown(function(event) $('#batterytracking-form input').keydown(function(event)
{ {
if (event.keyCode === 13) //Enter if (event.keyCode === 13) //Enter
{ {
if ($('#batterytracking-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error if (document.getElementById('batterytracking-form').checkValidity() === false) //There is at least one validation error
{ {
event.preventDefault(); event.preventDefault();
return false; return false;
} }
else
{
$('#save-batterytracking-button').click();
}
} }
}); });
$('#tracked_time').on('change', function(e) $('#tracked_time').find('input').on('keypress', function (e)
{ {
var value = $('#tracked_time').val(); Grocy.FrontendHelpers.ValidateForm('batterytracking-form');
var now = new Date();
var centuryStart = Number.parseInt(now.getFullYear().toString().substring(0, 2) + '00');
var centuryEnd = Number.parseInt(now.getFullYear().toString().substring(0, 2) + '99');
if (value === 'x' || value === 'X') {
value = '29991231';
}
if (value.length === 4 && !(Number.parseInt(value) > centuryStart && Number.parseInt(value) < centuryEnd))
{
value = (new Date()).getFullYear().toString() + value;
}
if (value.length === 8 && $.isNumeric(value))
{
value = value.replace(/(\d{4})(\d{2})(\d{2})/, '$1-$2-$3');
$('#tracked_time').val(value);
$('#batterytracking-form').validator('validate');
}
}); });
$('#tracked_time').on('keypress', function(e)
{
var element = $(e.target);
var value = element.val();
var dateObj = moment(element.val(), 'YYYY-MM-DD', true);
$('.datepicker').datepicker('hide');
//If input is empty and any arrow key is pressed, set date to today
if (value.length === 0 && (e.keyCode === 38 || e.keyCode === 40 || e.keyCode === 37 || e.keyCode === 39))
{
dateObj = moment(new Date(), 'YYYY-MM-DD', true);
}
if (dateObj.isValid())
{
if (e.keyCode === 38) //Up
{
element.val(dateObj.add(-1, 'days').format('YYYY-MM-DD'));
}
else if (e.keyCode === 40) //Down
{
element.val(dateObj.add(1, 'days').format('YYYY-MM-DD'));
}
else if (e.keyCode === 37) //Left
{
element.val(dateObj.add(-1, 'weeks').format('YYYY-MM-DD'));
}
else if (e.keyCode === 39) //Right
{
element.val(dateObj.add(1, 'weeks').format('YYYY-MM-DD'));
}
}
$('#batterytracking-form').validator('validate');
});

View File

@ -3,9 +3,25 @@ $(function()
$('.datetimepicker').datetimepicker( $('.datetimepicker').datetimepicker(
{ {
format: 'YYYY-MM-DD HH:mm:ss', format: 'YYYY-MM-DD HH:mm:ss',
showTodayButton: true, buttons: {
showToday: true,
showClose: true
},
calendarWeeks: true, calendarWeeks: true,
maxDate: moment(), maxDate: moment(),
locale: moment.locale() locale: moment.locale(),
defaultDate: moment().format('YYYY-MM-DD HH:mm:ss'),
icons: {
time: 'far fa-clock',
date: 'far fa-calendar',
up: 'fas fa-arrow-up',
down: 'fas fa-arrow-down',
previous: 'fas fa-chevron-left',
next: 'fas fa-chevron-right',
today: 'fas fa-calendar-check',
clear: 'far fa-trash-alt',
close: 'far fa-times-circle'
},
sideBySide: true
}); });
}); });

View File

@ -23,7 +23,7 @@
$('#product_id_text_input').focus(); $('#product_id_text_input').focus();
$('#product_id_text_input').val(''); $('#product_id_text_input').val('');
$('#product_id_text_input').trigger('change'); $('#product_id_text_input').trigger('change');
$('#consume-form').validator('validate'); Grocy.FrontendHelpers.ValidateForm('consume-form');
}, },
function(xhr) function(xhr)
{ {
@ -50,26 +50,19 @@ $('#product_id').on('change', function(e)
function (productDetails) function (productDetails)
{ {
$('#amount').attr('max', productDetails.stock_amount); $('#amount').attr('max', productDetails.stock_amount);
$('#consume-form').validator('update');
$('#amount_qu_unit').text(productDetails.quantity_unit_stock.name); $('#amount_qu_unit').text(productDetails.quantity_unit_stock.name);
if ((productDetails.stock_amount || 0) === 0) if ((productDetails.stock_amount || 0) === 0)
{ {
$('#product_id').val(''); $('#product_id').val('');
$('#product_id_text_input').val(''); $('#product_id_text_input').val('');
$('#product_id_text_input').addClass('has-error'); Grocy.FrontendHelpers.ValidateForm('consume-form');
$('#product_id_text_input').parent('.input-group').addClass('has-error');
$('#product_id_text_input').closest('.form-group').addClass('has-error');
$('#product-error').text(L('This product is not in stock')); $('#product-error').text(L('This product is not in stock'));
$('#product-error').show();
$('#product_id_text_input').focus(); $('#product_id_text_input').focus();
} }
else else
{ {
$('#product_id_text_input').removeClass('has-error'); Grocy.FrontendHelpers.ValidateForm('consume-form');
$('#product_id_text_input').parent('.input-group').removeClass('has-error');
$('#product_id_text_input').closest('.form-group').removeClass('has-error');
$('#product-error').hide();
$('#amount').focus(); $('#amount').focus();
} }
}, },
@ -104,9 +97,6 @@ $('#product_id_text_input').focus();
$('#product_id_text_input').val(''); $('#product_id_text_input').val('');
$('#product_id_text_input').trigger('change'); $('#product_id_text_input').trigger('change');
$('#consume-form').validator();
$('#consume-form').validator('validate');
$('#amount').on('focus', function(e) $('#amount').on('focus', function(e)
{ {
if ($('#product_id_text_input').val().length === 0) if ($('#product_id_text_input').val().length === 0)
@ -119,14 +109,23 @@ $('#amount').on('focus', function(e)
} }
}); });
$('#consume-form input').keyup(function (event)
{
Grocy.FrontendHelpers.ValidateForm('consume-form');
});
$('#consume-form input').keydown(function(event) $('#consume-form input').keydown(function(event)
{ {
if (event.keyCode === 13) //Enter if (event.keyCode === 13) //Enter
{ {
if ($('#consume-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error if (document.getElementById('consume-form').checkValidity() === false) //There is at least one validation error
{ {
event.preventDefault(); event.preventDefault();
return false; return false;
} }
else
{
$('#save-consume-button').click();
}
} }
}); });

View File

@ -30,9 +30,29 @@
} }
}); });
$('#habit-form input').keyup(function(event)
{
Grocy.FrontendHelpers.ValidateForm('habit-form');
});
$('#habit-form input').keydown(function(event)
{
if (event.keyCode === 13) //Enter
{
if (document.getElementById('habit-form').checkValidity() === false) //There is at least one validation error
{
event.preventDefault();
return false;
}
else
{
$('#save-habit-button').click();
}
}
});
$('#name').focus(); $('#name').focus();
$('#habit-form').validator(); Grocy.FrontendHelpers.ValidateForm('habit-form');
$('#habit-form').validator('validate');
$('.input-group-habit-period-type').on('change', function(e) $('.input-group-habit-period-type').on('change', function(e)
{ {
@ -42,10 +62,10 @@ $('.input-group-habit-period-type').on('change', function(e)
if (periodType === 'dynamic-regular') if (periodType === 'dynamic-regular')
{ {
$('#habit-period-type-info').text(L('This means it is estimated that a new execution of this habit is tracked #1 days after the last was tracked', periodDays.toString())); $('#habit-period-type-info').text(L('This means it is estimated that a new execution of this habit is tracked #1 days after the last was tracked', periodDays.toString()));
$('#habit-period-type-info').show(); $('#habit-period-type-info').removeClass('d-none');
} }
else else
{ {
$('#habit-period-type-info').hide(); $('#habit-period-type-info').addClass('d-none');
} }
}); });

View File

@ -7,18 +7,18 @@
Grocy.Api.Get('habits/get-habit-details/' + jsonForm.habit_id, Grocy.Api.Get('habits/get-habit-details/' + jsonForm.habit_id,
function (habitDetails) function (habitDetails)
{ {
Grocy.Api.Get('habits/track-habit-execution/' + jsonForm.habit_id + '?tracked_time=' + $('#tracked_time').val(), Grocy.Api.Get('habits/track-habit-execution/' + jsonForm.habit_id + '?tracked_time=' + $('#tracked_time').find('input').val(),
function(result) function(result)
{ {
toastr.success(L('Tracked execution of habit #1 on #2', habitDetails.habit.name, $('#tracked_time').val())); toastr.success(L('Tracked execution of habit #1 on #2', habitDetails.habit.name, $('#tracked_time').find('input').val()));
$('#habit_id').val(''); $('#habit_id').val('');
$('#habit_id_text_input').focus(); $('#habit_id_text_input').focus();
$('#habit_id_text_input').val(''); $('#habit_id_text_input').val('');
$('#tracked_time').val(moment().format('YYYY-MM-DD HH:mm:ss')); $('#tracked_time').find('input').val(moment().format('YYYY-MM-DD HH:mm:ss'));
$('#tracked_time').trigger('change'); $('#tracked_time').find('input').trigger('change');
$('#habit_id_text_input').trigger('change'); $('#habit_id_text_input').trigger('change');
$('#habittracking-form').validator('validate'); Grocy.FrontendHelpers.ValidateForm('habittracking-form');
}, },
function(xhr) function(xhr)
{ {
@ -40,18 +40,7 @@ $('#habit_id').on('change', function(e)
if (habitId) if (habitId)
{ {
Grocy.Components.HabitCard.Refresh(habitId); Grocy.Components.HabitCard.Refresh(habitId);
$('#tracked_time').focus(); $('#tracked_time').find('input').focus();
}
});
$('#tracked_time').val(moment().format('YYYY-MM-DD HH:mm:ss'));
$('#tracked_time').trigger('change');
$('#tracked_time').on('focus', function(e)
{
if ($('#habit_id_text_input').val().length === 0)
{
$('#habit_id_text_input').focus();
} }
}); });
@ -63,23 +52,30 @@ $('#habit_id').val('');
$('#habit_id_text_input').focus(); $('#habit_id_text_input').focus();
$('#habit_id_text_input').val(''); $('#habit_id_text_input').val('');
$('#habit_id_text_input').trigger('change'); $('#habit_id_text_input').trigger('change');
Grocy.FrontendHelpers.ValidateForm('habittracking-form');
$('#habittracking-form').validator(); $('#habittracking-form input').keyup(function (event)
$('#habittracking-form').validator('validate'); {
Grocy.FrontendHelpers.ValidateForm('habittracking-form');
});
$('#habittracking-form input').keydown(function(event) $('#habittracking-form input').keydown(function(event)
{ {
if (event.keyCode === 13) //Enter if (event.keyCode === 13) //Enter
{ {
if ($('#habittracking-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error if (document.getElementById('habittracking-form').checkValidity() === false) //There is at least one validation error
{ {
event.preventDefault(); event.preventDefault();
return false; return false;
} }
else
{
$('#save-habittracking-button').click();
}
} }
}); });
$('#tracked_time').on('keypress', function(e) $('#tracked_time').find('input').on('keypress', function(e)
{ {
$('#habittracking-form').validator('validate'); Grocy.FrontendHelpers.ValidateForm('habittracking-form');
}); });

View File

@ -40,14 +40,14 @@
} }
else else
{ {
$('#inventory-change-info').hide(); $('#inventory-change-info').addClass('d-none');
$('#new_amount').val(''); $('#new_amount').val('');
$('#best_before_date').val(''); $('#best_before_date').val('');
$('#product_id').val(''); $('#product_id').val('');
$('#product_id_text_input').focus(); $('#product_id_text_input').focus();
$('#product_id_text_input').val(''); $('#product_id_text_input').val('');
$('#product_id_text_input').trigger('change'); $('#product_id_text_input').trigger('change');
$('#inventory-form').validator('validate'); Grocy.FrontendHelpers.ValidateForm('inventory-form');
} }
}, },
function(xhr) function(xhr)
@ -170,33 +170,6 @@ $('#product_id_text_input').focus();
$('#product_id_text_input').val(''); $('#product_id_text_input').val('');
$('#product_id_text_input').trigger('change'); $('#product_id_text_input').trigger('change');
$('#inventory-form').validator({
custom: {
'isodate': function($el)
{
if ($el.val().length !== 0 && !moment($el.val(), 'YYYY-MM-DD', true).isValid())
{
return 'Wrong date format, needs to be YYYY-MM-DD';
}
else if (moment($el.val()).isValid())
{
if (moment($el.val()).isBefore(moment(), 'day'))
{
return 'This value cannot be before today.';
}
}
},
'notequal': function($el)
{
if ($el.val().length !== 0 && $el.val().toString() === $el.attr('not-equal').toString())
{
return 'This value cannot be equal to ' + $el.attr('not-equal').toString();
}
}
}
});
$('#inventory-form').validator('validate');
$('#new_amount').on('focus', function(e) $('#new_amount').on('focus', function(e)
{ {
if ($('#product_id_text_input').val().length === 0) if ($('#product_id_text_input').val().length === 0)
@ -209,15 +182,24 @@ $('#new_amount').on('focus', function(e)
} }
}); });
$('#inventory-form input').keyup(function (event)
{
Grocy.FrontendHelpers.ValidateForm('inventory-form');
});
$('#inventory-form input').keydown(function(event) $('#inventory-form input').keydown(function(event)
{ {
if (event.keyCode === 13) //Enter if (event.keyCode === 13) //Enter
{ {
if ($('#inventory-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error if (document.getElementById('inventory-form').checkValidity() === false) //There is at least one validation error
{ {
event.preventDefault(); event.preventDefault();
return false; return false;
} }
else
{
$('#save-inventory-button').click();
}
} }
}); });
@ -254,12 +236,12 @@ $('#new_amount').on('keypress', function(e)
$('#best_before_date').on('change', function(e) $('#best_before_date').on('change', function(e)
{ {
$('#inventory-form').validator('validate'); Grocy.FrontendHelpers.ValidateForm('inventory-form');
}); });
$('#best_before_date').on('keypress', function(e) $('#best_before_date').on('keypress', function(e)
{ {
$('#inventory-form').validator('validate'); Grocy.FrontendHelpers.ValidateForm('inventory-form');
}); });
$('#best_before_date').on('keydown', function(e) $('#best_before_date').on('keydown', function(e)
@ -270,11 +252,11 @@ $('#best_before_date').on('keydown', function(e)
} }
}); });
$('#new_amount').on('change', function(e) $('#new_amount').on('keyup', function(e)
{ {
if ($('#product_id').parent().hasClass('has-error')) if ($('#product_id').parent().hasClass('has-error'))
{ {
$('#inventory-change-info').hide(); $('#inventory-change-info').addClass('d-none');
return; return;
} }
@ -292,23 +274,22 @@ $('#new_amount').on('change', function(e)
{ {
var amountToAdd = newAmount - productDetails.stock_amount; var amountToAdd = newAmount - productDetails.stock_amount;
$('#inventory-change-info').text(L('This means #1 will be added to stock', amountToAdd.toString() + ' ' + productDetails.quantity_unit_stock.name)); $('#inventory-change-info').text(L('This means #1 will be added to stock', amountToAdd.toString() + ' ' + productDetails.quantity_unit_stock.name));
$('#inventory-change-info').show(); $('#inventory-change-info').removeClass('d-none')
$('#best_before_date').attr('required', 'required'); $('#best_before_date').attr('required', 'required');
} }
else if (newAmount < productStockAmount) else if (newAmount < productStockAmount)
{ {
var amountToRemove = productStockAmount - newAmount; var amountToRemove = productStockAmount - newAmount;
$('#inventory-change-info').text(L('This means #1 will be removed from stock', amountToRemove.toString() + ' ' + productDetails.quantity_unit_stock.name)); $('#inventory-change-info').text(L('This means #1 will be removed from stock', amountToRemove.toString() + ' ' + productDetails.quantity_unit_stock.name));
$('#inventory-change-info').show(); $('#inventory-change-info').removeClass('d-none')
$('#best_before_date').removeAttr('required'); $('#best_before_date').removeAttr('required');
} }
else else
{ {
$('#inventory-change-info').hide(); $('#inventory-change-info').addClass('d-none');
} }
$('#inventory-form').validator('update'); Grocy.FrontendHelpers.ValidateForm('inventory-form');
$('#inventory-form').validator('validate');
}, },
function(xhr) function(xhr)
{ {

View File

@ -30,6 +30,26 @@
} }
}); });
$('#location-form input').keyup(function (event)
{
Grocy.FrontendHelpers.ValidateForm('location-form');
});
$('#location-form input').keydown(function (event)
{
if (event.keyCode === 13) //Enter
{
if (document.getElementById('location-form').checkValidity() === false) //There is at least one validation error
{
event.preventDefault();
return false;
}
else
{
$('#save-location-button').click();
}
}
});
$('#name').focus(); $('#name').focus();
$('#location-form').validator(); Grocy.FrontendHelpers.ValidateForm('location-form');
$('#location-form').validator('validate');

View File

@ -1,10 +1,7 @@
$('.logout-button').hide(); $('#username').focus();
$('.logout-button-divider').hide();
$('#username').focus();
if (GetUriParam('invalid') === 'true') if (GetUriParam('invalid') === 'true')
{ {
$('#login-error').text(L('Invalid credentials, please try again')); $('#login-error').text(L('Invalid credentials, please try again'));
$('#login-error').show(); $('#login-error').removeClass('d-none');
} }

View File

@ -82,15 +82,35 @@ $('.input-group-qu').on('change', function(e)
if (factor > 1) if (factor > 1)
{ {
$('#qu-conversion-info').text(L('This means 1 #1 purchased will be converted into #2 #3 in stock', $("#qu_id_purchase option:selected").text(), (1 * factor).toString(), $("#qu_id_stock option:selected").text())); $('#qu-conversion-info').text(L('This means 1 #1 purchased will be converted into #2 #3 in stock', $("#qu_id_purchase option:selected").text(), (1 * factor).toString(), $("#qu_id_stock option:selected").text()));
$('#qu-conversion-info').show(); $('#qu-conversion-info').removeClass('d-none');
} }
else else
{ {
$('#qu-conversion-info').hide(); $('#qu-conversion-info').addClass('d-none');
}
});
$('#product-form input').keyup(function(event)
{
Grocy.FrontendHelpers.ValidateForm('product-form');
});
$('#product-form input').keydown(function(event)
{
if (event.keyCode === 13) //Enter
{
if (document.getElementById('product-form').checkValidity() === false) //There is at least one validation error
{
event.preventDefault();
return false;
}
else
{
$('#save-product-button').click();
}
} }
}); });
$('#name').focus(); $('#name').focus();
$('#product-form').validator();
$('#product-form').validator('validate');
$('.input-group-qu').trigger('change'); $('.input-group-qu').trigger('change');
Grocy.FrontendHelpers.ValidateForm('product-form');

View File

@ -48,7 +48,7 @@
$('#product_id_text_input').focus(); $('#product_id_text_input').focus();
$('#product_id_text_input').val(''); $('#product_id_text_input').val('');
$('#product_id_text_input').trigger('change'); $('#product_id_text_input').trigger('change');
$('#purchase-form').validator('validate'); Grocy.FrontendHelpers.ValidateForm('purchase-form');
} }
}, },
function(xhr) function(xhr)
@ -180,26 +180,6 @@ $('#product_id_text_input').focus();
$('#product_id_text_input').val(''); $('#product_id_text_input').val('');
$('#product_id_text_input').trigger('change'); $('#product_id_text_input').trigger('change');
$('#purchase-form').validator({
custom: {
'isodate': function($el)
{
if ($el.val().length !== 0 && !moment($el.val(), 'YYYY-MM-DD', true).isValid())
{
return 'Wrong date format, needs to be YYYY-MM-DD';
}
else if (moment($el.val()).isValid())
{
if (moment($el.val()).isBefore(moment(), 'day'))
{
return 'This value cannot be before today.';
}
}
}
}
});
$('#purchase-form').validator('validate');
$('#best_before_date').on('focus', function(e) $('#best_before_date').on('focus', function(e)
{ {
if ($('#product_id_text_input').val().length === 0) if ($('#product_id_text_input').val().length === 0)
@ -220,15 +200,24 @@ $('#amount').on('focus', function(e)
} }
}); });
$('#purchase-form input').keyup(function(event)
{
Grocy.FrontendHelpers.ValidateForm('purchase-form');
});
$('#purchase-form input').keydown(function(event) $('#purchase-form input').keydown(function(event)
{ {
if (event.keyCode === 13) //Enter if (event.keyCode === 13) //Enter
{ {
if ($('#purchase-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error if (document.getElementById('purchase-form').checkValidity() === false) //There is at least one validation error
{ {
event.preventDefault(); event.preventDefault();
return false; return false;
} }
else
{
$('#save-purchase-button').click();
}
} }
}); });
@ -260,10 +249,15 @@ if (addBarcode !== undefined)
$('#best_before_date').on('change', function(e) $('#best_before_date').on('change', function(e)
{ {
$('#purchase-form').validator('validate'); Grocy.FrontendHelpers.ValidateForm('purchase-form');
}); });
$('#best_before_date').on('keypress', function(e) $('#best_before_date').on('keypress', function(e)
{ {
$('#purchase-form').validator('validate'); Grocy.FrontendHelpers.ValidateForm('purchase-form');
});
$('#amount').on('change', function (e)
{
Grocy.FrontendHelpers.ValidateForm('purchase-form');
}); });

View File

@ -30,6 +30,26 @@
} }
}); });
$('#quantityunit-form input').keyup(function(event)
{
Grocy.FrontendHelpers.ValidateForm('quantityunit-form');
});
$('#quantityunit-form input').keydown(function(event)
{
if (event.keyCode === 13) //Enter
{
if (document.getElementById('quantityunit-form').checkValidity() === false) //There is at least one validation error
{
event.preventDefault();
return false;
}
else
{
$('#save-quantityunit-button').click();
}
}
});
$('#name').focus(); $('#name').focus();
$('#quantityunit-form').validator(); Grocy.FrontendHelpers.ValidateForm('quantityunit-form');
$('#quantityunit-form').validator('validate');

View File

@ -42,43 +42,6 @@ $('#product_id').on('change', function(e)
function (productDetails) function (productDetails)
{ {
$('#amount_qu_unit').text(productDetails.quantity_unit_purchase.name); $('#amount_qu_unit').text(productDetails.quantity_unit_purchase.name);
if ($('#product_id').hasClass('suppress-next-custom-validate-event'))
{
$('#product_id').removeClass('suppress-next-custom-validate-event');
}
else
{
Grocy.Api.Get('get-objects/shopping_list',
function (currentShoppingListItems)
{
if (currentShoppingListItems.filter(function (e) { return e.product_id === productId; }).length > 0)
{
$('#product_id').val('');
$('#product_id_text_input').val('');
$('#product_id_text_input').addClass('has-error');
$('#product_id_text_input').parent('.input-group').addClass('has-error');
$('#product_id_text_input').closest('.form-group').addClass('has-error');
$('#product-error').text('This product is already on the shopping list.');
$('#product-error').show();
$('#product_id_text_input').focus();
}
else
{
$('#product_id_text_input').removeClass('has-error');
$('#product_id_text_input').parent('.input-group').removeClass('has-error');
$('#product_id_text_input').closest('.form-group').removeClass('has-error');
$('#product-error').hide();
$('#amount').focus();
}
},
function(xhr)
{
console.error(xhr);
}
);
}
}, },
function(xhr) function(xhr)
{ {
@ -113,8 +76,7 @@ if (Grocy.EditMode === 'edit')
$('#product_id').trigger('change'); $('#product_id').trigger('change');
} }
$('#shoppinglist-form').validator(); Grocy.FrontendHelpers.ValidateForm('shoppinglist-form');
$('#shoppinglist-form').validator('validate');
$('#amount').on('focus', function(e) $('#amount').on('focus', function(e)
{ {
@ -124,14 +86,23 @@ $('#amount').on('focus', function(e)
} }
}); });
$('#shoppinglist-form input').keyup(function (event)
{
Grocy.FrontendHelpers.ValidateForm('shoppinglist-form');
});
$('#shoppinglist-form input').keydown(function (event) $('#shoppinglist-form input').keydown(function (event)
{ {
if (event.keyCode === 13) //Enter if (event.keyCode === 13) //Enter
{ {
if ($('#shoppinglist-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error if (document.getElementById('shoppinglist-form').checkValidity() === false) //There is at least one validation error
{ {
event.preventDefault(); event.preventDefault();
return false; return false;
} }
else
{
$('#save-shoppinglist-button').click();
}
} }
}); });

View File

@ -10,15 +10,15 @@
<h1> <h1>
@yield('title') @yield('title')
<a class="btn btn-outline-dark" href="{{ $U('/battery/new') }}"> <a class="btn btn-outline-dark" href="{{ $U('/battery/new') }}">
<i class="fa fa-plus"></i>&nbsp;{{ $L('Add') }} <i class="fas fa-plus"></i>&nbsp;{{ $L('Add') }}
</a> </a>
</h1> </h1>
</div> </div>
</div> </div>
<div class="row mt-3"> <div class="row mt-3">
<div class="col-3"> <div class="col-xs-12 col-md-6 col-xl-3">
<label for="search">{{ $L('Search') }}</label> <label for="search"><i class="fas fa-search"></i> {{ $L('Search') }}</label>
<input type="text" class="form-control" id="search"> <input type="text" class="form-control" id="search">
</div> </div>
</div> </div>
@ -39,10 +39,10 @@
<tr> <tr>
<td class="fit-content"> <td class="fit-content">
<a class="btn btn-info btn-sm" href="{{ $U('/battery/') }}{{ $battery->id }}"> <a class="btn btn-info btn-sm" href="{{ $U('/battery/') }}{{ $battery->id }}">
<i class="fa fa-pencil"></i> <i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-danger btn-sm battery-delete-button" href="#" data-battery-id="{{ $battery->id }}" data-battery-name="{{ $battery->name }}"> <a class="btn btn-danger btn-sm battery-delete-button" href="#" data-battery-id="{{ $battery->id }}" data-battery-name="{{ $battery->name }}">
<i class="fa fa-trash"></i> <i class="fas fa-trash"></i>
</a> </a>
</td> </td>
<td> <td>

View File

@ -18,8 +18,8 @@
</div> </div>
<div class="row mt-3"> <div class="row mt-3">
<div class="col-3"> <div class="col-xs-12 col-md-6 col-xl-3">
<label for="search">{{ $L('Search') }}</label> <label for="search"><i class="fas fa-search"></i> {{ $L('Search') }}</label>
<input type="text" class="form-control" id="search"> <input type="text" class="form-control" id="search">
</div> </div>
</div> </div>
@ -42,7 +42,7 @@
<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) }}" <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 }}" data-battery-id="{{ $curentBatteryEntry->battery_id }}"
data-battery-name="{{ FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->name }}"> data-battery-name="{{ FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->name }}">
<i class="fa fa-fire"></i> <i class="fas fa-fire"></i>
</a> </a>
</td> </td>
<td> <td>

View File

@ -19,12 +19,12 @@
<script>Grocy.EditObjectId = {{ $battery->id }}</script> <script>Grocy.EditObjectId = {{ $battery->id }}</script>
@endif @endif
<form id="battery-form"> <form id="battery-form" novalidate>
<div class="form-group"> <div class="form-group">
<label for="name">{{ $L('Name') }}</label> <label for="name">{{ $L('Name') }}</label>
<input type="text" class="form-control" required id="name" name="name" value="@if($mode == 'edit'){{ $battery->name }}@endif"> <input type="text" class="form-control" required id="name" name="name" value="@if($mode == 'edit'){{ $battery->name }}@endif">
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('A name is required') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -6,10 +6,10 @@
@section('content') @section('content')
<div class="row"> <div class="row">
<div class="col-lg-4 col-xs-12"> <div class="col-xs-12 col-md-6 col-xl-4">
<h1>@yield('title')</h1> <h1>@yield('title')</h1>
<form id="batterytracking-form"> <form id="batterytracking-form" novalidate>
<div class="form-group"> <div class="form-group">
<label for="battery_id">{{ $L('Battery') }}</label> <label for="battery_id">{{ $L('Battery') }}</label>
@ -19,26 +19,20 @@
<option value="{{ $battery->id }}">{{ $battery->name }}</option> <option value="{{ $battery->id }}">{{ $battery->name }}</option>
@endforeach @endforeach
</select> </select>
<div id="battery-error" class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('You have to select a battery') }}</div>
</div> </div>
<div class="form-group"> @include('components.datetimepicker', array(
<label for="tracked_time">{{ $L('Tracked time') }}</label> 'id' => 'tracked_time',
<div class="input-group date datetimepicker"> 'label' => 'Tracked time'
<input type="text" class="form-control" id="tracked_time" name="tracked_time" required > ))
<span class="input-group-addon">
<span class="fa fa-calendar"></span>
</span>
</div>
<div class="invalid-feedback"></div>
</div>
<button id="save-batterytracking-button" type="submit" class="btn btn-success">{{ $L('OK') }}</button> <button id="save-batterytracking-button" type="submit" class="btn btn-success">{{ $L('OK') }}</button>
</form> </form>
</div> </div>
<div class="col-lg-4 col-xs-12"> <div class="col-xs-12 col-md-6 col-xl-4">
@include('components.batterycard') @include('components.batterycard')
</div> </div>
</div> </div>

View File

@ -4,9 +4,10 @@
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<i class="fa fa-fw fa-battery-three-quarters"></i> {{ $L('Battery overview') }} <strong><span id="batterycard-battery-name"></span></strong> <i class="fas fa-battery-three-quarters"></i> {{ $L('Battery overview') }}
</div> </div>
<div class="card-body"> <div class="card-body">
<h3><span id="batterycard-battery-name"></span></h3>
<strong>{{ $L('Used in') }}:</strong> <span id="batterycard-battery-used_in"></span><br> <strong>{{ $L('Used in') }}:</strong> <span id="batterycard-battery-used_in"></span><br>
<strong>{{ $L('Charge cycles count') }}:</strong> <span id="batterycard-battery-charge-cycles-count"></span><br> <strong>{{ $L('Charge cycles count') }}:</strong> <span id="batterycard-battery-charge-cycles-count"></span><br>
<strong>{{ $L('Last charged') }}:</strong> <span id="batterycard-battery-last-charged"></span> <time id="batterycard-battery-last-charged-timeago" class="timeago timeago-contextual"></time><br> <strong>{{ $L('Last charged') }}:</strong> <span id="batterycard-battery-last-charged"></span> <time id="batterycard-battery-last-charged-timeago" class="timeago timeago-contextual"></time><br>

View File

@ -5,9 +5,9 @@
<div class="form-group"> <div class="form-group">
<label for="{{ $id }}">{{ $L($label) }}&nbsp;&nbsp;<span class="small text-muted"><time id="datepicker-timeago" class="timeago timeago-contextual"></time>@if(!empty($hint))<br>{{ $L($hint) }}@endif</span></label> <label for="{{ $id }}">{{ $L($label) }}&nbsp;&nbsp;<span class="small text-muted"><time id="datepicker-timeago" class="timeago timeago-contextual"></time>@if(!empty($hint))<br>{{ $L($hint) }}@endif</span></label>
<div class="input-group date"> <div class="input-group date">
<input type="text" data-isodate="isodate" class="form-control datepicker" id="{{ $id }}" name="{{ $id }}" required autocomplete="off"> <input type="text" data-isodate="isodate" class="form-control datepicker" id="{{ $id }}" name="{{ $id }}" required autocomplete="off" min="2018-07-11">
<div id="datepicker-button" class="input-group-append"> <div id="datepicker-button" class="input-group-append">
<div class="input-group-text"><i class="fa fa-calendar"></i></div> <div class="input-group-text"><i class="fas fa-calendar"></i></div>
</div> </div>
</div> </div>
<div class="invalid-feedback"></div> <div class="invalid-feedback"></div>

View File

@ -3,11 +3,11 @@
@endpush @endpush
<div class="form-group"> <div class="form-group">
<label for="{{ $id }}">{{ $L($label) }}</label> <label>{{ $L($label) }}</label>
<div class="input-group date datetimepicker" id="{{ $id }}" data-target-input="nearest"> <div class="input-group date datetimepicker" id="{{ $id }}" data-target-input="nearest">
<input type="text" class="form-control datetimepicker-input" data-target="#{{ $id }}"/> <input type="text" class="form-control datetimepicker-input" data-target="#{{ $id }}"/>
<div class="input-group-append" data-target="#{{ $id }}" data-toggle="datetimepicker"> <div class="input-group-append" data-target="#{{ $id }}" data-toggle="datetimepicker">
<div class="input-group-text"><i class="fa fa-calendar"></i></div> <div class="input-group-text"><i class="fas fa-calendar"></i></div>
</div> </div>
</div> </div>
<div class="invalid-feedback"></div> <div class="invalid-feedback"></div>

View File

@ -4,9 +4,10 @@
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<i class="fa fa-fw fa-refresh"></i> {{ $L('Habit overview') }} <strong><span id="habitcard-habit-name"></span></strong> <i class="fas fa-refresh"></i> {{ $L('Habit overview') }}
</div> </div>
<div class="card-body"> <div class="card-body">
<h3><span id="habitcard-habit-name"></span></h3>
<strong>{{ $L('Tracked count') }}:</strong> <span id="habitcard-habit-tracked-count"></span><br> <strong>{{ $L('Tracked count') }}:</strong> <span id="habitcard-habit-tracked-count"></span><br>
<strong>{{ $L('Last tracked') }}:</strong> <span id="habitcard-habit-last-tracked"></span> <time id="habitcard-habit-last-tracked-timeago" class="timeago timeago-contextual"></time><br> <strong>{{ $L('Last tracked') }}:</strong> <span id="habitcard-habit-last-tracked"></span> <time id="habitcard-habit-last-tracked-timeago" class="timeago timeago-contextual"></time><br>
</div> </div>

View File

@ -4,9 +4,10 @@
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<i class="fa fa-fw fa-product-hunt"></i> {{ $L('Product overview') }} <strong><span id="productcard-product-name"></span></strong> <i class="fab fa-product-hunt"></i> {{ $L('Product overview') }}
</div> </div>
<div class="card-body"> <div class="card-body">
<h3><span id="productcard-product-name"></span></h3>
<strong>{{ $L('Stock quantity unit') }}:</strong> <span id="productcard-product-stock-qu-name"></span><br> <strong>{{ $L('Stock quantity unit') }}:</strong> <span id="productcard-product-stock-qu-name"></span><br>
<strong>{{ $L('Stock amount') }}:</strong> <span id="productcard-product-stock-amount"></span> <span id="productcard-product-stock-qu-name2"></span><br> <strong>{{ $L('Stock amount') }}:</strong> <span id="productcard-product-stock-amount"></span> <span id="productcard-product-stock-qu-name2"></span><br>
<strong>{{ $L('Last purchased') }}:</strong> <span id="productcard-product-last-purchased"></span> <time id="productcard-product-last-purchased-timeago" class="timeago timeago-contextual"></time><br> <strong>{{ $L('Last purchased') }}:</strong> <span id="productcard-product-last-purchased"></span> <time id="productcard-product-last-purchased-timeago" class="timeago timeago-contextual"></time><br>

View File

@ -6,26 +6,26 @@
@section('content') @section('content')
<div class="row"> <div class="row">
<div class="col-lg-4 col-xs-12"> <div class="col-xs-12 col-md-6 col-xl-4">
<h1>@yield('title')</h1> <h1>@yield('title')</h1>
<form id="consume-form"> <form id="consume-form" novalidate>
<div class="form-group"> <div class="form-group">
<label for="product_id">{{ $L('Product') }}&nbsp;&nbsp;<i class="fa fa-barcode"></i></label> <label for="product_id">{{ $L('Product') }}&nbsp;&nbsp;<i class="fas fa-barcode"></i></label>
<select class="form-control combobox" id="product_id" name="product_id" required> <select class="form-control combobox" id="product_id" name="product_id" required>
<option value=""></option> <option value=""></option>
@foreach($products as $product) @foreach($products as $product)
<option data-additional-searchdata="{{ $product->barcode }}" value="{{ $product->id }}">{{ $product->name }}</option> <option data-additional-searchdata="{{ $product->barcode }}" value="{{ $product->id }}">{{ $product->name }}</option>
@endforeach @endforeach
</select> </select>
<div id="product-error" class="invalid-feedback"></div> <div id="product-error" class="invalid-feedback">{{ $L('You have to select a product') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="amount">{{ $L('Amount') }}&nbsp;&nbsp;<span id="amount_qu_unit" class="small text-muted"></span></label> <label for="amount">{{ $L('Amount') }}&nbsp;&nbsp;<span id="amount_qu_unit" class="small text-muted"></span></label>
<input type="number" class="form-control" id="amount" name="amount" value="1" min="1" required> <input type="number" class="form-control" id="amount" name="amount" value="1" min="1" required>
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('The amount cannot be lower than #1', '0') }}</div>
</div> </div>
<div class="checkbox"> <div class="checkbox">
@ -39,7 +39,7 @@
</form> </form>
</div> </div>
<div class="col-lg-6 col-xs-12"> <div class="col-xs-12 col-md-6 col-xl-4">
@include('components.productcard') @include('components.productcard')
</div> </div>
</div> </div>

View File

@ -19,12 +19,12 @@
<script>Grocy.EditObjectId = {{ $habit->id }};</script> <script>Grocy.EditObjectId = {{ $habit->id }};</script>
@endif @endif
<form id="habit-form"> <form id="habit-form" novalidate>
<div class="form-group"> <div class="form-group">
<label for="name">{{ $L('Name') }}</label> <label for="name">{{ $L('Name') }}</label>
<input type="text" class="form-control" required id="name" name="name" value="@if($mode == 'edit'){{ $habit->name }}@endif"> <input type="text" class="form-control" required id="name" name="name" value="@if($mode == 'edit'){{ $habit->name }}@endif">
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('A name is required') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -39,16 +39,16 @@
<option @if($mode == 'edit' && $periodType == $habit->period_type) selected="selected" @endif value="{{ $periodType }}">{{ $L($periodType) }}</option> <option @if($mode == 'edit' && $periodType == $habit->period_type) selected="selected" @endif value="{{ $periodType }}">{{ $L($periodType) }}</option>
@endforeach @endforeach
</select> </select>
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('A period type is required') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="period_days">{{ $L('Period days') }}</label> <label for="period_days">{{ $L('Period days') }}</label>
<input type="number" class="form-control input-group-habit-period-type" id="period_days" name="period_days" value="@if($mode == 'edit'){{ $habit->period_days }}@endif"> <input type="number" class="form-control input-group-habit-period-type" id="period_days" name="period_days" min="0" value="@if($mode == 'edit'){{ $habit->period_days }}@endif">
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('This cannot be negative') }}</div>
</div> </div>
<p id="habit-period-type-info" class="help-block text-muted"></p> <p id="habit-period-type-info" class="form-text text-muted small d-none"></p>
<button id="save-habit-button" type="submit" class="btn btn-success">{{ $L('Save') }}</button> <button id="save-habit-button" type="submit" class="btn btn-success">{{ $L('Save') }}</button>

View File

@ -10,15 +10,15 @@
<h1> <h1>
@yield('title') @yield('title')
<a class="btn btn-outline-dark" href="{{ $U('/habit/new') }}"> <a class="btn btn-outline-dark" href="{{ $U('/habit/new') }}">
<i class="fa fa-plus"></i>&nbsp;{{ $L('Add') }} <i class="fas fa-plus"></i>&nbsp;{{ $L('Add') }}
</a> </a>
</h1> </h1>
</div> </div>
</div> </div>
<div class="row mt-3"> <div class="row mt-3">
<div class="col-3"> <div class="col-xs-12 col-md-6 col-xl-3">
<label for="search">{{ $L('Search') }}</label> <label for="search"><i class="fas fa-search"></i> {{ $L('Search') }}</label>
<input type="text" class="form-control" id="search"> <input type="text" class="form-control" id="search">
</div> </div>
</div> </div>
@ -40,10 +40,10 @@
<tr> <tr>
<td class="fit-content"> <td class="fit-content">
<a class="btn btn-info btn-sm" href="{{ $U('/habit/') }}{{ $habit->id }}"> <a class="btn btn-info btn-sm" href="{{ $U('/habit/') }}{{ $habit->id }}">
<i class="fa fa-pencil"></i> <i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-danger btn-sm habit-delete-button" href="#" data-habit-id="{{ $habit->id }}" data-habit-name="{{ $habit->name }}"> <a class="btn btn-danger btn-sm habit-delete-button" href="#" data-habit-id="{{ $habit->id }}" data-habit-name="{{ $habit->name }}">
<i class="fa fa-trash"></i> <i class="fas fa-trash"></i>
</a> </a>
</td> </td>
<td> <td>

View File

@ -18,8 +18,8 @@
</div> </div>
<div class="row mt-3"> <div class="row mt-3">
<div class="col-3"> <div class="col-xs-12 col-md-6 col-xl-3">
<label for="search">{{ $L('Search') }}</label> <label for="search"><i class="fas fa-search"></i> {{ $L('Search') }}</label>
<input type="text" class="form-control" id="search"> <input type="text" class="form-control" id="search">
</div> </div>
</div> </div>
@ -42,7 +42,7 @@
<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) }}" <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 }}" data-habit-id="{{ $curentHabitEntry->habit_id }}"
data-habit-name="{{ FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->name }}"> data-habit-name="{{ FindObjectInArrayByPropertyValue($habits, 'id', $curentHabitEntry->habit_id)->name }}">
<i class="fa fa-play"></i> <i class="fas fa-play"></i>
</a> </a>
</td> </td>
<td> <td>

View File

@ -6,10 +6,10 @@
@section('content') @section('content')
<div class="row"> <div class="row">
<div class="col-lg-4 col-xs-12"> <div class="col-xs-12 col-md-6 col-xl-4">
<h1>@yield('title')</h1> <h1>@yield('title')</h1>
<form id="habittracking-form"> <form id="habittracking-form" novalidate>
<div class="form-group"> <div class="form-group">
<label for="habit_id">{{ $L('Habit') }}</label> <label for="habit_id">{{ $L('Habit') }}</label>
@ -19,7 +19,7 @@
<option value="{{ $habit->id }}">{{ $habit->name }}</option> <option value="{{ $habit->id }}">{{ $habit->name }}</option>
@endforeach @endforeach
</select> </select>
<div id="product-error" class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('You have to select a habit') }}</div>
</div> </div>
@include('components.datetimepicker', array( @include('components.datetimepicker', array(
@ -32,7 +32,7 @@
</form> </form>
</div> </div>
<div class="col-lg-4 col-xs-12"> <div class="col-xs-12 col-md-6 col-xl-4">
@include('components.habitcard') @include('components.habitcard')
</div> </div>
</div> </div>

View File

@ -6,28 +6,28 @@
@section('content') @section('content')
<div class="row"> <div class="row">
<div class="col-lg-4 col-xs-12"> <div class="col-xs-12 col-md-6 col-xl-4">
<h1>@yield('title')</h1> <h1>@yield('title')</h1>
<form id="inventory-form"> <form id="inventory-form" novalidate>
<div class="form-group"> <div class="form-group">
<label for="product_id">{{ $L('Product') }}&nbsp;&nbsp;<i class="fa fa-barcode"></i><span id="barcode-lookup-disabled-hint" class="small text-muted d-none">&nbsp;&nbsp;{{ $L('Barcode lookup is disabled') }}</span></label> <label for="product_id">{{ $L('Product') }}&nbsp;&nbsp;<i class="fas fa-barcode"></i><span id="barcode-lookup-disabled-hint" class="small text-muted d-none">&nbsp;&nbsp;{{ $L('Barcode lookup is disabled') }}</span></label>
<select class="form-control combobox" id="product_id" name="product_id" required> <select class="form-control combobox" id="product_id" name="product_id" required>
<option value=""></option> <option value=""></option>
@foreach($products as $product) @foreach($products as $product)
<option data-additional-searchdata="{{ $product->barcode }}" value="{{ $product->id }}">{{ $product->name }}</option> <option data-additional-searchdata="{{ $product->barcode }}" value="{{ $product->id }}">{{ $product->name }}</option>
@endforeach @endforeach
</select> </select>
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('You have to select a product') }}</div>
<div id="flow-info-addbarcodetoselection" class="text-muted small d-none"><strong><span id="addbarcodetoselection"></span></strong> {{ $L('will be added to the list of barcodes for the selected product on submit') }}</div> <div id="flow-info-addbarcodetoselection" class="form-text text-muted small d-none"><strong><span id="addbarcodetoselection"></span></strong> {{ $L('will be added to the list of barcodes for the selected product on submit') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="new_amount">{{ $L('New amount') }}&nbsp;&nbsp;<span id="new_amount_qu_unit" class="small text-muted"></span></label> <label for="new_amount">{{ $L('New amount') }}&nbsp;&nbsp;<span id="new_amount_qu_unit" class="small text-muted"></span></label>
<input type="number" data-notequal="notequal" class="form-control" id="new_amount" name="new_amount" min="0" not-equal="-1" required> <input type="number" data-notequal="notequal" class="form-control" id="new_amount" name="new_amount" min="0" not-equal="-1" required>
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('The amount cannot be lower than #1', '0') }}</div>
<div id="inventory-change-info" class="text-muted"></div> <div id="inventory-change-info" class="form-text text-muted small d-none"></div>
</div> </div>
@include('components.datepicker', array( @include('components.datepicker', array(
@ -41,7 +41,7 @@
</form> </form>
</div> </div>
<div class="col-lg-4 col-xs-12"> <div class="col-xs-12 col-md-6 col-xl-4">
@include('components.productcard') @include('components.productcard')
</div> </div>
</div> </div>

View File

@ -15,7 +15,7 @@
<link href="{{ $U('/node_modules/bootstrap/dist/css/bootstrap.min.css?v=', true) }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/node_modules/bootstrap/dist/css/bootstrap.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/node_modules/startbootstrap-sb-admin/css/sb-admin.min.css?v=', true) }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/node_modules/startbootstrap-sb-admin/css/sb-admin.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/node_modules/font-awesome/css/font-awesome.min.css?v=', true) }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/node_modules/@fortawesome/fontawesome-free/css/all.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css?v=', true) }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker3.min.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/node_modules/@danielfarrell/bootstrap-combobox/css/bootstrap-combobox.css?v=', true) }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/node_modules/@danielfarrell/bootstrap-combobox/css/bootstrap-combobox.css?v=', true) }}{{ $version }}" rel="stylesheet">
<link href="{{ $U('/node_modules/datatables.net-bs4/css/dataTables.bootstrap4.css?v=', true) }}{{ $version }}" rel="stylesheet"> <link href="{{ $U('/node_modules/datatables.net-bs4/css/dataTables.bootstrap4.css?v=', true) }}{{ $version }}" rel="stylesheet">
@ -38,104 +38,104 @@
<body class="fixed-nav"> <body class="fixed-nav">
<nav id="mainNav" class="navbar navbar-expand-lg navbar-light fixed-top"> <nav id="mainNav" class="navbar navbar-expand-lg navbar-light fixed-top">
<a class="navbar-brand" href="{{ $U('/') }}"><img src="{{ $U('/img/grocy_logo.svg?v=', true) }}" height="30"></a> <a class="navbar-brand py-0" href="{{ $U('/') }}"><img src="{{ $U('/img/grocy_logo.svg?v=', true) }}{{ $version }}" height="30"></a>
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#sidebarResponsive"> <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#sidebarResponsive">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
<div id="sidebarResponsive" class="collapse navbar-collapse"> <div id="sidebarResponsive" class="collapse navbar-collapse">
<ul class="navbar-nav navbar-sidenav"> <ul class="navbar-nav navbar-sidenav pt-2">
<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Stock overview') }}" data-nav-for-page="stockoverview"> <li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Stock overview') }}" data-nav-for-page="stockoverview">
<a class="nav-link discrete-link" href="{{ $U('/stockoverview') }}"> <a class="nav-link discrete-link" href="{{ $U('/stockoverview') }}">
<i class="fa fa-fw fa-dashboard"></i> <i class="fas fa-tachometer-alt"></i>
<span class="nav-link-text">{{ $L('Stock overview') }}</span> <span class="nav-link-text">{{ $L('Stock overview') }}</span>
</a> </a>
</li> </li>
<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Habits overview') }}" data-nav-for-page="habitsoverview"> <li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Habits overview') }}" data-nav-for-page="habitsoverview">
<a class="nav-link discrete-link" href="{{ $U('/habitsoverview') }}"> <a class="nav-link discrete-link" href="{{ $U('/habitsoverview') }}">
<i class="fa fa-fw fa-dashboard"></i> <i class="fas fa-tachometer-alt"></i>
<span class="nav-link-text">{{ $L('Habits overview') }}</span> <span class="nav-link-text">{{ $L('Habits overview') }}</span>
</a> </a>
</li> </li>
<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Batteries overview') }}" data-nav-for-page="batteriesoverview"> <li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Batteries overview') }}" data-nav-for-page="batteriesoverview">
<a class="nav-link discrete-link" href="{{ $U('/batteriesoverview') }}"> <a class="nav-link discrete-link" href="{{ $U('/batteriesoverview') }}">
<i class="fa fa-fw fa-dashboard"></i> <i class="fas fa-tachometer-alt"></i>
<span class="nav-link-text">{{ $L('Batteries overview') }}</span> <span class="nav-link-text">{{ $L('Batteries overview') }}</span>
</a> </a>
</li> </li>
<li class="nav-item mt-4" data-toggle="tooltip" data-placement="right" title="{{ $L('Purchase') }}" data-nav-for-page="purchase"> <li class="nav-item mt-4" data-toggle="tooltip" data-placement="right" title="{{ $L('Purchase') }}" data-nav-for-page="purchase">
<a class="nav-link discrete-link" href="{{ $U('/purchase') }}"> <a class="nav-link discrete-link" href="{{ $U('/purchase') }}">
<i class="fa fa-fw fa-shopping-cart"></i> <i class="fas fa-shopping-cart"></i>
<span class="nav-link-text">{{ $L('Purchase') }}</span> <span class="nav-link-text">{{ $L('Purchase') }}</span>
</a> </a>
</li> </li>
<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Consume') }}" data-nav-for-page="consume"> <li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Consume') }}" data-nav-for-page="consume">
<a class="nav-link discrete-link" href="{{ $U('/consume') }}"> <a class="nav-link discrete-link" href="{{ $U('/consume') }}">
<i class="fa fa-fw fa-cutlery"></i> <i class="fas fa-utensils"></i>
<span class="nav-link-text">{{ $L('Consume') }}</span> <span class="nav-link-text">{{ $L('Consume') }}</span>
</a> </a>
</li> </li>
<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Shopping list') }}" data-nav-for-page="shoppinglist"> <li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Shopping list') }}" data-nav-for-page="shoppinglist">
<a class="nav-link discrete-link" href="{{ $U('/shoppinglist') }}"> <a class="nav-link discrete-link" href="{{ $U('/shoppinglist') }}">
<i class="fa fa-fw fa-shopping-bag"></i> <i class="fas fa-shopping-bag"></i>
<span class="nav-link-text">{{ $L('Shopping list') }}</span> <span class="nav-link-text">{{ $L('Shopping list') }}</span>
</a> </a>
</li> </li>
<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Inventory') }}" data-nav-for-page="inventory"> <li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Inventory') }}" data-nav-for-page="inventory">
<a class="nav-link discrete-link" href="{{ $U('/inventory') }}"> <a class="nav-link discrete-link" href="{{ $U('/inventory') }}">
<i class="fa fa-fw fa-list"></i> <i class="fas fa-list"></i>
<span class="nav-link-text">{{ $L('Inventory') }}</span> <span class="nav-link-text">{{ $L('Inventory') }}</span>
</a> </a>
</li> </li>
<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Habit tracking') }}" data-nav-for-page="habittracking"> <li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Habit tracking') }}" data-nav-for-page="habittracking">
<a class="nav-link discrete-link" href="{{ $U('/habittracking') }}"> <a class="nav-link discrete-link" href="{{ $U('/habittracking') }}">
<i class="fa fa-fw fa-play"></i> <i class="fas fa-play"></i>
<span class="nav-link-text">{{ $L('Habit tracking') }}</span> <span class="nav-link-text">{{ $L('Habit tracking') }}</span>
</a> </a>
</li> </li>
<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Battery tracking') }}" data-nav-for-page="batterytracking"> <li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Battery tracking') }}" data-nav-for-page="batterytracking">
<a class="nav-link discrete-link" href="{{ $U('/batterytracking') }}"> <a class="nav-link discrete-link" href="{{ $U('/batterytracking') }}">
<i class="fa fa-fw fa-fire"></i> <i class="fas fa-fire"></i>
<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('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">
<i class="fa fa-fw fa-wrench"></i> <i class="fas fa-table"></i>
<span class="nav-link-text">{{ $L('Manage master data') }}</span> <span class="nav-link-text">{{ $L('Manage master data') }}</span>
</a> </a>
<ul id="top-nav-manager-master-data" class="sidenav-second-level collapse"> <ul id="top-nav-manager-master-data" class="sidenav-second-level collapse">
<li data-nav-for-page="products"> <li data-nav-for-page="products">
<a class="nav-link discrete-link" href="{{ $U('/products') }}"> <a class="nav-link discrete-link" href="{{ $U('/products') }}">
<i class="fa fa-fw fa-product-hunt"></i> <i class="fab fa-product-hunt"></i>
<span class="nav-link-text">{{ $L('Products') }}</span> <span class="nav-link-text">{{ $L('Products') }}</span>
</a> </a>
</li> </li>
<li data-nav-for-page="locations"> <li data-nav-for-page="locations">
<a class="nav-link discrete-link" href="{{ $U('/locations') }}"> <a class="nav-link discrete-link" href="{{ $U('/locations') }}">
<i class="fa fa-fw fa-map-marker"></i> <i class="fas fa-map-marker-alt"></i>
<span class="nav-link-text">{{ $L('Locations') }}</span> <span class="nav-link-text">{{ $L('Locations') }}</span>
</a> </a>
</li> </li>
<li data-nav-for-page="quantityunits"> <li data-nav-for-page="quantityunits">
<a class="nav-link discrete-link" href="{{ $U('/quantityunits') }}"> <a class="nav-link discrete-link" href="{{ $U('/quantityunits') }}">
<i class="fa fa-fw fa-balance-scale"></i> <i class="fas fa-balance-scale"></i>
<span class="nav-link-text">{{ $L('Quantity units') }}</span> <span class="nav-link-text">{{ $L('Quantity units') }}</span>
</a> </a>
</li> </li>
<li data-nav-for-page="habits"> <li data-nav-for-page="habits">
<a class="nav-link discrete-link" href="{{ $U('/habits') }}"> <a class="nav-link discrete-link" href="{{ $U('/habits') }}">
<i class="fa fa-fw fa-refresh"></i> <i class="fas fa-sync-alt"></i>
<span class="nav-link-text">{{ $L('Habits') }}</span> <span class="nav-link-text">{{ $L('Habits') }}</span>
</a> </a>
</li> </li>
<li data-nav-for-page="batteries"> <li data-nav-for-page="batteries">
<a class="nav-link discrete-link" href="{{ $U('/batteries') }}"> <a class="nav-link discrete-link" href="{{ $U('/batteries') }}">
<i class="fa fa-fw fa-battery-three-quarters"></i> <i class="fas fa-battery-three-quarters"></i>
<span class="nav-link-text">{{ $L('Batteries') }}</span> <span class="nav-link-text">{{ $L('Batteries') }}</span>
</a> </a>
</li> </li>
@ -146,26 +146,32 @@
<ul class="navbar-nav sidenav-toggler"> <ul class="navbar-nav sidenav-toggler">
<li class="nav-item"> <li class="nav-item">
<a id="sidenavToggler" class="nav-link text-center"> <a id="sidenavToggler" class="nav-link text-center">
<i class="fa fa-fw fa-angle-left"></i> <i class="fas fa-angle-left"></i>
</a> </a>
</li> </li>
</ul> </ul>
<ul class="navbar-nav ml-auto"> <ul class="navbar-nav ml-auto">
@if(AUTHENTICATED === true)
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link dropdown-toggle mr-lg-2" href="#" data-toggle="dropdown">@if(AUTHENTICATED === true){{ HTTP_USER }}@else{{ $L('Not logged in') }}@endif</a> <a class="nav-link dropdown-toggle discrete-link" href="#" data-toggle="dropdown"><i class="fas fa-user"></i> {{ HTTP_USER }}</a>
<div class="dropdown-menu dropdown-menu-right"> <div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item logout-button discrete-link" href="{{ $U('/logout') }}"><i class="fa fa-sign-out fa-fw"></i>&nbsp;{{ $L('Logout') }}</a> <a class="dropdown-item logout-button discrete-link" href="{{ $U('/logout') }}"><i class="fas fa-sign-out-alt"></i>&nbsp;{{ $L('Logout') }}</a>
</div>
</li>
@endif
<div class="dropdown-divider logout-button-divider"></div> <li class="nav-item dropdown">
<a class="nav-link dropdown-toggle discrete-link" href="#" data-toggle="dropdown"><i class="fas fa-wrench"></i></a>
<a class="dropdown-item discrete-link" href="{{ $U('/manageapikeys') }}"><i class="fa fa-handshake-o fa-fw"></i>&nbsp;{{ $L('Manage API keys') }}</a> <div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item discrete-link" target="_blank" href="{{ $U('/api') }}"><i class="fa fa-book"></i>&nbsp;{{ $L('REST API & data model documentation') }}</a> <a class="dropdown-item discrete-link" href="{{ $U('/manageapikeys') }}"><i class="fas fa-handshake"></i>&nbsp;{{ $L('Manage API keys') }}</a>
<a class="dropdown-item discrete-link" target="_blank" href="{{ $U('/api') }}"><i class="fas fa-book"></i>&nbsp;{{ $L('REST API & data model documentation') }}</a>
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<a class="dropdown-item discrete-link" href="#" data-toggle="modal" data-target="#about-modal"><i class="fa fa-info fa-fw"></i>&nbsp;{{ $L('About grocy') }} (Version {{ $version }})</a> <a class="dropdown-item discrete-link" href="#" data-toggle="modal" data-target="#about-modal"><i class="fas fa-info fa-fw"></i>&nbsp;{{ $L('About grocy') }} (Version {{ $version }})</a>
</div> </div>
</li> </li>
</ul> </ul>
@ -199,7 +205,7 @@
<br> <br>
Life runs on code<br> Life runs on code<br>
<a href="https://github.com/berrnd/grocy" class="discrete-link" target="_blank"> <a href="https://github.com/berrnd/grocy" class="discrete-link" target="_blank">
<i class="fa fa-github"></i> <i class="fas fa-github"></i>
</a> </a>
</div> </div>
</div> </div>
@ -212,10 +218,9 @@
<script src="{{ $U('/node_modules/bootbox/dist/bootbox.min.js?v=', true) }}{{ $version }}"></script> <script src="{{ $U('/node_modules/bootbox/dist/bootbox.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/node_modules/jquery-serializeJSON/jquery.serializejson.min.js?v=', true) }}{{ $version }}"></script> <script src="{{ $U('/node_modules/jquery-serializeJSON/jquery.serializejson.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js?v=', true) }}{{ $version }}"></script> <script src="{{ $U('/node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js?v=', true) }}{{ $version }}"></script>
@if(!empty($L('bootstrap_datepicker_locale')))<script src="{{ $U('/bower_components', true) }}/bootstrap-datepicker/dist/locales/bootstrap-datepicker.{{ $L('bootstrap_datepicker_locale') }}.min.js?v={{ $version }}"></script>@endif @if(!empty($L('bootstrap_datepicker_locale')))<script src="{{ $U('/node_modules', true) }}/bootstrap-datepicker/dist/locales/bootstrap-datepicker.{{ $L('bootstrap_datepicker_locale') }}.min.js?v={{ $version }}"></script>@endif
<script src="{{ $U('/node_modules/moment/min/moment.min.js?v=', true) }}{{ $version }}"></script> <script src="{{ $U('/node_modules/moment/min/moment.min.js?v=', true) }}{{ $version }}"></script>
@if(!empty($L('moment_locale')))<script src="{{ $U('/bower_components', true) }}/moment/locale/{{ $L('moment_locale') }}.js?v={{ $version }}"></script>@endif @if(!empty($L('moment_locale')))<script src="{{ $U('/node_modules', true) }}/moment/locale/{{ $L('moment_locale') }}.js?v={{ $version }}"></script>@endif
<script src="{{ $U('/node_modules/bootstrap-validator/dist/validator.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/node_modules/@danielfarrell/bootstrap-combobox/js/bootstrap-combobox.js?v=', true) }}{{ $version }}"></script> <script src="{{ $U('/node_modules/@danielfarrell/bootstrap-combobox/js/bootstrap-combobox.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/node_modules/datatables.net/js/jquery.dataTables.min.js?v=', true) }}{{ $version }}"></script> <script src="{{ $U('/node_modules/datatables.net/js/jquery.dataTables.min.js?v=', true) }}{{ $version }}"></script>
<script src="{{ $U('/node_modules/datatables.net-bs4/js/dataTables.bootstrap4.js?v=', true) }}{{ $version }}"></script> <script src="{{ $U('/node_modules/datatables.net-bs4/js/dataTables.bootstrap4.js?v=', true) }}{{ $version }}"></script>

View File

@ -19,12 +19,12 @@
<script>Grocy.EditObjectId = {{ $location->id }};</script> <script>Grocy.EditObjectId = {{ $location->id }};</script>
@endif @endif
<form id="location-form"> <form id="location-form" novalidate>
<div class="form-group"> <div class="form-group">
<label for="name">{{ $L('Name') }}</label> <label for="name">{{ $L('Name') }}</label>
<input type="text" class="form-control" required id="name" name="name" value="@if($mode == 'edit'){{ $location->name }}@endif"> <input type="text" class="form-control" required id="name" name="name" value="@if($mode == 'edit'){{ $location->name }}@endif">
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('A name is required') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -10,15 +10,15 @@
<h1> <h1>
@yield('title') @yield('title')
<a class="btn btn-outline-dark" href="{{ $U('/location/new') }}"> <a class="btn btn-outline-dark" href="{{ $U('/location/new') }}">
<i class="fa fa-plus"></i>&nbsp;{{ $L('Add') }} <i class="fas fa-plus"></i>&nbsp;{{ $L('Add') }}
</a> </a>
</h1> </h1>
</div> </div>
</div> </div>
<div class="row mt-3"> <div class="row mt-3">
<div class="col-3"> <div class="col-xs-12 col-md-6 col-xl-3">
<label for="search">{{ $L('Search') }}</label> <label for="search"><i class="fas fa-search"></i> {{ $L('Search') }}</label>
<input type="text" class="form-control" id="search"> <input type="text" class="form-control" id="search">
</div> </div>
</div> </div>
@ -38,10 +38,10 @@
<tr> <tr>
<td class="fit-content"> <td class="fit-content">
<a class="btn btn-info btn-sm" href="{{ $U('/location/') }}{{ $location->id }}"> <a class="btn btn-info btn-sm" href="{{ $U('/location/') }}{{ $location->id }}">
<i class="fa fa-pencil"></i> <i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-danger btn-sm location-delete-button" href="#" data-location-id="{{ $location->id }}" data-location-name="{{ $location->name }}"> <a class="btn btn-danger btn-sm location-delete-button" href="#" data-location-id="{{ $location->id }}" data-location-name="{{ $location->name }}">
<i class="fa fa-trash"></i> <i class="fas fa-trash"></i>
</a> </a>
</td> </td>
<td> <td>

View File

@ -8,7 +8,7 @@
<div class="col-lg-6 offset-lg-3 col-xs-12"> <div class="col-lg-6 offset-lg-3 col-xs-12">
<h1 class="text-center">@yield('title')</h1> <h1 class="text-center">@yield('title')</h1>
<form method="post" action="{{ $U('/login') }}" id="login-form"> <form method="post" action="{{ $U('/login') }}" id="login-form" novalidate>
<div class="form-group"> <div class="form-group">
<label for="name">{{ $L('Username') }}</label> <label for="name">{{ $L('Username') }}</label>
@ -19,7 +19,7 @@
<div class="form-group"> <div class="form-group">
<label for="name">{{ $L('Password') }}</label> <label for="name">{{ $L('Password') }}</label>
<input type="password" class="form-control" required id="password" name="password"> <input type="password" class="form-control" required id="password" name="password">
<div id="login-error" class="invalid-feedback"></div> <div id="login-error" class="form-text text-danger d-none"></div>
</div> </div>
<button id="login-button" type="submit" class="btn btn-success">{{ $L('OK') }}</button> <button id="login-button" type="submit" class="btn btn-success">{{ $L('OK') }}</button>

View File

@ -14,15 +14,15 @@
<h1> <h1>
@yield('title') @yield('title')
<a class="btn btn-outline-dark" href="{{ $U('/manageapikeys/new') }}"> <a class="btn btn-outline-dark" href="{{ $U('/manageapikeys/new') }}">
<i class="fa fa-plus"></i>&nbsp;{{ $L('Add') }} <i class="fas fa-plus"></i>&nbsp;{{ $L('Add') }}
</a> </a>
</h1> </h1>
</div> </div>
</div> </div>
<div class="row mt-3"> <div class="row mt-3">
<div class="col-3"> <div class="col-xs-12 col-md-6 col-xl-3">
<label for="search">{{ $L('Search') }}</label> <label for="search"><i class="fas fa-search"></i> {{ $L('Search') }}</label>
<input type="text" class="form-control" id="search"> <input type="text" class="form-control" id="search">
</div> </div>
</div> </div>
@ -44,7 +44,7 @@
<tr id="apiKeyRow_{{ $apiKey->id }}"> <tr id="apiKeyRow_{{ $apiKey->id }}">
<td class="fit-content"> <td class="fit-content">
<a class="btn btn-danger btn-sm apikey-delete-button" href="#" data-apikey-id="{{ $apiKey->id }}" data-apikey-apikey="{{ $apiKey->api_key }}"> <a class="btn btn-danger btn-sm apikey-delete-button" href="#" data-apikey-id="{{ $apiKey->id }}" data-apikey-apikey="{{ $apiKey->api_key }}">
<i class="fa fa-trash"></i> <i class="fas fa-trash"></i>
</a> </a>
</td> </td>
<td> <td>

View File

@ -19,12 +19,12 @@
<script>Grocy.EditObjectId = {{ $product->id }};</script> <script>Grocy.EditObjectId = {{ $product->id }};</script>
@endif @endif
<form id="product-form"> <form id="product-form" novalidate>
<div class="form-group"> <div class="form-group">
<label for="name">{{ $L('Name') }}</label> <label for="name">{{ $L('Name') }}</label>
<input type="text" class="form-control" required id="name" name="name" value="@if($mode == 'edit'){{ $product->name}}@endif"> <input type="text" class="form-control" required id="name" name="name" value="@if($mode == 'edit'){{ $product->name}}@endif">
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('A name is required') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -33,7 +33,7 @@
</div> </div>
<div class="form-group tm-group"> <div class="form-group tm-group">
<label for="barcode-taginput">{{ $L('Barcode(s)') }}&nbsp;&nbsp;<i class="fa fa-barcode"></i></label> <label for="barcode-taginput">{{ $L('Barcode(s)') }}&nbsp;&nbsp;<i class="fas fa-barcode"></i></label>
<input type="text" class="form-control tm-input" id="barcode-taginput"> <input type="text" class="form-control tm-input" id="barcode-taginput">
<div id="barcode-taginput-container"></div> <div id="barcode-taginput-container"></div>
</div> </div>
@ -45,19 +45,19 @@
<option @if($mode == 'edit' && $location->id == $product->location_id) selected="selected" @endif value="{{ $location->id }}">{{ $location->name }}</option> <option @if($mode == 'edit' && $location->id == $product->location_id) selected="selected" @endif value="{{ $location->id }}">{{ $location->name }}</option>
@endforeach @endforeach
</select> </select>
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('A location is required') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="min_stock_amount">{{ $L('Minimum stock amount') }}</label> <label for="min_stock_amount">{{ $L('Minimum stock amount') }}</label>
<input required min="0" type="number" class="form-control" id="min_stock_amount" name="min_stock_amount" value="@if($mode == 'edit'){{ $product->min_stock_amount }}@else{{0}}@endif"> <input required min="0" type="number" class="form-control" id="min_stock_amount" name="min_stock_amount" value="@if($mode == 'edit'){{ $product->min_stock_amount }}@else{{0}}@endif">
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('The amount cannot be lower than #1', '0') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="default_best_before_days">{{ $L('Default best before days') }}<br><span class="small text-muted">{{ $L('For purchases this amount of days will be added to today for the best before date suggestion') }}</span></label> <label for="default_best_before_days">{{ $L('Default best before days') }}<br><span class="small text-muted">{{ $L('For purchases this amount of days will be added to today for the best before date suggestion') }}</span></label>
<input required min="0" type="number" class="form-control" id="default_best_before_days" name="default_best_before_days" value="@if($mode == 'edit'){{ $product->default_best_before_days }}@else{{0}}@endif"> <input required min="0" type="number" class="form-control" id="default_best_before_days" name="default_best_before_days" value="@if($mode == 'edit'){{ $product->default_best_before_days }}@else{{0}}@endif">
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('This cannot be negative') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -67,7 +67,7 @@
<option @if($mode == 'edit' && $quantityunit->id == $product->qu_id_purchase) selected="selected" @endif value="{{ $quantityunit->id }}">{{ $quantityunit->name }}</option> <option @if($mode == 'edit' && $quantityunit->id == $product->qu_id_purchase) selected="selected" @endif value="{{ $quantityunit->id }}">{{ $quantityunit->name }}</option>
@endforeach @endforeach
</select> </select>
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('A quantity unit is required') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -77,16 +77,16 @@
<option @if($mode == 'edit' && $quantityunit->id == $product->qu_id_stock) selected="selected" @endif value="{{ $quantityunit->id }}">{{ $quantityunit->name }}</option> <option @if($mode == 'edit' && $quantityunit->id == $product->qu_id_stock) selected="selected" @endif value="{{ $quantityunit->id }}">{{ $quantityunit->name }}</option>
@endforeach @endforeach
</select> </select>
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('A quantity unit is required') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="qu_factor_purchase_to_stock">{{ $L('Factor purchase to stock quantity unit') }}</label> <label for="qu_factor_purchase_to_stock">{{ $L('Factor purchase to stock quantity unit') }}</label>
<input required min="1" type="number" class="form-control input-group-qu" id="qu_factor_purchase_to_stock" name="qu_factor_purchase_to_stock" value="@if ($mode == 'edit'){{ $product->qu_factor_purchase_to_stock }}@else{{1}}@endif"> <input required min="1" type="number" class="form-control input-group-qu" id="qu_factor_purchase_to_stock" name="qu_factor_purchase_to_stock" value="@if ($mode == 'edit'){{ $product->qu_factor_purchase_to_stock }}@else{{1}}@endif">
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('The amount cannot be lower than #1', '1') }}</div>
</div> </div>
<p id="qu-conversion-info" class="text-muted"></p> <p id="qu-conversion-info" class="form-text text-muted small d-none"></p>
<button id="save-product-button" type="submit" class="btn btn-success">{{ $L('Save') }}</button> <button id="save-product-button" type="submit" class="btn btn-success">{{ $L('Save') }}</button>
</form> </form>

View File

@ -10,15 +10,15 @@
<h1> <h1>
@yield('title') @yield('title')
<a class="btn btn-outline-dark" href="{{ $U('/product/new') }}"> <a class="btn btn-outline-dark" href="{{ $U('/product/new') }}">
<i class="fa fa-plus"></i>&nbsp;{{ $L('Add') }} <i class="fas fa-plus"></i>&nbsp;{{ $L('Add') }}
</a> </a>
</h1> </h1>
</div> </div>
</div> </div>
<div class="row mt-3"> <div class="row mt-3">
<div class="col-3"> <div class="col-xs-12 col-md-6 col-xl-3">
<label for="search">{{ $L('Search') }}</label> <label for="search"><i class="fas fa-search"></i> {{ $L('Search') }}</label>
<input type="text" class="form-control" id="search"> <input type="text" class="form-control" id="search">
</div> </div>
</div> </div>
@ -43,10 +43,10 @@
<tr> <tr>
<td class="fit-content"> <td class="fit-content">
<a class="btn btn-info btn-sm" href="{{ $U('/product/') }}{{ $product->id }}"> <a class="btn btn-info btn-sm" href="{{ $U('/product/') }}{{ $product->id }}">
<i class="fa fa-pencil"></i> <i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-danger btn-sm product-delete-button" href="#" data-product-id="{{ $product->id }}" data-product-name="{{ $product->name }}"> <a class="btn btn-danger btn-sm product-delete-button" href="#" data-product-id="{{ $product->id }}" data-product-name="{{ $product->name }}">
<i class="fa fa-trash"></i> <i class="fas fa-trash"></i>
</a> </a>
</td> </td>
<td> <td>

View File

@ -6,21 +6,21 @@
@section('content') @section('content')
<div class="row"> <div class="row">
<div class="col-lg-4 col-xs-12"> <div class="col-xs-12 col-md-6 col-xl-4">
<h1>@yield('title')</h1> <h1>@yield('title')</h1>
<form id="purchase-form"> <form id="purchase-form" novalidate>
<div class="form-group"> <div class="form-group">
<label for="product_id">{{ $L('Product') }}&nbsp;&nbsp;<i class="fa fa-barcode"></i><span id="barcode-lookup-disabled-hint" class="small text-muted d-none">&nbsp;&nbsp;Barcode lookup is disabled</span></label> <label for="product_id">{{ $L('Product') }}&nbsp;&nbsp;<i class="fas fa-barcode"></i><span id="barcode-lookup-disabled-hint" class="small text-muted d-none">&nbsp;&nbsp;Barcode lookup is disabled</span></label>
<select class="form-control combobox" id="product_id" name="product_id" required> <select class="form-control combobox" id="product_id" name="product_id" required>
<option value=""></option> <option value=""></option>
@foreach($products as $product) @foreach($products as $product)
<option data-additional-searchdata="{{ $product->barcode }}" value="{{ $product->id }}">{{ $product->name }}</option> <option data-additional-searchdata="{{ $product->barcode }}" value="{{ $product->id }}">{{ $product->name }}</option>
@endforeach @endforeach
</select> </select>
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('You have to select a product') }}</div>
<div id="flow-info-addbarcodetoselection" class="text-muted small d-none"><strong><span id="addbarcodetoselection"></span></strong> {{ $L('will be added to the list of barcodes for the selected product on submit') }}</div> <div id="flow-info-addbarcodetoselection" class="form-text text-muted small d-none"><strong><span id="addbarcodetoselection"></span></strong> {{ $L('will be added to the list of barcodes for the selected product on submit') }}</div>
</div> </div>
@include('components.datepicker', array( @include('components.datepicker', array(
@ -31,7 +31,7 @@
<div class="form-group"> <div class="form-group">
<label for="amount">{{ $L('Amount') }}&nbsp;&nbsp;<span id="amount_qu_unit" class="small text-muted"></span></label> <label for="amount">{{ $L('Amount') }}&nbsp;&nbsp;<span id="amount_qu_unit" class="small text-muted"></span></label>
<input type="number" class="form-control" id="amount" name="amount" value="1" min="1" required> <input type="number" class="form-control" id="amount" name="amount" value="1" min="1" required>
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('The amount cannot be lower than #1', '1') }}</div>
</div> </div>
<button id="save-purchase-button" type="submit" class="btn btn-success">{{ $L('OK') }}</button> <button id="save-purchase-button" type="submit" class="btn btn-success">{{ $L('OK') }}</button>
@ -39,7 +39,7 @@
</form> </form>
</div> </div>
<div class="col-lg-6 col-xs-12"> <div class="col-xs-12 col-md-6 col-xl-4">
@include('components.productcard') @include('components.productcard')
</div> </div>
</div> </div>

View File

@ -19,12 +19,12 @@
<script>Grocy.EditObjectId = {{ $quantityunit->id }};</script> <script>Grocy.EditObjectId = {{ $quantityunit->id }};</script>
@endif @endif
<form id="quantityunit-form"> <form id="quantityunit-form" novalidate>
<div class="form-group"> <div class="form-group">
<label for="name">{{ $L('Name') }}</label> <label for="name">{{ $L('Name') }}</label>
<input type="text" class="form-control" required id="name" name="name" value="@if($mode == 'edit'){{ $quantityunit->name }}@endif"> <input type="text" class="form-control" required id="name" name="name" value="@if($mode == 'edit'){{ $quantityunit->name }}@endif">
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('A name is required') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -10,15 +10,15 @@
<h1> <h1>
@yield('title') @yield('title')
<a class="btn btn-outline-dark" href="{{ $U('/quantityunit/new') }}"> <a class="btn btn-outline-dark" href="{{ $U('/quantityunit/new') }}">
<i class="fa fa-plus"></i>&nbsp;{{ $L('Add') }} <i class="fas fa-plus"></i>&nbsp;{{ $L('Add') }}
</a> </a>
</h1> </h1>
</div> </div>
</div> </div>
<div class="row mt-3"> <div class="row mt-3">
<div class="col-3"> <div class="col-xs-12 col-md-6 col-xl-3">
<label for="search">{{ $L('Search') }}</label> <label for="search"><i class="fas fa-search"></i> {{ $L('Search') }}</label>
<input type="text" class="form-control" id="search"> <input type="text" class="form-control" id="search">
</div> </div>
</div> </div>
@ -38,10 +38,10 @@
<tr> <tr>
<td class="fit-content"> <td class="fit-content">
<a class="btn btn-info btn-sm" href="{{ $U('/quantityunit/') }}{{ $quantityunit->id }}"> <a class="btn btn-info btn-sm" href="{{ $U('/quantityunit/') }}{{ $quantityunit->id }}">
<i class="fa fa-pencil"></i> <i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-danger btn-sm quantityunit-delete-button" href="#" data-quantityunit-id="{{ $quantityunit->id }}" data-quantityunit-name="{{ $quantityunit->name }}"> <a class="btn btn-danger btn-sm quantityunit-delete-button" href="#" data-quantityunit-id="{{ $quantityunit->id }}" data-quantityunit-name="{{ $quantityunit->name }}">
<i class="fa fa-trash"></i> <i class="fas fa-trash"></i>
</a> </a>
</td> </td>
<td> <td>

View File

@ -10,18 +10,18 @@
<h1> <h1>
@yield('title') @yield('title')
<a class="btn btn-outline-dark" href="{{ $U('/shoppinglistitem/new') }}"> <a class="btn btn-outline-dark" href="{{ $U('/shoppinglistitem/new') }}">
<i class="fa fa-plus"></i>&nbsp;{{ $L('Add') }} <i class="fas fa-plus"></i>&nbsp;{{ $L('Add') }}
</a> </a>
<a id="add-products-below-min-stock-amount" class="btn btn-info" href="#"> <a id="add-products-below-min-stock-amount" class="btn btn-info" href="#">
<i class="fa fa-plus"></i>&nbsp;{{ $L('Add products that are below defined min. stock amount') }} <i class="fas fa-plus"></i>&nbsp;{{ $L('Add products that are below defined min. stock amount') }}
</a> </a>
</h1> </h1>
</div> </div>
</div> </div>
<div class="row mt-3"> <div class="row mt-3">
<div class="col-3"> <div class="col-xs-12 col-md-6 col-xl-3">
<label for="search">{{ $L('Search') }}</label> <label for="search"><i class="fas fa-search"></i> {{ $L('Search') }}</label>
<input type="text" class="form-control" id="search"> <input type="text" class="form-control" id="search">
</div> </div>
</div> </div>
@ -40,11 +40,11 @@
@foreach($listItems as $listItem) @foreach($listItems as $listItem)
<tr class="@if($listItem->amount_autoadded > 0) table-info @endif"> <tr class="@if($listItem->amount_autoadded > 0) table-info @endif">
<td class="fit-content"> <td class="fit-content">
<a class="btn btn-info" href="{{ $U('/shoppinglistitem/') }}{{ $listItem->id }}"> <a class="btn btn-sm btn-info" href="{{ $U('/shoppinglistitem/') }}{{ $listItem->id }}">
<i class="fa fa-pencil"></i> <i class="fas fa-edit"></i>
</a> </a>
<a class="btn btn-danger shoppinglist-delete-button" href="#" data-shoppinglist-id="{{ $listItem->id }}"> <a class="btn btn-sm btn-danger shoppinglist-delete-button" href="#" data-shoppinglist-id="{{ $listItem->id }}">
<i class="fa fa-trash"></i> <i class="fas fa-trash"></i>
</a> </a>
</td> </td>
<td> <td>

View File

@ -10,7 +10,7 @@
@section('content') @section('content')
<div class="row"> <div class="row">
<div class="col-lg-4 col-xs-12"> <div class="col-xs-12 col-md-6 col-xl-4">
<h1>@yield('title')</h1> <h1>@yield('title')</h1>
<script>Grocy.EditMode = '{{ $mode }}';</script> <script>Grocy.EditMode = '{{ $mode }}';</script>
@ -19,23 +19,22 @@
<script>Grocy.EditObjectId = {{ $listItem->id }};</script> <script>Grocy.EditObjectId = {{ $listItem->id }};</script>
@endif @endif
<form id="shoppinglist-form"> <form id="shoppinglist-form" novalidate>
<div class="form-group"> <div class="form-group">
<label for="product_id">{{ $L('Product') }}&nbsp;&nbsp;<i class="fa fa-barcode"></i></label> <label for="product_id">{{ $L('Product') }}&nbsp;&nbsp;<i class="fas fa-barcode"></i></label>
<select class="form-control combobox" id="product_id" name="product_id" value="@if($mode == 'edit') {{ $listItem->product_id }} @endif"> <select class="form-control combobox" id="product_id" name="product_id" value="@if($mode == 'edit') {{ $listItem->product_id }} @endif">
<option value=""></option> <option value=""></option>
@foreach($products as $product) @foreach($products as $product)
<option @if($mode == 'edit' && $product->id == $listItem->product_id) selected="selected" @endif data-additional-searchdata="{{ $product->barcode }}" value="{{ $product->id }}">{{ $product->name }}</option> <option @if($mode == 'edit' && $product->id == $listItem->product_id) selected="selected" @endif data-additional-searchdata="{{ $product->barcode }}" value="{{ $product->id }}">{{ $product->name }}</option>
@endforeach @endforeach
</select> </select>
<div id="product-error" class="invalid-feedback"></div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="amount">{{ $L('Amount') }}&nbsp;&nbsp;<span id="amount_qu_unit" class="small text-muted"></span><br><span class="small text-warning">@if($mode == 'edit' && $listItem->amount_autoadded > 0){{ $L('#1 units were automatically added and will apply in addition to the amount entered here', $listItem->amount_autoadded) }}@endif</span></label> <label for="amount">{{ $L('Amount') }}&nbsp;&nbsp;<span id="amount_qu_unit" class="small text-muted"></span><br><span class="small text-warning">@if($mode == 'edit' && $listItem->amount_autoadded > 0){{ $L('#1 units were automatically added and will apply in addition to the amount entered here', $listItem->amount_autoadded) }}@endif</span></label>
<input type="number" class="form-control" id="amount" name="amount" value="@if($mode == 'edit'){{ $listItem->amount }}@else{{1}}@endif" min="0" required> <input type="number" class="form-control" id="amount" name="amount" value="@if($mode == 'edit'){{ $listItem->amount }}@else{{1}}@endif" min="0" required>
<div class="invalid-feedback"></div> <div class="invalid-feedback">{{ $L('This cannot be negative') }}</div>
</div> </div>
<div class="form-group"> <div class="form-group">
@ -48,7 +47,7 @@
</form> </form>
</div> </div>
<div class="col-lg-4 col-xs-12"> <div class="col-xs-12 col-md-6 col-xl-4">
@include('components.productcard') @include('components.productcard')
</div> </div>
</div> </div>

View File

@ -19,8 +19,8 @@
</div> </div>
<div class="row mt-3"> <div class="row mt-3">
<div class="col-3"> <div class="col-xs-12 col-md-6 col-xl-3">
<label for="location-filter">{{ $L('Filter by location') }}</label> <label for="location-filter"><i class="fas fa-filter"></i> {{ $L('Filter by location') }}</label>
<select class="form-control" id="location-filter"> <select class="form-control" id="location-filter">
<option value="all">{{ $L('All') }}</option> <option value="all">{{ $L('All') }}</option>
@foreach($locations as $location) @foreach($locations as $location)
@ -28,8 +28,8 @@
@endforeach @endforeach
</select> </select>
</div> </div>
<div class="col-3"> <div class="col-xs-12 col-md-6 col-xl-3">
<label for="search">{{ $L('Search') }}</label> <label for="search"><i class="fas fa-search"></i> {{ $L('Search') }}</label>
<input type="text" class="form-control" id="search"> <input type="text" class="form-control" id="search">
</div> </div>
</div> </div>
@ -55,14 +55,14 @@
data-product-name="{{ FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name }}" data-product-name="{{ FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name }}"
data-product-qu-name="{{ FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name }}" data-product-qu-name="{{ FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name }}"
data-consume-amount="1"> data-consume-amount="1">
<i class="fa fa-cutlery"></i> 1 <i class="fas fa-utensils"></i> 1
</a> </a>
<a id="product-{{ $currentStockEntry->product_id }}-consume-all-button" class="btn btn-danger btn-sm product-consume-button" href="#" title="{{ $L('Consume all #1 which are currently in stock', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name) }}" <a id="product-{{ $currentStockEntry->product_id }}-consume-all-button" class="btn btn-danger btn-sm product-consume-button" href="#" title="{{ $L('Consume all #1 which are currently in stock', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name) }}"
data-product-id="{{ $currentStockEntry->product_id }}" data-product-id="{{ $currentStockEntry->product_id }}"
data-product-name="{{ FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name }}" data-product-name="{{ FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->name }}"
data-product-qu-name="{{ FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name }}" data-product-qu-name="{{ FindObjectInArrayByPropertyValue($quantityunits, 'id', FindObjectInArrayByPropertyValue($products, 'id', $currentStockEntry->product_id)->qu_id_stock)->name }}"
data-consume-amount="{{ $currentStockEntry->amount }}"> data-consume-amount="{{ $currentStockEntry->amount }}">
<i class="fa fa-cutlery"></i> {{ $L('All') }} <i class="fas fa-utensils"></i> {{ $L('All') }}
</a> </a>
</td> </td>
<td> <td>

View File

@ -6,6 +6,16 @@
version "1.1.8" version "1.1.8"
resolved "https://github.com/pallidus-fintech/bootstrap-combobox.git#0bd1da781b99d390f1c75315b6025e7d8658b263" resolved "https://github.com/pallidus-fintech/bootstrap-combobox.git#0bd1da781b99d390f1c75315b6025e7d8658b263"
"@fortawesome/fontawesome-free@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.1.0.tgz#f35f5ba91366b7a58b0b6a4f22ff0907fe002219"
"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"
resolved "https://github.com/max-favilli/tagmanager.git#df9eb9935c8585a392dfc00602f890caf233fa94"
dependencies:
jquery "1"
"bootbox@https://github.com/makeusabrew/bootbox.git#v5.x": "bootbox@https://github.com/makeusabrew/bootbox.git#v5.x":
version "5.0.0" version "5.0.0"
resolved "https://github.com/makeusabrew/bootbox.git#8d843602d6ba7a2367829e01feee399d5f0a3a07" resolved "https://github.com/makeusabrew/bootbox.git#8d843602d6ba7a2367829e01feee399d5f0a3a07"
@ -20,10 +30,6 @@ bootstrap-datepicker@^1.8.0:
version "0.0.0" version "0.0.0"
resolved "https://github.com/samrayner/bootstrap-side-navbar.git#bda4883fd2b278df3a48db4add7dc4d994477734" resolved "https://github.com/samrayner/bootstrap-side-navbar.git#bda4883fd2b278df3a48db4add7dc4d994477734"
bootstrap-validator@^0.11.9:
version "0.11.9"
resolved "https://registry.yarnpkg.com/bootstrap-validator/-/bootstrap-validator-0.11.9.tgz#fb7058eef53623e78f5aa7967026f98f875a9404"
bootstrap@4.0.0: bootstrap@4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.0.0.tgz#ceb03842c145fcc1b9b4e15da2a05656ba68469a" resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.0.0.tgz#ceb03842c145fcc1b9b4e15da2a05656ba68469a"
@ -101,7 +107,7 @@ datatables.net@1.10.19, datatables.net@^1.10.15, datatables.net@^1.10.19:
dependencies: dependencies:
jquery ">=1.7" jquery ">=1.7"
font-awesome@4.7.0, font-awesome@^4.7.0: font-awesome@4.7.0:
version "4.7.0" version "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"
@ -131,7 +137,7 @@ moment-timezone@^0.5.11:
dependencies: dependencies:
moment ">= 2.9.0" moment ">= 2.9.0"
"moment@>= 2.9.0", moment@^2.18.1, moment@^2.22.2: "moment@>= 2.9.0", 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"
@ -154,16 +160,10 @@ startbootstrap-sb-admin@^4.0.0:
jquery "3.3.1" jquery "3.3.1"
jquery.easing "^1.4.1" jquery.easing "^1.4.1"
swagger-ui-dist@^3.13.4: swagger-ui-dist@^3.17.3:
version "3.17.3" version "3.17.3"
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-3.17.3.tgz#dfb96408ccc46775155f7369190c5d4b2016fe5c" resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-3.17.3.tgz#dfb96408ccc46775155f7369190c5d4b2016fe5c"
"tagmanager@https://github.com/max-favilli/tagmanager.git#3.0.2":
version "3.0.1"
resolved "https://github.com/max-favilli/tagmanager.git#df9eb9935c8585a392dfc00602f890caf233fa94"
dependencies:
jquery "1"
tempusdominus-bootstrap-4@^5.0.1: tempusdominus-bootstrap-4@^5.0.1:
version "5.0.1" version "5.0.1"
resolved "https://registry.yarnpkg.com/tempusdominus-bootstrap-4/-/tempusdominus-bootstrap-4-5.0.1.tgz#713d5d1547caf7784e510e480e32997ccbe7e511" resolved "https://registry.yarnpkg.com/tempusdominus-bootstrap-4/-/tempusdominus-bootstrap-4-5.0.1.tgz#713d5d1547caf7784e510e480e32997ccbe7e511"
@ -174,13 +174,13 @@ tempusdominus-bootstrap-4@^5.0.1:
moment-timezone "^0.5.11" moment-timezone "^0.5.11"
popper.js "^1.12.9" popper.js "^1.12.9"
timeago@^1.6.1: timeago@^1.6.3:
version "1.6.3" version "1.6.3"
resolved "https://registry.yarnpkg.com/timeago/-/timeago-1.6.3.tgz#162a1adae99356297df59339837d09f1b0f36465" resolved "https://registry.yarnpkg.com/timeago/-/timeago-1.6.3.tgz#162a1adae99356297df59339837d09f1b0f36465"
dependencies: dependencies:
jquery ">=1.2.3" jquery ">=1.2.3"
toastr@^2.1.3: toastr@^2.1.4:
version "2.1.4" version "2.1.4"
resolved "https://registry.yarnpkg.com/toastr/-/toastr-2.1.4.tgz#8b43be64fb9d0c414871446f2db8e8ca4e95f181" resolved "https://registry.yarnpkg.com/toastr/-/toastr-2.1.4.tgz#8b43be64fb9d0c414871446f2db8e8ca4e95f181"
dependencies: dependencies: