From c9aaad60d1875a2f7f695bcfb0c7db0c2785cc8d Mon Sep 17 00:00:00 2001 From: bach Date: Tue, 1 Apr 2025 15:04:32 +0200 Subject: [PATCH] actu filters ok --- composer.json | 1 + composer.lock | 50 ++- config/sync/core.extension.yml | 1 + config/sync/views.view.actus.yml | 287 ++++++++++++++++-- .../quartiers_de_demain/dist/assets/bundle.js | 16 +- .../dist/assets/bundle.js.map | 2 +- .../src/assets/js/quartiers_de_demain.js | 16 +- 7 files changed, 340 insertions(+), 33 deletions(-) diff --git a/composer.json b/composer.json index ce65b04..0997549 100644 --- a/composer.json +++ b/composer.json @@ -41,6 +41,7 @@ "drupal/verf": "^2.1", "drupal/views_autocomplete_filters": "^2.0", "drupal/views_block_area": "^1.0@beta", + "drupal/views_year_filter": "^2.1", "drupal/viewsreference": "^2.0@beta", "drupal/yaml_editor": "^1.2", "drush/drush": "^12.4", diff --git a/composer.lock b/composer.lock index d6aeade..f3cbcb5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1bbd67872d9de1d8d9dfb0ad3321a350", + "content-hash": "ad1e0913a8c7f00a9b7ed7a3edfda684", "packages": [ { "name": "asm89/stack-cors", @@ -7939,6 +7939,54 @@ "docs": "https://www.drupal.org/docs/8/modules/views-bulk-operations-vbo" } }, + { + "name": "drupal/views_year_filter", + "version": "2.1.6", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/views_year_filter.git", + "reference": "2.1.6" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/views_year_filter-2.1.6.zip", + "reference": "2.1.6", + "shasum": "641ab95b58ecff6c07cabcae5d108277aa336a30" + }, + "require": { + "drupal/core": "^10 || ^11" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "2.1.6", + "datestamp": "1740230890", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "abjih", + "homepage": "https://www.drupal.org/user/3519087" + }, + { + "name": "berramou", + "homepage": "https://www.drupal.org/user/3535998" + } + ], + "description": "Add Year filter to views.", + "homepage": "https://www.drupal.org/project/views_year_filter", + "support": { + "source": "https://git.drupalcode.org/project/views_year_filter" + } + }, { "name": "drupal/viewsreference", "version": "2.0.0-beta10", diff --git a/config/sync/core.extension.yml b/config/sync/core.extension.yml index 9c96394..b71b321 100644 --- a/config/sync/core.extension.yml +++ b/config/sync/core.extension.yml @@ -125,6 +125,7 @@ module: views_bulk_edit: 0 views_bulk_operations: 0 views_ui: 0 + views_year_filter: 0 viewsreference: 0 yaml_editor: 0 extlink: 1 diff --git a/config/sync/views.view.actus.yml b/config/sync/views.view.actus.yml index 9933650..94ec6e0 100644 --- a/config/sync/views.view.actus.yml +++ b/config/sync/views.view.actus.yml @@ -18,6 +18,7 @@ dependencies: - taxonomy - text - user + - verf - views_block_area id: actus label: Actus @@ -670,6 +671,7 @@ display: field_identifier: '' exposed: false granularity: second + arguments: { } filters: status: id: status @@ -691,6 +693,7 @@ display: plugin_id: bundle value: actualite: actualite + group: 1 langcode: id: langcode table: node_field_data @@ -771,6 +774,217 @@ display: default_group: All default_group_multiple: { } group_items: { } + field_type_d_actualite_target_id: + id: field_type_d_actualite_target_id + table: node__field_type_d_actualite + field: field_type_d_actualite_target_id + relationship: none + group_type: group + admin_label: '' + plugin_id: taxonomy_index_tid + operator: or + value: { } + group: 1 + exposed: true + expose: + operator_id: field_type_d_actualite_target_id_op + label: 'par type' + description: '' + use_operator: false + operator: field_type_d_actualite_target_id_op + operator_limit_selection: false + operator_list: { } + identifier: field_type_d_actualite_target_id + required: false + remember: false + multiple: true + remember_roles: + authenticated: authenticated + anonymous: '0' + admin: '0' + root: '0' + editeur: '0' + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + reduce_duplicates: false + vid: type_d_actualite + type: select + hierarchy: false + limit: true + error_message: true + save_lineage: false + force_deepest: false + parent: null + level_labels: '' + hierarchy_depth: 0 + required_depth: 0 + none_label: '- Please select -' + field_date_value: + id: field_date_value + table: node__field_date + field: field_date_value + relationship: none + group_type: group + admin_label: '' + plugin_id: datetime + operator: '=' + value: + min: '' + max: '' + value: '' + type: date_year + group: 1 + exposed: true + expose: + operator_id: field_date_value_op + label: 'Date (field_date)' + description: '' + use_operator: false + operator: field_date_value_op + operator_limit_selection: false + operator_list: { } + identifier: field_date_value + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + admin: '0' + root: '0' + editeur: '0' + min_placeholder: '' + max_placeholder: '' + placeholder: '' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + field_site_target_id_verf: + id: field_site_target_id_verf + table: node__field_site + field: field_site_target_id_verf + relationship: field_site + group_type: group + admin_label: '' + plugin_id: verf + operator: in + value: { } + group: 1 + exposed: true + expose: + operator_id: field_site_target_id_verf_op + label: 'par site(s)' + description: '' + use_operator: false + operator: field_site_target_id_verf_op + operator_limit_selection: false + operator_list: { } + identifier: field_site_target_id_verf + required: false + remember: false + multiple: true + remember_roles: + authenticated: authenticated + anonymous: '0' + admin: '0' + root: '0' + editeur: '0' + reduce: 0 + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + verf_target_bundles: + site: site + actualite: '0' + partenaire: '0' + ressource: '0' + static: '0' + show_unpublished: 0 + combine: + id: combine + table: views + field: combine + relationship: none + group_type: group + admin_label: '' + plugin_id: combine + operator: contains + value: '' + group: 1 + exposed: true + expose: + operator_id: combine_op + label: recherche + description: '' + use_operator: false + operator: combine_op + operator_limit_selection: false + operator_list: { } + identifier: combine + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + admin: '0' + root: '0' + editeur: '0' + placeholder: '' + autocomplete_filter: 0 + autocomplete_min_chars: '0' + autocomplete_items: '10' + autocomplete_field: '' + autocomplete_raw_suggestion: 1 + autocomplete_raw_dropdown: 1 + autocomplete_dependent: 0 + autocomplete_contextual: 0 + autocomplete_autosubmit: 0 + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + fields: + title: title + title_1: title_1 + body: body filter_groups: operator: AND groups: @@ -778,9 +992,11 @@ display: defaults: title: false sorts: false + arguments: false filters: false filter_groups: false display_description: '' + exposed_block: true display_extenders: matomo: enabled: false @@ -799,12 +1015,15 @@ display: contexts: - 'languages:language_content' - 'languages:language_interface' + - url - 'user.node_grants:view' - user.permissions tags: - 'config:field.storage.node.body' - 'config:field.storage.node.field_date' - 'config:field.storage.node.field_site' + - 'config:views.view.actus' + - node_list page_1: id: page_1 display_title: 'Page à la une' @@ -819,9 +1038,20 @@ display: reset_button: true reset_button_label: Réinitialiser exposed_sorts_label: 'Trier par' - expose_sort_order: true + expose_sort_order: false sort_asc_label: Asc sort_desc_label: Desc + empty: + title: + id: title + table: views + field: title + relationship: none + group_type: group + admin_label: '' + plugin_id: title + empty: true + title: Archives sorts: field_date_end_value: id: field_date_end_value @@ -962,7 +1192,7 @@ display: identifier: field_type_d_actualite_target_id required: false remember: false - multiple: false + multiple: true remember_roles: authenticated: authenticated anonymous: '0' @@ -1008,12 +1238,12 @@ display: min: '' max: '' value: '' - type: date + type: date_year group: 1 exposed: true expose: operator_id: field_date_value_op - label: 'Par année' + label: 'par année' description: '' use_operator: false operator: field_date_value_op @@ -1044,48 +1274,37 @@ display: default_group: All default_group_multiple: { } group_items: { } - title: - id: title - table: node_field_data - field: title + field_site_target_id_verf: + id: field_site_target_id_verf + table: node__field_site + field: field_site_target_id_verf relationship: field_site group_type: group admin_label: '' - entity_type: node - entity_field: title - plugin_id: string - operator: contains - value: '' + plugin_id: verf + operator: in + value: { } group: 1 exposed: true expose: - operator_id: title_op - label: 'par site' + operator_id: field_site_target_id_verf_op + label: 'par site(s)' description: '' use_operator: false - operator: title_op + operator: field_site_target_id_verf_op operator_limit_selection: false operator_list: { } - identifier: site + identifier: field_site_target_id_verf required: false remember: false - multiple: false + multiple: true remember_roles: authenticated: authenticated anonymous: '0' admin: '0' root: '0' editeur: '0' - placeholder: '' - autocomplete_filter: 1 - autocomplete_min_chars: '0' - autocomplete_items: '10' - autocomplete_field: title_1 - autocomplete_raw_suggestion: 0 - autocomplete_raw_dropdown: 0 - autocomplete_dependent: 0 - autocomplete_contextual: 1 - autocomplete_autosubmit: 0 + reduce: 0 is_grouped: false group_info: label: '' @@ -1098,6 +1317,13 @@ display: default_group: All default_group_multiple: { } group_items: { } + verf_target_bundles: + site: site + actualite: '0' + partenaire: '0' + ressource: '0' + static: '0' + show_unpublished: 0 combine: id: combine table: views @@ -1112,7 +1338,7 @@ display: exposed: true expose: operator_id: combine_op - label: 'Dans le texte' + label: Recherche description: '' use_operator: false operator: combine_op @@ -1159,6 +1385,7 @@ display: groups: 1: AND defaults: + empty: false title: false exposed_form: false sorts: false @@ -1221,3 +1448,5 @@ display: - 'config:field.storage.node.body' - 'config:field.storage.node.field_date' - 'config:field.storage.node.field_site' + - 'config:views.view.actus' + - node_list diff --git a/web/themes/custom/quartiers_de_demain/dist/assets/bundle.js b/web/themes/custom/quartiers_de_demain/dist/assets/bundle.js index 603735e..331b74e 100644 --- a/web/themes/custom/quartiers_de_demain/dist/assets/bundle.js +++ b/web/themes/custom/quartiers_de_demain/dist/assets/bundle.js @@ -908,7 +908,21 @@ $(document).ready(function () { links.slideToggle(); $(this).toggleClass("open"); }); - }); + }); + // slimselect + // duplicated due to embeded view (archives) + var type_select = new SlimSelect({ + select: '#edit-field-type-d-actualite-target-id--2' + }) + var type_select2 = new SlimSelect({ + select: '#edit-field-type-d-actualite-target-id--3' + }) + var type_select = new SlimSelect({ + select: '#edit-field-site-target-id-verf--2' + }) + var type_select = new SlimSelect({ + select: '#edit-field-site-target-id-verf--3' + }) } }); diff --git a/web/themes/custom/quartiers_de_demain/dist/assets/bundle.js.map b/web/themes/custom/quartiers_de_demain/dist/assets/bundle.js.map index be5e438..a4c1e78 100644 --- a/web/themes/custom/quartiers_de_demain/dist/assets/bundle.js.map +++ b/web/themes/custom/quartiers_de_demain/dist/assets/bundle.js.map @@ -1 +1 @@ -{"version":3,"file":"./bundle.js","mappings":";UAAA;UACA;;;;;WCDA;WACA;WACA;WACA;WACA,GAAG;WACH;WACA;WACA,CAAC;;;;;WCPD;WACA;WACA;WACA,uDAAuD,iBAAiB;WACxE;WACA,gDAAgD,aAAa;WAC7D;;;;;WCNA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;;;;;;;;;AClBA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAE;;;AAGF;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,QAAQ;AACR;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;AACH,6BAA6B,kBAAkB;;;AAG/C;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA,KAAK;AACL;;AAEA;;AAEA;AACA,uBAAuB;AACvB;;AAEA;AACA;AACA,QAAQ,4BAA4B;AACpC,QAAQ;AACR;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA,QAAQ,gCAAgC;AACxC,QAAQ;AACR;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,6BAA6B;AACrC,QAAQ;AACR;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA,QAAQ,+BAA+B;AACvC,QAAQ;AACR;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,MAAM;AACN;AACA;AACA,QAAQ;AACR;AACA;AACA;;;AAGA,oDAAoD;AACpD;;AAEA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,IAAI;AACJ;AACA;AACA,MAAM;AACN;AACA;AACA;;AAEA,CAAC;;AAED;;;;AAIA;;;AAGA;AACA;AACA;AACA;AACA;AACA,wCAAwC,sDAAsD;AAC9F;AACA;;AAEA;AACA;AACA,CAAC;;;AAGD;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;;AAGA;AACA;AACA,CAAC;;AAED;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;;AAGH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;;;;AAIA;;AAEA;;AAEA;AACA;AACA,2BAA2B;;AAE3B;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,IAAI;;;AAGJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,QAAQ;;AAER,IAAI;;AAEJ;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf,OAAO;;AAEP;AACA,CAAC;AACD;;;AAGA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,CAAC;;AAED;;;;AAIA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,6BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA,mFAAmF;AACnF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,mFAAmF;AACnF;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,GAAG;AACH,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;;AAGD;;;;AAIA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,mDAAmD;;AAEnD;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,CAAC;AACD;;;AAGA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,CAAC;;AAED;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;;AAEA,kCAAkC;AAClC;AACA,kDAAkD;AAClD;AACA,IAAI,OAAO;AACX;AACA;AACA,0DAA0D;AAC1D;AACA;AACA;;AAEA;AACA;AACA;AACA,CAAC;;AAED;;AAEA;AACA;AACA;AACA;AACA,kDAAkD;;AAElD;AACA,wCAAwC;AACxC;AACA,GAAG;AACH,CAAC;AACD;;;;AAIA;;AAEA;AACA;AACA;AACA;AACA,mCAAmC;AACnC,oDAAoD;AACpD,gCAAgC;;AAEhC;AACA;AACA,oGAAoG;;AAEpG;AACA;AACA,gCAAgC;AAChC,YAAY;AACZ,gCAAgC;AAChC;;AAEA;AACA;AACA,sBAAsB;AACtB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,iFAAiF;;AAEjF;AACA,2CAA2C;;AAE3C;AACA,iEAAiE;AACjE;AACA,gBAAgB;AAChB,8EAA8E;AAC9E,4DAA4D;AAC5D;AACA,WAAW;AACX,OAAO;;;AAGP;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,CAAC;;;AAGD;;;;AAIA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,OAAO;AACP,GAAG;AACH;AACA,CAAC;;;AAGD;;;AAGA,CAAC;;;;;;;;;;AC51BD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;;;;AAKD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,MAAM;AACN,IAAI;;AAEJ;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;AACH;AACA;AACA;AACA;AACA;;;;;;;;;;ACzDA,+DAAe,qBAAuB,qBAAqB,E","sources":["webpack://quartiers_de_demain/webpack/bootstrap","webpack://quartiers_de_demain/webpack/runtime/global","webpack://quartiers_de_demain/webpack/runtime/make namespace object","webpack://quartiers_de_demain/webpack/runtime/publicPath","webpack://quartiers_de_demain/./src/assets/js/quartiers_de_demain.js","webpack://quartiers_de_demain/./src/assets/js/animated_formes.js","webpack://quartiers_de_demain/./src/assets/scss/quartiers_de_demain.scss"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","var scriptUrl;\nif (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + \"\";\nvar document = __webpack_require__.g.document;\nif (!scriptUrl && document) {\n\tif (document.currentScript)\n\t\tscriptUrl = document.currentScript.src;\n\tif (!scriptUrl) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tif(scripts.length) {\n\t\t\tvar i = scripts.length - 1;\n\t\t\twhile (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;\n\t\t}\n\t}\n}\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","/**\n * @file\n * quartiers_de_demain behaviors.\n */\n (function (Drupal) {\n\n 'use strict';\n\n Drupal.behaviors.quartiers_de_demain = {\n attach: function (context, settings) {\n console.log('It works!');\n }\n };\n} (Drupal));\n\n\n//////// start header ////////////\ndocument.addEventListener('DOMContentLoaded', function() {\n\n const header = document.querySelector('header[role=\"banner\"]');\n const logo = document.querySelector('#block-quartiers-de-demain-logoquartiersdedemain > div:nth-child(1) > div:nth-child(1) > a:nth-child(1) > svg:nth-child(1)');\n const headerNavContainer = document.querySelector('.header_nav_container');\n const isFirstLoad = !performance.getEntriesByType(\"navigation\")[0].type.includes('back_forward');\n const isTargetPath = window.location.pathname === '/';\n\n // Fonction pour démarrer l'animation du logo SVG\n function startLogoAnimation() {\n logo.classList.add('animated');\n }\n\n // Fonction pour arrêter l'animation du logo SVG\n function stopLogoAnimation() {\n logo.classList.remove('animated');\n }\n\n // Vérifier si le header a la classe header--collapse\n function checkHeaderCollapse() {\n if (header.classList.contains('header--collapsed')) {\n stopLogoAnimation();\n } else if (header.classList.contains('header--collapsed-already')) {\n stopLogoAnimation();\n } else {\n startLogoAnimation();\n }\n\n }\n\n // Appeler la fonction au chargement initial\n checkHeaderCollapse();\n\n // Observer les changements de classe sur le header\n const observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(mutation) {\n if (mutation.attributeName === 'class') {\n checkHeaderCollapse();\n }\n });\n });\n observer.observe(header, { attributes: true });\n\n\n // Si ce n'est pas la première charge ou si le chemin n'est pas le chemin cible, ajouter la classe immédiatement\n if (!isFirstLoad || !isTargetPath) {\n header.classList.add('header--collapsed-already');\n // logo.classList.remove('animated');\n stopLogoAnimation();\n } else {\n // Sinon, appliquer la transition après un délai\n setTimeout(() => {\n header.classList.add('header--collapsed');\n }, 5000);\n }\n\n //////////////////////////////////////\n\n let lastScrollTop = 0;\n let threshold = 100; // Change this value as needed\n let isHidden = false;\n\n function slideOut() {\n headerNavContainer.animate([\n { transform: 'translateX(0)' },\n { transform: 'translateX(-100%)' }\n ], {\n duration: 300,\n fill: 'forwards'\n });\n isHidden = true;\n }\n\n function slideIn() {\n headerNavContainer.animate([\n { transform: 'translateX(-100%)' },\n { transform: 'translateX(0)' }\n ], {\n duration: 300,\n fill: 'forwards'\n });\n isHidden = false;\n }\n \n function slideDown() {\n // headerNavContainer.style.display = 'block';\n headerNavContainer.animate([\n { transform: 'translateY(0%)' },\n { transform: 'translateY(+100%)' }\n ], {\n duration: 300,\n fill: 'forwards'\n });\n isHidden = false;\n }\n\n function slideUp() {\n headerNavContainer.animate([\n { transform: 'translateY(100%)' },\n { transform: 'translateY(0%)' }\n ], {\n duration: 300,\n fill: 'forwards'\n }).onfinish = function() {\n // headerNavContainer.style.display = 'none';\n };\n isHidden = true;\n }\n // Fonction pour ajuster la hauteur du header lors du défilement\n function adjustHeaderHeight() {\n if (window.scrollY > 0) {\n header.classList.add('shrink');\n } else {\n header.classList.remove('shrink');\n }\n }\n\n function handleScroll() {\n let scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const isMobile = window.innerWidth < 811;\n\n if (scrollTop > threshold && !isHidden) {\n if (isMobile) {\n slideUp();\n } else {\n slideOut();\n }\n } else if (scrollTop <= threshold && isHidden) {\n if (isMobile) {\n slideDown();\n } else {\n slideIn();\n }\n }\n\n\n lastScrollTop = scrollTop <= 0 ? 0 : scrollTop; // For Mobile or negative scrolling\n }\n\n function handleTouchAndMouseEnter() {\n if (isHidden) {\n if (window.innerWidth < 811) {\n slideDown();\n } else {\n slideIn();\n }\n }\n }\n\n function handleTouchAndMouseLeave() {\n if (lastScrollTop > threshold && !isHidden) {\n if (window.innerWidth < 811) {\n slideUp();\n } else {\n slideOut();\n }\n }\n }\n\n window.addEventListener('scroll', handleScroll);\n window.addEventListener('scroll', adjustHeaderHeight);\n\n // Mouse events for desktop\n header.addEventListener('mouseenter', handleTouchAndMouseEnter);\n header.addEventListener('mouseleave', handleTouchAndMouseLeave);\n\n // Touch events for tablets and mobile devices\n header.addEventListener('touchstart', handleTouchAndMouseEnter);\n header.addEventListener('touchend', handleTouchAndMouseLeave);\n\n // Initial check to see if we're at the top of the page\n if (window.pageYOffset <= threshold) {\n if (window.innerWidth < 811) {\n slideDown();\n } else { \n slideIn();\n } \n } else {\n if (window.innerWidth < 811) {\n slideUp();\n } else {\n slideIn();\n }\n }\n\n});\n\n//////// end header ////////////\n\n\n\n//// ancre dans texte au click paragraphe correspondant arrive en dessous du header \n\n\n(function($, window) {\nvar adjustAnchor = function() {\n var $anchor = $('.sidebar_first_container'),\n fixedElementHeight = 500;\n if ($anchor.length > 0) {\n $('html, body').stop().animate({scrollTop: $anchor.offset().top - fixedElementHeight }, 0);\n }\n};\n\n$(window).on('hashchange', function() {\n adjustAnchor();\n});\n\n\n//////////////////////// start script smooth apparition des textes /////////////////\n\nfunction scrollReaveal(){\n\n const nodes = {\n logo : document.querySelectorAll('#logo-animated-container'),\n chapeau : document.querySelectorAll('.field_body'),\n paragraph: document.querySelectorAll('.field_field_textes .paragraph--type--static-parts'),\n enjeux : document.querySelectorAll('.field_field_textes .paragraph--type--static-parts .enjeux'),\n // mapHome : document.querySelectorAll('.field_field_map_block #block-sitesmapblock'),\n // mapSite : document.querySelectorAll('#sites-map-container'),\n lienDoc : document.querySelectorAll('.field_field_documents'),\n lienURL : document.querySelectorAll('.field_field_liens_site'),\n }\n\n const showUp = {\n origin: 'bottom',\n delay: 100,\n duration: 1000,\n distance: '50px',\n easing: 'cubic-bezier(0.5, 0, 0, 1)'\n }\n\n const Show = {\n delay: 100,\n duration: 600,\n easing: 'cubic-bezier(0.5, 0, 0, 1)'\n }\n\n console.log(nodes);\n\n ScrollReveal().reveal(nodes.logo, Show);\n ScrollReveal().reveal(nodes.chapeau, showUp);\n ScrollReveal().reveal(nodes.paragraph, showUp);\n ScrollReveal().reveal(nodes.enjeux, showUp);\n // ScrollReveal().reveal(nodes.mapHome, showUp);\n // ScrollReveal().reveal(nodes.mapSite, showUp);\n ScrollReveal().reveal(nodes.lienDoc, showUp);\n ScrollReveal().reveal(nodes.lienURL, showUp);\n\n}\n\n\n$( document ).ready(function() {\n scrollReaveal();\n});\n\n//////////////////////// end script smooth apparition des textes /////////////////\n\n// //////////////////// start Timeline script ///////////////////////\n\n // Update month field to only show the first 3 letters\n document.querySelectorAll('.paragraph--type--phase-deroulement').forEach(function(paragraph) {\n const monthField = paragraph.querySelector('.field_field_date_de_moi div:nth-of-type(2)');\n if (monthField) {\n const monthText = monthField.textContent.trim();\n if (monthText === \"juillet\") {\n monthField.textContent = monthText.slice(0, 4);\n monthField.classList.add('after');\n } else if (monthText === \"juin\") {\n monthField.textContent = monthText.slice(0, 4);\n } else if (monthText.length > 3) {\n monthField.textContent = monthText.slice(0, 3);\n monthField.classList.add('after');\n }\n }\n });\n\n // Fonction pour ajouter ou retirer la classe .only\n function updateDateClasses() {\n document.querySelectorAll('.paragraph--type--phase-deroulement .date').forEach(function(dateElement) {\n const date2Element = dateElement.querySelector('.date2');\n const yearElement = dateElement.querySelector('.field_field_date_de_annee');\n\n if (date2Element && !date2Element.textContent.trim()) {\n if (yearElement) {\n yearElement.classList.add('only');\n }\n } else {\n if (yearElement) {\n yearElement.classList.remove('only');\n }\n }\n });\n }\n\n // Exécuter la fonction une première fois pour le contenu déjà présent\n updateDateClasses();\n\n // MutationObserver pour surveiller les changements dans le DOM\n const observer = new MutationObserver(function(mutationsList, observer) {\n for(let mutation of mutationsList) {\n if (mutation.type === 'childList') {\n updateDateClasses();\n }\n }\n });\n\n\n// ////////////////////// start calendrier home /////////////////////////////////\n $(document).ready(function(){\n $('.__timeline-content').slick({\n slidesToShow: 3,\n slidesToScroll: 1,\n dots: false,\n arrows: true,\n centerMode: false,\n draggable: true,\n infinite: false,\n responsive: [\n {\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: false,\n arrows: true,\n draggable: true,\n centerMode: false,\n infinite: false,\n }\n }]\n });\n console.log('salut slick calendrier');\n \n });\n \n//////////////////////// end calendrier home /////////////////////////////////\n\n\n\n//////////////////////// end Timeline script /////////////////////////////////////////////\n\n/////////////////// caracteres body actus/////////////////////////\n\n// document.addEventListener('DOMContentLoaded', function() {\n// // Maximum number of characters to display\n// const maxChars = 140; // Adjust this value as needed\n\n// document.querySelectorAll('#actus-caroussel .node-type-actualite .field_body').forEach(function(paragraph) {\n// let text = paragraph.textContent.trim();\n// if (text.length > maxChars) {\n// let truncatedText = text.slice(0, maxChars) + '...';\n// paragraph.textContent = truncatedText;\n// }\n// });\n// });\n\n\n//////////// start slideshow actus home ////////////////////////// \n// $(document).ready(function(){\n// let actuview = $('.content-actus .view .view-rows-wrapper')\n// if (actuview) {\n// actuview.slick({\n// slidesToShow: 3,\n// dots: false,\n// arrows: true,\n// adaptiveHeight: false,\n// autoplay: false,\n// responsive: [\n// {\n// breakpoint: 810,\n// settings: {\n// slidesToShow: 1,\n// adaptiveHeight: false,\n// arrows: true,\n// draggable: true,\n// autoplay: false,\n// }\n// }]\n// });\n// console.log('salut slick home');\n \n// }\n// $('.slick-carousel').slick({\n// lazyLoad: 'progressive', // Option 'ondemand' ou 'progressive'\n// });\n\n// });\n\n//////////// end slideshow actus home ////////////////////////// \n\n\n//////////// start slideshow images home ////////////////////////// \n$(document).ready(function () {\n let diapohome = $('.config_pages--type--diaporama-home .diaporama');\n\n if (diapohome.length) {\n // Initialisation de Slick\n diapohome.slick({\n slidesToShow: 1,\n dots: false,\n arrows: false,\n // centerMode: true,\n adaptiveHeight: false,\n autoplay: true, // Activer l'autoplay\n autoplaySpeed: 4000, // Changement de slide toutes les 4 secondes\n // infinite: true,\n pauseOnHover: false, // Ne pas arrêter l'autoplay lors du survol\n pauseOnFocus: false,\n responsive: [\n {\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: false,\n arrows: false,\n draggable: true,\n centerMode: false,\n }\n }]\n });\n\n}\n});\n//////////// end slideshow images home ////////////////////////// \n\n\n//////////// start slideshow /actualites ////////////////////////// \n$(document).ready(function(){\n // Vérifier si on N'EST PAS sur la page #home\n if (!$(\"#page-node\").length) {\n let actuview2 = $('.content-wrapper-actu .field_field_images .actu-diaporama');\n\n if (actuview2.length > 0) {\n actuview2.slick({\n slidesToShow: 1,\n dots: false,\n arrows: true,\n adaptiveHeight: false,\n autoplay: false,\n responsive: [\n {\n breakpoint: 810,\n settings: {\n slidesToShow: 1,\n adaptiveHeight: false,\n arrows: true,\n draggable: true,\n autoplay: false,\n }\n }\n ]\n });\n console.log('Slick activé sur les actualités');\n console.log('Slick activé sur 1 actu');\n }\n // } else {\n // console.log('Slick désactivé sur la page Home');\n }\n});\n\n//////////// end slideshow /actualites ////////////////////////// \n\n\n\n//////////////// start lightbox galerie image page site////////////////////////\n// Sélection des images à ouvrir dans la lightbox\nlet images = document.querySelectorAll('.paragraph--type--site-diapo .lightbox-trigger');\nlet currentIndex;\n\n// Création de la lightbox\nconst lightbox = document.createElement('div');\nlightbox.id = 'lightbox';\nlightbox.classList.add('lightbox');\ndocument.body.appendChild(lightbox);\n\n// Image affichée dans la lightbox\nconst img = document.createElement('img');\nimg.classList.add('lightbox-content');\nlightbox.appendChild(img);\n\n// Légende\nconst caption = document.createElement('p');\ncaption.classList.add('caption');\nlightbox.appendChild(caption);\n\n// Bouton de fermeture\nconst closeBtn = document.createElement('span');\ncloseBtn.classList.add('close');\ncloseBtn.innerHTML = '×';\nlightbox.appendChild(closeBtn);\n\n// Bouton précédent avec image\nconst prevBtn = document.createElement('a');\nprevBtn.classList.add('prev');\nconst prevImg = document.createElement('img');\nprevImg.src = \"/themes/custom/quartiers_de_demain/dist/assets/img/prev-blanc.svg\"; // 🔁 adapte ce chemin\nprevImg.alt = 'Précédent';\nprevBtn.appendChild(prevImg);\nlightbox.appendChild(prevBtn);\n\n// Bouton suivant avec image\nconst nextBtn = document.createElement('a');\nnextBtn.classList.add('next');\nconst nextImg = document.createElement('img');\nnextImg.src = '/themes/custom/quartiers_de_demain/dist/assets/img/next-blanc.svg'; // 🔁 adapte ce chemin\nnextImg.alt = 'Suivant';\nnextBtn.appendChild(nextImg);\nlightbox.appendChild(nextBtn);\n\n// Fonction d'affichage\nfunction showImage(index) {\n if (index < 0) index = images.length - 1;\n if (index >= images.length) index = 0;\n currentIndex = index;\n\n img.src = images[currentIndex].getAttribute('src');\n\n const captionText = images[currentIndex]\n .closest('.cadre-img-zoom')\n ?.nextElementSibling?.querySelector('.image-field-caption p')\n ?.textContent || '';\n\n caption.textContent = captionText;\n lightbox.style.display = 'flex';\n}\n\n// Clic sur une image\nimages.forEach((image, index) => {\n image.addEventListener('click', () => {\n showImage(index);\n });\n});\n\n// Navigation & fermeture\ncloseBtn.addEventListener('click', () => lightbox.style.display = 'none');\nprevBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n showImage(currentIndex - 1);\n});\nnextBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n showImage(currentIndex + 1);\n});\n\n// Clic en dehors de l'image pour fermer\nlightbox.addEventListener('click', (e) => {\n if (e.target === lightbox) lightbox.style.display = 'none';\n});\n\n// Clavier\ndocument.addEventListener('keydown', (e) => {\n if (lightbox.style.display === 'flex') {\n if (e.key === 'Escape') lightbox.style.display = 'none';\n else if (e.key === 'ArrowLeft') showImage(currentIndex - 1);\n else if (e.key === 'ArrowRight') showImage(currentIndex + 1);\n }\n});\n\n\n//////////////// end lightbox galerie image page site////////////////////////\n\n\n\n//////////////////// start wrapper views-row lessites /////////////////////////\ndocument.addEventListener(\"DOMContentLoaded\", function() {\n// Sélectionne le conteneur principal avec l'ID 'lessites'\nconst container = document.getElementById(\"lessites\");\n\n// Vérifie si le conteneur existe pour éviter toute erreur sur d'autres pages\nif (container) {\n // Sélectionne l'élément 'view' à l'intérieur de '.views-element-container'\n const viewContainer = container.querySelector(\".views-element-container .view\");\n\n // Vérifie si 'viewContainer' existe pour éviter les erreurs\n if (viewContainer) {\n // Crée une div englobante pour tous les éléments 'views-row'\n const wrapperDiv = document.createElement(\"div\");\n wrapperDiv.classList.add(\"views-row-wrapper\"); // ajoute une classe pour faciliter le style CSS\n\n // Déplace tous les éléments 'views-row' dans la nouvelle div\n const viewsRows = viewContainer.querySelectorAll(\".views-row\");\n viewsRows.forEach(row => wrapperDiv.appendChild(row));\n\n // Ajoute la div englobante dans le 'viewContainer'\n viewContainer.appendChild(wrapperDiv);\n }\n}\n});\n//////////////////// end wrapper views-row lessites /////////////////////////\n\n\n//////////////////// start div infos site ////////////////////////\n\n// Vérifie si la page a la classe 'node-type-site' dans le \nif (document.body.classList.contains('node-type-site')) {\n// Sélectionne le conteneur principal\nconst blockRegion = document.querySelector('.block-region-second');\n\n// Liste des classes spécifiques à cibler\nconst fieldClasses = [\n '.field_field_region',\n '.field_field_nom_du_qpv_nb_d_hab',\n '.field_field_departement_s',\n '.field_field_programme_de_l_etat',\n '.field_field_porteur_s_de_site',\n '.field_field_nom_de_la_commune_nb_d_hab'\n];\n\n// Sélectionne les div parents de chacun des champs listés\nconst elementsToWrap = [];\nfieldClasses.forEach(className => {\n const fieldElement = blockRegion.querySelector(className);\n if (fieldElement) {\n // Ajoute le parent du champ au tableau si trouvé\n elementsToWrap.push(fieldElement.parentElement);\n }\n});\n\n// Vérifie que des éléments ont été trouvés\nif (elementsToWrap.length > 0) {\n // Crée le conteneur avec la classe 'infos'\n const infosContainer = document.createElement('div');\n infosContainer.className = 'infos';\n\n // Insère le conteneur `.infos` avant le premier élément ciblé\n const firstElement = elementsToWrap[0];\n blockRegion.insertBefore(infosContainer, firstElement);\n\n // Déplace chaque élément dans le conteneur `.infos`\n elementsToWrap.forEach(element => infosContainer.appendChild(element));\n}\n}\n//////////////////// end div infos site ////////////////////////\n\n\n//////////////////// start div infos actualité ////////////////////////\n\n$(document).ready(function () {\n // Vérifier si .layout-container A l'ID #page-node (et non un élément enfant)\n if ($(\".layout-container\").attr(\"id\") === \"page-node\") {\n $(\"article.node-type-actualite\").each(function () {\n let article = $(this);\n let dateField = article.find(\".field_field_date\");\n let typeField = article.find(\".field_field_type_d_actualite\");\n let siteField = article.find(\".field_field_site\");\n\n \n\n // Vérifier si les deux éléments existent\n if (dateField.length > 0 || typeField.length > 0) {\n // Vérifier si l'encapsulation n'existe pas déjà\n if (article.find(\".infos-actu\").length === 0) {\n // Créer un conteneur et y insérer les éléments\n let infosActu = $(\"
\").addClass(\"infos-actu\").append(dateField, typeField, siteField);\n \n // Ajouter ce conteneur après les champs existants\n article.append(infosActu);\n }\n }\n });\n }\n});\n\n//////////////////// end div infos actualité ////////////////////////\n\n//////////////////////////////////////////////////////////////////\n\ndocument.addEventListener(\"DOMContentLoaded\", function() {\n// Sélectionner les éléments à déplacer\nconst documentsField = document.querySelector(\".field_field_documents\");\nconst liensSiteField = document.querySelector(\".field_field_liens_site\");\n\n// Sélectionner la destination\nconst thirdRegion = document.querySelector(\".block-region-third > div\");\n\n// Créer une nouvelle div pour englober les éléments déplacés\nconst wrapperDiv = document.createElement(\"div\");\nwrapperDiv.classList.add(\"documents-liens-wrapper\");\n\n// Déplacer les éléments dans la nouvelle div\nif (documentsField && liensSiteField && thirdRegion) {\n wrapperDiv.appendChild(documentsField);\n wrapperDiv.appendChild(liensSiteField);\n\n // Ajouter la nouvelle div dans la destination\n thirdRegion.appendChild(wrapperDiv);\n}\n});\ndocument.addEventListener(\"DOMContentLoaded\", function() {\n// Sélectionner les éléments pertinents\nconst documentsLiensWrapper = document.querySelector(\".documents-liens-wrapper\");\nconst blockRegionThird = document.querySelector(\".block-region-third\");\n\n// Vérifier que les éléments existent avant de les manipuler\nif (documentsLiensWrapper && blockRegionThird) {\n // Déplacer .documents-liens-wrapper en dehors du div contenant les boutons prev/next\n blockRegionThird.appendChild(documentsLiensWrapper);\n}\n});\n\n/////////////////// start langswitcher position responsive//////////////////////\ndocument.addEventListener(\"DOMContentLoaded\", function () {\n// Fonction pour déplacer le bloc en fonction de la taille de l'écran\nfunction moveLanguageSwitcher() {\n const languageSwitcher = document.getElementById(\"block-quartiers-de-demain-selecteurdelangue\");\n const navContainer = document.querySelector(\".header_nav_container\");\n\n if (window.innerWidth <= 810) { // Si écran téléphone\n if (languageSwitcher && navContainer && !navContainer.contains(languageSwitcher)) {\n navContainer.appendChild(languageSwitcher); // Déplace le bloc dans header_nav_container\n }\n } else { // Si écran non téléphone\n const headerRightContainer = document.querySelector(\".header_right_container\");\n if (languageSwitcher && headerRightContainer && !headerRightContainer.contains(languageSwitcher)) {\n headerRightContainer.appendChild(languageSwitcher); // Remet le bloc dans sa position initiale\n }\n }\n}\n\n// Déclencher au chargement et au redimensionnement\nmoveLanguageSwitcher();\nwindow.addEventListener(\"resize\", moveLanguageSwitcher);\n});\n\n/////////////////// end langswitcher position responsive///////////////////////////////////////////////////////////\n\n/////////////// start class à view-rows-ressources ////////\n$(document).ready(function () {\n $(\".view-rows-wrapper\").each(function () {\n let h3Container = $(this).prev(\"h3\").find(\"div[class^='type-']\");\n let classToAdd = h3Container.attr(\"class\"); // Récupère la classe complète (ex: \"type-Documentation\")\n\n if (classToAdd) {\n $(this).addClass(classToAdd); // Ajoute cette classe à .view-rows-wrapper\n }\n });\n});\n////////////////// end class à view-rows-wrapper ////////////////\n\n\n\n/////////////////// start voir plus... ressources ////////////////////\n\n$(document).ready(function () {\n // Vérifier si on est sur la page avec l'ID #ressources\n if ($(\"#ressources\").length > 0) {\n $(\".view-rows-wrapper\").each(function () {\n let container = $(this); // Cible uniquement cette section\n let items = container.find(\".views-row\"); // Les éléments à afficher progressivement\n let visibleCount = 4; // Nombre d'éléments visibles au départ (par défaut)\n\n // Récupérer la classe `type-XXX`\n let typeClass = container.attr(\"class\").split(\" \").find(cls => cls.startsWith(\"type-\"));\n let typeName = typeClass ? typeClass.replace(\"type-\", \"\").replace(/-/g, \" \") : \"contenu\"; // Nettoyer le nom\n\n // Ajuster le nombre d'éléments visibles en fonction du type\n if (typeClass && (typeClass === \"type-podcast\" || typeClass.toLowerCase() === \"type-vidéo\")) {\n visibleCount = 2; // Pour Podcast et Vidéo\n } else if (typeClass === \"type-kit-de-communication\") {\n visibleCount = 1; // Pour Kit de Communication\n }\n\n // Si le nombre total d'éléments est inférieur ou égal à la limite, ne pas ajouter le bouton\n if (items.length <= visibleCount) {\n return; // Sortir de la boucle\n }\n\n // Ajouter le bouton dynamiquement après chaque `.view-rows-wrapper`\n let button = $(\"