mirror of
https://github.com/grocy/grocy.git
synced 2025-04-28 17:23:56 +00:00
Finish equipment / instruction manuals feature (references #25)
This commit is contained in:
parent
81ec011095
commit
b242a5de52
@ -266,7 +266,17 @@ return array(
|
||||
'Select file' => 'Datei auswählen',
|
||||
'Image of product #1' => 'Bild des Produkts #1',
|
||||
'This product cannot be deleted because it is in stock, please remove the stock amount first.' => 'Dieses Produkt kann nicht gelöscht werden, da es auf Lager ist, bitte zuerst den Bestand entfernen.',
|
||||
'Delete not possible' => 'Löschen nicht möglich',
|
||||
'Delete not possible' => 'Löschen nicht möglich',
|
||||
'Equipment' => 'Ausstattung',
|
||||
'Instruction manual' => 'Bedienungsanleitung',
|
||||
'The selected equipment has no instruction manual' => 'Das ausgewählte Gerät hat keine Bedienungsanleitung',
|
||||
'Notes' => 'Notizen',
|
||||
'Edit equipment' => 'Geräte bearbeiten',
|
||||
'Create equipment' => 'Geräte erstellen',
|
||||
'If you don\'t select a file, the current instruction manual will not be altered' => 'Wenn du keine Datei auswählst, wird die aktuelle Bedienungsanleitung nicht verändert',
|
||||
'Current instruction manual' => 'Aktuelle Bedienungsanleitung',
|
||||
'No instruction manual available' => 'Keine Bedienungsanleitung vorhanden',
|
||||
'The current instruction manual will be deleted when you save the equipment' => 'Die aktuelle Bedienungsanleitung wird beim Speichern des Geräts gelöscht',
|
||||
|
||||
//Constants
|
||||
'manually' => 'Manuell',
|
||||
@ -277,6 +287,7 @@ return array(
|
||||
'timeago_nan' => 'vor NaN Jahren',
|
||||
'moment_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 <i>ctrl</i> oder <i>⌘</i> + <i>C</i> um Tabelle<br>in Zwischenspeicher zu kopieren.<br><br>Um abzubrechen die Nachricht anklicken oder Escape drücken.","copySuccess":{"1":"1 Spalte kopiert","_":"%d Spalten kopiert"}}}',
|
||||
'summernote_locale' => 'de-DE',
|
||||
|
||||
//Demo data
|
||||
'Cookies' => 'Cookies',
|
||||
@ -348,5 +359,7 @@ return array(
|
||||
'Tinned food' => 'Konservern',
|
||||
'Butchery products' => 'Metzgerei',
|
||||
'Vegetables/Fruits' => 'Obst/Gemüse',
|
||||
'Refrigerated products' => 'Kühlregal'
|
||||
'Refrigerated products' => 'Kühlregal',
|
||||
'Coffee machine' => 'Kaffeemaschine',
|
||||
'Dishwasher' => 'Spülmaschine'
|
||||
);
|
||||
|
@ -9,5 +9,6 @@ return array(
|
||||
'timeago_locale' => 'en',
|
||||
'timeago_nan' => 'NaN years ago',
|
||||
'moment_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"}}'
|
||||
'datatables_localization' => '{"sEmptyTable":"No data available in table","sInfo":"Showing _START_ to _END_ of _TOTAL_ entries","sInfoEmpty":"Showing 0 to 0 of 0 entries","sInfoFiltered":"(filtered from _MAX_ total entries)","sInfoPostFix":"","sInfoThousands":",","sLengthMenu":"Show _MENU_ entries","sLoadingRecords":"Loading...","sProcessing":"Processing...","sSearch":"Search:","sZeroRecords":"No matching records found","oPaginate":{"sFirst":"First","sLast":"Last","sNext":"Next","sPrevious":"Previous"},"oAria":{"sSortAscending":": activate to sort column ascending","sSortDescending":": activate to sort column descending"}}',
|
||||
'summernote_locale' => ''
|
||||
);
|
||||
|
@ -150,6 +150,7 @@ return array(
|
||||
'timeago_nan' => 'NaN anni fa',
|
||||
'moment_locale' => 'it',
|
||||
'datatables_localization' => '{"sEmptyTable":"Nessun dato disponibile","sInfo":"Mostrando da _START_ a _END_ di _TOTAL_ voci","sInfoEmpty":"Mostrando da 0 a 0 di 0 voci","sInfoFiltered":"(Filtrato da _MAX_ voci totali)","sInfoPostFix":"","sInfoThousands":",","sLengthMenu":"Mostra _MENU_ voci","sLoadingRecords":"Caricando...","sProcessing":"Calcolando...","sSearch":"Cerca:","sZeroRecords":"Nessun risultato trovato","oPaginate":{"sFirst":"Prima","sLast":"Ultima","sNext":"Prossima","sPrevious":"Precedente"},"oAria":{"sSortAscending":": ordine crescente","sSortDescending":": ordine decrescente"}}',
|
||||
'summernote_locale' => 'it-IT',
|
||||
|
||||
//Demo data
|
||||
'Cookies' => 'Biscotti',
|
||||
|
@ -27,6 +27,7 @@
|
||||
"tagmanager": "https://github.com/max-favilli/tagmanager.git#3.0.2",
|
||||
"tempusdominus-bootstrap-4": "^5.0.1",
|
||||
"timeago": "^1.6.3",
|
||||
"toastr": "^2.1.4"
|
||||
"toastr": "^2.1.4",
|
||||
"summernote": "^0.8.10"
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
'initComplete': function()
|
||||
{
|
||||
this.api().row({ order: 'current' }, 0).select();
|
||||
DisplayEquipment($('#equipment-table tbody tr:eq(0)').data("equipment-id"));
|
||||
}
|
||||
});
|
||||
|
||||
@ -29,10 +30,41 @@ equipmentTable.on('select', function(e, dt, type, indexes)
|
||||
if (type === 'row')
|
||||
{
|
||||
var selectedEquipmentId = $(equipmentTable.row(indexes[0]).node()).data("equipment-id");
|
||||
console.log(selectedEquipmentId);
|
||||
DisplayEquipment(selectedEquipmentId)
|
||||
}
|
||||
});
|
||||
|
||||
function DisplayEquipment(id)
|
||||
{
|
||||
Grocy.Api.Get('get-object/equipment/' + id,
|
||||
function(equipmentItem)
|
||||
{
|
||||
$("#description-tab").html(equipmentItem.description);
|
||||
|
||||
if (equipmentItem.instruction_manual_file_name !== null && !equipmentItem.instruction_manual_file_name.isEmpty())
|
||||
{
|
||||
var pdfUrl = U('/api/file/equipmentmanuals?file_name=' + equipmentItem.instruction_manual_file_name);
|
||||
$("#selected-equipment-instruction-manual").attr("src", pdfUrl);
|
||||
$("#selected-equipment-instruction-manual").removeClass("d-none");
|
||||
$("#selected-equipment-has-no-instruction-manual-hint").addClass("d-none");
|
||||
|
||||
$("a[href='#instruction-manual-tab']").tab("show");
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#selected-equipment-instruction-manual").addClass("d-none");
|
||||
$("#selected-equipment-has-no-instruction-manual-hint").removeClass("d-none");
|
||||
|
||||
$("a[href='#description-tab']").tab("show");
|
||||
}
|
||||
},
|
||||
function(xhr)
|
||||
{
|
||||
console.error(xhr);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$("#search").on("keyup", function()
|
||||
{
|
||||
var value = $(this).val();
|
||||
|
@ -114,10 +114,15 @@ Grocy.DeleteInstructionManualOnSave = false;
|
||||
$('#delete-current-instruction-manual-button').on('click', function (e)
|
||||
{
|
||||
Grocy.DeleteInstructionManualOnSave = true;
|
||||
//$("#current-instruction-manual").addClass("d-none");
|
||||
$("#current-equipment-instruction-manual").addClass("d-none");
|
||||
$("#delete-current-instruction-manual-on-save-hint").removeClass("d-none");
|
||||
$("#delete-current-instruction-manual-button").addClass("disabled");
|
||||
});
|
||||
|
||||
$('#description').summernote({
|
||||
minHeight: '300px',
|
||||
lang: L('summernote_locale')
|
||||
});
|
||||
|
||||
$('#name').focus();
|
||||
Grocy.FrontendHelpers.ValidateForm('equipment-form');
|
||||
|
@ -14,6 +14,7 @@ class DemoDataGeneratorService extends BaseService
|
||||
if (intval($rowCount) === 0)
|
||||
{
|
||||
$loremIpsum = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.';
|
||||
$loremIpsumWithHtmlFormattings = "<h1>Lorem ipsum</h1><p>Lorem ipsum <b>dolor sit</b> amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur <span style=\"background-color: rgb(255, 255, 0);\">sadipscing elitr</span>, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</p><ul><li>At vero eos et accusam et justo duo dolores et ea rebum.</li><li>Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</li></ul><h1>Lorem ipsum</h1><p>Lorem ipsum <b>dolor sit</b> amet, consetetur \r\nsadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et \r\ndolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et\r\n justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea \r\ntakimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit \r\namet, consetetur <span style=\"background-color: rgb(255, 255, 0);\">sadipscing elitr</span>,\r\n sed diam nonumy eirmod tempor invidunt ut labore et dolore magna \r\naliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo \r\ndolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus \r\nest Lorem ipsum dolor sit amet.</p>";
|
||||
|
||||
$sql = "
|
||||
UPDATE users SET username = '{$localizationService->Localize('Demo User')}' WHERE id = 1;
|
||||
@ -105,8 +106,8 @@ class DemoDataGeneratorService extends BaseService
|
||||
INSERT INTO tasks (name, due_date, assigned_to_user_id) VALUES ('{$localizationService->Localize('Find a solution for what to do when I forget the door keys')}', date(datetime('now', 'localtime'), '+3 day'), 1);
|
||||
INSERT INTO tasks (name, due_date, assigned_to_user_id) VALUES ('{$localizationService->Localize('Task')}3', date(datetime('now', 'localtime'), '+4 day'), 1);
|
||||
|
||||
INSERT INTO equipment (name, description) VALUES ('{$localizationService->Localize('Coffee machine')}', '{$loremIpsum}'); --1
|
||||
INSERT INTO equipment (name, description) VALUES ('{$localizationService->Localize('Dishwasher')}', '{$loremIpsum}'); --2
|
||||
INSERT INTO equipment (name, description, instruction_manual_file_name) VALUES ('{$localizationService->Localize('Coffee machine')}', '{$loremIpsumWithHtmlFormattings}', 'loremipsum.pdf'); --1
|
||||
INSERT INTO equipment (name, description) VALUES ('{$localizationService->Localize('Dishwasher')}', '{$loremIpsumWithHtmlFormattings}'); --2
|
||||
|
||||
INSERT INTO migrations (migration) VALUES (-1);
|
||||
";
|
||||
@ -205,10 +206,12 @@ class DemoDataGeneratorService extends BaseService
|
||||
$batteriesService->TrackChargeCycle(3, date('Y-m-d H:i:s', strtotime('-65 days')));
|
||||
$batteriesService->TrackChargeCycle(4, date('Y-m-d H:i:s', strtotime('-56 days')));
|
||||
|
||||
// Download demo product pictures
|
||||
// Download demo storage data
|
||||
$productPicturesFolder = GROCY_DATAPATH . '/storage/productpictures';
|
||||
$equipmentManualsFolder = GROCY_DATAPATH . '/storage/equipmentmanuals';
|
||||
mkdir(GROCY_DATAPATH . '/storage');
|
||||
mkdir(GROCY_DATAPATH . '/storage/productpictures');
|
||||
mkdir(GROCY_DATAPATH . '/storage/equipmentmanuals');
|
||||
$sslOptions = array(
|
||||
'ssl' => array(
|
||||
'verify_peer' => false,
|
||||
@ -220,6 +223,7 @@ class DemoDataGeneratorService extends BaseService
|
||||
file_put_contents("$productPicturesFolder/gummybears.jpg", file_get_contents('https://releases.grocy.info/demoresources/gummybears.jpg', false, stream_context_create($sslOptions)));
|
||||
file_put_contents("$productPicturesFolder/paprika.jpg", file_get_contents('https://releases.grocy.info/demoresources/paprika.jpg', false, stream_context_create($sslOptions)));
|
||||
file_put_contents("$productPicturesFolder/tomato.jpg", file_get_contents('https://releases.grocy.info/demoresources/tomato.jpg', false, stream_context_create($sslOptions)));
|
||||
file_put_contents("$equipmentManualsFolder/loremipsum.pdf", file_get_contents('https://releases.grocy.info/demoresources/loremipsum.pdf', false, stream_context_create($sslOptions)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,9 +54,23 @@
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-md-9">
|
||||
<h3>{{ $L('Instruction manual') }}</h3>
|
||||
<p id="selected-equipment-has-no-instruction-manual-hint">{{ $L('The selected equipment has no instruction manual') }}</p>
|
||||
<p>TODO: Here the current instruction manual needs to be shown (PDF.js), if any...</p>
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="tab" href="#instruction-manual-tab">{{ $L('Instruction manual') }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#description-tab">{{ $L('Notes') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content border-left border-right border-bottom py-2 px-2">
|
||||
<div class="tab-pane fade show active" id="instruction-manual-tab">
|
||||
<p id="selected-equipment-has-no-instruction-manual-hint" class="text-muted font-italic d-none">{{ $L('The selected equipment has no instruction manual') }}</p>
|
||||
<embed id="selected-equipment-instruction-manual" class="embed-responsive embed-responsive-4by3" width="100%" height="800px" src="" type="application/pdf">
|
||||
</div>
|
||||
<div class="tab-pane fade" id="description-tab">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
@ -8,6 +8,15 @@
|
||||
|
||||
@section('viewJsName', 'equipmentform')
|
||||
|
||||
@push('pageScripts')
|
||||
<script src="{{ $U('/node_modules/summernote/dist/summernote-bs4.js?v=', true) }}{{ $version }}"></script>
|
||||
@if(!empty($L('summernote_locale')))<script src="{{ $U('/node_modules', true) }}/summernote/dist/lang/summernote-{{ $L('summernote_locale') }}.js?v={{ $version }}"></script>@endif
|
||||
@endpush
|
||||
|
||||
@push('pageStyles')
|
||||
<link href="{{ $U('/node_modules/summernote/dist/summernote-bs4.css?v=', true) }}{{ $version }}" rel="stylesheet">
|
||||
@endpush
|
||||
|
||||
@section('content')
|
||||
<div class="row">
|
||||
|
||||
@ -42,8 +51,8 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="description">{{ $L('Description') }}</label>
|
||||
<textarea class="form-control" rows="25" id="description" name="description">@if($mode == 'edit'){{ $equipment->description }}@endif</textarea>
|
||||
<label for="description">{{ $L('Notes') }}</label>
|
||||
<textarea class="form-control" id="description" name="description">@if($mode == 'edit'){{ $equipment->description }}@endif</textarea>
|
||||
</div>
|
||||
|
||||
<button id="save-equipment-button" class="btn btn-success">{{ $L('Save') }}</button>
|
||||
@ -55,10 +64,10 @@
|
||||
<label class="mt-2">{{ $L('Current instruction manual') }}</label>
|
||||
<button id="delete-current-instruction-manual-button" class="btn btn-sm btn-danger @if(empty($equipment->instruction_manual_file_name)) disabled @endif"><i class="fas fa-trash"></i> {{ $L('Delete') }}</button>
|
||||
@if(!empty($equipment->instruction_manual_file_name))
|
||||
<p>TODO: Here the current instruction manual needs to be shown (PDF.js), if any...</p>
|
||||
<embed id="current-equipment-instruction-manual" class="embed-responsive embed-responsive-4by3" width="100%" height="800px" src="{{ $U('/api/file/equipmentmanuals?file_name=' . $equipment->instruction_manual_file_name) }}" type="application/pdf">
|
||||
<p id="delete-current-instruction-manual-on-save-hint" class="form-text text-muted font-italic d-none">{{ $L('The current instruction manual will be deleted when you save the equipment') }}</p>
|
||||
@else
|
||||
<p id="no-current-instruction-manual-hint" class="form-text text-muted font-italic">{{ $L('No instruction manual') }}</p>
|
||||
<p id="no-current-instruction-manual-hint" class="form-text text-muted font-italic">{{ $L('No instruction manual available') }}</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
@ -95,7 +95,7 @@
|
||||
</li>
|
||||
<li class="nav-item" data-toggle="tooltip" data-placement="right" title="{{ $L('Equipment') }}" data-nav-for-page="equipment">
|
||||
<a class="nav-link discrete-link" href="{{ $U('/equipment') }}">
|
||||
<i class="fas fa-warehouse"></i>
|
||||
<i class="fas fa-toolbox"></i>
|
||||
<span class="nav-link-text">{{ $L('Equipment') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
|
@ -10,7 +10,7 @@
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.3.1.tgz#5466b8f31c1f493a96754c1426c25796d0633dd9"
|
||||
|
||||
"TagManager@https://github.com/max-favilli/tagmanager.git#3.0.2":
|
||||
"TagManager@https://github.com/max-favilli/tagmanager.git#3.0.2", "tagmanager@https://github.com/max-favilli/tagmanager.git#3.0.2":
|
||||
version "3.0.1"
|
||||
resolved "https://github.com/max-favilli/tagmanager.git#df9eb9935c8585a392dfc00602f890caf233fa94"
|
||||
dependencies:
|
||||
@ -202,6 +202,10 @@ startbootstrap-sb-admin@^4.0.0:
|
||||
jquery "3.3.1"
|
||||
jquery.easing "^1.4.1"
|
||||
|
||||
summernote@^0.8.10:
|
||||
version "0.8.10"
|
||||
resolved "https://registry.yarnpkg.com/summernote/-/summernote-0.8.10.tgz#21a5d7f18a3b07500b58b60d5907417a54897520"
|
||||
|
||||
swagger-ui-dist@^3.17.3:
|
||||
version "3.19.1"
|
||||
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-3.19.1.tgz#ee176cfb070470bb81ba98a686e808035a882cb1"
|
||||
|
Loading…
x
Reference in New Issue
Block a user