commit 03c02899dcd27c4771b15be227aefe3e86309933
Author: vastja <vastja@students.zcu.cz>
Date:   Thu Apr 30 16:17:12 2020 +0000

    Re #7933
    + základní funkcionalita formulářů v aplikaci - viz. Symfony forms

diff --git a/website/composer.json b/website/composer.json
index 906578b..4696e3b 100644
--- a/website/composer.json
+++ b/website/composer.json
@@ -15,7 +15,8 @@
         "symfony/framework-bundle": "5.0.*",
         "symfony/twig-pack": "*",
         "symfony/yaml": "5.0.*",
-        "symfony/asset": "*"
+        "symfony/asset": "*",
+		"symfony/form" : "*"
     },
     "require-dev": {
         "friendsofphp/php-cs-fixer": "^2.16",
diff --git a/website/config/services.yaml b/website/config/services.yaml
index d318be5..d9387bb 100644
--- a/website/config/services.yaml
+++ b/website/config/services.yaml
@@ -29,5 +29,6 @@ services:
     # add more service definitions when explicit configuration is needed
     # please note that last definitions always *replace* previous ones
 
-    App\OpenData\OpenDataManager: ~      
+    App\OpenData\OpenDataManager: ~
     App\OpenData\IOpenDataManager: '@App\OpenData\OpenDataManager'
+    App\Form\Type\DataSetType: ~
diff --git a/website/public/js/zcu-heatmap.js b/website/public/js/zcu-heatmap.js
index 29822b9..dca05e9 100644
--- a/website/public/js/zcu-heatmap.js
+++ b/website/public/js/zcu-heatmap.js
@@ -1,4 +1,6 @@
 var map;
+var heatmapLayer = null;
+
 var startX = 49.7248;
 var startY = 13.3521;
 var startZoom = 17;
@@ -57,11 +59,11 @@ function animateTimeline() {
     }, 400);
 }
 
+function showHeatmap(route, date) {
 
-function showHeatmap(route) {
   $.ajax({
     type: "POST",
-    url: route,
+    url: route + date,
     success: function(result) {
       drawHeatmap(result);
     }
@@ -70,7 +72,38 @@ function showHeatmap(route) {
 
 
 function drawHeatmap(points) {
+
+  // Todo still switched
   points = points.map(function (p) { return [p['y'], p['x'], p['number']]; });
+  if (heatmapLayer != null) {
+    mymap.removeLayer(heatmapLayer);
+  }
+  heatmapLayer = L.heatLayer(points).addTo(mymap), draw = true; 
+  // var heat_01 = ...
+  // on background map.addLayer(heat_01) -> map.removeLayer(heat_01);
+}
 
-  L.heatLayer(points).addTo(map), draw = true;
-}
\ No newline at end of file
+function checkDataSetsAvailability(route) {
+
+  var parts = $('#date').val().split('-');
+  
+  $.ajax({
+    type: "POST",
+    // Todo it might be good idea to change db collections format
+    url: route + '/' + parts[2] + parts[1] + parts[0],
+    success: function(result) {
+      updateAvailableDataSets(result);
+    }
+  });
+}
+
+function updateAvailableDataSets(available) {
+  
+  var options;
+  for (i = 0; i < available.length; i++) {
+    options += '<options value="' + i + '">' + available[i] + '</option>\n'; 
+  }
+
+  $('#types').empty().append(options);
+  
+}
diff --git a/website/src/Controller/HeatmapController.php b/website/src/Controller/HeatmapController.php
index d3e1aa0..a3ca911 100644
--- a/website/src/Controller/HeatmapController.php
+++ b/website/src/Controller/HeatmapController.php
@@ -2,7 +2,10 @@
 
 namespace App\Controller;
 
+use App\Entity\DataSet;
+use App\Form\Type\DataSetType;
 use App\OpenData\IOpenDataManager;
+use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\Routing\Annotation\Route;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 
@@ -10,8 +13,26 @@ class HeatmapController extends AbstractController {
     /**
      * @Route("/heatmap", name="heatmap")
      */
-    public function index() {
-        return $this->render('heatmap.html.twig');
+    public function index(Request $request) {
+        $dataSet = new DataSet();
+
+        $form = $this->createForm(DataSetType::class, $dataSet);
+        $form->handleRequest($request);
+
+        // Todo validation
+        // $form->isValid()
+        $dataSet = $form->getData();
+        if ($form->isSubmitted()) {
+            $dataSet = $form->getData();
+            // Todo do something
+        }
+
+        return $this->render(
+            'heatmap.html.twig',
+            [
+                'form' => $form->createView(),
+            ]
+        );
     }
 
     /**
@@ -20,4 +41,11 @@ class HeatmapController extends AbstractController {
     public function opendata(IOpenDataManager $manager, $collectionName) {
         return $this->json($manager->getCollectionDataByName($collectionName));
     }
+
+    /**
+     * @Route("heatmap/available/{date}", name="available")
+     */
+    public function availableDatasets(IOpenDataManager $manager, $date = '01012020') {
+        return $this->json($manager->getAvailableCollectionsByDay($date));
+    }
 }
diff --git a/website/src/Entity/DataSet.php b/website/src/Entity/DataSet.php
new file mode 100644
index 0000000..4fb7e0c
--- /dev/null
+++ b/website/src/Entity/DataSet.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Entity;
+
+//Todo some checks
+class DataSet {
+    protected $time;
+    protected $date;
+    protected $type;
+
+    public function setTime($time) {
+        $this->time = $time;
+    }
+
+    public function getTime() {
+        return $this->time;
+    }
+
+    public function setDate($date) {
+        $this->date = $date;
+    }
+
+    public function getDate() {
+        return $this->date;
+    }
+
+    public function setType($type) {
+        $this->type = $type;
+    }
+
+    public function getType() {
+        return $this->type;
+    }
+}
diff --git a/website/src/Form/DataSetType.php b/website/src/Form/DataSetType.php
new file mode 100644
index 0000000..e0456b3
--- /dev/null
+++ b/website/src/Form/DataSetType.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace App\Form\Type;
+
+use App\Utils\Utils;
+use App\Entity\DataSet;
+use App\OpenData\IOpenDataManager;
+use Symfony\Component\Form\FormView;
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\FormInterface;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+
+class DataSetType extends AbstractType {
+    private $manager;
+
+    public function __construct(IOpenDataManager $manager) {
+        $this->manager = $manager;
+    }
+
+    public function buildForm(FormBuilderInterface $builder, array $options) {
+        $builder
+            ->add('date', TextType::class)
+            ->add('time', ChoiceType::class, [
+                'choices' => [
+                    '0:00-1:00' => 0,
+                    '1:00-2:00' => 1,
+                    '2:00-3:00' => 2,
+                    '3:00-4:00' => 3,
+                    '4:00-5:00' => 4,
+                    '5:00-6:00' => 5,
+                    '6:00-7:00' => 6,
+                    '7:00-8:00' => 7,
+                    '8:00-9:00' => 8,
+                    '9:00-10:00' => 9,
+                    '10:00-11:00' => 10,
+                    '11:00-12:00' => 11,
+                    '12:00-13:00' => 12,
+                    '13:00-14:00' => 13,
+                    '14:00-15:00' => 14,
+                    '15:00-16:00' => 15,
+                    '16:00-17:00' => 16,
+                    '17:00-18:00' => 17,
+                    '18:00-19:00' => 18,
+                    '19:00-20:00' => 19,
+                    '20:00-21:00' => 20,
+                    '21:00-22:00' => 21,
+                    '22:00-23:00' => 22,
+                    '23:00-0:00' => 23,
+                ],
+            ])
+            ->add('type', ChoiceType::class, [
+                'choices' => Utils::prepareDatasetsNames($this->manager->getAvailableCollections()),
+            ])
+            ->add('submit', SubmitType::class);
+    }
+
+    public function configureOptions(OptionsResolver $resolver) {
+        $resolver->setDefaults([
+            'data_class' => DataSet::class,
+        ]);
+    }
+
+    // public function buildView(FormView $view, Forminterface $form, array $options) {
+
+    // }
+}
diff --git a/website/src/IOpenDataManager.php b/website/src/IOpenDataManager.php
index 6b62fed..02faf82 100644
--- a/website/src/IOpenDataManager.php
+++ b/website/src/IOpenDataManager.php
@@ -4,4 +4,8 @@ namespace App\OpenData;
 
 interface IOpenDataManager {
     public function getCollectionDataByName($name);
+
+    public function getAvailableCollections();
+
+    public function getAvailableCollectionsByDay($date);
 }
diff --git a/website/src/OpenDataManager.php b/website/src/OpenDataManager.php
index 4f31b2f..621ba26 100644
--- a/website/src/OpenDataManager.php
+++ b/website/src/OpenDataManager.php
@@ -25,4 +25,37 @@ class OpenDataManager implements IOpenDataManager {
 
         return $openData->toArray();
     }
+
+    public function getAvailableCollections() {
+        $openData = $this->manager->executeQuery('open-data-db.DATASETS', new Query([], ['projection' => ['name' => 1, '_id' => 0]]));
+
+        $openData->setTypeMap([
+            'array' => 'array',
+            'document' => 'array',
+            'root' => 'array',
+        ]);
+
+        return $openData->toArray();
+    }
+
+    public function getAvailableCollectionsByDay($date) {
+        $availableInDate = [];
+        $available = $this->getAvailableCollections();
+        $index = 0;
+        foreach ($available as $key => $value) {
+            $openData = $this->manager->executeQuery('open-data-db.'.$value['name'].$date, new Query([], []));
+
+            $openData->setTypeMap([
+                'array' => 'array',
+                'document' => 'array',
+                'root' => 'array',
+            ]);
+
+            if (false == empty($openData->toArray())) {
+                $availableInDate[$value['name']] = $index++;
+            }
+        }
+
+        return $availableInDate;
+    }
 }
diff --git a/website/src/Utils/Utils.php b/website/src/Utils/Utils.php
new file mode 100644
index 0000000..53cc920
--- /dev/null
+++ b/website/src/Utils/Utils.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Utils;
+
+class Utils {
+    public static function prepareDatasetsNames($datasets) {
+        $names;
+
+        $index = 0;
+        foreach ($datasets as $key => $value) {
+            $names[$value['name']] = $index++;
+        }
+
+        return $names;
+    }
+}
diff --git a/website/templates/heatmap.html.twig b/website/templates/heatmap.html.twig
index 9b8343b..c386eb5 100644
--- a/website/templates/heatmap.html.twig
+++ b/website/templates/heatmap.html.twig
@@ -21,65 +21,70 @@
       </button>
 
       <div class="collapse navbar-collapse" id="navigation">
-        <form method="get">
+        
+        {{ form_start(form) }}
+
           <ul class="navbar-nav">
             <li class="nav-item">
-              <label for="date">Vyberte datum</label>
-              <input type="date" name="date" id="date" class="form-control" required>
+              {{ form_label(form.date, 'Vyberte datum') }}
+              {{
+                form_widget(form.date,
+                {
+                  'type' : 'date',
+                  'id' : 'date',
+                  'attr' : {
+                    'class' : 'form-control',                 
+                    'onChange' : 'checkDataSetsAvailability("' ~ path('available') ~ '")'
+                  }
+                })
+              }}
             </li>
 
             <li class="nav-item">
-              <label for="hour">Vyberte čas</label>
-              <select name="hour" id="hour" class="custom-select">
-                <option value="0">0:00&ndash;1:00</option>
-                <option value="1">1:00&ndash;2:00</option>
-                <option value="2">2:00&ndash;3:00</option>
-                <option value="3">3:00&ndash;4:00</option>
-                <option value="4">4:00&ndash;5:00</option>
-                <option value="5">5:00&ndash;6:00</option>
-                <option value="6">6:00&ndash;7:00</option>
-                <option value="7">7:00&ndash;8:00</option>
-                <option value="8">8:00&ndash;9:00</option>
-                <option value="9">9:00&ndash;10:00</option>
-                <option value="10">10:00&ndash;11:00</option>
-                <option value="11">11:00&ndash;12:00</option>
-                <option value="12">12:00&ndash;13:00</option>
-                <option value="13">13:00&ndash;14:00</option>
-                <option value="14">14:00&ndash;15:00</option>
-                <option value="15">15:00&ndash;16:00</option>
-                <option value="16">16:00&ndash;17:00</option>
-                <option value="17">17:00&ndash;18:00</option>
-                <option value="18">18:00&ndash;19:00</option>
-                <option value="19">19:00&ndash;20:00</option>
-                <option value="20">20:00&ndash;21:00</option>
-                <option value="21">21:00&ndash;22:00</option>
-                <option value="22">22:00&ndash;23:00</option>
-                <option value="23">23:00&ndash;0:00</option>
-              </select>
+              {{ form_label(form.date, 'Vyberte čas') }}
+              {{
+                form_widget(form.time, {
+                  'attr' : {
+                    'class' : "custom-select"
+                  }
+                })
+              }}             
             </li>
 
             <li class="nav-item">
-              <label for="dataset">Vybrané datové sady</label>
-              <select name="dataset" id="dataset" class="custom-select">
-                <option value="internet">Wi-Fi a drátové připojení</option>
-                <option value="jis">JIS snímače</option>
-                <option value="scoobikes">Koloběžky</option>
-              </select>
+              {{ form_label(form.date, 'Vybrané datové sady') }}
+              {{
+                form_widget(form.type, {
+                  'id' : 'types',
+                  'attr' : {
+                    'class' : "custom-select"                 
+                  }
+                })
+              }}  
             </li>
 
             <li class="nav-item">
-              <button class="btn btn-secondary" type="submit">
-                Potvrdit výběr
-              </button>
+              {{
+                form_widget(form.submit,
+                {
+                  'label' : 'Potvrdit výběr',
+                  'type' : 'submit',
+                  'attr' : {
+                    'class': 'btn btn-secondary'
+                  }
+                })
+              }}
             </li>
 
             <li class="nav-item button">
               <h2>
                 <a href="{{ path('home') }}" class="nav-link">O&nbsp;projektu</a>
               </h2>
-            </li>
-          </ul>
-        </form>
+            </li> 
+          </ul> 
+        
+        {{ form_end(form) }}
+
       </div>
 
       <a href="{{ path('home') }}" class="navbar-button">
@@ -152,14 +157,15 @@
 
 {% block javascripts %}
 
-  <script src="{{ asset('js/jquery-3.4.1.min.js') }}"></script>
-  <script src="{{ asset('js/bootstrap.min.js') }}"></script>
-  <script src="{{ asset('js/leaflet.js') }}"></script>
-  <script src="{{ asset('js/leaflet-heat.js') }}"></script>
-  <script src="{{ asset('js/zcu-heatmap.js') }}"></script>
-  <script>
-      initMap();
-      showHeatmap("{{ path('opendata', {'collectionName':'open-data-db.KOLOBEZKY31102018'}) }}");
-  </script>
+    <script src="{{ asset('js/jquery-3.4.1.min.js') }}"></script>
+    <script src="{{ asset('js/bootstrap.min.js') }}"></script>
+    <script src="{{ asset('js/leaflet.js') }}"></script>
+    <script src="{{ asset('js/leaflet-heat.js') }}"></script>
+    <script src="{{ asset('js/zcu-heatmap.js') }}"></script>
+    <script>
+       initMap();
+       showHeatmap("{{ path('opendata', {'collectionName':'open-data-db.'}) }}", 'KOLOBEZKY31102018');
+    </script>
+
 
 {% endblock %}
\ No newline at end of file
