Compare commits

..

19 Commits

Author SHA1 Message Date
e85851bd4d MODIF CONFIGS DRUPAL centre de ressources: tri par étape + ressources mis en avant 2025-05-22 00:51:02 +02:00
bfb39a0259 filtre ressources par étape + triées par ordre chrono 2025-05-20 20:07:03 +02:00
e7a5e163ff réajout du field type de ressource 2025-04-14 16:03:11 +02:00
95e1b02760 suppression du field type de ressource qui bug en prod 2025-04-14 14:24:40 +02:00
b12af44825 test ci-cd 2025-04-07 19:33:55 +02:00
d90aa2726b test ci-cd 2025-04-07 18:35:29 +02:00
7387ce7f50 EXPORT CONFIG ! fin du centre de ressource 2025-04-02 01:06:39 +02:00
7792005403 test ci/cd 2025-03-28 18:16:12 +01:00
b538e754d2 test ci/cd 2025-03-28 16:05:00 +01:00
d805ef35b1 avancées centre de ressources 2025-03-28 15:10:03 +01:00
a1916e3219 avancées centre de ressource 2025-03-26 00:28:41 +01:00
9093caa557 MODIFS CONFIGS : fetch ressources content 2025-03-11 23:53:31 +01:00
2ca44f2550 refactor content store data fetching with promises 2025-03-07 17:46:13 +01:00
dffd179bc9 retour à l'index en cliquant sur la carte depuis une étape 2025-03-03 22:42:55 +01:00
6ecf055060 MODIF CONFIGS : view étape l'icône sur la map n'est plus hardcodée 2025-02-28 17:24:54 +01:00
8b2938de0e content type ressource 2025-02-24 13:26:00 +01:00
ed8edbd0c0 updated core and contrib, profile update 2025-02-24 13:16:56 +01:00
045a6050be updated core and contrib 2025-02-24 13:11:01 +01:00
d900ea5472 content type ressource 2025-02-24 12:30:20 +01:00
96 changed files with 3488 additions and 930 deletions

460
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,6 @@ langcode: fr
maxlength_block_class_field: 255
field_type: multiple_textfields
default_case: standard
block_classes_stored: { }
enable_attributes: true
enable_auto_complete: true
qty_classes_per_block: 10
@@ -16,7 +15,7 @@ weight_attributes: 0
weight_class: 0
weight_id: 0
filter_html_clean_css_identifier: ''
maxlength_attributes: 255
maxlength_attributes: 0
maxlength_id: 255
attribute_keys_stored: '[]'
attribute_value_stored: '[]'

View File

@@ -0,0 +1,11 @@
features:
node_user_picture: false
comment_user_picture: true
comment_user_verification: true
favicon: 0
logo:
use_default: 0
path: 'public://favicon-caravane_1.png'
favicon:
use_default: 0
path: ''

View File

@@ -1,4 +1,4 @@
uuid: b0c240c8-beea-4be3-96b8-6543b6734b25
uuid: 39f683b9-ea9f-4e84-8dec-c30162c19b72
langcode: fr
status: true
dependencies: { }
@@ -12,6 +12,6 @@ context:
fallback:
language: ''
menu:
path: /edit/partenaire
path: /edit/partenaires
weight: 0
description: ''

View File

@@ -0,0 +1,17 @@
uuid: 67828fd5-674e-4e52-9f2f-3457e06c0baa
langcode: fr
status: true
dependencies: { }
id: intro_ressource
label: 'intro ressource'
token: false
context:
show_warning: true
group:
language: false
fallback:
language: ''
menu:
path: /edit/ressource
weight: 0
description: ''

View File

@@ -0,0 +1,22 @@
uuid: 83ba5ce9-056a-4c77-8b23-0801dc5eca3b
langcode: fr
status: true
dependencies:
config:
- node.type.equipe
id: node.equipe.promote
field_name: promote
entity_type: node
bundle: equipe
label: "Promu en page d'accueil"
description: ''
required: false
translatable: true
default_value:
-
value: 0
default_value_callback: ''
settings:
on_label: Activé
off_label: Désactivé
field_type: boolean

View File

@@ -0,0 +1,22 @@
uuid: e76cb255-d05a-4ffd-8f7e-23a17e8f25a5
langcode: fr
status: true
dependencies:
config:
- node.type.ressource
id: node.ressource.promote
field_name: promote
entity_type: node
bundle: ressource
label: "Promu en page d'accueil"
description: ''
required: false
translatable: true
default_value:
-
value: 0
default_value_callback: ''
settings:
on_label: Activé
off_label: Désactivé
field_type: boolean

View File

@@ -1,4 +1,4 @@
uuid: c8c782e1-e597-4e4d-ac96-65142dbadedb
uuid: 3d095235-90fe-4b5f-ae32-ef10c26c1f47
langcode: fr
status: true
dependencies:

View File

@@ -0,0 +1,33 @@
uuid: c5c09811-6a65-4cff-9936-78dc896b9adf
langcode: fr
status: true
dependencies:
config:
- config_pages.type.intro_ressource
- field.field.config_pages.intro_ressource.field_intro
- field.field.config_pages.intro_ressource.field_titre
module:
- text
id: config_pages.intro_ressource.default
targetEntityType: config_pages
bundle: intro_ressource
mode: default
content:
field_intro:
type: text_textarea
weight: 1
region: content
settings:
rows: 5
placeholder: ''
third_party_settings: { }
field_titre:
type: string_textfield
weight: 0
region: content
settings:
size: 60
placeholder: ''
third_party_settings: { }
hidden:
label: true

View File

@@ -0,0 +1,95 @@
uuid: 71b2f68b-0171-41db-ba52-664ecb84b433
langcode: fr
status: true
dependencies:
config:
- field.field.node.equipe.body
- field.field.node.equipe.field_personne_s
- field.field.node.equipe.field_poid
- node.type.equipe
module:
- field_group
- paragraphs
- text
third_party_settings:
field_group:
group_details:
children:
- field_poid
- status
label: Details
region: content
parent_name: ''
weight: 3
format_type: details_sidebar
format_settings:
classes: ''
show_empty_fields: false
id: ''
label_as_html: false
open: true
description: ''
required_fields: true
weight: -100
id: node.equipe.default
targetEntityType: node
bundle: equipe
mode: default
content:
body:
type: text_textarea_with_summary
weight: 1
region: content
settings:
rows: 9
summary_rows: 3
placeholder: ''
show_summary: false
third_party_settings: { }
field_personne_s:
type: paragraphs
weight: 2
region: content
settings:
title: Paragraphe
title_plural: Paragraphs
edit_mode: open
closed_mode: summary
autocollapse: none
closed_mode_threshold: 0
add_mode: dropdown
form_display_mode: default
default_paragraph_type: ''
features:
collapse_edit_all: collapse_edit_all
duplicate: duplicate
third_party_settings: { }
field_poid:
type: number
weight: 12
region: content
settings:
placeholder: ''
third_party_settings: { }
status:
type: boolean_checkbox
weight: 13
region: content
settings:
display_label: true
third_party_settings: { }
title:
type: string_textfield
weight: 0
region: content
settings:
size: 60
placeholder: ''
third_party_settings: { }
hidden:
created: true
langcode: true
path: true
promote: true
sticky: true
uid: true

View File

@@ -1,3 +1,4 @@
uuid: 4b684ae9-1a47-4712-bfbe-54da6f8555da
langcode: fr
status: true
dependencies:

View File

@@ -0,0 +1,207 @@
uuid: 4102b51d-df23-46b8-8a6f-0adee6746f5f
langcode: fr
status: true
dependencies:
config:
- field.field.node.ressource.field_autheurice
- field.field.node.ressource.field_date_ressource
- field.field.node.ressource.field_etape
- field.field.node.ressource.field_introduction
- field.field.node.ressource.field_mis_en_avant
- field.field.node.ressource.field_parties_ressource
- field.field.node.ressource.field_thematiques
- field.field.node.ressource.field_type_de_ressource
- node.type.ressource
module:
- autocomplete_deluxe
- datetime
- field_group
- paragraphs
- path
- text
third_party_settings:
field_group:
group_details:
children:
- field_thematiques
- field_etape
- status
- path
- field_mis_en_avant
- field_type_de_ressource
label: Details
region: content
parent_name: ''
weight: 6
format_type: details_sidebar
format_settings:
classes: ''
show_empty_fields: false
id: ''
label_as_html: false
open: true
description: ''
required_fields: true
weight: -100
group_tabs:
children:
- group_infos
- group_parties
label: Tabs
region: content
parent_name: ''
weight: 1
format_type: tabs
format_settings:
classes: ''
show_empty_fields: false
id: ''
label_as_html: false
direction: horizontal
width_breakpoint: 640
group_infos:
children:
- field_autheurice
- field_date_ressource
- field_introduction
label: Infos
region: content
parent_name: group_tabs
weight: 20
format_type: tab
format_settings:
classes: ''
show_empty_fields: false
id: ''
label_as_html: false
formatter: closed
description: ''
required_fields: true
group_parties:
children:
- field_parties_ressource
label: Parties
region: content
parent_name: group_tabs
weight: 21
format_type: tab
format_settings:
classes: ''
show_empty_fields: false
id: ''
label_as_html: false
formatter: closed
description: ''
required_fields: true
id: node.ressource.default
targetEntityType: node
bundle: ressource
mode: default
content:
field_autheurice:
type: string_textfield
weight: 2
region: content
settings:
size: 60
placeholder: ''
third_party_settings: { }
field_date_ressource:
type: datetime_default
weight: 3
region: content
settings: { }
third_party_settings: { }
field_etape:
type: entity_reference_autocomplete
weight: 28
region: content
settings:
match_operator: CONTAINS
match_limit: 10
size: 60
placeholder: ''
third_party_settings: { }
field_introduction:
type: text_textarea
weight: 4
region: content
settings:
rows: 5
placeholder: ''
third_party_settings: { }
field_mis_en_avant:
type: boolean_checkbox
weight: 31
region: content
settings:
display_label: true
third_party_settings: { }
field_parties_ressource:
type: paragraphs
weight: 5
region: content
settings:
title: Paragraphe
title_plural: Paragraphs
edit_mode: open
closed_mode: summary
autocollapse: none
closed_mode_threshold: 0
add_mode: dropdown
form_display_mode: default
default_paragraph_type: ''
features:
collapse_edit_all: collapse_edit_all
duplicate: duplicate
third_party_settings: { }
field_thematiques:
type: autocomplete_deluxe
weight: 27
region: content
settings:
match_operator: CONTAINS
autocomplete_route_name: autocomplete_deluxe.autocomplete
size: 60
selection_handler: default
match_limit: 10
min_length: 0
delimiter: ''
not_found_message_allow: false
not_found_message: "The term '@term' will be added"
new_terms: false
no_empty_message: 'No terms could be found. Please type in order to add a new term.'
third_party_settings: { }
field_type_de_ressource:
type: options_select
weight: 32
region: content
settings: { }
third_party_settings: { }
path:
type: path
weight: 30
region: content
settings: { }
third_party_settings: { }
status:
type: boolean_checkbox
weight: 29
region: content
settings:
display_label: true
third_party_settings: { }
title:
type: string_textfield
weight: 0
region: content
settings:
size: 60
placeholder: ''
third_party_settings: { }
hidden:
created: true
langcode: true
promote: true
sticky: true
uid: true

View File

@@ -0,0 +1,70 @@
uuid: 0f3046d1-fa2d-4286-a5a4-dcad356723f0
langcode: fr
status: true
dependencies:
config:
- field.field.paragraph.document.field_autheurice_s
- field.field.paragraph.document.field_date
- field.field.paragraph.document.field_document
- field.field.paragraph.document.field_sous_titre
- field.field.paragraph.document.field_titre
- field.field.paragraph.document.field_vignette
- image.style.thumbnail
- paragraphs.paragraphs_type.document
module:
- datetime
- file
- image
id: paragraph.document.default
targetEntityType: paragraph
bundle: document
mode: default
content:
field_autheurice_s:
type: string_textfield
weight: 3
region: content
settings:
size: 60
placeholder: ''
third_party_settings: { }
field_date:
type: datetime_default
weight: 4
region: content
settings: { }
third_party_settings: { }
field_document:
type: file_generic
weight: 5
region: content
settings:
progress_indicator: throbber
third_party_settings: { }
field_sous_titre:
type: string_textfield
weight: 2
region: content
settings:
size: 60
placeholder: ''
third_party_settings: { }
field_titre:
type: string_textfield
weight: 1
region: content
settings:
size: 60
placeholder: ''
third_party_settings: { }
field_vignette:
type: image_image
weight: 0
region: content
settings:
progress_indicator: throbber
preview_image_style: thumbnail
third_party_settings: { }
hidden:
created: true
status: true

View File

@@ -5,7 +5,6 @@ dependencies:
config:
- config_pages.type.intro_gouvernance
- field.field.config_pages.intro_gouvernance.field_intro
- field.field.config_pages.intro_gouvernance.field_titre
module:
- text
id: config_pages.intro_gouvernance.default
@@ -18,15 +17,8 @@ content:
label: visually_hidden
settings: { }
third_party_settings: { }
weight: 1
region: content
field_titre:
type: string
label: above
settings:
link_to_entity: false
third_party_settings: { }
weight: 0
region: content
hidden:
field_titre: true
search_api_excerpt: true

View File

@@ -1,4 +1,4 @@
uuid: a79b589c-3286-425b-b508-38744f9ebeb1
uuid: cad2e853-7706-4477-a3cc-d810dcd76c96
langcode: fr
status: true
dependencies:
@@ -18,7 +18,7 @@ content:
label: visually_hidden
settings: { }
third_party_settings: { }
weight: 1
weight: 0
region: content
field_titre:
type: string
@@ -26,7 +26,7 @@ content:
settings:
link_to_entity: false
third_party_settings: { }
weight: 0
weight: 1
region: content
hidden:
search_api_excerpt: true

View File

@@ -0,0 +1,32 @@
uuid: 342c8cdf-4085-4e41-941f-b503beb0ad1f
langcode: fr
status: true
dependencies:
config:
- config_pages.type.intro_ressource
- field.field.config_pages.intro_ressource.field_intro
- field.field.config_pages.intro_ressource.field_titre
module:
- text
id: config_pages.intro_ressource.default
targetEntityType: config_pages
bundle: intro_ressource
mode: default
content:
field_intro:
type: text_default
label: visually_hidden
settings: { }
third_party_settings: { }
weight: 0
region: content
field_titre:
type: string
label: above
settings:
link_to_entity: false
third_party_settings: { }
weight: 0
region: content
hidden:
search_api_excerpt: true

View File

@@ -0,0 +1,40 @@
uuid: 6c5f13b3-2cff-4094-a335-ccc5c7163003
langcode: fr
status: true
dependencies:
config:
- field.field.node.equipe.body
- field.field.node.equipe.field_personne_s
- field.field.node.equipe.field_poid
- node.type.equipe
module:
- entity_reference_revisions
- text
- user
id: node.equipe.default
targetEntityType: node
bundle: equipe
mode: default
content:
body:
type: text_default
label: visually_hidden
settings: { }
third_party_settings: { }
weight: 0
region: content
field_personne_s:
type: entity_reference_revisions_entity_view
label: visually_hidden
settings:
view_mode: default
link: ''
third_party_settings: { }
weight: 1
region: content
hidden:
field_poid: true
footnotes_group: true
langcode: true
links: true
search_api_excerpt: true

View File

@@ -0,0 +1,37 @@
uuid: aef5e1f6-ce57-488c-bb21-1990e7123a67
langcode: fr
status: true
dependencies:
config:
- core.entity_view_mode.node.teaser
- field.field.node.equipe.body
- field.field.node.equipe.field_personne_s
- field.field.node.equipe.field_poid
- node.type.equipe
module:
- text
- user
id: node.equipe.teaser
targetEntityType: node
bundle: equipe
mode: teaser
content:
body:
type: text_summary_or_trimmed
label: hidden
settings:
trim_length: 600
third_party_settings: { }
weight: 101
region: content
links:
settings: { }
third_party_settings: { }
weight: 100
region: content
hidden:
field_personne_s: true
field_poid: true
footnotes_group: true
langcode: true
search_api_excerpt: true

View File

@@ -0,0 +1,100 @@
uuid: bf3d8317-459e-4833-8e55-9745ff540413
langcode: fr
status: true
dependencies:
config:
- field.field.node.ressource.field_autheurice
- field.field.node.ressource.field_date_ressource
- field.field.node.ressource.field_etape
- field.field.node.ressource.field_introduction
- field.field.node.ressource.field_mis_en_avant
- field.field.node.ressource.field_parties_ressource
- field.field.node.ressource.field_thematiques
- field.field.node.ressource.field_type_de_ressource
- node.type.ressource
module:
- datetime
- entity_reference_revisions
- options
- text
- user
id: node.ressource.default
targetEntityType: node
bundle: ressource
mode: default
content:
field_autheurice:
type: string
label: above
settings:
link_to_entity: false
third_party_settings: { }
weight: 103
region: content
field_date_ressource:
type: datetime_default
label: above
settings:
timezone_override: ''
format_type: medium
third_party_settings: { }
weight: 104
region: content
field_etape:
type: entity_reference_label
label: above
settings:
link: true
third_party_settings: { }
weight: 105
region: content
field_introduction:
type: text_default
label: above
settings: { }
third_party_settings: { }
weight: 107
region: content
field_mis_en_avant:
type: boolean
label: above
settings:
format: default
format_custom_false: ''
format_custom_true: ''
third_party_settings: { }
weight: 109
region: content
field_parties_ressource:
type: entity_reference_revisions_entity_view
label: above
settings:
view_mode: default
link: ''
third_party_settings: { }
weight: 106
region: content
field_thematiques:
type: entity_reference_label
label: visually_hidden
settings:
link: true
third_party_settings: { }
weight: 4
region: content
field_type_de_ressource:
type: list_default
label: above
settings: { }
third_party_settings: { }
weight: 108
region: content
links:
settings: { }
third_party_settings: { }
weight: 100
region: content
hidden:
footnotes_group: true
langcode: true
search_api_excerpt: true

View File

@@ -0,0 +1,39 @@
uuid: 1a7f54a0-6af9-4db8-994f-8784c4fa0b0d
langcode: fr
status: true
dependencies:
config:
- core.entity_view_mode.node.teaser
- field.field.node.ressource.field_autheurice
- field.field.node.ressource.field_date_ressource
- field.field.node.ressource.field_etape
- field.field.node.ressource.field_introduction
- field.field.node.ressource.field_mis_en_avant
- field.field.node.ressource.field_parties_ressource
- field.field.node.ressource.field_thematiques
- field.field.node.ressource.field_type_de_ressource
- node.type.ressource
module:
- user
id: node.ressource.teaser
targetEntityType: node
bundle: ressource
mode: teaser
content:
links:
settings: { }
third_party_settings: { }
weight: 100
region: content
hidden:
field_autheurice: true
field_date_ressource: true
field_etape: true
field_introduction: true
field_mis_en_avant: true
field_parties_ressource: true
field_thematiques: true
field_type_de_ressource: true
footnotes_group: true
langcode: true
search_api_excerpt: true

View File

@@ -0,0 +1,75 @@
uuid: 3e7728df-de61-4949-b50a-a220db1c6c12
langcode: fr
status: true
dependencies:
config:
- field.field.paragraph.document.field_autheurice_s
- field.field.paragraph.document.field_date
- field.field.paragraph.document.field_document
- field.field.paragraph.document.field_sous_titre
- field.field.paragraph.document.field_titre
- field.field.paragraph.document.field_vignette
- paragraphs.paragraphs_type.document
module:
- datetime
- file
- image
id: paragraph.document.default
targetEntityType: paragraph
bundle: document
mode: default
content:
field_autheurice_s:
type: string
label: visually_hidden
settings:
link_to_entity: false
third_party_settings: { }
weight: 3
region: content
field_date:
type: datetime_default
label: visually_hidden
settings:
timezone_override: ''
format_type: medium
third_party_settings: { }
weight: 4
region: content
field_document:
type: file_default
label: above
settings:
use_description_as_link_text: true
third_party_settings: { }
weight: 5
region: content
field_sous_titre:
type: string
label: visually_hidden
settings:
link_to_entity: false
third_party_settings: { }
weight: 2
region: content
field_titre:
type: string
label: visually_hidden
settings:
link_to_entity: false
third_party_settings: { }
weight: 1
region: content
field_vignette:
type: image
label: visually_hidden
settings:
image_link: ''
image_style: ''
image_loading:
attribute: lazy
third_party_settings: { }
weight: 0
region: content
hidden:
search_api_excerpt: true

View File

@@ -1,4 +1,4 @@
uuid: 3035b470-e4d9-4807-acd6-24a09525f537
uuid: 884f84e5-faeb-4719-a083-32cb215fd311
langcode: fr
status: true
dependencies:

View File

@@ -1,4 +1,4 @@
uuid: bbddf173-169d-4977-ba3f-d1ec9f5aa452
uuid: 00096414-fab5-4bed-ac99-b819ad041ed9
langcode: fr
status: true
dependencies:

View File

@@ -0,0 +1,24 @@
uuid: e669e2a0-7ad6-4744-9bcf-efd428aa8070
langcode: fr
status: true
dependencies:
config:
- config_pages.type.intro_ressource
- field.storage.config_pages.field_intro
- filter.format.wysiwyg
module:
- text
id: config_pages.intro_ressource.field_intro
field_name: field_intro
entity_type: config_pages
bundle: intro_ressource
label: Intro
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
allowed_formats:
- wysiwyg
field_type: text_long

View File

@@ -0,0 +1,19 @@
uuid: 1a5ca231-32de-4adc-b066-22a8377bf323
langcode: fr
status: true
dependencies:
config:
- config_pages.type.intro_ressource
- field.storage.config_pages.field_titre
id: config_pages.intro_ressource.field_titre
field_name: field_titre
entity_type: config_pages
bundle: intro_ressource
label: titre
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: string

View File

@@ -0,0 +1,24 @@
uuid: 09512770-b2ed-4ca1-a548-2f59f416c789
langcode: fr
status: true
dependencies:
config:
- field.storage.node.body
- node.type.equipe
module:
- text
id: node.equipe.body
field_name: body
entity_type: node
bundle: equipe
label: Présentation
description: ''
required: false
translatable: true
default_value: { }
default_value_callback: ''
settings:
display_summary: true
required_summary: false
allowed_formats: { }
field_type: text_with_summary

View File

@@ -0,0 +1,61 @@
uuid: 8198a2fc-6ac0-4d39-b72f-55dbaf51fb10
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_personne_s
- node.type.equipe
- paragraphs.paragraphs_type.personne
module:
- entity_reference_revisions
id: node.equipe.field_personne_s
field_name: field_personne_s
entity_type: node
bundle: equipe
label: Personne(s)
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
handler: 'default:paragraph'
handler_settings:
target_bundles:
personne: personne
negate: 0
target_bundles_drag_drop:
carte_sensible:
weight: 12
enabled: false
chiffre_cle:
weight: 14
enabled: false
chiffres_cles:
weight: 13
enabled: false
diaporama:
weight: 15
enabled: false
entretien:
weight: 16
enabled: false
entretien_question_reponse:
weight: 17
enabled: false
exergue:
weight: 18
enabled: false
galleries:
weight: 19
enabled: false
personne:
weight: 20
enabled: true
titre_texte:
weight: 21
enabled: false
video:
weight: 22
enabled: false
field_type: entity_reference_revisions

View File

@@ -0,0 +1,25 @@
uuid: a1872697-2226-4008-a585-993279d18649
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_poid
- node.type.equipe
id: node.equipe.field_poid
field_name: field_poid
entity_type: node
bundle: equipe
label: Poid
description: ''
required: false
translatable: false
default_value:
-
value: 0
default_value_callback: ''
settings:
min: -20
max: 20
prefix: ''
suffix: ''
field_type: integer

View File

@@ -0,0 +1,19 @@
uuid: 42ddeda4-ef27-484f-bdc0-e385bcdc139c
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_autheurice
- node.type.ressource
id: node.ressource.field_autheurice
field_name: field_autheurice
entity_type: node
bundle: ressource
label: Auteur⋅ice
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: string

View File

@@ -0,0 +1,21 @@
uuid: 1c46663f-8000-4366-9150-e03675aac525
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_date_ressource
- node.type.ressource
module:
- datetime
id: node.ressource.field_date_ressource
field_name: field_date_ressource
entity_type: node
bundle: ressource
label: Date
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: datetime

View File

@@ -0,0 +1,29 @@
uuid: 42150082-682c-4f4d-892e-1544e409eb42
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_etape
- node.type.etape
- node.type.ressource
id: node.ressource.field_etape
field_name: field_etape
entity_type: node
bundle: ressource
label: Etape
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
handler: 'default:node'
handler_settings:
target_bundles:
etape: etape
sort:
field: _none
direction: ASC
auto_create: false
auto_create_bundle: ''
field_type: entity_reference

View File

@@ -0,0 +1,24 @@
uuid: a2317fba-c5ee-4c63-b2d5-5d6d8aa98685
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_introduction
- filter.format.wysiwyg
- node.type.ressource
module:
- text
id: node.ressource.field_introduction
field_name: field_introduction
entity_type: node
bundle: ressource
label: introduction
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
allowed_formats:
- wysiwyg
field_type: text_long

View File

@@ -0,0 +1,23 @@
uuid: 3e824533-8b04-4c3c-acb4-cdf87f40e281
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_mis_en_avant
- node.type.ressource
id: node.ressource.field_mis_en_avant
field_name: field_mis_en_avant
entity_type: node
bundle: ressource
label: 'mis en avant'
description: ''
required: false
translatable: false
default_value:
-
value: 0
default_value_callback: ''
settings:
on_label: Activé
off_label: Désactivé
field_type: boolean

View File

@@ -0,0 +1,72 @@
uuid: 3fd63e18-4bce-4e11-a6b3-3cd627c64391
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_parties_ressource
- node.type.ressource
- paragraphs.paragraphs_type.diaporama
- paragraphs.paragraphs_type.document
- paragraphs.paragraphs_type.galleries
- paragraphs.paragraphs_type.titre_texte
- paragraphs.paragraphs_type.video
module:
- entity_reference_revisions
id: node.ressource.field_parties_ressource
field_name: field_parties_ressource
entity_type: node
bundle: ressource
label: Parties
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
handler: 'default:paragraph'
handler_settings:
target_bundles:
document: document
diaporama: diaporama
galleries: galleries
titre_texte: titre_texte
video: video
negate: 0
target_bundles_drag_drop:
carte_sensible:
weight: 14
enabled: false
chiffre_cle:
weight: 16
enabled: false
chiffres_cles:
weight: 15
enabled: false
diaporama:
weight: 17
enabled: true
document:
weight: 13
enabled: true
entretien:
weight: 18
enabled: false
entretien_question_reponse:
weight: 19
enabled: false
exergue:
weight: 20
enabled: false
galleries:
weight: 21
enabled: true
personne:
weight: 22
enabled: false
titre_texte:
weight: 23
enabled: true
video:
weight: 24
enabled: true
field_type: entity_reference_revisions

View File

@@ -0,0 +1,29 @@
uuid: 087a6777-c29f-4d0c-aad0-98ffe3e65ab7
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_thematiques
- node.type.ressource
- taxonomy.vocabulary.thematiques
id: node.ressource.field_thematiques
field_name: field_thematiques
entity_type: node
bundle: ressource
label: Thématiques
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
handler: 'default:taxonomy_term'
handler_settings:
target_bundles:
thematiques: thematiques
sort:
field: name
direction: asc
auto_create: false
auto_create_bundle: ''
field_type: entity_reference

View File

@@ -0,0 +1,21 @@
uuid: e439dc6f-3fc5-40cb-b615-f95c5a22a6f9
langcode: fr
status: true
dependencies:
config:
- field.storage.node.field_type_de_ressource
- node.type.ressource
module:
- options
id: node.ressource.field_type_de_ressource
field_name: field_type_de_ressource
entity_type: node
bundle: ressource
label: 'Type de ressource'
description: ''
required: true
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: list_string

View File

@@ -0,0 +1,19 @@
uuid: bf0364b9-e5ee-4bd5-b229-4935d7284e8a
langcode: fr
status: true
dependencies:
config:
- field.storage.paragraph.field_autheurice_s
- paragraphs.paragraphs_type.document
id: paragraph.document.field_autheurice_s
field_name: field_autheurice_s
entity_type: paragraph
bundle: document
label: Autheur⋅ice(s)
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: string

View File

@@ -0,0 +1,21 @@
uuid: 3fe468b5-dc03-47d8-a4eb-eb9fa6b51ea9
langcode: fr
status: true
dependencies:
config:
- field.storage.paragraph.field_date
- paragraphs.paragraphs_type.document
module:
- datetime
id: paragraph.document.field_date
field_name: field_date
entity_type: paragraph
bundle: document
label: Date
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: datetime

View File

@@ -0,0 +1,27 @@
uuid: 68276064-4601-4b82-a6b5-336faf39a572
langcode: fr
status: true
dependencies:
config:
- field.storage.paragraph.field_document
- paragraphs.paragraphs_type.document
module:
- file
id: paragraph.document.field_document
field_name: field_document
entity_type: paragraph
bundle: document
label: Document
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
handler: 'default:file'
handler_settings: { }
file_directory: '[date:custom:Y]-[date:custom:m]'
file_extensions: 'pdf doc docx odt zip'
max_filesize: ''
description_field: true
field_type: file

View File

@@ -0,0 +1,19 @@
uuid: cddd8fbd-4397-41b9-9dde-5d018b91bf5f
langcode: fr
status: true
dependencies:
config:
- field.storage.paragraph.field_sous_titre
- paragraphs.paragraphs_type.document
id: paragraph.document.field_sous_titre
field_name: field_sous_titre
entity_type: paragraph
bundle: document
label: Sous-titre
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: string

View File

@@ -0,0 +1,19 @@
uuid: f697951d-0042-4a72-bc0d-53251f0f8f37
langcode: fr
status: true
dependencies:
config:
- field.storage.paragraph.field_titre
- paragraphs.paragraphs_type.document
id: paragraph.document.field_titre
field_name: field_titre
entity_type: paragraph
bundle: document
label: Titre
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: string

View File

@@ -0,0 +1,41 @@
uuid: 9ff673ba-4d36-4621-9eef-4c362d689788
langcode: fr
status: true
dependencies:
config:
- field.storage.paragraph.field_vignette
- paragraphs.paragraphs_type.document
module:
- image
id: paragraph.document.field_vignette
field_name: field_vignette
entity_type: paragraph
bundle: document
label: Vignette
description: ''
required: false
translatable: false
default_value: { }
default_value_callback: ''
settings:
handler: 'default:file'
handler_settings: { }
file_directory: '[date:custom:Y]-[date:custom:m]'
file_extensions: 'png gif jpg jpeg webp'
max_filesize: ''
max_resolution: ''
min_resolution: ''
alt_field: true
alt_field_required: true
title_field: false
title_field_required: false
default_image:
uuid: ''
alt: ''
title: ''
width: null
height: null
caption: ''
caption_field: 0
caption_field_required: 0
field_type: image

View File

@@ -0,0 +1,21 @@
uuid: b296abc1-35b8-4a42-9ecc-01b24f689d64
langcode: fr
status: true
dependencies:
module:
- node
id: node.field_autheurice
field_name: field_autheurice
entity_type: node
type: string
settings:
max_length: 255
case_sensitive: false
is_ascii: false
module: core
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@@ -0,0 +1,20 @@
uuid: 067cb21a-63e7-4ec0-9e84-d94aa05a90ad
langcode: fr
status: true
dependencies:
module:
- datetime
- node
id: node.field_date_ressource
field_name: field_date_ressource
entity_type: node
type: datetime
settings:
datetime_type: date
module: datetime
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@@ -0,0 +1,19 @@
uuid: 9d4c41d9-887c-4d7a-aa95-a3c02c49cb51
langcode: fr
status: true
dependencies:
module:
- node
id: node.field_etape
field_name: field_etape
entity_type: node
type: entity_reference
settings:
target_type: node
module: core
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@@ -0,0 +1,19 @@
uuid: 6646cf31-1641-44c2-ad7d-776506b27e89
langcode: fr
status: true
dependencies:
module:
- node
- text
id: node.field_introduction
field_name: field_introduction
entity_type: node
type: text_long
settings: { }
module: text
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@@ -0,0 +1,18 @@
uuid: e92021e0-c606-4e50-b042-012920aa6341
langcode: fr
status: true
dependencies:
module:
- node
id: node.field_mis_en_avant
field_name: field_mis_en_avant
entity_type: node
type: boolean
settings: { }
module: core
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@@ -0,0 +1,21 @@
uuid: b2aa7bc8-95a8-4260-81d3-78c515ff2fd8
langcode: fr
status: true
dependencies:
module:
- entity_reference_revisions
- node
- paragraphs
id: node.field_parties_ressource
field_name: field_parties_ressource
entity_type: node
type: entity_reference_revisions
settings:
target_type: paragraph
module: entity_reference_revisions
locked: false
cardinality: -1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@@ -0,0 +1,33 @@
uuid: be6b9eb9-d827-4adc-9106-e7c31b94aff6
langcode: fr
status: true
dependencies:
module:
- node
- options
id: node.field_type_de_ressource
field_name: field_type_de_ressource
entity_type: node
type: list_string
settings:
allowed_values:
-
value: cartes_blanches
label: 'Cartes blanches'
-
value: reportages
label: Reportages
-
value: videos
label: Videos
-
value: documents
label: Documents
allowed_values_function: ''
module: options
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@@ -0,0 +1,21 @@
uuid: dbcf9d2c-90f4-4678-9bba-30ea2f7ffdb3
langcode: fr
status: true
dependencies:
module:
- paragraphs
id: paragraph.field_autheurice_s
field_name: field_autheurice_s
entity_type: paragraph
type: string
settings:
max_length: 255
case_sensitive: false
is_ascii: false
module: core
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@@ -0,0 +1,20 @@
uuid: 2d35b014-4b74-436b-8325-53f1cffa1ed9
langcode: fr
status: true
dependencies:
module:
- datetime
- paragraphs
id: paragraph.field_date
field_name: field_date
entity_type: paragraph
type: datetime
settings:
datetime_type: date
module: datetime
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@@ -0,0 +1,23 @@
uuid: 781e5561-6299-4ce5-a4e4-72211d29087a
langcode: fr
status: true
dependencies:
module:
- file
- paragraphs
id: paragraph.field_document
field_name: field_document
entity_type: paragraph
type: file
settings:
target_type: file
display_field: true
display_default: true
uri_scheme: public
module: file
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@@ -0,0 +1,21 @@
uuid: 79dede5a-213c-470a-a235-f2813301a849
langcode: fr
status: true
dependencies:
module:
- paragraphs
id: paragraph.field_sous_titre
field_name: field_sous_titre
entity_type: paragraph
type: string
settings:
max_length: 255
case_sensitive: false
is_ascii: false
module: core
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@@ -0,0 +1,30 @@
uuid: 6bfd41d2-f70a-4da3-b7a9-44182e168607
langcode: fr
status: true
dependencies:
module:
- file
- image
- paragraphs
id: paragraph.field_vignette
field_name: field_vignette
entity_type: paragraph
type: image
settings:
target_type: file
display_field: false
display_default: false
uri_scheme: public
default_image:
uuid: ''
alt: ''
title: ''
width: null
height: null
module: image
locked: false
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false

View File

@@ -0,0 +1,11 @@
uuid: 04893961-9641-44e5-8b17-4d5b0bbab8c9
langcode: fr
status: true
dependencies:
config:
- node.type.equipe
id: node.equipe
target_entity_type_id: node
target_bundle: equipe
default_langcode: site_default
language_alterable: false

View File

@@ -0,0 +1,11 @@
uuid: 0df50a36-6f55-483f-8ce0-3d7925fe9e3a
langcode: fr
status: true
dependencies:
config:
- node.type.ressource
id: node.ressource
target_entity_type_id: node
target_bundle: ressource
default_langcode: site_default
language_alterable: false

View File

@@ -0,0 +1,11 @@
uuid: 262f5172-e9c1-4397-9181-20adc7c5d424
langcode: fr
status: true
dependencies:
config:
- taxonomy.vocabulary.type_de_ressource
id: taxonomy_term.type_de_ressource
target_entity_type_id: taxonomy_term
target_bundle: type_de_ressource
default_langcode: site_default
language_alterable: false

View File

@@ -0,0 +1,17 @@
uuid: 6e81bafe-2667-41ed-aa55-4125cbe6e4ff
langcode: fr
status: true
dependencies:
module:
- menu_ui
third_party_settings:
menu_ui:
available_menus: { }
parent: ''
name: Equipe
type: equipe
description: null
help: null
new_revision: true
preview_mode: 0
display_submitted: false

View File

@@ -0,0 +1,18 @@
uuid: d5f38b26-d2fa-476c-a7ef-b3e010ef54c8
langcode: fr
status: true
dependencies:
module:
- menu_ui
third_party_settings:
menu_ui:
available_menus:
- main
parent: 'main:'
name: Ressource
type: ressource
description: null
help: null
new_revision: true
preview_mode: 0
display_submitted: false

View File

@@ -0,0 +1,10 @@
uuid: 1de180fd-c057-4065-9006-597f51b0959c
langcode: fr
status: true
dependencies: { }
id: document
label: Document
icon_uuid: null
icon_default: null
description: ''
behavior_plugins: { }

View File

@@ -14,7 +14,7 @@ smtp_from: ''
smtp_fromname: ''
smtp_client_hostname: ''
smtp_client_helo: ''
smtp_allowhtml: ''
smtp_allowhtml: false
smtp_test_address: ''
smtp_reroute_address: ''
smtp_debugging: false

View File

@@ -4,7 +4,7 @@ favicon:
mimetype: image/vnd.microsoft.icon
path: ''
url: ''
use_default: true
use_default: false
features:
comment_user_picture: true
comment_user_verification: true

View File

@@ -0,0 +1,9 @@
uuid: 53ccb1e6-b330-4dac-8eb8-8ef6f79d2c7a
langcode: fr
status: true
dependencies: { }
name: 'Type de ressource'
vid: type_de_ressource
description: null
weight: 0
new_revision: false

View File

@@ -20,4 +20,5 @@ permissions:
- 'restful get rest_menu_item'
- 'view intro_gouvernance config page entity'
- 'view intro_partenaire config page entity'
- 'view intro_ressource config page entity'
- 'view media'

View File

@@ -17,7 +17,7 @@ dependencies:
_core:
default_config_hash: dJ0L2DNSj5q6XVZAGsuVDpJTh5UeYkIPwKrUOOpr8YI
id: authenticated
label: 'Utilisateur authentifié'
label: 'Authenticated user'
weight: 1
is_admin: false
permissions:
@@ -28,4 +28,5 @@ permissions:
- 'use text format simple'
- 'use text format wysiwyg'
- 'view intro_gouvernance config page entity'
- 'view intro_partenaires config page entity'
- 'view media'

View File

@@ -6,9 +6,11 @@ dependencies:
- filter.format.footnote
- filter.format.simple
- filter.format.wysiwyg
- node.type.equipe
- node.type.etape
- node.type.gallerie_photo
- node.type.partenaire
- node.type.ressource
- node.type.static
- taxonomy.vocabulary.saisons
- taxonomy.vocabulary.thematiques
@@ -33,39 +35,51 @@ permissions:
- 'administer nodes'
- 'break content lock'
- 'change own username'
- 'create equipe content'
- 'create etape content'
- 'create gallerie_photo content'
- 'create partenaire content'
- 'create ressource content'
- 'create terms in saisons'
- 'create terms in thematiques'
- 'delete equipe revisions'
- 'delete etape revisions'
- 'delete gallerie_photo revisions'
- 'delete partenaire revisions'
- 'delete ressource revisions'
- 'delete static revisions'
- 'delete terms in saisons'
- 'delete terms in thematiques'
- 'edit any equipe content'
- 'edit any etape content'
- 'edit any gallerie_photo content'
- 'edit any partenaire content'
- 'edit any ressource content'
- 'edit any static content'
- 'edit intro_gouvernance config page entity'
- 'edit intro_partenaire config page entity'
- 'edit intro_partenaires config page entity'
- 'edit own equipe content'
- 'edit own etape content'
- 'edit own gallerie_photo content'
- 'edit own partenaire content'
- 'edit own ressource content'
- 'edit own static content'
- 'edit terms in saisons'
- 'edit terms in thematiques'
- 'revert equipe revisions'
- 'revert etape revisions'
- 'revert gallerie_photo revisions'
- 'revert partenaire revisions'
- 'revert ressource revisions'
- 'revert static revisions'
- 'use text format footnote'
- 'use text format simple'
- 'use text format wysiwyg'
- 'view equipe revisions'
- 'view etape revisions'
- 'view gallerie_photo revisions'
- 'view partenaire revisions'
- 'view ressource revisions'
- 'view static revisions'
- 'view the administration theme'
- 'view unpublished paragraphs'

View File

@@ -284,7 +284,7 @@ display:
popupAnchor:
x: ''
'y': ''
html: "<div></div>\r\n<div></div>\r\n<div></div>\r\n<div class=\"url\">[node:url]</div>\r\n<div class=\"couleur\">[node:field_couleur]</div>"
html: "<div class=\"url\">[node:url]</div>\r\n<div class=\"couleur\">[node:field_couleur]</div>"
html_class: 'leaflet-map-divicon '
circle_marker_options: '{"radius":100,"color":"red","fillColor":"#f03","fillOpacity":0.5}'
leaflet_markercluster:
@@ -299,6 +299,7 @@ display:
geocoder:
control: false
settings:
popup: false
autocomplete:
placeholder: 'Search Address'
title: 'Search an Address on the Map'
@@ -311,7 +312,6 @@ display:
min_terms: 4
delay: 800
zoom: 16
popup: false
options: ''
map_lazy_load:
lazy_load: true
@@ -1195,7 +1195,18 @@ display:
defaults:
fields: false
display_description: ''
display_extenders: { }
display_extenders:
matomo:
enabled: false
keyword_gets: ''
keyword_behavior: first
keyword_concat_separator: ' '
category_behavior: none
category_gets: ''
category_concat_separator: ' '
category_fallback: ''
category_facets: { }
category_facets_concat_separator: ', '
cache_metadata:
max-age: -1
contexts:

View File

@@ -200,7 +200,7 @@ display:
type: normal
title: 'Les partenaires'
description: ''
weight: -48
weight: -47
expanded: false
menu_name: main
parent: ''

View File

@@ -12,7 +12,8 @@ import '../scss/main.scss'
(function ($, Drupal, drupalSettings) {
const CaravaneTheme = function () {
function init () {
function init () {
console.log('07/04 ci-cd fonctionne, import des configs ?')
// console.log('DrupalSettings', drupalSettings);
const baseUrl = window.location.protocol + "//" + window.location.host;
@@ -39,8 +40,9 @@ import '../scss/main.scss'
generalListLinks,
logoLink,
mapIcons,
mapContainer,
} = processClickableElements();
const clickableElements = [...etapeListLinks, ...generalListLinks, logoLink, ...mapIcons];
const clickableElements = [...etapeListLinks, ...generalListLinks, logoLink, ...mapIcons, mapContainer];
setupMapStore(mapStore, map, settings);

View File

@@ -3,335 +3,76 @@
import { defineStore } from 'pinia';
import REST from '../api/rest-axios';
import { useLayoutStore } from './layout';
import { findContentByPath } from '../utils/content/findContentByPath';
import { getCleanDate, fetchFromRelationships, getRelatedEtape, getRelatedRessources } from '../utils/content/contentFetchUtils';
import { getCarteSensible, getTitreTexte, getChiffresCles, getDiaporama, getEntretien, getVideos, getDocument, getGallerie } from '../utils/content/cleanParties';
import { getPartenaires, getGouvernance, getRessources } from '../utils/content/multiItemPages';
export const useContentStore = defineStore('content', {
state: () => ({
contentType: '',
pageTitle: '',
content: {
contentTitle: '',
coordinates: {},
adresse: {},
etape_number: '',
couleur: '',
dates: {},
previous : {},
next: {},
vignette: {},
parties: [],
liens: [],
pieces_jointes: [],
intro: '',
partenaires: [],
gouvernances: [],
},
content: {},
loading: false,
error: null,
}),
actions: {
async fetchContentData(path) {
console.log('start fetch content');
this.resetStore(false);
const contentTypes = [ 'etape', 'static', 'gouvernance', 'partenaire' ];
const contentTypes = ['etape', 'static', 'gouvernance', 'partenaire', 'ressource'];
try {
const findContentByPath = async (contentTypes, path) => {
for (let type of contentTypes) {
const response = await REST.get(`/jsonapi/node/${type}/`);
const content = response.data.data.find(content =>
content.attributes.metatag.some(tag =>
tag.tag === "link" && tag.attributes.href === path
)
);
if (content) {
console.log('content found');
return {
contentType: type,
rawContent: content,
};
}
// Handle special case for governance/partners (multiple items per page)
const pageRequested = window.location.href.split('/').pop().replace(/s?$/, '');
if (type === pageRequested
|| (type === 'gouvernance' && pageRequested === 'contact')
) {
return {
contentType: type,
rawContent: response.data.data,
};
}
}
return null;
};
const { contentType, rawContent } = await findContentByPath(contentTypes, path);
this.contentType = contentType;
// console.log(`current type: ${contentType}`);
if (
this.contentType === 'etape'
|| this.contentType === 'static'
|| this.contentType === 'ressourceItem'
) {
const vignettePromise = fetchFromRelationships('field_vignette', rawContent.relationships);
const partiesPromise = fetchFromRelationships(this.contentType === 'ressourceItem' ? 'field_parties_ressource' : 'field_parties', rawContent.relationships);
// TO DEBUG
const cleanContentMethod = 'original';
if (this.contentType !== 'gouvernance' && this.contentType !== 'partenaire'
&& cleanContentMethod === 'original'
) {
console.time('etape content processing');
// pageTitle
for (let tag of rawContent.attributes.metatag) {
if (tag.tag === "meta") {
this.pageTitle = tag.attributes.content;
break;
}
}
// contentTitle
this.content.contentTitle = rawContent.attributes.title;
let previousEtapePromise, nextEtapePromise;
// vignette
const vignetteFetch = await this.fetchFromRelationships('field_vignette', rawContent.relationships);
if (vignetteFetch) {
this.content.vignette = {
url: {
original: vignetteFetch.attributes.uri.url,
small: vignetteFetch.attributes.image_style_uri.content_small,
medium: vignetteFetch.attributes.image_style_uri.content_medium,
large: vignetteFetch.attributes.image_style_uri.content_large,
},
alt: rawContent.relationships.field_vignette.data.meta.alt
};
}
// liens
if (rawContent.attributes.field_liens.length) {
this.content.liens = [];
for (let lien of rawContent.attributes.field_liens) {
this.content.liens.push({
title: lien.title,
url: lien.uri,
});
}
}
// pièces jointes
if (rawContent.relationships.field_pieces_jointes.data.length) {
this.content.pieces_jointes = [];
for (let pieceJointe of rawContent.relationships.field_pieces_jointes.data) {
if (pieceJointe.meta.display) {
const uuid = pieceJointe.id;
const response = await REST.get(`/jsonapi/file/file/${uuid}`);
this.content.pieces_jointes.push({
title: pieceJointe.meta.description,
url: response.data.data.attributes.uri.url,
});
}
}
}
if (this.contentType === 'etape') {
previousEtapePromise = getRelatedEtape('previous', path);
nextEtapePromise = getRelatedEtape('next', path);
if (contentType === 'etape') {
// coordinates
this.content.coordinates = {
lat: rawContent.attributes.field_geofield.lat,
lon: rawContent.attributes.field_geofield.lon,
};
// adresse
this.content.adresse = rawContent.attributes.field_adresse;
// étape number
this.content.etape_number = rawContent.attributes.field_arret_numero;
// couleur
this.content.couleur = rawContent.attributes.field_couleur;
// dates
this.content.dates = {
start: this.getCleanDate(rawContent.attributes.field_dates.value),
end: this.getCleanDate(rawContent.attributes.field_dates.end_value),
start: getCleanDate(rawContent.attributes.field_dates.value),
end: getCleanDate(rawContent.attributes.field_dates.end_value),
}
// previous / next
await this.getRelatedEtape('previous', path);
await this.getRelatedEtape('next', path);
this.content.relatedRessources = await getRelatedRessources(rawContent.id);
}
// parties
const fieldParties = contentType === 'etape' ? 'field_parties' : 'field_parties_static';
const partiesFetch = await this.fetchFromRelationships(fieldParties, rawContent.relationships);
console.log(this.content);
console.timeEnd('etape content processing');
if (partiesFetch) {
this.content.parties = [];
for (let partie of partiesFetch) {
const partieType = partie.type.replace(/^paragraph--/, "");
let partieContent = {
type: partieType,
};
switch (partieType) {
case 'carte_sensible':
const carteSensibleFetch = await this.fetchFromRelationships('field_image_carte', partie.relationships);
if (carteSensibleFetch) {
partieContent.carteSensible = {
url: {
original: carteSensibleFetch.attributes.uri.url,
small: carteSensibleFetch.attributes.image_style_uri.content_small,
medium: carteSensibleFetch.attributes.image_style_uri.content_medium,
large: carteSensibleFetch.attributes.image_style_uri.content_large,
xlarge: carteSensibleFetch.attributes.image_style_uri.content_x_large,
},
alt: partie.relationships.field_image_carte.data.meta.alt,
};
}
break;
case 'titre_texte':
console.time('get images from text original')
partieContent.titre = partie.attributes.field_titre;
partieContent.texte = partie.attributes.field_texte.value;
// get the resized images from the text
const imgRegex = /<img[^>]+>/g;
const uuidRegex = /data-entity-uuid="([^"]+)"/;
const imgTags = partieContent.texte.match(imgRegex);
if (imgTags) {
for (const imgTag of imgTags) {
const uuidMatch = imgTag.match(uuidRegex);
if (uuidMatch && uuidMatch[1]) {
const uuid = uuidMatch[1];
const response = await REST.get(`/jsonapi/file/file/${uuid}`);
const imagesFetch = response.data.data;
const newImgTag = imgTag
.replace(/src="[^"]+"/,`src="${imagesFetch.attributes.image_style_uri.content_medium}"`)
.replace('>',' data-large-src="' + imagesFetch.attributes.image_style_uri.content_large + '">');
partieContent.texte = partieContent.texte.replace(imgTag, newImgTag);
}
}
}
console.timeEnd('get images from text original')
break;
case 'chiffres_cles':
const chiffresClesFetch = await this.fetchFromRelationships('field_chiffres_clefs', partie.relationships);
if (chiffresClesFetch) {
partieContent.chiffresCles = [];
for (let chiffre of chiffresClesFetch) {
partieContent.chiffresCles.push({
chiffre: chiffre.attributes.field_chiffre,
description: chiffre.attributes.field_description,
});
}
}
break;
case 'diaporama':
const diaporamaFetch = await this.fetchFromRelationships('field_diaporama', partie.relationships);
if (diaporamaFetch) {
partieContent.diaporama = [];
for (let [index, image] of diaporamaFetch.entries()) {
partieContent.diaporama.push({
url: {
original: image.attributes.uri.url,
small: image.attributes.image_style_uri.content_small,
medium: image.attributes.image_style_uri.content_medium,
large: image.attributes.image_style_uri.content_large,
},
alt: partie.relationships.field_diaporama.data[index].meta.alt,
});
}
}
break;
case 'entretien':
partieContent.entretien = {};
partieContent.entretien.titre = partie.attributes.field_titre;
const personnesFetch = await this.fetchFromRelationships('field_personne_s', partie.relationships);
const questionsReponsesFetch = await this.fetchFromRelationships('field_questions_reponses', partie.relationships);
if (personnesFetch && questionsReponsesFetch) {
partieContent.entretien.personnes = [];
for (let personne of personnesFetch) {
const portraitFetch = await this.fetchFromRelationships('field_portrait', personne.relationships);
if (portraitFetch) {
partieContent.entretien.personnes.push({
portrait: {
original: portraitFetch.attributes.uri.url,
small: portraitFetch.attributes.image_style_uri.content_small,
medium: portraitFetch.attributes.image_style_uri.content_medium,
large: portraitFetch.attributes.image_style_uri.content_large,
},
alt: personne.relationships.field_portrait.data.meta.alt,
description: personne.attributes.field_description,
});
}
}
partieContent.entretien.questionsReponses = [];
for (let qr of questionsReponsesFetch) {
partieContent.entretien.questionsReponses.push({
question: qr.attributes.field_question,
reponse: qr.attributes.field_reponse.value,
});
}
}
break;
case 'exergue':
partieContent.exergue = partie.attributes.field_texte_exergue.value;
break;
case 'video':
partieContent.videos = [];
for (let video of partie.attributes.field_videos) {
const videoId = video.split('?v=')[1];
const videoUrl = `https://www.youtube.com/embed/${videoId}`;
partieContent.videos.push(videoUrl);
}
break;
}
this.content.parties.push(partieContent);
if (this.contentType === 'ressourceItem') {
console.log(rawContent);
this.content.ressourceType = rawContent.attributes.field_type_de_ressource;
this.content.auteurice = rawContent.attributes.field_autheurice;
this.content.date = getCleanDate(rawContent.attributes.field_date_ressource);
this.content.introduction = rawContent.attributes.field_introduction?.processed;
if (rawContent.relationships.field_etape.data) {
const relatedEtapeFetch = fetchFromRelationships('field_etape', rawContent.relationships);
const relatedEtape = await Promise.resolve(relatedEtapeFetch);
const relatedEtapeUrl = relatedEtape.attributes.metatag.find(tag => tag.tag === "link")?.attributes.href;
this.content.relatedEtape = await getRelatedEtape('', relatedEtapeUrl);
}
}
console.log('content cleaned');
} else if (this.contentType !== 'gouvernance' && this.contentType !== 'partenaire'
&& cleanContentMethod === 'promise'
) {
console.time('etape content promise processing');
const vignettePromise = this.fetchFromRelationships('field_vignette', rawContent.relationships);
const partiesPromise = this.fetchFromRelationships('field_parties', rawContent.relationships);
const previousEtapePromise = contentType === 'etape'? this.getRelatedEtape('previous', path) : null;
const nextEtapePromise = contentType === 'etape' ? this.getRelatedEtape('next', path) : null;
if (contentType === 'etape') {
// coordinates
this.content.coordinates = {
lat: rawContent.attributes.field_geofield.lat,
lon: rawContent.attributes.field_geofield.lon,
};
// adresse
this.content.adresse = rawContent.attributes.field_adresse;
// étape number
this.content.etape_number = rawContent.attributes.field_arret_numero;
// couleur
this.content.couleur = rawContent.attributes.field_couleur;
// dates
this.content.dates = {
start: this.getCleanDate(rawContent.attributes.field_dates.value),
end: this.getCleanDate(rawContent.attributes.field_dates.end_value),
}
useLayoutStore().hideEtapeList(true);
}
// pageTitle
for (let tag of rawContent.attributes.metatag) {
if (tag.tag === "meta") {
this.pageTitle = tag.attributes.content;
break;
}
}
// contentTitle
this.pageTitle = rawContent.attributes.metatag.find(tag => tag.tag === "meta")?.attributes.content;
this.content.contentTitle = rawContent.attributes.title;
const [vignetteData, partiesData] = await Promise.all([vignettePromise, partiesPromise]);
@@ -351,151 +92,106 @@ export const useContentStore = defineStore('content', {
if (partiesData) {
const partiesPromises = partiesData.map(async (partie) => {
const partieType = partie.type.replace(/^paragraph--/, "");
let partieContent = { type: partieType };
let partieContent = { type: partieType };
switch(partieType) {
switch (partieType) {
case 'carte_sensible':
const carteSensiblePromise = this.fetchFromRelationships('field_image_carte', partie.relationships);
const carteSensibleData = await carteSensiblePromise;
if (carteSensibleData) {
partieContent.carteSensible = {
url: {
original: carteSensibleData.attributes.uri.url,
small: carteSensibleData.attributes.image_style_uri.content_small,
medium: carteSensibleData.attributes.image_style_uri.content_medium,
large: carteSensibleData.attributes.image_style_uri.content_large,
xlarge: carteSensibleData.attributes.image_style_uri.content_x_large,
},
alt: partie.relationships.field_image_carte.data.meta.alt,
};
}
partieContent.carteSensible = await getCarteSensible(partie);
break;
case 'titre_texte':
partieContent.titre = partie.attributes.field_titre;
partieContent.texte = partie.attributes.field_texte.value;
// get the resized images from the text
const imgRegex = /<img[^>]+>/g;
const uuidRegex = /data-entity-uuid="([^"]+)"/;
const imgTags = partieContent.texte.match(imgRegex);
if (imgTags) {
const imagePromises = imgTags.map(imgTag => {
const uuidMatch = imgTag.match(uuidRegex);
if (uuidMatch && uuidMatch[1]) {
return REST.get(`/jsonapi/file/file/${uuidMatch[1]}`)
.then(response => ({
originalTag: imgTag,
imageData: response.data.data
}));
}
});
const images = await Promise.all(imagePromises);
images.forEach(({originalTag, imageData}) => {
const newImgTag = originalTag
.replace(/src="[^"]+"/,`src="${imageData.attributes.image_style_uri.content_medium}"`)
.replace('>',' data-large-src="' + imageData.attributes.image_style_uri.content_large + '">');
partieContent.texte = partieContent.texte.replace(originalTag, newImgTag);
});
}
const { titre, texte } = await getTitreTexte(partie);
partieContent.titre = titre;
partieContent.texte = texte;
break;
case 'chiffres_cles':
const chiffresClesFetch = await this.fetchFromRelationships('field_chiffres_clefs', partie.relationships);
if (chiffresClesFetch) {
partieContent.chiffresCles = [];
for (let chiffre of chiffresClesFetch) {
partieContent.chiffresCles.push({
chiffre: chiffre.attributes.field_chiffre,
description: chiffre.attributes.field_description,
});
}
}
partieContent.chiffresCles = await getChiffresCles(partie);
break;
case 'diaporama':
partieContent.diaporama = await getDiaporama(partie);
break;
case 'entretien':
partieContent.entretien = await getEntretien(partie);
break;
case 'exergue':
partieContent.exergue = partie.attributes.field_texte_exergue.value;
break;
case 'video':
partieContent.videos = getVideos(partie);
break;
case 'document':
partieContent.document = await getDocument(partie);
break;
case 'galleries':
partieContent.gallerie = await getGallerie(partie);
break;
}
return partieContent;
});
// liens
if (rawContent.attributes.field_liens?.length) {
this.content.liens = [];
for (let lien of rawContent.attributes.field_liens) {
this.content.liens.push({
title: lien.title,
url: lien.uri,
});
}
}
// pièces jointes
if (rawContent.relationships.field_pieces_jointes?.data.length) {
this.content.pieces_jointes = [];
for (let pieceJointe of rawContent.relationships.field_pieces_jointes.data) {
if (pieceJointe.meta.display) {
const uuid = pieceJointe.id;
const response = await REST.get(`/jsonapi/file/file/${uuid}`);
this.content.pieces_jointes.push({
title: pieceJointe.meta.description,
url: response.data.data.attributes.uri.url,
});
}
}
}
this.content.parties = await Promise.all(partiesPromises);
}
// related étapes
if (contentType === 'etape') await Promise.all([previousEtapePromise, nextEtapePromise]);
console.log(this.content);
console.timeEnd('etape content promise processing');
if (contentType === 'etape') {
const [prevContent, nextContent] = await Promise.all([previousEtapePromise, nextEtapePromise]);
this.content.previous = prevContent;
this.content.next = nextContent;
}
} else {
// pages gouvernance (contact) et partenaire
// ont plusieurs items par pages
// pages gouvernance (contact), ressources et partenaire
// ont plusieurs items par pages
const intro = await REST.get(`/jsonapi/config_pages/intro_${this.contentType}/`);
const introContent = intro.data.data[0];
this.pageTitle =
`${introContent.attributes.field_titre} ${introContent.attributes.metatag.find(tag => tag.tag === "meta")?.attributes.content}`;
this.pageTitle =
`${introContent.attributes.field_titre} ${introContent.attributes.metatag.find(tag => tag.tag === "meta")?.attributes.content}`;
this.content.contentTitle = introContent.attributes.field_titre;
this.content.intro = introContent.attributes.field_intro?.value;
const multiItemPageArray = [];
let multiItemPageArray = [];
if (this.contentType === 'partenaire') {
for (let item of rawContent) {
const logoFetch = await REST.get(item.relationships.field_logo.links.related.href);
multiItemPageArray.push({
title: item.attributes.title,
description: item.attributes.body.value,
weight: item.attributes.field_poid,
link_url: item.attributes.field_lien.uri ,
logo_alt: item.relationships.field_logo.data.meta.alt,
logo_url: {
original: logoFetch.data.data.attributes.uri.url,
small: logoFetch.data.data.attributes.image_style_uri.content_small,
medium: logoFetch.data.data.attributes.image_style_uri.content_medium,
large: logoFetch.data.data.attributes.image_style_uri.content_large,
},
});
switch (this.contentType) {
case 'ressource':
multiItemPageArray = await getRessources(rawContent);
this.content.ressourceTypes = new Set(multiItemPageArray.map(item => item.ressourceType));
useLayoutStore().hideEtapeList(true);
break;
case 'partenaire':
multiItemPageArray = await getPartenaires(rawContent);
break;
case 'gouvernance':
multiItemPageArray = await getGouvernance(rawContent);
break;
}
} else if (this.contentType === 'gouvernance') {
for (let item of rawContent) {
const personnesFetch = await REST.get(item.relationships.field_personne_s.links.related.href);
let personnes = [];
for (let personne of personnesFetch.data.data) {
const portraitFetch = await REST.get(personne.relationships.field_portrait.links.related.href);
personnes.push({
nom: personne.attributes.field_nom,
prenom: personne.attributes.field_prenom,
description: personne.attributes.field_description,
photo_meta: personne.relationships.field_portrait.data?.meta.alt,
photo_url: portraitFetch.data.data ? {
original: portraitFetch.data.data.attributes.uri.url,
small: portraitFetch.data.data.attributes.image_style_uri.content_small,
medium: portraitFetch.data.data.attributes.image_style_uri.content_medium,
large: portraitFetch.data.data.attributes.image_style_uri.content_large,
} : null
});
}
multiItemPageArray.push({
title: item.attributes.title,
weight: item.attributes.field_poid,
personnes: personnes,
});
}
}
this.content[`${this.contentType}s`] = multiItemPageArray;
// console.log(this.content);
}
} catch (error) {
this.error = 'Failed to fetch data';
@@ -504,113 +200,13 @@ export const useContentStore = defineStore('content', {
this.loading = false;
}
},
getCleanDate(date) {
return {
d: date.split('-')[2],
m: new Intl.DateTimeFormat('fr-FR', { month: 'long' }).format(new Date(date)),
y: date.split('-')[0],
}
},
async getRelatedEtape(direction, path) {
const getRelatedEtapeContent = async (relatedEtapeData) => {
if (relatedEtapeData) {
const vignetteFetch = await REST.get(relatedEtapeData.relationships.field_vignette.links.related.href);
if (vignetteFetch.data.data) {
this.content[direction] = {
url: relatedEtapeData.attributes.metatag.find(tag => tag.tag === "link")?.attributes.href,
couleur: relatedEtapeData.attributes.field_couleur,
title: relatedEtapeData.attributes.title,
postalCode: relatedEtapeData.attributes.field_adresse.postal_code,
dates: {
start: this.getCleanDate(relatedEtapeData.attributes.field_dates.value),
end: this.getCleanDate(relatedEtapeData.attributes.field_dates.end_value),
},
vignette: {
url: {
original: vignetteFetch.data.data.attributes.uri.url,
small: vignetteFetch.data.data.attributes.image_style_uri.content_small,
medium: vignetteFetch.data.data.attributes.image_style_uri.content_medium,
large: vignetteFetch.data.data.attributes.image_style_uri.content_large,
},
alt: relatedEtapeData.relationships.field_vignette.data.meta.alt,
},
}
}
}
}
const allEtapesData = await REST.get('/jsonapi/views/etapes/block_1/');
for (let [index, etape] of allEtapesData.data.data.entries()) {
if (etape.attributes.metatag.some(tag =>
tag.tag === "link" && tag.attributes.href === path
)) {
const relatedEtapeIndex = direction === 'next' ? index + 1 : index - 1;
await getRelatedEtapeContent(allEtapesData.data.data[relatedEtapeIndex]);
}
}
},
async getRelatedEtape(direction, path) {
const getRelatedEtapeContent = (relatedEtapeData) => {
if (relatedEtapeData) {
return this.fetchFromRelationships('field_vignette', relatedEtapeData.relationships)
.then(vignetteFetch => {
if (vignetteFetch) {
this.content[direction] = {
url: relatedEtapeData.attributes.metatag.find(tag => tag.tag === "link")?.attributes.href,
couleur: relatedEtapeData.attributes.field_couleur,
title: relatedEtapeData.attributes.title,
postalCode: relatedEtapeData.attributes.field_adresse.postal_code,
dates: {
start: this.getCleanDate(relatedEtapeData.attributes.field_dates.value),
end: this.getCleanDate(relatedEtapeData.attributes.field_dates.end_value),
},
vignette: {
url: {
original: vignetteFetch.attributes.uri.url,
small: vignetteFetch.attributes.image_style_uri.content_small,
medium: vignetteFetch.attributes.image_style_uri.content_medium,
large: vignetteFetch.attributes.image_style_uri.content_large,
},
alt: relatedEtapeData.relationships.field_vignette.data.meta.alt,
},
}
}
});
}
}
const allEtapesPromise = REST.get('/jsonapi/views/etapes/block_1/');
return allEtapesPromise.then(allEtapesData => {
for (let [index, etape] of allEtapesData.data.data.entries()) {
if (etape.attributes.metatag.some(tag =>
tag.tag === "link" && tag.attributes.href === path
)) {
const relatedEtapeIndex = direction === 'next' ? index + 1 : index - 1;
return getRelatedEtapeContent(allEtapesData.data.data[relatedEtapeIndex]);
}
}
});
},
async fetchFromRelationships(field, relationships) {
if (relationships[field].links) {
const contentLink = relationships[field].links.related.href;
return REST.get(contentLink)
.then(contentFetch => contentFetch.data.data)
.catch(error => {
this.error = 'Failed to fetch data';
console.error('Issue with getNodeData', error);
});
}
return null;
},
resetStore(forFrontDisplay) {
this.contentType = '';
this.pageTitle = '';
this.content = {};
this.loading = !forFrontDisplay;
this.error = null;
useLayoutStore().hideEtapeList(false);
}
},
});

View File

@@ -46,6 +46,30 @@ export const useLayoutStore = defineStore('layout', {
this.toggleEtapeListScroll(isIntersecting, listeEtape, column, headerRect.height, animationToggleRect.top);
},
hideEtapeList(souldListHide) {
const etapeList = document.querySelector(window.innerWidth >= this.minDesktopWidth ? '#etapes-liste' : '.layout__region--third');
const animationButton = document.querySelector('#animation-toggle');
const listContainer = etapeList.parentNode;
if (souldListHide) {
listContainer.style.minWidth = '30vw';
etapeList.style.opacity = '0';
setTimeout(() => {
etapeList.style.display = 'none';
}, 300);
if (window.innerWidth >= this.minDesktopWidth) {
animationButton.style.display = 'none';
}
} else {
listContainer.style.minWidth = 'unset';
etapeList.style.display = 'block';
setTimeout(() => {
etapeList.style.opacity = '1';
}, 10);
if (window.innerWidth >= this.minDesktopWidth) {
animationButton.style.display = 'block';
}
}
},
toggleEtapeListScroll(isIntersecting, listeEtape, column, headerHeight, animationToggleTop) {
if (isIntersecting && !this.isEtapeListeScrollable
|| !isIntersecting && this.isEtapeListeScrollable) {

View File

@@ -16,7 +16,7 @@ export const useMapStore = defineStore('mapState', {
animationDuration: 3,
}),
actions: {
zoomToPlace(lat, long) {
zoomToPlace(lat, long) {
if (useLayoutStore().isDesktop) long = long - 0.03;
this.map.flyTo(
[lat, long],
@@ -24,25 +24,21 @@ export const useMapStore = defineStore('mapState', {
{ animate: this.animationsAreEnabled, duration: this.animationDuration });
this.currentZoom = this.maxZoom;
},
resetMap(animate = this.animationsAreEnabled, duration = this.animationDuration) {
resetMap(animate = this.animationsAreEnabled, duration = this.animationDuration) {
this.map.flyTo(
this.defaultMapCenter,
useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile,
{ animate, duration });
this.currentZoom = useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile;
},
lockMap() {
setTimeout(() => {
this.map.options.minZoom = this.currentZoom;
this.map.options.maxZoom = this.currentZoom;
}, this.animationDuration * 1000 + 100);
lockMap() {
this.map.dragging.disable();
this.map.touchZoom.disable();
this.map.doubleClickZoom.disable();
this.map.scrollWheelZoom.disable();
this.map.boxZoom.disable();
this.map.keyboard.disable();
// map.tap.disable();
this.map._controlContainer.style.display = 'none';
},
unlockMap() {
this.map.options.minZoom = useLayoutStore().isDesktop ? this.defaultZoomDesktop : this.defaultZoomMobile;
@@ -53,7 +49,7 @@ export const useMapStore = defineStore('mapState', {
this.map.scrollWheelZoom.enable();
this.map.boxZoom.enable();
this.map.keyboard.enable();
// map.tap.enable();
this.map._controlContainer.style.display = 'block';
},
toggleAnimation() {
this.animationsAreEnabled = !this.animationsAreEnabled;

View File

@@ -0,0 +1,176 @@
import REST from '../../api/rest-axios';
import { fetchFromRelationships, getCleanDate } from './contentFetchUtils';
export async function getCarteSensible(partie) {
const carteSensiblePromise = fetchFromRelationships('field_image_carte', partie.relationships);
const carteSensibleData = await carteSensiblePromise;
if (carteSensibleData) {
return {
url: {
original: carteSensibleData.attributes.uri.url,
small: carteSensibleData.attributes.image_style_uri.content_small,
medium: carteSensibleData.attributes.image_style_uri.content_medium,
large: carteSensibleData.attributes.image_style_uri.content_large,
xlarge: carteSensibleData.attributes.image_style_uri.content_x_large,
},
alt: partie.relationships.field_image_carte.data.meta.alt,
};
}
}
export async function getTitreTexte(partie) {
let titre = partie.attributes.field_titre;
let texte = partie.attributes.field_texte.value;
// get the resized images from the text
const imgRegex = /<img[^>]+>/g;
const uuidRegex = /data-entity-uuid="([^"]+)"/;
const imgTags = texte.match(imgRegex);
if (imgTags) {
const imagePromises = imgTags.map(imgTag => {
const uuidMatch = imgTag.match(uuidRegex);
if (uuidMatch && uuidMatch[1]) {
return REST.get(`/jsonapi/file/file/${uuidMatch[1]}`)
.then(response => ({
originalTag: imgTag,
imageData: response.data.data
}));
}
});
const images = await Promise.all(imagePromises);
images.forEach(({originalTag, imageData}) => {
const newImgTag = originalTag
.replace(/src="[^"]+"/,`src="${imageData.attributes.image_style_uri.content_medium}"`)
.replace('>',' data-large-src="' + imageData.attributes.image_style_uri.content_large + '">');
texte = texte.replace(originalTag, newImgTag);
});
}
return { titre, texte };
}
export async function getChiffresCles(partie) {
const chiffresClesFetch = await fetchFromRelationships('field_chiffres_clefs', partie.relationships);
if (chiffresClesFetch) {
let chiffresCles = [];
for (let chiffre of chiffresClesFetch) {
chiffresCles.push({
chiffre: chiffre.attributes.field_chiffre,
description: chiffre.attributes.field_description,
});
}
return chiffresCles;
}
}
export async function getDiaporama(partie) {
const diaporamaFetch = await fetchFromRelationships('field_diaporama', partie.relationships);
if (diaporamaFetch) {
const diaporamaPromises = diaporamaFetch.map((image, index) => {
return {
url: {
original: image.attributes.uri.url,
small: image.attributes.image_style_uri.content_small,
medium: image.attributes.image_style_uri.content_medium,
large: image.attributes.image_style_uri.content_large,
},
alt: partie.relationships.field_diaporama.data[index].meta.alt,
};
});
return await Promise.all(diaporamaPromises);
}
}
export async function getEntretien(partie) {
const [personnesFetch, questionsReponsesFetch] = await Promise.all([
fetchFromRelationships('field_personne_s', partie.relationships),
fetchFromRelationships('field_questions_reponses', partie.relationships)
]);
if (personnesFetch && questionsReponsesFetch) {
const personnesPromises = personnesFetch.map(async (personne) => {
const portraitFetch = await fetchFromRelationships('field_portrait', personne.relationships);
if (portraitFetch) {
return {
portrait: {
original: portraitFetch.attributes.uri.url,
small: portraitFetch.attributes.image_style_uri.content_small,
medium: portraitFetch.attributes.image_style_uri.content_medium,
large: portraitFetch.attributes.image_style_uri.content_large,
},
alt: personne.relationships.field_portrait.data.meta.alt,
description: personne.attributes.field_description,
};
}
});
const questionsReponses = questionsReponsesFetch.map(qr => ({
question: qr.attributes.field_question,
reponse: qr.attributes.field_reponse.value,
}));
return {
titre: partie.attributes.field_titre,
personnes: await Promise.all(personnesPromises),
questionsReponses: questionsReponses
}
}
}
export function getVideos(partie) {
let videos = [];
for (let video of partie.attributes.field_videos) {
const videoId = video.split('?v=')[1];
const videoUrl = `https://www.youtube.com/embed/${videoId}`;
videos.push(videoUrl);
}
return videos;
}
export async function getDocument(partie) {
// const documentFetch = await fetchFromRelationships('field_document', partie.relationships);
const uuid = partie.relationships.field_document.data.id;
const documentFetch = await REST.get(`/jsonapi/file/file/${uuid}`);
const url = documentFetch.data.data.attributes.uri.url;
const titre = partie.attributes.field_titre;
const sousTitre = partie.attributes.field_sous_titre;
const date = partie.attributes.field_date ? getCleanDate(partie.attributes.field_date) : null;
const auteurice = partie.relationships.field_autheurice_s;
const description = partie.relationships.field_document.data.meta.description;
const vignetteFetch = await REST.get(`/jsonapi/file/file/${partie.relationships.field_vignette.data.id}`);
const vignette = { url: vignetteFetch.data.data.attributes.image_style_uri.content_small, alt: partie.relationships.field_vignette.data.meta.alt };
return { url, titre, sousTitre, date, auteurice, description, vignette };
}
export async function getGallerie(partie) {
const gallerieFetch = await fetchFromRelationships('field_gallerie', partie.relationships);
if (gallerieFetch) {
const titre = gallerieFetch.attributes.title;
const introduction = gallerieFetch.attributes.body?.processed;
const imagesFetch = await fetchFromRelationships('field_images', gallerieFetch.relationships);
let images = [];
imagesFetch.forEach((image, index) => {
images.push({
url: {
original: image.attributes.uri.url,
small: image.attributes.image_style_uri.content_small,
medium: image.attributes.image_style_uri.content_medium,
large: image.attributes.image_style_uri.content_large,
},
alt: gallerieFetch.relationships.field_images.data[index].meta.alt,
});
});
return { titre, introduction, images };
}
}

View File

@@ -0,0 +1,150 @@
import REST from '../../api/rest-axios';
export async function fetchFromRelationships(field, relationships) {
field = relationships[field] ? field : `${field}_static`;
if (relationships[field]?.links) {
const contentLink = relationships[field].links.related.href;
return REST.get(contentLink)
.then(contentFetch => contentFetch.data.data)
.catch(error => {
this.error = 'Failed to fetch data';
console.error('Issue with getNodeData', error);
});
}
return null;
}
export function getCleanDate(date) {
return {
d: date.split('-')[2],
m: new Intl.DateTimeFormat('fr-FR', { month: 'long' }).format(new Date(date)),
y: date.split('-')[0],
}
}
export async function getRelatedEtape(direction, path) {
const getRelatedEtapeContent = (relatedEtapeData) => {
if (relatedEtapeData) {
return fetchFromRelationships('field_vignette', relatedEtapeData.relationships)
.then(vignetteFetch => {
if (vignetteFetch) {
return {
url: relatedEtapeData.attributes.metatag.find(tag => tag.tag === "link")?.attributes.href,
couleur: relatedEtapeData.attributes.field_couleur,
title: relatedEtapeData.attributes.title,
postalCode: relatedEtapeData.attributes.field_adresse.postal_code,
dates: {
start: getCleanDate(relatedEtapeData.attributes.field_dates.value),
end: getCleanDate(relatedEtapeData.attributes.field_dates.end_value),
},
vignette: {
url: {
original: vignetteFetch.attributes.uri.url,
small: vignetteFetch.attributes.image_style_uri.content_small,
medium: vignetteFetch.attributes.image_style_uri.content_medium,
large: vignetteFetch.attributes.image_style_uri.content_large,
},
alt: relatedEtapeData.relationships.field_vignette.data.meta.alt,
},
}
}
});
}
}
const allEtapesPromise = REST.get('/jsonapi/views/etapes/block_1/');
return allEtapesPromise.then(allEtapesData => {
for (let [index, etape] of allEtapesData.data.data.entries()) {
if (etape.attributes.metatag.some(tag =>
tag.tag === "link" && tag.attributes.href === path
)) {
const relatedEtapeIndex = direction ? (direction === 'next' ? index + 1 : index - 1) : index;
return getRelatedEtapeContent(allEtapesData.data.data[relatedEtapeIndex]);
}
}
});
}
export async function getRessourceItemCard(item) {
try {
const ressourceFetch = await REST.get(item.links.self.href);
const partiesFetch = await REST.get(item.relationships.field_parties_ressource.links.related.href);
const parties = partiesFetch.data.data;
const vignettePartie = parties.find(partie => partie.type !== "paragraph--titre_texte");
let vignette = null;
if (vignettePartie) {
let alt;
switch (vignettePartie.type) {
case 'paragraph--diaporama':
alt = vignettePartie.relationships.field_diaporama.data[0].meta.alt;
const diaporamaFetch = await REST.get(vignettePartie.relationships.field_diaporama.links.related.href);
vignette = {
url: diaporamaFetch.data.data[0].attributes.image_style_uri.content_small,
alt
};
break;
case 'paragraph--video':
const videoId = vignettePartie.attributes.field_videos[0].split('?v=')[1];
vignette = {
url: `https://img.youtube.com/vi/${videoId}/0.jpg`,
alt: item.attributes.title
};
break;
case 'paragraph--galleries':
const gallerieFetch = await REST.get(vignettePartie.relationships.field_gallerie.links.related.href);
const galleryAlt = gallerieFetch.data.data.relationships.field_images.data[0].meta.alt;
const gallerieImageFetch = await REST.get(gallerieFetch.data.data.relationships.field_images.links.related.href);
vignette = {
url: gallerieImageFetch.data.data[0].attributes.image_style_uri.content_small,
alt: galleryAlt
};
break;
case 'paragraph--document':
alt = vignettePartie.relationships.field_vignette.data.meta.alt;
const documentFetch = await REST.get(vignettePartie.relationships.field_vignette.links.related.href);
vignette = {
url: documentFetch.data.data.attributes.image_style_uri.content_small,
alt
};
break;
default:
vignette = null;
}
}
const relatedEtape = await REST.get(item.relationships.field_etape.links.related.href);
console.log(item);
return {
ressourceType: item.attributes.field_type_de_ressource,
title: item.attributes.title,
auteurice: item.attributes.field_autheurice,
promoted: item.attributes.field_mis_en_avant,
date: getCleanDate(item.attributes.field_date_ressource),
url: ressourceFetch.data.data.attributes.metatag.find(tag => tag.tag === "link")?.attributes.href,
relatedEtape: relatedEtape.data.data.attributes.title,
vignette
};
} catch (error) {
console.error('Error fetching resource:', error);
return null;
}
}
export async function getRelatedRessources(etapeId) {
const ressources = await REST.get(`/jsonapi/node/ressource/`);
const ressourcesRelatedToEtape = ressources.data.data.filter(ressource => ressource.relationships.field_etape.data?.id === etapeId);
const ressourcesRelatedPromises = ressourcesRelatedToEtape.map(ressource => getRessourceItemCard(ressource));
return await Promise.all(ressourcesRelatedPromises);
}

View File

@@ -0,0 +1,32 @@
import REST from '../../api/rest-axios';
export async function findContentByPath(contentTypes, path) {
for (let type of contentTypes) {
const response = await REST.get(`/jsonapi/node/${type}/`);
const content = response.data.data.find(content =>
content.attributes.metatag.some(tag =>
tag.tag === "link" && tag.attributes.href === path
)
);
if (content) {
return {
contentType: content.type === 'node--ressource' ? 'ressourceItem' : type,
rawContent: content,
};
}
// Handle special case for gouvernance, ressources, partenaires (multiple items per page)
let pageRequested = window.location.href.split('/').pop().replace(/s?$/, '');
if (type === pageRequested
|| (type === 'gouvernance' && pageRequested === 'contact')
) {
return {
contentType: type,
rawContent: response.data.data,
};
}
}
return null;
}

View File

@@ -0,0 +1,63 @@
import REST from '../../api/rest-axios';
import { getCleanDate, getRessourceItemCard } from './contentFetchUtils';
export async function getPartenaires(rawContent) {
const logoPromises = rawContent.map(item =>
REST.get(item.relationships.field_logo.links.related.href)
.then(logoFetch => ({
title: item.attributes.title,
description: item.attributes.body.value,
weight: item.attributes.field_poid,
link_url: item.attributes.field_lien.uri,
logo_alt: item.relationships.field_logo.data.meta.alt,
logo_url: {
original: logoFetch.data.data.attributes.uri.url,
small: logoFetch.data.data.attributes.image_style_uri.content_small,
medium: logoFetch.data.data.attributes.image_style_uri.content_medium,
large: logoFetch.data.data.attributes.image_style_uri.content_large,
}
}))
);
return await Promise.all(logoPromises);
}
export async function getGouvernance(rawContent) {
const itemPromises = rawContent.map(item =>
REST.get(item.relationships.field_personne_s.links.related.href)
.then(async personnesFetch => {
const portraitPromises = personnesFetch.data.data.map(personne =>
REST.get(personne.relationships.field_portrait.links.related.href)
.then(portraitFetch => ({
nom: personne.attributes.field_nom,
prenom: personne.attributes.field_prenom,
description: personne.attributes.field_description,
photo_meta: personne.relationships.field_portrait.data?.meta.alt,
photo_url: portraitFetch.data.data ? {
original: portraitFetch.data.data.attributes.uri.url,
small: portraitFetch.data.data.attributes.image_style_uri.content_small,
medium: portraitFetch.data.data.attributes.image_style_uri.content_medium,
large: portraitFetch.data.data.attributes.image_style_uri.content_large,
} : null
}))
);
return Promise.all(portraitPromises)
.then(personnes => ({
title: item.attributes.title,
weight: item.attributes.field_poid,
personnes
}));
})
);
return await Promise.all(itemPromises);
}
export async function getRessources(rawContent) {
console.log(rawContent);
const ressourcesPromises = rawContent.map(item => getRessourceItemCard(item));
return await Promise.all(ressourcesPromises);
}

View File

@@ -22,12 +22,10 @@ export function handleClickableElements(clickableElements, store, router, baseUr
let href = link.href || link.dataset.href;
if (href.startsWith(baseUrl)) href = href.replace(baseUrl, '');
link.onclick = async function (e) {
console.log('click on link, route push');
router.push(href);
link.onclick = async function (e) {
if (href !== window.location.pathname) {
pageChange(href, store, siteName, mapStore, baseUrl);
router.push(href);
pageChange(href, store, siteName, mapStore, baseUrl);
}
}
}
@@ -40,7 +38,6 @@ export async function handleBrowserNavigation(store, baseUrl, siteName, mapStore
}
export async function pageChange(href, store, siteName, mapStore, baseUrl) {
console.log('trigger page change');
if (href === '/') {
store.resetStore(true);
document.title = siteName;

View File

@@ -4,6 +4,7 @@ export function processClickableElements() {
generalListLinks: processStaticLinks(),
logoLink: processLogoLink(),
mapIcons: processMapIcons(),
mapContainer: processMapContainer(),
};
}
@@ -14,9 +15,9 @@ function processEtapeLinks() {
etape_link.addEventListener('click', (e) => e.preventDefault());
const couleur = etape_link.dataset.couleur;
li.dataset.href = etape_link.attributes.href.value;
const iconElements = li.querySelectorAll('.icone-arret > div');
const iconElements = li.querySelectorAll('.icone-arret');
for (let element of iconElements) {
element.style.backgroundColor = couleur;
element.style.backgroundColor = couleur;
}
});
@@ -46,16 +47,10 @@ function processMapIcons() {
const hrefContainer = icon.querySelector('.url');
icon.dataset.href = hrefContainer.innerText;
hrefContainer.style.display = "none";
const colorContainer = icon.querySelector('.couleur');
let color = colorContainer.innerText;
colorContainer.style.display = "none";
const iconElements = icon.querySelectorAll('div');
for (let iconElement of iconElements) {
iconElement.style.backgroundColor = color;
}
icon.style.backgroundColor = color;
icon.addEventListener('mouseenter', () => {
icon.style.transform = `${icon.style.transform} scale(1.1)`;
@@ -70,3 +65,11 @@ function processMapIcons() {
return icons;
}
function processMapContainer() {
let mapContainer = document.querySelector('.leaflet-layer');
mapContainer.style.height = "100vh";
mapContainer.style.width = "100vw";
mapContainer.dataset.href = "/";
return mapContainer;
}

View File

@@ -3,18 +3,17 @@
:enter-active-class="animationsAreEnabled ? 'v-enter-active' : 'no-transition'"
:leave-active-class="animationsAreEnabled ? 'v-leave-active' : 'no-transition'"
>
<div v-if="!loading && (
contentType === 'etape'
|| contentType === 'static'
|| contentType === 'gouvernance'
|| contentType === 'partenaire'
)">
<div v-if="!loading && contentType != ''">
<div class="content-wrapper">
<ModaleHeader
:contentType="contentType"
:content="content"
:couleur="content.couleur || brandColor" />
<main>
<RessourceItemHeader
v-if="contentType === 'ressourceItem'"
:content="content"
:couleur="brandColor" />
<div v-for="partie in content.parties" class="partie">
<ModaleCarteSensible
v-if="partie.type === 'carte_sensible'"
@@ -42,31 +41,46 @@
<ModaleVideos
v-if="partie.type === 'video'"
:partie="partie" />
<ModaleGallerie
v-if="partie.type === 'galleries'"
:partie="partie"
:couleur="content.couleur || brandColor" />
<ModaleDocument
v-if="partie.type === 'document'"
:partie="partie"
:couleur="content.couleur || brandColor" />
</div>
<EquipeContent
v-if="contentType === 'gouvernance'"
:content="content"
:couleur="content.couleur || brandColor" />
v-if="contentType === 'gouvernance'"
:content="content"
:couleur="brandColor" />
<PartenairesContent
v-if="contentType === 'partenaire'"
:content="content" />
v-if="contentType === 'partenaire'"
:content="content" />
<CentreDeRessource
v-if="contentType === 'ressource'"
:content="content"
:couleur="brandColor" />
<RelatedRessources
v-if="contentType === 'etape' && content.relatedRessources.length"
:relatedRessources="content.relatedRessources"
:couleur="content.couleur || brandColor" />
</main>
<PiecesJointes
v-if="content.pieces_jointes || content.liens"
:content="content"
:couleur="content.couleur || brandColor"
/>
:couleur="content.couleur || brandColor" />
<ModaleFooter
:contentType="contentType"
:content="content"
:couleur="content.couleur || brandColor"
/>
:contentType="contentType"
:content="content"
:couleur="content.couleur || brandColor" />
</div>
</div>
</Transition>
</template>
<script setup>
import { watch, onMounted } from 'vue';
import { watch, onMounted, nextTick } from 'vue';
import { storeToRefs } from 'pinia';
import { useContentStore } from '../stores/content';
@@ -76,7 +90,10 @@ import ModaleHeader from './components/ModaleHeader.vue';
import ModaleFooter from './components/ModaleFooter.vue';
import EquipeContent from './components/EquipeContent.vue';
import PartenairesContent from './components/PartenairesContent.vue';
import CentreDeRessource from './components/CentreDeRessource.vue';
import RessourceItemHeader from './components/RessourceItemHeader.vue';
import PiecesJointes from './components/PiecesJointes.vue';
import RelatedRessources from './components/RelatedRessources.vue';
import ModaleCarteSensible from './components/parties/ModaleCarteSensible.vue';
import ModaleTitreTexte from './components/parties/ModaleTitreTexte.vue';
@@ -85,6 +102,8 @@ import ModaleDiaporama from './components/parties/ModaleDiaporama.vue';
import ModaleEntretien from './components/parties/ModaleEntretien.vue';
import ModaleExergue from './components/parties/ModaleExergue.vue';
import ModaleVideos from './components/parties/ModaleVideos.vue';
import ModaleGallerie from './components/parties/ModaleGallerie.vue';
import ModaleDocument from './components/parties/ModaleDocument.vue';
const store = useContentStore();
const mapState = useMapStore();
@@ -118,8 +137,9 @@ const handleMapMovement = () => {
() => loading.value,
() => {
if (!loading.value) {
console.log('loading done');
isModaleEtape = contentType.value === 'etape';
console.log(contentType.value);
// Define helper functions in variables
const disableModaleTransition = () => {
@@ -138,7 +158,6 @@ const handleMapMovement = () => {
};
if (animationsAreEnabled.value) {
if (isModaleEtape) {
if (!wasModaleEtape) {
// national -> détail
@@ -161,8 +180,10 @@ const handleMapMovement = () => {
}
} else {
if (isModaleEtape) {
// ? -> détail
zoomToContentPlace();
} else {
// ? -> national
mapState.resetMap();
}
disableModaleTransition();
@@ -176,12 +197,38 @@ const handleMapMovement = () => {
);
};
watch(() => contentType.value, () => {
if (contentType.value === '') {
handleMapLock(false);
} else {
handleMapLock(true);
}
});
const handleMapLock = (shoudLock) => {
const checkAndExecute = () => {
const leafletLayer = document.querySelector('.leaflet-layer');
if (leafletLayer) {
if (shoudLock) {
mapState.lockMap();
} else {
mapState.unlockMap();
}
} else {
setTimeout(checkAndExecute, 100);
}
}
checkAndExecute();
}
onMounted(() => {
console.log('modale mounted');
isModaleEtape = contentType.value === 'etape';
wasModaleEtape = isModaleEtape;
handleColorChange();
handleMapMovement();
nextTick(() => {
isModaleEtape = contentType.value === 'etape';
wasModaleEtape = isModaleEtape;
handleColorChange();
handleMapMovement();
});
});
</script>

View File

@@ -0,0 +1,162 @@
<template>
<div id="centre-de-ressource" :style="{ '--couleur': couleur }">
<div class="filters">
<input type="text" v-model="searchQuery" placeholder="Rechercher..." class="search-bar">
<select v-model="selectedType">
<option value="">Tous les types</option>
<option v-for="type in content.ressourceTypes" :key="type" :value="type">
{{ type.replace(/_/g, ' ').replace(/^\w/, char => char.toUpperCase()) }}
</option>
</select>
<select v-model="selectedEtape">
<option value="">Toutes les étapes</option>
<option v-for="etape in allRelatedEtapes" :key="etape" :value="etape">
{{ etape }}
</option>
</select>
</div>
<div v-if="content.intro" v-html="content.intro" class="intro"></div>
<template v-for="(type, typeIndex) in filteredTypes" :key="type">
<div class="type-section" v-if="ressourcesToDisplay[type] && ressourcesToDisplay[type].length > 0">
<h3>{{ type.replace(/_/g, ' ').replace(/^\w/, char => char.toUpperCase()) }}</h3>
<div class="ressource-list">
<TransitionGroup name="itemFade" tag="div" appear>
<div class="ressource-item"
v-for="(ressource, ressourceIndex) in ressourcesToDisplay[type]"
:key="`${type}-${ressourceIndex}`"
:style="{ '--index': ressourceIndex - visibleItemsPerSection }">
<RessourceCard :ressource="ressource" :index="`${typeIndex}-${ressourceIndex}`" />
</div>
</TransitionGroup>
</div>
<div class="button-container">
<div v-if="ressourcesByType(type).length > visibleItemsPerSection
&& ressourcesToDisplay[type].length === visibleItemsPerSection"
class="ressource-button"
@click="loadMore(type)">
Voir plus ↓
</div>
<div v-if="ressourcesToDisplay[type].length > visibleItemsPerSection"
class="ressource-button"
@click="showLess(type)">
Voir moins ↑
</div>
</div>
</div>
</template>
</div>
</template>
<script setup>
import RessourceCard from './RessourceCard.vue';
import useParseDate from '../composables/useParseDates';
import { ref, computed, watch, nextTick } from 'vue';
const props = defineProps({
content: Object,
couleur: String,
});
const searchQuery = ref('');
const selectedType = ref('');
const ressourcesToDisplay = ref({});
const visibleItemsPerSection = 4;
const selectedEtape = ref('');
const allRelatedEtapes = new Set();
props.content.ressources.forEach(ressource => {
if (ressource.relatedEtape) {
allRelatedEtapes.add(ressource.relatedEtape);
}
})
const filteredTypes = computed(() => {
return selectedType.value ? [selectedType.value] : props.content.ressourceTypes;
});
const ressourcesByType = (type) => {
return props.content.ressources
.filter(ressource => !selectedEtape.value || ressource.relatedEtape === selectedEtape.value)
.filter(ressource => ressource.ressourceType === type)
.filter(ressource =>
searchQuery.value === '' ||
ressource.title.toLowerCase().includes(searchQuery.value.toLowerCase())
).sort((a, b) => {
if (a.promoted && !b.promoted) return -1;
if (!a.promoted && b.promoted) return 1;
const dateA = useParseDate(a.date);
const dateB = useParseDate(b.date);
return dateB - dateA; // descending order (newest first)
});
};
const initializeRessources = (type) => {
ressourcesToDisplay.value[type] = ressourcesByType(type).slice(0, visibleItemsPerSection);
};
props.content.ressourceTypes.forEach(type => initializeRessources(type));
const loadMore = (type) => {
const currentLength = ressourcesToDisplay.value[type].length;
if (currentLength < ressourcesByType(type).length) {
ressourcesToDisplay.value[type] = ressourcesByType(type).slice(0, currentLength + visibleItemsPerSection);
}
};
const showLess = (type) => {
ressourcesToDisplay.value[type] = ressourcesByType(type).slice(0, visibleItemsPerSection);
};
watch(searchQuery, () => {
props.content.ressourceTypes.forEach(type => {
initializeRessources(type);
});
});
watch(ressourcesToDisplay.value, async () => {
await nextTick();
document.querySelectorAll('.ressource-item > div').forEach(el => {
const card = el.__vueParentComponent.exposed;
if (card && card.setClickableElements) {
card.setClickableElements();
}
});
}, { deep: true });
watch(selectedType, async () => {
await nextTick();
document.querySelectorAll('.ressource-item > div').forEach(el => {
const card = el.__vueParentComponent.exposed;
if (card && card.setClickableElements) {
card.setClickableElements();
}
});
});
watch(selectedEtape, () => {
props.content.ressourceTypes.forEach(type => {
initializeRessources(type);
});
});
</script>
<style lang="scss" scoped>
.itemFade-enter-active, .itemFade-leave-active {
transition: all 0.3s ease !important;
transition-delay: calc(0.1s * var(--index)) !important;
}
.itemFade-enter-from, .itemFade-leave-to {
opacity: 0;
transform: translateY(-20px) !important;
}
.itemFade-enter-to, .itemFade-leave-from {
opacity: 1;
transform: translateY(0px);
}
</style>

View File

@@ -0,0 +1,39 @@
<template>
<div class="card" :class="direction ? (direction === 'previous' ? 'previous' : 'next') : 'solo'" :data-href="relatedContent.url">
<div class="icon" :style="{ backgroundColor: relatedContent.couleur }"></div>
<div class="card-content">
<div class="infos">
<div class="titre">{{ relatedContent.title }} <span>({{ relatedContent.postalCode.slice(0, 2) }})</span></div>
<div class="date">Du {{ relatedContent.dates.start.d }} {{ relatedContent.dates.start.m }}<br>au {{ relatedContent.dates.end.d }} {{ relatedContent.dates.end.m }} {{ relatedContent.dates.end.y }}</div>
</div>
<div class="vignette">
<img :src="relatedContent.vignette.url.small" :alt="relatedContent.vignette.alt">
</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
relatedContent: Object,
direction: String,
});
import { onMounted } from 'vue';
import router from '../../router/router';
import { useContentStore } from '../../stores/content';
import { useMapStore } from '../../stores/map';
import { handleClickableElements } from '../../utils/handle-navigation.js';
const store = useContentStore();
const mapStore = useMapStore();
const siteName = document.querySelector('#site_name').innerText;
onMounted(() => {
const relatedEtapesCards = document.querySelectorAll('.card');
const baseUrl = window.location.protocol + "//" + window.location.host;
handleClickableElements(relatedEtapesCards, store, router, baseUrl, siteName, mapStore);
});
</script>

View File

@@ -16,6 +16,7 @@
:navigation="true"
:pagination="true"
:initialSlide="currentSlideIndex"
:keyboard="{ enabled: true }"
:injectStyles="[`
.swiper-button-next, .swiper-button-prev {
color: white;

View File

@@ -5,52 +5,20 @@
</div>
<div v-if="contentType === 'etape' && (content.previous || content.next)" class="related-etape-links">
<div v-if="content.previous" class="card previous" @click="goToRelatedElement(content.previous.url)">
<div class="icon">
<div :style="{ backgroundColor: content.previous.couleur }"></div>
<div :style="{ backgroundColor: content.previous.couleur }"></div>
<div :style="{ backgroundColor: content.previous.couleur }"></div>
</div>
<div class="card-content">
<div class="infos">
<div class="titre">{{ content.previous.title }} <span>({{ content.previous.postalCode.slice(0, 2) }})</span></div>
<div class="date">Du {{ content.previous.dates.start.d }} {{ content.previous.dates.start.m }}<br>au {{ content.previous.dates.end.d }} {{ content.previous.dates.end.m }} {{ content.previous.dates.end.y }}</div>
</div>
<div class="vignette">
<img :src="content.previous.vignette.url.small" :alt="content.previous.vignette.alt">
</div>
</div>
</div>
<div v-if="content.next" class="card next" @click="goToRelatedElement(content.next.url)">
<div class="icon">
<div :style="{ backgroundColor: content.next.couleur }"></div>
<div :style="{ backgroundColor: content.next.couleur }"></div>
<div :style="{ backgroundColor: content.next.couleur }"></div>
</div>
<div class="card-content">
<div class="infos">
<div class="titre">{{ content.next.title }} <span>({{ content.next.postalCode.slice(0, 2) }})</span></div>
<div class="date">Du {{ content.next.dates.start.d }} {{ content.next.dates.start.m }}<br>au {{ content.next.dates.end.d }} {{ content.next.dates.end.m }} {{ content.next.dates.end.y }}</div>
</div>
<div class="vignette">
<img :src="content.next.vignette.url.small" :alt="content.next.vignette.alt">
</div>
</div>
<EtapeCard v-if="content.previous" :relatedContent="content.previous" :direction="'previous'"/>
<EtapeCard v-if="content.next" :relatedContent="content.next" :direction="'next'"/>
</div>
<div v-if="contentType === 'ressourceItem' && content.relatedEtape" >
<div class="related-etape-label" :style="{ backgroundColor: couleur }">Étape de la ressource</div>
<div class="related-etape-links">
<EtapeCard :relatedContent="content.relatedEtape" :direction="''" />
</div>
</div>
</footer>
</template>
<script setup>
import { useContentStore } from '../../stores/content';
import { pageChange } from '../../utils/handle-navigation.js';
const brandColor = "#80c8bf";
const store = useContentStore();
const mapStore = useContentStore();
const siteName = document.querySelector('#site_name').innerText;
import EtapeCard from './EtapeCard.vue';
const props = defineProps({
contentType: String,
@@ -58,11 +26,4 @@ const props = defineProps({
couleur: String,
map: Object,
});
async function goToRelatedElement(href) {
const baseUrl = window.location.protocol + "//" + window.location.host;
if (href.startsWith(baseUrl)) href = href.replace(baseUrl, '');
pageChange(href, store, siteName, mapStore, baseUrl)
}
</script>

View File

@@ -14,7 +14,7 @@
<div class="locality">
<div class="top-triangle" v-if="contentType === 'etape'"></div>
<div class="locality-title">
<h1>{{content.contentTitle}} <em v-if="content.adresse">({{ content.adresse.postal_code.slice(0, 2) }})</em></h1>
<h1>{{ contentType === 'ressourceItem' ? 'Centre de ressources' : content.contentTitle }} <em v-if="content.adresse">({{ content.adresse.postal_code.slice(0, 2) }})</em></h1>
</div>
</div>
</div>

View File

@@ -0,0 +1,23 @@
<template>
<div class="partie related-ressources">
<h3>
<p :style="{ background: `linear-gradient(transparent 70%, ${couleur} 70%)` }">
Ressources liées
</p>
</h3>
<div class="ressource-list sm-ressource-list">
<div class="ressource-item" v-for="(relatedRessource, index) in relatedRessources">
<RessourceCard :ressource="relatedRessource" :index="index" />
</div>
</div>
</div>
</template>
<script setup>
import RessourceCard from './RessourceCard.vue';
const props = defineProps({
relatedRessources: Object,
couleur: String,
});
</script>

View File

@@ -0,0 +1,49 @@
<template>
<div
:data-href="ressource.url"
:id="`ressource-${index}`"
:class="ressource.promoted ? 'promoted' : ''">
<figure>
<img :src="ressource.vignette.url" :alt="ressource.vignette.alt" />
</figure>
<div>
<h4>{{ ressource.title }}</h4>
<p>Le {{ ressource.date.d }} {{ ressource.date.m }} {{ ressource.date.y }}</p>
<p>Par {{ ressource.auteurice }}</p>
</div>
</div>
</template>
<script setup>
import { onMounted } from 'vue';
import router from '../../router/router';
import { handleClickableElements } from '../../utils/handle-navigation.js';
import { useContentStore } from '../../stores/content';
import { useMapStore } from '../../stores/map';
const store = useContentStore();
const mapStore = useMapStore();
const siteName = document.querySelector('#site_name').innerText;
let relatedItemCards, baseUrl;
onMounted(() => {
baseUrl = window.location.protocol + "//" + window.location.host;
setClickableElements();
});
const setClickableElements = () => {
relatedItemCards = document.querySelector(`#ressource-${props.index}`);
handleClickableElements([relatedItemCards], store, router, baseUrl, siteName, mapStore);
}
defineExpose({
setClickableElements,
});
const props = defineProps({
ressource: Object,
index: String,
});
</script>

View File

@@ -0,0 +1,63 @@
<template>
<header id="ressource-item-header">
<div class="retour">
<p data-href="/ressources"> Retour au centre de ressources</p>
</div>
<div class="type">{{ content.displayedType }}</div>
<div class="title">
<h2
:style="{ background: `linear-gradient(transparent 70%, ${couleur} 70%)` }">
{{ content.contentTitle }}
</h2>
</div>
<div class="meta">Par {{ content.auteurice }}, le {{ content.date.d }} {{ content.date.m }} {{ content.date.y }}</div>
</header>
</template>
<script setup>
import { onMounted } from 'vue';
import router from '../../router/router';
import { useContentStore } from '../../stores/content';
import { useMapStore } from '../../stores/map';
import { handleClickableElements } from '../../utils/handle-navigation.js';
const store = useContentStore();
const mapStore = useMapStore();
const siteName = document.querySelector('#site_name').innerText;
const props = defineProps({
content: Object,
couleur: String,
});
function setDisplayedType() {
const ressourceType = props.content.ressourceType;
switch (ressourceType) {
case 'cartes_blanches':
props.content.displayedType = 'Carte blanche';
break;
case 'documents':
props.content.displayedType = 'Document';
break;
case 'galleries':
props.content.displayedType = 'Galerie';
break;
case 'videos':
props.content.displayedType = 'Vidéo';
break;
case 'reportages':
props.content.displayedType = 'Reportage';
break;
}
}
onMounted(() => {
const backToRessourcesLink = document.querySelectorAll('.retour > p');
const baseUrl = window.location.protocol + "//" + window.location.host;
handleClickableElements(backToRessourcesLink, store, router, baseUrl, siteName, mapStore);
setDisplayedType();
});
</script>

View File

@@ -59,7 +59,7 @@ const handleImageClick = (event) => {
const swiperEl = img.closest('swiper-container');
swiperEl.querySelectorAll('swiper-slide').forEach((slide) => {
const img = slide.querySelector('img');
const altText = slide.querySelector('figcaption')?.textContent || '';
const altText = slide.querySelector('figcaption')?.textContent || '';
Object.values(props.partie.diaporama).forEach((image) => {
if (image.url.medium === img.src) {
swiperMedia.push({ src: image.url.large, alt: altText });

View File

@@ -0,0 +1,50 @@
<template>
<div class="document"
:style="{ '--couleur': couleur }">
<div
class="intro"
v-html="partie.document.description">
</div>
<div class="document-grid">
<figure>
<a :href="partie.document.url" target="_blank">
<img :src="partie.document.vignette.url" :alt="partie.document.vignette.alt" />
</a>
</figure>
<div class="infos">
<p>{{ partie.document.titre }}</p>
<p>{{ partie.document.sousTitre }}</p>
<p>{{ partie.document.auteurice }}</p>
<p>{{ partie.document.date?.m }} {{ partie.document.date?.y }}</p>
</div>
<div class="download">
<a :href="partie.document.url" target="_blank">Télécharger le document</a>
</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
partie: Object,
couleur: String,
});
</script>
<style lang="scss" scoped>
.intro {
position: relative;
padding-left: 1.8rem;
margin: 3rem 0;
&::before {
content: '';
display: block;
position: absolute;
background-color: var(--couleur);
width: 0.8rem;
height: 100%;
margin-right: 1rem;
left: 0;
}
}
</style>

View File

@@ -0,0 +1,84 @@
<template>
<div class="gallerie">
<h3><p :style="{ background: `linear-gradient(transparent 70%, ${couleur} 70%)` }">{{ partie.gallerie.titre }}</p></h3>
<div class="intro" v-html="partie.gallerie.introduction"></div>
<div class="images-grid">
<figure v-for="image in partie.gallerie.images">
<img :src="image.url.medium" :alt="image.alt" @click="handleImageClick">
<figcaption class="caption">{{ image.alt }}</figcaption>
</figure>
</div>
</div>
<ImageModale
:isOpen="isModaleOpen"
:image="currentImage"
:swiperContent="swiperPopupContent"
@close="closeImageModale" />
</template>
<script setup>
import { onMounted } from 'vue';
import { useImageModal } from '../../composables/useImageModale';
import ImageModale from '../ImageModale.vue';
// WebComponent
// https://swiperjs.com/element
import { register } from 'swiper/element/bundle';
register();
const props = defineProps({
partie: Object,
couleur: String,
});
const {
isModaleOpen,
currentImage,
swiperPopupContent,
openImageModale,
closeImageModale
} = useImageModal();
const handleImageClick = (event) => {
const clickedImg = event.target;
if (clickedImg.tagName === 'IMG') {
let swiperMedia = [];
const imgGrid = clickedImg.closest('.images-grid');
imgGrid.querySelectorAll('figure').forEach((figure) => {
const img = figure.querySelector('img');
const altText = figure.querySelector('figcaption')?.textContent || '';
Object.values(props.partie.gallerie.images).forEach((image) => {
if (img.src === image.url.medium) {
swiperMedia.push({ src: image.url.large, alt: altText });
}
});
});
openImageModale(clickedImg.src, clickedImg.alt, swiperMedia);
}
}
onMounted(() => {
setVerticalImages();
document.documentElement.style.setProperty('--etape-couleur', props.couleur);
});
function setVerticalImages() {
const images = document.querySelectorAll('.images-grid figure img');
images.forEach((img) => {
if (img.naturalHeight > img.naturalWidth) {
img.classList.add('vertical');
img.closest('figure').querySelector('figcaption').style.textAlign = 'center';
}
});
}
</script>
<style lang="scss" scoped>
:root {
--swiper-navigation-color: #1a1918; /* cf main.scss */
--swiper-pagination-color: var(--etape-couleur);
--swiper-navigation-top-offset: calc(100% - 1.5rem);
--swiper-navigation-sides-offset: 5vw; /* cf main.scss */
}
</style>

View File

@@ -9,7 +9,7 @@ export function useImageModal() {
const hamburger = document.querySelector('#hamburger');
const menu = document.querySelector('#menu');
const openImageModale = (src, alt, swiperMedia) => {
const openImageModale = (src, alt, swiperMedia) => {
currentImage.value = { src, alt };
swiperPopupContent.value = swiperMedia || [];
isModaleOpen.value = true;

View File

@@ -0,0 +1,26 @@
const frenchMonthMap = {
janvier: 0,
février: 1,
mars: 2,
avril: 3,
mai: 4,
juin: 5,
juillet: 6,
août: 7,
septembre: 8,
octobre: 9,
novembre: 10,
décembre: 11
};
export default function parseDate(dateObj) {
if (!dateObj || !frenchMonthMap[dateObj.m?.toLowerCase()]) return new Date(0);
const day = Number(dateObj.d);
const month = frenchMonthMap[dateObj.m.toLowerCase()];
const year = Number(dateObj.y);
if (isNaN(day) || isNaN(month) || isNaN(year)) return new Date(0);
return new Date(year, month, day);
}

View File

@@ -0,0 +1 @@
<svg width="20" xmlns="http://www.w3.org/2000/svg" height="24" fill="none"><path d="M19.996,13.728L19.992,17.434L9.964,24.000L0.000,17.500L0.000,13.541L0.000,10.459L0.000,6.500L9.964,0.000L19.992,6.566L19.996,10.272L20.000,10.272L19.998,12.000L19.996,13.728ZL19.996,13.728ZL19.998,12.000" style="fill: rgb(0, 0, 0); fill-opacity: 1;" class="fills"/></svg>

After

Width:  |  Height:  |  Size: 355 B

View File

@@ -15,6 +15,9 @@ $modale-width-desktop: 50vw;
$brand-pattern-height: 110px;
$xsm-font-size-mobile: 0.5rem;
$xsm-font-size-desktop: 0.6rem;
$sm-font-size-mobile: 0.6rem;
$sm-font-size-desktop: 0.8rem;
@@ -163,7 +166,7 @@ body{
}
> #hamburger {
position: fixed;
height: 5vh;
height: max(5vh, 40px);
right: 0;
top: 0;
margin-right: $body-margin-x;
@@ -343,27 +346,15 @@ body{
left: 0;
}
.leaflet-map-divicon {
width: 10px;
height: 30px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 20px !important;
height: 20px !important;
transition: transform 0.3s ease-out;
> div {
background-color: red;
display: block;
width: 20px;
height: 10px;
}
> div:first-of-type {
height: 8px;
clip-path: polygon(0 0, 100% 0, 50% 100%);
transform: rotate(180deg);
}
> div:nth-of-type(3) {
height: 8px;
clip-path: polygon(0 0, 100% 0, 50% 100%);
transform-origin: center;
mask-image: url("/themes/custom/caravane/assets/pictograms/hexagone.svg");
mask-size: contain;
mask-repeat: no-repeat;
> .url, .couleur {
display: none;
}
}
}
@@ -689,24 +680,12 @@ body{
}
}
> .icone-arret {
width: 10px;
height: 30px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
> div {
display: block;
width: 20px;
height: 10px;
&:first-of-type, &:last-of-type {
height: 8px;
clip-path: polygon(0 0, 100% 0, 50% 100%);
}
&:first-of-type {
transform: rotate(180deg);
}
}
min-width: 20px;
height: 20px;
display: block;
mask-image: url("/themes/custom/caravane/assets/pictograms/hexagone.svg");
mask-size: contain;
mask-repeat: no-repeat;
}
}
> li:hover {
@@ -789,11 +768,30 @@ body{
position: relative;
background-color: white;
font-size: $labeur-font-size-mobile;
//padding-bottom: $modale-bottom-padding;
&:has(#centre-de-ressource, #ressource-item-header) {
left: 5vw;
}
@media screen and (min-width: $desktop-min-width) {
font-size: $labeur-font-size-desktop;
width: $modale-width-desktop;
}
&:has(#centre-de-ressource),
&:has(#ressource-item-header) {
@media screen and (min-width: $tablet-min-width) {
left: 8vw;
width: 84vw;
.locality-title {
width: 42vw;
margin-left: 21vw;
}
}
@media screen and (min-width: $desktop-min-width) {
.locality-title {
width: 30vw;
margin-left: 27vw;
}
}
}
img {
width: 100%;
height: auto;
@@ -926,10 +924,20 @@ body{
}
}
> main {
z-index: 1;
position: relative;
width: 100%;
padding: 0 $modale-x-padding;
padding-bottom: 5vh;
box-sizing: border-box;
&:has(#ressource-item-header) {
// padding-right: 50%;
margin-bottom: 3rem;
@media screen and (min-width: $desktop-min-width) {
margin-bottom: 6rem;
padding: 0 calc($modale-x-padding * 4);
}
}
> .partie,
> #equipe {
width: 100%;
@@ -957,7 +965,9 @@ body{
}
.partie-title,
> .chiffres-cles,
> .entretien {
> .entretien,
> .gallerie,
&.related-ressources {
> h3 {
position: relative;
display: inline-block;
@@ -1094,6 +1104,99 @@ body{
> .videos iframe {
margin: 2rem 0;
}
> .gallerie {
> .intro {
margin-bottom: 2rem;
}
> .images-grid {
margin-top: 3rem;
display: grid;
grid-template-columns: 1fr 1fr;
column-gap: 5rem;
row-gap: 2rem;
@media screen and (min-width: $desktop-min-width) {
grid-template-columns: repeat(3, 1fr);
}
}
figure {
margin: 0;
> img {
cursor: pointer;
transform: scale(1);
transition: transform 0.2s ease-in-out;
&:hover {
transform: scale(1.02);
}
&.vertical {
box-sizing: border-box;
padding: 0 25%;
}
}
}
}
> .document {
.download {
> a {
color: $main-color;
text-decoration: none;
font-size: $sm-font-size-mobile;
background-color: $brand-color;
font-weight: bold;
padding: 0.5rem 1rem;
border-radius: 1rem;
display: inline-block;
transform: scale(1);
transition: transform 0.2s ease-in-out;
&:hover {
transform: scale(1.02);
}
@media screen and (min-width: $desktop-min-width) {
font-size: $sm-font-size-desktop;
}
}
}
> .document-grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto auto;
column-gap: 2rem;
> figure {
grid-column: 1 / 2;
grid-row: 1 / 3;
margin: 0;
background-color: var(--couleur);
img {
padding: 0.6rem;
box-sizing: border-box;
width: 100%;
height: auto;
object-fit: cover;
transform: scale(1);
transition: transform 0.2s ease-in-out;
&:hover {
transform: scale(1.02);
}
@media screen and (min-width: $desktop-min-width) {
padding: 2rem;
}
}
}
> .infos {
> p {
margin: 0;
margin-bottom: 0.8rem;
&:first-of-type {
font-weight: bold;
}
}
}
> .download {
align-self: end;
justify-self: end;
}
}
}
}
.caption {
font-size: $sm-font-size-mobile;
@@ -1176,6 +1279,113 @@ body{
margin-top: 10vh;
}
}
#centre-de-ressource {
.filters {
margin: 3rem 0;
margin-top: 5rem;
> .search-bar{
margin-right: 2rem;
border: solid 1px var(--couleur);
padding: 0.5rem 1rem;
border-radius: 1rem;
font-size: $sm-font-size-mobile;
font-family: 'Marianne', sans-serif;
}
> select {
max-width: 20%;
margin-right: 2rem;
appearance: none;
border: solid 1px var(--couleur);
padding: 0.5rem 1rem;
font-size: $sm-font-size-mobile;
font-family: 'Marianne', sans-serif;
border-radius: 1rem;
background-color: white;
background: url("data:image/svg+xml,<svg height='10px' width='10px' viewBox='0 0 16 16' fill='rgba(128, 200, 191)' xmlns='http://www.w3.org/2000/svg'><path d='M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/></svg>") no-repeat;
background-position: calc(100% - 1rem) center !important;
padding-right: 2.5rem !important;
}
}
> .intro {
font-size: $sm-font-size-mobile;
margin-bottom: 4rem;
@media screen and (min-width: $desktop-min-width) {
font-size: $sm-font-size-desktop;
width: 66%;
}
}
> .type-section {
> h3 {
display: inline-block;
font-size: $l-font-size-mobile;
font-family: 'Joost', sans-serif;
margin: 0;
margin-bottom: 2rem;
z-index: 1;
position: relative;
padding: 0 0.5rem;
background: linear-gradient(transparent 70%, $brand-color 70%);
@media screen and (min-width: $desktop-min-width) {
font-size: $l-font-size-desktop;
}
}
> .button-container {
display: flex;
justify-content: center;
> .ressource-button {
display: inline;
font-size: $sm-font-size-mobile;
background-color: $brand-color;
padding: 0.5rem 1.5rem;
border-radius: 1rem;
cursor: pointer;
transition: transform 0.2s ease-in-out;
transform: scale(1);
&:hover {
transform: scale(0.95);
}
@media screen and (min-width: $desktop-min-width) {
font-size: $sm-font-size-desktop;
}
}
}
}
}
> #ressource-item-header {
> .retour {
margin-bottom: 1.5rem;
> p {
display: inline-block;
cursor: pointer;
font-size: $sm-font-size-mobile;
@media screen and (min-width: $desktop-min-width) {
font-size: $sm-font-size-desktop;
}
}
}
> .type,
> .meta {
text-align: center;
font-size: $m-font-size-mobile;
font-family: 'Joost', sans-serif;
@media screen and (min-width: $desktop-min-width) {
font-size: $m-font-size-desktop;
}
}
> .title {
width: 100%;
text-align: center;
> h2 {
display: inline-block;
margin-top: 1rem;
font-size: $xl-font-size-mobile;
font-family: 'Joost', sans-serif;
@media screen and (min-width: $desktop-min-width) {
font-size: $xl-font-size-desktop;
}
}
}
}
}
> .pieces-jointes {
z-index: 1;
@@ -1232,6 +1442,7 @@ body{
}
}
> footer {
position: relative;
z-index: 0;
.pattern-bottom {
mask-image: linear-gradient(to top, rgba(0,0,0,1), rgba(0,0,0,0));
@@ -1243,15 +1454,33 @@ body{
background-size: 300px;
background-size: repeat;
}
> div:has(.related-etape-label) {
z-index: 1;
position: relative;
.related-etape-label {
display: inline-block;
padding: 0.5rem 1rem;
padding-left: calc($modale-x-padding / 2);
font-size: $sm-font-size-mobile;
margin-bottom: 1.5rem;
@media screen and (min-width: $desktop-min-width) {
margin-bottom: 0;
font-size: $sm-font-size-desktop;
}
}
}
.related-etape-links {
position: absolute;
//bottom: calc(($modale-bottom-padding / 2) * -1);
width: 100%;
box-sizing: border-box;
padding: 0 calc($modale-x-padding / 2);
display: grid;
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr;
width: 75%;
&:not(:has(.solo)) {
width: 100%;
position: absolute;
grid-template-rows: 1fr 1fr;
}
@media screen and (min-width: $desktop-min-width) {
grid-template-columns: 1fr 1fr;
margin-top: 2.5rem;
@@ -1287,24 +1516,12 @@ body{
}
> .icon {
z-index: 2;
width: 10px;
height: 30px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
> div {
display: block;
width: 20px;
height: 10px;
&:first-of-type, &:last-of-type {
height: 8px;
clip-path: polygon(0 0, 100% 0, 50% 100%);
}
&:first-of-type {
transform: rotate(180deg);
}
}
width: 25px;
height: 25px;
mask-image: url("/themes/custom/caravane/assets/pictograms/hexagone.svg");
mask-size: contain;
mask-repeat: no-repeat;
margin-right: -8px;
}
> .card-content {
z-index: 1;
@@ -1318,21 +1535,21 @@ body{
padding: 1rem 0.5rem;
font-weight: bold;
font-family: 'Joost', sans-serif;
font-size: $m-font-size-mobile;
font-size: $labeur-font-size-mobile;
@media screen and (min-width: $desktop-min-width) {
font-size: $m-font-size-desktop;
font-size: $labeur-font-size-desktop;
}
> span {
font-weight: lighter;
}
}
> .date {
font-size: $sm-font-size-mobile;
font-size: $xsm-font-size-mobile;
font-family: 'Marianne', sans-serif;
font-weight: lighter;
padding-bottom: 1rem;
@media screen and (min-width: $desktop-min-width) {
font-size: $sm-font-size-desktop;
font-size: $xsm-font-size-desktop;
}
}
}
@@ -1353,6 +1570,84 @@ body{
}
}
}
.ressource-list > div:not(.ressource-item),
.ressource-list.sm-ressource-list {
display: grid;
grid-template-columns: 1fr;
align-items: start;
gap: 2rem;
margin-bottom: 2.5rem;
@media screen and (min-width: $tablet-min-width) {
grid-template-columns: repeat(2, 1fr);
}
@media screen and (min-width: $desktop-min-width) {
grid-template-columns: repeat(4, 1fr);
}
&.sm-ressource-list {
margin-top: 2rem;
grid-template-columns: repeat(2, 1fr);
}
> .ressource-item > div {
display: flex;
gap: 0.8rem;
@media screen and (min-width: $desktop-min-width) {
gap: 1.2rem;
}
cursor: pointer;
transform: scale(1);
transition: transform 0.2s ease-in-out;
&.promoted {
&::after {
content: '';
position: absolute;
top: -10px;
left: -10px;
width: 20px !important;
height: 20px !important;
background-color: $brand-color;
mask-image: url("/themes/custom/caravane/assets/pictograms/hexagone.svg");
mask-size: contain;
mask-repeat: no-repeat;
}
}
&:hover {
transform: scale(1.05);
}
> figure {
width: 40%;
margin: 0;
}
> div {
width: 50%;
> h4 {
font-size: $m-font-size-mobile;
font-family: 'Joost', sans-serif;
margin: 0;
margin-bottom: 0.5rem;
@media screen and (min-width: $desktop-min-width) {
font-size: $m-font-size-desktop;
}
}
> p {
margin: 0;
font-size: $sm-font-size-mobile;
@media screen and (min-width: $desktop-min-width) {
font-size: $sm-font-size-desktop;
}
}
}
}
}
}
> #animation-toggle {
transition: opacity 0.3s ease-out;

View File

@@ -18,4 +18,4 @@ regions:
content: 'Content'
sidebar_first: 'Sidebar first'
sidebar_second: 'Sidebar second'
footer: 'Footer'
footer: 'Footer'

View File

@@ -55,7 +55,4 @@
{%- endfor %}
</div>
<div class="icone-arret">
<div></div>
<div></div>
<div></div>
</div>