commit cdaf3e0a57c07aff29f99021b97e58f43e736eb2
Author: Filip Jani <jsem@filek.cz>
Date:   Sat May 25 18:42:06 2019 +0200

    Re #7505 formulář pro editaci dat transliterace
    - vytvořen formulář
    - načítání výchozích hodnot formuláře
    - úprava vzhledu formulářů

diff --git a/app/AdminModule/component/Transliteration/TransliterationDataEditForm.latte b/app/AdminModule/component/Transliteration/TransliterationDataEditForm.latte
new file mode 100644
index 0000000..ad52789
--- /dev/null
+++ b/app/AdminModule/component/Transliteration/TransliterationDataEditForm.latte
@@ -0,0 +1,70 @@
+{ifset $containers}
+    {form form class => 'form'}
+        {foreach $containers as $containerName => $container}
+
+            <div class="card mb-1">
+
+                <h5 class="mb-0">
+                    <a class="btn btn-link" data-toggle="collapse" data-target="#{$containerName}"
+                       aria-expanded="false">
+                        <small>
+                            <span class="fa fa-fw fa-plus"></span>
+                            <span class="fa fa-fw fa-minus"></span>
+                        </small> {$container['title']}
+                    </a>
+                </h5>
+
+                <div id="{$containerName}" class="collapse">
+                    <div class="card-body">
+
+                        {foreach $container as $multiplierName => $multiplier}
+
+                            {if $multiplierName !== 'title'}
+                                {var name = $containerName . '-' . $multiplierName}
+
+                                <div class="card mb-1">
+                                    <h5 class="mb-0">
+                                        <a class="btn btn-link" data-toggle="collapse" data-target="#{$name}"
+                                           aria-expanded="false" onclick="return false;">
+                                            <small>
+                                                <span class="fa fa-fw fa-plus"></span>
+                                                <span class="fa fa-fw fa-minus"></span>
+                                            </small> {$multiplier}
+                                        </a>
+                                    </h5>
+
+                                    <div id="{$name}" class="collapse">
+                                        <div class="card-body">
+                                            <div n:multiplier="$name" n:class="row, mb-2">
+                                                <div class="col-5">
+                                                    <input n:name="\App\Model\Repository\LineRepository::COLUMN_LINE_NUMBER" n:class="form-control, form-control-sm">
+                                                </div>
+                                                <div class="col-5">
+                                                    <input n:name="\App\Model\Repository\LineRepository::COLUMN_TRANSLITERATION" n:class="form-control, form-control-sm">
+                                                </div>
+                                                <div class="col-2">
+                                                    {btnRemove 'class' => 'btn btn-danger btn-sm float-right'}
+                                                </div>
+                                            </div>
+
+                                            {btnCreate $name 'class' => 'btn btn-info btn-sm'}
+                                        </div>
+                                    </div>
+
+                                </div>
+                            {/if}
+
+                        {/foreach}
+
+                    </div>
+                </div>
+            </div>
+        {/foreach}
+
+        <div class="row mt-5">
+            <div class="col-4 offset-8 float-right">
+                {input submit}
+            </div>
+        </div>
+    {/form}
+{/ifset}
\ No newline at end of file
diff --git a/app/AdminModule/component/Transliteration/TransliterationDataEditForm.php b/app/AdminModule/component/Transliteration/TransliterationDataEditForm.php
new file mode 100644
index 0000000..2ba66f3
--- /dev/null
+++ b/app/AdminModule/component/Transliteration/TransliterationDataEditForm.php
@@ -0,0 +1,145 @@
+<?php
+
+
+namespace App\AdminModule\Components;
+
+
+use App\Model\Facade\TransliterationFacade;
+use App\Model\Repository\LineRepository;
+use App\Model\Repository\ObjectTypeRepository;
+use App\Model\Repository\SurfaceTypeRepository;
+use App\Utils\Form;
+use Nette\Application\UI\Control;
+use Nette\Forms\Container;
+use WebChemistry\Forms\Controls\Multiplier;
+
+class TransliterationDataEditForm extends Control
+{
+    /** @var int ID transliterace */
+    private $id;
+
+    /** @var array Pole objektů a typu povrch pro strom dat transliterace */
+    private $containers;
+
+    /**
+     * @var ObjectTypeRepository
+     */
+    private $objectTypeRepository;
+    /**
+     * @var SurfaceTypeRepository
+     */
+    private $surfaceTypeRepository;
+    /**
+     * @var TransliterationFacade
+     */
+    private $transliterationFacade;
+
+    public function __construct(ObjectTypeRepository $objectTypeRepository,
+                                SurfaceTypeRepository $surfaceTypeRepository,
+                                TransliterationFacade $transliterationFacade
+    )
+    {
+        parent::__construct();
+
+        $this->objectTypeRepository = $objectTypeRepository;
+        $this->surfaceTypeRepository = $surfaceTypeRepository;
+        $this->transliterationFacade = $transliterationFacade;
+
+        $objectTypes = $this->objectTypeRepository->fetchObjectTypes();
+        $surfaceTypes = $this->surfaceTypeRepository->fetchSurfaceTypes();
+        $containers = [];
+
+        // Načtení typů objektů a typu povrchů do pole pro vykreslení v šabloně
+        foreach ($objectTypes as $objectType)
+        {
+            $containers[$this->transliterationFacade->getInputName($objectType)]['title'] = $objectType;
+
+            foreach ($surfaceTypes as $surfaceType)
+            {
+                $containers[$this->transliterationFacade->getInputName($objectType)][$this->transliterationFacade->getInputName($objectType, $surfaceType)] = $surfaceType;
+            }
+        }
+
+        $this->containers = $containers;
+    }
+
+    public function render()
+    {
+        $this->template->setFile(__DIR__ . '/TransliterationDataEditForm.latte');
+
+        $this->template->containers = $this->containers;
+
+        $this->template->render();
+    }
+
+    public function createComponentForm()
+    {
+        $form = new Form;
+
+        foreach ($this->containers as $name => $container)
+        {
+            $cont = $form->addContainer($name);
+
+            foreach ($container as $nameMultiplier => $multiplier)
+            {
+                if ($nameMultiplier === 'title')
+                {
+                    continue;
+                }
+
+                /** @var Multiplier $multiplier */
+                $multiplier = $cont->addMultiplier($nameMultiplier, function (Container $container)
+                {
+                    $container->addInteger(LineRepository::COLUMN_LINE_NUMBER);
+                    $container->addText(LineRepository::COLUMN_TRANSLITERATION);
+                }, 0);
+
+                $multiplier->addCreateButton('Add line')->setValidationScope([])->addClass('btn btn-primary');
+                $multiplier->addRemoveButton('Delete')->addClass('btn btn-danger');
+            }
+        }
+
+        $form->setDefaults($this->getDefaults());
+
+        $form->onSuccess[] = [$this, 'formSuccess'];
+        $form->addSubmit('submit', 'Save');
+
+        return $form;
+    }
+
+    public function formSuccess(Form $form)
+    {
+
+    }
+
+    /**
+     * Nastavení ID právě upravované transliterace
+     *
+     * @param int $id
+     */
+    public function setTransliteration(int $id)
+    {
+        $this->id = $id;
+    }
+
+    /**
+     * Vrací hodnoty formuláře při editaci
+     *
+     * @return array
+     */
+    private function getDefaults()
+    {
+        if (isset($this->id))
+        {
+            return $this->transliterationFacade->getTransliterationData($this->id);
+        }
+    }
+}
+
+interface ITransliterationDataEditFormFactory
+{
+    /**
+     * @return TransliterationDataEditForm
+     */
+    public function create();
+}
\ No newline at end of file
diff --git a/app/AdminModule/component/Transliteration/TransliterationEditForm.latte b/app/AdminModule/component/Transliteration/TransliterationEditForm.latte
index d4c1261..8254aeb 100644
--- a/app/AdminModule/component/Transliteration/TransliterationEditForm.latte
+++ b/app/AdminModule/component/Transliteration/TransliterationEditForm.latte
@@ -1,6 +1,6 @@
 {form form}
     <div class="row">
-        <div class="col-4">
+        <div class="col-12">
             <div class="row mb-2">
                 <div class="col-4">
                     {label \App\Model\Repository\TransliterationRepository::COLUMN_BOOK_ID}
@@ -91,18 +91,18 @@
             <div n:multiplier="references">
                 <div class="row mb-2">
 
-                    <div class="col-2">
+                    <div class="col-3">
                         <input n:name="\App\Model\Repository\LitReferenceRepository::COLUMN_SERIES" n:class="form-control"
                                 required></div>
 
-                    <div class="col-2">
+                    <div class="col-3">
                         <input n:name="\App\Model\Repository\LitReferenceRepository::COLUMN_NUMBER" n:class="form-control">
                     </div>
 
-                    <div class="col-2">
+                    <div class="col-3">
                         <input n:name="\App\Model\Repository\LitReferenceRepository::COLUMN_PLATE" n:class="form-control">
                     </div>
-                    <div class="col-2">{btnRemove 'class' => 'btn btn-danger'}</div>
+                    <div class="col-2">{btnRemove 'class' => 'btn btn-danger float-right'}</div>
                 </div>
             </div>
 
@@ -111,7 +111,7 @@
     </div>
 
     <div class="row mt-5">
-        <div class="col-4">
+        <div class="col-4 offset-8 float-right">
             {input submit}
         </div>
     </div>
diff --git a/app/AdminModule/presenters/TransliterationPresenter.php b/app/AdminModule/presenters/TransliterationPresenter.php
index fb7f546..3d6baa9 100644
--- a/app/AdminModule/presenters/TransliterationPresenter.php
+++ b/app/AdminModule/presenters/TransliterationPresenter.php
@@ -4,6 +4,7 @@
 namespace App\AdminModule\Presenters;
 
 
+use App\AdminModule\Components\ITransliterationDataEditFormFactory;
 use App\AdminModule\Components\ITransliterationGridFactory;
 use App\AdminModule\Components\ITransliterationEditFormFactory;
 use App\Model\Repository\TransliterationRepository;
@@ -25,14 +26,22 @@ class TransliterationPresenter extends BaseUserPresenter
      */
     private $transliterationRepository;
 
+    /**
+     * @var ITransliterationDataEditFormFactory
+     */
+    private $transliterationDataEditFormFactory;
+
     public function __construct(ITransliterationGridFactory $transliterationGridFactory,
                                 ITransliterationEditFormFactory $transliterationEditFormFactory,
-                                TransliterationRepository $transliterationRepository)
+                                TransliterationRepository $transliterationRepository,
+                                ITransliterationDataEditFormFactory $transliterationDataEditFormFactory
+    )
     {
         parent::__construct();
         $this->transliterationEditFormFactory = $transliterationEditFormFactory;
         $this->transliterationGridFactory = $transliterationGridFactory;
         $this->transliterationRepository = $transliterationRepository;
+        $this->transliterationDataEditFormFactory = $transliterationDataEditFormFactory;
     }
 
     /**
@@ -57,6 +66,7 @@ class TransliterationPresenter extends BaseUserPresenter
     public function actionEdit(int $id)
     {
         $this['transliterationEditForm']->setTransliteration($id);
+        $this['transliterationDataEditForm']->setTransliteration($id);
     }
 
     public function createComponentTransliterationGrid()
@@ -69,4 +79,9 @@ class TransliterationPresenter extends BaseUserPresenter
         return $this->transliterationEditFormFactory->create();
     }
 
+    public function createComponentTransliterationDataEditForm()
+    {
+        return  $this->transliterationDataEditFormFactory->create();
+    }
+
 }
\ No newline at end of file
diff --git a/app/AdminModule/templates/@layout.latte b/app/AdminModule/templates/@layout.latte
index e3cb3eb..2054723 100644
--- a/app/AdminModule/templates/@layout.latte
+++ b/app/AdminModule/templates/@layout.latte
@@ -39,6 +39,7 @@
           integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous">
 
     <link rel="stylesheet" href="{$basePath}/css/admin/style.css">
+    <link rel="stylesheet" href="{$basePath}/css/common.css">
 
     <script src="https://nette.github.io/resources/js/netteForms.min.js"></script>
     <script src="{$basePath}/js/nette.ajax.js"></script>
diff --git a/app/AdminModule/templates/Transliteration/edit.latte b/app/AdminModule/templates/Transliteration/edit.latte
index 4902b29..e9116ec 100644
--- a/app/AdminModule/templates/Transliteration/edit.latte
+++ b/app/AdminModule/templates/Transliteration/edit.latte
@@ -1,8 +1,30 @@
 {block content}
     <div class="row">
-        <div class="col-12">
+        <div class="col-5">
             <div class="display-5">Edit Transliteration</div>
+
+            <fieldset>
+                <legend>Transliteration information</legend>
+
+                {control transliterationEditForm}
+            </fieldset>
         </div>
     </div>
-    {control transliterationEditForm}
-{/block}
\ No newline at end of file
+
+    <div class="row mt-5">
+        <div class="col-5">
+            <fieldset>
+                <legend>Transliteration data</legend>
+
+                {control transliterationDataEditForm}
+            </fieldset>
+        </div>
+    </div>
+{/block}
+
+{block scripts}
+<script>
+    $(function () {
+        $.nette.init();
+    });
+</script>
\ No newline at end of file
diff --git a/app/FrontModule/templates/@layout.latte b/app/FrontModule/templates/@layout.latte
index d3ee7db..24a3735 100644
--- a/app/FrontModule/templates/@layout.latte
+++ b/app/FrontModule/templates/@layout.latte
@@ -39,6 +39,7 @@
           integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous">
 
     <link rel="stylesheet" href="{$basePath}/css/front/style.css">
+    <link rel="stylesheet" href="{$basePath}/css/common.css">
 
     <script src="https://nette.github.io/resources/js/netteForms.min.js"></script>
     <script src="{$basePath}/js/nette.ajax.js"></script>
diff --git a/app/config/components.neon b/app/config/components.neon
index 62e9cb2..02309d4 100644
--- a/app/config/components.neon
+++ b/app/config/components.neon
@@ -21,6 +21,7 @@ services:
     - App\AdminModule\Components\IBookTypeEditFormFactory
     - App\AdminModule\Components\IBookEditFormFactory
     - App\AdminModule\Components\ITransliterationEditFormFactory
+    - App\AdminModule\Components\ITransliterationDataEditFormFactory
 
     - App\FrontModule\Components\IKeyboard
     - App\FrontModule\Components\ITransliterationSearchResultListFactory
\ No newline at end of file
diff --git a/app/config/model.neon b/app/config/model.neon
index 63cc685..e385582 100644
--- a/app/config/model.neon
+++ b/app/config/model.neon
@@ -19,6 +19,7 @@ services:
 
     #Facade
     - App\Model\Facade\UserFacade
+    - App\Model\Facade\TransliterationFacade
 
     #Sessions
     - App\Model\TransliterationSearchModel
\ No newline at end of file
diff --git a/app/model/facade/TransliterationFacade.php b/app/model/facade/TransliterationFacade.php
new file mode 100644
index 0000000..f29ade3
--- /dev/null
+++ b/app/model/facade/TransliterationFacade.php
@@ -0,0 +1,104 @@
+<?php
+
+
+namespace App\Model\Facade;
+
+
+use App\Model\Repository\LineRepository;
+use App\Model\Repository\ObjectTypeRepository;
+use App\Model\Repository\SurfaceRepository;
+use App\Model\Repository\SurfaceTypeRepository;
+use Nette\Database\Table\ActiveRow;
+
+class TransliterationFacade
+{
+    /**
+     * @var SurfaceRepository
+     */
+    private $surfaceRepository;
+    /**
+     * @var LineRepository
+     */
+    private $lineRepository;
+    /**
+     * @var ObjectTypeRepository
+     */
+    private $objectTypeRepository;
+    /**
+     * @var SurfaceTypeRepository
+     */
+    private $surfaceTypeRepository;
+
+    public function __construct(SurfaceRepository $surfaceRepository,
+                                LineRepository $lineRepository,
+                                ObjectTypeRepository $objectTypeRepository,
+                                SurfaceTypeRepository $surfaceTypeRepository
+    )
+    {
+        $this->surfaceRepository = $surfaceRepository;
+        $this->lineRepository = $lineRepository;
+        $this->objectTypeRepository = $objectTypeRepository;
+        $this->surfaceTypeRepository = $surfaceTypeRepository;
+    }
+
+    /**
+     * Uloží data transliterace
+     *
+     * @param int $id
+     * @param array $values
+     */
+    public function saveTransliterationData(int $id, array $values)
+    {
+
+    }
+
+    /**
+     * Vrací data transliterace pro formulář
+     *
+     * @param int $id : ID transliterace
+     * @return array
+     */
+    public function getTransliterationData(int $id)
+    {
+        $surfaces = $this->surfaceRepository->findByTransliterationId($id)->fetchAll();
+
+        $surfaceTypes = $this->surfaceTypeRepository->fetchSurfaceTypes();
+        $objectTypes = $this->objectTypeRepository->fetchObjectTypes();
+
+        $defaults = array();
+
+        /** @var ActiveRow $surface */
+        foreach ($surfaces as $surface)
+        {
+            // Načtení všech řádek
+            $lineRows = $surface->related(LineRepository::TABLE_NAME, SurfaceRepository::COLUMN_ID)->fetchAll();
+            if ($lineRows === FALSE)
+            {
+                continue;
+            }
+
+            // Získání názvu typu povrchu a typu objektu
+            $surfaceType = $surfaceTypes[$surface->{SurfaceRepository::COLUMN_SURFACE_TYPE_ID}];
+            $objectType = $objectTypes[$surface->{SurfaceRepository::COLUMN_OBJECT_TYPE_ID}];
+
+            $objectName = $this->getInputName($objectType);
+            $surfaceName = $this->getInputName($objectType, $surfaceType);
+
+            $defaults[$objectName][$surfaceName] = $lineRows;
+        }
+
+        return $defaults;
+    }
+
+    /**
+     * Vrací název inputu pro formulář
+     *
+     * @param string $container
+     * @param string|NULL $name
+     * @return string
+     */
+    public function getInputName(string $container, string $name = NULL)
+    {
+        return str_replace(' ', '', $container) . str_replace(' ', '', $name);
+    }
+}
\ No newline at end of file
diff --git a/app/model/repository/ObjectTypeRepository.php b/app/model/repository/ObjectTypeRepository.php
index 3a1e3f8..b35f41b 100644
--- a/app/model/repository/ObjectTypeRepository.php
+++ b/app/model/repository/ObjectTypeRepository.php
@@ -16,4 +16,14 @@ class ObjectTypeRepository extends Repository
     /** Sloupečky tabulky */
     const COLUMN_ID = 'id_object_type';
     const COLUMN_OBJECT_TYPE = 'object_type';
+
+    /**
+     * Vrací typy objektů pro formulář pro přidávání transliterací
+     *
+     * @return array
+     */
+    public function fetchObjectTypes()
+    {
+        return $this->findAll()->fetchPairs(self::COLUMN_ID, self::COLUMN_OBJECT_TYPE);
+    }
 }
\ No newline at end of file
diff --git a/app/model/repository/SurfaceRepository.php b/app/model/repository/SurfaceRepository.php
index cfbdec2..88409f1 100644
--- a/app/model/repository/SurfaceRepository.php
+++ b/app/model/repository/SurfaceRepository.php
@@ -19,4 +19,15 @@ class SurfaceRepository extends Repository
     const COLUMN_TRANSLITERATION_ID = 'id_transliteration';
     const COLUMN_OBJECT_TYPE_ID = 'id_object_type';
     const COLUMN_SURFACE_TYPE_ID = 'id_surface_type';
+
+    /**
+     * Vrací povrchy podle ID transliterace
+     *
+     * @param int $id : ID transliterace
+     * @return \Nette\Database\Table\Selection
+     */
+    public function findByTransliterationId(int $id)
+    {
+        return $this->findBy([self::COLUMN_TRANSLITERATION_ID => $id]);
+    }
 }
\ No newline at end of file
diff --git a/app/model/repository/SurfaceTypeRepository.php b/app/model/repository/SurfaceTypeRepository.php
index d5655cf..4f6b055 100644
--- a/app/model/repository/SurfaceTypeRepository.php
+++ b/app/model/repository/SurfaceTypeRepository.php
@@ -17,4 +17,14 @@ class SurfaceTypeRepository extends Repository
     const COLUMN_ID = 'id_surface_type';
     const COLUMN_SURFACE_TYPE = 'surface_type';
     const COLUMN_SORTER = 'sorter';
+
+    /**
+     * Vrací typy povrchů pro formulář pro přidávání transliterací
+     *
+     * @return array
+     */
+    public function fetchSurfaceTypes()
+    {
+        return $this->findAll()->order(self::COLUMN_SORTER)->fetchPairs(self::COLUMN_ID, self::COLUMN_SURFACE_TYPE);
+    }
 }
\ No newline at end of file
diff --git a/app/utils/Form.php b/app/utils/Form.php
index 57059c6..de8a0ae 100644
--- a/app/utils/Form.php
+++ b/app/utils/Form.php
@@ -29,37 +29,37 @@ class Form extends \Nette\Application\UI\Form
 
     public function addText($name, $label = null, $cols = null, $maxLength = null)
     {
-        return parent::addText($name, $label, $cols, $maxLength)->setHtmlAttribute('class', 'form-control');
+        return parent::addText($name, $label, $cols, $maxLength)->setHtmlAttribute('class', 'form-control form-control-sm');
     }
 
     public function addSelect($name, $label = null, array $items = null, $size = null)
     {
-        return parent::addSelect($name, $label, $items, $size)->setHtmlAttribute('class', 'form-control');
+        return parent::addSelect($name, $label, $items, $size)->setHtmlAttribute('class', 'form-control form-control-sm');
     }
 
     public function addPassword($name, $label = null, $cols = null, $maxLength = null)
     {
-        return parent::addPassword($name, $label, $cols, $maxLength)->setHtmlAttribute('class', 'form-control');
+        return parent::addPassword($name, $label, $cols, $maxLength)->setHtmlAttribute('class', 'form-control form-control-sm');
     }
 
     public function addEmail($name, $label = null)
     {
-        return parent::addEmail($name, $label)->setHtmlAttribute('class', 'form-control');
+        return parent::addEmail($name, $label)->setHtmlAttribute('class', 'form-control form-control-sm');
     }
 
     public function addTextArea($name, $label = null, $cols = null, $rows = null)
     {
-        return parent::addTextArea($name, $label, $cols, $rows)->setHtmlAttribute('class', 'form-control');
+        return parent::addTextArea($name, $label, $cols, $rows)->setHtmlAttribute('class', 'form-control form-control-sm');
     }
 
     public function addUpload($name, $label = null, $multiple = false)
     {
-        return parent::addUpload($name, $label, $multiple)->setHtmlAttribute('class', 'form-control');
+        return parent::addUpload($name, $label, $multiple)->setHtmlAttribute('class', 'form-control form-control-sm');
     }
 
     public function addInteger($name, $label = null)
     {
-        return parent::addInteger($name, $label)->setHtmlAttribute('class', 'form-control');
+        return parent::addInteger($name, $label)->setHtmlAttribute('class', 'form-control form-control-sm');
     }
 
     protected function beforeRender()
@@ -71,7 +71,7 @@ class Form extends \Nette\Application\UI\Form
             $type = $control->getOption('type');
             if ($type === 'button')
             {
-                $control->getControlPrototype()->addClass('btn btn-success form-control');
+                $control->getControlPrototype()->addClass('btn btn-success btn-sm form-control');
             }
         }
     }
diff --git a/www/css/common.css b/www/css/common.css
new file mode 100644
index 0000000..0b495e1
--- /dev/null
+++ b/www/css/common.css
@@ -0,0 +1,30 @@
+fieldset
+{
+    border: 1px solid #ddd !important;
+    margin: 0;
+    xmin-width: 0;
+    padding: 10px;
+    position: relative;
+    border-radius:4px;
+    background-color:#f5f5f5;
+    padding-left:10px!important;
+}
+
+legend
+{
+    font-size:14px;
+    font-weight:bold;
+    margin-bottom: 0px;
+    width: 35%;
+    border: 1px solid #ddd;
+    border-radius: 4px;
+    padding: 5px 5px 5px 10px;
+    background-color: #ffffff;
+}
+
+a[aria-expanded=true] .fa-plus {
+    display: none;
+}
+a[aria-expanded=false] .fa-minus {
+    display: none;
+}
