Browse Source

Merge branch 'feature/new_structures_search_frame' into develop

Conflicts:
	ot_templating/Resources/Public/assets/Classic/style/classic-blue.css
	ot_templating/Resources/Public/assets/Classic/style/classic-blue.css.map
	ot_templating/Resources/Public/assets/Classic/style/classic-green.css
	ot_templating/Resources/Public/assets/Classic/style/classic-green.css.map
	ot_templating/Resources/Public/assets/Classic/style/classic-grey.css
	ot_templating/Resources/Public/assets/Classic/style/classic-grey.css.map
	ot_templating/Resources/Public/assets/Classic/style/classic-light-blue.css
	ot_templating/Resources/Public/assets/Classic/style/classic-light-blue.css.map
	ot_templating/Resources/Public/assets/Classic/style/classic-light-red.css
	ot_templating/Resources/Public/assets/Classic/style/classic-light-red.css.map
	ot_templating/Resources/Public/assets/Classic/style/classic-orange.css
	ot_templating/Resources/Public/assets/Classic/style/classic-orange.css.map
	ot_templating/Resources/Public/assets/Classic/style/classic-purple.css
	ot_templating/Resources/Public/assets/Classic/style/classic-purple.css.map
	ot_templating/Resources/Public/assets/Classic/style/classic-red.css
	ot_templating/Resources/Public/assets/Classic/style/classic-red.css.map
Olivier Massot 4 years ago
parent
commit
bbfd0de53b
60 changed files with 2482 additions and 198 deletions
  1. 8 0
      doc/shared_frames.md
  2. 430 0
      ot_core/Classes/Domain/Model/FederationStructure.php
  3. 3 0
      ot_core/Classes/Domain/Repository/ApiPagedCollection.php
  4. 74 0
      ot_core/Classes/Domain/Repository/FederationStructureRepository.php
  5. 0 63
      ot_core/Classes/Middleware/Frontend/OtSiteResolver.php
  6. 1 1
      ot_core/Classes/Service/OpentalentApiService.php
  7. 5 0
      ot_core/Classes/ViewHelpers/OtAbstractViewHelper.php
  8. 80 0
      ot_templating/Classes/ViewHelpers/Organizations/AsGeoMarkersArrayViewHelper.php
  9. 102 0
      ot_templating/Classes/ViewHelpers/Organizations/GetChildFederationViewHelper.php
  10. 138 0
      ot_templating/Classes/ViewHelpers/Organizations/GetFederationStructuresViewHelper.php
  11. 101 0
      ot_templating/Classes/ViewHelpers/PaginationViewHelper.php
  12. 73 0
      ot_templating/Classes/ViewHelpers/Utilities/PaginateArrayViewHelper.php
  13. 58 0
      ot_templating/Classes/ViewHelpers/Utilities/RangeViewHelper.php
  14. 64 1
      ot_templating/Resources/Private/Language/locallang.xlf
  15. 1 1
      ot_templating/Resources/Private/Layouts/Classic/Structures.html
  16. 1 1
      ot_templating/Resources/Private/Layouts/Classic/StructuresEvents.html
  17. 101 0
      ot_templating/Resources/Private/Layouts/Classic/StructuresFrame.html
  18. 2 2
      ot_templating/Resources/Private/Layouts/Modern/Structures.html
  19. 1 1
      ot_templating/Resources/Private/Layouts/Modern/StructuresEvents.html
  20. 14 0
      ot_templating/Resources/Private/Partials/Classic/Assets.html
  21. 1 1
      ot_templating/Resources/Private/Partials/Classic/EventsIndex.html
  22. 0 22
      ot_templating/Resources/Private/Partials/Classic/Pagination.html
  23. 1 1
      ot_templating/Resources/Private/Partials/Modern/EventsIndex.html
  24. 0 22
      ot_templating/Resources/Private/Partials/Modern/Pagination.html
  25. 18 0
      ot_templating/Resources/Private/Templates/Page/StructuresFrame.html
  26. 0 0
      ot_templating/Resources/Public/assets/Classic/script/leaflet.markercluster.js
  27. 32 26
      ot_templating/Resources/Public/assets/Classic/script/main.js
  28. 586 0
      ot_templating/Resources/Public/assets/Classic/script/structures.js
  29. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-blue.css
  30. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-blue.css.map
  31. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-green.css
  32. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-green.css.map
  33. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-grey.css
  34. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-grey.css.map
  35. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-light-blue.css
  36. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-light-blue.css.map
  37. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-light-red.css
  38. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-light-red.css.map
  39. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-orange.css
  40. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-orange.css.map
  41. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-purple.css
  42. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-purple.css.map
  43. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-red.css
  44. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-red.css.map
  45. 60 0
      ot_templating/Resources/Public/assets/Classic/style/ext/MarkerCluster.Default.css
  46. 14 0
      ot_templating/Resources/Public/assets/Classic/style/ext/MarkerCluster.css
  47. 1 1
      ot_templating/Resources/Public/assets/Classic/style/module/_menu.scss
  48. 4 0
      ot_templating/Resources/Public/assets/Classic/style/module/_pagination.scss
  49. 452 0
      ot_templating/Resources/Public/assets/Classic/style/module/_structures.scss
  50. 0 0
      ot_templating/Resources/Public/assets/Classic/style/style.css
  51. 0 0
      ot_templating/Resources/Public/assets/Classic/style/style.css.map
  52. 53 53
      ot_templating/Resources/Public/assets/Modern/fonts/revicons.svg
  53. 3 2
      ot_templating/Resources/Public/assets/Modern/style/custom.css
  54. BIN
      ot_templating/Resources/Public/media/gear.gif
  55. BIN
      ot_templating/Resources/Public/media/guadeloupe.png
  56. BIN
      ot_templating/Resources/Public/media/guyane.png
  57. BIN
      ot_templating/Resources/Public/media/la_reunion.png
  58. BIN
      ot_templating/Resources/Public/media/martinique.png
  59. BIN
      ot_templating/Resources/Public/media/mayotte.png
  60. BIN
      ot_templating/Resources/Public/media/metropole.png

+ 8 - 0
doc/shared_frames.md

@@ -0,0 +1,8 @@
+
+# Frames partagées
+
+Certains cadres sont partagés entre différents templates ou utilisés en tant qu'iframes par des
+sites externes.
+
+Exemple: la recherche des structures adhérentes à une fédération.
+

+ 430 - 0
ot_core/Classes/Domain/Model/FederationStructure.php

@@ -0,0 +1,430 @@
+<?php
+namespace Opentalent\OtCore\Domain\Model;
+
+use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
+
+/**
+ * FederationStructure
+ *
+ * Similar to the Organization object, this entity is created from the federation_structures api route,
+ * which is designed to return the structures belonging to a federation
+ */
+class FederationStructure extends AbstractEntity
+{
+    /**
+     * id
+     *
+     * @var int
+     */
+    protected $id;
+
+    /**
+     * name
+     *
+     * @var string
+     */
+    protected $name;
+
+    /**
+     * principalType
+     *
+     * @var string
+     */
+    protected $principalType;
+
+    /**
+     * website
+     *
+     * @var string
+     */
+    protected $website;
+
+    /**
+     * addressCity
+     *
+     * @var string
+     */
+    protected $addressCity;
+
+    /**
+     * postalCode
+     *
+     * @var string
+     */
+    protected $postalCode;
+
+    /**
+     * streetAdress
+     *
+     * @var string
+     */
+    protected $streetAddress;
+
+    /**
+     * latitude
+     *
+     * @var float
+     */
+    protected $latitude;
+
+    /**
+     * longitude
+     *
+     * @var float
+     */
+    protected $longitude;
+
+    /**
+     * country
+     *
+     * @var string
+     */
+    protected $country;
+
+    /**
+     * categories
+     *
+     * @var array
+     */
+    protected $categories;
+
+    /**
+     * logo
+     *
+     * @var string
+     */
+    protected $logoUri;
+
+    /**
+     * parent_name
+     *
+     * @var int
+     */
+    protected $parentId;
+
+    /**
+     * parent_name
+     *
+     * @var string
+     */
+    protected $parentName;
+
+    /**
+     * parents
+     *
+     * @var string
+     */
+    protected $parents;
+
+    /**
+     * Returns the id
+     *
+     * @return int $id
+     */
+    public function getId(): int
+    {
+        return $this->id;
+    }
+
+    /**
+     * Sets the id
+     *
+     * @param int $id
+     * @return void
+     */
+    public function setId(int $id)
+    {
+        $this->id = $id;
+    }
+
+    /**
+     * Returns the name
+     *
+     * @return string $name
+     */
+    public function getName(): ?string
+    {
+        return $this->name;
+    }
+
+    /**
+     * Sets the name
+     *
+     * @param string|null $name
+     * @return void
+     */
+    public function setName(?string $name)
+    {
+        $this->name = $name;
+    }
+
+    /**
+     * Returns the principalType
+     *
+     * @return string $principalType
+     */
+    public function getPrincipalType(): ?string
+    {
+        return $this->principalType;
+    }
+
+    /**
+     * Sets the principalType
+     *
+     * @param string|null $principalType
+     * @return void
+     */
+    public function setPrincipalType(?string $principalType)
+    {
+        $this->principalType = $principalType;
+    }
+
+    /**
+     * Returns the website
+     *
+     * @return string $website
+     */
+    public function getWebsite(): ?string
+    {
+        return $this->website;
+    }
+
+    /**
+     * Sets the website
+     *
+     * @param string|null $website
+     * @return void
+     */
+    public function setWebsite(?string $website)
+    {
+        $this->website = $website;
+    }
+
+    /**
+     * Returns the addressCity
+     *
+     * @return string $addressCity
+     */
+    public function getAddressCity(): ?string
+    {
+        return $this->addressCity;
+    }
+
+    /**
+     * Sets the addressCity
+     *
+     * @param string|null $addressCity
+     * @return void
+     */
+    public function setAddressCity(?string $addressCity)
+    {
+        $this->addressCity = $addressCity;
+    }
+
+    /**
+     * Returns the postalCode
+     *
+     * @return string $postalCode
+     */
+    public function getPostalCode(): ?string
+    {
+        return $this->postalCode;
+    }
+
+    /**
+     * Sets the postalCode
+     *
+     * @param string|null $postalCode
+     * @return void
+     */
+    public function setPostalCode(?string $postalCode)
+    {
+        $this->postalCode = $postalCode;
+    }
+
+    /**
+     * Returns the streetAddress
+     *
+     * @return string $streetAddress
+     */
+    public function getStreetAddress(): ?string
+    {
+        return $this->streetAddress;
+    }
+
+    /**
+     * Sets the streetAdress
+     *
+     * @param string|null $streetAddress
+     * @return void
+     */
+    public function setStreetAddress(?string $streetAddress)
+    {
+        $this->streetAddress = $streetAddress;
+    }
+
+    /**
+     * Returns the latitude
+     *
+     * @return float $latitude
+     */
+    public function getLatitude(): ?float
+    {
+        return $this->latitude;
+    }
+
+    /**
+     * Sets the latitude
+     *
+     * @param float|null $latitude
+     */
+    public function setLatitude(?float $latitude)
+    {
+        $this->latitude = $latitude;
+    }
+
+    /**
+     * Returns the longitude
+     *
+     * @return float $longitude
+     */
+    public function getLongitude(): ?float
+    {
+        return $this->longitude;
+    }
+
+    /**
+     * Sets the longitude
+     *
+     * @param float|null $longitude
+     */
+    public function setLongitude(?float $longitude)
+    {
+        $this->longitude = $longitude;
+    }
+
+    /**
+     * Returns the country
+     *
+     * @return string $country
+     */
+    public function getCountry(): ?string
+    {
+        return $this->country;
+    }
+
+    /**
+     * Sets the country
+     *
+     * @param string|null $country
+     * @return void
+     */
+    public function setCountry(?string $country)
+    {
+        $this->country = $country;
+    }
+
+    /**
+     * Returns the categories
+     *
+     * @return array|null $categories
+     */
+    public function getCategories(): ?array
+    {
+        return $this->categories;
+    }
+
+    /**
+     * Sets the categories
+     *
+     * @param array|null $categories
+     */
+    public function setCategories(?array $categories)
+    {
+        $this->categories = $categories;
+    }
+
+    /**
+     * Returns the logo
+     *
+     * @return string $logoUri
+     */
+    public function getLogoUri(): ?string
+    {
+        return $this->logoUri;
+    }
+
+    /**
+     * Sets the logo
+     *
+     * @param string|null $logoUri
+     * @return void
+     */
+    public function setLogoUri(?string $logoUri)
+    {
+        $this->logoUri = $logoUri;
+    }
+
+    /**
+     * Returns the parent name
+     *
+     * @return string $parentId
+     */
+    public function getParentId(): ?string
+    {
+        return $this->parentId;
+    }
+
+    /**
+     * Sets the parent id
+     *
+     * @param string|null $parent_name
+     * @return void
+     */
+    public function setParentId(?string $parentId)
+    {
+        $this->parentId = $parentId;
+    }
+
+    /**
+     * Returns the parent name
+     *
+     * @return string $parentName
+     */
+    public function getParentName(): ?string
+    {
+        return $this->parentName;
+    }
+
+    /**
+     * Sets the parent name
+     *
+     * @param string|null $parentName
+     * @return void
+     */
+    public function setParentName(?string $parentName)
+    {
+        $this->parentName = $parentName;
+    }
+
+    /**
+     * Returns the parents
+     *
+     * @return string $parents
+     */
+    public function getParents(): ?string
+    {
+        return $this->parents;
+    }
+
+    /**
+     * Sets the parents
+     *
+     * @param string|null $parents
+     * @return void
+     */
+    public function setParents(?string $parents)
+    {
+        $this->parents = $parents;
+    }
+}

+ 3 - 0
ot_core/Classes/Domain/Repository/ApiPagedCollection.php

@@ -66,6 +66,9 @@ class ApiPagedCollection
      * @return int
      */
     public function getLastPage() {
+        if (!$this->getItemsPerPage() > 0) {
+            return 1;
+        }
         $nb = intdiv($this->getTotalItems(), $this->getItemsPerPage());
         if ($this->getTotalItems() % $this->getItemsPerPage() != 0) {
             $nb += 1;

+ 74 - 0
ot_core/Classes/Domain/Repository/FederationStructureRepository.php

@@ -0,0 +1,74 @@
+<?php
+
+namespace Opentalent\OtCore\Domain\Repository;
+
+use GuzzleHttp\Exception\GuzzleException;
+use Opentalent\OtCore\Domain\Model\FederationStructure;
+use Opentalent\OtCore\Domain\Model\Organization;
+use Opentalent\OtCore\Exception\ApiRequestException;
+
+/**
+ * Class FederationStructureRepository
+ * @package Opentalent\OtCore\Domain\Repository
+ *
+ */
+class FederationStructureRepository extends BaseApiRepository
+{
+    const URI_TRAILING_PART = '/api/public/federation_structures';
+    const HYDRA_TYPE = 'PortailFederationStructure';
+
+    /**
+     * Get the organization's child structures by id
+     *
+     * @param int $id The id of the organization
+     * @param array $searchParams An array of parameters which will be passed to the Api request as URI parameters
+     * @param int $page
+     * @return ApiPagedCollection
+     * @throws ApiRequestException
+     */
+    public function findChildrenById(int $id, $searchParams = [], $page = 1, $depth = 5): ApiPagedCollection
+    {
+        $params = [];
+        $params['parent'] = $id;
+        $params['page'] = $page;
+        $params['depth'] = $depth;
+
+        $params = array_merge($params, $searchParams);
+
+        return $this->getApiRecords($params);
+    }
+
+    /**
+     * Returns an Organization object from an Api record
+     *
+     * @param array $record
+     * @return FederationStructure|null
+     */
+    protected function memberToObject(array $record) {
+        if ($record['@type'] != $this::HYDRA_TYPE) {
+            return null;
+        }
+
+        $federationStructure = new FederationStructure();
+        $a = explode('/', $record['@id']);
+        $federationStructure->setId(end($a));
+        $federationStructure->setName($record['name']);
+        $federationStructure->setPrincipalType($record['principalType']);
+        $federationStructure->setWebsite($record['website']);
+        $federationStructure->setAddressCity($record['addressCity']);
+        $federationStructure->setPostalCode($record['postalCode']);
+        $federationStructure->setStreetAddress($record['streetAddress']);
+        $federationStructure->setLatitude($record['latitude']);
+        $federationStructure->setLongitude($record['longitude']);
+        $federationStructure->setCountry($record['country']);
+        $federationStructure->setCategories($record['categories']);
+        if ($record['logoId']) {
+            $federationStructure->setLogoUri($this->apiService->getApiUri('_internal/secure/files/') . $record['logoId']);
+        }
+        $federationStructure->setParentId($record['n1Id']);
+        $federationStructure->setParentName($record['n1Name']);
+        $federationStructure->setParents($record['parents']);
+        return $federationStructure;
+    }
+
+}

+ 0 - 63
ot_core/Classes/Middleware/Frontend/OtSiteResolver.php

@@ -1,63 +0,0 @@
-<?php
-declare(strict_types = 1);
-namespace Opentalent\OtCore\Middleware\Frontend;
-
-use Opentalent\OtCore\Exception\NoSuchWebsiteException;
-use Opentalent\OtCore\Website\OtWebsiteRepository;
-use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\ServerRequestInterface;
-use Psr\Http\Server\RequestHandlerInterface;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Extbase\Object\ObjectManager;
-use TYPO3\CMS\Core\Routing\SiteRouteResult;
-use TYPO3\CMS\Frontend\Controller\ErrorController;
-use TYPO3\CMS\Frontend\Page\PageAccessFailureReasons;
-
-/**
- *
- */
-class OtSiteResolver extends \TYPO3\CMS\Frontend\Middleware\SiteResolver
-{
-    /**
-     * Resolve the site/language information by checking the page ID or the URL.
-     *
-     * @param ServerRequestInterface $request
-     * @param RequestHandlerInterface $handler
-     * @return ResponseInterface
-     */
-    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
-    {
-        $otWebsiteRepository = GeneralUtility::makeInstance(ObjectManager::class)->get(OtWebsiteRepository::class);
-
-        try {
-            $devMode = $_SERVER['TYPO3_CONTEXT'] == "Development";
-
-            $otWebsite = $otWebsiteRepository->matchUriToWebsite($request->getUri(), $devMode);
-            $site = $otWebsiteRepository->generateWebsiteConfiguration($otWebsite);
-            $language = $site->getDefaultLanguage();
-            if ($devMode) {
-                preg_match("/\w+\/(.*)/", $request->getUri()->getPath(), $m);
-                $tail = $m[1] ?? "";
-            } else {
-                $tail = rtrim($request->getUri()->getPath(), '/');
-            }
-        } catch (NoSuchWebsiteException $e) {
-            // site not found
-            // either it will be redirected, or it will return a pageNotFound error during the page resolution
-            return $handler->handle($request);
-        }
-
-        $routeResult = new SiteRouteResult($request->getUri(), $site, $language, $tail);
-
-        $request = $request->withAttribute('ot_website', $otWebsite);
-        $request = $request->withAttribute('site', $routeResult->getSite());
-        $request = $request->withAttribute('language', $routeResult->getLanguage());
-        $request = $request->withAttribute('routing', $routeResult);
-
-        // At this point, we later get further route modifiers
-        // for bw-compat we update $GLOBALS[TYPO3_REQUEST] to be used later in TSFE.
-        $GLOBALS['TYPO3_REQUEST'] = $request;
-
-        return $handler->handle($request);
-    }
-}

+ 1 - 1
ot_core/Classes/Service/OpentalentApiService.php

@@ -70,7 +70,7 @@ class OpentalentApiService implements LoggerAwareInterface
      * @param string $trailing_part
      * @return string
      */
-    protected function getApiUri(string $trailing_part = ""): string
+    public function getApiUri(string $trailing_part = ""): string
     {
         $host = $_SERVER['HTTP_HOST'] ?? $_SERVER['VIRTUAL_HOST'];
 

+ 5 - 0
ot_core/Classes/ViewHelpers/OtAbstractViewHelper.php

@@ -6,6 +6,7 @@ use FluidTYPO3\Vhs\Utility\ErrorUtility;
 use Opentalent\OtCore\Website\OtPageRepository;
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerAwareTrait;
+use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
 use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
 
 /**
@@ -47,4 +48,8 @@ class OtAbstractViewHelper  extends AbstractViewHelper implements LoggerAwareInt
     {
         return $GLOBALS['LANG'];
     }
+
+    protected function translate(string $id) {
+        return LocalizationUtility::translate($id, 'ot_templating');
+    }
 }

+ 80 - 0
ot_templating/Classes/ViewHelpers/Organizations/AsGeoMarkersArrayViewHelper.php

@@ -0,0 +1,80 @@
+<?php
+
+namespace Opentalent\OtTemplating\ViewHelpers\Organizations;
+
+use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
+use Opentalent\OtCore\ViewHelpers\OtAbstractViewHelper;
+use Opentalent\OtCore\Domain\Model\Organization;
+use Opentalent\OtCore\Domain\Repository\OrganizationRepository;
+use Opentalent\OtCore\Exception\ApiRequestException;
+
+/**
+ *   This viewhelper formats an array of Organization / FederationStructures objects into an json-array
+ *   containing the data needed by the leaflet markers: [{id: 0, long: 0, lat: 0, label: ''}, ...]
+ *
+ *     {namespace ot=Opentalent\OtTemplating\ViewHelpers}
+ *
+ *     <ot:organizations.asGeoMarkersArray structures="structures">
+ *          <f:debug>{organization}</f:debug>
+ *     </ot:organizations.asGeoMarkersArray>
+ *
+ * @package Opentalent\OtTemplating\ViewHelpers
+ */
+class AsGeoMarkersArrayViewHelper extends OtAbstractViewHelper {
+
+    use TemplateVariableViewHelperTrait;
+
+    /**
+     * >> Required to prevent typo3 to escape the html output
+     * @var boolean
+     */
+    protected $escapeOutput = true;
+
+    /**
+     * -- This method is expected by Fluid --
+     * Declares the viewhelper's parameters
+     */
+    public function initializeArguments()
+    {
+        $this->registerArgument(
+            'structures',
+            'array',
+            'Array of Organization or FederationStructure objects',
+            true
+        );
+    }
+
+    /**
+     * -- This method is expected by Fluid --
+     * Renders the content as html
+     *
+     * @return string
+     * @throws ApiRequestException
+     */
+    public function render()
+    {
+        $structures = $this->arguments['structures'];
+
+        $markers = [];
+        foreach ($structures as $structure)  {
+            if ($structure->getLongitude() && $structure->getLatitude()) {
+                $markers[] = [
+                    'id' => $structure->getId(),
+                    'long' => $structure->getLongitude(),
+                    'lat' => $structure->getLatitude(),
+                    'label' => $structure->getName() ?? ""
+                ];
+            }
+        }
+
+        return json_encode($markers);
+    }
+
+    /**
+     * @param OrganizationRepository $organizationRepository
+     */
+    public function injectOrganizationRepository(OrganizationRepository $organizationRepository)
+    {
+        $this->organizationRepository = $organizationRepository;
+    }
+}

+ 102 - 0
ot_templating/Classes/ViewHelpers/Organizations/GetChildFederationViewHelper.php

@@ -0,0 +1,102 @@
+<?php
+
+namespace Opentalent\OtTemplating\ViewHelpers\Organizations;
+
+use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
+use Opentalent\OtCore\Domain\Repository\FederationStructureRepository;
+use Opentalent\OtCore\ViewHelpers\OtAbstractViewHelper;
+
+/**
+ *   This view helper returns all of the children federations as an ApiPagedCollection, without pagination
+ *
+ *     {namespace ot=Opentalent\OtTemplating\ViewHelpers}
+ *
+ *     <ot:organizations.getChildFederation as="organization"
+ *                               organizationId="1">
+ *          <f:debug>{organization}</f:debug>
+ *     </ot:organizations.getChildFederation>
+ *
+ * @package Opentalent\OtTemplating\ViewHelpers
+ */
+class GetChildFederationViewHelper extends OtAbstractViewHelper {
+
+    use TemplateVariableViewHelperTrait;
+
+    /**
+     * >> Required to prevent typo3 to escape the html output
+     * @var boolean
+     */
+    protected $escapeOutput = false;
+
+    /**
+     * @var FederationStructureRepository
+     *
+     */
+    protected $federationRepository;
+
+    /**
+     * -- This method is expected by Fluid --
+     * Declares the viewhelper's parameters
+     */
+    public function initializeArguments()
+    {
+        $this->registerArgument(
+            'as',
+            'string',
+            'Name of the returned array',
+            true
+        );
+        $this->registerArgument(
+            'parentId',
+            'integer',
+            'Id of the parent organization',
+            true
+        );
+        $this->registerArgument(
+            'itemsPerPage',
+            'string',
+            'Number of items per page',
+            false,
+            10
+        );
+    }
+
+    /**
+     * -- This method is expected by Fluid --
+     * Renders the content as html
+     *
+     * @return string
+     * @throws \Opentalent\OtCore\Exception\ApiRequestException
+     */
+    public function render()
+    {
+        $as = $this->arguments['as'];
+        $parentId = $this->arguments['parentId'];
+        $itemsPerPage = $this->arguments['itemsPerPage'];
+        $page = $_REQUEST['page'] ?? 1;
+
+        if ($itemsPerPage == 'all') {
+            $itemsPerPage = 99999; // the 'all' keyword raise an error during the api call
+            $page = 1;
+        }
+
+        $searchParams = ['itemsPerPage' => $itemsPerPage];
+
+        $searchParams['filter[where][n1Id]'] = $parentId;
+        $searchParams['filter[end][principalType]'] = 'FEDERATION';
+        $organizations = $this->federationRepository->findChildrenById($parentId, $searchParams, $page, 1);
+
+        $variables = [
+            $as => $organizations
+        ];
+        return $this->renderChildrenWithVariables($variables);
+    }
+
+    /**
+     * @param FederationStructureRepository $federationRepository
+     */
+    public function injectFederationRepository(FederationStructureRepository $federationRepository)
+    {
+        $this->federationRepository = $federationRepository;
+    }
+}

+ 138 - 0
ot_templating/Classes/ViewHelpers/Organizations/GetFederationStructuresViewHelper.php

@@ -0,0 +1,138 @@
+<?php
+
+namespace Opentalent\OtTemplating\ViewHelpers\Organizations;
+
+use FluidTYPO3\Vhs\Traits\TemplateVariableViewHelperTrait;
+use Opentalent\OtCore\Domain\Repository\FederationStructureRepository;
+use Opentalent\OtCore\ViewHelpers\OtAbstractViewHelper;
+
+/**
+ *   This view helper returns all of the organization children structures as an ApiPagedCollection, without pagination
+ *
+ *     {namespace ot=Opentalent\OtTemplating\ViewHelpers}
+ *
+ *     <ot:organizations.getFederationStructures as="organization"
+ *                               organizationId="1">
+ *          <f:debug>{organization}</f:debug>
+ *     </ot:organizations.getFederationStructures>
+ *
+ * @package Opentalent\OtTemplating\ViewHelpers
+ */
+class GetFederationStructuresViewHelper extends OtAbstractViewHelper {
+
+    use TemplateVariableViewHelperTrait;
+
+    /**
+     * >> Required to prevent typo3 to escape the html output
+     * @var boolean
+     */
+    protected $escapeOutput = false;
+
+    /**
+     * @var FederationStructureRepository
+     *
+     */
+    protected $federationRepository;
+
+    /**
+     * -- This method is expected by Fluid --
+     * Declares the viewhelper's parameters
+     */
+    public function initializeArguments()
+    {
+        $this->registerArgument(
+            'as',
+            'string',
+            'Name of the returned array',
+            true
+        );
+        $this->registerArgument(
+            'parentId',
+            'integer',
+            'Id of the parent organization',
+            true
+        );
+        $this->registerArgument(
+            'itemsPerPage',
+            'string',
+            'Number of items per page',
+            false,
+            10
+        );
+        $this->registerArgument(
+            'depth',
+            'integer',
+            'Max level of depth',
+            false,
+            5
+        );
+    }
+
+    /**
+     * -- This method is expected by Fluid --
+     * Renders the content as html
+     *
+     * @return string
+     * @throws \Opentalent\OtCore\Exception\ApiRequestException
+     */
+    public function render()
+    {
+        $as = $this->arguments['as'];
+        $parentId = $this->arguments['parentId'];
+        $itemsPerPage = $this->arguments['itemsPerPage'];
+        $page = $_REQUEST['page'] ?? 1;
+        $depth = $_REQUEST['depth'] ?? 5;
+
+        if ($itemsPerPage == 'all') {
+            $itemsPerPage = 99999; // the 'all' keyword raise an error during the api call
+            $page = 1;
+        }
+
+        $searchParams = ['itemsPerPage' => $itemsPerPage];
+
+//        // If a federation was selected in the filters, it is used as parent
+//        if($_REQUEST['search-federation']) {
+//            $parentId = (int)$_REQUEST['search-federation'];
+//        }
+//
+//        // Search structures by name
+//        if($_REQUEST['search-query']) {
+//            $searchParams['what'] = $_REQUEST['search-query'];
+//        }
+//
+//        // Filters
+//        if($_REQUEST['search-category']) {
+//            $searchParams['category'] = $_REQUEST['search-category'];
+//        }
+//        if($_REQUEST['search-province']) {
+//            // A leading '_' may have been added to prevent the '0' from being stripped by fluid
+//            $province = ltrim($_REQUEST['search-province'], '_');
+//            $searchParams['province'] = $province;
+//        }
+//        if($_REQUEST['lat']) {
+//            $radius = (int)$_REQUEST['search-radius'] ?? 0;
+//
+//            // radius is always increased of 10km to take into account the size of the city itself
+//            $radius += 10;
+//
+//            $searchParams['lat'] = $_REQUEST['lat'];
+//            $searchParams['long'] = $_REQUEST['long'];
+//            $searchParams['radius'] = $radius;
+//        }
+
+        $organizations = $this->federationRepository->findChildrenById($parentId, $searchParams, $page, $depth);
+
+        $variables = [
+            $as => $organizations
+        ];
+        return $this->renderChildrenWithVariables($variables);
+    }
+
+    /**
+     * @param FederationStructureRepository $federationRepository
+     */
+    public function injectFederationRepository(FederationStructureRepository $federationRepository)
+    {
+        $this->federationRepository = $federationRepository;
+    }
+}

+ 101 - 0
ot_templating/Classes/ViewHelpers/PaginationViewHelper.php

@@ -0,0 +1,101 @@
+<?php
+
+namespace Opentalent\OtTemplating\ViewHelpers;
+
+use Opentalent\OtCore\ViewHelpers\OtAbstractViewHelper;
+
+/**
+ *
+ *     {namespace ot=Opentalent\OtTemplating\ViewHelpers}
+ *
+ *     {ot:pagination(collection:collection)}
+ *
+ * @package Opentalent\OtTemplating\ViewHelpers
+ */
+class PaginationViewHelper extends OtAbstractViewHelper
+{
+    /**
+     * >> Required to prevent typo3 to escape the html output
+     * @var boolean
+     */
+    protected $escapeOutput = false;
+
+    /**
+     * -- This method is expected by Fluid --
+     * Declares the viewhelper's parameters
+     */
+    public function initializeArguments()
+    {
+        $this->registerArgument(
+            'collection',
+            'object',
+            'The ApiPagedCollection object',
+            true
+        );
+    }
+
+    /**
+     * -- This method is expected by Fluid --
+     * Renders the content as html
+     *
+     * @return string Rendered tag
+     */
+    public function render() {
+        $collection = $this->arguments['collection'];
+        $lastPage = $collection->getLastPage();
+        $currentPage = $collection->getCurrentPage();
+
+        if (!$lastPage > 0) {
+            return "";
+        }
+
+        $divWrapper = '<div class="pagination-bar">%s</div>';
+
+        $goToFirst = '<a href="' . $this->getUriWithPage(1) . '" ' .
+            'title="' . $this->translate('go-to-first-page') . '">' .
+            '<i class="fa fa-angle-double-left"></i>' .
+            '</a>';
+        $goToLast = '<a href="' . $this->getUriWithPage($lastPage) . '"' .
+            'title="' . $this->translate('go-to-last-page') . '">' .
+            '<i class="fa fa-angle-double-right"></i>' .
+            '</a>';
+
+        $startAt = $currentPage > 6  ? $currentPage - 5 : 1;
+        $endAt = $currentPage < ($lastPage - 5) ? $currentPage + 5 : $lastPage;
+
+        $ul = '<ul>';
+        for ($i = $startAt; $i <= $endAt; $i++) {
+            $ul .= '<li class="' . ($i == $currentPage ? 'current' : '') . '">';
+            $ul .= '<a href="' . $this->getUriWithPage($i) . '" title="' . $this->translate('go-to-page') . $i .'">' . $i . '</a>';
+            $ul .= '</li>';
+        }
+        $ul .= '</ul>';
+
+        return sprintf($divWrapper, $goToFirst . $ul . $goToLast);
+    }
+
+    private function getUriWithPage(int $page, bool $nocache = true) {
+        $request = $GLOBALS['TYPO3_REQUEST'];
+        $uri = $request->getUri();
+        $query = $uri->getQuery();
+
+        if (preg_match("/.*page=\d+.*/", $query)) {
+            $query = preg_replace(
+                "/page=\d+/",
+                "page=" . $page,
+                $query
+            );
+        } elseif ($query != '') {
+            $query .= "&page=" . $page;
+        } else {
+            $query .= "page=" . $page;
+        }
+
+        $query = preg_replace("/&no_cache=1/", "", $query);
+        if ($nocache) {
+            $query .= '&no_cache=1';
+        }
+        return (string)$uri->withQuery($query);
+    }
+
+}

+ 73 - 0
ot_templating/Classes/ViewHelpers/Utilities/PaginateArrayViewHelper.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace Opentalent\OtTemplating\ViewHelpers\Utilities;
+
+use Closure;
+use Opentalent\OtCore\ViewHelpers\OtAbstractViewHelper;
+use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
+
+/**
+ *   Transform an array into a paginated array
+ *
+ *     {namespace ot=Opentalent\OtTemplating\ViewHelpers}
+ *
+ *     {ot:utilities.paginateArray('[0, 1, ...]')}
+ *
+ * @package Opentalent\OtTemplating\ViewHelpers
+ */
+class PaginateArrayViewHelper extends OtAbstractViewHelper {
+
+    /**
+     * -- This method is expected by Fluid --
+     * Declares the viewhelper's parameters
+     */
+    public function initializeArguments()
+    {
+        $this->registerArgument('array',
+            'array',
+            "The array",
+            true);
+        $this->registerArgument('itemsPerPage',
+            'integer',
+            "Number of items per page",
+            false,
+            10
+        );
+    }
+
+    /**
+     * -- This method is expected by Fluid --
+     * Renders the content as html
+     *
+     * @param array $arguments
+     * @param Closure $renderChildrenClosure
+     * @param RenderingContextInterface $renderingContext
+     * @return array
+     */
+    public static function renderStatic(
+        array $arguments,
+        Closure $renderChildrenClosure,
+        RenderingContextInterface $renderingContext
+    ) {
+        $array = $arguments['array'];
+        $itemsPerPage = $arguments['itemsPerPage'];
+
+        $i = 0;
+        $pageArray = [];
+        $pages = [];
+
+        foreach($array as $k => $v) {
+
+            if ($i % $itemsPerPage == 0) {
+                if ($pageArray) {
+                    $pages[] = $pageArray;
+                }
+                $pageArray = [];
+            }
+            $pageArray[$k] = $v;
+            $i++;
+        }
+
+        return $pages;
+    }
+}

+ 58 - 0
ot_templating/Classes/ViewHelpers/Utilities/RangeViewHelper.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace Opentalent\OtTemplating\ViewHelpers\Utilities;
+
+use Closure;
+use Opentalent\OtCore\ViewHelpers\OtAbstractViewHelper;
+use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
+
+/**
+ *   Returns an array of integers going from i to j
+ *
+ *     {namespace ot=Opentalent\OtTemplating\ViewHelpers}
+ *
+ *     {ot:utilities.range(i: 0, j: 10)}
+ *
+ * @package Opentalent\OtTemplating\ViewHelpers
+ */
+class RangeViewHelper extends OtAbstractViewHelper {
+
+    /**
+     * -- This method is expected by Fluid --
+     * Declares the viewhelper's parameters
+     */
+    public function initializeArguments()
+    {
+        $this->registerArgument('i',
+            'integer',
+            "Low limit",
+            true);
+        $this->registerArgument('j',
+            'integer',
+            "High limit",
+            true);
+    }
+
+    /**
+     * -- This method is expected by Fluid --
+     * Renders the content as html
+     *
+     * @param array $arguments
+     * @param Closure $renderChildrenClosure
+     * @param RenderingContextInterface $renderingContext
+     * @return string|null
+     */
+    public static function renderStatic(
+        array $arguments,
+        Closure $renderChildrenClosure,
+        RenderingContextInterface $renderingContext
+    ) {
+        $i = $arguments['i'];
+        $j = $arguments['j'];
+        $array = [];
+        for($x=$i;$x<=$j;$x++) {
+            $array[] = $x;
+        }
+        return $array;
+    }
+}

+ 64 - 1
ot_templating/Resources/Private/Language/locallang.xlf

@@ -152,23 +152,59 @@
 				<source>Revenir à la liste des actualités</source>
 			</trans-unit>
 			<trans-unit id="member-companies">
-				<source>Sociétés adhérentes</source>
+				<source>Nos structures adhérentes</source>
+			</trans-unit>
+			<trans-unit id="map">
+				<source>Carte</source>
+			</trans-unit>
+			<trans-unit id="list">
+				<source>Liste</source>
 			</trans-unit>
 			<trans-unit id="no-result">
 				<source>Aucun résultat</source>
 			</trans-unit>
+			<trans-unit id="no-result">
+				<source>Une erreur s'est produite</source>
+			</trans-unit>
 			<trans-unit id="find">
 				<source>Trouver</source>
 			</trans-unit>
 			<trans-unit id="see">
 				<source>Voir</source>
 			</trans-unit>
+			<trans-unit id="see-more">
+				<source>En savoir plus</source>
+			</trans-unit>
+			<trans-unit id="go-to-first-page">
+				<source>Aller à la première page</source>
+			</trans-unit>
+			<trans-unit id="go-to-last-page">
+				<source>Aller à la dernière page</source>
+			</trans-unit>
+			<trans-unit id="go-to-page">
+				<source>Aller à la page</source>
+			</trans-unit>
+			<trans-unit id="around-me">
+				<source>Autour de moi</source>
+			</trans-unit>
+			<trans-unit id="geoloc-unavailable">
+				<source>Erreur: La géolocalisation n'est pas disponible, vérifiez les permissions de votre navigateur</source>
+			</trans-unit>
+			<trans-unit id="geoloc-unsupported">
+				<source>La géolocalisation n'est pas disponible sur votre navigateur</source>
+			</trans-unit>
+			<trans-unit id="click-on-land-to-go-there">
+				<source>Cliquez sur une des régions ci-dessous pour centrer la carte sur elle</source>
+			</trans-unit>
 			<trans-unit id="look-for-an-event">
 				<source>Rechercher un évènement</source>
 			</trans-unit>
 			<trans-unit id="search">
 				<source>Rechercher</source>
 			</trans-unit>
+			<trans-unit id="please-wait">
+				<source>Veuillez patienter...</source>
+			</trans-unit>
 			<trans-unit id="more-informations">
 				<source>Plus d'infos</source>
 			</trans-unit>
@@ -1610,6 +1646,33 @@
 			<trans-unit id="CONDUCTOR" xml:space="preserve">
 			    <source>Directeur ou chef d'orchestre</source>
 			</trans-unit>
+			<trans-unit id="1MC" xml:space="preserve">
+			    <source>Musique</source>
+			</trans-unit>
+			<trans-unit id="2TH" xml:space="preserve">
+			    <source>Théatre</source>
+			</trans-unit>
+			<trans-unit id="3DA" xml:space="preserve">
+			    <source>Dance</source>
+			</trans-unit>
+			<trans-unit id="5FA" xml:space="preserve">
+			    <source>Art du spectacle</source>
+			</trans-unit>
+			<trans-unit id="OTAR" xml:space="preserve">
+			    <source>Arts de rue</source>
+			</trans-unit>
+			<trans-unit id="OTCI" xml:space="preserve">
+			    <source>École de cirque</source>
+			</trans-unit>
+			<trans-unit id="6AR" xml:space="preserve">
+			    <source>Musée</source>
+			</trans-unit>
+			<trans-unit id="8CI" xml:space="preserve">
+			    <source>Cinéma</source>
+			</trans-unit>
+			<trans-unit id="OTAU" xml:space="preserve">
+			    <source>Autres</source>
+			</trans-unit>
 		</body>
 	</file>
 </xliff>

+ 1 - 1
ot_templating/Resources/Private/Layouts/Classic/Structures.html

@@ -91,7 +91,7 @@
                             </div>
                         </f:for>
 
-                        <f:render partial="Classic/Pagination" arguments="{collection: structuresCollection}"/>
+                        {ot:pagination(collection: structuresCollection)}
                     </div>
                 </div>
             </ot:organizations.getChildren>

+ 1 - 1
ot_templating/Resources/Private/Layouts/Classic/StructuresEvents.html

@@ -110,7 +110,7 @@
                         </div>
                     </f:for>
 
-                    <f:render partial="Classic/Pagination" arguments="{collection: eventsCollection}"/>
+                    {ot:pagination(collection: eventsCollection)}
                 </div>
             </div>
 

File diff suppressed because it is too large
+ 101 - 0
ot_templating/Resources/Private/Layouts/Classic/StructuresFrame.html


+ 2 - 2
ot_templating/Resources/Private/Layouts/Modern/Structures.html

@@ -90,14 +90,14 @@
                                                     </div>
                                                 </div>
 
-                                                <a href="https://{structure.subdomain}.opentalent.fr" class="structure-see">
+                                                <a target="_blank" href="https://{structure.subdomain}.opentalent.fr" class="structure-see">
                                                     <i class="fa fa-plus" style="margin-right: 5px;"></i>
                                                     <span><f:translate key="see"/></span>
                                                 </a>
                                             </div>
                                         </f:for>
 
-                                        <f:render partial="Modern/Pagination" arguments="{collection: structuresCollection}"/>
+                                        {ot:pagination(collection: structuresCollection)}
                                     </div>
                                 </div>
                             </ot:organizations.getChildren>

+ 1 - 1
ot_templating/Resources/Private/Layouts/Modern/StructuresEvents.html

@@ -112,7 +112,7 @@
                                         </div>
                                     </f:for>
 
-                                    <f:render partial="Modern/Pagination" arguments="{collection: eventsCollection}"/>
+                                    {ot:pagination(collection: eventsCollection)}
                                 </div>
                             </div>
                         </ot:events.getAll>

+ 14 - 0
ot_templating/Resources/Private/Partials/Classic/Assets.html

@@ -29,6 +29,16 @@ Assets included with the VHS viewhelpers
                rewrite="0"
                standalone="1"/>
 
+<v:asset.style name="classic-leaflet-clusters-css"
+               path="{assets_dir}/style/ext/MarkerCluster.css"
+               rewrite="0"
+               standalone="1"/>
+
+<v:asset.style name="classic-leaflet-clusters-default-css"
+               path="{assets_dir}/style/ext/MarkerCluster.Default.css"
+               rewrite="0"
+               standalone="1"/>
+
 <f:comment><!-- Theme's file shall not be rewritten since
                 it may not be updated from a website to another --></f:comment>
 <v:asset.style name="classic-theme"
@@ -56,6 +66,10 @@ Assets included with the VHS viewhelpers
                 path="{assets_dir}/script/leaflet.js"
                 defer="1"/>
 
+<v:asset.script name="classic-leaflet-clusters"
+                path="{assets_dir}/script/leaflet.markercluster.js"
+                defer="1"/>
+
 <v:asset.script name="classic-main"
                 path="{assets_dir}/script/main.js"
                 dependencies="classic-jquery,classic-datepicker,classic-slick,classic-leaflet"

+ 1 - 1
ot_templating/Resources/Private/Partials/Classic/EventsIndex.html

@@ -95,6 +95,6 @@
             </div>
         </f:for>
 
-        <f:render partial="Classic/Pagination" arguments="{collection: eventsCollection}"/>
+        {ot:pagination(collection: eventsCollection)}
     </div>
 </div>

+ 0 - 22
ot_templating/Resources/Private/Partials/Classic/Pagination.html

@@ -1,22 +0,0 @@
-{namespace ot=Opentalent\OtTemplating\ViewHelpers}
-
-<f:comment><!-- Pagination --></f:comment>
-<f:comment><!--
-    This partial expects an ApiPagedCollection
-    named {collection} as argument
- --></f:comment>
-
-<f:if condition="{collection.lastPage} > 0">
-    <div class="pagination-bar">
-        <p><f:translate key="pages"/>:</p>
-        <ul>
-            <f:for each="{collection.pages}" as="page">
-                <li class="{f:if(condition: '{page}=={collection.currentPage}', then: 'current', else: '')}">
-                    <a href="{ot:request.withPage(page: page)}">
-                        {page}
-                    </a>
-                </li>
-            </f:for>
-        </ul>
-    </div>
-</f:if>

+ 1 - 1
ot_templating/Resources/Private/Partials/Modern/EventsIndex.html

@@ -95,6 +95,6 @@
             </div>
         </f:for>
 
-        <f:render partial="Modern/Pagination" arguments="{collection: eventsCollection}"/>
+        {ot:pagination(collection: eventsCollection)}
     </div>
 </div>

+ 0 - 22
ot_templating/Resources/Private/Partials/Modern/Pagination.html

@@ -1,22 +0,0 @@
-{namespace ot=Opentalent\OtTemplating\ViewHelpers}
-
-<f:comment><!-- Pagination --></f:comment>
-<f:comment><!--
-    This partial expects an ApiPagedCollection
-    named {collection} as argument
- --></f:comment>
-
-<f:if condition="{collection.lastPage} > 0">
-    <div class="pagination-bar">
-        <p><f:translate key="pages"/>:</p>
-        <ul>
-            <f:for each="{collection.pages}" as="page">
-                <li class="{f:if(condition: '{page}=={collection.currentPage}', then: 'current', else: '')}">
-                    <a href="{ot:request.withPage(page: page)}">
-                        {page}
-                    </a>
-                </li>
-            </f:for>
-        </ul>
-    </div>
-</f:if>

+ 18 - 0
ot_templating/Resources/Private/Templates/Page/StructuresFrame.html

@@ -0,0 +1,18 @@
+{namespace flux=FluidTYPO3\Flux\ViewHelpers}
+{namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
+
+<f:comment><!-- uses the layout StructuresFrame, defined in layouts/[templateName]/StructuresFrame.html --></f:comment>
+<f:layout name="{ot:template.current()}/StructuresFrame" />
+
+<f:section name='Configuration'>
+    <flux:form id="structures_frame" label="LLL:template_structures_frame" extensionName="Opentalent.OtTemplating">
+    </flux:form>
+
+    <!-- Backend layout grid -->
+    <flux:grid>
+        <flux:grid.row>
+        </flux:grid.row>
+    </flux:grid>
+</f:section>
+

File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/script/leaflet.markercluster.js


+ 32 - 26
ot_templating/Resources/Public/assets/Classic/script/main.js

@@ -78,8 +78,10 @@ $(document).ready(function(){
     });
 
     // * Sticky menu
-    var menuTop = $('#menu').offset().top;
-    var menuHeight = $('#menu').height();
+    if ($('#menu').length) {
+        var menuTop = $('#menu').offset().top;
+        var menuHeight = $('#menu').height();
+    }
 
     $(function(){
         $(window).scroll(function() {
@@ -125,6 +127,10 @@ $(document).ready(function(){
     // }
 
     // **** Forms ****
+    // $('.search-submit').on('click', function(e) {
+    //     $(this).parent('form').submit();
+    // })
+
     $('.datepicker').datepicker({
         minDate: new Date(),
         maxDate: "+2y",
@@ -168,8 +174,9 @@ $(document).ready(function(){
     });
 
     // **** Leaflet: maps *****
+    var map;
 
-    function showMap(mapDiv) {
+    function showMap(mapDiv, zoomToItems=true) {
 
         let mapId = $(mapDiv).attr("id");
         if (!mapId) {
@@ -178,7 +185,7 @@ $(document).ready(function(){
         }
 
         // Collect the data from th map children <i>
-        var items = [];
+        let items = [];
         mapDiv.children('.item-geodata').each(function () {
             let item = {
                 id: $(this).data('id'),
@@ -190,30 +197,22 @@ $(document).ready(function(){
         });
 
         // Instanciate the map object  @see https://leafletjs.com/reference-1.6.0.html#map-factory
-        var mapOptions = {scrollWheelZoom: false};
-        var initialZoom = 13;
-        var map = L.map(mapId, mapOptions);
-        if (items.length > 0) {
-            map.setView([items[0].lat, items[0].long], initialZoom);
+        const mapOptions = {scrollWheelZoom: false, zoomSnap: 0.25};
+        map = L.map(mapId, mapOptions);
+        if (zoomToItems && items.length > 0) {
+            map.setView([items[0].lat, items[0].long], 13);
         } else {
-            map.setView([46.3399276, 2.6067229], 5);
+            map.setView([46.71, 2.14], 6);
         }
 
         // Add the tile layer
-        // L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
-        //     maxZoom: 18,
-        //     id: 'mapbox/streets-v11',
-        //     tileSize: 512,
-        //     // zoomOffset: -1,
-        //     attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
-        //     accessToken: 'pk.eyJ1Ijoib2xpdmllci1tYXNzb3QiLCJhIjoiY2s5OGl1M2cxMWNpajNscnV4Zm5maWY3eSJ9.YDESFgB-JuAhplTzXI6hGQ',
-        // }).addTo(map);
         L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
             attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
         }).addTo(map);
 
         // Collect the event geodata to create the markers
-        let markers = []
+        let markers = [];
+
         items.forEach(function (item) {
             let marker = L.marker([item.lat, item.long]).addTo(map);
             marker.bindPopup(item.label);
@@ -221,15 +220,22 @@ $(document).ready(function(){
         });
 
         // Set the view
-        if (items.length > 0) {
-            var markersGroup = new L.featureGroup(markers);
-            map.fitBounds(markersGroup.getBounds());
-            map.zoomSnap = 1;
-            map.zoomOut();
+        let bounds = null;
+        if (zoomToItems && items.length > 0) {
+            const markersGroup = new L.featureGroup(markers);
+            bounds = markersGroup.getBounds()
+        } else {
+            bounds = L.latLngBounds(
+                    L.latLng(51.03, -5.78),
+                    L.latLng(41.2, 9.70)
+                );
+        }
+        if (bounds !== null) {
+            map.fitBounds(bounds);
+            // map.zoomOut();
         }
     }
 
-
     // Display map on events index page
     if ($('.ot-all-events #event-map').length) {
         showMap($('#event-map').first());
@@ -240,7 +246,7 @@ $(document).ready(function(){
         showMap($('#event-map').first());
     }
 
-    // Display map on network structures page
+    // Display map on (non-framed) network structures page
     if ($('.ot-structures #structure-map').length) {
         showMap($('#structure-map').first());
     }

+ 586 - 0
ot_templating/Resources/Public/assets/Classic/script/structures.js

@@ -0,0 +1,586 @@
+
+const variants_uris = {
+    "preprod.opentalent.fr": "https://api.preprod.opentalent.fr",
+    "local.sub.opentalent.fr": "https://local.api.opentalent.fr",
+    "typo3": "http://docker.nginx.opentalent.fr"
+};
+
+const base_uri = variants_uris[$(location).attr('hostname')];
+let apiGetUrl = base_uri + '/api/public/federation_structures?_format=json&page=1&itemsPerPage=99999';
+
+
+// Converts numeric degrees to radians
+function toRad(Value)
+{
+    return Value * Math.PI / 180;
+}
+
+//This function takes in latitude and longitude of two location and returns the distance between them as the crow flies (in km)
+function sphericDistance(lat1, lon1, lat2, lon2)
+{
+    let R = 6371; // km
+    let dLat = toRad(lat2-lat1);
+    let dLon = toRad(lon2-lon1);
+    lat1 = toRad(lat1);
+    lat2 = toRad(lat2);
+
+    let a = Math.sin(dLat/2) * Math.sin(dLat/2) +
+        Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
+    let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
+    return R * c;
+}
+
+// Specific JS used for the Structures layout
+// > Needs to be loaded after the main.js script
+$(document).ready(function() {
+
+    const queryParameters = new URLSearchParams(window.location.search);
+    let organizationId = queryParameters.get('organization-id');
+
+    if (!organizationId) {
+        throw 'Missing organization-id parameter';
+    }
+
+    // Init
+    let document = $('html, body');
+    let structureFrame = $('.ot-structures-frame').first();
+
+    // let organizationId = structureFrame.data('org-id');
+
+    let resultsPageDiv = structureFrame.find('.structures-page').first();
+    let pleaseWaitSpan = structureFrame.find('.please-wait').first();
+    let noResultSpan = structureFrame.find('.no-result').first();
+    let cardDivModel = structureFrame.find('.structure-card-model').first();
+    let paginationBar = structureFrame.find('.pagination-bar').first();
+    let paginationList = structureFrame.find('.pagination-list').first();
+    let gotoFirstPage = structureFrame.find('.goto-first-page').first();
+    let gotoLastPage = structureFrame.find('.goto-last-page').first();
+
+    let form = $("#structure-search-form");
+    let whatInput = form.find("input[name='search-query']").first();
+    let cityInput = form.find("input[name='search-city']").first();
+    let latInput = form.find("input[name='lat']").first();
+    let longInput = form.find("input[name='long']").first();
+    let categorySelect = form.find("select[name='search-category']").first();
+    let provinceSelect = form.find("select[name='search-province']").first();
+    let federationSelect = form.find("select[name='search-federation']").first();
+    let radiusSelect = form.find("select[name='search-radius']").first();
+    let resetButton = form.find("button.reset-search").first();
+    let submitButton = form.find("button.submit-search").first();
+
+    // Translations
+    let tr = {};
+    $('#labels').find('span').each(function (i, elt) {
+       tr[$(elt).attr('id')] = $(elt).text();
+    });
+
+    let structures_categories = {
+        '1MC': tr['1MC'],
+        '2TH': tr['2TH'],
+        '3DA': tr['3DA'],
+        '5FA': tr['5FA'],
+        'OTAR':tr['OTAR'],
+        'OTCI':tr['OTCI'],
+        '6AR': tr['6AR'],
+        '8CI': tr['8CI'],
+        'OTAU':tr['OTAU'],
+    }
+
+    // #### Instanciate and populate leaflet map
+    let mapDiv = $('#structure-map').first();
+    let mapId = $(mapDiv).attr("id");
+
+    // Instanciate the map object  @see https://leafletjs.com/reference-1.6.0.html#map-factory
+    const mapOptions = {scrollWheelZoom: false, zoomSnap: 0.25};
+    map = L.map(mapId, mapOptions);
+    map.setView([46.71, 2.14], 6);
+
+    // Add the tile layer
+    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
+        attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
+    }).addTo(map);
+
+    var listenMapMoves = false;
+
+    var defaultsBounds = [51.03, -5.78, 41.2, 9.70];
+
+    // Set the view
+    let resetMapBounds = function () {
+        area = null;
+        bounds = L.latLngBounds(
+            L.latLng(defaultsBounds[0], defaultsBounds[1]),
+            L.latLng(defaultsBounds[2], defaultsBounds[3])
+        );
+        map.fitBounds(bounds);
+    }
+    resetMapBounds();
+
+    var clusters = null;
+
+
+    // #### Filters
+
+    // The current query
+    var query = {};
+    var area = null;
+
+    // Update the current query with form data
+    function updateQuery() {
+        query['what'] = whatInput.val();
+        query['lat'] = latInput.val();
+        query['long'] = longInput.val();
+        query['category'] = categorySelect.val();
+        query['province'] = provinceSelect.val();
+        query['federation'] = federationSelect.val();
+        query['radius'] = radiusSelect.val();
+    }
+
+    function updateArea(long1, lat1, long2, lat2) {
+        area = [long1, lat1, long2, lat2];
+    }
+
+    // Does the given structure match the current query
+    function matchCurrentQuery(structure) {
+
+        // Filter by name
+        if (query['what'] && !structure.name.toLowerCase().includes(query['what'].toLowerCase())) {
+            return false;
+        }
+
+        // filter by geographical position
+        if (query['lat'] && query['long']) {
+            if (!structure.latitude || !structure.longitude) {
+                return false;
+            }
+
+            let radius = Number(query['radius']) ?? 0;
+
+            // radius is increased by 10km to approximate the city radius
+            radius += 10;
+
+            if (sphericDistance(query['lat'], query['long'], structure.latitude, structure.longitude) > radius) {
+                return false;
+            }
+        }
+
+        // filter by category
+        if (query['category'] && !structure.categories.includes(query['category'])) {
+            return false;
+        }
+
+        if (query['province']) {
+            let province = query['province'];
+
+            // A leading '_' may have been added to prevent the '0' from being stripped by fluid
+            province = province.replace('_', '');
+
+            if (!structure.postalCode.startsWith(province)) {
+                return false
+            }
+        }
+        if (query['federation'] && !structure.parents.includes(Number(query['federation']))) {
+            return false;
+        }
+
+        // filter by map bounds
+        if (area !== null) {
+            if (structure.longitude < area[0] ||
+                structure.latitude < area[1] ||
+                structure.longitude > area[2] ||
+                structure.latitude > area[3]
+            ) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    function populateFederationsSelect() {
+        federationSelect.children('option:not(:first)').remove();
+        let has_options = false;
+        structures.forEach(function (structure) {
+            if (structure.n1Id === organizationId && structure.principalType.endsWith('FEDERATION')) {
+                let id = structure['@id'].split('/').pop()
+                let option = '<option value="' + id + '">' + structure.name + '</option>';
+                federationSelect.append(option);
+                has_options = true;
+            }
+        })
+        if (has_options) {
+            federationSelect.prop("disabled", false);
+        }
+    }
+
+    // #### Display results
+    const itemsPerPage = 8;
+    let currentPage = 1;
+
+    updateQuery();
+
+    // on page link clicked event
+    function pageLinkClicked(e) {
+        e.preventDefault();
+        let page = $(this).data('page');
+        if (page > 0) {
+            currentPage = page;
+        }
+        refresh();
+        $('body,html').animate({scrollTop: 0},500);
+    }
+    gotoFirstPage.on('click', pageLinkClicked);
+    gotoLastPage.on('click', pageLinkClicked);
+
+    function refresh(listOnly=false) {
+
+        // Reinitialize current results
+        pleaseWaitSpan.show();
+        listenMapMoves = false;
+
+        resultsPageDiv.find('.structure-card').remove();
+        paginationList.find('.goto-page-li').remove();
+        paginationList.hide();
+        if (!listOnly && clusters !== null) {
+            map.removeLayer(clusters);
+        }
+
+        // ** Update results
+        let results = [];
+        structures.forEach(function(structure) {
+            if (matchCurrentQuery(structure)) {
+                results.push(structure)
+            }
+        });
+
+        // ** Show the results for the current page
+        let index = 0;
+
+        results.forEach(function(structure) {
+            if (((currentPage - 1) * itemsPerPage) <= index && index < (currentPage * itemsPerPage)) {
+                let cardDiv = $(cardDivModel).clone();
+
+                cardDiv.data('id', structure.id);
+
+                let categoryTagModel = cardDiv.find('.structure-category-model').first();
+                structure.categories.forEach(function (cat) {
+                    let tag = categoryTagModel.clone();
+                    tag.text(structures_categories[cat]);
+                    tag.removeClass('structure-category-model')
+                    tag.addClass('structure-category')
+                    tag.show();
+                    categoryTagModel.parent().append(tag);
+                });
+
+                cardDiv.find('.structure-poster').first().children('img').first().attr('src', structure.logoUri);
+                cardDiv.find('.structure-name').first().text(structure.name);
+                cardDiv.find('.structure-details-address').first().text(
+                    [structure.streetAddress, structure.postalCode, structure.addressCity].join(" ")
+                );
+                cardDiv.find('.structure-details-federation').first().text(structure.n1Name);
+
+                cardDiv.show();
+                cardDiv.removeClass('structure-card-model');
+                cardDiv.addClass('structure-card');
+                cardDiv.appendTo(resultsPageDiv);
+            }
+            index++;
+        });
+
+        // ** Update results on map
+        if (!listOnly) {
+            clusters = L.markerClusterGroup();
+
+            results.forEach(function (item) {
+                if (item.longitude && item.latitude) {
+                    let marker = L.marker([item.latitude, item.longitude]);
+                    marker.bindPopup(`<b>${item.name}</b><br/>${item.postalCode} ${item.addressCity}<br/><a href="${item.website}" target="_blank">${item.website}</a>`);
+                    clusters.addLayer(marker);
+                }
+            });
+            map.addLayer(clusters);
+        }
+
+        // ** Update pagination
+        let resultsCount = results.length;
+        let pagesCount = Math.floor(resultsCount / itemsPerPage) + 1;
+        gotoLastPage.data("page", pagesCount);
+
+        let pageLiModel = paginationList.find('.goto-page-li-model').first();
+
+        let page_min = currentPage > 5 ? currentPage - 5 : 1;
+        let page_max = currentPage < (pagesCount - 5) ? currentPage + 5 : pagesCount;
+
+        for (let i = page_min; i <= page_max; i++) {
+            let pageLi = pageLiModel.clone();
+
+            let pageLink = pageLi.children('a').first();
+
+            pageLink.text("" + i);
+            pageLink.attr("data-page", i);
+            pageLink.on('click', pageLinkClicked)
+
+            if (i === currentPage) {
+                pageLi.addClass('current');
+            }
+            pageLi.removeClass('goto-page-li-model')
+            pageLi.addClass('goto-page-li')
+
+            pageLi.show();
+
+            pageLi.appendTo(paginationList);
+        }
+        paginationBar.show()
+        paginationList.show()
+
+        // Finalize
+        pleaseWaitSpan.hide();
+        listenMapMoves = true;
+    }
+
+    function fitMapToResults() {
+        bounds = clusters.getBounds();
+        if (bounds.isValid()) {
+            map.fitBounds(bounds);
+        }
+    }
+
+    // #### Load structures data and refresh
+    var structures = [];
+    $.ajax({
+        type: 'GET',
+        url: apiGetUrl,
+        dataType: "json",
+        contentType: "application/json; charset=utf-8"
+    })
+    .done(function(res) {
+        structures = res["hydra:member"];
+        populateFederationsSelect();
+        refresh();
+    })
+    .fail(function() {
+        structureFrame.find(".error-message").show()
+    });
+
+
+    // #### Events
+
+    // Update query
+    form.on('submit', function(e) {
+        e.preventDefault();
+        updateQuery();
+        area = null;
+        currentPage = 1;
+        refresh();
+        if (Object.values(query).some((k) => k)) {
+            // if it's not an empty query, fit to results
+            fitMapToResults();
+        }
+    });
+
+    submitButton.on('click', function() {
+        form.submit();
+    });
+
+    $('.filters select', form).on('change', function() {
+        form.submit();
+    });
+
+    // Reset search fields
+    resetButton.on('click', function (e) {
+        e.preventDefault();
+        let form = $(this).closest('form');
+        form.find('input').each(function () {
+            $(this).val('');
+        });
+        form.find('select').each(function () {
+            $(this).val('');
+        });
+        resetMapBounds();
+        form.submit();
+    });
+
+    // Map goto commands
+    $('img[data-map-fit]').on('click', function (e) {
+        let goto = $(this).data('map-fit');
+        let corners = goto.split(";");
+        let p1 = corners[0].split(",");
+        let p2 = corners[1].split(",");
+        let bounds = L.latLngBounds(L.latLng(p1[0], p1[1]), L.latLng(p2[0], p2[1]));
+        map.fitBounds(bounds);
+    });
+
+    // Toggle structures list and map view
+    let filtersRow = form.find('.filters').first();
+    let buttonsRow = form.find('.search-buttons').first();
+
+    $('.activate-map-view').on('click', function (e) {
+        e.preventDefault();
+        if (structureFrame.hasClass('map-view')) {
+            // already in map view
+            return;
+        }
+        structureFrame.removeClass('list-view');
+        structureFrame.addClass('map-view');
+
+        // move reset and submit buttons
+        submitButton.appendTo(buttonsRow);
+        resetButton.prependTo(buttonsRow);
+        buttonsRow.show();
+    })
+    $('.activate-list-view').on('click', function (e) {
+        e.preventDefault();
+        if (structureFrame.hasClass('list-view')) {
+            // already in list view
+            return;
+        }
+        structureFrame.removeClass('map-view');
+        structureFrame.addClass('list-view');
+
+        // move reset and submit buttons
+        submitButton.appendTo(filtersRow);
+        resetButton.prependTo(filtersRow);
+        buttonsRow.hide();
+
+        resetButton.prependTo()
+
+
+        resetMapBounds();
+    })
+
+    // Filter results on map moves
+    map.on('zoomend moveend', function(e) {
+        if (listenMapMoves) {
+            let bounds = map.getBounds();
+            updateArea(bounds.getWest(), bounds.getSouth(), bounds.getEast(), bounds.getNorth())
+            refresh(true);
+        }
+    })
+
+    // ### Location filter
+    let addressApiUrl = "https://api-adresse.data.gouv.fr/search/?type=municipality&autocomplete=1&limit=5&q=";
+
+    let resultDropdownDiv = form.find('.city-search-dropdown').first();
+    let inputName = resultDropdownDiv.siblings("input[name='search-city']").first();
+    let inputLat = resultDropdownDiv.siblings("input[name='lat']").first();
+    let inputLong = resultDropdownDiv.siblings("input[name='long']").first();
+    let resultDiv = resultDropdownDiv.find('.city-search-results').first();
+    let loadingDiv = resultDropdownDiv.find('.city-search-loading').first();
+    let noResultDiv = resultDropdownDiv.find('.city-search-no-result').first();
+    let geolocButton = form.find("button[name='search-localize']").first();
+
+    function setNewLocation(name, long, lat) {
+        inputName.val(name);
+        inputLong.val(long);
+        inputLat.val(lat);
+        inputName.css("cursor", "pointer");
+        resultDropdownDiv.hide();
+        form.submit();
+    }
+
+    function hideCityResults() {
+        resultDropdownDiv.hide();
+        // if no city was selected, clear the input
+        if (!inputLat.val()) {
+            inputName.val('');
+            resultDiv.empty();
+        }
+        inputName.css("cursor", "inherit");
+    }
+
+    document.click(function() {
+        hideCityResults();
+    });
+
+    $(document).keyup(function(e) {
+        if(e.key === "Escape") {
+            hideCityResults();
+        }
+    });
+
+    inputName.click(function(e) {
+        if (resultDiv.children('.city-search-item').length > 0) {
+            resultDropdownDiv.show();
+        }
+        e.stopPropagation();
+    });
+
+    resultDiv.on('click', '.city-search-item', function (e) {
+        setNewLocation($(this).text(), $(this).data("x"), $(this).data("y"))
+        e.stopPropagation();
+    });
+
+    inputName.on('click', function(e) {
+        if ($(this).is(":focus")) {
+            $(this).val('');
+        }
+    });
+
+    function populateCitySearchResults() {
+        let query = inputName.val();
+        let url = addressApiUrl + encodeURI(query);
+
+        if (!query) {
+            resultDropdownDiv.hide();
+            return;
+        }
+
+        inputLat.val('');
+        inputLong.val('');
+        loadingDiv.show();
+        resultDiv.empty();
+        resultDropdownDiv.show();
+        noResultDiv.hide();
+
+        $.ajax({
+            type: 'GET',
+            url: url,
+            dataType: "json",
+            contentType: "application/json; charset=utf-8"
+        })
+        .done(function(res) {
+            let features = res.features;
+            if (!features.length > 0) {
+                noResultDiv.show();
+                return;
+            }
+            features.forEach(function (f) {
+                let x = f.geometry.coordinates[0];
+                let y = f.geometry.coordinates[1];
+                let name = f.properties.name;
+                let postcode = f.properties.postcode;
+                let span = '<div class="city-search-item" data-x="' + x + '" data-y="' + y + '">' + name + ' (' + postcode + ')</div>';
+                resultDiv.append(span);
+            });
+            loadingDiv.hide();
+        })
+        .fail(function(e) {
+            console.error(e);
+            loadingDiv.hide();
+        });
+    }
+
+    var runningPopulate = null;
+
+    inputName.on('input', function(e) {
+        if (runningPopulate !== null) {
+            window.clearTimeout(runningPopulate)
+        }
+        runningPopulate = window.setTimeout(populateCitySearchResults, 300);
+    });
+
+    geolocButton.on('click', function(e) {
+        if (navigator.geolocation) {
+            navigator.geolocation.getCurrentPosition(
+                function (geoloc) {
+                    setNewLocation(tr['around-me'], geoloc.coords.longitude, geoloc.coords.latitude)
+                    e.stopPropagation();
+                 },
+                function () {
+                    alert(tr['geoloc-unavailable']);
+                }
+            );
+            e.stopPropagation();
+        } else {
+            alert(tr['geoloc-unsupported']);
+        }
+    });
+});

File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-blue.css


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-blue.css.map


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-green.css


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-green.css.map


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-grey.css


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-grey.css.map


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-light-blue.css


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-light-blue.css.map


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-light-red.css


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-light-red.css.map


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-orange.css


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-orange.css.map


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-purple.css


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-purple.css.map


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-red.css


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-red.css.map


+ 60 - 0
ot_templating/Resources/Public/assets/Classic/style/ext/MarkerCluster.Default.css

@@ -0,0 +1,60 @@
+.marker-cluster-small {
+	background-color: rgba(181, 226, 140, 0.6);
+	}
+.marker-cluster-small div {
+	background-color: rgba(110, 204, 57, 0.6);
+	}
+
+.marker-cluster-medium {
+	background-color: rgba(241, 211, 87, 0.6);
+	}
+.marker-cluster-medium div {
+	background-color: rgba(240, 194, 12, 0.6);
+	}
+
+.marker-cluster-large {
+	background-color: rgba(253, 156, 115, 0.6);
+	}
+.marker-cluster-large div {
+	background-color: rgba(241, 128, 23, 0.6);
+	}
+
+	/* IE 6-8 fallback colors */
+.leaflet-oldie .marker-cluster-small {
+	background-color: rgb(181, 226, 140);
+	}
+.leaflet-oldie .marker-cluster-small div {
+	background-color: rgb(110, 204, 57);
+	}
+
+.leaflet-oldie .marker-cluster-medium {
+	background-color: rgb(241, 211, 87);
+	}
+.leaflet-oldie .marker-cluster-medium div {
+	background-color: rgb(240, 194, 12);
+	}
+
+.leaflet-oldie .marker-cluster-large {
+	background-color: rgb(253, 156, 115);
+	}
+.leaflet-oldie .marker-cluster-large div {
+	background-color: rgb(241, 128, 23);
+}
+
+.marker-cluster {
+	background-clip: padding-box;
+	border-radius: 20px;
+	}
+.marker-cluster div {
+	width: 30px;
+	height: 30px;
+	margin-left: 5px;
+	margin-top: 5px;
+
+	text-align: center;
+	border-radius: 15px;
+	font: 12px "Helvetica Neue", Arial, Helvetica, sans-serif;
+	}
+.marker-cluster span {
+	line-height: 30px;
+	}

+ 14 - 0
ot_templating/Resources/Public/assets/Classic/style/ext/MarkerCluster.css

@@ -0,0 +1,14 @@
+.leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow {
+	-webkit-transition: -webkit-transform 0.3s ease-out, opacity 0.3s ease-in;
+	-moz-transition: -moz-transform 0.3s ease-out, opacity 0.3s ease-in;
+	-o-transition: -o-transform 0.3s ease-out, opacity 0.3s ease-in;
+	transition: transform 0.3s ease-out, opacity 0.3s ease-in;
+}
+
+.leaflet-cluster-spider-leg {
+	/* stroke-dashoffset (duration and function) should match with leaflet-marker-icon transform in order to track it exactly */
+	-webkit-transition: -webkit-stroke-dashoffset 0.3s ease-out, -webkit-stroke-opacity 0.3s ease-in;
+	-moz-transition: -moz-stroke-dashoffset 0.3s ease-out, -moz-stroke-opacity 0.3s ease-in;
+	-o-transition: -o-stroke-dashoffset 0.3s ease-out, -o-stroke-opacity 0.3s ease-in;
+	transition: stroke-dashoffset 0.3s ease-out, stroke-opacity 0.3s ease-in;
+}

+ 1 - 1
ot_templating/Resources/Public/assets/Classic/style/module/_menu.scss

@@ -140,7 +140,7 @@ $submenu-item-height: 30px;
 #menu-container.sticky {
   position: fixed;
   top: 0;
-  z-index: 999;
+  z-index: 9999;
   //max-width: 60vw;
 }
 

+ 4 - 0
ot_templating/Resources/Public/assets/Classic/style/module/_pagination.scss

@@ -4,6 +4,8 @@ $content-a-color: $content-a-color;
   display: flex;
   flex-direction: row;
   margin: 12px auto;
+  align-items: center;
+  justify-content: center;
 }
 
 .pagination-bar p {
@@ -15,6 +17,8 @@ $content-a-color: $content-a-color;
   display: flex;
   flex-direction: row;
   flex-wrap: wrap;
+  margin: 0;
+  padding: 0 16px;
 }
 
 .pagination-bar li {

+ 452 - 0
ot_templating/Resources/Public/assets/Classic/style/module/_structures.scss

@@ -1,5 +1,9 @@
 // Structures page
 
+$btn-background-color: $menu-background-color;
+$btn-text-color: $menu-font-color;
+$input-border-color: #bfbfbf;
+
 .ot-structures {
   @include flex;
   flex-direction: row;
@@ -135,3 +139,451 @@
   }
 
 }
+
+// New template for the framed template structures
+.ot-structures-frame {
+  @include flex;
+  flex-direction: row;
+  flex-wrap: wrap;
+
+  header {
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-start;
+    width: 100%;
+    align-items: center;
+  }
+
+  h2 {
+    font-size: 21px;
+    font-weight: 750;
+    flex: 1;
+    text-align: left;
+    color: $btn-background-color;
+  }
+
+  header a {
+    padding: 3px;
+    margin: 2px;
+    font-weight: 500;
+  }
+
+  input, select {
+    height: 36px;
+    border: solid 1px $input-border-color;
+    border-radius: 0;
+  }
+
+  .structure-col {
+    @include flex;
+    flex-direction: column;
+    flex: 1;
+    max-width: 50%;
+    padding: 12px;
+    align-items: center;
+  }
+
+  .btn {
+    background-color: $btn-background-color;
+    border-radius: 4px;
+    padding: 8px;
+    font-weight: 750;
+    color: $btn-text-color;
+    text-align: center;
+  }
+
+  .spacer {
+    flex: 1;
+  }
+
+  // The wrapper role is to maintain the map's height equal to its width
+  // @see https://stackoverflow.com/a/14896313/4279120
+  #structure-map-wrapper {
+    position: relative;
+    width: 100%;
+    padding-bottom: 100%;
+    float: left;
+    height: 0;
+  }
+
+  #structure-map {
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    left: 0;
+  }
+
+  #structure-map a {
+    text-decoration: none;
+  }
+
+  #structure-map-bar {
+    margin: 16px 2% 6px 2%;
+    max-width: 100%;
+  }
+
+  #structure-map-bar .btn {
+    margin: 0 10%;
+  }
+
+  #overseas-provinces-list {
+    @include flex;
+    flex-direction: row;
+    list-style: none;
+    align-items: center;
+    flex-wrap: wrap;
+    padding: 0;
+  }
+
+  #overseas-provinces-list li {
+    border: solid 1px #000000;
+    height: 80px;
+    width: 80px;
+    margin: 0 6px 6px 0;
+  }
+
+  #overseas-provinces-list li img {
+    width: 100%;
+    max-width: 100%;
+    height: 100%;
+    cursor: pointer;
+  }
+
+  .structure-search {
+    width: 100%;
+  }
+
+  .structure-search form {
+    width: 100%;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .structure-search-row {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+    margin-bottom: 8px;
+  }
+
+  .search-bar-wrapper {
+    display: flex;
+    flex-direction: row;
+    height: 30px;
+    padding: 6px 2%;
+    border: solid 1px $input-border-color;
+    margin: 6px 0;
+    max-width: 44%;
+  }
+
+  .search-bar-wrapper:not(:last-child) {
+    margin-right: auto;
+  }
+
+  .search-bar {
+    flex: 1;
+    background: none;
+    outline: none;
+    height: auto;
+    font-size: 18px;
+    border: none;
+    width: 95%;
+  }
+
+  .search-bar-btn {
+    border: none;
+    background: none;
+    width: 5%;
+    min-width: 24px;
+    padding: 5px;
+    font-size: 18px;
+    cursor: pointer;
+    min-height: 32px;
+  }
+
+  .search-bar-btn .fas {
+    color: darken($input-border-color, 20);
+  }
+
+  .city-search-dropdown {
+    min-width: 100%;
+    position: relative;
+    display: inline-block;
+    top: -24px;
+    left: -24px;
+  }
+
+  .city-search-results, .city-search-no-result, .city-search-loading {
+    position: absolute;
+    min-width: 100%;
+    background: #EEEEEE;
+    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
+    z-index: 99;
+  }
+
+  .city-search-loading img {
+    padding:10px;
+    width:30px;
+  }
+
+  .city-search-item {
+    display: block;
+    padding: 12px 24px;
+    white-space: nowrap;
+  }
+
+  .city-search-item:hover {
+    background-color: #d9d9d9;
+    cursor: pointer;
+  }
+
+  .structure-search select {
+    color: $btn-background-color;
+    padding: 4px 6px;
+    margin: 3px 6px;
+    font-weight: 750;
+    width: 127px;
+    font-size: 12px;
+  }
+
+  .structure-search .reset-search {
+    background: none;
+    color: $btn-background-color;
+    margin: 0 6px 6px 6px;
+    cursor: pointer;
+    height: 36px;
+    border: solid 2px $btn-background-color;
+    border-radius: 0;
+  }
+
+  .structure-search .submit-search {
+    background-color: $btn-background-color;
+    color: $btn-text-color;
+    font-weight: 750;
+    margin: 0 6px 6px 6px;
+    cursor: pointer;
+    height: 36px;
+    border: none;
+    border-radius: 0;
+  }
+
+  .structure-results .structures-page {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+  }
+
+  .structure-card {
+    display: flex;
+    flex-direction: column;
+    width: 44%;
+    min-width: 240px;
+    border: solid 1px #cccccc;
+    border-radius: 4px;
+    padding: 12px 8px;
+    margin: 8px 1%;
+    background-color: #f2f2f2;
+  }
+
+  .structure-poster {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    margin: 8px;
+    min-width: 200px;
+  }
+
+  .structure-poster img {
+    width: auto;
+    height: auto;
+  }
+
+  .structure-details {
+    display: flex;
+    flex-direction: column;
+  }
+
+  .structure-details > * {
+    margin: 4px;
+  }
+
+  .structure-categories {
+    display: flex;
+    flex-direction: row;
+    min-height: 18px;
+  }
+
+  .structure-category {
+    background-color: #d9d9d9;
+    color: #262626;
+    font-size: 11px;
+    margin-right: 4px;
+    padding: 1px 5px;
+    height: 16px;
+    border-radius: 6px;
+  }
+
+  .structure-name {
+    font-size: 21px;
+    font-weight: 750;
+    width: 100%;
+    text-align: left;
+    color: $btn-background-color;
+  }
+
+  .structure-details-table tr {
+    background-color: #eeeeee !important;
+  }
+
+  .structure-details-table td {
+    border:none;
+  }
+
+  .structure-details-entry {
+    color: #595959;
+  }
+
+  .structure-details-entry .fas {
+    color: $btn-background-color;
+  }
+
+  .structure-see {
+    width: 128px;
+    max-height: 28px;
+    padding: 4px;
+    font-weight: 500;
+    margin-top: 8px;
+  }
+
+  .structure-see:hover {
+    text-decoration: none;
+    color: white;
+  }
+
+  .pagination-bar {
+    li a {
+      color: #4d4d4d;
+      font-weight: 600;
+    }
+
+    li.current a {
+      color: $btn-background-color;
+    }
+  }
+}
+
+.ot-structures-frame.list-view {
+  // List view changes
+
+  .structure-col-map {
+    display: none;
+  }
+
+  .structure-search form .search-buttons {
+  }
+
+  .search-bar-wrapper {
+    flex: 1;
+    max-width: none;
+  }
+
+  .search-bar-wrapper:not(:last-child) {
+    margin-right: 2%;
+  }
+
+  .structure-search-row.filters {
+    margin: 0 auto 12px auto;
+  }
+
+  .search-bar {
+    flex: 1;
+    max-width: none;
+  }
+
+  .filters select, .filters button {
+    height: 52px;
+    width: auto;
+  }
+
+  .filters button {
+    margin: 3px 6px;
+  }
+
+  .structure-col-results {
+    width: 100%;
+    max-width: 100%;
+  }
+
+  .structure-card {
+    width: 95%;
+    flex-direction: row;
+  }
+
+  .structure-card .spacer {
+    flex: 0; // disable spacer in list view
+  }
+
+  .structure-details {
+    flex: 1;
+  }
+
+  .structure-see {
+    align-self: flex-end;
+  }
+}
+
+.ot-structures-frame.map-view .activate-map-view {
+  font-weight: 750;
+}
+.ot-structures-frame.list-view .activate-list-view {
+  font-weight: 750;
+}
+
+// Small screens
+@media screen and (max-width: 700px) {
+  .ot-structures-frame {
+    flex-direction: column;
+    flex-wrap: nowrap;
+
+    .structure-col {
+      max-width: none;
+
+      // prevents content to be higher than the container
+      min-width: 100px;
+      overflow: hidden;
+    }
+
+    #overseas-provinces-list li {
+      margin: 0 auto 6px auto;
+      height: 90px;
+      width: 90px;
+    }
+
+    .structure-search-row {
+      flex-direction: column;
+    }
+
+    .search-bar-wrapper {
+      width: 95%;
+      max-width: 95%;
+      margin: 3px auto;
+    }
+
+    .search-bar-wrapper input {
+      width: auto;
+    }
+
+    .structure-search select {
+      width: 95%;
+      margin: 3px auto;
+    }
+
+    .structure-card {
+      width: 100%;
+    }
+
+    .list-view .structure-card {
+      flex-direction: column;
+    }
+  }
+}

File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/style.css


File diff suppressed because it is too large
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/style.css.map


+ 53 - 53
ot_templating/Resources/Public/assets/Modern/fonts/revicons.svg

@@ -1,54 +1,54 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg xmlns="http://www.w3.org/2000/svg">
-<metadata>Copyright (C) 2013 by original authors @ fontello.com</metadata>
-<defs>
-<font id="revicons" horiz-adv-x="1000" >
-<font-face font-family="revicons" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
-<missing-glyph horiz-adv-x="1000" />
-<glyph glyph-name="search" unicode="&#xe802;" d="m643 386q0 103-74 176t-176 74t-177-74t-73-176t73-177t177-73t176 73t74 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69q-80 0-153 31t-125 84t-84 125t-31 153t31 152t84 126t125 84t153 31t152-31t126-84t84-126t31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
-<glyph glyph-name="pencil-1" unicode="&#xe831;" d="m795 731c50-46 44-118-4-165l-46-46s35 53-37 123c-64 64-124 37-124 37l49 48c43 45 120 45 162 3z m-89-250l-492-493l-210-51l-4 4l55 210l493 490c8 2 30 9 60 2l-523-522l-15-55l60-60l56 15l25 24l3 56l-40 40l479 479c7-7 7-7 15-15c71-70 38-124 38-124z" horiz-adv-x="830" />
-<glyph glyph-name="picture-1" unicode="&#xe803;" d="m357 529q0-45-31-76t-76-32t-76 32t-31 76t31 75t76 32t76-32t31-75z m572-215v-250h-786v107l178 179l90-89l285 285z m53 393h-893q-7 0-12-5t-6-13v-678q0-8 6-13t12-5h893q7 0 13 5t5 13v678q0 7-5 13t-13 5z m89-18v-678q0-37-26-63t-63-27h-893q-36 0-63 27t-26 63v678q0 37 26 63t63 27h893q37 0 63-27t26-63z" horiz-adv-x="1071.4" />
-<glyph glyph-name="cancel" unicode="&#xe80a;" d="m724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165l-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164l-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164l164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164l164-164q15-15 15-38z" horiz-adv-x="785.7" />
-<glyph glyph-name="info-circled" unicode="&#xe80f;" d="m571 82v89q0 8-5 13t-12 5h-54v286q0 8-5 13t-13 5h-178q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h53v-179h-53q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h250q7 0 12 5t5 13z m-71 500v89q0 8-5 13t-13 5h-107q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h107q8 0 13 5t5 13z m357-232q0-117-57-215t-156-156t-215-58t-216 58t-155 156t-58 215t58 215t155 156t216 58t215-58t156-156t57-215z" horiz-adv-x="857.1" />
-<glyph glyph-name="trash" unicode="&#xe801;" d="m286 439v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m143 0v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m142 0v-321q0-8-5-13t-12-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q7 0 12-5t5-13z m72-404v529h-500v-529q0-12 4-22t8-15t6-5h464q2 0 6 5t8 15t4 22z m-375 601h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q22 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" />
-<glyph glyph-name="left-dir" unicode="&#xe817;" d="m357 600v-500q0-14-10-25t-26-11t-25 11l-250 250q-10 11-10 25t10 25l250 250q11 11 25 11t26-11t10-25z" horiz-adv-x="357.1" />
-<glyph glyph-name="right-dir" unicode="&#xe818;" d="m321 350q0-14-10-25l-250-250q-11-11-25-11t-25 11t-11 25v500q0 15 11 25t25 11t25-11l250-250q10-10 10-25z" horiz-adv-x="357.1" />
-<glyph glyph-name="down-open" unicode="&#xe83b;" d="m899 457q0-29-21-50l-363-363q-21-22-51-22q-30 0-50 22l-363 363q-21 20-21 50q0 30 21 51l41 42q22 20 51 20q29 0 50-20l271-271l271 271q21 20 51 20q29 0 50-20l42-42q21-22 21-51z" horiz-adv-x="928.6" />
-<glyph glyph-name="left-open" unicode="&#xe819;" d="m414-28l-364 364q-20 20-20 50t20 51l364 363q21 20 51 20t50-20l42-42q21-21 21-51t-21-50l-271-271l271-271q21-21 21-51t-21-50l-42-42q-21-20-50-20t-51 20z" horiz-adv-x="642.9" />
-<glyph glyph-name="right-open" unicode="&#xe81a;" d="m613 386q0-29-20-51l-364-363q-21-21-50-21t-51 21l-42 42q-21 21-21 50q0 30 21 51l271 271l-271 270q-21 22-21 51q0 30 21 50l42 42q20 21 51 21t50-21l364-363q20-21 20-50z" horiz-adv-x="642.9" />
-<glyph glyph-name="angle-left" unicode="&#xe820;" d="m350 546q0-7-6-12l-219-220l219-219q6-6 6-13t-6-13l-28-28q-5-5-12-5t-13 5l-260 260q-6 6-6 13t6 13l260 260q5 6 13 6t12-6l28-28q6-5 6-13z" horiz-adv-x="357.1" />
-<glyph glyph-name="angle-right" unicode="&#xe81d;" d="m332 314q0-7-6-13l-260-260q-5-5-12-5t-13 5l-28 28q-6 6-6 13t6 13l219 219l-219 220q-6 5-6 12t6 13l28 28q5 6 13 6t12-6l260-260q6-5 6-13z" horiz-adv-x="357.1" />
-<glyph glyph-name="left-big" unicode="&#xe81f;" d="m857 350v-71q0-30-18-51t-47-21h-393l164-164q21-20 21-50t-21-50l-42-43q-21-20-51-20q-29 0-50 20l-364 364q-20 21-20 50q0 29 20 51l364 363q21 21 50 21q29 0 51-21l42-42q21-21 21-50t-21-51l-164-164h393q29 0 47-20t18-51z" horiz-adv-x="857.1" />
-<glyph glyph-name="right-big" unicode="&#xe81e;" d="m821 314q0-30-20-50l-363-364q-22-20-51-20q-29 0-50 20l-42 42q-22 21-22 51t22 51l163 163h-393q-29 0-47 21t-18 51v71q0 30 18 51t47 20h393l-163 164q-22 21-22 51t22 50l42 42q21 21 50 21q29 0 51-21l363-363q20-20 20-51z" horiz-adv-x="857.1" />
-<glyph glyph-name="magic" unicode="&#xe807;" d="m664 526l164 163l-60 60l-164-164z m249 163q0-15-10-25l-717-718q-10-10-25-10t-25 10l-111 111q-10 10-10 25t10 25l718 718q10 10 25 10t25-10l110-111q10-10 10-25z m-753 106l54-16l-54-17l-17-55l-17 55l-55 17l55 16l17 55z m195-90l109-34l-109-33l-34-109l-33 109l-109 33l109 34l33 109z m519-267l55-17l-55-16l-17-55l-17 55l-54 16l54 17l17 55z m-357 357l54-16l-54-17l-17-55l-17 55l-54 17l54 16l17 55z" horiz-adv-x="928.6" />
-<glyph glyph-name="picture" unicode="&#xe800;" d="m856 518l-100 0l-124 150l-214-150l-180 0q-52 0-90-39t-38-91l0-160l-108 296q-10 38 22 52l680 248q36 10 50-24z m106-90q16 0 27-12t11-28l0-472q0-16-11-28t-27-12l-724 0q-16 0-27 12t-11 28l0 472q0 16 11 28t27 12l724 0z m-56-452l0 162l-72 160l-166-60l-130-132l-138 170l-92-214l0-86l598 0z" horiz-adv-x="1000" />
-<glyph glyph-name="export" unicode="&#xe80b;" d="m750 60l0 56l100 82l0-188q0-20-15-35t-35-15l-750 0q-20 0-35 15t-15 35l0 550q0 22 14 36t36 14l288 0q-32-24-59-49t-39-39l-10-12l-130 0l0-450l650 0z m-82 348q-166 0-242-41t-160-181q0 8 1 22t9 56t22 79t44 83t70 79t107 56t149 23l0 156l332-250l-332-260l0 178z" horiz-adv-x="1000" />
-<glyph glyph-name="cog" unicode="&#xe832;" d="m760 350q0-72 80-122q-12-40-34-82q-70 18-136-44q-54-58-34-136q-40-20-84-36q-46 82-132 82t-132-82q-44 16-84 36q20 80-34 136q-54 54-136 34q-14 26-34 82q82 52 82 132q0 72-82 124q20 56 34 82q74-18 136 44q54 56 34 136q42 22 84 34q46-80 132-80t132 80q42-12 84-34q-20-78 34-136q66-62 136-44q22-42 34-82q-80-50-80-124z m-340-182q76 0 129 53t53 129t-53 130t-129 54t-129-54t-53-130t53-129t129-53z" horiz-adv-x="840" />
-<glyph glyph-name="login" unicode="&#xe833;" d="m800 800q42 0 71-29t29-71l0-700q0-40-29-70t-71-30l-450 0q-40 0-69 30t-29 70l0 100l98 0l0-100l450 0l0 700l-450 0l0-150l-98 0l0 150q0 42 29 71t69 29l450 0z m-350-670l0 120l-450 0l0 150l450 0l0 120l200-194z" horiz-adv-x="900" />
-<glyph glyph-name="logout" unicode="&#xe834;" d="m502 0l0 100l98 0l0-100q0-40-29-70t-71-30l-400 0q-40 0-70 30t-30 70l0 700q0 42 30 71t70 29l400 0q42 0 71-29t29-71l0-150l-98 0l0 150l-402 0l0-700l402 0z m398 326l-198-196l0 120l-450 0l0 150l450 0l0 120z" horiz-adv-x="900" />
-<glyph glyph-name="video" unicode="&#xe805;" d="m214-43v72q0 14-10 25t-25 10h-72q-14 0-25-10t-11-25v-72q0-14 11-25t25-11h72q14 0 25 11t10 25z m0 214v72q0 14-10 25t-25 11h-72q-14 0-25-11t-11-25v-72q0-14 11-25t25-10h72q14 0 25 10t10 25z m0 215v71q0 15-10 25t-25 11h-72q-14 0-25-11t-11-25v-71q0-15 11-25t25-11h72q14 0 25 11t10 25z m572-429v286q0 14-11 25t-25 11h-429q-14 0-25-11t-10-25v-286q0-14 10-25t25-11h429q15 0 25 11t11 25z m-572 643v71q0 15-10 26t-25 10h-72q-14 0-25-10t-11-26v-71q0-15 11-25t25-11h72q14 0 25 11t10 25z m786-643v72q0 14-11 25t-25 10h-71q-15 0-25-10t-11-25v-72q0-14 11-25t25-11h71q15 0 25 11t11 25z m-214 429v285q0 15-11 26t-25 10h-429q-14 0-25-10t-10-26v-285q0-15 10-25t25-11h429q15 0 25 11t11 25z m214-215v72q0 14-11 25t-25 11h-71q-15 0-25-11t-11-25v-72q0-14 11-25t25-10h71q15 0 25 10t11 25z m0 215v71q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-71q0-15 11-25t25-11h71q15 0 25 11t11 25z m0 214v71q0 15-11 26t-25 10h-71q-15 0-25-10t-11-26v-71q0-15 11-25t25-11h71q15 0 25 11t11 25z m71 89v-750q0-37-26-63t-63-26h-893q-36 0-63 26t-26 63v750q0 37 26 63t63 27h893q37 0 63-27t26-63z" horiz-adv-x="1071.4" />
-<glyph glyph-name="arrow-combo" unicode="&#xe827;" d="m230 850l230-364l-460 0z m0-1000l-230 366l460 0z" horiz-adv-x="460" />
-<glyph glyph-name="left-open-1" unicode="&#xe82a;" d="m242 626q14 16 39 16t41-16q38-36 0-80l-186-196l186-194q38-44 0-80q-16-16-40-16t-40 16l-226 236q-16 16-16 38q0 24 16 40q206 214 226 236z" horiz-adv-x="341" />
-<glyph glyph-name="right-open-1" unicode="&#xe82b;" d="m98 626l226-236q16-16 16-40q0-22-16-38l-226-236q-16-16-40-16t-40 16q-36 36 0 80l186 194l-186 196q-36 44 0 80q16 16 41 16t39-16z" horiz-adv-x="340" />
-<glyph glyph-name="left-open-mini" unicode="&#xe822;" d="m252 180q26-26 0-48q-26-26-48 0l-192 194q-24 24 0 50l192 194q22 26 48 0q26-22 0-48l-156-172z" horiz-adv-x="265" />
-<glyph glyph-name="right-open-mini" unicode="&#xe823;" d="m13 180l158 170l-158 172q-26 26 0 48q26 26 48 0l192-194q24-26 0-50l-192-194q-22-26-48 0q-26 22 0 48z" horiz-adv-x="265" />
-<glyph glyph-name="left-open-big" unicode="&#xe824;" d="m452-20q26-26 0-48q-26-26-48 0l-392 394q-24 24 0 50l392 394q22 26 48 0q26-22 0-48l-358-372z" horiz-adv-x="465" />
-<glyph glyph-name="right-open-big" unicode="&#xe825;" d="m13-20l358 370l-358 372q-26 26 0 48q26 26 48 0l392-394q24-26 0-50l-392-394q-22-26-48 0q-26 22 0 48z" horiz-adv-x="465" />
-<glyph glyph-name="left" unicode="&#xe836;" d="m378 20l-378 330l378 330l0-190l352 0l0-278l-352 0l0-192z" horiz-adv-x="730" />
-<glyph glyph-name="right" unicode="&#xe826;" d="m350 680l380-330l-380-330l0 192l-350 0l0 278l350 0l0 190z" horiz-adv-x="730" />
-<glyph glyph-name="ccw" unicode="&#xe808;" d="m532 736q170 0 289-120t119-290t-119-290t-289-120q-142 0-252 88l70 74q84-60 182-60q126 0 216 90t90 218t-90 218t-216 90q-124 0-214-87t-92-211l142 0l-184-204l-184 204l124 0q2 166 122 283t286 117z" horiz-adv-x="940" />
-<glyph glyph-name="arrows-ccw" unicode="&#xe806;" d="m186 140l116 116l0-292l-276 16l88 86q-116 122-114 290t120 288q100 100 240 116l4-102q-100-16-172-88q-88-88-90-213t84-217z m332 598l276-16l-88-86q116-122 114-290t-120-288q-96-98-240-118l-2 104q98 16 170 88q88 88 90 213t-84 217l-114-116z" horiz-adv-x="820" />
-<glyph glyph-name="palette" unicode="&#xe829;" d="m857 622q72-48 101-110t20-104t-35-48q-16-4-54 10t-80 10t-80-46q-30-46-21-75t34-65t23-50q-2-26-36-63t-126-74t-216-37q-186 0-291 101t-95 245q8 118 104 235t216 151q290 84 536-80z m-318-466q30 0 52 22t22 54t-22 53t-52 21q-32 0-54-21t-22-53t22-54t54-22z" horiz-adv-x="980" />
-<glyph glyph-name="list-add" unicode="&#xe80c;" d="m350 400q22 0 36-15t14-35t-15-35t-35-15l-300 0q-20 0-35 15t-15 35t14 35t36 15l300 0z m0-200q22 0 36-15t14-35t-15-35t-35-15l-300 0q-20 0-35 15t-15 35t14 35t36 15l300 0z m620 200q30 0 30-50t-30-50l-170 0l0-170q0-30-50-30t-50 30l0 170l-164 0q-30 0-30 50t30 50l164 0l0 170q0 30 50 30t50-30l0-170l170 0z m-620 200q22 0 36-15t14-35t-15-35t-35-15l-300 0q-20 0-35 15t-15 35t14 35t36 15l300 0z" horiz-adv-x="1000" />
-<glyph glyph-name="doc" unicode="&#xe809;" d="m818 595q16-16 16-36l0-521q0-65-46-111t-110-46l-522 0q-65 0-110 46t-46 111l0 625q0 65 46 110t110 46l417 0q22 0 37-15z m-110-36l-135 134l0-56q0-32 23-55t55-23l57 0z m-30-574q21 0 36 16t15 37l0 469l-78 0q-53 0-92 38t-38 92l0 78l-365 0q-21 0-37-15t-15-37l0-625q0-21 15-37t37-16l522 0z" horiz-adv-x="834" />
-<glyph glyph-name="left-open-outline" unicode="&#xe82e;" d="m638 91q0-64-47-111t-110-46q-65 0-110 45l-371 372l371 371q44 44 111 44t111-44q45-45 45-111q0-65-45-110l-150-150l150-150q45-45 45-110z m-490 260l297-298q15-15 37-15t37 15t15 38q0 21-15 36l-224 224l224 223q15 15 15 37q0 22-15 37t-37 15t-37-15z" horiz-adv-x="638" />
-<glyph glyph-name="left-open-2" unicode="&#xe82c;" d="m481 684q32-31 32-74t-32-74l-186-186l186-186q32-31 32-74t-32-74t-73-31t-74 31l-334 334l334 334q30 31 74 31t73-31z" horiz-adv-x="513" />
-<glyph glyph-name="right-open-outline" unicode="&#xe82f;" d="m156-66q-63 0-110 46t-46 111t46 110l150 150l-150 150q-46 46-46 110q0 65 46 111q44 44 110 44t110-44l372-371l-372-372q-45-45-110-45z m0 729q-21 0-37-16t-15-36q0-20 16-37l223-223l-223-224q-16-16-16-36q0-22 16-38q15-15 36-15t37 15l297 298l-297 297q-15 15-37 15z" horiz-adv-x="638" />
-<glyph glyph-name="right-open-2" unicode="&#xe82d;" d="m31 684q30 31 74 31t74-31l335-334l-335-334q-31-31-74-31t-74 31t-31 74t31 74l188 186l-188 186q-31 32-31 74t31 74z" horiz-adv-x="514" />
-<glyph glyph-name="equalizer" unicode="&#xe83a;" d="m576 239l0-112l-55 0l0-167q0-23-17-40t-39-17t-39 17t-17 40l0 167l-56 0l0 112l56 0l0 503q0 24 17 39t38 16q24 0 41-16t16-39l0-503l55 0z m335 335l0-112l-55 0l0-502q0-23-16-40t-41-17q-23 0-39 17t-16 40l0 502l-56 0l0 112l56 0l0 168q0 24 16 39t39 16t41-16t16-39l0-168l55 0z m-670-112l0-111l-55 0l0-391q0-23-16-40t-40-17q-23 0-39 17t-17 40l0 391l-56 0l0 111l56 0l0 280q0 24 16 39t40 16t40-16t16-39l0-280l55 0z" horiz-adv-x="928" />
-<glyph glyph-name="layers-alt" unicode="&#xe804;" d="m18 127l446-111l447 111l0-111l-447-113l-446 113l0 111z m0 224l446-112l447 112l0-112l-447-112l-446 112l0 112z m0 223l446-112l447 112l0-112l-447-111l-446 111l0 112z m0 223l446-112l447 112l0-112l-447-111l-446 111l0 112z" horiz-adv-x="928" />
-<glyph glyph-name="popup" unicode="&#xe828;" d="m700 750q42 0 71-29t29-71l0-400q0-40-29-70t-71-30l-400 0q-40 0-70 30t-30 70l0 402q0 40 29 69t71 29l400 0z m0-500l0 400l-400 0l0-400l400 0z m-600 100l0-300l300 0l0-100l-300 0q-40 0-70 30t-30 70l0 300l100 0z" horiz-adv-x="800" />
-</font>
-</defs>
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata>Copyright (C) 2013 by original authors @ fontello.com</metadata>
+<defs>
+<font id="revicons" horiz-adv-x="1000" >
+<font-face font-family="revicons" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
+<missing-glyph horiz-adv-x="1000" />
+<glyph glyph-name="search" unicode="&#xe802;" d="m643 386q0 103-74 176t-176 74t-177-74t-73-176t73-177t177-73t176 73t74 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69q-80 0-153 31t-125 84t-84 125t-31 153t31 152t84 126t125 84t153 31t152-31t126-84t84-126t31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
+<glyph glyph-name="pencil-1" unicode="&#xe831;" d="m795 731c50-46 44-118-4-165l-46-46s35 53-37 123c-64 64-124 37-124 37l49 48c43 45 120 45 162 3z m-89-250l-492-493l-210-51l-4 4l55 210l493 490c8 2 30 9 60 2l-523-522l-15-55l60-60l56 15l25 24l3 56l-40 40l479 479c7-7 7-7 15-15c71-70 38-124 38-124z" horiz-adv-x="830" />
+<glyph glyph-name="picture-1" unicode="&#xe803;" d="m357 529q0-45-31-76t-76-32t-76 32t-31 76t31 75t76 32t76-32t31-75z m572-215v-250h-786v107l178 179l90-89l285 285z m53 393h-893q-7 0-12-5t-6-13v-678q0-8 6-13t12-5h893q7 0 13 5t5 13v678q0 7-5 13t-13 5z m89-18v-678q0-37-26-63t-63-27h-893q-36 0-63 27t-26 63v678q0 37 26 63t63 27h893q37 0 63-27t26-63z" horiz-adv-x="1071.4" />
+<glyph glyph-name="cancel" unicode="&#xe80a;" d="m724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165l-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164l-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164l164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164l164-164q15-15 15-38z" horiz-adv-x="785.7" />
+<glyph glyph-name="info-circled" unicode="&#xe80f;" d="m571 82v89q0 8-5 13t-12 5h-54v286q0 8-5 13t-13 5h-178q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h53v-179h-53q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h250q7 0 12 5t5 13z m-71 500v89q0 8-5 13t-13 5h-107q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h107q8 0 13 5t5 13z m357-232q0-117-57-215t-156-156t-215-58t-216 58t-155 156t-58 215t58 215t155 156t216 58t215-58t156-156t57-215z" horiz-adv-x="857.1" />
+<glyph glyph-name="trash" unicode="&#xe801;" d="m286 439v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m143 0v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m142 0v-321q0-8-5-13t-12-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q7 0 12-5t5-13z m72-404v529h-500v-529q0-12 4-22t8-15t6-5h464q2 0 6 5t8 15t4 22z m-375 601h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q22 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" />
+<glyph glyph-name="left-dir" unicode="&#xe817;" d="m357 600v-500q0-14-10-25t-26-11t-25 11l-250 250q-10 11-10 25t10 25l250 250q11 11 25 11t26-11t10-25z" horiz-adv-x="357.1" />
+<glyph glyph-name="right-dir" unicode="&#xe818;" d="m321 350q0-14-10-25l-250-250q-11-11-25-11t-25 11t-11 25v500q0 15 11 25t25 11t25-11l250-250q10-10 10-25z" horiz-adv-x="357.1" />
+<glyph glyph-name="down-open" unicode="&#xe83b;" d="m899 457q0-29-21-50l-363-363q-21-22-51-22q-30 0-50 22l-363 363q-21 20-21 50q0 30 21 51l41 42q22 20 51 20q29 0 50-20l271-271l271 271q21 20 51 20q29 0 50-20l42-42q21-22 21-51z" horiz-adv-x="928.6" />
+<glyph glyph-name="left-open" unicode="&#xe819;" d="m414-28l-364 364q-20 20-20 50t20 51l364 363q21 20 51 20t50-20l42-42q21-21 21-51t-21-50l-271-271l271-271q21-21 21-51t-21-50l-42-42q-21-20-50-20t-51 20z" horiz-adv-x="642.9" />
+<glyph glyph-name="right-open" unicode="&#xe81a;" d="m613 386q0-29-20-51l-364-363q-21-21-50-21t-51 21l-42 42q-21 21-21 50q0 30 21 51l271 271l-271 270q-21 22-21 51q0 30 21 50l42 42q20 21 51 21t50-21l364-363q20-21 20-50z" horiz-adv-x="642.9" />
+<glyph glyph-name="angle-left" unicode="&#xe820;" d="m350 546q0-7-6-12l-219-220l219-219q6-6 6-13t-6-13l-28-28q-5-5-12-5t-13 5l-260 260q-6 6-6 13t6 13l260 260q5 6 13 6t12-6l28-28q6-5 6-13z" horiz-adv-x="357.1" />
+<glyph glyph-name="angle-right" unicode="&#xe81d;" d="m332 314q0-7-6-13l-260-260q-5-5-12-5t-13 5l-28 28q-6 6-6 13t6 13l219 219l-219 220q-6 5-6 12t6 13l28 28q5 6 13 6t12-6l260-260q6-5 6-13z" horiz-adv-x="357.1" />
+<glyph glyph-name="left-big" unicode="&#xe81f;" d="m857 350v-71q0-30-18-51t-47-21h-393l164-164q21-20 21-50t-21-50l-42-43q-21-20-51-20q-29 0-50 20l-364 364q-20 21-20 50q0 29 20 51l364 363q21 21 50 21q29 0 51-21l42-42q21-21 21-50t-21-51l-164-164h393q29 0 47-20t18-51z" horiz-adv-x="857.1" />
+<glyph glyph-name="right-big" unicode="&#xe81e;" d="m821 314q0-30-20-50l-363-364q-22-20-51-20q-29 0-50 20l-42 42q-22 21-22 51t22 51l163 163h-393q-29 0-47 21t-18 51v71q0 30 18 51t47 20h393l-163 164q-22 21-22 51t22 50l42 42q21 21 50 21q29 0 51-21l363-363q20-20 20-51z" horiz-adv-x="857.1" />
+<glyph glyph-name="magic" unicode="&#xe807;" d="m664 526l164 163l-60 60l-164-164z m249 163q0-15-10-25l-717-718q-10-10-25-10t-25 10l-111 111q-10 10-10 25t10 25l718 718q10 10 25 10t25-10l110-111q10-10 10-25z m-753 106l54-16l-54-17l-17-55l-17 55l-55 17l55 16l17 55z m195-90l109-34l-109-33l-34-109l-33 109l-109 33l109 34l33 109z m519-267l55-17l-55-16l-17-55l-17 55l-54 16l54 17l17 55z m-357 357l54-16l-54-17l-17-55l-17 55l-54 17l54 16l17 55z" horiz-adv-x="928.6" />
+<glyph glyph-name="picture" unicode="&#xe800;" d="m856 518l-100 0l-124 150l-214-150l-180 0q-52 0-90-39t-38-91l0-160l-108 296q-10 38 22 52l680 248q36 10 50-24z m106-90q16 0 27-12t11-28l0-472q0-16-11-28t-27-12l-724 0q-16 0-27 12t-11 28l0 472q0 16 11 28t27 12l724 0z m-56-452l0 162l-72 160l-166-60l-130-132l-138 170l-92-214l0-86l598 0z" horiz-adv-x="1000" />
+<glyph glyph-name="export" unicode="&#xe80b;" d="m750 60l0 56l100 82l0-188q0-20-15-35t-35-15l-750 0q-20 0-35 15t-15 35l0 550q0 22 14 36t36 14l288 0q-32-24-59-49t-39-39l-10-12l-130 0l0-450l650 0z m-82 348q-166 0-242-41t-160-181q0 8 1 22t9 56t22 79t44 83t70 79t107 56t149 23l0 156l332-250l-332-260l0 178z" horiz-adv-x="1000" />
+<glyph glyph-name="cog" unicode="&#xe832;" d="m760 350q0-72 80-122q-12-40-34-82q-70 18-136-44q-54-58-34-136q-40-20-84-36q-46 82-132 82t-132-82q-44 16-84 36q20 80-34 136q-54 54-136 34q-14 26-34 82q82 52 82 132q0 72-82 124q20 56 34 82q74-18 136 44q54 56 34 136q42 22 84 34q46-80 132-80t132 80q42-12 84-34q-20-78 34-136q66-62 136-44q22-42 34-82q-80-50-80-124z m-340-182q76 0 129 53t53 129t-53 130t-129 54t-129-54t-53-130t53-129t129-53z" horiz-adv-x="840" />
+<glyph glyph-name="login" unicode="&#xe833;" d="m800 800q42 0 71-29t29-71l0-700q0-40-29-70t-71-30l-450 0q-40 0-69 30t-29 70l0 100l98 0l0-100l450 0l0 700l-450 0l0-150l-98 0l0 150q0 42 29 71t69 29l450 0z m-350-670l0 120l-450 0l0 150l450 0l0 120l200-194z" horiz-adv-x="900" />
+<glyph glyph-name="logout" unicode="&#xe834;" d="m502 0l0 100l98 0l0-100q0-40-29-70t-71-30l-400 0q-40 0-70 30t-30 70l0 700q0 42 30 71t70 29l400 0q42 0 71-29t29-71l0-150l-98 0l0 150l-402 0l0-700l402 0z m398 326l-198-196l0 120l-450 0l0 150l450 0l0 120z" horiz-adv-x="900" />
+<glyph glyph-name="video" unicode="&#xe805;" d="m214-43v72q0 14-10 25t-25 10h-72q-14 0-25-10t-11-25v-72q0-14 11-25t25-11h72q14 0 25 11t10 25z m0 214v72q0 14-10 25t-25 11h-72q-14 0-25-11t-11-25v-72q0-14 11-25t25-10h72q14 0 25 10t10 25z m0 215v71q0 15-10 25t-25 11h-72q-14 0-25-11t-11-25v-71q0-15 11-25t25-11h72q14 0 25 11t10 25z m572-429v286q0 14-11 25t-25 11h-429q-14 0-25-11t-10-25v-286q0-14 10-25t25-11h429q15 0 25 11t11 25z m-572 643v71q0 15-10 26t-25 10h-72q-14 0-25-10t-11-26v-71q0-15 11-25t25-11h72q14 0 25 11t10 25z m786-643v72q0 14-11 25t-25 10h-71q-15 0-25-10t-11-25v-72q0-14 11-25t25-11h71q15 0 25 11t11 25z m-214 429v285q0 15-11 26t-25 10h-429q-14 0-25-10t-10-26v-285q0-15 10-25t25-11h429q15 0 25 11t11 25z m214-215v72q0 14-11 25t-25 11h-71q-15 0-25-11t-11-25v-72q0-14 11-25t25-10h71q15 0 25 10t11 25z m0 215v71q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-71q0-15 11-25t25-11h71q15 0 25 11t11 25z m0 214v71q0 15-11 26t-25 10h-71q-15 0-25-10t-11-26v-71q0-15 11-25t25-11h71q15 0 25 11t11 25z m71 89v-750q0-37-26-63t-63-26h-893q-36 0-63 26t-26 63v750q0 37 26 63t63 27h893q37 0 63-27t26-63z" horiz-adv-x="1071.4" />
+<glyph glyph-name="arrow-combo" unicode="&#xe827;" d="m230 850l230-364l-460 0z m0-1000l-230 366l460 0z" horiz-adv-x="460" />
+<glyph glyph-name="left-open-1" unicode="&#xe82a;" d="m242 626q14 16 39 16t41-16q38-36 0-80l-186-196l186-194q38-44 0-80q-16-16-40-16t-40 16l-226 236q-16 16-16 38q0 24 16 40q206 214 226 236z" horiz-adv-x="341" />
+<glyph glyph-name="right-open-1" unicode="&#xe82b;" d="m98 626l226-236q16-16 16-40q0-22-16-38l-226-236q-16-16-40-16t-40 16q-36 36 0 80l186 194l-186 196q-36 44 0 80q16 16 41 16t39-16z" horiz-adv-x="340" />
+<glyph glyph-name="left-open-mini" unicode="&#xe822;" d="m252 180q26-26 0-48q-26-26-48 0l-192 194q-24 24 0 50l192 194q22 26 48 0q26-22 0-48l-156-172z" horiz-adv-x="265" />
+<glyph glyph-name="right-open-mini" unicode="&#xe823;" d="m13 180l158 170l-158 172q-26 26 0 48q26 26 48 0l192-194q24-26 0-50l-192-194q-22-26-48 0q-26 22 0 48z" horiz-adv-x="265" />
+<glyph glyph-name="left-open-big" unicode="&#xe824;" d="m452-20q26-26 0-48q-26-26-48 0l-392 394q-24 24 0 50l392 394q22 26 48 0q26-22 0-48l-358-372z" horiz-adv-x="465" />
+<glyph glyph-name="right-open-big" unicode="&#xe825;" d="m13-20l358 370l-358 372q-26 26 0 48q26 26 48 0l392-394q24-26 0-50l-392-394q-22-26-48 0q-26 22 0 48z" horiz-adv-x="465" />
+<glyph glyph-name="left" unicode="&#xe836;" d="m378 20l-378 330l378 330l0-190l352 0l0-278l-352 0l0-192z" horiz-adv-x="730" />
+<glyph glyph-name="right" unicode="&#xe826;" d="m350 680l380-330l-380-330l0 192l-350 0l0 278l350 0l0 190z" horiz-adv-x="730" />
+<glyph glyph-name="ccw" unicode="&#xe808;" d="m532 736q170 0 289-120t119-290t-119-290t-289-120q-142 0-252 88l70 74q84-60 182-60q126 0 216 90t90 218t-90 218t-216 90q-124 0-214-87t-92-211l142 0l-184-204l-184 204l124 0q2 166 122 283t286 117z" horiz-adv-x="940" />
+<glyph glyph-name="arrows-ccw" unicode="&#xe806;" d="m186 140l116 116l0-292l-276 16l88 86q-116 122-114 290t120 288q100 100 240 116l4-102q-100-16-172-88q-88-88-90-213t84-217z m332 598l276-16l-88-86q116-122 114-290t-120-288q-96-98-240-118l-2 104q98 16 170 88q88 88 90 213t-84 217l-114-116z" horiz-adv-x="820" />
+<glyph glyph-name="palette" unicode="&#xe829;" d="m857 622q72-48 101-110t20-104t-35-48q-16-4-54 10t-80 10t-80-46q-30-46-21-75t34-65t23-50q-2-26-36-63t-126-74t-216-37q-186 0-291 101t-95 245q8 118 104 235t216 151q290 84 536-80z m-318-466q30 0 52 22t22 54t-22 53t-52 21q-32 0-54-21t-22-53t22-54t54-22z" horiz-adv-x="980" />
+<glyph glyph-name="list-add" unicode="&#xe80c;" d="m350 400q22 0 36-15t14-35t-15-35t-35-15l-300 0q-20 0-35 15t-15 35t14 35t36 15l300 0z m0-200q22 0 36-15t14-35t-15-35t-35-15l-300 0q-20 0-35 15t-15 35t14 35t36 15l300 0z m620 200q30 0 30-50t-30-50l-170 0l0-170q0-30-50-30t-50 30l0 170l-164 0q-30 0-30 50t30 50l164 0l0 170q0 30 50 30t50-30l0-170l170 0z m-620 200q22 0 36-15t14-35t-15-35t-35-15l-300 0q-20 0-35 15t-15 35t14 35t36 15l300 0z" horiz-adv-x="1000" />
+<glyph glyph-name="doc" unicode="&#xe809;" d="m818 595q16-16 16-36l0-521q0-65-46-111t-110-46l-522 0q-65 0-110 46t-46 111l0 625q0 65 46 110t110 46l417 0q22 0 37-15z m-110-36l-135 134l0-56q0-32 23-55t55-23l57 0z m-30-574q21 0 36 16t15 37l0 469l-78 0q-53 0-92 38t-38 92l0 78l-365 0q-21 0-37-15t-15-37l0-625q0-21 15-37t37-16l522 0z" horiz-adv-x="834" />
+<glyph glyph-name="left-open-outline" unicode="&#xe82e;" d="m638 91q0-64-47-111t-110-46q-65 0-110 45l-371 372l371 371q44 44 111 44t111-44q45-45 45-111q0-65-45-110l-150-150l150-150q45-45 45-110z m-490 260l297-298q15-15 37-15t37 15t15 38q0 21-15 36l-224 224l224 223q15 15 15 37q0 22-15 37t-37 15t-37-15z" horiz-adv-x="638" />
+<glyph glyph-name="left-open-2" unicode="&#xe82c;" d="m481 684q32-31 32-74t-32-74l-186-186l186-186q32-31 32-74t-32-74t-73-31t-74 31l-334 334l334 334q30 31 74 31t73-31z" horiz-adv-x="513" />
+<glyph glyph-name="right-open-outline" unicode="&#xe82f;" d="m156-66q-63 0-110 46t-46 111t46 110l150 150l-150 150q-46 46-46 110q0 65 46 111q44 44 110 44t110-44l372-371l-372-372q-45-45-110-45z m0 729q-21 0-37-16t-15-36q0-20 16-37l223-223l-223-224q-16-16-16-36q0-22 16-38q15-15 36-15t37 15l297 298l-297 297q-15 15-37 15z" horiz-adv-x="638" />
+<glyph glyph-name="right-open-2" unicode="&#xe82d;" d="m31 684q30 31 74 31t74-31l335-334l-335-334q-31-31-74-31t-74 31t-31 74t31 74l188 186l-188 186q-31 32-31 74t31 74z" horiz-adv-x="514" />
+<glyph glyph-name="equalizer" unicode="&#xe83a;" d="m576 239l0-112l-55 0l0-167q0-23-17-40t-39-17t-39 17t-17 40l0 167l-56 0l0 112l56 0l0 503q0 24 17 39t38 16q24 0 41-16t16-39l0-503l55 0z m335 335l0-112l-55 0l0-502q0-23-16-40t-41-17q-23 0-39 17t-16 40l0 502l-56 0l0 112l56 0l0 168q0 24 16 39t39 16t41-16t16-39l0-168l55 0z m-670-112l0-111l-55 0l0-391q0-23-16-40t-40-17q-23 0-39 17t-17 40l0 391l-56 0l0 111l56 0l0 280q0 24 16 39t40 16t40-16t16-39l0-280l55 0z" horiz-adv-x="928" />
+<glyph glyph-name="layers-alt" unicode="&#xe804;" d="m18 127l446-111l447 111l0-111l-447-113l-446 113l0 111z m0 224l446-112l447 112l0-112l-447-112l-446 112l0 112z m0 223l446-112l447 112l0-112l-447-111l-446 111l0 112z m0 223l446-112l447 112l0-112l-447-111l-446 111l0 112z" horiz-adv-x="928" />
+<glyph glyph-name="popup" unicode="&#xe828;" d="m700 750q42 0 71-29t29-71l0-400q0-40-29-70t-71-30l-400 0q-40 0-70 30t-30 70l0 402q0 40 29 69t71 29l400 0z m0-500l0 400l-400 0l0-400l400 0z m-600 100l0-300l300 0l0-100l-300 0q-40 0-70 30t-30 70l0 300l100 0z" horiz-adv-x="800" />
+</font>
+</defs>
 </svg>

+ 3 - 2
ot_templating/Resources/Public/assets/Modern/style/custom.css

@@ -1202,10 +1202,11 @@ iframe {
     display: flex;
     flex-direction: row;
     margin: 12px auto;
+    align-items: center;
 }
 
-.pagination-bar p {
-    margin: 4px;
+.pagination-bar a {
+    padding: 0 4px;
 }
 
 .pagination-bar ul {

BIN
ot_templating/Resources/Public/media/gear.gif


BIN
ot_templating/Resources/Public/media/guadeloupe.png


BIN
ot_templating/Resources/Public/media/guyane.png


BIN
ot_templating/Resources/Public/media/la_reunion.png


BIN
ot_templating/Resources/Public/media/martinique.png


BIN
ot_templating/Resources/Public/media/mayotte.png


BIN
ot_templating/Resources/Public/media/metropole.png


Some files were not shown because too many files changed in this diff