فهرست منبع

load all structures and add js pagination

Olivier Massot 4 سال پیش
والد
کامیت
7672b7afb4
24فایلهای تغییر یافته به همراه275 افزوده شده و 92 حذف شده
  1. 0 2
      ot_templating/Classes/ViewHelpers/PaginationViewHelper.php
  2. 73 0
      ot_templating/Classes/ViewHelpers/Utilities/PaginateArrayViewHelper.php
  3. 58 0
      ot_templating/Classes/ViewHelpers/Utilities/RangeViewHelper.php
  4. 94 67
      ot_templating/Resources/Private/Layouts/Classic/Structures.html
  5. 49 22
      ot_templating/Resources/Public/assets/Classic/script/main.js
  6. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-blue.css
  7. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-blue.css.map
  8. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-green.css
  9. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-green.css.map
  10. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-grey.css
  11. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-grey.css.map
  12. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-light-blue.css
  13. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-light-blue.css.map
  14. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-light-red.css
  15. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-light-red.css.map
  16. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-orange.css
  17. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-orange.css.map
  18. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-purple.css
  19. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-purple.css.map
  20. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-red.css
  21. 0 0
      ot_templating/Resources/Public/assets/Classic/style/classic-red.css.map
  22. 1 1
      ot_templating/Resources/Public/assets/Classic/style/module/_structures.scss
  23. 0 0
      ot_templating/Resources/Public/assets/Classic/style/style.css
  24. 0 0
      ot_templating/Resources/Public/assets/Classic/style/style.css.map

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

@@ -3,8 +3,6 @@
 namespace Opentalent\OtTemplating\ViewHelpers;
 
 use Opentalent\OtCore\ViewHelpers\OtAbstractViewHelper;
-use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
-use TYPO3\CMS\Fluid\ViewHelpers\TranslateViewHelper;
 
 /**
  *

+ 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;
+    }
+}

+ 94 - 67
ot_templating/Resources/Private/Layouts/Classic/Structures.html

@@ -11,23 +11,19 @@
     <f:comment><!-- Central column --></f:comment>
     <div class="content">
         <f:comment><!-- All members --></f:comment>
-        <div class="ot-structures map-view">
 
-            <ot:organizations.getFederationStructures as="structuresCollection"
-                                                      parentId="{settings.organizationId}">
+        <ot:organizations.getFederationStructures as="structuresCollection"
+                                                  parentId="{settings.organizationId}"
+                                                  itemsPerPage="all">
+
+            <f:comment><!-- The data is stored as an attribute, then templated with JS for performance reasons --></f:comment>
+            <div class="ot-structures map-view" data-structures="{v:format.json.encode(value:structuresCollection.members)}">
 
                 <div class="structure-col structure-col-map">
-                    <ot:organizations.getFederationStructures as="allStructuresCollection"
-                                                              parentId="{settings.organizationId}"
-                                                              itemsPerPage="all">
-                        <div id="structure-map-wrapper">
-                            <div id="structure-map"
-                                 data-all-structures="{ot:organizations.asGeoMarkersArray(structures:allStructuresCollection.members)}"
-                                 data-selected-structures="{ot:organizations.asGeoMarkersArray(structures:structuresCollection.members)}"
-                            >
-                            </div>
+                    <div id="structure-map-wrapper">
+                        <div id="structure-map">
                         </div>
-                    </ot:organizations.getFederationStructures>
+                    </div>
 
                     <div id="structure-map-bar">
                         <div class="btn">{f:translate(key: 'click-on-land-to-go-there')}</div>
@@ -96,67 +92,98 @@
                             <span><f:translate key="no-result"/></span>
                         </f:if>
 
-                        <f:for each="{structuresCollection.members}" as="structure" iteration="it">
-
-                            <div class="structure-card" data-id="{structure.id}">
-
-                                <div class="structure-poster">
-                                    <f:if condition="{structure.logoId}">
-                                        <f:then>
-                                            <img src='{structure.logoId}' alt="poster" />
-                                        </f:then>
-                                        <f:else>
-                                            <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
-                                        </f:else>
-                                    </f:if>
-                                </div>
-
-                                <div class="structure-details">
-                                    <f:comment>
-                                        <!--                                    <div class="structure-categories">-->
-<!--                                        <f:for each="{structure.categories}" as="category">-->
-<!--                                            <span class="structure-category">-->
-<!--                                                <f:translate key="{category}"/>-->
-<!--                                            </span>-->
-<!--                                        </f:for>-->
-<!--                                    </div>--></f:comment>
-
-                                    <div class="structure-name">
-                                        {structure.name}
+                        <v:variable.set name="pagedStructures" value="{ot:utilities.paginateArray(array:structuresCollection.members)}" />
+
+                        <f:for each="{pagedStructures}" as="page_items" iteration="it">
+
+                            <div class="structures-page"
+                                 style="{f:if(condition: '{it.cycle}!=1', then: 'display:none;')}"
+                                 data-page="{it.cycle}"
+                            >
+                                <f:for each="{page_items}" as="structure">
+                                    <div class="structure-card" data-id="{structure.id}">
+
+                                        <div class="structure-poster">
+                                            <f:if condition="{structure.logoId}">
+                                                <f:then>
+                                                    <img src='{structure.logoId}' alt="poster" />
+                                                </f:then>
+                                                <f:else>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                                                </f:else>
+                                            </f:if>
+                                        </div>
+
+                                        <div class="structure-details">
+                                            <f:comment>
+                                                <!--                                    <div class="structure-categories">-->
+        <!--                                        <f:for each="{structure.categories}" as="category">-->
+        <!--                                            <span class="structure-category">-->
+        <!--                                                <f:translate key="{category}"/>-->
+        <!--                                            </span>-->
+        <!--                                        </f:for>-->
+        <!--                                    </div>--></f:comment>
+
+                                            <div class="structure-name">
+                                                {structure.name}
+                                            </div>
+                                            <table class="structure-details-table">
+                                                <tr class="structure-details-entry structure-address">
+                                                    <td><i class="fas fa-map-marker-alt"></i></td>
+                                                    <td>
+                                                        <f:if condition="{structure.streetAddress}">
+                                                            {structure.streetAddress} -
+                                                        </f:if>
+                                                        {structure.postalCode} {structure.addressCity}
+                                                    </td>
+                                                </tr>
+                                                <tr class="structure-details-entry structure-federation">
+                                                    <td><i class="fas fa-project-diagram"></i></td>
+                                                    <td>{structure.parentName}</td>
+                                                </tr>
+                                            </table>
+                                        </div>
+
+                                        <div class="spacer"></div>
+
+                                        <a target="_blank" class="btn structure-see" href="https://{structure.subdomain}.opentalent.fr">
+                                            <span><f:translate key="see-more"/></span>
+                                            <i class="fa fa-caret-right" style="margin-left: 5px;"></i>
+                                        </a>
                                     </div>
-                                    <table class="structure-details-table">
-                                        <tr class="structure-details-entry structure-address">
-                                            <td><i class="fas fa-map-marker-alt"></i></td>
-                                            <td>
-                                                <f:if condition="{structure.streetAddress}">
-                                                    {structure.streetAddress} -
-                                                </f:if>
-                                                {structure.postalCode} {structure.addressCity}
-                                            </td>
-                                        </tr>
-                                        <tr class="structure-details-entry structure-federation">
-                                            <td><i class="fas fa-project-diagram"></i></td>
-                                            <td>{structure.parentName}</td>
-                                        </tr>
-                                    </table>
-                                </div>
-
-                                <div class="spacer"></div>
-
-                                <a target="_blank" class="btn structure-see" href="https://{structure.subdomain}.opentalent.fr">
-                                    <span><f:translate key="see-more"/></span>
-                                    <i class="fa fa-caret-right" style="margin-left: 5px;"></i>
-                                </a>
+                                </f:for>
                             </div>
                         </f:for>
 
-                        {ot:pagination(collection: structuresCollection)}
+                        <div class="pagination-bar">
+                            <v:variable.set name="lastPage" value="{ot:utilities.count(array:pagedStructures)}" />
+
+                            <a class="goto-page" data-page="1" href="#page-1" title="{f:translate(key:'go-to-first-page')}">
+                                <i class="fa fa-angle-double-left"></i>
+                            </a>
+
+                            <ul>
+                            <f:for each="{pagedStructures}" as="_" iteration="it">
+                                <li class="{f:if(condition:'{it.cycle}==1',then:'current',else:'')}"
+                                    style="{f:if(condition:'{it.cycle}>10',then:'display:none;',else:'')}"
+                                    data-page="{it.cycle}"
+                                >
+                                    <a class="goto-page" data-page="{it.cycle}" href="#page-{it.cycle}" title="{f:translate(key:'go-to-page')}{it.cycle}">
+                                        {it.cycle}
+                                    </a>
+                                </li>
+                            </f:for>
+                            </ul>
+
+                            <a class="goto-page" data-page="{lastPage}" href="#page-{lastPage}" title="{f:translate(key:'go-to-last-page')}">
+                                <i class="fa fa-angle-double-right"></i>
+                            </a>
+                        </div>
 
                     </div>
                 </div>
-            </ot:organizations.getFederationStructures>
-
-        </div>
+            </div>
+        </ot:organizations.getFederationStructures>
     </div>
 </div>
 

+ 49 - 22
ot_templating/Resources/Public/assets/Classic/script/main.js

@@ -247,37 +247,33 @@ $(document).ready(function(){
     // Display map on network structures page
     if ($('.ot-structures #structure-map').length) {
 
+        // Instanciate leaflet map
         let mapDiv = $('#structure-map').first();
         showMap(mapDiv, false);
 
-        let greySquareIcon = L.divIcon({
-            html: '<svg style="width:5px;height:5px;fill:#808080" width="512px" height="512px" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="M416,464H96a48.05,48.05,0,0,1-48-48V96A48.05,48.05,0,0,1,96,48H416a48.05,48.05,0,0,1,48,48V416A48.05,48.05,0,0,1,416,464Z"/></svg>',
-            className: "",
-            iconSize: [5, 5],
-            iconAnchor: [0, 10],
-        });
+        // load data
+        let structures = $(mapDiv).closest('.ot-structures').data('structures');
+        console.log(structures);
+
 
+        // Load clustered markers on leaflet map
         var clusters = L.markerClusterGroup();
 
-        let allStructures = mapDiv.data('all-structures') ?? [];
-        allStructures.forEach(function (item) {
-            // L.marker([item.lat, item.long], { icon: greySquareIcon, zIndexOffset: -1 }).addTo(map);
-            clusters.addLayer(L.marker([item.lat, item.long], { icon: greySquareIcon, zIndexOffset: -1 }))
+        structures.forEach(function (item) {
+            if (item.longitude && item.latitude) {
+                let marker = L.marker([item.latitude, item.longitude]);
+                let label = `<b>${item.name}</b><br/>${item.postalCode} ${item.addressCity}<br/>`
+                if (item.otherWebsite) {
+                    label += `<a href="${item.otherWebsite}" target="_blank">En savoir plus</a>`
+                }
+                marker.bindPopup(label);
+                clusters.addLayer(marker);
+            }
         });
         map.addLayer(clusters);
 
-        // let orangeSquareIcon = L.divIcon({
-        //     html: '<svg style="width:8px;height:8px;fill:#e4611b" width="512px" height="512px" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><title>ionicons-v5-q</title><path d="M416,464H96a48.05,48.05,0,0,1-48-48V96A48.05,48.05,0,0,1,96,48H416a48.05,48.05,0,0,1,48,48V416A48.05,48.05,0,0,1,416,464Z"/></svg>',
-        //     className: "",
-        //     iconSize: [8, 8],
-        //     iconAnchor: [0, 16],
-        // });
-
-        let selectedStructures = mapDiv.data('selected-structures') ?? [];
-        selectedStructures.forEach(function (item) {
-            L.marker([item.lat, item.long]).addTo(map);
-            // L.marker([item.lat, item.long], { icon: orangeSquareIcon }).addTo(map);
-        });
+        // populate results list
+
     }
 
     // Goto commands
@@ -290,6 +286,37 @@ $(document).ready(function(){
         map.fitBounds(bounds);
     });
 
+    // Goto page links
+    $('a.goto-page').on('click', function(e) {
+        e.preventDefault();
+        let goto = $(this).data('page');
+
+        let ul = $(this).closest('ul');
+        let current_li = ul.children('li.current').first()
+        let target_li = ul.find('li[data-page='.concat(goto, ']')).first();
+
+        let current_page = current_li.data('page')
+
+        let results = $(this).closest('.structure-results');
+        let current_div = results.find('.structures-page[data-page='.concat(current_page, ']'))
+        let target_div = results.find('.structures-page[data-page='.concat(goto, ']'))
+
+        current_div.hide();
+        target_div.show();
+
+        current_li.removeClass('current');
+        target_li.addClass('current');
+
+        ul.children('li').each(function (x) {
+            if ($(x).data('page') <= current_page + 5 && $(x).data('page') >= current_page - 5) {
+                $(x).show();
+            } else {
+                $(x).hide();
+            }
+        });
+
+
+    });
 
     // Toggle structures list and map view
     $('.activate-map-view').on('click', function(e) {

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-blue.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-blue.css.map


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-green.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-green.css.map


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-grey.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-grey.css.map


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-light-blue.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-light-blue.css.map


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-light-red.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-light-red.css.map


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-orange.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-orange.css.map


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-purple.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-purple.css.map


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-red.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/classic-red.css.map


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

@@ -172,7 +172,7 @@ $input-border-color: #bfbfbf;
     border-radius: 0;
   }
 
-  .structure-results {
+  .structure-results .structures-page {
     display: flex;
     flex-direction: row;
     flex-wrap: wrap;

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/style.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
ot_templating/Resources/Public/assets/Classic/style/style.css.map


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است