diff --git a/config-dist.php b/config-dist.php index 58ea7b6f..1eed9b62 100644 --- a/config-dist.php +++ b/config-dist.php @@ -1,4 +1,7 @@ view->set('version', $applicationService->GetInstalledVersion()); + + $localizationService = new LocalizationService(CULTURE); + $container->view->set('localizationStrings', $localizationService->GetCurrentCultureLocalizations()); + $container->view->set('L', function($text, ...$placeholderValues) use($localizationService) + { + return $localizationService->Localize($text, ...$placeholderValues); + }); } protected $AppContainer; diff --git a/localization/de.php b/localization/de.php new file mode 100644 index 00000000..e4da8043 --- /dev/null +++ b/localization/de.php @@ -0,0 +1,135 @@ + 'Bestand', + '#1 products with #2 units in stock' => '#1 Produkte (#2 Einheiten) vorrätig', + '#1 products expiring within the next #2 days' => '#1 Produkte laufen innerhalb der nächsten #2 Tage ab', + '#1 products are already expired' => '#1 Produkte sind bereits abgelaufen', + '#1 products are below defined min. stock amount' => '#1 Produkte sind unter Mindestbestand', + 'Product' => 'Produkt', + 'Amount' => 'Menge', + 'Next best before date' => 'Nächstes MHD', + 'Logout' => 'Abmelden', + 'Habits overview' => 'Gewohnheiten', + 'Batteries overview' => 'Batterien', + 'Purchase' => 'Einkauf', + 'Consume' => 'Verbrauch', + 'Inventory' => 'Inventur', + 'Shopping list' => 'Einkaufszettel', + 'Habit tracking' => 'Gewohnheit-Ausführung', + 'Battery tracking' => 'Batterie-Ladzyklus', + 'Products' => 'Produkte', + 'Locations' => 'Standorte', + 'Quantity units' => 'Mengeneinheiten', + 'Habits' => 'Gewohnheiten', + 'Batteries' => 'Batterien', + 'Habit' => 'Gewohnheit', + 'Next estimated tracking' => 'Nächste geplante Ausführung', + 'Last tracked' => 'Zuletzt ausgeführt', + 'Battery' => 'Batterie', + 'Last charged' => 'Zuletzt geladen', + 'Next planned charge cycle' => 'Nächster geplanter Ladezyklus', + 'Best before' => 'MHD', + 'OK' => 'OK', + 'Product overview' => 'Produktübersicht', + 'Stock quantity unit' => 'Mengeneinheit Bestand', + 'Stock amount' => 'Bestand', + 'Last purchased' => 'Zuletzt gekauft', + 'Last used' => 'Zuletzt benutzt', + 'Spoiled' => 'Verdorben', + 'Barcode lookup is disabled' => 'Barcode-Suche ist deaktiviert', + 'will be added to the list of barcodes for the selected product on submit' => 'wird der Liste der Barcodes für das ausgewählte Produkt beim Speichern hinzugefügt', + 'New amount' => 'Neue Menge', + 'Note' => 'Notiz', + 'Tracked time' => 'Ausführungszeit', + 'Habit overview' => 'Gewohnheit Übersicht', + 'Tracked count' => 'Ausführungsanzahl', + 'Battery overview' => 'Batterie Übersicht', + 'Charge cycles count' => 'Ladezyklen', + 'Create shopping list item' => 'Einkaufszettel Eintrag erstellen', + 'Edit shopping list item' => 'Einkaufszettel Eintrag bearbeiten', + '#1 units were automatically added and will apply in addition to the amount entered here' => '#1 Einheiten wurden automatisch hinzugefügt und gelten zusätzlich der hier eingegebenen Menge', + 'Save' => 'Speichern', + 'Add' => 'Hinzufügen', + 'Name' => 'Name', + 'Location' => 'Standort', + 'Min. stock amount' => 'Mindestbestand', + 'QU purchase' => 'ME Einkauf', + 'QU stock' => 'ME Bestand', + 'QU factor' => 'ME-Faktor', + 'Description' => 'Beschreibung', + 'Create product' => 'Produkt erstellen', + 'Barcode(s)' => 'Barcode(s)', + 'Minimum stock amount' => 'Mindestbestand', + 'Default best before days' => 'Standard Haltbarkeit in Tagen', + 'Quantity unit purchase' => 'Mengeneinheit Einkauf', + 'Quantity unit stock' => 'Mengeneinheit Bestand', + 'Factor purchase to stock quantity unit' => 'Faktor Mengeneinheit Einkauf zu Mengeneinheit Bestand', + 'Create location' => 'Standort erstellen', + 'Create quantity unit' => 'Mengeneinheit erstellen', + 'Period type' => 'Periodentyp', + 'Period days' => 'Tage/Periode', + 'Create habit' => 'Gewohnheit erstellen', + 'Used in' => 'Benutzt in', + 'Create battery' => 'Batterie erstellen', + 'Edit battery' => 'Batterie bearbeiten', + 'Edit habit' => 'Gewohnheit bearbeiten', + 'Edit quantity unit' => 'Mengeneinheit bearbeiten', + 'Edit product' => 'Produkt bearbeiten', + 'Edit location' => 'Standort bearbeiten', + 'Record data' => 'Daten erfassen', + 'Manage master data' => 'Stammdaten verwalten', + 'This will apply to added products' => 'Dies gilt für hinzugefügte Produkte', + 'never' => 'nie', + 'Add products that are below defined min. stock amount' => 'Produkte unter Mindestbestand hinzufügen', + 'For purchases this amount of days will be added to today for the best before date suggestion' => 'Bei Einkäufen wird hierauf basierend das MHD vorausgefüllt', + 'This means 1 #1 purchased will be converted into #2 #3 in stock' => 'Das bedeutet 1 #1 im Einkauf entsprechen #2 #3 im Bestand', + 'Login' => 'Anmelden', + 'Username' => 'Benutzername', + 'Password' => 'Passwort', + 'Invalid credentials, please try again' => 'Ungültige Zugangsdaten, bitte versuche es erneut', + + //Constants + 'manually' => 'Manuell', + 'dynamic-regular' => 'Dynamisch regelmäßig', + + //Technical component translations + 'timeago_locale' => 'de', + 'timeago_nan' => 'vor NaN Jahren', + 'moment_locale' => 'de', + 'bootstrap_datepicker_locale' => 'de', + 'datatables_localization' => '{"sEmptyTable":"Keine Daten in der Tabelle vorhanden","sInfo":"_START_ bis _END_ von _TOTAL_ Einträgen","sInfoEmpty":"Keine Daten vorhanden","sInfoFiltered":"(gefiltert von _MAX_ Einträgen)","sInfoPostFix":"","sInfoThousands":".","sLengthMenu":"_MENU_ Einträge anzeigen","sLoadingRecords":"Wird geladen ..","sProcessing":"Bitte warten ..","sSearch":"Suchen","sZeroRecords":"Keine Einträge vorhanden","oPaginate":{"sFirst":"Erste","sPrevious":"Zurück","sNext":"Nächste","sLast":"Letzte"},"oAria":{"sSortAscending":": aktivieren, um Spalte aufsteigend zu sortieren","sSortDescending":": aktivieren, um Spalte absteigend zu sortieren"},"select":{"rows":{"0":"Zum Auswählen auf eine Zeile klicken","1":"1 Zeile ausgewählt","_":"%d Zeilen ausgewählt"}},"buttons":{"print":"Drucken","colvis":"Spalten","copy":"Kopieren","copyTitle":"In Zwischenablage kopieren","copyKeys":"Taste ctrl oder + C um Tabelle
in Zwischenspeicher zu kopieren.

Um abzubrechen die Nachricht anklicken oder Escape drücken.","copySuccess":{"1":"1 Spalte kopiert","_":"%d Spalten kopiert"}}}', + + //Demo data + 'Cookies' => 'Cookies', + 'Chocolate' => 'Schokolade', + 'Pantry' => 'Vorratskammer', + 'Candy cupboard' => 'Süßigkeitenschrank', + 'Tinned food cupboard' => 'Konservenschrank', + 'Fridge' => 'Kühlschrank', + 'Piece' => 'Stück', + 'Pack' => 'Packung', + 'Glass' => 'Glas', + 'Tin' => 'Dose', + 'Can' => 'Becher', + 'Bunch' => 'Bund', + 'Gummy bears' => 'Gummibärchen', + 'Crisps' => 'Chips', + 'Eggs' => 'Eier', + 'Noodles' => 'Nudeln', + 'Pickles' => 'Essiggurken', + 'Gulash soup' => 'Gulaschsuppe', + 'Yogurt' => 'Joghurt', + 'Cheese' => 'Käse', + 'Cold cuts' => 'Aufschnitt', + 'Paprika' => 'Paprika', + 'Cucumber' => 'Gurke', + 'Radish' => 'Radieschen', + 'Tomato' => 'Tomaten', + 'Changed towels in the bathroom' => 'Handtücher im Bad gewechselt', + 'Cleaned the kitchen floor' => 'Küchenboden gewischt', + 'Warranty ends' => 'Garantie endet', + 'TV remote control' => 'TV Fernbedienung', + 'Alarm clock' => 'Wecker', + 'Heat remote control' => 'Fernbedienung Heizung' +); diff --git a/localization/en.php b/localization/en.php new file mode 100644 index 00000000..36516dd8 --- /dev/null +++ b/localization/en.php @@ -0,0 +1,14 @@ + 'Manually', + 'dynamic-regular' => 'Dynamic regular', + + //Technical component translations + 'timeago_locale' => 'en', + 'timeago_nan' => 'NaN years ago', + 'moment_locale' => '', + 'bootstrap_datepicker_locale' => '', + 'datatables_localization' => '{"sEmptyTable":"No data available in table","sInfo":"Showing _START_ to _END_ of _TOTAL_ entries","sInfoEmpty":"Showing 0 to 0 of 0 entries","sInfoFiltered":"(filtered from _MAX_ total entries)","sInfoPostFix":"","sInfoThousands":",","sLengthMenu":"Show _MENU_ entries","sLoadingRecords":"Loading...","sProcessing":"Processing...","sSearch":"Search:","sZeroRecords":"No matching records found","oPaginate":{"sFirst":"First","sLast":"Last","sNext":"Next","sPrevious":"Previous"},"oAria":{"sSortAscending":": activate to sort column ascending","sSortDescending":": activate to sort column descending"}}' +); diff --git a/migrations/0021.sql b/migrations/0021.sql new file mode 100644 index 00000000..ee52c94a --- /dev/null +++ b/migrations/0021.sql @@ -0,0 +1,11 @@ +DELETE FROM locations +WHERE name = 'DefaultLocation'; + +DELETE FROM quantity_units +WHERE name = 'DefaultQuantityUnit'; + +DELETE FROM products +WHERE name = 'DefaultProduct1'; + +DELETE FROM products +WHERE name = 'DefaultProduct2'; diff --git a/public/css/grocy.css b/public/css/grocy.css index 590a6f6d..b2c2fc1a 100644 --- a/public/css/grocy.css +++ b/public/css/grocy.css @@ -46,12 +46,12 @@ } .nav-sidebar > li > a:hover { - box-shadow: inset 4px 0 0 #337ab7; + box-shadow: inset 5px 0 0 #337ab7; transition: all 0.3s; } .nav-sidebar > li > a:focus { - box-shadow: inset 4px 0 0 #ab2230; + box-shadow: inset 5px 0 0 #ab2230; transition: all 0.3s; } @@ -59,7 +59,7 @@ .nav-sidebar > .active > a:hover, .nav-sidebar > .active > a:focus { background-color: #d6d6d6; - box-shadow: inset 4px 0 0 #ab2230; + box-shadow: inset 5px 0 0 #ab2230; transition: all 0.3s; } @@ -114,7 +114,9 @@ a.discrete-link:focus { font-weight: bold; letter-spacing: -5px; font-size: 2.2em; - color: inherit !important; + color: #0b024c !important; + margin-left: 0 !important; + padding-left: 5px !important; } diff --git a/public/img/grocy.png b/public/img/grocy.png index 37cc0608..b1e6c121 100644 Binary files a/public/img/grocy.png and b/public/img/grocy.png differ diff --git a/public/js/grocy.js b/public/js/grocy.js index 54afd320..5869d700 100644 --- a/public/js/grocy.js +++ b/public/js/grocy.js @@ -1,17 +1,27 @@ -var Grocy = { }; -Grocy.Components = { }; - -$(function() +L = function(text, ...placeholderValues) { - if (!Grocy.ActiveNav.isEmpty()) + var localizedText = Grocy.LocalizationStrings[text]; + if (localizedText === undefined) { - var menuItem = $('.nav').find("[data-nav-for-page='" + Grocy.ActiveNav + "']"); - menuItem.addClass('active'); - } + localizedText = text; + } + + for (var i = 0; i < placeholderValues.length; i++) + { + localizedText = localizedText.replace('#' + (i + 1), placeholderValues[i]); + } + + return localizedText; +} - $.timeago.settings.allowFuture = true; - $('time.timeago').timeago(); -}); +if (!Grocy.ActiveNav.isEmpty()) +{ + var menuItem = $('.nav').find("[data-nav-for-page='" + Grocy.ActiveNav + "']"); + menuItem.addClass('active'); +} + +$.timeago.settings.allowFuture = true; +$('time.timeago').timeago(); Grocy.FetchJson = function(url, success, error) { diff --git a/public/viewjs/batteries.js b/public/viewjs/batteries.js index 2350f98a..51f39bc9 100644 --- a/public/viewjs/batteries.js +++ b/public/viewjs/batteries.js @@ -31,13 +31,11 @@ }); }); -$(function() -{ - $('#batteries-table').DataTable({ - 'pageLength': 50, - 'order': [[1, 'asc']], - 'columnDefs': [ - { 'orderable': false, 'targets': 0 } - ] - }); +$('#batteries-table').DataTable({ + 'pageLength': 50, + 'order': [[1, 'asc']], + 'columnDefs': [ + { 'orderable': false, 'targets': 0 } + ], + 'language': JSON.parse(L('datatables_localization')) }); diff --git a/public/viewjs/batteriesoverview.js b/public/viewjs/batteriesoverview.js index e1a32725..d1f63bad 100644 --- a/public/viewjs/batteriesoverview.js +++ b/public/viewjs/batteriesoverview.js @@ -1,7 +1,5 @@ -$(function() -{ - $('#batteries-overview-table').DataTable({ - 'pageLength': 50, - 'order': [[1, 'desc']] - }); +$('#batteries-overview-table').DataTable({ + 'pageLength': 50, + 'order': [[1, 'desc']], + 'language': JSON.parse(L('datatables_localization')) }); diff --git a/public/viewjs/batteryform.js b/public/viewjs/batteryform.js index 8b3b8d8f..8b90d287 100644 --- a/public/viewjs/batteryform.js +++ b/public/viewjs/batteryform.js @@ -30,9 +30,6 @@ } }); -$(function() -{ - $('#name').focus(); - $('#battery-form').validator(); - $('#battery-form').validator('validate'); -}); +$('#name').focus(); +$('#battery-form').validator(); +$('#battery-form').validator('validate'); diff --git a/public/viewjs/batterytracking.js b/public/viewjs/batterytracking.js index b86a919c..6bbf2f6c 100644 --- a/public/viewjs/batterytracking.js +++ b/public/viewjs/batterytracking.js @@ -44,50 +44,47 @@ $('#battery_id').on('change', function(e) } }); -$(function() +$('.datetimepicker').datetimepicker( { - $('.datetimepicker').datetimepicker( - { - format: 'YYYY-MM-DD HH:mm:ss', - showTodayButton: true, - calendarWeeks: true, - maxDate: moment() - }); + 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').val(moment().format('YYYY-MM-DD HH:mm:ss')); +$('#tracked_time').trigger('change'); - $('#tracked_time').on('focus', function(e) +$('#tracked_time').on('focus', function(e) +{ + if ($('#battery_id_text_input').val().length === 0) { - if ($('#battery_id_text_input').val().length === 0) + $('#battery_id_text_input').focus(); + } +}); + +$('.combobox').combobox({ + appendId: '_text_input' +}); + +$('#battery_id').val(''); +$('#battery_id_text_input').focus(); +$('#battery_id_text_input').val(''); +$('#battery_id_text_input').trigger('change'); + +$('#batterytracking-form').validator(); +$('#batterytracking-form').validator('validate'); + +$('#batterytracking-form input').keydown(function(event) +{ + if (event.keyCode === 13) //Enter + { + if ($('#batterytracking-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error { - $('#battery_id_text_input').focus(); + event.preventDefault(); + return false; } - }); - - $('.combobox').combobox({ - appendId: '_text_input' - }); - - $('#battery_id').val(''); - $('#battery_id_text_input').focus(); - $('#battery_id_text_input').val(''); - $('#battery_id_text_input').trigger('change'); - - $('#batterytracking-form').validator(); - $('#batterytracking-form').validator('validate'); - - $('#batterytracking-form input').keydown(function(event) - { - if (event.keyCode === 13) //Enter - { - if ($('#batterytracking-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error - { - event.preventDefault(); - return false; - } - } - }); + } }); $('#tracked_time').on('change', function(e) diff --git a/public/viewjs/components/batterycard.js b/public/viewjs/components/batterycard.js index 267cd9ba..9a44ed38 100644 --- a/public/viewjs/components/batterycard.js +++ b/public/viewjs/components/batterycard.js @@ -6,11 +6,12 @@ Grocy.Components.BatteryCard.Refresh = function(batteryId) function(batteryDetails) { $('#batterycard-battery-name').text(batteryDetails.battery.name); + $('#batterycard-battery-used_in').text(batteryDetails.battery.used_in); $('#batterycard-battery-last-charged').text((batteryDetails.last_charged || 'never')); $('#batterycard-battery-last-charged-timeago').text($.timeago(batteryDetails.last_charged || '')); $('#batterycard-battery-charge-cycles-count').text((batteryDetails.charge_cycles_count || '0')); - EmptyElementWhenMatches('#batterycard-battery-last-charged-timeago', 'NaN years ago'); + EmptyElementWhenMatches('#batterycard-battery-last-charged-timeago', L('timeago_nan')); }, function(xhr) { diff --git a/public/viewjs/components/datepicker.js b/public/viewjs/components/datepicker.js index 0b62cf66..24fafe2f 100644 --- a/public/viewjs/components/datepicker.js +++ b/public/viewjs/components/datepicker.js @@ -9,11 +9,12 @@ $(function() calendarWeeks: true, orientation: 'bottom auto', weekStart: 1, - showOnFocus: false + showOnFocus: false, + language: L('bootstrap_datepicker_locale') }); $('.datepicker').trigger('change'); - EmptyElementWhenMatches('#datepicker-timeago', 'NaN years ago'); + EmptyElementWhenMatches('#datepicker-timeago', L('timeago_nan')); }); $('.datepicker').on('keydown', function(e) @@ -82,7 +83,7 @@ $('.datepicker').on('change', function(e) } $('#datepicker-timeago').text($.timeago($('.datepicker').val())); - EmptyElementWhenMatches('#datepicker-timeago', 'NaN years ago'); + EmptyElementWhenMatches('#datepicker-timeago', L('timeago_nan')); }); $('#datepicker-button').on('click', function(e) diff --git a/public/viewjs/components/datetimepicker.js b/public/viewjs/components/datetimepicker.js index 303dc964..5a6ab3b0 100644 --- a/public/viewjs/components/datetimepicker.js +++ b/public/viewjs/components/datetimepicker.js @@ -5,6 +5,7 @@ $(function() format: 'YYYY-MM-DD HH:mm:ss', showTodayButton: true, calendarWeeks: true, - maxDate: moment() + maxDate: moment(), + locale: moment.locale('de') }); }); diff --git a/public/viewjs/components/habitcard.js b/public/viewjs/components/habitcard.js index 350c5c2f..9a4fac6b 100644 --- a/public/viewjs/components/habitcard.js +++ b/public/viewjs/components/habitcard.js @@ -10,7 +10,7 @@ Grocy.Components.HabitCard.Refresh = function (habitId) $('#habitcard-habit-last-tracked-timeago').text($.timeago(habitDetails.last_tracked || '')); $('#habitcard-habit-tracked-count').text((habitDetails.tracked_count || '0')); - EmptyElementWhenMatches('#habitcard-habit-last-tracked-timeago', 'NaN years ago'); + EmptyElementWhenMatches('#habitcard-habit-last-tracked-timeago', L('timeago_nan')); }, function(xhr) { diff --git a/public/viewjs/components/productcard.js b/public/viewjs/components/productcard.js index b49be651..bfa54fb9 100644 --- a/public/viewjs/components/productcard.js +++ b/public/viewjs/components/productcard.js @@ -9,13 +9,13 @@ Grocy.Components.ProductCard.Refresh = function(productId) $('#productcard-product-stock-amount').text(productDetails.stock_amount || '0'); $('#productcard-product-stock-qu-name').text(productDetails.quantity_unit_stock.name); $('#productcard-product-stock-qu-name2').text(productDetails.quantity_unit_stock.name); - $('#productcard-product-last-purchased').text((productDetails.last_purchased || 'never').substring(0, 10)); + $('#productcard-product-last-purchased').text((productDetails.last_purchased || L('never')).substring(0, 10)); $('#productcard-product-last-purchased-timeago').text($.timeago(productDetails.last_purchased || '')); - $('#productcard-product-last-used').text((productDetails.last_used || 'never').substring(0, 10)); + $('#productcard-product-last-used').text((productDetails.last_used || L('never')).substring(0, 10)); $('#productcard-product-last-used-timeago').text($.timeago(productDetails.last_used || '')); - EmptyElementWhenMatches('#productcard-product-last-purchased-timeago', 'NaN years ago'); - EmptyElementWhenMatches('#productcard-product-last-used-timeago', 'NaN years ago'); + EmptyElementWhenMatches('#productcard-product-last-purchased-timeago', L('timeago_nan')); + EmptyElementWhenMatches('#productcard-product-last-used-timeago', L('timeago_nan')); }, function(xhr) { diff --git a/public/viewjs/consume.js b/public/viewjs/consume.js index ae000b99..9f444c14 100644 --- a/public/viewjs/consume.js +++ b/public/viewjs/consume.js @@ -81,55 +81,52 @@ $('#product_id').on('change', function(e) } }); -$(function() -{ - $('.combobox').combobox({ - appendId: '_text_input' - }); - - $('#product_id_text_input').on('change', function(e) - { - var input = $('#product_id_text_input').val().toString(); - var possibleOptionElement = $("#product_id option[data-additional-searchdata*='" + input + "']").first(); - - if (possibleOptionElement.length > 0) - { - $('#product_id').val(possibleOptionElement.val()); - $('#product_id').data('combobox').refresh(); - $('#product_id').trigger('change'); - } - }); - - $('#amount').val(1); - $('#product_id').val(''); - $('#product_id_text_input').focus(); - $('#product_id_text_input').val(''); - $('#product_id_text_input').trigger('change'); - - $('#consume-form').validator(); - $('#consume-form').validator('validate'); - - $('#amount').on('focus', function(e) - { - if ($('#product_id_text_input').val().length === 0) - { - $('#product_id_text_input').focus(); - } - else - { - $(this).select(); - } - }); - - $('#consume-form input').keydown(function(event) - { - if (event.keyCode === 13) //Enter - { - if ($('#consume-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error - { - event.preventDefault(); - return false; - } - } - }); +$('.combobox').combobox({ + appendId: '_text_input' +}); + +$('#product_id_text_input').on('change', function(e) +{ + var input = $('#product_id_text_input').val().toString(); + var possibleOptionElement = $("#product_id option[data-additional-searchdata*='" + input + "']").first(); + + if (possibleOptionElement.length > 0) + { + $('#product_id').val(possibleOptionElement.val()); + $('#product_id').data('combobox').refresh(); + $('#product_id').trigger('change'); + } +}); + +$('#amount').val(1); +$('#product_id').val(''); +$('#product_id_text_input').focus(); +$('#product_id_text_input').val(''); +$('#product_id_text_input').trigger('change'); + +$('#consume-form').validator(); +$('#consume-form').validator('validate'); + +$('#amount').on('focus', function(e) +{ + if ($('#product_id_text_input').val().length === 0) + { + $('#product_id_text_input').focus(); + } + else + { + $(this).select(); + } +}); + +$('#consume-form input').keydown(function(event) +{ + if (event.keyCode === 13) //Enter + { + if ($('#consume-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error + { + event.preventDefault(); + return false; + } + } }); diff --git a/public/viewjs/habitform.js b/public/viewjs/habitform.js index 5970606e..b03384ea 100644 --- a/public/viewjs/habitform.js +++ b/public/viewjs/habitform.js @@ -30,12 +30,9 @@ } }); -$(function() -{ - $('#name').focus(); - $('#habit-form').validator(); - $('#habit-form').validator('validate'); -}); +$('#name').focus(); +$('#habit-form').validator(); +$('#habit-form').validator('validate'); $('.input-group-habit-period-type').on('change', function(e) { diff --git a/public/viewjs/habits.js b/public/viewjs/habits.js index 42840c07..a34d0ce4 100644 --- a/public/viewjs/habits.js +++ b/public/viewjs/habits.js @@ -31,13 +31,11 @@ }); }); -$(function() -{ - $('#habits-table').DataTable({ - 'pageLength': 50, - 'order': [[1, 'asc']], - 'columnDefs': [ - { 'orderable': false, 'targets': 0 } - ] - }); +$('#habits-table').DataTable({ + 'pageLength': 50, + 'order': [[1, 'asc']], + 'columnDefs': [ + { 'orderable': false, 'targets': 0 } + ], + 'language': JSON.parse(L('datatables_localization')) }); diff --git a/public/viewjs/habitsoverview.js b/public/viewjs/habitsoverview.js index 4d7fb551..1f2bb50c 100644 --- a/public/viewjs/habitsoverview.js +++ b/public/viewjs/habitsoverview.js @@ -1,7 +1,5 @@ -$(function() -{ - $('#habits-overview-table').DataTable({ - 'pageLength': 50, - 'order': [[1, 'desc']] - }); +$('#habits-overview-table').DataTable({ + 'pageLength': 50, + 'order': [[1, 'desc']], + 'language': JSON.parse(L('datatables_localization')) }); diff --git a/public/viewjs/habittracking.js b/public/viewjs/habittracking.js index 696314eb..7971e21f 100644 --- a/public/viewjs/habittracking.js +++ b/public/viewjs/habittracking.js @@ -44,42 +44,39 @@ $('#habit_id').on('change', function(e) } }); -$(function() +$('#tracked_time').val(moment().format('YYYY-MM-DD HH:mm:ss')); +$('#tracked_time').trigger('change'); + +$('#tracked_time').on('focus', function(e) { - $('#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) { - if ($('#habit_id_text_input').val().length === 0) - { - $('#habit_id_text_input').focus(); - } - }); + $('#habit_id_text_input').focus(); + } +}); - $('.combobox').combobox({ - appendId: '_text_input' - }); +$('.combobox').combobox({ + appendId: '_text_input' +}); - $('#habit_id').val(''); - $('#habit_id_text_input').focus(); - $('#habit_id_text_input').val(''); - $('#habit_id_text_input').trigger('change'); +$('#habit_id').val(''); +$('#habit_id_text_input').focus(); +$('#habit_id_text_input').val(''); +$('#habit_id_text_input').trigger('change'); - $('#habittracking-form').validator(); - $('#habittracking-form').validator('validate'); +$('#habittracking-form').validator(); +$('#habittracking-form').validator('validate'); - $('#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 ($('#habittracking-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error - { - event.preventDefault(); - return false; - } + event.preventDefault(); + return false; } - }); + } }); $('#tracked_time').on('keypress', function(e) diff --git a/public/viewjs/inventory.js b/public/viewjs/inventory.js index 5c9782b9..f3d7704b 100644 --- a/public/viewjs/inventory.js +++ b/public/viewjs/inventory.js @@ -87,169 +87,166 @@ $('#product_id').on('change', function(e) } }); -$(function() -{ - $('.combobox').combobox({ - appendId: '_text_input' - }); +$('.combobox').combobox({ + appendId: '_text_input' +}); - $('#product_id_text_input').on('change', function(e) +$('#product_id_text_input').on('change', function(e) +{ + var input = $('#product_id_text_input').val().toString(); + var possibleOptionElement = $("#product_id option[data-additional-searchdata*='" + input + "']").first(); + + if (GetUriParam('addbarcodetoselection') === undefined && possibleOptionElement.length > 0) { - var input = $('#product_id_text_input').val().toString(); - var possibleOptionElement = $("#product_id option[data-additional-searchdata*='" + input + "']").first(); - - if (GetUriParam('addbarcodetoselection') === undefined && possibleOptionElement.length > 0) + $('#product_id').val(possibleOptionElement.val()); + $('#product_id').data('combobox').refresh(); + $('#product_id').trigger('change'); + } + else + { + var optionElement = $("#product_id option:contains('" + input + "')").first(); + if (input.length > 0 && optionElement.length === 0 && GetUriParam('addbarcodetoselection') === undefined ) { - $('#product_id').val(possibleOptionElement.val()); - $('#product_id').data('combobox').refresh(); - $('#product_id').trigger('change'); - } - else - { - var optionElement = $("#product_id option:contains('" + input + "')").first(); - if (input.length > 0 && optionElement.length === 0 && GetUriParam('addbarcodetoselection') === undefined ) - { - bootbox.dialog({ - message: '' + input + ' could not be resolved to a product, how do you want to proceed?', - title: 'Create or assign product', - onEscape: function() { }, - size: 'large', - backdrop: true, - buttons: { - cancel: { - label: 'Cancel', - className: 'btn-default', - callback: function() { } - }, - addnewproduct: { - label: 'Add as new product', - className: 'btn-success add-new-product-dialog-button', - callback: function() - { - window.location.href = '/product/new?prefillname=' + encodeURIComponent(input) + '&returnto=' + encodeURIComponent(window.location.pathname); - } - }, - addbarcode: { - label: 'Add as barcode to existing product', - className: 'btn-info add-new-barcode-dialog-button', - callback: function() - { - window.location.href = '/inventory?addbarcodetoselection=' + encodeURIComponent(input); - } - }, - addnewproductwithbarcode: { - label: 'Add as new product + prefill barcode', - className: 'btn-warning add-new-product-with-barcode-dialog-button', - callback: function() - { - window.location.href = '/product/new?prefillbarcode=' + encodeURIComponent(input) + '&returnto=' + encodeURIComponent(window.location.pathname); - } + bootbox.dialog({ + message: '' + input + ' could not be resolved to a product, how do you want to proceed?', + title: 'Create or assign product', + onEscape: function() { }, + size: 'large', + backdrop: true, + buttons: { + cancel: { + label: 'Cancel', + className: 'btn-default', + callback: function() { } + }, + addnewproduct: { + label: 'Add as new product', + className: 'btn-success add-new-product-dialog-button', + callback: function() + { + window.location.href = '/product/new?prefillname=' + encodeURIComponent(input) + '&returnto=' + encodeURIComponent(window.location.pathname); + } + }, + addbarcode: { + label: 'Add as barcode to existing product', + className: 'btn-info add-new-barcode-dialog-button', + callback: function() + { + window.location.href = '/inventory?addbarcodetoselection=' + encodeURIComponent(input); + } + }, + addnewproductwithbarcode: { + label: 'Add as new product + prefill barcode', + className: 'btn-warning add-new-product-with-barcode-dialog-button', + callback: function() + { + window.location.href = '/product/new?prefillbarcode=' + encodeURIComponent(input) + '&returnto=' + encodeURIComponent(window.location.pathname); } } - }).on('keypress', function(e) - { - if (e.key === 'B' || e.key === 'b') - { - $('.add-new-barcode-dialog-button').click(); - } - if (e.key === 'p' || e.key === 'P') - { - $('.add-new-product-dialog-button').click(); - } - if (e.key === 'a' || e.key === 'A') - { - $('.add-new-product-with-barcode-dialog-button').click(); - } - }); - } - } - }); - - $('#new_amount').val(''); - $('#best_before_date').val(''); - $('#product_id').val(''); - $('#product_id_text_input').focus(); - $('#product_id_text_input').val(''); - $('#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) + }).on('keypress', function(e) { - if ($el.val().length !== 0 && $el.val().toString() === $el.attr('not-equal').toString()) + if (e.key === 'B' || e.key === 'b') { - return 'This value cannot be equal to ' + $el.attr('not-equal').toString(); + $('.add-new-barcode-dialog-button').click(); } - } + if (e.key === 'p' || e.key === 'P') + { + $('.add-new-product-dialog-button').click(); + } + if (e.key === 'a' || e.key === 'A') + { + $('.add-new-product-with-barcode-dialog-button').click(); + } + }); } - }); - $('#inventory-form').validator('validate'); - - $('#new_amount').on('focus', function(e) - { - if ($('#product_id_text_input').val().length === 0) - { - $('#product_id_text_input').focus(); - } - else - { - $(this).select(); - } - }); - - $('#inventory-form input').keydown(function(event) - { - if (event.keyCode === 13) //Enter - { - if ($('#inventory-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error - { - event.preventDefault(); - return false; - } - } - }); - - var prefillProduct = GetUriParam('createdproduct'); - if (prefillProduct !== undefined) - { - var possibleOptionElement = $("#product_id option[data-additional-searchdata*='" + prefillProduct + "']").first(); - if (possibleOptionElement.length === 0) - { - possibleOptionElement = $("#product_id option:contains('" + prefillProduct + "')").first(); - } - - if (possibleOptionElement.length > 0) - { - $('#product_id').val(possibleOptionElement.val()); - $('#product_id').data('combobox').refresh(); - $('#product_id').trigger('change'); - $('#new_amount').focus(); - } - } - - var addBarcode = GetUriParam('addbarcodetoselection'); - if (addBarcode !== undefined) - { - $('#addbarcodetoselection').text(addBarcode); - $('#flow-info-addbarcodetoselection').removeClass('hide'); - $('#barcode-lookup-disabled-hint').removeClass('hide'); } }); +$('#new_amount').val(''); +$('#best_before_date').val(''); +$('#product_id').val(''); +$('#product_id_text_input').focus(); +$('#product_id_text_input').val(''); +$('#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) +{ + if ($('#product_id_text_input').val().length === 0) + { + $('#product_id_text_input').focus(); + } + else + { + $(this).select(); + } +}); + +$('#inventory-form input').keydown(function(event) +{ + if (event.keyCode === 13) //Enter + { + if ($('#inventory-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error + { + event.preventDefault(); + return false; + } + } +}); + +var prefillProduct = GetUriParam('createdproduct'); +if (prefillProduct !== undefined) +{ + var possibleOptionElement = $("#product_id option[data-additional-searchdata*='" + prefillProduct + "']").first(); + if (possibleOptionElement.length === 0) + { + possibleOptionElement = $("#product_id option:contains('" + prefillProduct + "')").first(); + } + + if (possibleOptionElement.length > 0) + { + $('#product_id').val(possibleOptionElement.val()); + $('#product_id').data('combobox').refresh(); + $('#product_id').trigger('change'); + $('#new_amount').focus(); + } +} + +var addBarcode = GetUriParam('addbarcodetoselection'); +if (addBarcode !== undefined) +{ + $('#addbarcodetoselection').text(addBarcode); + $('#flow-info-addbarcodetoselection').removeClass('hide'); + $('#barcode-lookup-disabled-hint').removeClass('hide'); +} + $('#new_amount').on('keypress', function(e) { $('#new_amount').trigger('change'); diff --git a/public/viewjs/locationform.js b/public/viewjs/locationform.js index 661ee560..f352620b 100644 --- a/public/viewjs/locationform.js +++ b/public/viewjs/locationform.js @@ -30,9 +30,6 @@ } }); -$(function() -{ - $('#name').focus(); - $('#location-form').validator(); - $('#location-form').validator('validate'); -}); +$('#name').focus(); +$('#location-form').validator(); +$('#location-form').validator('validate'); diff --git a/public/viewjs/locations.js b/public/viewjs/locations.js index 7f6bcb17..9c64b1a1 100644 --- a/public/viewjs/locations.js +++ b/public/viewjs/locations.js @@ -31,13 +31,11 @@ }); }); -$(function() -{ - $('#locations-table').DataTable({ - 'pageLength': 50, - 'order': [[1, 'asc']], - 'columnDefs': [ - { 'orderable': false, 'targets': 0 } - ] - }); +$('#locations-table').DataTable({ + 'pageLength': 50, + 'order': [[1, 'asc']], + 'columnDefs': [ + { 'orderable': false, 'targets': 0 } + ], + 'language': JSON.parse(L('datatables_localization')) }); diff --git a/public/viewjs/login.js b/public/viewjs/login.js index 6dd8e7c1..0ecea09e 100644 --- a/public/viewjs/login.js +++ b/public/viewjs/login.js @@ -1,12 +1,9 @@ -$(function() +$('.logout-button').hide(); + +$('#username').focus(); + +if (GetUriParam('invalid') === 'true') { - $('.logout-button').hide(); - - $('#username').focus(); - - if (GetUriParam('invalid') === 'true') - { - $('#login-error').text('Invalid credentials, please try again.'); - $('#login-error').show(); - } -}); + $('#login-error').text(L('Invalid credentials, please try again')); + $('#login-error').show(); +} diff --git a/public/viewjs/productform.js b/public/viewjs/productform.js index a39a264a..7008db76 100644 --- a/public/viewjs/productform.js +++ b/public/viewjs/productform.js @@ -37,59 +37,51 @@ } }); -$(function() -{ - $('#barcode-taginput').tagsManager({ - 'hiddenTagListName': 'barcode', - 'tagsContainer': '#barcode-taginput-container' - }); - - if (Grocy.EditMode === 'edit') - { - Grocy.FetchJson('/api/get-object/products/' + Grocy.EditObjectId, - function (product) - { - if (product.barcode !== null && product.barcode.length > 0) - { - product.barcode.split(',').forEach(function(item) - { - $('#barcode-taginput').tagsManager('pushTag', item); - }); - } - }, - function(xhr) - { - console.error(xhr); - } - ); - } - - $('#qu_factor_purchase_to_stock').trigger('change'); - $('#name').focus(); - $('#product-form').validator(); - $('#product-form').validator('validate'); - - var prefillName = GetUriParam('prefillname'); - if (prefillName !== undefined) - { - $('#name').val(prefillName); - $('#name').focus(); - } - - var prefillBarcode = GetUriParam('prefillbarcode'); - if (prefillBarcode !== undefined) - { - $('#barcode-taginput').tagsManager('pushTag', prefillBarcode); - $('#name').focus(); - } +$('#barcode-taginput').tagsManager({ + 'hiddenTagListName': 'barcode', + 'tagsContainer': '#barcode-taginput-container' }); +if (Grocy.EditMode === 'edit') +{ + Grocy.FetchJson('/api/get-object/products/' + Grocy.EditObjectId, + function (product) + { + if (product.barcode !== null && product.barcode.length > 0) + { + product.barcode.split(',').forEach(function(item) + { + $('#barcode-taginput').tagsManager('pushTag', item); + }); + } + }, + function(xhr) + { + console.error(xhr); + } + ); +} + +var prefillName = GetUriParam('prefillname'); +if (prefillName !== undefined) +{ + $('#name').val(prefillName); + $('#name').focus(); +} + +var prefillBarcode = GetUriParam('prefillbarcode'); +if (prefillBarcode !== undefined) +{ + $('#barcode-taginput').tagsManager('pushTag', prefillBarcode); + $('#name').focus(); +} + $('.input-group-qu').on('change', function(e) { var factor = $('#qu_factor_purchase_to_stock').val(); if (factor > 1) { - $('#qu-conversion-info').text('This means 1 ' + $("#qu_id_purchase option:selected").text() + ' purchased will be converted into ' + (1 * factor).toString() + ' ' + $("#qu_id_stock option:selected").text() + ' in stock.'); + $('#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(); } else @@ -97,3 +89,8 @@ $('.input-group-qu').on('change', function(e) $('#qu-conversion-info').hide(); } }); + +$('#name').focus(); +$('#product-form').validator(); +$('#product-form').validator('validate'); +$('.input-group-qu').trigger('change'); diff --git a/public/viewjs/products.js b/public/viewjs/products.js index 364cae4e..0cd05aa7 100644 --- a/public/viewjs/products.js +++ b/public/viewjs/products.js @@ -31,13 +31,11 @@ }); }); -$(function() -{ - $('#products-table').DataTable({ - 'pageLength': 50, - 'order': [[1, 'asc']], - 'columnDefs': [ - { 'orderable': false, 'targets': 0 } - ] - }); +$('#products-table').DataTable({ + 'pageLength': 50, + 'order': [[1, 'asc']], + 'columnDefs': [ + { 'orderable': false, 'targets': 0 } + ], + 'language': JSON.parse(L('datatables_localization')) }); diff --git a/public/viewjs/purchase.js b/public/viewjs/purchase.js index cfd9c418..a7a98934 100644 --- a/public/viewjs/purchase.js +++ b/public/viewjs/purchase.js @@ -96,170 +96,167 @@ $('#product_id').on('change', function(e) } }); -$(function() -{ - $('.combobox').combobox({ - appendId: '_text_input' - }); +$('.combobox').combobox({ + appendId: '_text_input' +}); - $('#product_id_text_input').on('change', function(e) +$('#product_id_text_input').on('change', function(e) +{ + var input = $('#product_id_text_input').val().toString(); + var possibleOptionElement = $("#product_id option[data-additional-searchdata*='" + input + "']").first(); + + if (GetUriParam('addbarcodetoselection') === undefined && possibleOptionElement.length > 0) { - var input = $('#product_id_text_input').val().toString(); - var possibleOptionElement = $("#product_id option[data-additional-searchdata*='" + input + "']").first(); - - if (GetUriParam('addbarcodetoselection') === undefined && possibleOptionElement.length > 0) + $('#product_id').val(possibleOptionElement.val()); + $('#product_id').data('combobox').refresh(); + $('#product_id').trigger('change'); + } + else + { + var optionElement = $("#product_id option:contains('" + input + "')").first(); + if (input.length > 0 && optionElement.length === 0 && GetUriParam('addbarcodetoselection') === undefined ) { - $('#product_id').val(possibleOptionElement.val()); - $('#product_id').data('combobox').refresh(); - $('#product_id').trigger('change'); - } - else - { - var optionElement = $("#product_id option:contains('" + input + "')").first(); - if (input.length > 0 && optionElement.length === 0 && GetUriParam('addbarcodetoselection') === undefined ) - { - bootbox.dialog({ - message: '' + input + ' could not be resolved to a product, how do you want to proceed?', - title: 'Create or assign product', - onEscape: function() { }, - size: 'large', - backdrop: true, - buttons: { - cancel: { - label: 'Cancel', - className: 'btn-default', - callback: function() { } - }, - addnewproduct: { - label: 'Add as new product', - className: 'btn-success add-new-product-dialog-button', - callback: function() - { - window.location.href = '/product/new?prefillname=' + encodeURIComponent(input) + '&returnto=' + encodeURIComponent(window.location.pathname); - } - }, - addbarcode: { - label: 'Add as barcode to existing product', - className: 'btn-info add-new-barcode-dialog-button', - callback: function() - { - window.location.href = '/purchase?addbarcodetoselection=' + encodeURIComponent(input); - } - }, - addnewproductwithbarcode: { - label: 'Add as new product + prefill barcode', - className: 'btn-warning add-new-product-with-barcode-dialog-button', - callback: function() - { - window.location.href = '/product/new?prefillbarcode=' + encodeURIComponent(input) + '&returnto=' + encodeURIComponent(window.location.pathname); - } + bootbox.dialog({ + message: '' + input + ' could not be resolved to a product, how do you want to proceed?', + title: 'Create or assign product', + onEscape: function() { }, + size: 'large', + backdrop: true, + buttons: { + cancel: { + label: 'Cancel', + className: 'btn-default', + callback: function() { } + }, + addnewproduct: { + label: 'Add as new product', + className: 'btn-success add-new-product-dialog-button', + callback: function() + { + window.location.href = '/product/new?prefillname=' + encodeURIComponent(input) + '&returnto=' + encodeURIComponent(window.location.pathname); + } + }, + addbarcode: { + label: 'Add as barcode to existing product', + className: 'btn-info add-new-barcode-dialog-button', + callback: function() + { + window.location.href = '/purchase?addbarcodetoselection=' + encodeURIComponent(input); + } + }, + addnewproductwithbarcode: { + label: 'Add as new product + prefill barcode', + className: 'btn-warning add-new-product-with-barcode-dialog-button', + callback: function() + { + window.location.href = '/product/new?prefillbarcode=' + encodeURIComponent(input) + '&returnto=' + encodeURIComponent(window.location.pathname); } } - }).on('keypress', function(e) - { - if (e.key === 'B' || e.key === 'b') - { - $('.add-new-barcode-dialog-button').click(); - } - if (e.key === 'p' || e.key === 'P') - { - $('.add-new-product-dialog-button').click(); - } - if (e.key === 'a' || e.key === 'A') - { - $('.add-new-product-with-barcode-dialog-button').click(); - } - }); - } - } - }); - - $('#amount').val(0); - $('#best_before_date').val(''); - $('#product_id').val(''); - $('#product_id_text_input').focus(); - $('#product_id_text_input').val(''); - $('#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) - { - if ($('#product_id_text_input').val().length === 0) - { - $('#product_id_text_input').focus(); - } - }); - - $('#amount').on('focus', function(e) - { - if ($('#product_id_text_input').val().length === 0) - { - $('#product_id_text_input').focus(); - } - else - { - $(this).select(); - } - }); - - $('#purchase-form input').keydown(function(event) - { - if (event.keyCode === 13) //Enter - { - if ($('#purchase-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error + }).on('keypress', function(e) { - event.preventDefault(); - return false; - } + if (e.key === 'B' || e.key === 'b') + { + $('.add-new-barcode-dialog-button').click(); + } + if (e.key === 'p' || e.key === 'P') + { + $('.add-new-product-dialog-button').click(); + } + if (e.key === 'a' || e.key === 'A') + { + $('.add-new-product-with-barcode-dialog-button').click(); + } + }); } - }); - - var prefillProduct = GetUriParam('createdproduct'); - if (prefillProduct !== undefined) - { - var possibleOptionElement = $("#product_id option[data-additional-searchdata*='" + prefillProduct + "']").first(); - if (possibleOptionElement.length === 0) - { - possibleOptionElement = $("#product_id option:contains('" + prefillProduct + "')").first(); - } - - if (possibleOptionElement.length > 0) - { - $('#product_id').val(possibleOptionElement.val()); - $('#product_id').data('combobox').refresh(); - $('#product_id').trigger('change'); - $('#best_before_date').focus(); - } - } - - var addBarcode = GetUriParam('addbarcodetoselection'); - if (addBarcode !== undefined) - { - $('#addbarcodetoselection').text(addBarcode); - $('#flow-info-addbarcodetoselection').removeClass('hide'); - $('#barcode-lookup-disabled-hint').removeClass('hide'); } }); +$('#amount').val(0); +$('#best_before_date').val(''); +$('#product_id').val(''); +$('#product_id_text_input').focus(); +$('#product_id_text_input').val(''); +$('#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) +{ + if ($('#product_id_text_input').val().length === 0) + { + $('#product_id_text_input').focus(); + } +}); + +$('#amount').on('focus', function(e) +{ + if ($('#product_id_text_input').val().length === 0) + { + $('#product_id_text_input').focus(); + } + else + { + $(this).select(); + } +}); + +$('#purchase-form input').keydown(function(event) +{ + if (event.keyCode === 13) //Enter + { + if ($('#purchase-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error + { + event.preventDefault(); + return false; + } + } +}); + +var prefillProduct = GetUriParam('createdproduct'); +if (prefillProduct !== undefined) +{ + var possibleOptionElement = $("#product_id option[data-additional-searchdata*='" + prefillProduct + "']").first(); + if (possibleOptionElement.length === 0) + { + possibleOptionElement = $("#product_id option:contains('" + prefillProduct + "')").first(); + } + + if (possibleOptionElement.length > 0) + { + $('#product_id').val(possibleOptionElement.val()); + $('#product_id').data('combobox').refresh(); + $('#product_id').trigger('change'); + $('#best_before_date').focus(); + } +} + +var addBarcode = GetUriParam('addbarcodetoselection'); +if (addBarcode !== undefined) +{ + $('#addbarcodetoselection').text(addBarcode); + $('#flow-info-addbarcodetoselection').removeClass('hide'); + $('#barcode-lookup-disabled-hint').removeClass('hide'); +} + $('#best_before_date').on('change', function(e) { $('#purchase-form').validator('validate'); diff --git a/public/viewjs/quantityunitform.js b/public/viewjs/quantityunitform.js index 488efa4d..c81df2fa 100644 --- a/public/viewjs/quantityunitform.js +++ b/public/viewjs/quantityunitform.js @@ -30,9 +30,6 @@ } }); -$(function() -{ - $('#name').focus(); - $('#quantityunit-form').validator(); - $('#quantityunit-form').validator('validate'); -}); +$('#name').focus(); +$('#quantityunit-form').validator(); +$('#quantityunit-form').validator('validate'); diff --git a/public/viewjs/quantityunits.js b/public/viewjs/quantityunits.js index 587ea855..6463bd8d 100644 --- a/public/viewjs/quantityunits.js +++ b/public/viewjs/quantityunits.js @@ -31,13 +31,11 @@ }); }); -$(function() -{ - $('#quantityunits-table').DataTable({ - 'pageLength': 50, - 'order': [[1, 'asc']], - 'columnDefs': [ - { 'orderable': false, 'targets': 0 } - ] - }); +$('#quantityunits-table').DataTable({ + 'pageLength': 50, + 'order': [[1, 'asc']], + 'columnDefs': [ + { 'orderable': false, 'targets': 0 } + ], + 'language': JSON.parse(L('datatables_localization')) }); diff --git a/public/viewjs/shoppinglist.js b/public/viewjs/shoppinglist.js index 198d17c7..7ecd5549 100644 --- a/public/viewjs/shoppinglist.js +++ b/public/viewjs/shoppinglist.js @@ -26,13 +26,11 @@ $(document).on('click', '#add-products-below-min-stock-amount', function(e) ); }); -$(function() -{ - $('#shoppinglist-table').DataTable({ - 'pageLength': 50, - 'order': [[1, 'asc']], - 'columnDefs': [ - { 'orderable': false, 'targets': 0 } - ] - }); +$('#shoppinglist-table').DataTable({ + 'pageLength': 50, + 'order': [[1, 'asc']], + 'columnDefs': [ + { 'orderable': false, 'targets': 0 } + ], + 'language': JSON.parse(L('datatables_localization')) }); diff --git a/public/viewjs/shoppinglistform.js b/public/viewjs/shoppinglistform.js index 4d20eb62..2ba8bb7f 100644 --- a/public/viewjs/shoppinglistform.js +++ b/public/viewjs/shoppinglistform.js @@ -36,22 +36,13 @@ $('#product_id').on('change', function(e) if (productId) { + Grocy.Components.ProductCard.Refresh(productId); + Grocy.FetchJson('/api/stock/get-product-details/' + productId, function (productDetails) { - $('#selected-product-name').text(productDetails.product.name); - $('#selected-product-stock-amount').text(productDetails.stock_amount || '0'); - $('#selected-product-stock-qu-name').text(productDetails.quantity_unit_stock.name); - $('#selected-product-stock-qu-name2').text(productDetails.quantity_unit_stock.name); - $('#selected-product-last-purchased').text((productDetails.last_purchased || 'never').substring(0, 10)); - $('#selected-product-last-purchased-timeago').text($.timeago(productDetails.last_purchased || '')); - $('#selected-product-last-used').text((productDetails.last_used || 'never').substring(0, 10)); - $('#selected-product-last-used-timeago').text($.timeago(productDetails.last_used || '')); $('#amount_qu_unit').text(productDetails.quantity_unit_purchase.name); - EmptyElementWhenMatches('#selected-product-last-purchased-timeago', 'NaN years ago'); - EmptyElementWhenMatches('#selected-product-last-used-timeago', 'NaN years ago'); - if ($('#product_id').hasClass('suppress-next-custom-validate-event')) { $('#product_id').removeClass('suppress-next-custom-validate-event'); @@ -97,53 +88,50 @@ $('#product_id').on('change', function(e) } }); -$(function() +$('.combobox').combobox({ + appendId: '_text_input' +}); + +$('#product_id_text_input').on('change', function(e) { - $('.combobox').combobox({ - appendId: '_text_input' - }); + var input = $('#product_id_text_input').val().toString(); + var possibleOptionElement = $("#product_id option[data-additional-searchdata*='" + input + "']").first(); - $('#product_id_text_input').on('change', function(e) - { - var input = $('#product_id_text_input').val().toString(); - var possibleOptionElement = $("#product_id option[data-additional-searchdata*='" + input + "']").first(); - - if (possibleOptionElement.length > 0 && possibleOptionElement.text().length > 0) { - $('#product_id').val(possibleOptionElement.val()); - $('#product_id').data('combobox').refresh(); - $('#product_id').trigger('change'); - } - }); - - $('#product_id_text_input').focus(); - $('#product_id_text_input').trigger('change'); - - if (Grocy.EditMode === 'edit') - { - $('#product_id').addClass('suppress-next-custom-validate-event'); + if (possibleOptionElement.length > 0 && possibleOptionElement.text().length > 0) { + $('#product_id').val(possibleOptionElement.val()); + $('#product_id').data('combobox').refresh(); $('#product_id').trigger('change'); } - - $('#shoppinglist-form').validator(); - $('#shoppinglist-form').validator('validate'); - - $('#amount').on('focus', function(e) - { - if ($('#product_id_text_input').val().length === 0) - { - $('#product_id_text_input').focus(); - } - }); - - $('#shoppinglist-form input').keydown(function(event) - { - if (event.keyCode === 13) //Enter - { - if ($('#shoppinglist-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error - { - event.preventDefault(); - return false; - } - } - }); +}); + +$('#product_id_text_input').focus(); +$('#product_id_text_input').trigger('change'); + +if (Grocy.EditMode === 'edit') +{ + $('#product_id').addClass('suppress-next-custom-validate-event'); + $('#product_id').trigger('change'); +} + +$('#shoppinglist-form').validator(); +$('#shoppinglist-form').validator('validate'); + +$('#amount').on('focus', function(e) +{ + if ($('#product_id_text_input').val().length === 0) + { + $('#product_id_text_input').focus(); + } +}); + +$('#shoppinglist-form input').keydown(function(event) +{ + if (event.keyCode === 13) //Enter + { + if ($('#shoppinglist-form').validator('validate').has('.has-error').length !== 0) //There is at least one validation error + { + event.preventDefault(); + return false; + } + } }); diff --git a/public/viewjs/stockoverview.js b/public/viewjs/stockoverview.js index c5825bbf..e7922127 100644 --- a/public/viewjs/stockoverview.js +++ b/public/viewjs/stockoverview.js @@ -1,7 +1,5 @@ -$(function() -{ - $('#stock-overview-table').DataTable({ - 'pageLength': 50, - 'order': [[2, 'asc']] - }); +$('#stock-overview-table').DataTable({ + 'pageLength': 50, + 'order': [[2, 'asc']], + 'language': JSON.parse(L('datatables_localization')) }); diff --git a/services/DemoDataGeneratorService.php b/services/DemoDataGeneratorService.php index 156c0e48..1715b29f 100644 --- a/services/DemoDataGeneratorService.php +++ b/services/DemoDataGeneratorService.php @@ -2,47 +2,52 @@ namespace Grocy\Services; +use \Grocy\Services\LocalizationService; + class DemoDataGeneratorService extends BaseService { public function PopulateDemoData() { + $localizationService = new LocalizationService(CULTURE); + $rowCount = $this->DatabaseService->ExecuteDbQuery('SELECT COUNT(*) FROM migrations WHERE migration = -1')->fetchColumn(); if (intval($rowCount) === 0) { $sql = " - UPDATE locations SET name = 'Vorratskammer', description = '' WHERE id = 1; - INSERT INTO locations (name) VALUES ('Süßigkeitenschrank'); --2 - INSERT INTO locations (name) VALUES ('Konservenschrank'); --3 - INSERT INTO locations (name) VALUES ('Kühlschrank'); --4 + INSERT INTO locations (name) VALUES ('{$localizationService->Localize('Pantry')}'); --2 + INSERT INTO locations (name) VALUES ('{$localizationService->Localize('Candy cupboard')}'); --3 + INSERT INTO locations (name) VALUES ('{$localizationService->Localize('Tinned food cupboard')}'); --4 + INSERT INTO locations (name) VALUES ('{$localizationService->Localize('Fridge')}'); --5 - UPDATE quantity_units SET name = 'Stück' WHERE id = 1; - INSERT INTO quantity_units (name) VALUES ('Packung'); --2 - INSERT INTO quantity_units (name) VALUES ('Glas'); --3 - INSERT INTO quantity_units (name) VALUES ('Dose'); --4 - INSERT INTO quantity_units (name) VALUES ('Becher'); --5 - INSERT INTO quantity_units (name) VALUES ('Bund'); --6 + INSERT INTO quantity_units (name) VALUES ('{$localizationService->Localize('Piece')}'); --2 + INSERT INTO quantity_units (name) VALUES ('{$localizationService->Localize('Pack')}'); --3 + INSERT INTO quantity_units (name) VALUES ('{$localizationService->Localize('Glass')}'); --4 + INSERT INTO quantity_units (name) VALUES ('{$localizationService->Localize('Tin')}'); --5 + INSERT INTO quantity_units (name) VALUES ('{$localizationService->Localize('Can')}'); --6 + INSERT INTO quantity_units (name) VALUES ('{$localizationService->Localize('Bunch')}'); --7 - DELETE FROM products WHERE id IN (1, 2); - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, min_stock_amount) VALUES ('Gummibärchen', 2, 2, 2, 1, 8); --3 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, min_stock_amount) VALUES ('Chips', 2, 2, 2, 1, 10); --4 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Eier', 1, 2, 1, 10); --5 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Nudeln', 1, 2, 2, 1); --6 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Essiggurken', 3, 3, 3, 1); --7 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Gulaschsuppe', 3, 4, 4, 1); --8 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Joghurt', 4, 5, 5, 1); --9 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Käse', 4, 2, 2, 1); --10 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Aufschnitt', 4, 2, 2, 1); --11 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Paprika', 4, 1, 1, 1); --12 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Gurke', 4, 1, 1, 1); --13 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Radieschen', 4, 6, 6, 1); --14 - INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('Tomate', 4, 1, 1, 1); --15 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, min_stock_amount) VALUES ('{$localizationService->Localize('Cookies')}', 3, 3, 3, 1, 8); --1 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, min_stock_amount) VALUES ('{$localizationService->Localize('Chocolate')}', 3, 3, 3, 1, 8); --2 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, min_stock_amount) VALUES ('{$localizationService->Localize('Gummy bears')}', 3, 3, 3, 1, 8); --3 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock, min_stock_amount) VALUES ('{$localizationService->Localize('Crisps')}', 3, 3, 3, 1, 10); --4 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Eggs')}', 5, 3, 2, 10); --5 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Noodles')}', 3, 3, 3, 1); --6 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Pickles')}', 4,4, 4, 1); --7 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Gulash soup')}', 4, 5, 5, 1); --8 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Yogurt')}', 5, 6, 6, 1); --9 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Cheese')}', 5, 3, 3, 1); --10 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Cold cuts')}', 5, 3, 3, 1); --11 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Paprika')}', 5, 2, 2, 1); --12 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Cucumber')}', 5, 2, 2, 1); --13 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Radish')}', 5, 7, 7, 1); --14 + INSERT INTO products (name, location_id, qu_id_purchase, qu_id_stock, qu_factor_purchase_to_stock) VALUES ('{$localizationService->Localize('Tomato')}', 5, 2, 2, 1); --15 - INSERT INTO habits (name, period_type, period_days) VALUES ('Changed towels in the bathroom', 'manually', 5); --1 - INSERT INTO habits (name, period_type, period_days) VALUES ('Cleaned the kitchen floor', 'dynamic-regular', 7); --2 + INSERT INTO habits (name, period_type, period_days) VALUES ('{$localizationService->Localize('Changed towels in the bathroom')}', 'manually', 5); --1 + INSERT INTO habits (name, period_type, period_days) VALUES ('{$localizationService->Localize('Cleaned the kitchen floor')}', 'dynamic-regular', 7); --2 - INSERT INTO batteries (name, description, used_in) VALUES ('Battery1', 'Warranty ends 2022', 'TV remote control'); --1 - INSERT INTO batteries (name, description, used_in) VALUES ('Battery2', 'Warranty ends 2022', 'Alarm clock'); --2 - INSERT INTO batteries (name, description, used_in, charge_interval_days) VALUES ('Battery3', 'Warranty ends 2022', 'Heat remote control', 60); --3 + INSERT INTO batteries (name, description, used_in) VALUES ('{$localizationService->Localize('Battery')}1', '{$localizationService->Localize('Warranty ends')} 2023', '{$localizationService->Localize('TV remote control')}'); --1 + INSERT INTO batteries (name, description, used_in) VALUES ('{$localizationService->Localize('Battery')}2', '{$localizationService->Localize('Warranty ends')} 2022', '{$localizationService->Localize('Alarm clock')}'); --2 + INSERT INTO batteries (name, description, used_in, charge_interval_days) VALUES ('{$localizationService->Localize('Battery')}3', '{$localizationService->Localize('Warranty ends')} 2022', '{$localizationService->Localize('Heat remote control')}', 60); --3 INSERT INTO migrations (migration) VALUES (-1); "; diff --git a/services/LocalizationService.php b/services/LocalizationService.php new file mode 100644 index 00000000..56e81d27 --- /dev/null +++ b/services/LocalizationService.php @@ -0,0 +1,103 @@ +Culture = $culture; + + $this->StringsDefaultCulture = $this->LoadLocalizationFile(self::DEFAULT_CULTURE); + $this->StringsCurrentCulture = $this->LoadLocalizationFile($culture); + $this->StringsMerged = array_merge($this->StringsDefaultCulture, $this->StringsCurrentCulture); + } + + protected $Culture; + protected $StringsDefaultCulture; + protected $StringsCurrentCulture; + protected $StringsMerged; + + private function LoadLocalizationFile(string $culture) + { + $file = __DIR__ . "/../localization/$culture.php"; + + if (file_exists($file)) + { + return require $file; + } + else + { + return array(); + } + } + + private function LogMissingLocalization(string $culture, string $text) + { + $file = __DIR__ . "/../data/missing_translations_$culture.json"; + + $missingTranslations = array(); + if (file_exists($file)) + { + $missingTranslations = json_decode(file_get_contents($file), true); + } + + if (!array_key_exists($text, $missingTranslations)) + { + $missingTranslations[$text] = '#TranslationMissing#'; + } + + if (count($missingTranslations) > 0) + { + file_put_contents($file, json_encode($missingTranslations, JSON_PRETTY_PRINT)); + } + } + + public function Localize(string $text, ...$placeholderValues) + { + if (MODE === 'dev') + { + if (!array_key_exists($text, $this->StringsDefaultCulture)) + { + $this->LogMissingLocalization(self::DEFAULT_CULTURE, $text); + } + + if (!array_key_exists($text, $this->StringsCurrentCulture)) + { + $this->LogMissingLocalization($this->Culture, $text); + } + } + + $localizedText = $text; + if (array_key_exists($text, $this->StringsMerged)) + { + $localizedText = $this->StringsMerged[$text]; + } + + for ($i = 0; $i < count($placeholderValues); $i++) + { + $localizedText = str_replace('#' . ($i + 1), $placeholderValues[$i], $localizedText); + } + + return $localizedText; + } + + public function GetLocalizations() + { + return $this->StringsMerged; + } + + public function GetDefaultCultureLocalizations() + { + return $this->StringsDefaultCulture; + } + + public function GetCurrentCultureLocalizations() + { + return $this->StringsCurrentCulture; + } +} diff --git a/version.txt b/version.txt index bd8bf882..27f9cd32 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.7.0 +1.8.0 diff --git a/views/batteries.blade.php b/views/batteries.blade.php index bb7d26a1..df484c89 100644 --- a/views/batteries.blade.php +++ b/views/batteries.blade.php @@ -1,6 +1,6 @@ @extends('layout.default') -@section('title', 'Batteries') +@section('title', $L('Batteries')) @section('activeNav', 'batteries') @section('viewJsName', 'batteries') @@ -8,9 +8,9 @@

- Batteries + @yield('title') -  Add +  {{ $L('Add') }}

@@ -19,9 +19,9 @@ # - Name - Description - Used in + {{ $L('Name') }} + {{ $L('Description') }} + {{ $L('Used in') }} diff --git a/views/batteriesoverview.blade.php b/views/batteriesoverview.blade.php index d0b2ca54..cc1be1af 100644 --- a/views/batteriesoverview.blade.php +++ b/views/batteriesoverview.blade.php @@ -1,21 +1,21 @@ @extends('layout.default') -@section('title', 'Batteries overview') +@section('title', $L('Batteries overview')) @section('activeNav', 'batteriesoverview') @section('viewJsName', 'batteriesoverview') @section('content')
-

Batteries overview

+

@yield('title')

- - - + + + diff --git a/views/batteryform.blade.php b/views/batteryform.blade.php index fa458144..2aef4538 100644 --- a/views/batteryform.blade.php +++ b/views/batteryform.blade.php @@ -1,9 +1,9 @@ @extends('layout.default') @if($mode == 'edit') - @section('title', 'Edit battery') + @section('title', $L('Edit battery')) @else - @section('title', 'Create battery') + @section('title', $L('Create battery')) @endif @section('viewJsName', 'batteryform') @@ -22,22 +22,22 @@
- +
- +
- +
- + diff --git a/views/batterytracking.blade.php b/views/batterytracking.blade.php index c4f4ed5f..710781ab 100644 --- a/views/batterytracking.blade.php +++ b/views/batterytracking.blade.php @@ -1,18 +1,18 @@ @extends('layout.default') -@section('title', 'Battery tracking') +@section('title', $L('Battery tracking')) @section('activeNav', 'batterytracking') @section('viewJsName', 'batterytracking') @section('content')
-

Battery tracking

+

@yield('title')

- + @@ -33,7 +33,7 @@
- + diff --git a/views/components/batterycard.blade.php b/views/components/batterycard.blade.php index 37aa345d..9f7e2226 100644 --- a/views/components/batterycard.blade.php +++ b/views/components/batterycard.blade.php @@ -4,11 +4,12 @@
-

Battery overview

+

{{ $L('Battery overview') }}

- Charge cycles count:
- Last charged:
+ {{ $L('Used in') }}:
+ {{ $L('Charge cycles count') }}:
+ {{ $L('Last charged') }}:

diff --git a/views/components/datepicker.blade.php b/views/components/datepicker.blade.php index c973b547..57e90bde 100644 --- a/views/components/datepicker.blade.php +++ b/views/components/datepicker.blade.php @@ -3,7 +3,7 @@ @endpush
- +
diff --git a/views/components/datetimepicker.blade.php b/views/components/datetimepicker.blade.php index 8dbc5b59..d64cdcdd 100644 --- a/views/components/datetimepicker.blade.php +++ b/views/components/datetimepicker.blade.php @@ -3,7 +3,7 @@ @endpush
- +
diff --git a/views/components/habitcard.blade.php b/views/components/habitcard.blade.php index 9a650d87..c8543e09 100644 --- a/views/components/habitcard.blade.php +++ b/views/components/habitcard.blade.php @@ -4,11 +4,11 @@
-

Habit overview

+

{{ $L('Habit overview') }}

- Tracked count:
- Last tracked:
+ {{ $L('Tracked count') }}:
+ {{ $L('Last tracked') }}:

diff --git a/views/components/productcard.blade.php b/views/components/productcard.blade.php index 752fa67c..27c17b05 100644 --- a/views/components/productcard.blade.php +++ b/views/components/productcard.blade.php @@ -4,13 +4,13 @@
-

Product overview

-

Stock quantity unit:

+

{{ $L('Product overview') }}

+

{{ $L('Stock quantity unit') }}:

- Stock amount:
- Last purchased:
- Last used: + {{ $L('Stock amount') }}:
+ {{ $L('Last purchased') }}:
+ {{ $L('Last used') }}:

diff --git a/views/consume.blade.php b/views/consume.blade.php index 8e5acf14..c08c1bfa 100644 --- a/views/consume.blade.php +++ b/views/consume.blade.php @@ -1,18 +1,18 @@ @extends('layout.default') -@section('title', 'Consume') +@section('title', $L('Consume')) @section('activeNav', 'consume') @section('viewJsName', 'consume') @section('content')
-

Consume

+

@yield('title')

- +
- + diff --git a/views/habitform.blade.php b/views/habitform.blade.php index a15f54ce..bf2fea37 100644 --- a/views/habitform.blade.php +++ b/views/habitform.blade.php @@ -1,9 +1,9 @@ @extends('layout.default') @if($mode == 'edit') - @section('title', 'Edit habit') + @section('title', $L('Edit habit')) @else - @section('title', 'Create habit') + @section('title', $L('Create habit')) @endif @section('viewJsName', 'habitform') @@ -22,35 +22,35 @@
- +
- +
- +
- +

- + diff --git a/views/habits.blade.php b/views/habits.blade.php index d67e2192..327625cc 100644 --- a/views/habits.blade.php +++ b/views/habits.blade.php @@ -1,6 +1,6 @@ @extends('layout.default') -@section('title', 'Habits') +@section('title', $L('Habits')) @section('activeNav', 'habits') @section('viewJsName', 'habits') @@ -8,9 +8,9 @@

- Habits + @yield('title') -  Add +  {{ $L('Add') }}

@@ -19,10 +19,10 @@
- - - - + + + + @@ -40,7 +40,7 @@ {{ $habit->name }}
BatteryLast chargedNext planned charge cycle{{ $L('Battery') }}{{ $L('Last charged') }}{{ $L('Next planned charge cycle') }}
#NamePeriod typePeriod daysDescription{{ $L('Name') }}{{ $L('Period type') }}{{ $L('Period days') }}{{ $L('Description') }}
- {{ $habit->period_type }} + {{ $L($habit->period_type) }} {{ $habit->period_days }} diff --git a/views/habitsoverview.blade.php b/views/habitsoverview.blade.php index 164a8fbf..c561af24 100644 --- a/views/habitsoverview.blade.php +++ b/views/habitsoverview.blade.php @@ -1,21 +1,21 @@ @extends('layout.default') -@section('title', 'Habits overview') +@section('title', $L('Habits overview')) @section('activeNav', 'habitsoverview') @section('viewJsName', 'habitsoverview') @section('content')
-

Habits overview

+

@yield('title')

- - - + + + diff --git a/views/habittracking.blade.php b/views/habittracking.blade.php index 923409e0..8d145227 100644 --- a/views/habittracking.blade.php +++ b/views/habittracking.blade.php @@ -1,18 +1,18 @@ @extends('layout.default') -@section('title', 'Habit tracking') +@section('title', $L('Habit tracking')) @section('activeNav', 'habittracking') @section('viewJsName', 'habittracking') @section('content')
-

Habit tracking

+

@yield('title')

- + @foreach($products as $product) @@ -20,11 +20,11 @@ @endforeach
-
will be added to the list of barcodes for the selected product on submit.
+
{{ $L('will be added to the list of barcodes for the selected product on submit') }}
- +
@@ -32,10 +32,11 @@ @include('components.datepicker', array( 'id' => 'best_before_date', - 'label' => 'Best before  This will apply to added products' + 'label' => 'Best before', + 'hint' => 'This will apply to added products' )) - + diff --git a/views/layout/default.blade.php b/views/layout/default.blade.php index 999ab140..5e1e8430 100644 --- a/views/layout/default.blade.php +++ b/views/layout/default.blade.php @@ -25,10 +25,12 @@ - - - - + @@ -46,7 +48,7 @@ @@ -55,60 +57,60 @@ @@ -138,54 +140,54 @@ @@ -211,11 +213,14 @@
+ + @if(!empty($L('bootstrap_datepicker_locale')))@endif + @if(!empty($L('moment_locale')))@endif @@ -223,10 +228,13 @@ + + + @stack('componentScripts') diff --git a/views/locationform.blade.php b/views/locationform.blade.php index 0d1d4101..167c322f 100644 --- a/views/locationform.blade.php +++ b/views/locationform.blade.php @@ -1,9 +1,9 @@ @extends('layout.default') @if($mode == 'edit') - @section('title', 'Edit location') + @section('title', $L('Edit location')) @else - @section('title', 'Create location') + @section('title', $L('Create location')) @endif @section('viewJsName', 'locationform') @@ -22,17 +22,17 @@
- +
- +
- + diff --git a/views/locations.blade.php b/views/locations.blade.php index 12a53ce4..e861887a 100644 --- a/views/locations.blade.php +++ b/views/locations.blade.php @@ -1,6 +1,6 @@ @extends('layout.default') -@section('title', 'Locations') +@section('title', $L('Locations')) @section('activeNav', 'locations') @section('viewJsName', 'locations') @@ -8,9 +8,9 @@

- Locations + @yield('title') -  Add +  {{ $L('Add') }}

@@ -19,8 +19,8 @@
- - + + diff --git a/views/login.blade.php b/views/login.blade.php index 5650270d..5dc10f38 100644 --- a/views/login.blade.php +++ b/views/login.blade.php @@ -1,28 +1,28 @@ @extends('layout.default') -@section('title', 'Login') +@section('title', $L('Login')) @section('viewJsName', 'login') @section('content')
-

Login

+

@yield('title')

- +
- +
- + diff --git a/views/productform.blade.php b/views/productform.blade.php index f19e3238..25d268fa 100644 --- a/views/productform.blade.php +++ b/views/productform.blade.php @@ -1,9 +1,9 @@ @extends('layout.default') @if($mode == 'edit') - @section('title', 'Edit product') + @section('title', $L('Edit product')) @else - @section('title', 'Create product') + @section('title', $L('Create product')) @endif @section('viewJsName', 'productform') @@ -22,24 +22,24 @@
- +
- +
- +
- +
- +
- + @foreach($quantityunits as $quantityunit) @@ -81,14 +81,14 @@
- +

- +
diff --git a/views/products.blade.php b/views/products.blade.php index 2fd42c6e..3d6ed2ab 100644 --- a/views/products.blade.php +++ b/views/products.blade.php @@ -1,6 +1,6 @@ @extends('layout.default') -@section('title', 'Products') +@section('title', $L('Products')) @section('activeNav', 'products') @section('viewJsName', 'products') @@ -8,9 +8,9 @@

- Products + @yield('title') -  Add +  {{ $L('Add') }}

@@ -19,13 +19,13 @@
- - - - - - - + + + + + + + diff --git a/views/purchase.blade.php b/views/purchase.blade.php index 436bff61..2e71fa90 100644 --- a/views/purchase.blade.php +++ b/views/purchase.blade.php @@ -1,18 +1,18 @@ @extends('layout.default') -@section('title', 'Purchase') +@section('title', $L('Purchase')) @section('activeNav', 'purchase') @section('viewJsName', 'purchase') @section('content')
-

Purchase

+

@yield('title')

- +
- + diff --git a/views/quantityunitform.blade.php b/views/quantityunitform.blade.php index 5937bb7a..56b18bd3 100644 --- a/views/quantityunitform.blade.php +++ b/views/quantityunitform.blade.php @@ -1,9 +1,9 @@ @extends('layout.default') @if($mode == 'edit') - @section('title', 'Edit quantity unit') + @section('title', $L('Edit quantity unit')) @else - @section('title', 'Create quantity unit') + @section('title', $L('Create quantity unit')) @endif @section('viewJsName', 'quantityunitform') @@ -22,17 +22,17 @@
- +
- +
- + diff --git a/views/quantityunits.blade.php b/views/quantityunits.blade.php index 1daabe43..86b69b5d 100644 --- a/views/quantityunits.blade.php +++ b/views/quantityunits.blade.php @@ -1,6 +1,6 @@ @extends('layout.default') -@section('title', 'Quantity units') +@section('title', $L('Quantity units')) @section('activeNav', 'quantityunits') @section('viewJsName', 'quantityunits') @@ -8,7 +8,7 @@

- Quantity units + @yield('title')  Add @@ -19,8 +19,8 @@

- - + + diff --git a/views/shoppinglist.blade.php b/views/shoppinglist.blade.php index 57d3340d..d21f4221 100644 --- a/views/shoppinglist.blade.php +++ b/views/shoppinglist.blade.php @@ -1,6 +1,6 @@ @extends('layout.default') -@section('title', 'Shopping list') +@section('title', $L('Shopping list')) @section('activeNav', 'shoppinglist') @section('viewJsName', 'shoppinglist') @@ -8,12 +8,12 @@ - - + + diff --git a/views/shoppinglistform.blade.php b/views/shoppinglistform.blade.php index 694e7df5..f5721a8a 100644 --- a/views/shoppinglistform.blade.php +++ b/views/shoppinglistform.blade.php @@ -1,9 +1,9 @@ @extends('layout.default') @if($mode == 'edit') - @section('title', 'Edit shopping list item') + @section('title', $L('Edit shopping list item')) @else - @section('title', 'Create shopping list item') + @section('title', $L('Create shopping list item')) @endif @section('viewJsName', 'shoppinglistform') @@ -22,7 +22,7 @@
- +
- +
- + -
-

Product overview

-

Stock quantity unit:

- -

- Stock amount:
- Last purchased:
- Last used: -

+
+ @include('components.productcard')
@stop diff --git a/views/stockoverview.blade.php b/views/stockoverview.blade.php index 52c8c3f3..b4a39690 100644 --- a/views/stockoverview.blade.php +++ b/views/stockoverview.blade.php @@ -1,19 +1,19 @@ @extends('layout.default') -@section('title', 'Stock overview') +@section('title', $L('Stock overview')) @section('activeNav', 'stockoverview') @section('viewJsName', 'stockoverview') @section('content')
-

Stock overview {{ count($currentStock) }} products with {{ SumArrayValue($currentStock, 'amount') }} units in stock

+

{{ $L('Stock overview') }} {{ $L('#1 products with #2 units in stock', count($currentStock), SumArrayValue($currentStock, 'amount')) }}

-

{{ count(FindAllObjectsInArrayByPropertyValue($currentStock, 'best_before_date', date('Y-m-d', strtotime('+5 days')), '<')) }} products expiring within the next 5 days

-

{{ count(FindAllObjectsInArrayByPropertyValue($currentStock, 'best_before_date', date('Y-m-d', strtotime('-1 days')), '<')) }} products are already expired

-

{{ count($missingProducts) }} products are below defined min. stock amount

+

{{ $L('#1 products expiring within the next #2 days', count(FindAllObjectsInArrayByPropertyValue($currentStock, 'best_before_date', date('Y-m-d', strtotime('+5 days')), '<')), 5) }}

+

{{ $L('#1 products are already expired', count(FindAllObjectsInArrayByPropertyValue($currentStock, 'best_before_date', date('Y-m-d', strtotime('-1 days')), '<'))) }}

+

{{ $L('#1 products are below defined min. stock amount', count($missingProducts)) }}

@@ -23,9 +23,9 @@
HabitNext estimated trackingLast tracked{{ $L('Habit') }}{{ $L('Next estimated tracking') }}{{ $L('Last tracked') }}
#NameDescription{{ $L('Name') }}{{ $L('Description') }}
#NameLocationMin. stock amountQU purchaseQU stockQU factorDescription{{ $L('Name') }}{{ $L('Location') }}{{ $L('Min. stock amount') }}{{ $L('QU purchase') }}{{ $L('QU stock') }}{{ $L('QU factor') }}{{ $L('Description') }}
#NameDescription{{ $L('Name') }}{{ $L('Description') }}
#Product / NoteAmount{{ $L('Product') }} / {{ $L('Note') }}{{ $L('Amount') }}
- - - + + +
ProductAmountNext best before date{{ $L('Product') }}{{ $L('Amount') }}{{ $L('Next best before date') }}