From b853b295b1eacdc2f5a76d53a216976e548eaa56 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Tue, 29 Mar 2022 10:46:27 +0200
Subject: [PATCH 001/152] OEL-1297: Submodule created, first approach, WIP.

---
 composer.json                                 |  11 +-
 modules/oe_whitelabel_extra_project/README.md |   1 +
 ...tion.oe_cx_project_stakeholder.default.yml |  90 +++++++++++
 ...y_view_display.node.oe_project.default.yml | 153 ++++++++++++++++++
 ...tity_view_display.node.oe_project.full.yml | 146 +++++++++++++++++
 ...tion.oe_cx_project_stakeholder.default.yml |  53 ++++++
 ..._stakeholder.oe_cx_contribution_budget.yml |  22 +++
 .../oe_whitelabel_extra_project.info.yml      |  14 ++
 .../oe_whitelabel_extra_project.module        | 125 ++++++++++++++
 ...project-participants--oe-project.html.twig |  20 +++
 .../node--oe-project--full.html.twig          |  36 +++++
 .../templates/oe-organisation.html.twig       |  30 ++++
 runner.yml.dist                               |   1 +
 13 files changed, 701 insertions(+), 1 deletion(-)
 create mode 100644 modules/oe_whitelabel_extra_project/README.md
 create mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
 create mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.default.yml
 create mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
 create mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
 create mode 100644 modules/oe_whitelabel_extra_project/config/install/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml
 create mode 100644 modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
 create mode 100644 modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
 create mode 100644 modules/oe_whitelabel_extra_project/templates/field--node--oe-project-participants--oe-project.html.twig
 create mode 100644 modules/oe_whitelabel_extra_project/templates/node--oe-project--full.html.twig
 create mode 100644 modules/oe_whitelabel_extra_project/templates/oe-organisation.html.twig

diff --git a/composer.json b/composer.json
index 0017f449..c9de2ab9 100644
--- a/composer.json
+++ b/composer.json
@@ -15,16 +15,20 @@
     "require-dev": {
         "composer/installers": "^1.11",
         "drupal/better_exposed_filters": "^5.0",
+        "drupal/composite_reference": "^2.1",
         "drupal/config_devel": "~1.2",
         "drupal/core-composer-scaffold": "^9.2",
         "drupal/core-dev": "^9.2",
         "drupal/ctools": "^3.7",
         "drupal/drupal-extension": "~4.1",
+        "drupal/entity_reference_revisions": "^1.9",
+        "drupal/field_group": "^3.2",
         "drupal/file_link": "^2.0.4",
         "drupal/pathauto": "^1.8",
         "drupal/search_api": "^1.21",
         "drupal/search_api_autocomplete": "^1.5",
         "drupal/token": "^1.10",
+        "drupal/typed_link": "^2.0",
         "drush/drush": "^10.3",
         "easyrdf/easyrdf": "1.0.0 as 0.9.1",
         "egulias/email-validator": "^2.1.22 || ^3.0",
@@ -34,7 +38,8 @@
         "openeuropa/composer-artifacts": "^1.0.0-alpha1",
         "openeuropa/oe_authentication": "^1.4",
         "openeuropa/oe_contact_forms": "~1.1",
-        "openeuropa/oe_content": "^2.8.0",
+        "openeuropa/oe_content": "^3.0.0-beta11",
+        "openeuropa/oe_content_extra": "EPIC-1293-Project",
         "openeuropa/oe_corporate_blocks": "^4.4",
         "openeuropa/oe_multilingual": "^1.9",
         "openeuropa/oe_starter_content": "1.x-dev",
@@ -54,6 +59,10 @@
         "openeuropa/oe_starter_content": {
             "type": "git",
             "url": "https://github.com/openeuropa/oe_starter_content"
+        },
+        "openeuropa/oe_content_extra": {
+            "type": "git",
+            "url": "https://github.com/openeuropa/oe_content_extra"
         }
     },
     "extra": {
diff --git a/modules/oe_whitelabel_extra_project/README.md b/modules/oe_whitelabel_extra_project/README.md
new file mode 100644
index 00000000..6e534158
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/README.md
@@ -0,0 +1 @@
+# OpenEuropa Whitelabel Content Extra Project
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
new file mode 100644
index 00000000..f6af08d1
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
@@ -0,0 +1,90 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_acronym
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_address
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_contact_url
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_logo
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_website
+    - oe_content_entity_organisation.oe_organisation_type.oe_cx_project_stakeholder
+  module:
+    - address
+    - link
+id: oe_organisation.oe_cx_project_stakeholder.default
+targetEntityType: oe_organisation
+bundle: oe_cx_project_stakeholder
+mode: default
+content:
+  langcode:
+    type: language_select
+    weight: 2
+    region: content
+    settings:
+      include_locked: true
+    third_party_settings: {  }
+  name:
+    type: string_textfield
+    weight: 1
+    region: content
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  oe_acronym:
+    type: string_textfield
+    weight: 2
+    region: content
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  oe_address:
+    type: address_default
+    weight: 4
+    region: content
+    settings: {  }
+    third_party_settings: {  }
+  oe_contact_url:
+    type: link_default
+    weight: 6
+    region: content
+    settings:
+      placeholder_url: ''
+      placeholder_title: ''
+    third_party_settings: {  }
+  oe_cx_contribution_budget:
+    type: number
+    weight: 7
+    region: content
+    settings:
+      placeholder: ''
+    third_party_settings: {  }
+  oe_logo:
+    type: entity_reference_autocomplete
+    weight: 3
+    region: content
+    settings:
+      match_operator: CONTAINS
+      match_limit: 10
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  oe_website:
+    type: link_default
+    weight: 5
+    region: content
+    settings:
+      placeholder_url: ''
+      placeholder_title: ''
+    third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    weight: 8
+    region: content
+    settings:
+      display_label: true
+    third_party_settings: {  }
+hidden:
+  created: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.default.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.default.yml
new file mode 100644
index 00000000..18b1feb6
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.default.yml
@@ -0,0 +1,153 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.node.oe_project.body
+    - field.field.node.oe_project.oe_cx_achievements_and_milestone
+    - field.field.node.oe_project.oe_cx_gallery
+    - field.field.node.oe_project.oe_cx_impacts
+    - field.field.node.oe_project.oe_cx_lead_contributors
+    - field.field.node.oe_project.oe_cx_objective
+    - field.field.node.oe_project.oe_departments
+    - field.field.node.oe_project.oe_documents
+    - field.field.node.oe_project.oe_featured_media
+    - field.field.node.oe_project.oe_project_budget
+    - field.field.node.oe_project.oe_project_budget_eu
+    - field.field.node.oe_project.oe_project_calls
+    - field.field.node.oe_project.oe_project_contact
+    - field.field.node.oe_project.oe_project_coordinators
+    - field.field.node.oe_project.oe_project_dates
+    - field.field.node.oe_project.oe_project_funding_programme
+    - field.field.node.oe_project.oe_project_locations
+    - field.field.node.oe_project.oe_project_participants
+    - field.field.node.oe_project.oe_project_result_files
+    - field.field.node.oe_project.oe_project_results
+    - field.field.node.oe_project.oe_project_website
+    - field.field.node.oe_project.oe_reference_code
+    - field.field.node.oe_project.oe_subject
+    - field.field.node.oe_project.oe_summary
+    - field.field.node.oe_project.oe_teaser
+    - node.type.oe_project
+  module:
+    - address
+    - entity_reference_revisions
+    - field_group
+    - rdf_skos
+    - text
+    - user
+third_party_settings:
+  field_group:
+    group_stakeholders:
+      children:
+        - oe_project_participants
+      label: Stakeholders
+      parent_name: ''
+      region: content
+      weight: 6
+      format_type: html_element
+      format_settings:
+        classes: ''
+        id: ''
+        element: div
+        show_label: false
+        label_element: h3
+        label_element_classes: ''
+        attributes: ''
+        effect: none
+        speed: fast
+id: node.oe_project.default
+targetEntityType: node
+bundle: oe_project
+mode: default
+content:
+  oe_cx_achievements_and_milestone:
+    type: text_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 8
+    region: content
+  oe_cx_gallery:
+    type: entity_reference_entity_view
+    label: above
+    settings:
+      view_mode: default
+      link: false
+    third_party_settings: {  }
+    weight: 9
+    region: content
+  oe_cx_impacts:
+    type: text_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 5
+    region: content
+  oe_cx_objective:
+    type: text_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 4
+    region: content
+  oe_project_locations:
+    type: address_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 0
+    region: content
+  oe_project_participants:
+    type: entity_reference_revisions_entity_view
+    label: above
+    settings:
+      view_mode: default
+      link: ''
+    third_party_settings: {  }
+    weight: 7
+    region: content
+  oe_subject:
+    type: skos_concept_entity_reference_label
+    label: hidden
+    settings:
+      link: false
+    third_party_settings: {  }
+    weight: 1
+    region: content
+  oe_summary:
+    type: text_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 2
+    region: content
+  oe_teaser:
+    type: text_default
+    label: hidden
+    settings: {  }
+    third_party_settings: {  }
+    weight: 3
+    region: content
+hidden:
+  body: true
+  langcode: true
+  links: true
+  oe_content_content_owner: true
+  oe_content_legacy_link: true
+  oe_content_navigation_title: true
+  oe_content_short_title: true
+  oe_cx_lead_contributors: true
+  oe_departments: true
+  oe_documents: true
+  oe_featured_media: true
+  oe_project_budget: true
+  oe_project_budget_eu: true
+  oe_project_calls: true
+  oe_project_contact: true
+  oe_project_coordinators: true
+  oe_project_dates: true
+  oe_project_funding_programme: true
+  oe_project_result_files: true
+  oe_project_results: true
+  oe_project_website: true
+  oe_reference_code: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
new file mode 100644
index 00000000..151749b7
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
@@ -0,0 +1,146 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.full
+    - field.field.node.oe_project.body
+    - field.field.node.oe_project.oe_cx_achievements_and_milestone
+    - field.field.node.oe_project.oe_cx_gallery
+    - field.field.node.oe_project.oe_cx_impacts
+    - field.field.node.oe_project.oe_cx_lead_contributors
+    - field.field.node.oe_project.oe_cx_objective
+    - field.field.node.oe_project.oe_departments
+    - field.field.node.oe_project.oe_documents
+    - field.field.node.oe_project.oe_featured_media
+    - field.field.node.oe_project.oe_project_budget
+    - field.field.node.oe_project.oe_project_budget_eu
+    - field.field.node.oe_project.oe_project_calls
+    - field.field.node.oe_project.oe_project_contact
+    - field.field.node.oe_project.oe_project_coordinators
+    - field.field.node.oe_project.oe_project_dates
+    - field.field.node.oe_project.oe_project_funding_programme
+    - field.field.node.oe_project.oe_project_locations
+    - field.field.node.oe_project.oe_project_participants
+    - field.field.node.oe_project.oe_project_result_files
+    - field.field.node.oe_project.oe_project_results
+    - field.field.node.oe_project.oe_project_website
+    - field.field.node.oe_project.oe_reference_code
+    - field.field.node.oe_project.oe_subject
+    - field.field.node.oe_project.oe_summary
+    - field.field.node.oe_project.oe_teaser
+    - node.type.oe_project
+  module:
+    - address
+    - entity_reference_revisions
+    - field_group
+    - rdf_skos
+    - text
+    - user
+third_party_settings:
+  field_group:
+    group_stakeholders:
+      children:
+        - oe_project_participants
+      label: Stakeholders
+      parent_name: ''
+      region: content
+      weight: 7
+      format_type: html_element
+      format_settings:
+        classes: ''
+        id: ''
+        element: div
+        show_label: false
+        label_element: h3
+        label_element_classes: ''
+        attributes: ''
+        effect: none
+        speed: fast
+id: node.oe_project.full
+targetEntityType: node
+bundle: oe_project
+mode: full
+content:
+  oe_cx_achievements_and_milestone:
+    type: text_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 8
+    region: content
+  oe_cx_impacts:
+    type: text_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 6
+    region: content
+  oe_cx_objective:
+    type: text_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 5
+    region: content
+  oe_project_locations:
+    type: address_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 1
+    region: content
+  oe_project_participants:
+    type: entity_reference_revisions_entity_view
+    label: above
+    settings:
+      view_mode: default
+      link: ''
+    third_party_settings: {  }
+    weight: 7
+    region: content
+  oe_subject:
+    type: skos_concept_entity_reference_label
+    label: hidden
+    settings:
+      link: false
+    third_party_settings: {  }
+    weight: 2
+    region: content
+  oe_summary:
+    type: text_default
+    label: above
+    settings: {  }
+    third_party_settings: {  }
+    weight: 3
+    region: content
+  oe_teaser:
+    type: text_default
+    label: hidden
+    settings: {  }
+    third_party_settings: {  }
+    weight: 4
+    region: content
+hidden:
+  body: true
+  langcode: true
+  links: true
+  oe_content_content_owner: true
+  oe_content_legacy_link: true
+  oe_content_navigation_title: true
+  oe_content_short_title: true
+  oe_cx_gallery: true
+  oe_cx_lead_contributors: true
+  oe_departments: true
+  oe_documents: true
+  oe_featured_media: true
+  oe_project_budget: true
+  oe_project_budget_eu: true
+  oe_project_calls: true
+  oe_project_contact: true
+  oe_project_coordinators: true
+  oe_project_dates: true
+  oe_project_funding_programme: true
+  oe_project_result_files: true
+  oe_project_results: true
+  oe_project_website: true
+  oe_reference_code: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
new file mode 100644
index 00000000..beb93b00
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
@@ -0,0 +1,53 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_acronym
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_address
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_contact_url
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_logo
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_website
+    - oe_content_entity_organisation.oe_organisation_type.oe_cx_project_stakeholder
+  module:
+    - oe_whitelabel_helper
+id: oe_organisation.oe_cx_project_stakeholder.default
+targetEntityType: oe_organisation
+bundle: oe_cx_project_stakeholder
+mode: default
+content:
+  name:
+    type: string
+    label: hidden
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+    weight: 0
+    region: content
+  oe_address:
+    type: oe_whitelabel_helper_address_inline
+    label: above
+    settings:
+      delimiter: ', '
+    third_party_settings: {  }
+    weight: 1
+    region: content
+  oe_cx_contribution_budget:
+    type: number_decimal
+    label: above
+    settings:
+      thousand_separator: .
+      decimal_separator: .
+      scale: 2
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 2
+    region: content
+hidden:
+  created: true
+  langcode: true
+  oe_acronym: true
+  oe_contact_url: true
+  oe_logo: true
+  oe_website: true
+  status: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml b/modules/oe_whitelabel_extra_project/config/install/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml
new file mode 100644
index 00000000..f4bbedb1
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/install/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml
@@ -0,0 +1,22 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.storage.oe_organisation.oe_cx_contribution_budget
+    - oe_content_entity_organisation.oe_organisation_type.oe_cx_project_stakeholder
+id: oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget
+field_name: oe_cx_contribution_budget
+entity_type: oe_organisation
+bundle: oe_cx_project_stakeholder
+label: 'Contribution to the budget'
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings:
+  min: null
+  max: null
+  prefix: EUR
+  suffix: ''
+field_type: float
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
new file mode 100644
index 00000000..93f95981
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
@@ -0,0 +1,14 @@
+name: OpenEuropa Whitelabel Content Extra Project
+type: module
+description: Module to override content extra project.
+package: OpenEuropa Whitelabel Theme
+core_version_requirement: ^9.2
+dependencies:
+  - oe_content_extra:oe_content_extra_project
+
+config_devel:
+  install:
+    - core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default
+    - core.entity_view_display.node.oe_project.full
+    - core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
new file mode 100644
index 00000000..207e87b6
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -0,0 +1,125 @@
+<?php
+
+/**
+ * @file
+ * OE Whitelabel theme extra project.
+ */
+
+declare(strict_types =  1);
+
+use Drupal\Core\Cache\CacheableMetadata;
+use Drupal\media\MediaInterface;
+use Drupal\media\Plugin\media\Source\Image;
+use Drupal\media_avportal\Plugin\media\Source\MediaAvPortalPhotoSource;
+use Drupal\oe_bootstrap_theme\ValueObject\ImageValueObject;
+use Drupal\Component\Utility\Html;
+
+/**
+ * Implements template_preprocess_node() for the project node type.
+ */
+function oe_whitelabel_extra_project_preprocess_node__oe_project(&$variables) {
+  if ($variables['view_mode'] !== 'full' && $variables['view_mode'] !== 'teaser') {
+    return;
+  }
+  _oe_whitelabel_extra_project_preprocess_featured_media($variables);
+  _oe_whitelabel_extra_project_preprocess_inpage_nav($variables);
+}
+
+/**
+ * Implements hook_preprocess().
+ */
+function _oe_whitelabel_extra_project_preprocess_featured_media(&$variables) {
+  if ($variables['view_mode'] !== 'full' && $variables['view_mode'] !== 'teaser') {
+    return;
+  }
+
+  /** @var \Drupal\node\NodeInterface $node */
+  $node = $variables['node'];
+
+  // Bail out if there is no media present.
+  if ($node->get('oe_featured_media')->isEmpty()) {
+    return;
+  }
+
+  /** @var \Drupal\media\Entity\Media $media */
+  $media = $node->get('oe_featured_media')->entity;
+  if (!$media instanceof MediaInterface) {
+    // The media entity is not available anymore, bail out.
+    return;
+  }
+
+  // Retrieve the correct media translation.
+  /** @var \Drupal\media\Entity\Media $media */
+  $media = \Drupal::service('entity.repository')->getTranslationFromContext($media, $node->language()->getId());
+
+  // Caches are handled by the formatter usually. Since we are not rendering
+  // the original render arrays, we need to propagate our caches to the
+  // paragraph template.
+  $cacheability = CacheableMetadata::createFromRenderArray($variables);
+  $cacheability->addCacheableDependency($media);
+
+  // Run access checks on the media entity.
+  $access = $media->access('view', $variables['user'], TRUE);
+  $cacheability->addCacheableDependency($access);
+  if (!$access->isAllowed()) {
+    $cacheability->applyTo($variables);
+    return;
+  }
+
+  // Get the media source.
+  $source = $media->getSource();
+
+  $is_image = $source instanceof MediaAvPortalPhotoSource || $source instanceof Image;
+
+  // If it's not an image and not a video, bail out.
+  if (!$is_image) {
+    $cacheability->applyTo($variables);
+    return;
+  }
+
+  $thumbnail = $media->get('thumbnail')->first();
+  $variables['image'] = ImageValueObject::fromImageItem($thumbnail);
+
+  if ($variables['view_mode'] == 'teaser') {
+    $variables['image'] = ['#markup' => $variables['image']->getSource()];
+  }
+
+  $cacheability->applyTo($variables);
+}
+
+/**
+ * Helper function to preprocess the inpage navigation pattern fields.
+ *
+ * @param array $variables
+ *   Render array variables.
+ */
+function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables): void {
+  /** @var \Drupal\node\NodeInterface $node */
+  $node = $variables['node'];
+
+  $variables['inpage_navigation_links'] = [];
+  $fields = [
+    'oe_summary',
+    'oe_cx_objective',
+    'oe_cx_impacts',
+    'oe_project_participants',
+    'oe_cx_achievements_and_milestone',
+  ];
+  foreach ($variables['content'] as &$item) {
+    if (!array_key_exists('#field_name', $item)) {
+      continue;
+    }
+
+    if (!in_array($item['#field_name'], $fields)) {
+      continue;
+    }
+
+    $unique_id = Html::getUniqueId('oe-project--' . $item['#field_name']);
+    $item['#attributes'] = ['id' => $unique_id];
+    $variables['inpage_navigation_links'][] = [
+      'path' => '#' . $unique_id,
+      'label' => $node->{$item['#field_name']}->getFieldDefinition()->getLabel(),
+    ];
+  }
+
+}
diff --git a/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-participants--oe-project.html.twig b/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-participants--oe-project.html.twig
new file mode 100644
index 00000000..e27e7231
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-participants--oe-project.html.twig
@@ -0,0 +1,20 @@
+{#
+/**
+ * @file
+ * Project participants field template.
+ *
+ * @see ./core/themes/stable/templates/field/field.html.twig
+ */
+#}
+{% set _title = 'Contributors'|t %}
+<h3 id="oe-project-oe-project-participants" class="fw-bold my-4">
+  {{ _title }}
+</h3>
+
+<div class="ecl-row">
+  {% for item in items %}
+    <div class="ecl-col-12 ecl-col-m-6">
+      {{ item.content }}
+    </div>
+  {% endfor %}
+</div>
diff --git a/modules/oe_whitelabel_extra_project/templates/node--oe-project--full.html.twig b/modules/oe_whitelabel_extra_project/templates/node--oe-project--full.html.twig
new file mode 100644
index 00000000..686f2a11
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/templates/node--oe-project--full.html.twig
@@ -0,0 +1,36 @@
+{#
+/**
+ * @file
+ * Project full display.
+ */
+#}
+{% if not content.oe_subject.isEmpty() %}
+  {% set _badge = {
+    label: content.oe_subject|field_value,
+    rounded_pill: true,
+  } %}
+{% endif %}
+{{ pattern('content_banner', {
+  background: 'gray',
+  title: label,
+  content: content.oe_teaser,
+  image: image,
+  attributes: create_attribute().addClass(['ps-0']),
+  badges: [_badge],
+}) }}
+{% set inpage_navigation_fields %}
+  {{ content.oe_summary }}
+  {{ content.oe_cx_objective }}
+  {{ content.oe_cx_impacts }}
+  {{ content.group_stakeholders }}
+  {{ content.oe_cx_achievements_and_milestone }}
+{% endset %}
+<div class="mt-md-4-75 mt-4">
+  {{ pattern('inpage_navigation', {
+    title: 'Page content',
+    links: inpage_navigation_links,
+    content: inpage_navigation_fields,
+    full_layout: true,
+  }) }}
+</div>
+
diff --git a/modules/oe_whitelabel_extra_project/templates/oe-organisation.html.twig b/modules/oe_whitelabel_extra_project/templates/oe-organisation.html.twig
new file mode 100644
index 00000000..c1a620f6
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/templates/oe-organisation.html.twig
@@ -0,0 +1,30 @@
+{#
+/**
+ * @file
+ * Organisation teaser.
+ */
+#}
+{% spaceless %}
+  <article class="ecl-u-mb-l ecl-u-border-bottom ecl-u-border-width-3 ecl-u-border-color-grey-15 ecl-content-item ecl-u-d-flex ecl-u-pb-m">
+    <div class="ecl-u-flex-grow-1 ecl-u-type-color-grey">
+      <h4 class="ecl-u-type-heading-4 ecl-u-mb-s ecl-u-mt-none">
+        {% if elements.oe_acronym is not empty %} {{ elements.oe_acronym }}{% endif %}
+      </h4>
+      {% set _items = [] %}
+      {% for _field in elements if _key|first != '#' and _field|field_value %}
+        {% set _value %}
+          {{ _field|field_value|safe_join(', ') }}
+        {% endset %}
+        {% set _items = _items|merge([{
+          term: _field|field_label,
+          definition: _value,
+        }]) %}
+      {% endfor %}
+        {{ pattern('description_list', {
+          items: _items,
+          orientation: 'horizontal',
+          attributes: create_attribute().addClass(['mt-3', 'mb-4']),
+        }) }}
+    </div>
+  </article>
+{% endspaceless %}
diff --git a/runner.yml.dist b/runner.yml.dist
index e607338d..5dead5f2 100644
--- a/runner.yml.dist
+++ b/runner.yml.dist
@@ -21,6 +21,7 @@ drupal:
     - "./vendor/bin/drush en oe_corporate_blocks -y"
     - "./vendor/bin/drush en oe_whitelabel_multilingual -y"
     - "./vendor/bin/drush en oe_whitelabel_contact_forms -y"
+    - "./vendor/bin/drush en oe_whitelabel_extra_project -y"
     - "./vendor/bin/drush en oe_whitelabel_helper -y"
     - "./vendor/bin/drush en oe_whitelabel_search -y"
     - "./vendor/bin/drush en oe_whitelabel_starter_news -y"
-- 
GitLab


From 85daddf2f74e053aea37a794782b97032fac443c Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Tue, 29 Mar 2022 10:52:18 +0200
Subject: [PATCH 002/152] OEL-1297: Overrides added.

---
 ...tion.oe_cx_project_stakeholder.default.yml | 52 +++----------------
 ...y_view_display.node.oe_project.default.yml |  0
 ...tion.oe_cx_project_stakeholder.default.yml |  0
 ..._stakeholder.oe_cx_contribution_budget.yml |  0
 .../oe_whitelabel_extra_project.install       | 31 +++++++++++
 5 files changed, 39 insertions(+), 44 deletions(-)
 rename modules/oe_whitelabel_extra_project/config/{install => overrides}/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml (60%)
 rename modules/oe_whitelabel_extra_project/config/{install => overrides}/core.entity_view_display.node.oe_project.default.yml (100%)
 rename modules/oe_whitelabel_extra_project/config/{install => overrides}/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml (100%)
 rename modules/oe_whitelabel_extra_project/config/{install => overrides}/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml (100%)
 create mode 100644 modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
similarity index 60%
rename from modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
rename to modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
index f6af08d1..db59f56b 100644
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
@@ -11,22 +11,14 @@ dependencies:
     - oe_content_entity_organisation.oe_organisation_type.oe_cx_project_stakeholder
   module:
     - address
-    - link
 id: oe_organisation.oe_cx_project_stakeholder.default
 targetEntityType: oe_organisation
 bundle: oe_cx_project_stakeholder
 mode: default
 content:
-  langcode:
-    type: language_select
-    weight: 2
-    region: content
-    settings:
-      include_locked: true
-    third_party_settings: {  }
   name:
     type: string_textfield
-    weight: 1
+    weight: 0
     region: content
     settings:
       size: 60
@@ -34,7 +26,7 @@ content:
     third_party_settings: {  }
   oe_acronym:
     type: string_textfield
-    weight: 2
+    weight: 1
     region: content
     settings:
       size: 60
@@ -42,49 +34,21 @@ content:
     third_party_settings: {  }
   oe_address:
     type: address_default
-    weight: 4
+    weight: 2
     region: content
     settings: {  }
     third_party_settings: {  }
-  oe_contact_url:
-    type: link_default
-    weight: 6
-    region: content
-    settings:
-      placeholder_url: ''
-      placeholder_title: ''
-    third_party_settings: {  }
   oe_cx_contribution_budget:
     type: number
-    weight: 7
-    region: content
-    settings:
-      placeholder: ''
-    third_party_settings: {  }
-  oe_logo:
-    type: entity_reference_autocomplete
     weight: 3
     region: content
     settings:
-      match_operator: CONTAINS
-      match_limit: 10
-      size: 60
       placeholder: ''
     third_party_settings: {  }
-  oe_website:
-    type: link_default
-    weight: 5
-    region: content
-    settings:
-      placeholder_url: ''
-      placeholder_title: ''
-    third_party_settings: {  }
-  status:
-    type: boolean_checkbox
-    weight: 8
-    region: content
-    settings:
-      display_label: true
-    third_party_settings: {  }
 hidden:
   created: true
+  langcode: true
+  oe_contact_url: true
+  oe_logo: true
+  oe_website: true
+  status: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.default.yml
similarity index 100%
rename from modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.default.yml
rename to modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.default.yml
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
similarity index 100%
rename from modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
rename to modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
diff --git a/modules/oe_whitelabel_extra_project/config/install/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml b/modules/oe_whitelabel_extra_project/config/overrides/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml
similarity index 100%
rename from modules/oe_whitelabel_extra_project/config/install/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml
rename to modules/oe_whitelabel_extra_project/config/overrides/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
new file mode 100644
index 00000000..d9e4b049
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Install and update functions for the whitelabel Extra Project module.
+ */
+
+declare(strict_types = 1);
+
+use Drupal\oe_bootstrap_theme\ConfigImporter;
+
+/**
+ * Implements hook_install().
+ *
+ * Customise fields for content project.
+ */
+function oe_whitelabel_extra_project_install($is_syncing): void {
+  // If we are installing from config, we bail out.
+  if ($is_syncing) {
+    return;
+  }
+
+  $configs = [
+    'core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default',
+    'core.entity_view_display.node.oe_project.default',
+    'core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default',
+    'field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget',
+  ];
+
+  ConfigImporter::importMultiple('oe_whitelabel_extra_project', '/config/overrides/', $configs);
+}
-- 
GitLab


From e20f8fbbdd618c1e995603b5bea3a81a6a7d78d6 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Tue, 29 Mar 2022 11:04:09 +0200
Subject: [PATCH 003/152] OEL-1297: Dependences fixed on composer and
 whitelabel extra.

---
 composer.json                                                   | 2 +-
 .../oe_whitelabel_extra_project.info.yml                        | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/composer.json b/composer.json
index c9de2ab9..76b5ee6c 100644
--- a/composer.json
+++ b/composer.json
@@ -39,7 +39,7 @@
         "openeuropa/oe_authentication": "^1.4",
         "openeuropa/oe_contact_forms": "~1.1",
         "openeuropa/oe_content": "^3.0.0-beta11",
-        "openeuropa/oe_content_extra": "EPIC-1293-Project",
+        "openeuropa/oe_content_extra": "dev-EPIC-1293-Project",
         "openeuropa/oe_corporate_blocks": "^4.4",
         "openeuropa/oe_multilingual": "^1.9",
         "openeuropa/oe_starter_content": "1.x-dev",
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
index 93f95981..933f7195 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
@@ -5,6 +5,7 @@ package: OpenEuropa Whitelabel Theme
 core_version_requirement: ^9.2
 dependencies:
   - oe_content_extra:oe_content_extra_project
+  - oe_whitelabel_helper:oe_whitelabel_helper
 
 config_devel:
   install:
-- 
GitLab


From a6d9eb720e73eba2b00bdf8c1e7e7e95e129c37b Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Tue, 29 Mar 2022 11:20:22 +0200
Subject: [PATCH 004/152] OEL-1297: Config exported.

---
 ...tion.oe_cx_project_stakeholder.default.yml | 54 +++++++++++++++++
 ...tion.oe_cx_project_stakeholder.default.yml | 53 ++++++++++++++++
 ...tity_view_display.node.oe_project.full.yml | 60 +++++++++++++------
 .../oe_whitelabel_extra_project.info.yml      |  2 -
 4 files changed, 148 insertions(+), 21 deletions(-)
 create mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
 create mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
 rename modules/oe_whitelabel_extra_project/config/{install => overrides}/core.entity_view_display.node.oe_project.full.yml (84%)

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
new file mode 100644
index 00000000..db59f56b
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
@@ -0,0 +1,54 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_acronym
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_address
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_contact_url
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_logo
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_website
+    - oe_content_entity_organisation.oe_organisation_type.oe_cx_project_stakeholder
+  module:
+    - address
+id: oe_organisation.oe_cx_project_stakeholder.default
+targetEntityType: oe_organisation
+bundle: oe_cx_project_stakeholder
+mode: default
+content:
+  name:
+    type: string_textfield
+    weight: 0
+    region: content
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  oe_acronym:
+    type: string_textfield
+    weight: 1
+    region: content
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  oe_address:
+    type: address_default
+    weight: 2
+    region: content
+    settings: {  }
+    third_party_settings: {  }
+  oe_cx_contribution_budget:
+    type: number
+    weight: 3
+    region: content
+    settings:
+      placeholder: ''
+    third_party_settings: {  }
+hidden:
+  created: true
+  langcode: true
+  oe_contact_url: true
+  oe_logo: true
+  oe_website: true
+  status: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
new file mode 100644
index 00000000..beb93b00
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
@@ -0,0 +1,53 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_acronym
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_address
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_contact_url
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_logo
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_website
+    - oe_content_entity_organisation.oe_organisation_type.oe_cx_project_stakeholder
+  module:
+    - oe_whitelabel_helper
+id: oe_organisation.oe_cx_project_stakeholder.default
+targetEntityType: oe_organisation
+bundle: oe_cx_project_stakeholder
+mode: default
+content:
+  name:
+    type: string
+    label: hidden
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+    weight: 0
+    region: content
+  oe_address:
+    type: oe_whitelabel_helper_address_inline
+    label: above
+    settings:
+      delimiter: ', '
+    third_party_settings: {  }
+    weight: 1
+    region: content
+  oe_cx_contribution_budget:
+    type: number_decimal
+    label: above
+    settings:
+      thousand_separator: .
+      decimal_separator: .
+      scale: 2
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 2
+    region: content
+hidden:
+  created: true
+  langcode: true
+  oe_acronym: true
+  oe_contact_url: true
+  oe_logo: true
+  oe_website: true
+  status: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
similarity index 84%
rename from modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
rename to modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
index 151749b7..3be9dd2c 100644
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
@@ -31,9 +31,9 @@ dependencies:
     - node.type.oe_project
   module:
     - address
+    - datetime_range
     - entity_reference_revisions
     - field_group
-    - rdf_skos
     - text
     - user
 third_party_settings:
@@ -44,7 +44,7 @@ third_party_settings:
       label: Stakeholders
       parent_name: ''
       region: content
-      weight: 7
+      weight: 8
       format_type: html_element
       format_settings:
         classes: ''
@@ -66,28 +66,60 @@ content:
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 8
+    weight: 9
     region: content
   oe_cx_impacts:
     type: text_default
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 6
+    weight: 7
     region: content
   oe_cx_objective:
     type: text_default
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 5
+    weight: 6
+    region: content
+  oe_project_budget:
+    type: number_decimal
+    label: above
+    settings:
+      thousand_separator: ''
+      decimal_separator: .
+      scale: 2
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 1
+    region: content
+  oe_project_budget_eu:
+    type: number_decimal
+    label: above
+    settings:
+      thousand_separator: ''
+      decimal_separator: .
+      scale: 2
+      prefix_suffix: true
+    third_party_settings: {  }
+    weight: 2
+    region: content
+  oe_project_dates:
+    type: daterange_default
+    label: above
+    settings:
+      timezone_override: ''
+      format_type: medium
+      separator: '-'
+    third_party_settings: {  }
+    weight: 0
     region: content
   oe_project_locations:
     type: address_default
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 1
+    weight: 3
     region: content
   oe_project_participants:
     type: entity_reference_revisions_entity_view
@@ -98,27 +130,19 @@ content:
     third_party_settings: {  }
     weight: 7
     region: content
-  oe_subject:
-    type: skos_concept_entity_reference_label
-    label: hidden
-    settings:
-      link: false
-    third_party_settings: {  }
-    weight: 2
-    region: content
   oe_summary:
     type: text_default
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 3
+    weight: 4
     region: content
   oe_teaser:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 4
+    weight: 5
     region: content
 hidden:
   body: true
@@ -133,14 +157,12 @@ hidden:
   oe_departments: true
   oe_documents: true
   oe_featured_media: true
-  oe_project_budget: true
-  oe_project_budget_eu: true
   oe_project_calls: true
   oe_project_contact: true
   oe_project_coordinators: true
-  oe_project_dates: true
   oe_project_funding_programme: true
   oe_project_result_files: true
   oe_project_results: true
   oe_project_website: true
   oe_reference_code: true
+  oe_subject: true
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
index 933f7195..85b12445 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
@@ -10,6 +10,4 @@ dependencies:
 config_devel:
   install:
     - core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default
-    - core.entity_view_display.node.oe_project.full
     - core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget
-- 
GitLab


From fadcb6cb1ad103266224ac9ef340269225780a92 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Tue, 29 Mar 2022 11:25:35 +0200
Subject: [PATCH 005/152] OEL-1297: Config exported full viewmode.

---
 ...tion.oe_cx_project_stakeholder.default.yml | 54 -------------------
 ...tion.oe_cx_project_stakeholder.default.yml | 53 ------------------
 .../oe_whitelabel_extra_project.info.yml      |  5 --
 .../oe_whitelabel_extra_project.install       |  1 +
 4 files changed, 1 insertion(+), 112 deletions(-)
 delete mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
 delete mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
deleted file mode 100644
index db59f56b..00000000
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default.yml
+++ /dev/null
@@ -1,54 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_acronym
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_address
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_contact_url
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_logo
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_website
-    - oe_content_entity_organisation.oe_organisation_type.oe_cx_project_stakeholder
-  module:
-    - address
-id: oe_organisation.oe_cx_project_stakeholder.default
-targetEntityType: oe_organisation
-bundle: oe_cx_project_stakeholder
-mode: default
-content:
-  name:
-    type: string_textfield
-    weight: 0
-    region: content
-    settings:
-      size: 60
-      placeholder: ''
-    third_party_settings: {  }
-  oe_acronym:
-    type: string_textfield
-    weight: 1
-    region: content
-    settings:
-      size: 60
-      placeholder: ''
-    third_party_settings: {  }
-  oe_address:
-    type: address_default
-    weight: 2
-    region: content
-    settings: {  }
-    third_party_settings: {  }
-  oe_cx_contribution_budget:
-    type: number
-    weight: 3
-    region: content
-    settings:
-      placeholder: ''
-    third_party_settings: {  }
-hidden:
-  created: true
-  langcode: true
-  oe_contact_url: true
-  oe_logo: true
-  oe_website: true
-  status: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
deleted file mode 100644
index beb93b00..00000000
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_acronym
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_address
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_contact_url
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_logo
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_website
-    - oe_content_entity_organisation.oe_organisation_type.oe_cx_project_stakeholder
-  module:
-    - oe_whitelabel_helper
-id: oe_organisation.oe_cx_project_stakeholder.default
-targetEntityType: oe_organisation
-bundle: oe_cx_project_stakeholder
-mode: default
-content:
-  name:
-    type: string
-    label: hidden
-    settings:
-      link_to_entity: false
-    third_party_settings: {  }
-    weight: 0
-    region: content
-  oe_address:
-    type: oe_whitelabel_helper_address_inline
-    label: above
-    settings:
-      delimiter: ', '
-    third_party_settings: {  }
-    weight: 1
-    region: content
-  oe_cx_contribution_budget:
-    type: number_decimal
-    label: above
-    settings:
-      thousand_separator: .
-      decimal_separator: .
-      scale: 2
-      prefix_suffix: true
-    third_party_settings: {  }
-    weight: 2
-    region: content
-hidden:
-  created: true
-  langcode: true
-  oe_acronym: true
-  oe_contact_url: true
-  oe_logo: true
-  oe_website: true
-  status: true
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
index 85b12445..8f5b3d0c 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
@@ -6,8 +6,3 @@ core_version_requirement: ^9.2
 dependencies:
   - oe_content_extra:oe_content_extra_project
   - oe_whitelabel_helper:oe_whitelabel_helper
-
-config_devel:
-  install:
-    - core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default
-    - core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
index d9e4b049..a49cd6bd 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
@@ -23,6 +23,7 @@ function oe_whitelabel_extra_project_install($is_syncing): void {
   $configs = [
     'core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default',
     'core.entity_view_display.node.oe_project.default',
+    'core.entity_view_display.node.oe_project.full',
     'core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default',
     'field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget',
   ];
-- 
GitLab


From fc12b29013c852214cb6b71532998ff44a833e3d Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Tue, 29 Mar 2022 12:28:28 +0200
Subject: [PATCH 006/152] OEL-1297: Config exported full form mode.

---
 ...y_form_display.node.oe_project.default.yml | 274 ++++++++++++++++++
 ...tity_view_display.node.oe_project.full.yml |  57 +++-
 .../oe_whitelabel_extra_project.install       |   1 +
 3 files changed, 321 insertions(+), 11 deletions(-)
 create mode 100644 modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml

diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml
new file mode 100644
index 00000000..f6b8dee8
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml
@@ -0,0 +1,274 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - field.field.node.oe_project.body
+    - field.field.node.oe_project.oe_cx_achievements_and_milestone
+    - field.field.node.oe_project.oe_cx_gallery
+    - field.field.node.oe_project.oe_cx_impacts
+    - field.field.node.oe_project.oe_cx_lead_contributors
+    - field.field.node.oe_project.oe_cx_objective
+    - field.field.node.oe_project.oe_departments
+    - field.field.node.oe_project.oe_documents
+    - field.field.node.oe_project.oe_featured_media
+    - field.field.node.oe_project.oe_project_budget
+    - field.field.node.oe_project.oe_project_budget_eu
+    - field.field.node.oe_project.oe_project_calls
+    - field.field.node.oe_project.oe_project_contact
+    - field.field.node.oe_project.oe_project_coordinators
+    - field.field.node.oe_project.oe_project_dates
+    - field.field.node.oe_project.oe_project_funding_programme
+    - field.field.node.oe_project.oe_project_locations
+    - field.field.node.oe_project.oe_project_participants
+    - field.field.node.oe_project.oe_project_result_files
+    - field.field.node.oe_project.oe_project_results
+    - field.field.node.oe_project.oe_project_website
+    - field.field.node.oe_project.oe_reference_code
+    - field.field.node.oe_project.oe_subject
+    - field.field.node.oe_project.oe_summary
+    - field.field.node.oe_project.oe_teaser
+    - node.type.oe_project
+  module:
+    - address
+    - datetime_range
+    - field_group
+    - inline_entity_form
+    - link
+    - oe_content_featured_media_field
+    - rdf_skos
+    - text
+third_party_settings:
+  field_group:
+    group_result:
+      children:
+        - oe_project_results
+        - oe_project_result_files
+      label: Result
+      region: hidden
+      parent_name: ''
+      weight: 30
+      format_type: details
+      format_settings:
+        classes: ''
+        id: ''
+        open: true
+        description: ''
+        required_fields: true
+    group_alternative_titles_teaser:
+      children:
+        - oe_featured_media
+        - status
+        - oe_teaser
+        - oe_subject
+      label: 'Alternative titles and teaser'
+      region: content
+      parent_name: ''
+      weight: 1
+      format_type: tab
+      format_settings:
+        classes: ''
+        id: ''
+        formatter: open
+        description: ''
+        required_fields: true
+    group_budget:
+      children:
+        - oe_project_budget
+        - oe_project_budget_eu
+      label: Budget
+      region: content
+      parent_name: group_details
+      weight: 6
+      format_type: tab
+      format_settings:
+        classes: ''
+        id: ''
+        formatter: open
+        description: ''
+        required_fields: true
+    group_details:
+      children:
+        - oe_project_dates
+        - group_budget
+        - oe_project_website
+        - oe_project_locations
+      label: 'Project details'
+      region: content
+      parent_name: ''
+      weight: 2
+      format_type: html_element
+      format_settings:
+        classes: ''
+        show_empty_fields: false
+        id: ''
+        element: div
+        show_label: true
+        label_element: h3
+        label_element_classes: ''
+        attributes: ''
+        effect: none
+        speed: fast
+        required_fields: true
+id: node.oe_project.default
+targetEntityType: node
+bundle: oe_project
+mode: default
+content:
+  oe_cx_achievements_and_milestone:
+    type: text_textarea
+    weight: 7
+    region: content
+    settings:
+      rows: 5
+      placeholder: ''
+    third_party_settings: {  }
+  oe_cx_impacts:
+    type: text_textarea
+    weight: 5
+    region: content
+    settings:
+      rows: 5
+      placeholder: ''
+    third_party_settings: {  }
+  oe_cx_objective:
+    type: text_textarea
+    weight: 4
+    region: content
+    settings:
+      rows: 5
+      placeholder: ''
+    third_party_settings: {  }
+  oe_featured_media:
+    type: oe_featured_media_autocomplete
+    weight: 8
+    region: content
+    settings:
+      match_operator: CONTAINS
+      match_limit: 10
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  oe_project_budget:
+    type: number
+    weight: 9
+    region: content
+    settings:
+      placeholder: ''
+    third_party_settings: {  }
+  oe_project_budget_eu:
+    type: number
+    weight: 10
+    region: content
+    settings:
+      placeholder: ''
+    third_party_settings: {  }
+  oe_project_dates:
+    type: daterange_datelist
+    weight: 5
+    region: content
+    settings:
+      increment: 15
+      date_order: DMY
+      time_type: none
+    third_party_settings: {  }
+  oe_project_locations:
+    type: address_default
+    weight: 8
+    region: content
+    settings: {  }
+    third_party_settings: {  }
+  oe_project_participants:
+    type: inline_entity_form_complex
+    weight: 6
+    region: content
+    settings:
+      form_mode: default
+      override_labels: true
+      label_singular: participant
+      label_plural: participants
+      allow_new: true
+      allow_existing: false
+      match_operator: CONTAINS
+      allow_duplicate: false
+      collapsible: true
+      collapsed: false
+      revision: true
+      removed_reference: keep
+    third_party_settings: {  }
+  oe_project_website:
+    type: link_default
+    weight: 7
+    region: content
+    settings:
+      placeholder_url: ''
+      placeholder_title: ''
+    third_party_settings: {  }
+  oe_subject:
+    type: skos_concept_entity_reference_autocomplete
+    weight: 11
+    region: content
+    settings:
+      match_operator: CONTAINS
+      match_limit: 10
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  oe_summary:
+    type: text_textarea
+    weight: 3
+    region: content
+    settings:
+      rows: 5
+      placeholder: ''
+    third_party_settings: {  }
+  oe_teaser:
+    type: text_textarea
+    weight: 10
+    region: content
+    settings:
+      rows: 5
+      placeholder: ''
+    third_party_settings: {  }
+  status:
+    type: boolean_checkbox
+    weight: 9
+    region: content
+    settings:
+      display_label: true
+    third_party_settings: {  }
+  title:
+    type: string_textfield
+    weight: 0
+    region: content
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  translation:
+    weight: 10
+    region: content
+    settings: {  }
+    third_party_settings: {  }
+hidden:
+  body: true
+  created: true
+  langcode: true
+  oe_content_content_owner: true
+  oe_content_legacy_link: true
+  oe_content_navigation_title: true
+  oe_content_short_title: true
+  oe_cx_gallery: true
+  oe_cx_lead_contributors: true
+  oe_departments: true
+  oe_documents: true
+  oe_project_calls: true
+  oe_project_contact: true
+  oe_project_coordinators: true
+  oe_project_funding_programme: true
+  oe_project_result_files: true
+  oe_project_results: true
+  oe_reference_code: true
+  path: true
+  promote: true
+  sticky: true
+  uid: true
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
index 3be9dd2c..80fe48bf 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
@@ -34,6 +34,7 @@ dependencies:
     - datetime_range
     - entity_reference_revisions
     - field_group
+    - link
     - text
     - user
 third_party_settings:
@@ -44,7 +45,7 @@ third_party_settings:
       label: Stakeholders
       parent_name: ''
       region: content
-      weight: 8
+      weight: 5
       format_type: html_element
       format_settings:
         classes: ''
@@ -56,6 +57,29 @@ third_party_settings:
         attributes: ''
         effect: none
         speed: fast
+    group_project_details:
+      children:
+        - oe_project_dates
+        - oe_project_budget
+        - oe_project_budget_eu
+        - oe_project_website
+        - oe_project_locations
+      label: 'Project details'
+      parent_name: ''
+      region: content
+      weight: 0
+      format_type: html_element
+      format_settings:
+        classes: ''
+        show_empty_fields: false
+        id: ''
+        element: div
+        show_label: true
+        label_element: h3
+        label_element_classes: ''
+        attributes: ''
+        effect: none
+        speed: fast
 id: node.oe_project.full
 targetEntityType: node
 bundle: oe_project
@@ -66,21 +90,21 @@ content:
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 9
+    weight: 6
     region: content
   oe_cx_impacts:
     type: text_default
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 7
+    weight: 4
     region: content
   oe_cx_objective:
     type: text_default
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 6
+    weight: 3
     region: content
   oe_project_budget:
     type: number_decimal
@@ -91,7 +115,7 @@ content:
       scale: 2
       prefix_suffix: true
     third_party_settings: {  }
-    weight: 1
+    weight: 2
     region: content
   oe_project_budget_eu:
     type: number_decimal
@@ -102,7 +126,7 @@ content:
       scale: 2
       prefix_suffix: true
     third_party_settings: {  }
-    weight: 2
+    weight: 3
     region: content
   oe_project_dates:
     type: daterange_default
@@ -112,14 +136,14 @@ content:
       format_type: medium
       separator: '-'
     third_party_settings: {  }
-    weight: 0
+    weight: 1
     region: content
   oe_project_locations:
     type: address_default
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 3
+    weight: 5
     region: content
   oe_project_participants:
     type: entity_reference_revisions_entity_view
@@ -130,19 +154,31 @@ content:
     third_party_settings: {  }
     weight: 7
     region: content
+  oe_project_website:
+    type: link
+    label: above
+    settings:
+      trim_length: 80
+      url_only: false
+      url_plain: false
+      rel: ''
+      target: ''
+    third_party_settings: {  }
+    weight: 4
+    region: content
   oe_summary:
     type: text_default
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 4
+    weight: 2
     region: content
   oe_teaser:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 5
+    weight: 1
     region: content
 hidden:
   body: true
@@ -163,6 +199,5 @@ hidden:
   oe_project_funding_programme: true
   oe_project_result_files: true
   oe_project_results: true
-  oe_project_website: true
   oe_reference_code: true
   oe_subject: true
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
index a49cd6bd..3b2218c8 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
@@ -21,6 +21,7 @@ function oe_whitelabel_extra_project_install($is_syncing): void {
   }
 
   $configs = [
+    'core.entity_form_display.node.oe_project.default',
     'core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default',
     'core.entity_view_display.node.oe_project.default',
     'core.entity_view_display.node.oe_project.full',
-- 
GitLab


From 03c31e98cf21466750e167c4398400033a52be66 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Tue, 29 Mar 2022 18:44:15 +0200
Subject: [PATCH 007/152] OEL-1297: Project section styled.

---
 ...oe_cx_project_stakeholder.coordinators.yml |  35 +++++
 ...view_mode.oe_organisation.coordinators.yml |   9 ++
 ...y_form_display.node.oe_project.default.yml | 120 +++++++++++++----
 ...tity_view_display.node.oe_project.full.yml | 126 +++++++++++++++---
 ...tion.oe_cx_project_stakeholder.default.yml |  11 +-
 .../oe_whitelabel_extra_project.info.yml      |   5 +
 .../oe_whitelabel_extra_project.module        |   1 +
 ...cx-lead-contributors--oe-project.html.twig |  20 +++
 ...project-coordinators--oe-project.html.twig |  14 ++
 ...project-participants--oe-project.html.twig |   2 +-
 ...--node--oe-project--group-budget.html.twig |  23 ++++
 ...--node--oe-project--group-period.html.twig |  23 ++++
 ...e-project--group-project-details.html.twig |  33 +++++
 .../node--oe-project--full.html.twig          |   2 +
 ...on--oe-stakeholder--coordinators.html.twig |   9 ++
 .../templates/oe-organisation.html.twig       |   4 +-
 16 files changed, 386 insertions(+), 51 deletions(-)
 create mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.coordinators.yml
 create mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.coordinators.yml
 create mode 100644 modules/oe_whitelabel_extra_project/templates/field--node--oe-cx-lead-contributors--oe-project.html.twig
 create mode 100644 modules/oe_whitelabel_extra_project/templates/field--node--oe-project-coordinators--oe-project.html.twig
 create mode 100644 modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-budget.html.twig
 create mode 100644 modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-period.html.twig
 create mode 100644 modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-project-details.html.twig
 create mode 100644 modules/oe_whitelabel_extra_project/templates/oe-organisation--oe-stakeholder--coordinators.html.twig

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.coordinators.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.coordinators.yml
new file mode 100644
index 00000000..e70e4004
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.coordinators.yml
@@ -0,0 +1,35 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.oe_organisation.coordinators
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_acronym
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_address
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_contact_url
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_logo
+    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_website
+    - oe_content_entity_organisation.oe_organisation_type.oe_cx_project_stakeholder
+id: oe_organisation.oe_cx_project_stakeholder.coordinators
+targetEntityType: oe_organisation
+bundle: oe_cx_project_stakeholder
+mode: coordinators
+content:
+  name:
+    type: string
+    label: hidden
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+    weight: 0
+    region: content
+hidden:
+  created: true
+  langcode: true
+  oe_acronym: true
+  oe_address: true
+  oe_contact_url: true
+  oe_cx_contribution_budget: true
+  oe_logo: true
+  oe_website: true
+  status: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.coordinators.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.coordinators.yml
new file mode 100644
index 00000000..e375236d
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.coordinators.yml
@@ -0,0 +1,9 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - oe_content_entity_organisation
+id: oe_organisation.coordinators
+label: Coordinators
+targetEntityType: oe_organisation
+cache: true
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml
index f6b8dee8..67e8f1a1 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml
@@ -29,7 +29,6 @@ dependencies:
     - field.field.node.oe_project.oe_teaser
     - node.type.oe_project
   module:
-    - address
     - datetime_range
     - field_group
     - inline_entity_form
@@ -44,9 +43,9 @@ third_party_settings:
         - oe_project_results
         - oe_project_result_files
       label: Result
-      region: hidden
+      region: content
       parent_name: ''
-      weight: 30
+      weight: 3
       format_type: details
       format_settings:
         classes: ''
@@ -56,10 +55,11 @@ third_party_settings:
         required_fields: true
     group_alternative_titles_teaser:
       children:
+        - oe_subject
         - oe_featured_media
         - status
         - oe_teaser
-        - oe_subject
+        - oe_project_coordinators
       label: 'Alternative titles and teaser'
       region: content
       parent_name: ''
@@ -91,11 +91,11 @@ third_party_settings:
         - oe_project_dates
         - group_budget
         - oe_project_website
-        - oe_project_locations
+        - oe_project_funding_programme
       label: 'Project details'
       region: content
       parent_name: ''
-      weight: 2
+      weight: 4
       format_type: html_element
       format_settings:
         classes: ''
@@ -116,31 +116,69 @@ mode: default
 content:
   oe_cx_achievements_and_milestone:
     type: text_textarea
-    weight: 7
+    weight: 10
     region: content
     settings:
       rows: 5
       placeholder: ''
     third_party_settings: {  }
+  oe_cx_gallery:
+    type: entity_reference_autocomplete
+    weight: 11
+    region: content
+    settings:
+      match_operator: CONTAINS
+      match_limit: 10
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
   oe_cx_impacts:
     type: text_textarea
-    weight: 5
+    weight: 9
     region: content
     settings:
       rows: 5
       placeholder: ''
     third_party_settings: {  }
+  oe_cx_lead_contributors:
+    type: inline_entity_form_complex
+    weight: 6
+    region: content
+    settings:
+      form_mode: default
+      override_labels: false
+      label_singular: ''
+      label_plural: ''
+      allow_new: true
+      allow_existing: false
+      match_operator: CONTAINS
+      allow_duplicate: false
+      collapsible: false
+      collapsed: false
+      revision: false
+      removed_reference: optional
+    third_party_settings: {  }
   oe_cx_objective:
     type: text_textarea
-    weight: 4
+    weight: 8
     region: content
     settings:
       rows: 5
       placeholder: ''
     third_party_settings: {  }
+  oe_documents:
+    type: entity_reference_autocomplete
+    weight: 2
+    region: content
+    settings:
+      match_operator: CONTAINS
+      match_limit: 10
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
   oe_featured_media:
     type: oe_featured_media_autocomplete
-    weight: 8
+    weight: 12
     region: content
     settings:
       match_operator: CONTAINS
@@ -162,6 +200,24 @@ content:
     settings:
       placeholder: ''
     third_party_settings: {  }
+  oe_project_coordinators:
+    type: inline_entity_form_complex
+    weight: 15
+    region: content
+    settings:
+      form_mode: default
+      override_labels: false
+      label_singular: ''
+      label_plural: ''
+      allow_new: true
+      allow_existing: false
+      match_operator: CONTAINS
+      allow_duplicate: false
+      collapsible: false
+      collapsed: false
+      revision: false
+      removed_reference: optional
+    third_party_settings: {  }
   oe_project_dates:
     type: daterange_datelist
     weight: 5
@@ -171,15 +227,19 @@ content:
       date_order: DMY
       time_type: none
     third_party_settings: {  }
-  oe_project_locations:
-    type: address_default
+  oe_project_funding_programme:
+    type: skos_concept_entity_reference_autocomplete
     weight: 8
     region: content
-    settings: {  }
+    settings:
+      match_operator: CONTAINS
+      match_limit: 10
+      size: 60
+      placeholder: ''
     third_party_settings: {  }
   oe_project_participants:
     type: inline_entity_form_complex
-    weight: 6
+    weight: 5
     region: content
     settings:
       form_mode: default
@@ -195,6 +255,24 @@ content:
       revision: true
       removed_reference: keep
     third_party_settings: {  }
+  oe_project_result_files:
+    type: entity_reference_autocomplete
+    weight: 0
+    region: content
+    settings:
+      match_operator: CONTAINS
+      match_limit: 10
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+  oe_project_results:
+    type: text_textarea
+    weight: 0
+    region: content
+    settings:
+      rows: 5
+      placeholder: ''
+    third_party_settings: {  }
   oe_project_website:
     type: link_default
     weight: 7
@@ -215,7 +293,7 @@ content:
     third_party_settings: {  }
   oe_summary:
     type: text_textarea
-    weight: 3
+    weight: 7
     region: content
     settings:
       rows: 5
@@ -223,7 +301,7 @@ content:
     third_party_settings: {  }
   oe_teaser:
     type: text_textarea
-    weight: 10
+    weight: 14
     region: content
     settings:
       rows: 5
@@ -231,7 +309,7 @@ content:
     third_party_settings: {  }
   status:
     type: boolean_checkbox
-    weight: 9
+    weight: 13
     region: content
     settings:
       display_label: true
@@ -257,16 +335,10 @@ hidden:
   oe_content_legacy_link: true
   oe_content_navigation_title: true
   oe_content_short_title: true
-  oe_cx_gallery: true
-  oe_cx_lead_contributors: true
   oe_departments: true
-  oe_documents: true
   oe_project_calls: true
   oe_project_contact: true
-  oe_project_coordinators: true
-  oe_project_funding_programme: true
-  oe_project_result_files: true
-  oe_project_results: true
+  oe_project_locations: true
   oe_reference_code: true
   path: true
   promote: true
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
index 80fe48bf..2980cb51 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
@@ -30,11 +30,11 @@ dependencies:
     - field.field.node.oe_project.oe_teaser
     - node.type.oe_project
   module:
-    - address
     - datetime_range
     - entity_reference_revisions
     - field_group
     - link
+    - rdf_skos
     - text
     - user
 third_party_settings:
@@ -42,10 +42,11 @@ third_party_settings:
     group_stakeholders:
       children:
         - oe_project_participants
+        - oe_cx_lead_contributors
       label: Stakeholders
       parent_name: ''
       region: content
-      weight: 5
+      weight: 8
       format_type: html_element
       format_settings:
         classes: ''
@@ -59,15 +60,14 @@ third_party_settings:
         speed: fast
     group_project_details:
       children:
-        - oe_project_dates
-        - oe_project_budget
-        - oe_project_budget_eu
+        - group_period
+        - group_budget
         - oe_project_website
-        - oe_project_locations
+        - oe_project_funding_programme
       label: 'Project details'
       parent_name: ''
       region: content
-      weight: 0
+      weight: 1
       format_type: html_element
       format_settings:
         classes: ''
@@ -80,6 +80,64 @@ third_party_settings:
         attributes: ''
         effect: none
         speed: fast
+    group_coordinators:
+      children:
+        - oe_project_coordinators
+      label: Coordinators
+      parent_name: ''
+      region: content
+      weight: 2
+      format_type: html_element
+      format_settings:
+        classes: ''
+        show_empty_fields: false
+        id: ''
+        element: div
+        show_label: false
+        label_element: h3
+        label_element_classes: ''
+        attributes: ''
+        effect: none
+        speed: fast
+    group_period:
+      children:
+        - oe_project_dates
+      label: Period
+      parent_name: group_project_details
+      region: content
+      weight: 0
+      format_type: html_element
+      format_settings:
+        classes: ''
+        show_empty_fields: false
+        id: ''
+        element: div
+        show_label: false
+        label_element: h3
+        label_element_classes: ''
+        attributes: ''
+        effect: none
+        speed: fast
+    group_budget:
+      children:
+        - oe_project_budget
+        - oe_project_budget_eu
+      label: Budget
+      parent_name: group_project_details
+      region: content
+      weight: 1
+      format_type: html_element
+      format_settings:
+        classes: ''
+        show_empty_fields: false
+        id: ''
+        element: div
+        show_label: false
+        label_element: h3
+        label_element_classes: ''
+        attributes: ''
+        effect: none
+        speed: fast
 id: node.oe_project.full
 targetEntityType: node
 bundle: oe_project
@@ -90,21 +148,30 @@ content:
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 6
+    weight: 9
     region: content
   oe_cx_impacts:
     type: text_default
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 4
+    weight: 7
+    region: content
+  oe_cx_lead_contributors:
+    type: entity_reference_revisions_entity_view
+    label: above
+    settings:
+      view_mode: default
+      link: ''
+    third_party_settings: {  }
+    weight: 13
     region: content
   oe_cx_objective:
     type: text_default
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 3
+    weight: 6
     region: content
   oe_project_budget:
     type: number_decimal
@@ -128,20 +195,30 @@ content:
     third_party_settings: {  }
     weight: 3
     region: content
+  oe_project_coordinators:
+    type: entity_reference_revisions_entity_view
+    label: inline
+    settings:
+      view_mode: coordinators
+      link: ''
+    third_party_settings: {  }
+    weight: 7
+    region: content
   oe_project_dates:
-    type: daterange_default
+    type: daterange_custom
     label: above
     settings:
       timezone_override: ''
-      format_type: medium
+      date_format: d/m/Y
       separator: '-'
     third_party_settings: {  }
     weight: 1
     region: content
-  oe_project_locations:
-    type: address_default
+  oe_project_funding_programme:
+    type: skos_concept_entity_reference_label
     label: above
-    settings: {  }
+    settings:
+      link: true
     third_party_settings: {  }
     weight: 5
     region: content
@@ -152,7 +229,7 @@ content:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 7
+    weight: 12
     region: content
   oe_project_website:
     type: link
@@ -166,19 +243,27 @@ content:
     third_party_settings: {  }
     weight: 4
     region: content
+  oe_subject:
+    type: skos_concept_entity_reference_label
+    label: above
+    settings:
+      link: false
+    third_party_settings: {  }
+    weight: 4
+    region: content
   oe_summary:
     type: text_default
     label: above
     settings: {  }
     third_party_settings: {  }
-    weight: 2
+    weight: 5
     region: content
   oe_teaser:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 1
+    weight: 3
     region: content
 hidden:
   body: true
@@ -189,15 +274,12 @@ hidden:
   oe_content_navigation_title: true
   oe_content_short_title: true
   oe_cx_gallery: true
-  oe_cx_lead_contributors: true
   oe_departments: true
   oe_documents: true
   oe_featured_media: true
   oe_project_calls: true
   oe_project_contact: true
-  oe_project_coordinators: true
-  oe_project_funding_programme: true
+  oe_project_locations: true
   oe_project_result_files: true
   oe_project_results: true
   oe_reference_code: true
-  oe_subject: true
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
index beb93b00..f8360f5a 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
@@ -24,6 +24,14 @@ content:
     third_party_settings: {  }
     weight: 0
     region: content
+  oe_acronym:
+    type: string
+    label: visually_hidden
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+    weight: 2
+    region: content
   oe_address:
     type: oe_whitelabel_helper_address_inline
     label: above
@@ -41,12 +49,11 @@ content:
       scale: 2
       prefix_suffix: true
     third_party_settings: {  }
-    weight: 2
+    weight: 3
     region: content
 hidden:
   created: true
   langcode: true
-  oe_acronym: true
   oe_contact_url: true
   oe_logo: true
   oe_website: true
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
index 8f5b3d0c..59a0bcfe 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
@@ -6,3 +6,8 @@ core_version_requirement: ^9.2
 dependencies:
   - oe_content_extra:oe_content_extra_project
   - oe_whitelabel_helper:oe_whitelabel_helper
+
+config_devel:
+  install:
+    - core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.coordinators
+    - core.entity_view_mode.oe_organisation.coordinators
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 207e87b6..a2247e9b 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -99,6 +99,7 @@ function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables):
 
   $variables['inpage_navigation_links'] = [];
   $fields = [
+    'oe_project_dates',
     'oe_summary',
     'oe_cx_objective',
     'oe_cx_impacts',
diff --git a/modules/oe_whitelabel_extra_project/templates/field--node--oe-cx-lead-contributors--oe-project.html.twig b/modules/oe_whitelabel_extra_project/templates/field--node--oe-cx-lead-contributors--oe-project.html.twig
new file mode 100644
index 00000000..6d5f465d
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/templates/field--node--oe-cx-lead-contributors--oe-project.html.twig
@@ -0,0 +1,20 @@
+{#
+/**
+ * @file
+ * Project participants field template.
+ *
+ * @see ./core/themes/stable/templates/field/field.html.twig
+ */
+#}
+{% set _title = 'Lead contributors'|t %}
+<h3 id="oe-project-oe-project-participants" class="fw-bold my-4">
+  {{ _title }}
+</h3>
+
+<div class="ecl-row">
+  {% for item in items %}
+    <div class="ecl-col-12 ecl-col-m-6">
+      {{ item.content }}
+    </div>
+  {% endfor %}
+</div>
diff --git a/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-coordinators--oe-project.html.twig b/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-coordinators--oe-project.html.twig
new file mode 100644
index 00000000..0e568840
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-coordinators--oe-project.html.twig
@@ -0,0 +1,14 @@
+{#
+/**
+ * @file
+ * Organisation teaser.
+ */
+#}
+<dl class="fw-bold mb-4 mt-3 mb-4 d-md-grid grid-3-9">
+  <dd>{{ label }}</dd>
+  <div>
+    <dt>
+      {{ element }}
+    </dt>
+  </div>
+</dl>
diff --git a/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-participants--oe-project.html.twig b/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-participants--oe-project.html.twig
index e27e7231..29c32398 100644
--- a/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-participants--oe-project.html.twig
+++ b/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-participants--oe-project.html.twig
@@ -6,7 +6,7 @@
  * @see ./core/themes/stable/templates/field/field.html.twig
  */
 #}
-{% set _title = 'Contributors'|t %}
+{% set _title = 'Participants'|t %}
 <h3 id="oe-project-oe-project-participants" class="fw-bold my-4">
   {{ _title }}
 </h3>
diff --git a/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-budget.html.twig b/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-budget.html.twig
new file mode 100644
index 00000000..e806f27d
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-budget.html.twig
@@ -0,0 +1,23 @@
+{#
+/**
+ * @file
+ * Stakeholders field group theme implementation.
+ *
+ * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
+ */
+#}
+  {% set _items = [] %}
+  {% for _field in element if _key|first != '#' and _field|field_value %}
+    {% set _value %}
+      {{ _field|field_value }}
+    {% endset %}
+    {% set _items = _items|merge([{
+      term: _field|field_label,
+      definition: _value,
+    }]) %}
+  {% endfor %}
+  {{ pattern('description_list', {
+    items: _items,
+    orientation: 'horizontal',
+    attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
+  }) }}
diff --git a/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-period.html.twig b/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-period.html.twig
new file mode 100644
index 00000000..e806f27d
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-period.html.twig
@@ -0,0 +1,23 @@
+{#
+/**
+ * @file
+ * Stakeholders field group theme implementation.
+ *
+ * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
+ */
+#}
+  {% set _items = [] %}
+  {% for _field in element if _key|first != '#' and _field|field_value %}
+    {% set _value %}
+      {{ _field|field_value }}
+    {% endset %}
+    {% set _items = _items|merge([{
+      term: _field|field_label,
+      definition: _value,
+    }]) %}
+  {% endfor %}
+  {{ pattern('description_list', {
+    items: _items,
+    orientation: 'horizontal',
+    attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
+  }) }}
diff --git a/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-project-details.html.twig b/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-project-details.html.twig
new file mode 100644
index 00000000..f8db50dd
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-project-details.html.twig
@@ -0,0 +1,33 @@
+{#
+/**
+ * @file
+ * Stakeholders field group theme implementation.
+ *
+ * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
+ */
+#}
+
+<div id="project-stakeholders" class="ecl-u-mt-3xl">
+  {% if title %}
+    <h3 id="oe-project-oe-project-dates" class="fw-bold mb-4">
+      {{ title }}
+    </h3>
+    {{ element.group_period }}
+    {{ element.group_budget }}
+  {% endif %}
+  {% set _items = [] %}
+  {% for _field in element if _key|first != '#' and _field|field_value %}
+    {% set _value %}
+      {{ _field|field_value }}
+    {% endset %}
+    {% set _items = _items|merge([{
+      term: _field|field_label,
+      definition: _value,
+    }]) %}
+  {% endfor %}
+  {{ pattern('description_list', {
+    items: _items,
+    orientation: 'horizontal',
+    attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
+  }) }}
+</div>
diff --git a/modules/oe_whitelabel_extra_project/templates/node--oe-project--full.html.twig b/modules/oe_whitelabel_extra_project/templates/node--oe-project--full.html.twig
index 686f2a11..7a69cd48 100644
--- a/modules/oe_whitelabel_extra_project/templates/node--oe-project--full.html.twig
+++ b/modules/oe_whitelabel_extra_project/templates/node--oe-project--full.html.twig
@@ -19,6 +19,8 @@
   badges: [_badge],
 }) }}
 {% set inpage_navigation_fields %}
+  {{ content.group_project_details }}
+  {{ content.group_coordinators }}
   {{ content.oe_summary }}
   {{ content.oe_cx_objective }}
   {{ content.oe_cx_impacts }}
diff --git a/modules/oe_whitelabel_extra_project/templates/oe-organisation--oe-stakeholder--coordinators.html.twig b/modules/oe_whitelabel_extra_project/templates/oe-organisation--oe-stakeholder--coordinators.html.twig
new file mode 100644
index 00000000..002c7220
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/templates/oe-organisation--oe-stakeholder--coordinators.html.twig
@@ -0,0 +1,9 @@
+{#
+/**
+ * @file
+ * coordinators field group theme implementation.
+ *
+ * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
+ */
+#}
+{{ elements.name }}
diff --git a/modules/oe_whitelabel_extra_project/templates/oe-organisation.html.twig b/modules/oe_whitelabel_extra_project/templates/oe-organisation.html.twig
index c1a620f6..970b901e 100644
--- a/modules/oe_whitelabel_extra_project/templates/oe-organisation.html.twig
+++ b/modules/oe_whitelabel_extra_project/templates/oe-organisation.html.twig
@@ -13,7 +13,7 @@
       {% set _items = [] %}
       {% for _field in elements if _key|first != '#' and _field|field_value %}
         {% set _value %}
-          {{ _field|field_value|safe_join(', ') }}
+          {{ _field|field_value }}
         {% endset %}
         {% set _items = _items|merge([{
           term: _field|field_label,
@@ -23,7 +23,7 @@
         {{ pattern('description_list', {
           items: _items,
           orientation: 'horizontal',
-          attributes: create_attribute().addClass(['mt-3', 'mb-4']),
+          attributes: create_attribute().addClass(['border-bottom', 'mt-3', 'mb-4']),
         }) }}
     </div>
   </article>
-- 
GitLab


From 217a2152572dc11a7c26b5817bf30e8f455b7d32 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Wed, 30 Mar 2022 10:06:39 +0200
Subject: [PATCH 008/152] OEL-1297: Templates moved, default viewmode removed.

---
 ...y_view_display.node.oe_project.default.yml | 153 ------------------
 .../oe_whitelabel_extra_project.module        |   4 -
 ...on--oe-stakeholder--coordinators.html.twig |   9 --
 ...cx-lead-contributors--oe-project.html.twig |   6 +-
 ...project-coordinators--oe-project.html.twig |   4 +-
 ...project-participants--oe-project.html.twig |   0
 ...--node--oe-project--group-budget.html.twig |   2 +-
 ...--node--oe-project--group-period.html.twig |   2 +-
 ...e-project--group-project-details.html.twig |   4 +-
 .../content}/node--oe-project--full.html.twig |   0
 ...on--oe-stakeholder--coordinators.html.twig |   7 +
 .../content}/oe-organisation.html.twig        |   2 +-
 12 files changed, 18 insertions(+), 175 deletions(-)
 delete mode 100644 modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.default.yml
 delete mode 100644 modules/oe_whitelabel_extra_project/templates/oe-organisation--oe-stakeholder--coordinators.html.twig
 rename {modules/oe_whitelabel_extra_project/templates => templates/overrides/content}/field--node--oe-cx-lead-contributors--oe-project.html.twig (74%)
 rename {modules/oe_whitelabel_extra_project/templates => templates/overrides/content}/field--node--oe-project-coordinators--oe-project.html.twig (62%)
 rename {modules/oe_whitelabel_extra_project/templates => templates/overrides/content}/field--node--oe-project-participants--oe-project.html.twig (100%)
 rename {modules/oe_whitelabel_extra_project/templates => templates/overrides/content}/field-group-html-element--node--oe-project--group-budget.html.twig (91%)
 rename {modules/oe_whitelabel_extra_project/templates => templates/overrides/content}/field-group-html-element--node--oe-project--group-period.html.twig (91%)
 rename {modules/oe_whitelabel_extra_project/templates => templates/overrides/content}/field-group-html-element--node--oe-project--group-project-details.html.twig (88%)
 rename {modules/oe_whitelabel_extra_project/templates => templates/overrides/content}/node--oe-project--full.html.twig (100%)
 create mode 100644 templates/overrides/content/oe-organisation--oe-stakeholder--coordinators.html.twig
 rename {modules/oe_whitelabel_extra_project/templates => templates/overrides/content}/oe-organisation.html.twig (96%)

diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.default.yml
deleted file mode 100644
index 18b1feb6..00000000
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.default.yml
+++ /dev/null
@@ -1,153 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.field.node.oe_project.body
-    - field.field.node.oe_project.oe_cx_achievements_and_milestone
-    - field.field.node.oe_project.oe_cx_gallery
-    - field.field.node.oe_project.oe_cx_impacts
-    - field.field.node.oe_project.oe_cx_lead_contributors
-    - field.field.node.oe_project.oe_cx_objective
-    - field.field.node.oe_project.oe_departments
-    - field.field.node.oe_project.oe_documents
-    - field.field.node.oe_project.oe_featured_media
-    - field.field.node.oe_project.oe_project_budget
-    - field.field.node.oe_project.oe_project_budget_eu
-    - field.field.node.oe_project.oe_project_calls
-    - field.field.node.oe_project.oe_project_contact
-    - field.field.node.oe_project.oe_project_coordinators
-    - field.field.node.oe_project.oe_project_dates
-    - field.field.node.oe_project.oe_project_funding_programme
-    - field.field.node.oe_project.oe_project_locations
-    - field.field.node.oe_project.oe_project_participants
-    - field.field.node.oe_project.oe_project_result_files
-    - field.field.node.oe_project.oe_project_results
-    - field.field.node.oe_project.oe_project_website
-    - field.field.node.oe_project.oe_reference_code
-    - field.field.node.oe_project.oe_subject
-    - field.field.node.oe_project.oe_summary
-    - field.field.node.oe_project.oe_teaser
-    - node.type.oe_project
-  module:
-    - address
-    - entity_reference_revisions
-    - field_group
-    - rdf_skos
-    - text
-    - user
-third_party_settings:
-  field_group:
-    group_stakeholders:
-      children:
-        - oe_project_participants
-      label: Stakeholders
-      parent_name: ''
-      region: content
-      weight: 6
-      format_type: html_element
-      format_settings:
-        classes: ''
-        id: ''
-        element: div
-        show_label: false
-        label_element: h3
-        label_element_classes: ''
-        attributes: ''
-        effect: none
-        speed: fast
-id: node.oe_project.default
-targetEntityType: node
-bundle: oe_project
-mode: default
-content:
-  oe_cx_achievements_and_milestone:
-    type: text_default
-    label: above
-    settings: {  }
-    third_party_settings: {  }
-    weight: 8
-    region: content
-  oe_cx_gallery:
-    type: entity_reference_entity_view
-    label: above
-    settings:
-      view_mode: default
-      link: false
-    third_party_settings: {  }
-    weight: 9
-    region: content
-  oe_cx_impacts:
-    type: text_default
-    label: above
-    settings: {  }
-    third_party_settings: {  }
-    weight: 5
-    region: content
-  oe_cx_objective:
-    type: text_default
-    label: above
-    settings: {  }
-    third_party_settings: {  }
-    weight: 4
-    region: content
-  oe_project_locations:
-    type: address_default
-    label: above
-    settings: {  }
-    third_party_settings: {  }
-    weight: 0
-    region: content
-  oe_project_participants:
-    type: entity_reference_revisions_entity_view
-    label: above
-    settings:
-      view_mode: default
-      link: ''
-    third_party_settings: {  }
-    weight: 7
-    region: content
-  oe_subject:
-    type: skos_concept_entity_reference_label
-    label: hidden
-    settings:
-      link: false
-    third_party_settings: {  }
-    weight: 1
-    region: content
-  oe_summary:
-    type: text_default
-    label: above
-    settings: {  }
-    third_party_settings: {  }
-    weight: 2
-    region: content
-  oe_teaser:
-    type: text_default
-    label: hidden
-    settings: {  }
-    third_party_settings: {  }
-    weight: 3
-    region: content
-hidden:
-  body: true
-  langcode: true
-  links: true
-  oe_content_content_owner: true
-  oe_content_legacy_link: true
-  oe_content_navigation_title: true
-  oe_content_short_title: true
-  oe_cx_lead_contributors: true
-  oe_departments: true
-  oe_documents: true
-  oe_featured_media: true
-  oe_project_budget: true
-  oe_project_budget_eu: true
-  oe_project_calls: true
-  oe_project_contact: true
-  oe_project_coordinators: true
-  oe_project_dates: true
-  oe_project_funding_programme: true
-  oe_project_result_files: true
-  oe_project_results: true
-  oe_project_website: true
-  oe_reference_code: true
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index a2247e9b..f2f7822e 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -29,10 +29,6 @@ function oe_whitelabel_extra_project_preprocess_node__oe_project(&$variables) {
  * Implements hook_preprocess().
  */
 function _oe_whitelabel_extra_project_preprocess_featured_media(&$variables) {
-  if ($variables['view_mode'] !== 'full' && $variables['view_mode'] !== 'teaser') {
-    return;
-  }
-
   /** @var \Drupal\node\NodeInterface $node */
   $node = $variables['node'];
 
diff --git a/modules/oe_whitelabel_extra_project/templates/oe-organisation--oe-stakeholder--coordinators.html.twig b/modules/oe_whitelabel_extra_project/templates/oe-organisation--oe-stakeholder--coordinators.html.twig
deleted file mode 100644
index 002c7220..00000000
--- a/modules/oe_whitelabel_extra_project/templates/oe-organisation--oe-stakeholder--coordinators.html.twig
+++ /dev/null
@@ -1,9 +0,0 @@
-{#
-/**
- * @file
- * coordinators field group theme implementation.
- *
- * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
- */
-#}
-{{ elements.name }}
diff --git a/modules/oe_whitelabel_extra_project/templates/field--node--oe-cx-lead-contributors--oe-project.html.twig b/templates/overrides/content/field--node--oe-cx-lead-contributors--oe-project.html.twig
similarity index 74%
rename from modules/oe_whitelabel_extra_project/templates/field--node--oe-cx-lead-contributors--oe-project.html.twig
rename to templates/overrides/content/field--node--oe-cx-lead-contributors--oe-project.html.twig
index 6d5f465d..06552d72 100644
--- a/modules/oe_whitelabel_extra_project/templates/field--node--oe-cx-lead-contributors--oe-project.html.twig
+++ b/templates/overrides/content/field--node--oe-cx-lead-contributors--oe-project.html.twig
@@ -1,7 +1,7 @@
 {#
 /**
  * @file
- * Project participants field template.
+ * Lead contributors field template.
  *
  * @see ./core/themes/stable/templates/field/field.html.twig
  */
@@ -11,9 +11,9 @@
   {{ _title }}
 </h3>
 
-<div class="ecl-row">
+<div class="bcl-row">
   {% for item in items %}
-    <div class="ecl-col-12 ecl-col-m-6">
+    <div class="bcl-col-12 bcl-col-m-6">
       {{ item.content }}
     </div>
   {% endfor %}
diff --git a/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-coordinators--oe-project.html.twig b/templates/overrides/content/field--node--oe-project-coordinators--oe-project.html.twig
similarity index 62%
rename from modules/oe_whitelabel_extra_project/templates/field--node--oe-project-coordinators--oe-project.html.twig
rename to templates/overrides/content/field--node--oe-project-coordinators--oe-project.html.twig
index 0e568840..9b0f8525 100644
--- a/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-coordinators--oe-project.html.twig
+++ b/templates/overrides/content/field--node--oe-project-coordinators--oe-project.html.twig
@@ -1,7 +1,9 @@
 {#
 /**
  * @file
- * Organisation teaser.
+ * Contributors field template.
+ *
+ * @see ./core/themes/stable/templates/field/field.html.twig
  */
 #}
 <dl class="fw-bold mb-4 mt-3 mb-4 d-md-grid grid-3-9">
diff --git a/modules/oe_whitelabel_extra_project/templates/field--node--oe-project-participants--oe-project.html.twig b/templates/overrides/content/field--node--oe-project-participants--oe-project.html.twig
similarity index 100%
rename from modules/oe_whitelabel_extra_project/templates/field--node--oe-project-participants--oe-project.html.twig
rename to templates/overrides/content/field--node--oe-project-participants--oe-project.html.twig
diff --git a/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-budget.html.twig b/templates/overrides/content/field-group-html-element--node--oe-project--group-budget.html.twig
similarity index 91%
rename from modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-budget.html.twig
rename to templates/overrides/content/field-group-html-element--node--oe-project--group-budget.html.twig
index e806f27d..bb833f21 100644
--- a/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-budget.html.twig
+++ b/templates/overrides/content/field-group-html-element--node--oe-project--group-budget.html.twig
@@ -1,7 +1,7 @@
 {#
 /**
  * @file
- * Stakeholders field group theme implementation.
+ * Budget field group theme implementation.
  *
  * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
  */
diff --git a/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-period.html.twig b/templates/overrides/content/field-group-html-element--node--oe-project--group-period.html.twig
similarity index 91%
rename from modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-period.html.twig
rename to templates/overrides/content/field-group-html-element--node--oe-project--group-period.html.twig
index e806f27d..20e57540 100644
--- a/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-period.html.twig
+++ b/templates/overrides/content/field-group-html-element--node--oe-project--group-period.html.twig
@@ -1,7 +1,7 @@
 {#
 /**
  * @file
- * Stakeholders field group theme implementation.
+ * Period field group theme implementation.
  *
  * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
  */
diff --git a/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-project-details.html.twig b/templates/overrides/content/field-group-html-element--node--oe-project--group-project-details.html.twig
similarity index 88%
rename from modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-project-details.html.twig
rename to templates/overrides/content/field-group-html-element--node--oe-project--group-project-details.html.twig
index f8db50dd..d055973d 100644
--- a/modules/oe_whitelabel_extra_project/templates/field-group-html-element--node--oe-project--group-project-details.html.twig
+++ b/templates/overrides/content/field-group-html-element--node--oe-project--group-project-details.html.twig
@@ -1,13 +1,13 @@
 {#
 /**
  * @file
- * Stakeholders field group theme implementation.
+ * Details field group theme implementation.
  *
  * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
  */
 #}
 
-<div id="project-stakeholders" class="ecl-u-mt-3xl">
+<div id="project-details" class="ecl-u-mt-3xl">
   {% if title %}
     <h3 id="oe-project-oe-project-dates" class="fw-bold mb-4">
       {{ title }}
diff --git a/modules/oe_whitelabel_extra_project/templates/node--oe-project--full.html.twig b/templates/overrides/content/node--oe-project--full.html.twig
similarity index 100%
rename from modules/oe_whitelabel_extra_project/templates/node--oe-project--full.html.twig
rename to templates/overrides/content/node--oe-project--full.html.twig
diff --git a/templates/overrides/content/oe-organisation--oe-stakeholder--coordinators.html.twig b/templates/overrides/content/oe-organisation--oe-stakeholder--coordinators.html.twig
new file mode 100644
index 00000000..45f36ef1
--- /dev/null
+++ b/templates/overrides/content/oe-organisation--oe-stakeholder--coordinators.html.twig
@@ -0,0 +1,7 @@
+{#
+/**
+ * @file
+ * Coordinator organisation teaser template.
+ */
+#}
+{{ elements.name }}
diff --git a/modules/oe_whitelabel_extra_project/templates/oe-organisation.html.twig b/templates/overrides/content/oe-organisation.html.twig
similarity index 96%
rename from modules/oe_whitelabel_extra_project/templates/oe-organisation.html.twig
rename to templates/overrides/content/oe-organisation.html.twig
index 970b901e..d94c738f 100644
--- a/modules/oe_whitelabel_extra_project/templates/oe-organisation.html.twig
+++ b/templates/overrides/content/oe-organisation.html.twig
@@ -1,7 +1,7 @@
 {#
 /**
  * @file
- * Organisation teaser.
+ * Organisation teaser template.
  */
 #}
 {% spaceless %}
-- 
GitLab


From 8b7aaf29140824c8417d7012a281554a0ee7215c Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Wed, 30 Mar 2022 11:11:21 +0200
Subject: [PATCH 009/152] OEL-1297: Ecl classes on templates removed.

---
 ...cx-lead-contributors--oe-project.html.twig | 20 -------------------
 ...project-participants--oe-project.html.twig | 20 -------------------
 2 files changed, 40 deletions(-)
 delete mode 100644 templates/overrides/content/field--node--oe-cx-lead-contributors--oe-project.html.twig
 delete mode 100644 templates/overrides/content/field--node--oe-project-participants--oe-project.html.twig

diff --git a/templates/overrides/content/field--node--oe-cx-lead-contributors--oe-project.html.twig b/templates/overrides/content/field--node--oe-cx-lead-contributors--oe-project.html.twig
deleted file mode 100644
index 06552d72..00000000
--- a/templates/overrides/content/field--node--oe-cx-lead-contributors--oe-project.html.twig
+++ /dev/null
@@ -1,20 +0,0 @@
-{#
-/**
- * @file
- * Lead contributors field template.
- *
- * @see ./core/themes/stable/templates/field/field.html.twig
- */
-#}
-{% set _title = 'Lead contributors'|t %}
-<h3 id="oe-project-oe-project-participants" class="fw-bold my-4">
-  {{ _title }}
-</h3>
-
-<div class="bcl-row">
-  {% for item in items %}
-    <div class="bcl-col-12 bcl-col-m-6">
-      {{ item.content }}
-    </div>
-  {% endfor %}
-</div>
diff --git a/templates/overrides/content/field--node--oe-project-participants--oe-project.html.twig b/templates/overrides/content/field--node--oe-project-participants--oe-project.html.twig
deleted file mode 100644
index 29c32398..00000000
--- a/templates/overrides/content/field--node--oe-project-participants--oe-project.html.twig
+++ /dev/null
@@ -1,20 +0,0 @@
-{#
-/**
- * @file
- * Project participants field template.
- *
- * @see ./core/themes/stable/templates/field/field.html.twig
- */
-#}
-{% set _title = 'Participants'|t %}
-<h3 id="oe-project-oe-project-participants" class="fw-bold my-4">
-  {{ _title }}
-</h3>
-
-<div class="ecl-row">
-  {% for item in items %}
-    <div class="ecl-col-12 ecl-col-m-6">
-      {{ item.content }}
-    </div>
-  {% endfor %}
-</div>
-- 
GitLab


From 7c1ae1308fa8c8cb3a835bf8ce522f4d42a3e529 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Wed, 30 Mar 2022 11:42:56 +0200
Subject: [PATCH 010/152] OEL-1297: Improvements on templates.

---
 ...project-coordinators--oe-project.html.twig |  4 +--
 ...e-project--group-project-details.html.twig |  3 --
 .../oe-organisation--default.html.twig        | 25 ++++++++++++++++
 .../content/oe-organisation.html.twig         | 30 -------------------
 4 files changed, 27 insertions(+), 35 deletions(-)
 create mode 100644 templates/overrides/content/oe-organisation--default.html.twig
 delete mode 100644 templates/overrides/content/oe-organisation.html.twig

diff --git a/templates/overrides/content/field--node--oe-project-coordinators--oe-project.html.twig b/templates/overrides/content/field--node--oe-project-coordinators--oe-project.html.twig
index 9b0f8525..453f5fea 100644
--- a/templates/overrides/content/field--node--oe-project-coordinators--oe-project.html.twig
+++ b/templates/overrides/content/field--node--oe-project-coordinators--oe-project.html.twig
@@ -9,8 +9,8 @@
 <dl class="fw-bold mb-4 mt-3 mb-4 d-md-grid grid-3-9">
   <dd>{{ label }}</dd>
   <div>
-    <dt>
+    <dd>
       {{ element }}
-    </dt>
+    </dd>
   </div>
 </dl>
diff --git a/templates/overrides/content/field-group-html-element--node--oe-project--group-project-details.html.twig b/templates/overrides/content/field-group-html-element--node--oe-project--group-project-details.html.twig
index d055973d..5ab0910b 100644
--- a/templates/overrides/content/field-group-html-element--node--oe-project--group-project-details.html.twig
+++ b/templates/overrides/content/field-group-html-element--node--oe-project--group-project-details.html.twig
@@ -6,8 +6,6 @@
  * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
  */
 #}
-
-<div id="project-details" class="ecl-u-mt-3xl">
   {% if title %}
     <h3 id="oe-project-oe-project-dates" class="fw-bold mb-4">
       {{ title }}
@@ -30,4 +28,3 @@
     orientation: 'horizontal',
     attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
   }) }}
-</div>
diff --git a/templates/overrides/content/oe-organisation--default.html.twig b/templates/overrides/content/oe-organisation--default.html.twig
new file mode 100644
index 00000000..15d784c5
--- /dev/null
+++ b/templates/overrides/content/oe-organisation--default.html.twig
@@ -0,0 +1,25 @@
+{#
+/**
+ * @file
+ * Organisation default teaser template.
+ */
+#}
+<h4 class="fw-bold mb-3">
+  {% if elements.oe_acronym is not empty %} {{ elements.oe_acronym }}{% endif %}
+</h4>
+{% set _items = [] %}
+{% for _field in elements if _key|first != '#' and _field|field_value %}
+  {% set _value %}
+    {{ _field|field_value }}
+  {% endset %}
+  {% set _items = _items|merge([{
+    term: _field|field_label,
+    definition: _value,
+  }]) %}
+{% endfor %}
+  {{ pattern('description_list', {
+    items: _items,
+    orientation: 'horizontal',
+    attributes: create_attribute().addClass(['border-bottom', 'mt-3', 'mb-4']),
+  }) }}
+
diff --git a/templates/overrides/content/oe-organisation.html.twig b/templates/overrides/content/oe-organisation.html.twig
deleted file mode 100644
index d94c738f..00000000
--- a/templates/overrides/content/oe-organisation.html.twig
+++ /dev/null
@@ -1,30 +0,0 @@
-{#
-/**
- * @file
- * Organisation teaser template.
- */
-#}
-{% spaceless %}
-  <article class="ecl-u-mb-l ecl-u-border-bottom ecl-u-border-width-3 ecl-u-border-color-grey-15 ecl-content-item ecl-u-d-flex ecl-u-pb-m">
-    <div class="ecl-u-flex-grow-1 ecl-u-type-color-grey">
-      <h4 class="ecl-u-type-heading-4 ecl-u-mb-s ecl-u-mt-none">
-        {% if elements.oe_acronym is not empty %} {{ elements.oe_acronym }}{% endif %}
-      </h4>
-      {% set _items = [] %}
-      {% for _field in elements if _key|first != '#' and _field|field_value %}
-        {% set _value %}
-          {{ _field|field_value }}
-        {% endset %}
-        {% set _items = _items|merge([{
-          term: _field|field_label,
-          definition: _value,
-        }]) %}
-      {% endfor %}
-        {{ pattern('description_list', {
-          items: _items,
-          orientation: 'horizontal',
-          attributes: create_attribute().addClass(['border-bottom', 'mt-3', 'mb-4']),
-        }) }}
-    </div>
-  </article>
-{% endspaceless %}
-- 
GitLab


From 075c8230370b2c983baae0a71a7b92ec004f493c Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Wed, 30 Mar 2022 11:54:15 +0200
Subject: [PATCH 011/152] OEL-1297: Default viewmode for oe_project entity
 removed.

---
 .../oe_whitelabel_extra_project.install                          | 1 -
 1 file changed, 1 deletion(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
index 3b2218c8..aacc3c4f 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
@@ -23,7 +23,6 @@ function oe_whitelabel_extra_project_install($is_syncing): void {
   $configs = [
     'core.entity_form_display.node.oe_project.default',
     'core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default',
-    'core.entity_view_display.node.oe_project.default',
     'core.entity_view_display.node.oe_project.full',
     'core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default',
     'field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget',
-- 
GitLab


From 9764aa33b1be8521df7cd8d394abbaf2afd01660 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Thu, 31 Mar 2022 02:06:28 +0200
Subject: [PATCH 012/152] OEL-1297: Templates improved, tests added.

---
 composer.json                                 |   5 +
 ...oe_cx_project_stakeholder.coordinators.yml |  35 --
 ...ay.oe_organisation.oe_stakeholder.name.yml |  33 ++
 ...entity_view_mode.oe_organisation.name.yml} |   4 +-
 ...y_form_display.node.oe_project.default.yml |  10 +-
 ...tity_view_display.node.oe_project.full.yml |  20 +-
 ..._stakeholder.oe_cx_contribution_budget.yml |  22 --
 .../oe_whitelabel_extra_project.info.yml      |   5 +-
 .../oe_whitelabel_extra_project.install       |   1 -
 ...--node--oe-project--group-budget.html.twig |  25 ++
 ...--oe-project--group-coordinators.html.twig |  25 ++
 ...--node--oe-project--group-period.html.twig |  25 ++
 ...e-project--group-project-details.html.twig |  32 ++
 .../content/node--oe-project--full.html.twig  |   2 +-
 .../oe-organisation--default.html.twig        |  21 ++
 ...project-coordinators--oe-project.html.twig |  16 -
 ...--node--oe-project--group-budget.html.twig |  23 --
 ...--node--oe-project--group-period.html.twig |  23 --
 ...e-project--group-project-details.html.twig |  30 --
 .../oe-organisation--default.html.twig        |  25 --
 ...on--oe-stakeholder--coordinators.html.twig |   7 -
 .../Functional/ContentProjectRenderTest.php   | 298 ++++++++++++++++++
 .../PatternAssertions/BasePatternAssert.php   | 196 ++++++++++++
 .../PatternAssertions/ContentBannerAssert.php |  66 ++++
 .../DescriptionListAssert.php                 |  62 ++++
 .../InPageNavigationAssert.php                |  60 ++++
 .../PatternAssertInterface.php                |  32 ++
 27 files changed, 909 insertions(+), 194 deletions(-)
 delete mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.coordinators.yml
 create mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_stakeholder.name.yml
 rename modules/oe_whitelabel_extra_project/config/install/{core.entity_view_mode.oe_organisation.coordinators.yml => core.entity_view_mode.oe_organisation.name.yml} (71%)
 delete mode 100644 modules/oe_whitelabel_extra_project/config/overrides/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml
 create mode 100644 templates/content/field-group-html-element--node--oe-project--group-budget.html.twig
 create mode 100644 templates/content/field-group-html-element--node--oe-project--group-coordinators.html.twig
 create mode 100644 templates/content/field-group-html-element--node--oe-project--group-period.html.twig
 create mode 100644 templates/content/field-group-html-element--node--oe-project--group-project-details.html.twig
 rename templates/{overrides => }/content/node--oe-project--full.html.twig (96%)
 create mode 100644 templates/content/oe-organisation--default.html.twig
 delete mode 100644 templates/overrides/content/field--node--oe-project-coordinators--oe-project.html.twig
 delete mode 100644 templates/overrides/content/field-group-html-element--node--oe-project--group-budget.html.twig
 delete mode 100644 templates/overrides/content/field-group-html-element--node--oe-project--group-period.html.twig
 delete mode 100644 templates/overrides/content/field-group-html-element--node--oe-project--group-project-details.html.twig
 delete mode 100644 templates/overrides/content/oe-organisation--default.html.twig
 delete mode 100644 templates/overrides/content/oe-organisation--oe-stakeholder--coordinators.html.twig
 create mode 100644 tests/src/Functional/ContentProjectRenderTest.php
 create mode 100644 tests/src/PatternAssertions/BasePatternAssert.php
 create mode 100644 tests/src/PatternAssertions/ContentBannerAssert.php
 create mode 100644 tests/src/PatternAssertions/DescriptionListAssert.php
 create mode 100644 tests/src/PatternAssertions/InPageNavigationAssert.php
 create mode 100644 tests/src/PatternAssertions/PatternAssertInterface.php

diff --git a/composer.json b/composer.json
index 76b5ee6c..0e3685fa 100644
--- a/composer.json
+++ b/composer.json
@@ -65,6 +65,11 @@
             "url": "https://github.com/openeuropa/oe_content_extra"
         }
     },
+    "autoload-dev": {
+        "psr-4": {
+            "Drupal\\Tests\\oe_whitelabel\\": "./tests/src/"
+        }
+    },
     "extra": {
         "composer-exit-on-patch-failure": true,
         "enable-patching": true,
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.coordinators.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.coordinators.yml
deleted file mode 100644
index e70e4004..00000000
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.coordinators.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - core.entity_view_mode.oe_organisation.coordinators
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_acronym
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_address
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_contact_url
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_logo
-    - field.field.oe_organisation.oe_cx_project_stakeholder.oe_website
-    - oe_content_entity_organisation.oe_organisation_type.oe_cx_project_stakeholder
-id: oe_organisation.oe_cx_project_stakeholder.coordinators
-targetEntityType: oe_organisation
-bundle: oe_cx_project_stakeholder
-mode: coordinators
-content:
-  name:
-    type: string
-    label: hidden
-    settings:
-      link_to_entity: false
-    third_party_settings: {  }
-    weight: 0
-    region: content
-hidden:
-  created: true
-  langcode: true
-  oe_acronym: true
-  oe_address: true
-  oe_contact_url: true
-  oe_cx_contribution_budget: true
-  oe_logo: true
-  oe_website: true
-  status: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_stakeholder.name.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_stakeholder.name.yml
new file mode 100644
index 00000000..19f15e31
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_stakeholder.name.yml
@@ -0,0 +1,33 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.oe_organisation.name
+    - field.field.oe_organisation.oe_stakeholder.oe_acronym
+    - field.field.oe_organisation.oe_stakeholder.oe_address
+    - field.field.oe_organisation.oe_stakeholder.oe_contact_url
+    - field.field.oe_organisation.oe_stakeholder.oe_logo
+    - field.field.oe_organisation.oe_stakeholder.oe_website
+    - oe_content_entity_organisation.oe_organisation_type.oe_stakeholder
+id: oe_organisation.oe_stakeholder.name
+targetEntityType: oe_organisation
+bundle: oe_stakeholder
+mode: name
+content:
+  name:
+    type: string
+    label: hidden
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+    weight: 0
+    region: content
+hidden:
+  created: true
+  langcode: true
+  oe_acronym: true
+  oe_address: true
+  oe_contact_url: true
+  oe_logo: true
+  oe_website: true
+  status: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.coordinators.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.name.yml
similarity index 71%
rename from modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.coordinators.yml
rename to modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.name.yml
index e375236d..71f18425 100644
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.coordinators.yml
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.name.yml
@@ -3,7 +3,7 @@ status: true
 dependencies:
   module:
     - oe_content_entity_organisation
-id: oe_organisation.coordinators
-label: Coordinators
+id: oe_organisation.name
+label: Name
 targetEntityType: oe_organisation
 cache: true
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml
index 67e8f1a1..70f83b1d 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml
@@ -92,6 +92,7 @@ third_party_settings:
         - group_budget
         - oe_project_website
         - oe_project_funding_programme
+        - oe_reference_code
       label: 'Project details'
       region: content
       parent_name: ''
@@ -281,6 +282,14 @@ content:
       placeholder_url: ''
       placeholder_title: ''
     third_party_settings: {  }
+  oe_reference_code:
+    type: string_textfield
+    weight: 9
+    region: content
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
   oe_subject:
     type: skos_concept_entity_reference_autocomplete
     weight: 11
@@ -339,7 +348,6 @@ hidden:
   oe_project_calls: true
   oe_project_contact: true
   oe_project_locations: true
-  oe_reference_code: true
   path: true
   promote: true
   sticky: true
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
index 2980cb51..c4bfb440 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
@@ -64,6 +64,7 @@ third_party_settings:
         - group_budget
         - oe_project_website
         - oe_project_funding_programme
+        - oe_reference_code
       label: 'Project details'
       parent_name: ''
       region: content
@@ -94,8 +95,8 @@ third_party_settings:
         id: ''
         element: div
         show_label: false
-        label_element: h3
-        label_element_classes: ''
+        label_element: div
+        label_element_classes: 'field__label fw-bold'
         attributes: ''
         effect: none
         speed: fast
@@ -197,9 +198,9 @@ content:
     region: content
   oe_project_coordinators:
     type: entity_reference_revisions_entity_view
-    label: inline
+    label: above
     settings:
-      view_mode: coordinators
+      view_mode: name
       link: ''
     third_party_settings: {  }
     weight: 7
@@ -220,7 +221,7 @@ content:
     settings:
       link: true
     third_party_settings: {  }
-    weight: 5
+    weight: 3
     region: content
   oe_project_participants:
     type: entity_reference_revisions_entity_view
@@ -241,6 +242,14 @@ content:
       rel: ''
       target: ''
     third_party_settings: {  }
+    weight: 2
+    region: content
+  oe_reference_code:
+    type: string
+    label: above
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
     weight: 4
     region: content
   oe_subject:
@@ -282,4 +291,3 @@ hidden:
   oe_project_locations: true
   oe_project_result_files: true
   oe_project_results: true
-  oe_reference_code: true
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml b/modules/oe_whitelabel_extra_project/config/overrides/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml
deleted file mode 100644
index f4bbedb1..00000000
--- a/modules/oe_whitelabel_extra_project/config/overrides/field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.storage.oe_organisation.oe_cx_contribution_budget
-    - oe_content_entity_organisation.oe_organisation_type.oe_cx_project_stakeholder
-id: oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget
-field_name: oe_cx_contribution_budget
-entity_type: oe_organisation
-bundle: oe_cx_project_stakeholder
-label: 'Contribution to the budget'
-description: ''
-required: false
-translatable: false
-default_value: {  }
-default_value_callback: ''
-settings:
-  min: null
-  max: null
-  prefix: EUR
-  suffix: ''
-field_type: float
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
index 59a0bcfe..dde16635 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
@@ -4,10 +4,11 @@ description: Module to override content extra project.
 package: OpenEuropa Whitelabel Theme
 core_version_requirement: ^9.2
 dependencies:
+  - drupal:twig_field_value
   - oe_content_extra:oe_content_extra_project
   - oe_whitelabel_helper:oe_whitelabel_helper
 
 config_devel:
   install:
-    - core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.coordinators
-    - core.entity_view_mode.oe_organisation.coordinators
+    - core.entity_view_display.oe_organisation.oe_stakeholder.name
+    - core.entity_view_mode.oe_organisation.name
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
index aacc3c4f..172efeb8 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
@@ -25,7 +25,6 @@ function oe_whitelabel_extra_project_install($is_syncing): void {
     'core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default',
     'core.entity_view_display.node.oe_project.full',
     'core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default',
-    'field.field.oe_organisation.oe_cx_project_stakeholder.oe_cx_contribution_budget',
   ];
 
   ConfigImporter::importMultiple('oe_whitelabel_extra_project', '/config/overrides/', $configs);
diff --git a/templates/content/field-group-html-element--node--oe-project--group-budget.html.twig b/templates/content/field-group-html-element--node--oe-project--group-budget.html.twig
new file mode 100644
index 00000000..a5468863
--- /dev/null
+++ b/templates/content/field-group-html-element--node--oe-project--group-budget.html.twig
@@ -0,0 +1,25 @@
+{#
+/**
+ * @file
+ * Budget field group theme implementation.
+ *
+ * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
+ */
+#}
+{% set _items = [] %}
+{% for _field in element if _key|first != '#' %}
+  {% set _value %}
+    {{ _field|field_value }}
+  {% endset %}
+  {% if _value is not empty %}
+    {% set _items = _items|merge([{
+      term: _field|field_label,
+      definition: _value,
+    }]) %}
+  {% endif %}
+{% endfor %}
+{{ pattern('description_list', {
+  items: _items,
+  orientation: 'horizontal',
+  attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
+}) }}
diff --git a/templates/content/field-group-html-element--node--oe-project--group-coordinators.html.twig b/templates/content/field-group-html-element--node--oe-project--group-coordinators.html.twig
new file mode 100644
index 00000000..23c6b581
--- /dev/null
+++ b/templates/content/field-group-html-element--node--oe-project--group-coordinators.html.twig
@@ -0,0 +1,25 @@
+{#
+/**
+ * @file
+ * Coordinator field group theme implementation.
+ *
+ * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
+ */
+#}
+{% set _items = [] %}
+{% for _field in element if _key|first != '#' and _field|field_value %}
+  {% set _value %}
+    {{ _field|field_value }}
+  {% endset %}
+  {% if _value is not empty %}
+    {% set _items = _items|merge([{
+      term: _field|field_label,
+      definition: _value,
+    }]) %}
+  {% endif %}
+{% endfor %}
+{{ pattern('description_list', {
+  items: _items,
+  orientation: 'horizontal',
+  attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
+}) }}
diff --git a/templates/content/field-group-html-element--node--oe-project--group-period.html.twig b/templates/content/field-group-html-element--node--oe-project--group-period.html.twig
new file mode 100644
index 00000000..370881f6
--- /dev/null
+++ b/templates/content/field-group-html-element--node--oe-project--group-period.html.twig
@@ -0,0 +1,25 @@
+{#
+/**
+ * @file
+ * Period field group theme implementation.
+ *
+ * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
+ */
+#}
+{% set _items = [] %}
+{% for _field in element if _key|first != '#' %}
+  {% set _value %}
+    {{ _field|field_value }}
+  {% endset %}
+  {% if _value is not empty %}
+    {% set _items = _items|merge([{
+      term: _field|field_label,
+      definition: _value,
+    }]) %}
+  {% endif %}
+{% endfor %}
+{{ pattern('description_list', {
+  items: _items,
+  orientation: 'horizontal',
+  attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
+}) }}
diff --git a/templates/content/field-group-html-element--node--oe-project--group-project-details.html.twig b/templates/content/field-group-html-element--node--oe-project--group-project-details.html.twig
new file mode 100644
index 00000000..8506238d
--- /dev/null
+++ b/templates/content/field-group-html-element--node--oe-project--group-project-details.html.twig
@@ -0,0 +1,32 @@
+{#
+/**
+ * @file
+ * Details field group theme implementation.
+ *
+ * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
+ */
+#}
+{% if title %}
+  <h3 id="oe-project-oe-project-dates" class="fw-bold mb-4">
+    {{ title }}
+  </h3>
+{% endif %}
+{{ element.group_period }}
+{{ element.group_budget }}
+{% set _items = [] %}
+{% for _field in element if _key|first != '#' and _field|field_value  %}
+  {% set _value %}
+    {{ _field|field_value }}
+  {% endset %}
+  {% if _value is not empty %}
+    {% set _items = _items|merge([{
+      term: _field|field_label,
+      definition: _value,
+    }]) %}
+  {% endif %}
+{% endfor %}
+{{ pattern('description_list', {
+  items: _items,
+  orientation: 'horizontal',
+  attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
+}) }}
diff --git a/templates/overrides/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
similarity index 96%
rename from templates/overrides/content/node--oe-project--full.html.twig
rename to templates/content/node--oe-project--full.html.twig
index 7a69cd48..9084fe27 100644
--- a/templates/overrides/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -29,7 +29,7 @@
 {% endset %}
 <div class="mt-md-4-75 mt-4">
   {{ pattern('inpage_navigation', {
-    title: 'Page content',
+    title: 'Page content'|t,
     links: inpage_navigation_links,
     content: inpage_navigation_fields,
     full_layout: true,
diff --git a/templates/content/oe-organisation--default.html.twig b/templates/content/oe-organisation--default.html.twig
new file mode 100644
index 00000000..6f51f90f
--- /dev/null
+++ b/templates/content/oe-organisation--default.html.twig
@@ -0,0 +1,21 @@
+<h4 class="fw-bold mb-3">
+  {% if elements.oe_acronym is not empty %} {{ elements.oe_acronym }}{% endif %}
+</h4>
+{% set _items = [] %}
+{% for _field in elements if _key|first != '#' %}
+  {% set _value %}
+    {{ _field|field_value }}
+  {% endset %}
+  {% if _value is not empty %}
+    {% set _items = _items|merge([{
+      term: _field|field_label,
+      definition: _value,
+    }]) %}
+  {% endif %}
+{% endfor %}
+{{ pattern('description_list', {
+  items: _items,
+  orientation: 'horizontal',
+  attributes: create_attribute().addClass(['border-bottom', 'mt-3', 'mb-4']),
+}) }}
+
diff --git a/templates/overrides/content/field--node--oe-project-coordinators--oe-project.html.twig b/templates/overrides/content/field--node--oe-project-coordinators--oe-project.html.twig
deleted file mode 100644
index 453f5fea..00000000
--- a/templates/overrides/content/field--node--oe-project-coordinators--oe-project.html.twig
+++ /dev/null
@@ -1,16 +0,0 @@
-{#
-/**
- * @file
- * Contributors field template.
- *
- * @see ./core/themes/stable/templates/field/field.html.twig
- */
-#}
-<dl class="fw-bold mb-4 mt-3 mb-4 d-md-grid grid-3-9">
-  <dd>{{ label }}</dd>
-  <div>
-    <dd>
-      {{ element }}
-    </dd>
-  </div>
-</dl>
diff --git a/templates/overrides/content/field-group-html-element--node--oe-project--group-budget.html.twig b/templates/overrides/content/field-group-html-element--node--oe-project--group-budget.html.twig
deleted file mode 100644
index bb833f21..00000000
--- a/templates/overrides/content/field-group-html-element--node--oe-project--group-budget.html.twig
+++ /dev/null
@@ -1,23 +0,0 @@
-{#
-/**
- * @file
- * Budget field group theme implementation.
- *
- * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
- */
-#}
-  {% set _items = [] %}
-  {% for _field in element if _key|first != '#' and _field|field_value %}
-    {% set _value %}
-      {{ _field|field_value }}
-    {% endset %}
-    {% set _items = _items|merge([{
-      term: _field|field_label,
-      definition: _value,
-    }]) %}
-  {% endfor %}
-  {{ pattern('description_list', {
-    items: _items,
-    orientation: 'horizontal',
-    attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
-  }) }}
diff --git a/templates/overrides/content/field-group-html-element--node--oe-project--group-period.html.twig b/templates/overrides/content/field-group-html-element--node--oe-project--group-period.html.twig
deleted file mode 100644
index 20e57540..00000000
--- a/templates/overrides/content/field-group-html-element--node--oe-project--group-period.html.twig
+++ /dev/null
@@ -1,23 +0,0 @@
-{#
-/**
- * @file
- * Period field group theme implementation.
- *
- * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
- */
-#}
-  {% set _items = [] %}
-  {% for _field in element if _key|first != '#' and _field|field_value %}
-    {% set _value %}
-      {{ _field|field_value }}
-    {% endset %}
-    {% set _items = _items|merge([{
-      term: _field|field_label,
-      definition: _value,
-    }]) %}
-  {% endfor %}
-  {{ pattern('description_list', {
-    items: _items,
-    orientation: 'horizontal',
-    attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
-  }) }}
diff --git a/templates/overrides/content/field-group-html-element--node--oe-project--group-project-details.html.twig b/templates/overrides/content/field-group-html-element--node--oe-project--group-project-details.html.twig
deleted file mode 100644
index 5ab0910b..00000000
--- a/templates/overrides/content/field-group-html-element--node--oe-project--group-project-details.html.twig
+++ /dev/null
@@ -1,30 +0,0 @@
-{#
-/**
- * @file
- * Details field group theme implementation.
- *
- * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
- */
-#}
-  {% if title %}
-    <h3 id="oe-project-oe-project-dates" class="fw-bold mb-4">
-      {{ title }}
-    </h3>
-    {{ element.group_period }}
-    {{ element.group_budget }}
-  {% endif %}
-  {% set _items = [] %}
-  {% for _field in element if _key|first != '#' and _field|field_value %}
-    {% set _value %}
-      {{ _field|field_value }}
-    {% endset %}
-    {% set _items = _items|merge([{
-      term: _field|field_label,
-      definition: _value,
-    }]) %}
-  {% endfor %}
-  {{ pattern('description_list', {
-    items: _items,
-    orientation: 'horizontal',
-    attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
-  }) }}
diff --git a/templates/overrides/content/oe-organisation--default.html.twig b/templates/overrides/content/oe-organisation--default.html.twig
deleted file mode 100644
index 15d784c5..00000000
--- a/templates/overrides/content/oe-organisation--default.html.twig
+++ /dev/null
@@ -1,25 +0,0 @@
-{#
-/**
- * @file
- * Organisation default teaser template.
- */
-#}
-<h4 class="fw-bold mb-3">
-  {% if elements.oe_acronym is not empty %} {{ elements.oe_acronym }}{% endif %}
-</h4>
-{% set _items = [] %}
-{% for _field in elements if _key|first != '#' and _field|field_value %}
-  {% set _value %}
-    {{ _field|field_value }}
-  {% endset %}
-  {% set _items = _items|merge([{
-    term: _field|field_label,
-    definition: _value,
-  }]) %}
-{% endfor %}
-  {{ pattern('description_list', {
-    items: _items,
-    orientation: 'horizontal',
-    attributes: create_attribute().addClass(['border-bottom', 'mt-3', 'mb-4']),
-  }) }}
-
diff --git a/templates/overrides/content/oe-organisation--oe-stakeholder--coordinators.html.twig b/templates/overrides/content/oe-organisation--oe-stakeholder--coordinators.html.twig
deleted file mode 100644
index 45f36ef1..00000000
--- a/templates/overrides/content/oe-organisation--oe-stakeholder--coordinators.html.twig
+++ /dev/null
@@ -1,7 +0,0 @@
-{#
-/**
- * @file
- * Coordinator organisation teaser template.
- */
-#}
-{{ elements.name }}
diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
new file mode 100644
index 00000000..0c37ab32
--- /dev/null
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -0,0 +1,298 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel\Functional;
+
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\file\Entity\File;
+use Drupal\media\Entity\Media;
+use Drupal\oe_content_entity\Entity\CorporateEntityInterface;
+use Drupal\oe_content_entity_organisation\Entity\OrganisationInterface;
+use Drupal\Tests\oe_whitelabel\PatternAssertions\InPageNavigationAssert;
+use Drupal\Tests\oe_whitelabel\PatternAssertions\DescriptionListAssert;
+use Drupal\Tests\oe_whitelabel\PatternAssertions\ContentBannerAssert;
+use Drupal\Tests\sparql_entity_storage\Traits\SparqlConnectionTrait;
+use Drupal\Tests\TestFileCreationTrait;
+
+/**
+ * Tests that our Project content type renders correctly.
+ */
+class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
+
+  use SparqlConnectionTrait;
+  use TestFileCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'oe_whitelabel_extra_project',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+    $this->setUpSparql();
+
+    $admin = $this->createUser([], NULL, TRUE);
+    $this->drupalLogin($admin);
+  }
+
+  /**
+   * Tests that the Project page renders correctly.
+   */
+  public function testProjectRendering(): void {
+    $assert_session = $this->assertSession();
+    $page = $this->getSession()->getPage();
+
+    // Create a media entity.
+    // Create file and media.
+    $file = File::create([
+      'uri' => $this->getTestFiles('image')[0]->uri,
+    ]);
+    $file->save();
+    $media = Media::create([
+      'bundle' => 'image',
+      'name' => 'Image test',
+      'oe_media_image' => [
+        [
+          'target_id' => $file->id(),
+          'alt' => 'Image test alt',
+          'title' => 'Image test title',
+        ],
+      ],
+    ]);
+    $media->save();
+    // Create organisations for Coordinators and Participants fields.
+    // Unpublished entity should not be shown.
+    $coordinator_organisation = $this->createStakeholderOrganisationEntity('coordinator', CorporateEntityInterface::PUBLISHED, 'oe_stakeholder');
+    $participant_organisation = $this->createStakeholderOrganisationEntity('participant', CorporateEntityInterface::PUBLISHED, 'oe_cx_project_stakeholder');
+
+    // Create a Project node.
+    /** @var \Drupal\node\Entity\Node $node */
+    $node = $this->getStorage('node')->create([
+      'type' => 'oe_project',
+      'title' => 'Test project node',
+      'oe_teaser' => 'Test project node',
+      'oe_summary' => 'Summary',
+      'oe_featured_media' => [
+        'target_id' => (int) $media->id(),
+        'caption' => 'Caption project_featured_media',
+      ],
+      'oe_project_dates' => [
+        'value' => '2020-05-10',
+        'end_value' => '2025-05-15',
+      ],
+      'oe_project_budget' => '100',
+      'oe_project_budget_eu' => '100',
+      'oe_project_website' => [
+        [
+          'uri' => 'http://example.com',
+          'title' => 'Example website',
+        ],
+      ],
+      'oe_reference_code' => 'Project reference',
+      'oe_subject' => 'http://data.europa.eu/uxp/1386',
+      'oe_project_funding_programme' => 'http://publications.europa.eu/resource/authority/eu-programme/AFIS2020',
+      'oe_project_coordinators' => [$coordinator_organisation],
+      'oe_project_participants' => [$participant_organisation],
+      'oe_cx_objective' => 'Objective',
+      'oe_cx_impacts' => 'Impacts',
+      'oe_cx_achievements_and_milestone' => 'Achievements and milestone',
+      'uid' => 0,
+      'status' => 1,
+    ]);
+    $node->save();
+    $this->drupalGet($node->toUrl());
+
+    // Assert page header - metadata.
+    $page_header = $assert_session->elementExists('css', '.bcl-content-banner');
+    $assert = new ContentBannerAssert();
+    $expected_values = [
+      'image' => [
+        'alt' => 'Image test alt',
+        'src' => 'image-test.png',
+      ],
+      'badges' => ['wood industry'],
+      'title' => 'Test project node',
+      'description' => 'Test project node',
+    ];
+    $assert->assertPattern($expected_values, $page_header->getOuterHtml());
+
+    // Assert navigation.
+    $navigation = $this->assertSession()->elementExists('css', 'nav.bcl-inpage-navigation');
+    $inpage_nav_assert = new InPageNavigationAssert();
+    $inpage_nav_expected_values = [
+      'title' => 'Page content',
+      'links' => [
+        [
+          'label' => 'Project period',
+          'href' => '#oe-project-oe-project-dates',
+        ],
+        [
+          'label' => 'Summary',
+          'href' => '#oe-project-oe-summary',
+        ],
+        [
+          'label' => 'Objective',
+          'href' => '#oe-project-oe-cx-objective',
+        ],
+        [
+          'label' => 'Impacts',
+          'href' => '#oe-project-oe-cx-impacts',
+        ],
+        [
+          'label' => 'Achievements and milestones',
+          'href' => '#oe-project-oe-cx-achievements-and-milestone',
+        ],
+        [
+          'label' => 'Participants',
+          'href' => '#oe-project-oe-project-participants',
+        ],
+      ],
+    ];
+    $inpage_nav_assert->assertPattern($inpage_nav_expected_values, $navigation->getOuterHtml());
+
+    // Assert top region - Project details.
+    $project_data = $assert_session->elementExists('css', '.col-md-9');
+
+    // Assert the description blocks inside the Project details.
+    $description_lists = $project_data->findAll('css', '.grid-3-9');
+    $this->assertCount(5, $description_lists);
+
+    // Period list group.
+    $field_list_assert = new DescriptionListAssert();
+    $first_field_list_expected_values = [
+      'items' => [
+        [
+          'term' => 'Project period',
+          'definition' => '10/05/2020 - 15/05/2025',
+        ],
+      ],
+    ];
+    $field_list_html = $description_lists[0]->getHtml();
+    $field_list_assert->assertPattern($first_field_list_expected_values, $field_list_html);
+
+    // Assert budget list group.
+    $field_list_assert = new DescriptionListAssert();
+    $second_field_list_expected_values = [
+      'items' => [
+        [
+          'term' => 'Overall budget',
+          'definition' => '€100.00',
+        ],
+        [
+          'term' => 'EU contribution',
+          'definition' => '€100.00',
+        ],
+      ],
+    ];
+    $field_list_html = $description_lists[1]->getHtml();
+    $field_list_assert->assertPattern($second_field_list_expected_values, $field_list_html);
+
+    // Assert details list group.
+    $field_list_assert = new DescriptionListAssert();
+    $third_field_list_expected_values = [
+      'items' => [
+        [
+          'term' => 'Website',
+          'definition' => 'Example website',
+        ],
+        [
+          'term' => 'Funding programme',
+          'definition' => 'Anti Fraud Information System (AFIS)',
+        ],
+        [
+          'term' => 'Reference',
+          'definition' => 'Project reference',
+        ],
+      ],
+    ];
+    $field_list_html = $description_lists[2]->getHtml();
+    $field_list_assert->assertPattern($third_field_list_expected_values, $field_list_html);
+
+    // Assert coordinators list group.
+    $field_list_assert = new DescriptionListAssert();
+    $fourth_field_list_expected_values = [
+      'items' => [
+        [
+          'term' => 'Coordinators',
+          'definition' => 'coordinator',
+        ],
+      ],
+    ];
+    $field_list_html = $description_lists[3]->getHtml();
+    $field_list_assert->assertPattern($fourth_field_list_expected_values, $field_list_html);
+
+    // Assert participants list group.
+    $field_list_assert = new DescriptionListAssert();
+    $fifth_field_list_expected_values = [
+      'items' => [
+        [
+          'term' => 'Name',
+          'definition' => 'participant',
+        ],
+        [
+          'term' => 'Address',
+          'definition' => 'Belgium',
+        ],
+        [
+          'term' => 'Acronym',
+          'definition' => 'Acronym participant',
+        ],
+        [
+          'term' => 'Contribution to the budget',
+          'definition' => '€22.30',
+        ],
+      ],
+    ];
+    $field_list_html = $description_lists[4]->getHtml();
+    $field_list_assert->assertPattern($fifth_field_list_expected_values, $field_list_html);
+  }
+
+  /**
+   * Creates a stakeholder organisation entity.
+   *
+   * @param string $name
+   *   Name of the entity. Is used as a parameter for test data.
+   * @param int $status
+   *   Entity status. 1 - published, 0 - unpublished.
+   * @param string $bundle
+   *   Bundle name used in the entity.
+   *
+   * @return \Drupal\oe_content_entity_organisation\Entity\OrganisationInterface
+   *   Organisation entity.
+   */
+  protected function createStakeholderOrganisationEntity(string $name, int $status, string $bundle): OrganisationInterface {
+    $organisation = $this->getStorage('oe_organisation')->create([
+      'bundle' => $bundle,
+      'name' => $name,
+      'oe_acronym' => "Acronym $name",
+      'oe_address' => [
+        'country_code' => 'BE',
+      ],
+      'oe_cx_contribution_budget' => '22.3',
+      'status' => $status,
+    ]);
+    $organisation->save();
+
+    return $organisation;
+  }
+
+  /**
+   * Gets the entity type's storage.
+   *
+   * @param string $entity_type_id
+   *   The entity type ID to get a storage for.
+   *
+   * @return \Drupal\Core\Entity\EntityStorageInterface
+   *   The entity type's storage.
+   */
+  protected function getStorage(string $entity_type_id): EntityStorageInterface {
+    return \Drupal::entityTypeManager()->getStorage($entity_type_id);
+  }
+
+}
diff --git a/tests/src/PatternAssertions/BasePatternAssert.php b/tests/src/PatternAssertions/BasePatternAssert.php
new file mode 100644
index 00000000..f817c242
--- /dev/null
+++ b/tests/src/PatternAssertions/BasePatternAssert.php
@@ -0,0 +1,196 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel\PatternAssertions;
+
+use PHPUnit\Framework\Assert;
+use PHPUnit\Framework\Exception;
+use Symfony\Component\DomCrawler\Crawler;
+
+/**
+ * Base class for asserting patterns.
+ */
+abstract class BasePatternAssert extends Assert implements PatternAssertInterface {
+
+  /**
+   * Method that returns the assertions to be run by a particular pattern.
+   *
+   * Assertions extending this class need to return an array containing the
+   * assertions to be run for every possible value that can be expected.
+   *
+   * @return array
+   *   An array containing the assertions to be run.
+   */
+  abstract protected function getAssertions(): array;
+
+  /**
+   * Method that asserts the base elements of a rendered pattern.
+   *
+   * @param string $html
+   *   The rendered pattern.
+   */
+  abstract protected function assertBaseElements(string $html): void;
+
+  /**
+   * Returns the variant of the provided rendered pattern.
+   *
+   * @param string $html
+   *   The rendered pattern.
+   *
+   * @return string
+   *   The variant of the rendered pattern.
+   */
+  protected function getPatternVariant(string $html): string {
+    return 'default';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function assertPattern(array $expected, string $html): void {
+    $variant = $this->getPatternVariant($html);
+    $this->assertBaseElements($html, $variant);
+    $assertion_map = $this->getAssertions($variant);
+    $crawler = new Crawler($html);
+    foreach ($expected as $name => $expected_value) {
+      if (!array_key_exists($name, $assertion_map)) {
+        $reflection = new \ReflectionClass($this);
+        throw new Exception(sprintf('"%s" does not provide any assertion for "%s".', $reflection->getName(), $name));
+      }
+      if (is_array($assertion_map[$name]) && is_callable($assertion_map[$name][0])) {
+        $callback = array_shift($assertion_map[$name]);
+        array_unshift($assertion_map[$name], $expected_value);
+        $assertion_map[$name][] = $crawler;
+        call_user_func_array($callback, $assertion_map[$name]);
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function assertVariant(string $variant, string $html): void {
+    self::assertEquals($variant, $this->getPatternVariant($html));
+  }
+
+  /**
+   * Asserts the value of an attribute of a particular element.
+   *
+   * @param string|null $expected
+   *   The expected value.
+   * @param string $selector
+   *   The CSS selector to find the element.
+   * @param string $attribute
+   *   The name of the attribute to check.
+   * @param \Symfony\Component\DomCrawler\Crawler $crawler
+   *   The DomCrawler where to check the element.
+   */
+  protected function assertElementAttribute($expected, string $selector, string $attribute, Crawler $crawler): void {
+    if (is_null($expected)) {
+      $this->assertElementNotExists($selector, $crawler);
+      return;
+    }
+    $this->assertElementExists($selector, $crawler);
+    $element = $crawler->filter($selector);
+    self::assertEquals($expected, $element->attr($attribute));
+  }
+
+  /**
+   * Asserts the text of a particular element.
+   *
+   * @param string|null $expected
+   *   The expected value.
+   * @param string $selector
+   *   The CSS selector to find the element.
+   * @param \Symfony\Component\DomCrawler\Crawler $crawler
+   *   The DomCrawler where to check the element.
+   */
+  protected function assertElementText($expected, string $selector, Crawler $crawler): void {
+    if (is_null($expected)) {
+      $this->assertElementNotExists($selector, $crawler);
+      return;
+    }
+    $this->assertElementExists($selector, $crawler);
+    $element = $crawler->filter($selector);
+    $actual = trim($element->text());
+    self::assertEquals($expected, $actual, \sprintf(
+      'Expected text value "%s" is not equal to the actual value "%s" found in the selector "%s".',
+      $expected, $actual, $selector
+    ));
+  }
+
+  /**
+   * Asserts the rendered html of a particular element.
+   *
+   * @param string|null $expected
+   *   The expected value.
+   * @param string $selector
+   *   The CSS selector to find the element.
+   * @param \Symfony\Component\DomCrawler\Crawler $crawler
+   *   The DomCrawler where to check the element.
+   */
+  protected function assertElementHtml($expected, string $selector, Crawler $crawler): void {
+    if (is_null($expected)) {
+      $this->assertElementNotExists($selector, $crawler);
+      return;
+    }
+    $this->assertElementExists($selector, $crawler);
+    $element = $crawler->filter($selector);
+    self::assertEquals($expected, $element->html());
+  }
+
+  /**
+   * Asserts that an element is present.
+   *
+   * @param string $selector
+   *   The CSS selector to find the element.
+   * @param \Symfony\Component\DomCrawler\Crawler $crawler
+   *   The DomCrawler where to check the element.
+   */
+  protected function assertElementExists(string $selector, Crawler $crawler): void {
+    $element = $crawler->filter($selector);
+    self::assertCount(1, $element, \sprintf(
+      'Element with selector "%s" not found in the provided html.',
+      $selector
+    ));
+  }
+
+  /**
+   * Asserts that an element is not present.
+   *
+   * @param string $selector
+   *   The CSS selector to find the element.
+   * @param \Symfony\Component\DomCrawler\Crawler $crawler
+   *   The DomCrawler where to check the element.
+   */
+  protected function assertElementNotExists(string $selector, Crawler $crawler): void {
+    $element = $crawler->filter($selector);
+    self::assertCount(0, $element, \sprintf(
+      'Element with selector "%s" was found in the provided html.',
+      $selector
+    ));
+  }
+
+  /**
+   * Asserts the image of the pattern.
+   *
+   * @param array|null $expected_image
+   *   The expected image.
+   * @param string $selector
+   *   The CSS selector to find the element.
+   * @param \Symfony\Component\DomCrawler\Crawler $crawler
+   *   The DomCrawler where to check the element.
+   */
+  protected function assertImage(?array $expected_image, string $selector, Crawler $crawler): void {
+    if (is_null($expected_image)) {
+      $this->assertElementNotExists($selector, $crawler);
+      return;
+    }
+    $this->assertElementExists($selector, $crawler);
+    $element = $crawler->filter($selector);
+    self::assertEquals($expected_image['alt'], $element->attr('alt'));
+    self::assertStringContainsString($expected_image['src'], $element->attr('src'));
+  }
+
+}
diff --git a/tests/src/PatternAssertions/ContentBannerAssert.php b/tests/src/PatternAssertions/ContentBannerAssert.php
new file mode 100644
index 00000000..d83d8ce8
--- /dev/null
+++ b/tests/src/PatternAssertions/ContentBannerAssert.php
@@ -0,0 +1,66 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel\PatternAssertions;
+
+use Symfony\Component\DomCrawler\Crawler;
+
+/**
+ * Assertions for the page header pattern.
+ */
+class ContentBannerAssert extends BasePatternAssert {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getAssertions(): array {
+    return [
+      'image' => [
+        [$this, 'assertImage'],
+        '.card-img-top',
+      ],
+      'badges' => [
+        [$this, 'assertBadgesElements'],
+      ],
+      'title' => [
+        [$this, 'assertElementText'],
+        '.card-title',
+      ],
+      'description' => [
+        [$this, 'assertElementText'],
+        '.card-body .mt-4',
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function assertBaseElements(string $html): void {
+    $crawler = new Crawler($html);
+    $page_header = $crawler->filter('.bcl-content-banner');
+    self::assertCount(1, $page_header);
+  }
+
+  /**
+   * Asserts the badges items of the pattern.
+   *
+   * @param array $badges
+   *   The expected badges item values.
+   * @param \Symfony\Component\DomCrawler\Crawler $crawler
+   *   The DomCrawler where to check the element.
+   */
+  protected function assertBadgesElements(array $badges, Crawler $crawler): void {
+    if (empty($badges)) {
+      $this->assertElementNotExists('.badge', $crawler);
+      return;
+    }
+    $badges_items = $crawler->filter('.mt-2-5');
+    self::assertCount(count($badges), $badges_items);
+    foreach ($badges as $index => $badge) {
+      self::assertEquals($badge, trim($badges_items->eq($index)->text()));
+    }
+  }
+
+}
diff --git a/tests/src/PatternAssertions/DescriptionListAssert.php b/tests/src/PatternAssertions/DescriptionListAssert.php
new file mode 100644
index 00000000..b8d376a5
--- /dev/null
+++ b/tests/src/PatternAssertions/DescriptionListAssert.php
@@ -0,0 +1,62 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel\PatternAssertions;
+
+use Symfony\Component\DomCrawler\Crawler;
+
+/**
+ * Assertions for the field list pattern.
+ *
+ * @see ./templates/patterns/field_list/field_list.ui_patterns.yml
+ */
+class DescriptionListAssert extends BasePatternAssert {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getAssertions(): array {
+    return [
+      'items' => [
+        [$this, 'assertItems'],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function assertBaseElements(string $html): void {
+    $crawler = new Crawler($html);
+    $field_list_container = $crawler->filter('body');
+    self::assertCount(1, $field_list_container);
+  }
+
+  /**
+   * Asserts the items of the pattern.
+   *
+   * @param array $expected_items
+   *   The expected item values.
+   * @param \Symfony\Component\DomCrawler\Crawler $crawler
+   *   The DomCrawler where to check the element.
+   */
+  protected function assertItems(array $expected_items, Crawler $crawler): void {
+    // Assert all labels are correct.
+    $expected_labels = array_column($expected_items, 'term');
+    $label_items = $crawler->filter('dt');
+    self::assertCount(count($expected_labels), $label_items);
+    foreach ($expected_labels as $index => $expected_label) {
+      self::assertEquals($expected_label, trim($label_items->eq($index)->text()));
+    }
+
+    // Assert all values are correct.
+    $expected_values = array_column($expected_items, 'definition');
+    $value_items = $crawler->filter('dd');
+    self::assertCount(count($expected_labels), $value_items);
+    foreach ($expected_values as $index => $expected_value) {
+      self::assertEquals($expected_value, trim($value_items->eq($index)->text()));
+    }
+  }
+
+}
diff --git a/tests/src/PatternAssertions/InPageNavigationAssert.php b/tests/src/PatternAssertions/InPageNavigationAssert.php
new file mode 100644
index 00000000..43e5e2fa
--- /dev/null
+++ b/tests/src/PatternAssertions/InPageNavigationAssert.php
@@ -0,0 +1,60 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel\PatternAssertions;
+
+use Symfony\Component\DomCrawler\Crawler;
+
+/**
+ * Assertions for in-page-navigation.
+ */
+class InPageNavigationAssert extends BasePatternAssert {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getAssertions(): array {
+    return [
+      'title' => [
+        [$this, 'assertElementText'],
+        'h5',
+      ],
+      'links' => [
+        [$this, 'assertList'],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function assertBaseElements(string $html): void {
+    $crawler = new Crawler($html);
+    $page_header = $crawler->filter('body');
+    self::assertCount(1, $page_header);
+  }
+
+  /**
+   * Asserts the in-page-navigation links list.
+   *
+   * @param array|null $expected
+   *   The expected description values.
+   * @param \Symfony\Component\DomCrawler\Crawler $crawler
+   *   The DomCrawler where to check the element.
+   */
+  protected function assertList($expected, Crawler $crawler): void {
+    $this->assertElementExists('ul.nav-pills', $crawler);
+
+    $actual = [];
+    $crawler->filter('ul.nav-pills  a.nav-link')->each(function (Crawler $node) use (&$actual) {
+      $actual[] = [
+        'label' => $node->text(),
+        'href' => $node->attr('href'),
+      ];
+    });
+
+    self::assertEquals($expected, $actual);
+  }
+
+}
diff --git a/tests/src/PatternAssertions/PatternAssertInterface.php b/tests/src/PatternAssertions/PatternAssertInterface.php
new file mode 100644
index 00000000..293eb8ff
--- /dev/null
+++ b/tests/src/PatternAssertions/PatternAssertInterface.php
@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel\PatternAssertions;
+
+/**
+ * Interface implemented by all pattern assertion objects.
+ */
+interface PatternAssertInterface {
+
+  /**
+   * Asserts that a rendered pattern is correct.
+   *
+   * @param array $expected
+   *   An array of expected values, keyed by field name.
+   * @param string $html
+   *   The rendered pattern.
+   */
+  public function assertPattern(array $expected, string $html): void;
+
+  /**
+   * Asserts that a rendered pattern uses a variant.
+   *
+   * @param string $variant
+   *   The variant to check for.
+   * @param string $html
+   *   The rendered pattern.
+   */
+  public function assertVariant(string $variant, string $html): void;
+
+}
-- 
GitLab


From 36284c322f71d7a0fa5e147e2b254a7ce4454979 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Thu, 31 Mar 2022 12:21:50 +0200
Subject: [PATCH 013/152] OEL-1297: Inpage order modified, titles and budget
 improved.

---
 ...tity_view_display.node.oe_project.full.yml | 20 ++++++-------
 .../content/node--oe-project--full.html.twig  | 28 +++++++++++++++----
 .../Functional/ContentProjectRenderTest.php   |  8 +++---
 3 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
index c4bfb440..512ed13f 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
@@ -146,30 +146,30 @@ mode: full
 content:
   oe_cx_achievements_and_milestone:
     type: text_default
-    label: above
+    label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 9
+    weight: 11
     region: content
   oe_cx_impacts:
     type: text_default
-    label: above
+    label: hidden
     settings: {  }
     third_party_settings: {  }
     weight: 7
     region: content
   oe_cx_lead_contributors:
     type: entity_reference_revisions_entity_view
-    label: above
+    label: hidden
     settings:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 13
+    weight: 10
     region: content
   oe_cx_objective:
     type: text_default
-    label: above
+    label: hidden
     settings: {  }
     third_party_settings: {  }
     weight: 6
@@ -225,12 +225,12 @@ content:
     region: content
   oe_project_participants:
     type: entity_reference_revisions_entity_view
-    label: above
+    label: hidden
     settings:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 12
+    weight: 9
     region: content
   oe_project_website:
     type: link
@@ -254,7 +254,7 @@ content:
     region: content
   oe_subject:
     type: skos_concept_entity_reference_label
-    label: above
+    label: hidden
     settings:
       link: false
     third_party_settings: {  }
@@ -262,7 +262,7 @@ content:
     region: content
   oe_summary:
     type: text_default
-    label: above
+    label: hidden
     settings: {  }
     third_party_settings: {  }
     weight: 5
diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 9084fe27..6b4fb0f3 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -5,10 +5,13 @@
  */
 #}
 {% if not content.oe_subject.isEmpty() %}
-  {% set _badge = {
-    label: content.oe_subject|field_value,
-    rounded_pill: true,
-  } %}
+  {% set _badges = [] %}
+  {% for _badge in content.oe_subject|field_value %}
+    {% set _badges = _badges|merge([{
+      label: _badge['#plain_text'],
+      rounded_pill: true,
+    }]) %}
+  {% endfor %}
 {% endif %}
 {{ pattern('content_banner', {
   background: 'gray',
@@ -16,15 +19,30 @@
   content: content.oe_teaser,
   image: image,
   attributes: create_attribute().addClass(['ps-0']),
-  badges: [_badge],
+  badges: _badges,
 }) }}
 {% set inpage_navigation_fields %}
   {{ content.group_project_details }}
   {{ content.group_coordinators }}
+  <h3 class="fw-bold mb-4 pt-3">
+    {{ content.oe_summary|field_label }}
+  </h3>
   {{ content.oe_summary }}
+  <h3 class="fw-bold mb-4 pt-3">
+    {{ content.oe_cx_objective|field_label }}
+  </h3>
   {{ content.oe_cx_objective }}
+  <h3 class="fw-bold mb-4 pt-3">
+    {{ content.oe_cx_impacts|field_label }}
+  </h3>
   {{ content.oe_cx_impacts }}
+  <h3 class="fw-bold mb-4 pt-3">
+    {{ content.group_stakeholders.oe_project_participants|field_label }}
+  </h3>
   {{ content.group_stakeholders }}
+  <h3 class="fw-bold mb-4 pt-3">
+    {{ content.oe_cx_achievements_and_milestone|field_label }}
+  </h3>
   {{ content.oe_cx_achievements_and_milestone }}
 {% endset %}
 <div class="mt-md-4-75 mt-4">
diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index 0c37ab32..56946e8f 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -144,14 +144,14 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
           'label' => 'Impacts',
           'href' => '#oe-project-oe-cx-impacts',
         ],
-        [
-          'label' => 'Achievements and milestones',
-          'href' => '#oe-project-oe-cx-achievements-and-milestone',
-        ],
         [
           'label' => 'Participants',
           'href' => '#oe-project-oe-project-participants',
         ],
+        [
+          'label' => 'Achievements and milestones',
+          'href' => '#oe-project-oe-cx-achievements-and-milestone',
+        ],
       ],
     ];
     $inpage_nav_assert->assertPattern($inpage_nav_expected_values, $navigation->getOuterHtml());
-- 
GitLab


From ec2aa8acf7935d86c1cfe74b255560a315918afc Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Thu, 31 Mar 2022 13:07:35 +0200
Subject: [PATCH 014/152] OEL-1297: Budget label improved.

---
 templates/content/node--oe-project--full.html.twig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 6b4fb0f3..c39c1860 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -8,7 +8,7 @@
   {% set _badges = [] %}
   {% for _badge in content.oe_subject|field_value %}
     {% set _badges = _badges|merge([{
-      label: _badge['#plain_text'],
+      label: _badge|raw,
       rounded_pill: true,
     }]) %}
   {% endfor %}
-- 
GitLab


From 7ff49c5cd61f2b87851a650bbc6b171608c2546c Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Thu, 31 Mar 2022 22:28:21 +0200
Subject: [PATCH 015/152] OEL-1297: Improve templates, export config and date
 formatter.

---
 composer.json                                 |  2 +-
 ...date_format.oe_whitelabel_project_date.yml |  7 ++++
 ...tity_view_display.node.oe_project.full.yml | 20 ++++++------
 .../oe_whitelabel_extra_project.info.yml      |  2 +-
 .../oe_whitelabel_extra_project.module        |  7 ++--
 oe_whitelabel.info.yml                        |  3 ++
 ...--oe-project--group-coordinators.html.twig |  2 +-
 .../content/node--oe-project--full.html.twig  | 32 +++++++------------
 .../oe-organisation--default.html.twig        | 10 +++---
 .../PatternAssertions/ContentBannerAssert.php |  2 +-
 .../DescriptionListAssert.php                 |  2 +-
 11 files changed, 45 insertions(+), 44 deletions(-)
 create mode 100644 modules/oe_whitelabel_extra_project/config/install/core.date_format.oe_whitelabel_project_date.yml

diff --git a/composer.json b/composer.json
index 0e3685fa..8afca89a 100644
--- a/composer.json
+++ b/composer.json
@@ -38,7 +38,7 @@
         "openeuropa/composer-artifacts": "^1.0.0-alpha1",
         "openeuropa/oe_authentication": "^1.4",
         "openeuropa/oe_contact_forms": "~1.1",
-        "openeuropa/oe_content": "^3.0.0-beta11",
+        "openeuropa/oe_content": "^2.8.0",
         "openeuropa/oe_content_extra": "dev-EPIC-1293-Project",
         "openeuropa/oe_corporate_blocks": "^4.4",
         "openeuropa/oe_multilingual": "^1.9",
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.date_format.oe_whitelabel_project_date.yml b/modules/oe_whitelabel_extra_project/config/install/core.date_format.oe_whitelabel_project_date.yml
new file mode 100644
index 00000000..1eb6de1d
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/install/core.date_format.oe_whitelabel_project_date.yml
@@ -0,0 +1,7 @@
+langcode: en
+status: true
+dependencies: {  }
+id: oe_whitelabel_project_date
+label: 'OE Whitelabel Project date'
+locked: false
+pattern: d/m/Y
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
index 512ed13f..fa9cae6c 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
@@ -46,7 +46,7 @@ third_party_settings:
       label: Stakeholders
       parent_name: ''
       region: content
-      weight: 8
+      weight: 7
       format_type: html_element
       format_settings:
         classes: ''
@@ -68,7 +68,7 @@ third_party_settings:
       label: 'Project details'
       parent_name: ''
       region: content
-      weight: 1
+      weight: 0
       format_type: html_element
       format_settings:
         classes: ''
@@ -87,7 +87,7 @@ third_party_settings:
       label: Coordinators
       parent_name: ''
       region: content
-      weight: 2
+      weight: 1
       format_type: html_element
       format_settings:
         classes: ''
@@ -156,7 +156,7 @@ content:
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 7
+    weight: 6
     region: content
   oe_cx_lead_contributors:
     type: entity_reference_revisions_entity_view
@@ -172,7 +172,7 @@ content:
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 6
+    weight: 5
     region: content
   oe_project_budget:
     type: number_decimal
@@ -206,11 +206,11 @@ content:
     weight: 7
     region: content
   oe_project_dates:
-    type: daterange_custom
+    type: daterange_default
     label: above
     settings:
       timezone_override: ''
-      date_format: d/m/Y
+      format_type: oe_whitelabel_project_date
       separator: '-'
     third_party_settings: {  }
     weight: 1
@@ -258,21 +258,21 @@ content:
     settings:
       link: false
     third_party_settings: {  }
-    weight: 4
+    weight: 3
     region: content
   oe_summary:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 5
+    weight: 4
     region: content
   oe_teaser:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 3
+    weight: 2
     region: content
 hidden:
   body: true
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
index dde16635..7d51c95a 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
@@ -4,11 +4,11 @@ description: Module to override content extra project.
 package: OpenEuropa Whitelabel Theme
 core_version_requirement: ^9.2
 dependencies:
-  - drupal:twig_field_value
   - oe_content_extra:oe_content_extra_project
   - oe_whitelabel_helper:oe_whitelabel_helper
 
 config_devel:
   install:
+    - core.date_format.oe_whitelabel_project_date
     - core.entity_view_display.oe_organisation.oe_stakeholder.name
     - core.entity_view_mode.oe_organisation.name
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index f2f7822e..8eae445e 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -10,7 +10,7 @@ declare(strict_types =  1);
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\media\MediaInterface;
 use Drupal\media\Plugin\media\Source\Image;
-use Drupal\media_avportal\Plugin\media\Source\MediaAvPortalPhotoSource;
+use Drupal\media\Plugin\media\Source\OEmbed;
 use Drupal\oe_bootstrap_theme\ValueObject\ImageValueObject;
 use Drupal\Component\Utility\Html;
 
@@ -64,11 +64,10 @@ function _oe_whitelabel_extra_project_preprocess_featured_media(&$variables) {
 
   // Get the media source.
   $source = $media->getSource();
-
-  $is_image = $source instanceof MediaAvPortalPhotoSource || $source instanceof Image;
+  $media_source = $source instanceof OEmbed || $source instanceof Image;
 
   // If it's not an image and not a video, bail out.
-  if (!$is_image) {
+  if (!$media_source) {
     $cacheability->applyTo($variables);
     return;
   }
diff --git a/oe_whitelabel.info.yml b/oe_whitelabel.info.yml
index c3e080e8..1ef10bd4 100644
--- a/oe_whitelabel.info.yml
+++ b/oe_whitelabel.info.yml
@@ -5,6 +5,9 @@ type: theme
 base theme: oe_bootstrap_theme
 core_version_requirement: ^8.9 || ^9.1
 
+dependencies:
+  - drupal:twig_field_value
+
 libraries:
   - oe_whitelabel/style
 
diff --git a/templates/content/field-group-html-element--node--oe-project--group-coordinators.html.twig b/templates/content/field-group-html-element--node--oe-project--group-coordinators.html.twig
index 23c6b581..f8fa53dd 100644
--- a/templates/content/field-group-html-element--node--oe-project--group-coordinators.html.twig
+++ b/templates/content/field-group-html-element--node--oe-project--group-coordinators.html.twig
@@ -21,5 +21,5 @@
 {{ pattern('description_list', {
   items: _items,
   orientation: 'horizontal',
-  attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
+  attributes: create_attribute().addClass(['mt-3', 'mb-4']),
 }) }}
diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index c39c1860..1275f3cb 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -21,29 +21,21 @@
   attributes: create_attribute().addClass(['ps-0']),
   badges: _badges,
 }) }}
+{% macro field_with_header(field) %}
+  {% if field|field_value is not empty %}
+    <h3 class="fw-bold mb-4 pt-3">{{ field|field_label }}</h3>
+    {{ field }}
+  {% endif %}
+{% endmacro %}
 {% set inpage_navigation_fields %}
   {{ content.group_project_details }}
   {{ content.group_coordinators }}
-  <h3 class="fw-bold mb-4 pt-3">
-    {{ content.oe_summary|field_label }}
-  </h3>
-  {{ content.oe_summary }}
-  <h3 class="fw-bold mb-4 pt-3">
-    {{ content.oe_cx_objective|field_label }}
-  </h3>
-  {{ content.oe_cx_objective }}
-  <h3 class="fw-bold mb-4 pt-3">
-    {{ content.oe_cx_impacts|field_label }}
-  </h3>
-  {{ content.oe_cx_impacts }}
-  <h3 class="fw-bold mb-4 pt-3">
-    {{ content.group_stakeholders.oe_project_participants|field_label }}
-  </h3>
-  {{ content.group_stakeholders }}
-  <h3 class="fw-bold mb-4 pt-3">
-    {{ content.oe_cx_achievements_and_milestone|field_label }}
-  </h3>
-  {{ content.oe_cx_achievements_and_milestone }}
+  {{ _self.field_with_header(content.oe_summary) }}
+  {{ _self.field_with_header(content.oe_cx_objective) }}
+  {{ _self.field_with_header(content.oe_cx_impacts) }}
+  {{ _self.field_with_header(content.group_stakeholders.oe_project_participants) }}
+  {{ _self.field_with_header(content.group_stakeholders.oe_cx_lead_contributors) }}
+  {{ _self.field_with_header(content.oe_cx_achievements_and_milestone) }}
 {% endset %}
 <div class="mt-md-4-75 mt-4">
   {{ pattern('inpage_navigation', {
diff --git a/templates/content/oe-organisation--default.html.twig b/templates/content/oe-organisation--default.html.twig
index 6f51f90f..7894c801 100644
--- a/templates/content/oe-organisation--default.html.twig
+++ b/templates/content/oe-organisation--default.html.twig
@@ -1,12 +1,12 @@
-<h4 class="fw-bold mb-3">
-  {% if elements.oe_acronym is not empty %} {{ elements.oe_acronym }}{% endif %}
-</h4>
+{% if elements.oe_acronym is not empty %}
+  <h4 class="fw-bold mb-3">{{ elements.oe_acronym }}</h4>
+{% endif %}
 {% set _items = [] %}
-{% for _field in elements if _key|first != '#' %}
+{% for _field in elements|without('oe_acronym') if _key|first != '#' %}
   {% set _value %}
     {{ _field|field_value }}
   {% endset %}
-  {% if _value is not empty %}
+  {% if _value|trim is not empty %}
     {% set _items = _items|merge([{
       term: _field|field_label,
       definition: _value,
diff --git a/tests/src/PatternAssertions/ContentBannerAssert.php b/tests/src/PatternAssertions/ContentBannerAssert.php
index d83d8ce8..764d3d7f 100644
--- a/tests/src/PatternAssertions/ContentBannerAssert.php
+++ b/tests/src/PatternAssertions/ContentBannerAssert.php
@@ -29,7 +29,7 @@ class ContentBannerAssert extends BasePatternAssert {
       ],
       'description' => [
         [$this, 'assertElementText'],
-        '.card-body .mt-4',
+        '.card-body',
       ],
     ];
   }
diff --git a/tests/src/PatternAssertions/DescriptionListAssert.php b/tests/src/PatternAssertions/DescriptionListAssert.php
index b8d376a5..be89d749 100644
--- a/tests/src/PatternAssertions/DescriptionListAssert.php
+++ b/tests/src/PatternAssertions/DescriptionListAssert.php
@@ -29,7 +29,7 @@ class DescriptionListAssert extends BasePatternAssert {
    */
   protected function assertBaseElements(string $html): void {
     $crawler = new Crawler($html);
-    $field_list_container = $crawler->filter('body');
+    $field_list_container = $crawler->filter('dl');
     self::assertCount(1, $field_list_container);
   }
 
-- 
GitLab


From d3716f12c2a837424d50a9bae0ced5577c4d2b9e Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 1 Apr 2022 01:38:02 +0200
Subject: [PATCH 016/152] OEL-1297: Simplify check for is image in preprocess.

---
 .../oe_whitelabel_extra_project.module                       | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 8eae445e..650ce867 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -64,10 +64,9 @@ function _oe_whitelabel_extra_project_preprocess_featured_media(&$variables) {
 
   // Get the media source.
   $source = $media->getSource();
-  $media_source = $source instanceof OEmbed || $source instanceof Image;
 
-  // If it's not an image and not a video, bail out.
-  if (!$media_source) {
+  if (!$source instanceof OEmbed && !$source instanceof Image) {
+    // Media is not a video or image, no thumbnail will be shown.
     $cacheability->applyTo($variables);
     return;
   }
-- 
GitLab


From c96b5f7c83a6d137a74d3a0768631998fa301c40 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 1 Apr 2022 01:38:45 +0200
Subject: [PATCH 017/152] OEL-1297: Add field group formatter plugin and base
 class.

---
 .../DescriptionListPattern.php                | 105 +++++++++++
 .../PatternFormatterBase.php                  | 166 ++++++++++++++++++
 2 files changed, 271 insertions(+)
 create mode 100644 modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
 create mode 100644 modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/PatternFormatterBase.php

diff --git a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
new file mode 100644
index 00000000..67d001fa
--- /dev/null
+++ b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
@@ -0,0 +1,105 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\oe_whitelabel_helper\Plugin\field_group\FieldGroupFormatter;
+
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Render\Element;
+use Drupal\Core\Render\RendererInterface;
+use Drupal\ui_patterns\UiPatternsManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Format a field group using the field list pattern.
+ *
+ * @FieldGroupFormatter(
+ *   id = "oe_whitelabel_helper_field_list_pattern",
+ *   label = @Translation("Description field list pattern"),
+ *   description = @Translation("Format a field group using the description list pattern."),
+ *   supported_contexts = {
+ *     "view"
+ *   }
+ * )
+ */
+class DescriptionListPattern extends PatternFormatterBase implements ContainerFactoryPluginInterface {
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The renderer service.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * Constructs a DescriptionList object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin ID for the plugin instance.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer.
+   * @param \Drupal\ui_patterns\UiPatternsManager $patterns_manager
+   *   The pattern manager.
+   */
+  public function __construct(array $configuration, string $plugin_id, array $plugin_definition, EntityTypeManagerInterface $entity_type_manager, RendererInterface $renderer, UiPatternsManager $patterns_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $patterns_manager);
+    $this->entityTypeManager = $entity_type_manager;
+    $this->renderer = $renderer;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity_type.manager'),
+      $container->get('renderer'),
+      $container->get('plugin.manager.ui_patterns')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getPatternId(): string {
+    return 'description_list';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getFields(array &$element, $rendering_object): array {
+    $fields = [];
+
+    foreach (Element::children($element) as $field_name) {
+      $build = [
+        '#label_display' => 'hidden',
+      ] + $element[$field_name];
+
+      // Assign field label and content to the pattern's fields.
+      $fields['items'][] = [
+        'term' => $element[$field_name]['#title'] ?? '',
+        'definition' => $this->renderer->render($build),
+      ];
+    }
+
+    return $fields;
+  }
+
+}
diff --git a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/PatternFormatterBase.php b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/PatternFormatterBase.php
new file mode 100644
index 00000000..8d3f2c8e
--- /dev/null
+++ b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/PatternFormatterBase.php
@@ -0,0 +1,166 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\oe_whitelabel_helper\Plugin\field_group\FieldGroupFormatter;
+
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Render\Element;
+use Drupal\field_group\FieldGroupFormatterBase;
+use Drupal\ui_patterns\UiPatternsManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Base class for field group formatters that use a pattern for rendering.
+ *
+ * Field group formatters extending this class generate a pattern context that
+ * is compatible with the one generated by the ui_patterns_field_group module.
+ *
+ * If you need to override pattern templates based on node, bundle or view mode
+ * just enable the ui_patterns_field_group module.
+ *
+ * @see https://ui-patterns.readthedocs.io/en/8.x-1.x/content/developer-documentation.html#working-with-pattern-suggestions
+ */
+abstract class PatternFormatterBase extends FieldGroupFormatterBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * UI Patterns manager.
+   *
+   * @var \Drupal\ui_patterns\UiPatternsManager
+   */
+  protected $patternsManager;
+
+  /**
+   * PatternFormatterBase constructor.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param array $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\ui_patterns\UiPatternsManager $patterns_manager
+   *   UI Patterns manager.
+   */
+  public function __construct(array $configuration, string $plugin_id, array $plugin_definition, UiPatternsManager $patterns_manager) {
+    parent::__construct($plugin_id, $plugin_definition, $configuration['group'], $configuration['settings'], $configuration['label']);
+    $this->configuration = $configuration;
+    $this->patternsManager = $patterns_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('plugin.manager.ui_patterns')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function defaultSettings() {
+    return [
+      'label' => '',
+      'variant' => '',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm() {
+    $pattern = $this->patternsManager->getDefinition($this->getPatternId());
+
+    $form['label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Field group label'),
+      '#default_value' => $this->label,
+    ];
+
+    if ($pattern->hasVariants()) {
+      $form['variant'] = [
+        '#title' => $this->t('Variant'),
+        '#type' => 'select',
+        '#options' => $pattern->getVariantsAsOptions(),
+        '#default_value' => $this->getSetting('variant'),
+      ];
+    }
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = [];
+
+    if ($this->getSetting('label')) {
+      $summary[] = $this->t('Label: @label', ['@label' => $this->getSetting('label')]);
+    }
+
+    if ($this->getSetting('variant')) {
+      $summary[] = $this->t('Variant: @variant', ['@variant' => $this->getSetting('variant')]);
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preRender(&$element, $rendering_object) {
+    parent::preRender($element, $rendering_object);
+
+    // Instantiate the pattern render array.
+    $pattern = [
+      '#type' => 'pattern',
+      '#id' => $this->getPatternId(),
+      '#variant' => $this->getSetting('variant'),
+      '#fields' => $this->getFields($element, $rendering_object),
+      '#context' => [
+        'type' => 'field_group',
+        'group_name' => $element['#group_name'],
+        'entity_type' => $element['#entity_type'],
+        'bundle' => $element['#bundle'],
+        'view_mode' => $this->group->mode,
+      ],
+    ];
+
+    // Remove all renderable elements, while keeping render metadata as that can
+    // be used to further manipulate the render array.
+    foreach (Element::children($element) as $key) {
+      unset($element[$key]);
+    }
+    $element += [
+      'pattern' => $pattern,
+    ];
+  }
+
+  /**
+   * Return pattern ID for the current formatter plugin.
+   *
+   * @return string
+   *   Pattern ID.
+   */
+  abstract protected function getPatternId(): string;
+
+  /**
+   * Return list of fields for the current pattern.
+   *
+   * @param array $element
+   *   Field group render element.
+   * @param object $rendering_object
+   *   Field group rendering object.
+   *
+   * @return array
+   *   Pattern fields to be rendered, or an empty array if none.
+   */
+  abstract protected function getFields(array &$element, $rendering_object): array;
+
+}
-- 
GitLab


From 6a0a438ac84bbbdbc9010a5f5cfaaa1934e449e0 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 1 Apr 2022 01:24:37 +0200
Subject: [PATCH 018/152] OEL-1297: Fix field group formatter comment and
 label.

---
 .../FieldGroupFormatter/DescriptionListPattern.php          | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
index 67d001fa..7130a40d 100644
--- a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
+++ b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
@@ -12,11 +12,11 @@ use Drupal\ui_patterns\UiPatternsManager;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
- * Format a field group using the field list pattern.
+ * Format a field group using the description list pattern.
  *
  * @FieldGroupFormatter(
- *   id = "oe_whitelabel_helper_field_list_pattern",
- *   label = @Translation("Description field list pattern"),
+ *   id = "oe_whitelabel_helper_description_list_pattern",
+ *   label = @Translation("Description list pattern"),
  *   description = @Translation("Format a field group using the description list pattern."),
  *   supported_contexts = {
  *     "view"
-- 
GitLab


From b85812f8f7021aed4165c8a6fe984c39f2325593 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 1 Apr 2022 01:25:16 +0200
Subject: [PATCH 019/152] OEL-1297: Always use horizontal orientation in field
 group formatter.

---
 .../FieldGroupFormatter/DescriptionListPattern.php       | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
index 7130a40d..b6314073 100644
--- a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
+++ b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
@@ -81,6 +81,15 @@ class DescriptionListPattern extends PatternFormatterBase implements ContainerFa
     return 'description_list';
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function preRender(&$element, $rendering_object) {
+    parent::preRender($element, $rendering_object);
+    // Only support horizontal mode in this field group formatter.
+    $element['pattern']['#settings']['orientation'] = 'horizontal';
+  }
+
   /**
    * {@inheritdoc}
    */
-- 
GitLab


From 898a3939df53a1b42545661c3e1fbda2b8cc79af Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 1 Apr 2022 01:26:58 +0200
Subject: [PATCH 020/152] OEL-1297: Rename some variables and simplify code in
 field group formatter.

---
 .../FieldGroupFormatter/DescriptionListPattern.php | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
index b6314073..2db1d77a 100644
--- a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
+++ b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
@@ -97,14 +97,16 @@ class DescriptionListPattern extends PatternFormatterBase implements ContainerFa
     $fields = [];
 
     foreach (Element::children($element) as $field_name) {
-      $build = [
-        '#label_display' => 'hidden',
-      ] + $element[$field_name];
-
+      $field_element = $element[$field_name];
+      $field_element['#label_display'] = 'hidden';
+      $field_markup = $this->renderer->render($field_element);
+      if (trim((string) $field_markup) === '') {
+        continue;
+      }
       // Assign field label and content to the pattern's fields.
       $fields['items'][] = [
-        'term' => $element[$field_name]['#title'] ?? '',
-        'definition' => $this->renderer->render($build),
+        'term' => $field_element['#title'] ?? '',
+        'definition' => $field_markup,
       ];
     }
 
-- 
GitLab


From f6f81af248e9863b909ac681602cfbc0dba4f27d Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 1 Apr 2022 01:28:08 +0200
Subject: [PATCH 021/152] OEL-1297: Remove old field group templates.

---
 ...--node--oe-project--group-budget.html.twig | 25 ---------------
 ...--oe-project--group-coordinators.html.twig | 25 ---------------
 ...--node--oe-project--group-period.html.twig | 25 ---------------
 ...e-project--group-project-details.html.twig | 32 -------------------
 4 files changed, 107 deletions(-)
 delete mode 100644 templates/content/field-group-html-element--node--oe-project--group-budget.html.twig
 delete mode 100644 templates/content/field-group-html-element--node--oe-project--group-coordinators.html.twig
 delete mode 100644 templates/content/field-group-html-element--node--oe-project--group-period.html.twig
 delete mode 100644 templates/content/field-group-html-element--node--oe-project--group-project-details.html.twig

diff --git a/templates/content/field-group-html-element--node--oe-project--group-budget.html.twig b/templates/content/field-group-html-element--node--oe-project--group-budget.html.twig
deleted file mode 100644
index a5468863..00000000
--- a/templates/content/field-group-html-element--node--oe-project--group-budget.html.twig
+++ /dev/null
@@ -1,25 +0,0 @@
-{#
-/**
- * @file
- * Budget field group theme implementation.
- *
- * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
- */
-#}
-{% set _items = [] %}
-{% for _field in element if _key|first != '#' %}
-  {% set _value %}
-    {{ _field|field_value }}
-  {% endset %}
-  {% if _value is not empty %}
-    {% set _items = _items|merge([{
-      term: _field|field_label,
-      definition: _value,
-    }]) %}
-  {% endif %}
-{% endfor %}
-{{ pattern('description_list', {
-  items: _items,
-  orientation: 'horizontal',
-  attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
-}) }}
diff --git a/templates/content/field-group-html-element--node--oe-project--group-coordinators.html.twig b/templates/content/field-group-html-element--node--oe-project--group-coordinators.html.twig
deleted file mode 100644
index f8fa53dd..00000000
--- a/templates/content/field-group-html-element--node--oe-project--group-coordinators.html.twig
+++ /dev/null
@@ -1,25 +0,0 @@
-{#
-/**
- * @file
- * Coordinator field group theme implementation.
- *
- * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
- */
-#}
-{% set _items = [] %}
-{% for _field in element if _key|first != '#' and _field|field_value %}
-  {% set _value %}
-    {{ _field|field_value }}
-  {% endset %}
-  {% if _value is not empty %}
-    {% set _items = _items|merge([{
-      term: _field|field_label,
-      definition: _value,
-    }]) %}
-  {% endif %}
-{% endfor %}
-{{ pattern('description_list', {
-  items: _items,
-  orientation: 'horizontal',
-  attributes: create_attribute().addClass(['mt-3', 'mb-4']),
-}) }}
diff --git a/templates/content/field-group-html-element--node--oe-project--group-period.html.twig b/templates/content/field-group-html-element--node--oe-project--group-period.html.twig
deleted file mode 100644
index 370881f6..00000000
--- a/templates/content/field-group-html-element--node--oe-project--group-period.html.twig
+++ /dev/null
@@ -1,25 +0,0 @@
-{#
-/**
- * @file
- * Period field group theme implementation.
- *
- * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
- */
-#}
-{% set _items = [] %}
-{% for _field in element if _key|first != '#' %}
-  {% set _value %}
-    {{ _field|field_value }}
-  {% endset %}
-  {% if _value is not empty %}
-    {% set _items = _items|merge([{
-      term: _field|field_label,
-      definition: _value,
-    }]) %}
-  {% endif %}
-{% endfor %}
-{{ pattern('description_list', {
-  items: _items,
-  orientation: 'horizontal',
-  attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
-}) }}
diff --git a/templates/content/field-group-html-element--node--oe-project--group-project-details.html.twig b/templates/content/field-group-html-element--node--oe-project--group-project-details.html.twig
deleted file mode 100644
index 8506238d..00000000
--- a/templates/content/field-group-html-element--node--oe-project--group-project-details.html.twig
+++ /dev/null
@@ -1,32 +0,0 @@
-{#
-/**
- * @file
- * Details field group theme implementation.
- *
- * @see ./modules/contrib/field_group/templates/field-group-html-element.html.twig
- */
-#}
-{% if title %}
-  <h3 id="oe-project-oe-project-dates" class="fw-bold mb-4">
-    {{ title }}
-  </h3>
-{% endif %}
-{{ element.group_period }}
-{{ element.group_budget }}
-{% set _items = [] %}
-{% for _field in element if _key|first != '#' and _field|field_value  %}
-  {% set _value %}
-    {{ _field|field_value }}
-  {% endset %}
-  {% if _value is not empty %}
-    {% set _items = _items|merge([{
-      term: _field|field_label,
-      definition: _value,
-    }]) %}
-  {% endif %}
-{% endfor %}
-{{ pattern('description_list', {
-  items: _items,
-  orientation: 'horizontal',
-  attributes: create_attribute().addClass(['mt-3', 'mb-4', 'border-bottom']),
-}) }}
-- 
GitLab


From e002f0ac32a226f7934a6cb8ee9fb5765f309f64 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 1 Apr 2022 01:28:42 +0200
Subject: [PATCH 022/152] OEL-1297: Remove group_stakeholders.

---
 templates/content/node--oe-project--full.html.twig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 1275f3cb..7e1c70ef 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -33,8 +33,8 @@
   {{ _self.field_with_header(content.oe_summary) }}
   {{ _self.field_with_header(content.oe_cx_objective) }}
   {{ _self.field_with_header(content.oe_cx_impacts) }}
-  {{ _self.field_with_header(content.group_stakeholders.oe_project_participants) }}
-  {{ _self.field_with_header(content.group_stakeholders.oe_cx_lead_contributors) }}
+  {{ _self.field_with_header(content.oe_project_participants) }}
+  {{ _self.field_with_header(content.oe_cx_lead_contributors) }}
   {{ _self.field_with_header(content.oe_cx_achievements_and_milestone) }}
 {% endset %}
 <div class="mt-md-4-75 mt-4">
-- 
GitLab


From 5315e514b84ef5739b2e376721bd74cc42241b80 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 1 Apr 2022 01:29:30 +0200
Subject: [PATCH 023/152] OEL-1297: Drop template for oe_organisation. No
 longer needed.

---
 .../oe-organisation--default.html.twig        | 21 -------------------
 1 file changed, 21 deletions(-)
 delete mode 100644 templates/content/oe-organisation--default.html.twig

diff --git a/templates/content/oe-organisation--default.html.twig b/templates/content/oe-organisation--default.html.twig
deleted file mode 100644
index 7894c801..00000000
--- a/templates/content/oe-organisation--default.html.twig
+++ /dev/null
@@ -1,21 +0,0 @@
-{% if elements.oe_acronym is not empty %}
-  <h4 class="fw-bold mb-3">{{ elements.oe_acronym }}</h4>
-{% endif %}
-{% set _items = [] %}
-{% for _field in elements|without('oe_acronym') if _key|first != '#' %}
-  {% set _value %}
-    {{ _field|field_value }}
-  {% endset %}
-  {% if _value|trim is not empty %}
-    {% set _items = _items|merge([{
-      term: _field|field_label,
-      definition: _value,
-    }]) %}
-  {% endif %}
-{% endfor %}
-{{ pattern('description_list', {
-  items: _items,
-  orientation: 'horizontal',
-  attributes: create_attribute().addClass(['border-bottom', 'mt-3', 'mb-4']),
-}) }}
-
-- 
GitLab


From e6edf7a0454bf2327aec585ae07726c7942a7c53 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 1 Apr 2022 01:33:42 +0200
Subject: [PATCH 024/152] OEL-1297: Update project full view mode.

---
 ...tity_view_display.node.oe_project.full.yml | 87 ++++++++-----------
 1 file changed, 36 insertions(+), 51 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
index fa9cae6c..f02ed113 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
@@ -39,36 +39,16 @@ dependencies:
     - user
 third_party_settings:
   field_group:
-    group_stakeholders:
-      children:
-        - oe_project_participants
-        - oe_cx_lead_contributors
-      label: Stakeholders
-      parent_name: ''
-      region: content
-      weight: 7
-      format_type: html_element
-      format_settings:
-        classes: ''
-        id: ''
-        element: div
-        show_label: false
-        label_element: h3
-        label_element_classes: ''
-        attributes: ''
-        effect: none
-        speed: fast
     group_project_details:
       children:
         - group_period
         - group_budget
-        - oe_project_website
-        - oe_project_funding_programme
-        - oe_reference_code
+        - group_website
+        - group_coordinators
       label: 'Project details'
       parent_name: ''
       region: content
-      weight: 0
+      weight: 2
       format_type: html_element
       format_settings:
         classes: ''
@@ -85,14 +65,16 @@ third_party_settings:
       children:
         - oe_project_coordinators
       label: Coordinators
-      parent_name: ''
+      parent_name: group_project_details
       region: content
-      weight: 1
-      format_type: html_element
+      weight: 3
+      format_type: oe_whitelabel_helper_description_list_pattern
       format_settings:
         classes: ''
         show_empty_fields: false
         id: ''
+        formatter: closed
+        description: ''
         element: div
         show_label: false
         label_element: div
@@ -107,18 +89,8 @@ third_party_settings:
       parent_name: group_project_details
       region: content
       weight: 0
-      format_type: html_element
-      format_settings:
-        classes: ''
-        show_empty_fields: false
-        id: ''
-        element: div
-        show_label: false
-        label_element: h3
-        label_element_classes: ''
-        attributes: ''
-        effect: none
-        speed: fast
+      format_type: oe_whitelabel_helper_description_list_pattern
+      format_settings: {  }
     group_budget:
       children:
         - oe_project_budget
@@ -127,11 +99,13 @@ third_party_settings:
       parent_name: group_project_details
       region: content
       weight: 1
-      format_type: html_element
+      format_type: oe_whitelabel_helper_description_list_pattern
       format_settings:
         classes: ''
         show_empty_fields: false
         id: ''
+        formatter: closed
+        description: ''
         element: div
         show_label: false
         label_element: h3
@@ -139,6 +113,17 @@ third_party_settings:
         attributes: ''
         effect: none
         speed: fast
+    group_website:
+      children:
+        - oe_project_website
+        - oe_project_funding_programme
+        - oe_reference_code
+      label: Website
+      parent_name: group_project_details
+      region: content
+      weight: 2
+      format_type: oe_whitelabel_helper_description_list_pattern
+      format_settings: {  }
 id: node.oe_project.full
 targetEntityType: node
 bundle: oe_project
@@ -149,14 +134,14 @@ content:
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 11
+    weight: 8
     region: content
   oe_cx_impacts:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 6
+    weight: 5
     region: content
   oe_cx_lead_contributors:
     type: entity_reference_revisions_entity_view
@@ -165,14 +150,14 @@ content:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 10
+    weight: 7
     region: content
   oe_cx_objective:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 5
+    weight: 4
     region: content
   oe_project_budget:
     type: number_decimal
@@ -203,7 +188,7 @@ content:
       view_mode: name
       link: ''
     third_party_settings: {  }
-    weight: 7
+    weight: 4
     region: content
   oe_project_dates:
     type: daterange_default
@@ -221,7 +206,7 @@ content:
     settings:
       link: true
     third_party_settings: {  }
-    weight: 3
+    weight: 4
     region: content
   oe_project_participants:
     type: entity_reference_revisions_entity_view
@@ -230,7 +215,7 @@ content:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 9
+    weight: 6
     region: content
   oe_project_website:
     type: link
@@ -242,7 +227,7 @@ content:
       rel: ''
       target: ''
     third_party_settings: {  }
-    weight: 2
+    weight: 3
     region: content
   oe_reference_code:
     type: string
@@ -250,7 +235,7 @@ content:
     settings:
       link_to_entity: false
     third_party_settings: {  }
-    weight: 4
+    weight: 5
     region: content
   oe_subject:
     type: skos_concept_entity_reference_label
@@ -258,21 +243,21 @@ content:
     settings:
       link: false
     third_party_settings: {  }
-    weight: 3
+    weight: 1
     region: content
   oe_summary:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 4
+    weight: 3
     region: content
   oe_teaser:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 2
+    weight: 0
     region: content
 hidden:
   body: true
-- 
GitLab


From be43dc7b05b811c08b3b055ce54288a36cdf6939 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 1 Apr 2022 01:34:28 +0200
Subject: [PATCH 025/152] OEL-1297: Update stakeholder with budget default view
 mode, using new field group formatter.

---
 ...tion.oe_cx_project_stakeholder.default.yml | 25 ++++++++++++++++---
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
index f8360f5a..4bc5d55b 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
@@ -10,7 +10,24 @@ dependencies:
     - field.field.oe_organisation.oe_cx_project_stakeholder.oe_website
     - oe_content_entity_organisation.oe_organisation_type.oe_cx_project_stakeholder
   module:
+    - field_group
     - oe_whitelabel_helper
+third_party_settings:
+  field_group:
+    group_info:
+      children:
+        - name
+        - oe_address
+        - oe_acronym
+        - oe_cx_contribution_budget
+      label: Info
+      parent_name: ''
+      region: content
+      weight: 0
+      format_type: oe_whitelabel_helper_description_list_pattern
+      format_settings:
+        classes: ''
+        id: ''
 id: oe_organisation.oe_cx_project_stakeholder.default
 targetEntityType: oe_organisation
 bundle: oe_cx_project_stakeholder
@@ -22,7 +39,7 @@ content:
     settings:
       link_to_entity: false
     third_party_settings: {  }
-    weight: 0
+    weight: 1
     region: content
   oe_acronym:
     type: string
@@ -30,7 +47,7 @@ content:
     settings:
       link_to_entity: false
     third_party_settings: {  }
-    weight: 2
+    weight: 3
     region: content
   oe_address:
     type: oe_whitelabel_helper_address_inline
@@ -38,7 +55,7 @@ content:
     settings:
       delimiter: ', '
     third_party_settings: {  }
-    weight: 1
+    weight: 2
     region: content
   oe_cx_contribution_budget:
     type: number_decimal
@@ -49,7 +66,7 @@ content:
       scale: 2
       prefix_suffix: true
     third_party_settings: {  }
-    weight: 3
+    weight: 4
     region: content
 hidden:
   created: true
-- 
GitLab


From 92680bb4d9b97d3e56719a45534426c0568b03a5 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 1 Apr 2022 02:29:26 +0200
Subject: [PATCH 026/152] OEL-1297: Move the twig module dependency to
 oe_whitelabel_helper.

---
 modules/oe_whitelabel_helper/oe_whitelabel_helper.info.yml | 1 +
 oe_whitelabel.info.yml                                     | 3 ---
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/modules/oe_whitelabel_helper/oe_whitelabel_helper.info.yml b/modules/oe_whitelabel_helper/oe_whitelabel_helper.info.yml
index 91e08098..e28b7efa 100644
--- a/modules/oe_whitelabel_helper/oe_whitelabel_helper.info.yml
+++ b/modules/oe_whitelabel_helper/oe_whitelabel_helper.info.yml
@@ -5,6 +5,7 @@ package: OpenEuropa Whitelabel Theme
 core_version_requirement: ^9.2
 
 dependencies:
+  - drupal:twig_field_value
   - oe_bootstrap_theme:oe_bootstrap_theme_helper
   - openeuropa:oe_corporate_blocks
 
diff --git a/oe_whitelabel.info.yml b/oe_whitelabel.info.yml
index 1ef10bd4..c3e080e8 100644
--- a/oe_whitelabel.info.yml
+++ b/oe_whitelabel.info.yml
@@ -5,9 +5,6 @@ type: theme
 base theme: oe_bootstrap_theme
 core_version_requirement: ^8.9 || ^9.1
 
-dependencies:
-  - drupal:twig_field_value
-
 libraries:
   - oe_whitelabel/style
 
-- 
GitLab


From ea04b06cfb09dd4f44b763a3a36327aac56a4dfd Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 1 Apr 2022 02:30:23 +0200
Subject: [PATCH 027/152] OEL-1297: Add test for the formatter.

---
 .../field_group/PatternFormatterTest.php      | 143 ++++++++++++++++++
 1 file changed, 143 insertions(+)
 create mode 100644 modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php

diff --git a/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php b/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php
new file mode 100644
index 00000000..d7952ca1
--- /dev/null
+++ b/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php
@@ -0,0 +1,143 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel_helper\Functional\Plugin\field_group;
+
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\field_group\Functional\FieldGroupTestTrait;
+
+/**
+ * Test the pattern field group formatter.
+ **/
+class PatternFormatterTest extends BrowserTestBase {
+
+  use FieldGroupTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'node',
+    'text',
+    'field_ui',
+    'field_group',
+    'oe_whitelabel_helper',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp(): void {
+    parent::setUp();
+
+    // Enable oe_theme and set it as default.
+    $this->assertTrue($this->container->get('theme_installer')->install(['oe_whitelabel']));
+    $this->container->get('config.factory')
+      ->getEditable('system.theme')
+      ->set('default', 'oe_whitelabel')
+      ->save();
+
+    // Rebuild the ui_pattern definitions to collect the ones provided by
+    // oe_theme itself.
+    $this->container->get('plugin.manager.ui_patterns')->clearCachedDefinitions();
+
+    // Create test user.
+    $admin_user = $this->drupalCreateUser([
+      'access content',
+      'administer content types',
+      'administer node fields',
+      'administer node form display',
+      'administer node display',
+      'bypass node access',
+    ]);
+    $this->drupalLogin($admin_user);
+
+    // Create content type.
+    $this->drupalCreateContentType([
+      'name' => 'Test',
+      'type' => 'test',
+    ]);
+
+    /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */
+    $display = \Drupal::entityTypeManager()
+      ->getStorage('entity_view_display')
+      ->load('node.test.default');
+
+    // Create test fields.
+    $fields = [
+      'field_test_1' => 'Field 1',
+      'field_test_2' => 'Field 2',
+    ];
+    foreach ($fields as $field_name => $field_label) {
+      $field_storage = FieldStorageConfig::create([
+        'field_name' => $field_name,
+        'entity_type' => 'node',
+        'type' => 'text',
+      ]);
+      $field_storage->save();
+
+      $instance = FieldConfig::create([
+        'field_storage' => $field_storage,
+        'bundle' => 'test',
+        'label' => $field_label,
+      ]);
+      $instance->save();
+
+      // Set the field visible on the display object.
+      $display->setComponent($field_name, [
+        'label' => 'above',
+        'type' => 'text_default',
+      ]);
+    }
+
+    // Save display + create node.
+    $display->save();
+  }
+
+  /**
+   * Test description list pattern formatter.
+   */
+  public function testDescriptionListPatternFormatter() {
+    $data = [
+      'weight' => '1',
+      'children' => [
+        0 => 'field_test_1',
+        1 => 'field_test_2',
+      ],
+      'label' => 'Test label',
+      'format_type' => 'oe_whitelabel_helper_description_list_pattern',
+    ];
+    $group = $this->createGroup('node', 'test', 'view', 'default', $data);
+
+    $this->drupalCreateNode([
+      'type' => 'test',
+      'field_test_1' => [
+        ['value' => 'Content test 1'],
+      ],
+      'field_test_2' => [
+        ['value' => 'Content test 2'],
+      ],
+    ]);
+
+    field_group_group_save($group);
+
+    // Assert that fields are rendered using the field list horizontal pattern.
+    $this->drupalGet('node/1');
+
+    $element_selector = 'dl';
+    $this->assertSession()->elementExists('css', $element_selector);
+    $this->assertSession()->elementTextContains('css', $element_selector . ' dt:nth-child(1)', 'Field 1');
+    $this->assertSession()->elementTextContains('css', $element_selector . ' dd:nth-child(2)', 'Content test 1');
+    $this->assertSession()->elementTextContains('css', $element_selector . ' dt:nth-child(3)', 'Field 2');
+    $this->assertSession()->elementTextContains('css', $element_selector . ' dd:nth-child(4)', 'Content test 2');
+  }
+
+}
-- 
GitLab


From 17154d0466dbb348295fe646bdbc75aeed1f2daf Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 1 Apr 2022 14:03:35 +0200
Subject: [PATCH 028/152] OEL-1297: Add separator lines (border-bottom) under
 field groups.

---
 .../oe_whitelabel_extra_project.module        | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 650ce867..072ef646 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -14,6 +14,32 @@ use Drupal\media\Plugin\media\Source\OEmbed;
 use Drupal\oe_bootstrap_theme\ValueObject\ImageValueObject;
 use Drupal\Component\Utility\Html;
 
+/**
+ * Implements hook_preprocess().
+ */
+function oe_whitelabel_extra_project_preprocess_pattern_description_list(array &$variables): void {
+  /** @var \Drupal\ui_patterns\Element\PatternContext $context */
+  $context = $variables['context'];
+  if ($context->getType() === 'field_group') {
+    $id = $context->getProperty('entity_type')
+      . '.' . $context->getProperty('bundle')
+      . '.' . $context->getProperty('view_mode')
+      . '.' . $context->getProperty('group_name');
+    switch ($id) {
+      case 'oe_organisation.oe_cx_project_stakeholder.default.group_info':
+      case 'node.oe_project.full.group_project_details':
+      case 'node.oe_project.full.group_coordinators':
+      case 'node.oe_project.full.group_period':
+      case 'node.oe_project.full.group_budget':
+      case 'node.oe_project.full.group_website':
+        /** @var \Drupal\Core\Template\Attribute $attributes */
+        $attributes = $variables['attributes'];
+        $attributes->addClass('border-bottom');
+        break;
+    }
+  }
+}
+
 /**
  * Implements template_preprocess_node() for the project node type.
  */
-- 
GitLab


From 9c6bb6c304b03961445d4c543920e41ec46401a9 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 1 Apr 2022 03:22:39 +0200
Subject: [PATCH 029/152] OEL-1297: Remove redundant interface in field group
 formatter class.

---
 .../field_group/FieldGroupFormatter/DescriptionListPattern.php | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
index 2db1d77a..85036892 100644
--- a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
+++ b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
@@ -5,7 +5,6 @@ declare(strict_types = 1);
 namespace Drupal\oe_whitelabel_helper\Plugin\field_group\FieldGroupFormatter;
 
 use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\ui_patterns\UiPatternsManager;
@@ -23,7 +22,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
  *   }
  * )
  */
-class DescriptionListPattern extends PatternFormatterBase implements ContainerFactoryPluginInterface {
+class DescriptionListPattern extends PatternFormatterBase {
   /**
    * The entity type manager.
    *
-- 
GitLab


From ec1e23992e7f0b69d45bf7333287e2223be27aba Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 1 Apr 2022 03:23:49 +0200
Subject: [PATCH 030/152] OEL-1297: Remove group_coordinators from project
 template, it is rendered as part of group_project_details.

---
 templates/content/node--oe-project--full.html.twig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 7e1c70ef..f0140376 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -29,7 +29,6 @@
 {% endmacro %}
 {% set inpage_navigation_fields %}
   {{ content.group_project_details }}
-  {{ content.group_coordinators }}
   {{ _self.field_with_header(content.oe_summary) }}
   {{ _self.field_with_header(content.oe_cx_objective) }}
   {{ _self.field_with_header(content.oe_cx_impacts) }}
-- 
GitLab


From 2c929b5b1c24b18f07ec9fc4632e151b88145176 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 1 Apr 2022 04:08:43 +0200
Subject: [PATCH 031/152] OEL-1297: Fix tests for pattern assertion and modify
 the schema for full project viewmode.

---
 .../schema/oe_whitelabel_helper.schema.yml    | 43 +++++++++++++++++++
 .../field_group/PatternFormatterTest.php      | 22 +++++-----
 .../Functional/ContentProjectRenderTest.php   |  2 +-
 .../PatternAssertions/ContentBannerAssert.php |  2 +-
 .../DescriptionListAssert.php                 |  2 +-
 5 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/modules/oe_whitelabel_helper/config/schema/oe_whitelabel_helper.schema.yml b/modules/oe_whitelabel_helper/config/schema/oe_whitelabel_helper.schema.yml
index df4af465..26601395 100644
--- a/modules/oe_whitelabel_helper/config/schema/oe_whitelabel_helper.schema.yml
+++ b/modules/oe_whitelabel_helper/config/schema/oe_whitelabel_helper.schema.yml
@@ -10,3 +10,46 @@ condition.plugin.oe_whitelabel_helper_current_component_library:
   mapping:
     component_library:
       type: string
+field_group.field_group_formatter_plugin.oe_whitelabel_helper_pattern_base:
+  type: field_group.field_group_formatter_plugin.base
+  label: 'Mapping for the base pattern formatter settings'
+  mapping:
+    classes:
+      type: string
+      label: 'Classes of the fieldgroup'
+    show_empty_fields:
+      type: boolean
+      label: 'Show Empty Fields'
+    id:
+      type: string
+      label: 'Html id of the fieldgroup'
+    formatter:
+      type: string
+      label: 'Formatting of the item'
+    description:
+      type: text
+      label: 'Description'
+    element:
+      type: string
+      label: 'html element tag to be used'
+    show_label:
+      type: boolean
+      label: 'show the label'
+    label_element:
+      type: string
+      label: 'html element tag to be used for the label'
+    label_element_classes:
+      type: string
+      label: 'html classes to be used for the label'
+    attributes:
+      type: string
+      label: 'html attributes for the element'
+    effect:
+      type: string
+      label: 'effect on the element'
+    speed:
+      type: string
+      label: 'speed of the effect'
+field_group.field_group_formatter_plugin.oe_whitelabel_helper_description_list_pattern:
+  type: field_group.field_group_formatter_plugin.oe_whitelabel_helper_pattern_base
+  label: 'Mapping for the description list pattern formatter settings'
diff --git a/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php b/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php
index d7952ca1..bb298765 100644
--- a/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php
+++ b/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php
@@ -10,8 +10,8 @@ use Drupal\Tests\BrowserTestBase;
 use Drupal\Tests\field_group\Functional\FieldGroupTestTrait;
 
 /**
- * Test the pattern field group formatter.
- **/
+ * Test the Description list pattern field group formatter.
+ */
 class PatternFormatterTest extends BrowserTestBase {
 
   use FieldGroupTestTrait;
@@ -38,7 +38,7 @@ class PatternFormatterTest extends BrowserTestBase {
   public function setUp(): void {
     parent::setUp();
 
-    // Enable oe_theme and set it as default.
+    // Enable oe_whitelabel and set it as default.
     $this->assertTrue($this->container->get('theme_installer')->install(['oe_whitelabel']));
     $this->container->get('config.factory')
       ->getEditable('system.theme')
@@ -46,7 +46,7 @@ class PatternFormatterTest extends BrowserTestBase {
       ->save();
 
     // Rebuild the ui_pattern definitions to collect the ones provided by
-    // oe_theme itself.
+    // oe_whitelabel itself.
     $this->container->get('plugin.manager.ui_patterns')->clearCachedDefinitions();
 
     // Create test user.
@@ -106,6 +106,8 @@ class PatternFormatterTest extends BrowserTestBase {
    * Test description list pattern formatter.
    */
   public function testDescriptionListPatternFormatter() {
+    $assert_session = $this->assertSession();
+
     $data = [
       'weight' => '1',
       'children' => [
@@ -116,6 +118,7 @@ class PatternFormatterTest extends BrowserTestBase {
       'format_type' => 'oe_whitelabel_helper_description_list_pattern',
     ];
     $group = $this->createGroup('node', 'test', 'view', 'default', $data);
+    field_group_group_save($group);
 
     $this->drupalCreateNode([
       'type' => 'test',
@@ -127,17 +130,14 @@ class PatternFormatterTest extends BrowserTestBase {
       ],
     ]);
 
-    field_group_group_save($group);
-
     // Assert that fields are rendered using the field list horizontal pattern.
     $this->drupalGet('node/1');
-
     $element_selector = 'dl';
     $this->assertSession()->elementExists('css', $element_selector);
-    $this->assertSession()->elementTextContains('css', $element_selector . ' dt:nth-child(1)', 'Field 1');
-    $this->assertSession()->elementTextContains('css', $element_selector . ' dd:nth-child(2)', 'Content test 1');
-    $this->assertSession()->elementTextContains('css', $element_selector . ' dt:nth-child(3)', 'Field 2');
-    $this->assertSession()->elementTextContains('css', $element_selector . ' dd:nth-child(4)', 'Content test 2');
+    $assert_session->elementTextContains('css', $element_selector . ' div dt', 'Field 1');
+    $assert_session->elementTextContains('css', $element_selector . ' dd:nth-child(2)', 'Content test 1');
+    $assert_session->elementTextContains('css', $element_selector . ' div:nth-child(3) dt', 'Field 2');
+    $assert_session->elementTextContains('css', $element_selector . ' dd:nth-child(4)', 'Content test 2');
   }
 
 }
diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index 56946e8f..0f1ab870 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -169,7 +169,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       'items' => [
         [
           'term' => 'Project period',
-          'definition' => '10/05/2020 - 15/05/2025',
+          'definition' => "10/05/2020\n - 15/05/2025",
         ],
       ],
     ];
diff --git a/tests/src/PatternAssertions/ContentBannerAssert.php b/tests/src/PatternAssertions/ContentBannerAssert.php
index 764d3d7f..d83d8ce8 100644
--- a/tests/src/PatternAssertions/ContentBannerAssert.php
+++ b/tests/src/PatternAssertions/ContentBannerAssert.php
@@ -29,7 +29,7 @@ class ContentBannerAssert extends BasePatternAssert {
       ],
       'description' => [
         [$this, 'assertElementText'],
-        '.card-body',
+        '.card-body .mt-4',
       ],
     ];
   }
diff --git a/tests/src/PatternAssertions/DescriptionListAssert.php b/tests/src/PatternAssertions/DescriptionListAssert.php
index be89d749..b8d376a5 100644
--- a/tests/src/PatternAssertions/DescriptionListAssert.php
+++ b/tests/src/PatternAssertions/DescriptionListAssert.php
@@ -29,7 +29,7 @@ class DescriptionListAssert extends BasePatternAssert {
    */
   protected function assertBaseElements(string $html): void {
     $crawler = new Crawler($html);
-    $field_list_container = $crawler->filter('dl');
+    $field_list_container = $crawler->filter('body');
     self::assertCount(1, $field_list_container);
   }
 
-- 
GitLab


From 27752b7e5412e0e25a60f0bb985b2fe0d1ace6b5 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 1 Apr 2022 09:34:49 +0200
Subject: [PATCH 032/152] OEL-1297: Change date and budget format.

---
 .../core.date_format.oe_whitelabel_project_date.yml       | 2 +-
 .../core.entity_view_display.node.oe_project.full.yml     | 8 ++++----
 ....oe_organisation.oe_cx_project_stakeholder.default.yml | 2 +-
 tests/src/Functional/ContentProjectRenderTest.php         | 8 ++++----
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.date_format.oe_whitelabel_project_date.yml b/modules/oe_whitelabel_extra_project/config/install/core.date_format.oe_whitelabel_project_date.yml
index 1eb6de1d..42fc99ee 100644
--- a/modules/oe_whitelabel_extra_project/config/install/core.date_format.oe_whitelabel_project_date.yml
+++ b/modules/oe_whitelabel_extra_project/config/install/core.date_format.oe_whitelabel_project_date.yml
@@ -4,4 +4,4 @@ dependencies: {  }
 id: oe_whitelabel_project_date
 label: 'OE Whitelabel Project date'
 locked: false
-pattern: d/m/Y
+pattern: 'd F Y'
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
index f02ed113..a8a4d701 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
@@ -163,8 +163,8 @@ content:
     type: number_decimal
     label: above
     settings:
-      thousand_separator: ''
-      decimal_separator: .
+      thousand_separator: .
+      decimal_separator: ','
       scale: 2
       prefix_suffix: true
     third_party_settings: {  }
@@ -174,8 +174,8 @@ content:
     type: number_decimal
     label: above
     settings:
-      thousand_separator: ''
-      decimal_separator: .
+      thousand_separator: .
+      decimal_separator: ','
       scale: 2
       prefix_suffix: true
     third_party_settings: {  }
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
index 4bc5d55b..42e1be42 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
@@ -62,7 +62,7 @@ content:
     label: above
     settings:
       thousand_separator: .
-      decimal_separator: .
+      decimal_separator: ','
       scale: 2
       prefix_suffix: true
     third_party_settings: {  }
diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index 0f1ab870..97a894db 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -169,7 +169,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       'items' => [
         [
           'term' => 'Project period',
-          'definition' => "10/05/2020\n - 15/05/2025",
+          'definition' => "10 May 2020\n - 15 May 2025",
         ],
       ],
     ];
@@ -182,11 +182,11 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       'items' => [
         [
           'term' => 'Overall budget',
-          'definition' => '€100.00',
+          'definition' => '€100,00',
         ],
         [
           'term' => 'EU contribution',
-          'definition' => '€100.00',
+          'definition' => '€100,00',
         ],
       ],
     ];
@@ -245,7 +245,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
         ],
         [
           'term' => 'Contribution to the budget',
-          'definition' => '€22.30',
+          'definition' => '€22,30',
         ],
       ],
     ];
-- 
GitLab


From 019a0557a0eb026896522ecf5c66428ad96ff227 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 1 Apr 2022 12:12:25 +0200
Subject: [PATCH 033/152] OEL-1297: Modify schema, tests and view mode, fix the
 issue with empty groups.

---
 ...tity_view_display.node.oe_project.full.yml | 42 ++++---------------
 ...tion.oe_cx_project_stakeholder.default.yml |  4 +-
 .../oe_whitelabel_extra_project.module        |  5 ++-
 .../schema/oe_whitelabel_helper.schema.yml    | 40 +++---------------
 .../DescriptionListPattern.php                |  6 ++-
 .../PatternFormatterBase.php                  | 11 +++--
 .../field_group/PatternFormatterTest.php      | 15 +------
 .../content/node--oe-project--full.html.twig  | 36 ++++++++--------
 8 files changed, 53 insertions(+), 106 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
index a8a4d701..91d6e587 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
@@ -69,19 +69,7 @@ third_party_settings:
       region: content
       weight: 3
       format_type: oe_whitelabel_helper_description_list_pattern
-      format_settings:
-        classes: ''
-        show_empty_fields: false
-        id: ''
-        formatter: closed
-        description: ''
-        element: div
-        show_label: false
-        label_element: div
-        label_element_classes: 'field__label fw-bold'
-        attributes: ''
-        effect: none
-        speed: fast
+      format_settings: {  }
     group_period:
       children:
         - oe_project_dates
@@ -100,19 +88,7 @@ third_party_settings:
       region: content
       weight: 1
       format_type: oe_whitelabel_helper_description_list_pattern
-      format_settings:
-        classes: ''
-        show_empty_fields: false
-        id: ''
-        formatter: closed
-        description: ''
-        element: div
-        show_label: false
-        label_element: h3
-        label_element_classes: ''
-        attributes: ''
-        effect: none
-        speed: fast
+      format_settings: {  }
     group_website:
       children:
         - oe_project_website
@@ -161,7 +137,7 @@ content:
     region: content
   oe_project_budget:
     type: number_decimal
-    label: above
+    label: hidden
     settings:
       thousand_separator: .
       decimal_separator: ','
@@ -172,7 +148,7 @@ content:
     region: content
   oe_project_budget_eu:
     type: number_decimal
-    label: above
+    label: hidden
     settings:
       thousand_separator: .
       decimal_separator: ','
@@ -183,7 +159,7 @@ content:
     region: content
   oe_project_coordinators:
     type: entity_reference_revisions_entity_view
-    label: above
+    label: hidden
     settings:
       view_mode: name
       link: ''
@@ -192,7 +168,7 @@ content:
     region: content
   oe_project_dates:
     type: daterange_default
-    label: above
+    label: hidden
     settings:
       timezone_override: ''
       format_type: oe_whitelabel_project_date
@@ -202,7 +178,7 @@ content:
     region: content
   oe_project_funding_programme:
     type: skos_concept_entity_reference_label
-    label: above
+    label: hidden
     settings:
       link: true
     third_party_settings: {  }
@@ -219,7 +195,7 @@ content:
     region: content
   oe_project_website:
     type: link
-    label: above
+    label: hidden
     settings:
       trim_length: 80
       url_only: false
@@ -231,7 +207,7 @@ content:
     region: content
   oe_reference_code:
     type: string
-    label: above
+    label: hidden
     settings:
       link_to_entity: false
     third_party_settings: {  }
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
index 42e1be42..6694eb33 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
@@ -25,9 +25,7 @@ third_party_settings:
       region: content
       weight: 0
       format_type: oe_whitelabel_helper_description_list_pattern
-      format_settings:
-        classes: ''
-        id: ''
+      format_settings: {  }
 id: oe_organisation.oe_cx_project_stakeholder.default
 targetEntityType: oe_organisation
 bundle: oe_cx_project_stakeholder
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 072ef646..0985cce6 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -15,7 +15,10 @@ use Drupal\oe_bootstrap_theme\ValueObject\ImageValueObject;
 use Drupal\Component\Utility\Html;
 
 /**
- * Implements hook_preprocess().
+ * Implements hook_preprocess_HOOK() for "pattern_description_list".
+ *
+ * Adds a bottom border for some instances of this pattern that are used in
+ * field groups on the project detail page.
  */
 function oe_whitelabel_extra_project_preprocess_pattern_description_list(array &$variables): void {
   /** @var \Drupal\ui_patterns\Element\PatternContext $context */
diff --git a/modules/oe_whitelabel_helper/config/schema/oe_whitelabel_helper.schema.yml b/modules/oe_whitelabel_helper/config/schema/oe_whitelabel_helper.schema.yml
index 26601395..2f171640 100644
--- a/modules/oe_whitelabel_helper/config/schema/oe_whitelabel_helper.schema.yml
+++ b/modules/oe_whitelabel_helper/config/schema/oe_whitelabel_helper.schema.yml
@@ -14,42 +14,12 @@ field_group.field_group_formatter_plugin.oe_whitelabel_helper_pattern_base:
   type: field_group.field_group_formatter_plugin.base
   label: 'Mapping for the base pattern formatter settings'
   mapping:
-    classes:
+    label:
+      type: label
+      label: 'Field group label'
+    variant:
       type: string
-      label: 'Classes of the fieldgroup'
-    show_empty_fields:
-      type: boolean
-      label: 'Show Empty Fields'
-    id:
-      type: string
-      label: 'Html id of the fieldgroup'
-    formatter:
-      type: string
-      label: 'Formatting of the item'
-    description:
-      type: text
-      label: 'Description'
-    element:
-      type: string
-      label: 'html element tag to be used'
-    show_label:
-      type: boolean
-      label: 'show the label'
-    label_element:
-      type: string
-      label: 'html element tag to be used for the label'
-    label_element_classes:
-      type: string
-      label: 'html classes to be used for the label'
-    attributes:
-      type: string
-      label: 'html attributes for the element'
-    effect:
-      type: string
-      label: 'effect on the element'
-    speed:
-      type: string
-      label: 'speed of the effect'
+      label: 'Pattern variant'
 field_group.field_group_formatter_plugin.oe_whitelabel_helper_description_list_pattern:
   type: field_group.field_group_formatter_plugin.oe_whitelabel_helper_pattern_base
   label: 'Mapping for the description list pattern formatter settings'
diff --git a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
index 85036892..85c91946 100644
--- a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
+++ b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/DescriptionListPattern.php
@@ -92,7 +92,7 @@ class DescriptionListPattern extends PatternFormatterBase {
   /**
    * {@inheritdoc}
    */
-  protected function getFields(array &$element, $rendering_object): array {
+  protected function getFields(array &$element, $rendering_object): ?array {
     $fields = [];
 
     foreach (Element::children($element) as $field_name) {
@@ -109,6 +109,10 @@ class DescriptionListPattern extends PatternFormatterBase {
       ];
     }
 
+    if (empty($fields['items'])) {
+      return NULL;
+    }
+
     return $fields;
   }
 
diff --git a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/PatternFormatterBase.php b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/PatternFormatterBase.php
index 8d3f2c8e..ded01d6d 100644
--- a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/PatternFormatterBase.php
+++ b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/PatternFormatterBase.php
@@ -117,12 +117,17 @@ abstract class PatternFormatterBase extends FieldGroupFormatterBase implements C
   public function preRender(&$element, $rendering_object) {
     parent::preRender($element, $rendering_object);
 
+    $fields = $this->getFields($element, $rendering_object);
+    if ($fields === NULL) {
+      // Don't render the pattern.
+      return;
+    }
     // Instantiate the pattern render array.
     $pattern = [
       '#type' => 'pattern',
       '#id' => $this->getPatternId(),
       '#variant' => $this->getSetting('variant'),
-      '#fields' => $this->getFields($element, $rendering_object),
+      '#fields' => $fields,
       '#context' => [
         'type' => 'field_group',
         'group_name' => $element['#group_name'],
@@ -158,9 +163,9 @@ abstract class PatternFormatterBase extends FieldGroupFormatterBase implements C
    * @param object $rendering_object
    *   Field group rendering object.
    *
-   * @return array
+   * @return array|null
    *   Pattern fields to be rendered, or an empty array if none.
    */
-  abstract protected function getFields(array &$element, $rendering_object): array;
+  abstract protected function getFields(array &$element, $rendering_object): ?array;
 
 }
diff --git a/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php b/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php
index bb298765..d0f51b39 100644
--- a/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php
+++ b/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php
@@ -10,7 +10,7 @@ use Drupal\Tests\BrowserTestBase;
 use Drupal\Tests\field_group\Functional\FieldGroupTestTrait;
 
 /**
- * Test the Description list pattern field group formatter.
+ * Test the pattern field group formatter.
  */
 class PatternFormatterTest extends BrowserTestBase {
 
@@ -30,7 +30,7 @@ class PatternFormatterTest extends BrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  protected $defaultTheme = 'stark';
+  protected $defaultTheme = 'oe_whitelabel';
 
   /**
    * {@inheritdoc}
@@ -38,17 +38,6 @@ class PatternFormatterTest extends BrowserTestBase {
   public function setUp(): void {
     parent::setUp();
 
-    // Enable oe_whitelabel and set it as default.
-    $this->assertTrue($this->container->get('theme_installer')->install(['oe_whitelabel']));
-    $this->container->get('config.factory')
-      ->getEditable('system.theme')
-      ->set('default', 'oe_whitelabel')
-      ->save();
-
-    // Rebuild the ui_pattern definitions to collect the ones provided by
-    // oe_whitelabel itself.
-    $this->container->get('plugin.manager.ui_patterns')->clearCachedDefinitions();
-
     // Create test user.
     $admin_user = $this->drupalCreateUser([
       'access content',
diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index f0140376..8d4d6570 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -27,21 +27,23 @@
     {{ field }}
   {% endif %}
 {% endmacro %}
-{% set inpage_navigation_fields %}
-  {{ content.group_project_details }}
-  {{ _self.field_with_header(content.oe_summary) }}
-  {{ _self.field_with_header(content.oe_cx_objective) }}
-  {{ _self.field_with_header(content.oe_cx_impacts) }}
-  {{ _self.field_with_header(content.oe_project_participants) }}
-  {{ _self.field_with_header(content.oe_cx_lead_contributors) }}
-  {{ _self.field_with_header(content.oe_cx_achievements_and_milestone) }}
-{% endset %}
-<div class="mt-md-4-75 mt-4">
-  {{ pattern('inpage_navigation', {
-    title: 'Page content'|t,
-    links: inpage_navigation_links,
-    content: inpage_navigation_fields,
-    full_layout: true,
-  }) }}
-</div>
+{% block inpage_navigation_content %}
+  {% set inpage_navigation_fields %}
+    {{ content.group_project_details }}
+    {{ _self.field_with_header(content.oe_summary) }}
+    {{ _self.field_with_header(content.oe_cx_objective) }}
+    {{ _self.field_with_header(content.oe_cx_impacts) }}
+    {{ _self.field_with_header(content.oe_project_participants) }}
+    {{ _self.field_with_header(content.oe_cx_lead_contributors) }}
+    {{ _self.field_with_header(content.oe_cx_achievements_and_milestone) }}
+  {% endset %}
+  <div class="mt-md-4-75 mt-4">
+    {{ pattern('inpage_navigation', {
+      title: 'Page content'|t,
+      links: inpage_navigation_links,
+      content: inpage_navigation_fields,
+      full_layout: true,
+    }) }}
+  </div>
+{% endblock %}
 
-- 
GitLab


From a727e374de04987b741de2c7d4b2a064428048e0 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 1 Apr 2022 16:53:23 +0200
Subject: [PATCH 034/152] OEL-1297: Re-export config to add classes into
 viewmode.

---
 .../core.entity_view_display.node.oe_project.full.yml |  2 +-
 ...organisation.oe_cx_project_stakeholder.default.yml | 11 +++++------
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
index 91d6e587..8032da8e 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
@@ -57,7 +57,7 @@ third_party_settings:
         element: div
         show_label: true
         label_element: h3
-        label_element_classes: ''
+        label_element_classes: 'fw-bold mb-4'
         attributes: ''
         effect: none
         speed: fast
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
index 6694eb33..f1faedb5 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default.yml
@@ -18,12 +18,11 @@ third_party_settings:
       children:
         - name
         - oe_address
-        - oe_acronym
         - oe_cx_contribution_budget
       label: Info
       parent_name: ''
       region: content
-      weight: 0
+      weight: 1
       format_type: oe_whitelabel_helper_description_list_pattern
       format_settings: {  }
 id: oe_organisation.oe_cx_project_stakeholder.default
@@ -41,15 +40,15 @@ content:
     region: content
   oe_acronym:
     type: string
-    label: visually_hidden
+    label: hidden
     settings:
       link_to_entity: false
     third_party_settings: {  }
-    weight: 3
+    weight: 0
     region: content
   oe_address:
     type: oe_whitelabel_helper_address_inline
-    label: above
+    label: hidden
     settings:
       delimiter: ', '
     third_party_settings: {  }
@@ -57,7 +56,7 @@ content:
     region: content
   oe_cx_contribution_budget:
     type: number_decimal
-    label: above
+    label: hidden
     settings:
       thousand_separator: .
       decimal_separator: ','
-- 
GitLab


From c52ebdecd25feb5d5a8293ee039a0c7071902007 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 1 Apr 2022 16:54:09 +0200
Subject: [PATCH 035/152] OEL-1297: Fix id issue on inpage navigation.

---
 .../oe_whitelabel_extra_project.module        |  4 +-
 .../content/node--oe-project--full.html.twig  | 42 ++++++++++++-------
 2 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 0985cce6..4ccbb40d 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -122,11 +122,11 @@ function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables):
 
   $variables['inpage_navigation_links'] = [];
   $fields = [
-    'oe_project_dates',
     'oe_summary',
     'oe_cx_objective',
     'oe_cx_impacts',
     'oe_project_participants',
+    'oe_cx_lead_contributors',
     'oe_cx_achievements_and_milestone',
   ];
   foreach ($variables['content'] as &$item) {
@@ -139,7 +139,7 @@ function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables):
     }
 
     $unique_id = Html::getUniqueId('oe-project--' . $item['#field_name']);
-    $item['#attributes'] = ['id' => $unique_id];
+    $item['#inpage_nav_id'] = $unique_id;
     $variables['inpage_navigation_links'][] = [
       'path' => '#' . $unique_id,
       'label' => $node->{$item['#field_name']}->getFieldDefinition()->getLabel(),
diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 8d4d6570..7cb861db 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -23,27 +23,41 @@
 }) }}
 {% macro field_with_header(field) %}
   {% if field|field_value is not empty %}
-    <h3 class="fw-bold mb-4 pt-3">{{ field|field_label }}</h3>
+    <h3 class="fw-bold mb-4 pt-3" id="{{ field['#inpage_nav_id'] }}">{{ field|field_label }}</h3>
     {{ field }}
   {% endif %}
 {% endmacro %}
-{% block inpage_navigation_content %}
-  {% set inpage_navigation_fields %}
-    {{ content.group_project_details }}
+{% set _project_details %}
+  {{ content.group_project_details }}
+{% endset %}
+{% if _project_details|trim is not empty %}
+  {% set _project_details %}
+    <div id="project-details">
+      {{ _project_details }}
+    </div>
+  {% endset %}
+  {% set inpage_navigation_links = [{
+    'path': '#project-details',
+    'label': content.group_project_details['#title'],
+  }]|merge(inpage_navigation_links) %}
+{% endif %}
+{% set inpage_navigation_fields %}
+  {% block inpage_navigation_content %}
+    {{ _project_details }}
     {{ _self.field_with_header(content.oe_summary) }}
     {{ _self.field_with_header(content.oe_cx_objective) }}
     {{ _self.field_with_header(content.oe_cx_impacts) }}
     {{ _self.field_with_header(content.oe_project_participants) }}
     {{ _self.field_with_header(content.oe_cx_lead_contributors) }}
     {{ _self.field_with_header(content.oe_cx_achievements_and_milestone) }}
-  {% endset %}
-  <div class="mt-md-4-75 mt-4">
-    {{ pattern('inpage_navigation', {
-      title: 'Page content'|t,
-      links: inpage_navigation_links,
-      content: inpage_navigation_fields,
-      full_layout: true,
-    }) }}
-  </div>
-{% endblock %}
+  {% endblock %}
+{% endset %}
+<div class="mt-md-4-75 mt-4">
+  {{ pattern('inpage_navigation', {
+    title: 'Page content'|t,
+    links: inpage_navigation_links,
+    content: inpage_navigation_fields,
+    full_layout: true,
+  }) }}
+</div>
 
-- 
GitLab


From 73bbfe1939d8a6941d3509fb95f9b83001ace3af Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 1 Apr 2022 16:55:05 +0200
Subject: [PATCH 036/152] OEL-1297: Create template, adapt test.

---
 ...n--oe-acronym--oe-cx-project-stakeholder.html.twig | 11 +++++++++++
 tests/src/Functional/ContentProjectRenderTest.php     |  8 ++------
 2 files changed, 13 insertions(+), 6 deletions(-)
 create mode 100644 templates/content/field--oe-organisation--oe-acronym--oe-cx-project-stakeholder.html.twig

diff --git a/templates/content/field--oe-organisation--oe-acronym--oe-cx-project-stakeholder.html.twig b/templates/content/field--oe-organisation--oe-acronym--oe-cx-project-stakeholder.html.twig
new file mode 100644
index 00000000..5e623ee2
--- /dev/null
+++ b/templates/content/field--oe-organisation--oe-acronym--oe-cx-project-stakeholder.html.twig
@@ -0,0 +1,11 @@
+{#
+/**
+ * @file
+ * Theme override for the Acronym field template.
+ *
+ * @see ./core/themes/stable/templates/field/field.html.twig
+ */
+#}
+<h4 class="fw-bold mb-3">
+  {{ element }}
+</h4>
diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index 97a894db..160784e6 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -129,8 +129,8 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       'title' => 'Page content',
       'links' => [
         [
-          'label' => 'Project period',
-          'href' => '#oe-project-oe-project-dates',
+          'label' => 'Project details',
+          'href' => '#project-details',
         ],
         [
           'label' => 'Summary',
@@ -239,10 +239,6 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
           'term' => 'Address',
           'definition' => 'Belgium',
         ],
-        [
-          'term' => 'Acronym',
-          'definition' => 'Acronym participant',
-        ],
         [
           'term' => 'Contribution to the budget',
           'definition' => '€22,30',
-- 
GitLab


From cb14f7b54b8768dfb7c39fa76219a23066210239 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 1 Apr 2022 17:07:24 +0200
Subject: [PATCH 037/152] OEL-1297: Modify the form viewmode on project.

---
 ...y_form_display.node.oe_project.default.yml | 43 ++++++-------------
 1 file changed, 13 insertions(+), 30 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml
index 70f83b1d..cf518277 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_form_display.node.oe_project.default.yml
@@ -45,7 +45,7 @@ third_party_settings:
       label: Result
       region: content
       parent_name: ''
-      weight: 3
+      weight: 13
       format_type: details
       format_settings:
         classes: ''
@@ -53,24 +53,6 @@ third_party_settings:
         open: true
         description: ''
         required_fields: true
-    group_alternative_titles_teaser:
-      children:
-        - oe_subject
-        - oe_featured_media
-        - status
-        - oe_teaser
-        - oe_project_coordinators
-      label: 'Alternative titles and teaser'
-      region: content
-      parent_name: ''
-      weight: 1
-      format_type: tab
-      format_settings:
-        classes: ''
-        id: ''
-        formatter: open
-        description: ''
-        required_fields: true
     group_budget:
       children:
         - oe_project_budget
@@ -93,6 +75,7 @@ third_party_settings:
         - oe_project_website
         - oe_project_funding_programme
         - oe_reference_code
+        - oe_project_coordinators
       label: 'Project details'
       region: content
       parent_name: ''
@@ -135,7 +118,7 @@ content:
     third_party_settings: {  }
   oe_cx_impacts:
     type: text_textarea
-    weight: 9
+    weight: 7
     region: content
     settings:
       rows: 5
@@ -143,7 +126,7 @@ content:
     third_party_settings: {  }
   oe_cx_lead_contributors:
     type: inline_entity_form_complex
-    weight: 6
+    weight: 9
     region: content
     settings:
       form_mode: default
@@ -161,7 +144,7 @@ content:
     third_party_settings: {  }
   oe_cx_objective:
     type: text_textarea
-    weight: 8
+    weight: 6
     region: content
     settings:
       rows: 5
@@ -169,7 +152,7 @@ content:
     third_party_settings: {  }
   oe_documents:
     type: entity_reference_autocomplete
-    weight: 2
+    weight: 12
     region: content
     settings:
       match_operator: CONTAINS
@@ -179,7 +162,7 @@ content:
     third_party_settings: {  }
   oe_featured_media:
     type: oe_featured_media_autocomplete
-    weight: 12
+    weight: 1
     region: content
     settings:
       match_operator: CONTAINS
@@ -203,7 +186,7 @@ content:
     third_party_settings: {  }
   oe_project_coordinators:
     type: inline_entity_form_complex
-    weight: 15
+    weight: 10
     region: content
     settings:
       form_mode: default
@@ -240,7 +223,7 @@ content:
     third_party_settings: {  }
   oe_project_participants:
     type: inline_entity_form_complex
-    weight: 5
+    weight: 8
     region: content
     settings:
       form_mode: default
@@ -292,7 +275,7 @@ content:
     third_party_settings: {  }
   oe_subject:
     type: skos_concept_entity_reference_autocomplete
-    weight: 11
+    weight: 3
     region: content
     settings:
       match_operator: CONTAINS
@@ -302,7 +285,7 @@ content:
     third_party_settings: {  }
   oe_summary:
     type: text_textarea
-    weight: 7
+    weight: 5
     region: content
     settings:
       rows: 5
@@ -310,7 +293,7 @@ content:
     third_party_settings: {  }
   oe_teaser:
     type: text_textarea
-    weight: 14
+    weight: 2
     region: content
     settings:
       rows: 5
@@ -318,7 +301,7 @@ content:
     third_party_settings: {  }
   status:
     type: boolean_checkbox
-    weight: 13
+    weight: 14
     region: content
     settings:
       display_label: true
-- 
GitLab


From 3377fd1dc6d4f6982793b2fd8b64d477805eb38c Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 1 Apr 2022 18:36:07 +0200
Subject: [PATCH 038/152] OEL-1297: Improve Formatter base and test.

---
 .../PatternFormatterBase.php                  |  3 ++-
 .../field_group/PatternFormatterTest.php      | 23 ++++---------------
 2 files changed, 7 insertions(+), 19 deletions(-)

diff --git a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/PatternFormatterBase.php b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/PatternFormatterBase.php
index ded01d6d..da15223c 100644
--- a/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/PatternFormatterBase.php
+++ b/modules/oe_whitelabel_helper/src/Plugin/field_group/FieldGroupFormatter/PatternFormatterBase.php
@@ -164,7 +164,8 @@ abstract class PatternFormatterBase extends FieldGroupFormatterBase implements C
    *   Field group rendering object.
    *
    * @return array|null
-   *   Pattern fields to be rendered, or an empty array if none.
+   *   Pattern fields to be rendered, or NULL if the field group
+   *   should not be displayed at all.
    */
   abstract protected function getFields(array &$element, $rendering_object): ?array;
 
diff --git a/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php b/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php
index d0f51b39..d00675ce 100644
--- a/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php
+++ b/modules/oe_whitelabel_helper/tests/src/Functional/Plugin/field_group/PatternFormatterTest.php
@@ -22,7 +22,6 @@ class PatternFormatterTest extends BrowserTestBase {
   protected static $modules = [
     'node',
     'text',
-    'field_ui',
     'field_group',
     'oe_whitelabel_helper',
   ];
@@ -38,17 +37,6 @@ class PatternFormatterTest extends BrowserTestBase {
   public function setUp(): void {
     parent::setUp();
 
-    // Create test user.
-    $admin_user = $this->drupalCreateUser([
-      'access content',
-      'administer content types',
-      'administer node fields',
-      'administer node form display',
-      'administer node display',
-      'bypass node access',
-    ]);
-    $this->drupalLogin($admin_user);
-
     // Create content type.
     $this->drupalCreateContentType([
       'name' => 'Test',
@@ -121,12 +109,11 @@ class PatternFormatterTest extends BrowserTestBase {
 
     // Assert that fields are rendered using the field list horizontal pattern.
     $this->drupalGet('node/1');
-    $element_selector = 'dl';
-    $this->assertSession()->elementExists('css', $element_selector);
-    $assert_session->elementTextContains('css', $element_selector . ' div dt', 'Field 1');
-    $assert_session->elementTextContains('css', $element_selector . ' dd:nth-child(2)', 'Content test 1');
-    $assert_session->elementTextContains('css', $element_selector . ' div:nth-child(3) dt', 'Field 2');
-    $assert_session->elementTextContains('css', $element_selector . ' dd:nth-child(4)', 'Content test 2');
+    $assert_session->elementsCount('css', 'dl', 1);
+    $assert_session->elementTextContains('css', 'dl div dt', 'Field 1');
+    $assert_session->elementTextContains('css', 'dl dd:nth-child(2)', 'Content test 1');
+    $assert_session->elementTextContains('css', 'dl div:nth-child(3) dt', 'Field 2');
+    $assert_session->elementTextContains('css', 'dl dd:nth-child(4)', 'Content test 2');
   }
 
 }
-- 
GitLab


From 598f7c08eb83133f90181281d811ca8f2b311143 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 4 Apr 2022 09:58:43 +0200
Subject: [PATCH 039/152] OEL-1390: Patch drupal/entity_reference_revisions, to
 have a label formatter.

---
 composer.json | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/composer.json b/composer.json
index 8afca89a..f75b7a11 100644
--- a/composer.json
+++ b/composer.json
@@ -81,6 +81,11 @@
                 }
             }
         },
+        "patches": {
+            "drupal/entity_reference_revisions": {
+                "https://www.drupal.org/project/entity_reference_revisions/issues/2937835": "https://www.drupal.org/files/issues/2021-03-26/entity_reference_revisions-field_formatter_label-2937835-36.patch"
+            }
+        },
         "drupal-scaffold": {
             "locations": {
                 "web-root": "./build"
-- 
GitLab


From 7209904689a71e0fdf3c410a32969468b3af05e9 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 4 Apr 2022 10:14:50 +0200
Subject: [PATCH 040/152] OEL-1390: Use the new formatter, and drop 'name' view
 mode.

---
 ...ay.oe_organisation.oe_stakeholder.name.yml | 33 -------------------
 ....entity_view_mode.oe_organisation.name.yml |  9 -----
 ...tity_view_display.node.oe_project.full.yml |  5 ++-
 .../oe_whitelabel_extra_project.info.yml      |  2 --
 4 files changed, 2 insertions(+), 47 deletions(-)
 delete mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_stakeholder.name.yml
 delete mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.name.yml

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_stakeholder.name.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_stakeholder.name.yml
deleted file mode 100644
index 19f15e31..00000000
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.oe_organisation.oe_stakeholder.name.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - core.entity_view_mode.oe_organisation.name
-    - field.field.oe_organisation.oe_stakeholder.oe_acronym
-    - field.field.oe_organisation.oe_stakeholder.oe_address
-    - field.field.oe_organisation.oe_stakeholder.oe_contact_url
-    - field.field.oe_organisation.oe_stakeholder.oe_logo
-    - field.field.oe_organisation.oe_stakeholder.oe_website
-    - oe_content_entity_organisation.oe_organisation_type.oe_stakeholder
-id: oe_organisation.oe_stakeholder.name
-targetEntityType: oe_organisation
-bundle: oe_stakeholder
-mode: name
-content:
-  name:
-    type: string
-    label: hidden
-    settings:
-      link_to_entity: false
-    third_party_settings: {  }
-    weight: 0
-    region: content
-hidden:
-  created: true
-  langcode: true
-  oe_acronym: true
-  oe_address: true
-  oe_contact_url: true
-  oe_logo: true
-  oe_website: true
-  status: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.name.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.name.yml
deleted file mode 100644
index 71f18425..00000000
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_mode.oe_organisation.name.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  module:
-    - oe_content_entity_organisation
-id: oe_organisation.name
-label: Name
-targetEntityType: oe_organisation
-cache: true
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
index 8032da8e..b57e9f20 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
@@ -158,11 +158,10 @@ content:
     weight: 3
     region: content
   oe_project_coordinators:
-    type: entity_reference_revisions_entity_view
+    type: entity_reference_revisions_label
     label: hidden
     settings:
-      view_mode: name
-      link: ''
+      link: false
     third_party_settings: {  }
     weight: 4
     region: content
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
index 7d51c95a..2a216223 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
@@ -10,5 +10,3 @@ dependencies:
 config_devel:
   install:
     - core.date_format.oe_whitelabel_project_date
-    - core.entity_view_display.oe_organisation.oe_stakeholder.name
-    - core.entity_view_mode.oe_organisation.name
-- 
GitLab


From 378d7ff32ccd1170d926804446eaa5fe9db2fc9b Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Tue, 29 Mar 2022 16:31:53 +0200
Subject: [PATCH 041/152] OEL-1298: Add theming for teaser display for Project.

Add view display teaser for node oe_project.
Add twig for Project's teaser.
Add badges management at module.
Add overrides yaml teaser file at install.
---
 ...ty_view_display.node.oe_project.teaser.yml | 126 ++++++++++++++++++
 .../oe_whitelabel_extra_project.install       |   1 +
 .../oe_whitelabel_extra_project.module        |  24 ++++
 .../node--oe-project--teaser.html.twig        |  22 +++
 4 files changed, 173 insertions(+)
 create mode 100644 modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml
 create mode 100644 templates/content/node--oe-project--teaser.html.twig

diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml
new file mode 100644
index 00000000..35e98b68
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml
@@ -0,0 +1,126 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.teaser
+    - field.field.node.oe_project.body
+    - field.field.node.oe_project.oe_cx_achievements_and_milestone
+    - field.field.node.oe_project.oe_cx_gallery
+    - field.field.node.oe_project.oe_cx_impacts
+    - field.field.node.oe_project.oe_cx_lead_contributors
+    - field.field.node.oe_project.oe_cx_objective
+    - field.field.node.oe_project.oe_departments
+    - field.field.node.oe_project.oe_documents
+    - field.field.node.oe_project.oe_featured_media
+    - field.field.node.oe_project.oe_project_budget
+    - field.field.node.oe_project.oe_project_budget_eu
+    - field.field.node.oe_project.oe_project_calls
+    - field.field.node.oe_project.oe_project_contact
+    - field.field.node.oe_project.oe_project_coordinators
+    - field.field.node.oe_project.oe_project_dates
+    - field.field.node.oe_project.oe_project_funding_programme
+    - field.field.node.oe_project.oe_project_locations
+    - field.field.node.oe_project.oe_project_participants
+    - field.field.node.oe_project.oe_project_result_files
+    - field.field.node.oe_project.oe_project_results
+    - field.field.node.oe_project.oe_project_website
+    - field.field.node.oe_project.oe_reference_code
+    - field.field.node.oe_project.oe_subject
+    - field.field.node.oe_project.oe_summary
+    - field.field.node.oe_project.oe_teaser
+    - node.type.oe_project
+  module:
+    - datetime_range
+    - field_group
+    - oe_content_featured_media_field
+    - rdf_skos
+    - text
+    - user
+third_party_settings:
+  field_group:
+    group_stakeholders:
+      children:
+        - oe_project_participants
+      label: Stakeholders
+      parent_name: ''
+      region: hidden
+      weight: 30
+      format_type: html_element
+      format_settings:
+        classes: ''
+        id: ''
+        element: div
+        show_label: false
+        label_element: h3
+        label_element_classes: ''
+        attributes: ''
+        effect: none
+        speed: fast
+_core:
+  default_config_hash: jIuyfx94stqGE35SUgeVttHtWMdmhiAIQUi0108xRIY
+id: node.oe_project.teaser
+targetEntityType: node
+bundle: oe_project
+mode: teaser
+content:
+  oe_featured_media:
+    type: oe_featured_media_label
+    label: hidden
+    settings:
+      link: true
+    third_party_settings: {  }
+    weight: 0
+    region: content
+  oe_project_dates:
+    type: daterange_default
+    label: hidden
+    settings:
+      timezone_override: ''
+      format_type: html_year
+      separator: '-'
+    third_party_settings: {  }
+    weight: 3
+    region: content
+  oe_subject:
+    type: skos_concept_entity_reference_label
+    label: hidden
+    settings:
+      link: false
+    third_party_settings: {  }
+    weight: 2
+    region: content
+  oe_teaser:
+    type: text_default
+    label: hidden
+    settings: {  }
+    third_party_settings: {  }
+    weight: 1
+    region: content
+hidden:
+  body: true
+  langcode: true
+  links: true
+  oe_content_content_owner: true
+  oe_content_legacy_link: true
+  oe_content_navigation_title: true
+  oe_content_short_title: true
+  oe_cx_achievements_and_milestone: true
+  oe_cx_gallery: true
+  oe_cx_impacts: true
+  oe_cx_lead_contributors: true
+  oe_cx_objective: true
+  oe_departments: true
+  oe_documents: true
+  oe_project_budget: true
+  oe_project_budget_eu: true
+  oe_project_calls: true
+  oe_project_contact: true
+  oe_project_coordinators: true
+  oe_project_funding_programme: true
+  oe_project_locations: true
+  oe_project_participants: true
+  oe_project_result_files: true
+  oe_project_results: true
+  oe_project_website: true
+  oe_reference_code: true
+  oe_summary: true
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
index 172efeb8..b9d87a18 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
@@ -24,6 +24,7 @@ function oe_whitelabel_extra_project_install($is_syncing): void {
     'core.entity_form_display.node.oe_project.default',
     'core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default',
     'core.entity_view_display.node.oe_project.full',
+    'core.entity_view_display.node.oe_project.teaser',
     'core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default',
   ];
 
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 4ccbb40d..03514efe 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -52,6 +52,7 @@ function oe_whitelabel_extra_project_preprocess_node__oe_project(&$variables) {
   }
   _oe_whitelabel_extra_project_preprocess_featured_media($variables);
   _oe_whitelabel_extra_project_preprocess_inpage_nav($variables);
+  _oe_whitelabel_extra_project_preprocess_badges($variables);
 }
 
 /**
@@ -147,3 +148,26 @@ function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables):
   }
 
 }
+
+/**
+ * Implements hook_preprocess().
+ */
+function _oe_whitelabel_extra_project_preprocess_badges(&$variables) {
+  if ($variables['view_mode'] !== 'full' && $variables['view_mode'] !== 'teaser') {
+    return;
+  }
+
+  /** @var \Drupal\node\NodeInterface $node */
+  $node = $variables['node'];
+
+  if ($node->get('oe_subject')->isEmpty()) {
+    return;
+  }
+
+  $variables['badges'] = [];
+  foreach ($node->get('oe_subject') as $item) {
+    $variables['badges'][] = [
+      '#title' => $item->entity->label(),
+    ];
+  }
+}
diff --git a/templates/content/node--oe-project--teaser.html.twig b/templates/content/node--oe-project--teaser.html.twig
new file mode 100644
index 00000000..7e34db8a
--- /dev/null
+++ b/templates/content/node--oe-project--teaser.html.twig
@@ -0,0 +1,22 @@
+{#
+/**
+ * @file
+ * Search result template.
+ */
+#}
+{% set _title %}
+  <a class="text-underline-hover" href="{{ url }}">{{ label }}</a>
+{% endset %}
+{% set _content %}
+  <span class="text-muted text-nowrap me-4-5">{{ content.oe_project_dates }}</span>
+{% endset %}
+<article{{attributes}}>
+  {{ pattern('card', {
+    variant: 'search',
+    title: _title,
+    text: content.oe_teaser,
+    image: image,
+    content: _content,
+    badges: badges,
+  }) }}
+</article>
-- 
GitLab


From e7e6e4402fb4d12a08ed10e894d3f91411ebaa62 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Wed, 30 Mar 2022 09:58:27 +0200
Subject: [PATCH 042/152] OEL-1298: Improve description and change to
 standalone class at node--oe-project--teaser.html.twig.

---
 templates/content/node--oe-project--teaser.html.twig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/templates/content/node--oe-project--teaser.html.twig b/templates/content/node--oe-project--teaser.html.twig
index 7e34db8a..e73c2f27 100644
--- a/templates/content/node--oe-project--teaser.html.twig
+++ b/templates/content/node--oe-project--teaser.html.twig
@@ -1,11 +1,11 @@
 {#
 /**
  * @file
- * Search result template.
+ * Template for Teaser view display of Project content type.
  */
 #}
 {% set _title %}
-  <a class="text-underline-hover" href="{{ url }}">{{ label }}</a>
+  <a class="standalone" href="{{ url }}">{{ label }}</a>
 {% endset %}
 {% set _content %}
   <span class="text-muted text-nowrap me-4-5">{{ content.oe_project_dates }}</span>
-- 
GitLab


From dc61a6c2aa9d2ed193f85bdc87abf4c23ef02bb7 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Wed, 30 Mar 2022 09:59:12 +0200
Subject: [PATCH 043/152] OEL-1298: Eliminate extra-check at badges function in
 oe_whitelabel_extra_project.module.

---
 .../oe_whitelabel_extra_project.module                        | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 03514efe..e845bb35 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -153,10 +153,6 @@ function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables):
  * Implements hook_preprocess().
  */
 function _oe_whitelabel_extra_project_preprocess_badges(&$variables) {
-  if ($variables['view_mode'] !== 'full' && $variables['view_mode'] !== 'teaser') {
-    return;
-  }
-
   /** @var \Drupal\node\NodeInterface $node */
   $node = $variables['node'];
 
-- 
GitLab


From 6e75c4262e7a3c5049ed93ea2647d5290eb5f22a Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Wed, 30 Mar 2022 09:59:48 +0200
Subject: [PATCH 044/152] OEL-1298: Eliminate _core tag at teaser yaml file.

---
 .../core.entity_view_display.node.oe_project.teaser.yml         | 2 --
 1 file changed, 2 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml
index 35e98b68..e4823928 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml
@@ -56,8 +56,6 @@ third_party_settings:
         attributes: ''
         effect: none
         speed: fast
-_core:
-  default_config_hash: jIuyfx94stqGE35SUgeVttHtWMdmhiAIQUi0108xRIY
 id: node.oe_project.teaser
 targetEntityType: node
 bundle: oe_project
-- 
GitLab


From 4ecd4e471b5a6be7574b51dbea302e841446e7d8 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Wed, 30 Mar 2022 16:05:50 +0200
Subject: [PATCH 045/152] OEL-1298: Adding Kernel test for Teaser view mode of
 Project content type.

---
 .../oe_whitelabel_extra_project.module        |   6 +-
 tests/fixtures/example_1.jpeg                 | Bin 0 -> 8873 bytes
 tests/fixtures/placeholder.png                | Bin 0 -> 2767 bytes
 tests/src/Kernel/AbstractKernelTestBase.php   | 114 +++++++++
 tests/src/Kernel/ContentRenderTestBase.php    | 242 ++++++++++++++++++
 .../MultilingualAbstractKernelTestBase.php    |  96 +++++++
 tests/src/Kernel/ProjectRenderTest.php        | 203 +++++++++++++++
 tests/src/Kernel/Traits/RenderTrait.php       |  96 +++++++
 .../PatternAssertions/BasePatternAssert.php   |  29 ++-
 tests/src/PatternAssertions/CardAssert.php    | 126 +++++++++
 .../PatternAssertions/ContentBannerAssert.php |  20 --
 11 files changed, 908 insertions(+), 24 deletions(-)
 create mode 100644 tests/fixtures/example_1.jpeg
 create mode 100644 tests/fixtures/placeholder.png
 create mode 100644 tests/src/Kernel/AbstractKernelTestBase.php
 create mode 100644 tests/src/Kernel/ContentRenderTestBase.php
 create mode 100644 tests/src/Kernel/MultilingualAbstractKernelTestBase.php
 create mode 100644 tests/src/Kernel/ProjectRenderTest.php
 create mode 100644 tests/src/Kernel/Traits/RenderTrait.php
 create mode 100644 tests/src/PatternAssertions/CardAssert.php

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index e845bb35..2784e8bb 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -103,9 +103,11 @@ function _oe_whitelabel_extra_project_preprocess_featured_media(&$variables) {
 
   $thumbnail = $media->get('thumbnail')->first();
   $variables['image'] = ImageValueObject::fromImageItem($thumbnail);
-
   if ($variables['view_mode'] == 'teaser') {
-    $variables['image'] = ['#markup' => $variables['image']->getSource()];
+    $variables['image'] = [
+      'path' => $variables['image']->getSource(),
+      'alt' => $variables['image']->getAlt(),
+    ];
   }
 
   $cacheability->applyTo($variables);
diff --git a/tests/fixtures/example_1.jpeg b/tests/fixtures/example_1.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..e04cde60ca8fa8d23a3668010a40f976abb78e8b
GIT binary patch
literal 8873
zcmb7qbzD?k7w#FlVJMOA?gr_Ulnxb;7-Z-eN+d<PyJ1Lak(3Yxqy(e{2?>!#q*3w?
zsJ!p}zVH5VH|NaRd#z`!z4tlm+4bY{^W_3SpsJ*z1b{#w;4b11xLgE<DSAPz0YF0o
zU<UvI13(8607!@&3F5W@kprlRCkSzSfhcbB0U%ZY`C5)ZA`$(`BT%7G0Ob!pER5-I
z9^nO%6kOe%&FyIwjZ~Cq<;@)+uI99SSMsZNT-WgXi4l}>Q_pr#_D%jMjOBMdpf~_P
zT<8cZ6kdKl-Z<pz_7Wq?7YSH@@gTyyzZgDV-aOE6+sjJ?>UTo4_R150hqyufynKS<
zyrSa#qO`oi;zIo5yu4Q^kt-dd7oh7JkTkDkNY^zWdJob<_`G^kNQzf-lpDFtRS}T{
z5%<-bqyGJTl!}1vBl5U^<fOl!-LZ&<c3&<c58A+B&f+{gj&9uMR!$ZWZc8Tz9xroe
z9zJef9za6c%h}x04g#aKfINmeO0xWDX=kB@T1m1P3Tg0aILkw9pm(3RLUf;K>RCRq
zvlO#pk(R=e@DlfOaCU&e%xS$G>>b_2y(C$#or@##S7II(1jyCOT3km#=??@^l4SYQ
z7Ee!4ZchPjC)dY3d}3l^JiPoo{QO)91ecq)Bh1{3%h8Pi;Q@>G+J^$f&C(U>41+p3
z{_zDt1lNtT|EptHn(Lk+%xP&Qu8QIsPF4_mss9cX37&tcZ_q|M5H}}#_p92ZMEL(;
z{w=&g8vifkzlAr*e}MXqP?(g8qovIs$N!<Zu`rgmkayK`a)VyA1M2u#N*>|}gSbMh
z{@DGO{>D-f(PaaOtJ_ukuky5i3bg#(e1DAp4Y{#XvNw0L(SmyYwf$SZu}8$qAN#+m
zzt9^W@=o?nuDXbTf=KB*TAJHKEnLlEH*Nlx_Qpcxs#i|V2-;de?V&Jl6-O(Gmz3t8
zivG9u|7rZUJwp7Pv;w?{o1a@m=x?Y0)7M|{jW=a2U3DkN$55EN6+{POEv5LU5&tRw
zp9WHV0-Ut`h<f>jxP=4-{>II}Z4m(}!E?olf5kH*#(&EYJV7vq=Z05^!VNPajtDxs
zUh(d729O7kk&vz~L_$Gas2HfIC@82{=;&w|I9ND1*jU)uxOjvFxOiYZY-|Ej0x%IV
z2?+@f{w*?6VlqNv65=Z-AY_CM3MwWlDkd>5HZJl1ce?BVz!-or(2EQL14v*HG8lB(
z1yEj%X~<Xez)eC!ziJ~038AGx$gh<D(xRZEAtRxKE~fz;WP~XJG67<6JG=`7YL@4`
ztNY^w6#nb|dUxd1BXMo!S>sB7|ERp*8ZpQF7iZn}8?0O<ADvH^5_5eLS(+Mc>K3lm
zl=BapbiT?s3AlTNvOJq7z@Pa5K8VyTKDgErzX@eBgzldBS_0@jKl&@tYj`gK#n8`V
zom{0%$tn9~EpHJxj+UtN2fk@x4~79?beSi+<6ia4c9mdLYb$5YO^UOw5R#A*Q?qvI
z+6`Y6@u3`TlgGw3{QLJKzs#9zei--^saPB^_xR^|fkLH?^}z{tHCw}SU!>Yb4eyi-
zr}}o8GO5+Ys}(ButmKIqgT|>!&DN@llxYULd%3xHQHT7|-xywStm)xRu6~?^*O)2n
zH_WWwdHM}TH&j;lvs&})bi*~w!$NY7$;D0sroGPKTj252Gr(jO?va#mm(=Ttcdgrr
zz1bTmmj_KF9?YYox`_N?3~I_M_i(wb$&g7iCFAFDaVJhEDF^d0v(E>UI}fmWlQzz%
zTU8f68;>`RZWCR-0_?4}T=^FOK$o!KU27P*s1_()-aLJFSb6$uHj@7m7_x1k$wL4E
z09k*f?NwRShv#h{3ip~Pv^$Kh#sB=!AfkYU005x^AS5)TtGWIvp@NW*QP2Q%A}}Ed
zt*{KQ00F5MA|fylfdWEBI=bs?OL{WoDnw(gW<U1OArd6Cj~nF@@topd%XrJB?lflD
z#<B?KRWnqyr&(mR{(RM!qG3v@;?_bnIQvOo9|ZRC$WjnXjtAcIX8WL_D0hxCA&NEf
zYX)*ZZs|DFLbSfl=!JMja-G}#vhVoK-V#LVQz>t`^ZcS(!F{=(bROlONaFU7nT`=M
zF?<BaN~gE*f$ooaDkTitkdu>UNZ%2-pUl7=tF}&gSa9AtkvJjBuyWEK?{+84CDjmF
zu7zir)dU(qD&MT~6B}3ZU}TA1hKGBe+2;jK0n6_Bz&e`-4Ew&e(3FwmijdaNQu3Y5
z(8A(+)yRTy^7!fRjn-=YEqK^&x2wSWzTcT3RgdYd=%j;!q4*U9RW2&d$C1IE*mm!$
zZ`l;;cdo(1q$GD{CW4za&xM=C8%ulq3ii8ERk7L39c}N&ju{g;`_vjg)=JdK(20Dg
zz5er#kVpK;+iKZTb}9ZOhaTEf<H{uYyo)u8{s%AoSSNJv+IQ3MoDEIY=fmwLiqDu_
zU&V3#7+$572FV<CYP`#X-pXqtd{LfTERsH}kdoESXn&$BPZhTPD8v|+Ew~G#5~&Ci
z5tmTC1X2-SUJ?v|5F-~V20AL{?=OG#;Q>@IArT#)tTq8LJp;eFOAQIFOkn)G9W-7c
z_y{SZfS{a~j^*NYJRk-SY0x1FtKd(l56R2pQ(0}TwR12138m!W0A9=&BKgC(y%VBi
zg!khF1S@>wRX;4rl5Ofg<i?1JB5Fu^^)({7cP0{QJnSsw*n)mia>()VbC!_<lP#RC
zjzv7CIn%o*Z;;E@c}072!@m4sCtYjgcYO196*g64&2v~|mRm!Gub1ZjW1T9ss0#~1
z*QIE`5&!c2OCT9<YoOlhb9JlrdQs}2tCRTdqG6GB8oU$Vq|jgcTTI1Pk;$i{(3kUX
zDmCC*@o6smLLQG45{M@%+)p=_U3`m#jSWC5=<d?4sjL@kc-n6*m7dmhjFP}=7hgJ;
zKNz|jMG5<A`$JseaR<2pGT!z{)2sp`AoOB5)6Hm<g;GMuTmRLXRk_@;T`c+Qhrdb;
z=IXr-C7U6mo1LA8$q%@n?w7migsy5`0;E#xzdo&tsvG)Irp!Py+{$%OMUXh;S?#^Y
zBh?L$SlG5pQ;y*|DRsMrLT&nl<Bd-=H)yie8wEpDr^gi)ZyU*MSJz2~oFCd;sI>d1
zmv3|wG9f#ccL=INYhTmD8&V4L7#+(uTp}=*PCmuUbae&_J=M~CiMGJLA)6(4gu`~*
zHL8VeHfZzH)_|1Jc!ea(r2T*tWxT4c8@Xh9YzO>;^Qr!R`6*RuPbgD89hd@h@dMpT
zhVnyqy~hi;o?yN`KDYgb_`141hTQ>gAF=O(*HvV!ET7X;eZm|mA&^ks)Y|Ho&w#QJ
z9X3?$&?If>^}CRH>awvput~5T5z)OGJtEg{eyT`?C+bNa2=!DeNnTo7GSrTK`|Qg%
zwq8%N9)%I6J1?b;^k0n{8KhrKEE=jAr%u#Q?-wu5W^G{7Nr{&Uy^<$F+B*P!71p!i
zr)YwX=ftptoI#It>0V7Ak;mh@%(4nO<POHeeXKVQlJ4#Am)`On!1t~o@6=#34xg2R
zEktdq>Y9+?&f1dn(%Q`b98()Rd{*0Xcv|X_+?!Z}wRlXJPp{)_FdYy6yows5WKmC7
zlRR+i?MPkUc9r#vS-0D4wl#bPQ*3^!qrvAkNFG^phT(NJjs(Z>i`izybojKk;DCYA
z7R%{l1nb1FS%(;4(J-$zU5IqeIxs4Nb@Y6)1jG#d+AbutyfWr+K_Q*M_?mZ%JB$Ka
zmLu1cL%OCM5ruZPf(xbZ66?JuFINO-*d_FJUgj+h4Rvb1TtXYd_Q})Olx$#z%j)(w
zm$G5pR+bx1MbpQQ$P7toQEKu@&@rgUkHlkLMusSMa<wiq(INF6x{x(v55%C)I)@-d
zWJ~F#49Bb;E{jx6CyrpzJYY1PsFu3~YL`#Pv&24kN`t>sb=EDpN6pcQcf2paH?dtF
zK5=b^?^aN>Hg}O0_Up&)eF|x|;?-H1(?`SRW-=df#Vt((r_qeZ`->ASr9XM(xZFNe
zgBI7hj2oRC(gitE&C(d$AZB1wNVJOJdqn$9xIOz`=QCveDiS1g<9RcW<_hfft@hj>
zx(n_O2cEX~KFz!Ot9IgkEy;&15<@gUkw5Ii7U2*aVxY_Mq#=(KdM)o6`<%^>goRMe
zr}DcHsZSY<X~>=N%d+<b?wpB*nX1`-vN;CZqZj)^A=TR4oNn5s?A#Lh)#M$xg%m#x
zI1?D>y9@~VdtUEW+*wP#M^#rbIk%*-BI*x4(%|!hPwm#M#bE}vcXt$?n;f$oR8Vd2
zD}T&)jVP=-=d4>Q+bWY6fE_2h40rb+wF+MlYYcAU#ErYNHan;#hqA63j4kWb@YX?j
zIXQ4sKHw%bl{=JR==2efm6@A&xx$4hlcLSC)w>>yjm8?e)bT!Df6Z%l`wPHc@|Et}
zx==^ny^SxK+4KFW%t&{%KvH^VM<x-vnO?Ecl6=oQMzQ8zp0lOu^>>CZtM{t)Vv|VW
zHP_!?GLgGCbyk|ili6Lhd{9urN_hz^Gxj>XO%(|&P4jch&h5xj3hVor`zksN9wHdw
z8w_QSDvu!^NSVJSyXK)5CDs~QvS^xM(L5I852f*5)Tsf`l>BL6ufMXjDjvACJ<)$S
zrcB~|EK_17e*E+jh(ZLrJYsQym{U;EFfsp`VgQuu8HQd~+uQ|}fS6w{o|Zu-5MJ|c
zWRX`#SI@%LE$9^qBIFYi3p#fGEIiPpk#?{JgmqarD)@g)6IXibjSYS~WDc;4{bJ{N
z7~vP)>e^$f6%G?IPa%@QW1QqS=Tt8o_z)E)4n2Mk$-!n2w1ThfDHLM&q>kI$%{Mtk
z_9Z@T9%pzNgY3A!7Bpi$Iz%RyQmfCA&LI~;nkAQDqriOM*OYf5bPsFxX?V}%C(X(h
zlv~-ZW1A!<LXHcxjXbIOSQDyA?zyP0PG#erlKPYrv7vDvR2hdsPph?#dZJuZXYYk{
zeXa`H$P+3t+FpUkW^Q))=oMPhOSkMqW{^^kCsY2UNjlFRsaUVPm2zaLFQTxzTyhYL
z*SivTKU&{4Bl{p+y0zL$b=rZwvZ802cP61@jTIfZ2hsmTSeERu-k7GA^a{^enYnJm
zSkqSCBm7wLB!?}X$WS2(YjhBrM7KKWwW!^lG>PG8vROwORBA<OYfeWi#=EM|Lf88K
z1bf42l`fk`57Ri0=ahr0IttAQq{~jy!-%m?n%i9DFuQh=_i6_t{chE5R@pPpHr4Ps
zwsYjPrbVs~w8QZkG4DuqnI}n#M}F|y44V(C+Tkl{FQGPQYL@T>Yx7cPv!_^ni<xd4
z-rTd{678*1%$Eyk`gXqc+;fT0-`lh|@ofG@rv?jQ$nIAQ*~CoOQe~JLUEPQ<C^(Ma
zi)dB>5ReZhQ`L<~7}fC_&$VacPV~qGb_yBkQ`nwom0~s(#Uw;EEShPUn=q$(uGc>-
z4dr)a^YqKh6w@V>jyW#X<`G7V7=w95DL1xcs58(<nz{`=u^px`ASH=z7jD`m%qCf;
zB5BRyXd%*shKx;mJuHc+Q?4SIMkNd&L{VclE*}lDD@3m%{NNc?#}8TzEk+qXg@1Zx
z`&OuQT3zt9HIEhrTsWY+1RA1KL7W6AXHccWY&dm;SyktVb7ruMyxwLm<FJ-{5Ze|}
z?R?c#$a{iv+xxMZhuO;qrqx!MrOjq|1(p;NmW65~0)STG(FHG)USo!3nZxUR6uP&4
zYrU|Mj=DpSRWt{C9n-`259+d_p;c5VrlhY72gRchr!<jxdBbC@gtfAU@-MzBLP^$h
zmkgV+#3b|aM_aZC(zlJ$A8vL2%r_}ox>x7!9Qq|m^;@xVe$}i=Ud?@Tqz6fQ_AD<B
z*}cfrM|BGOMb0SXp4;}8hrqkGe=&%r4ksmK6AC{KsB<g^kHhd~zua=uF#cQ<q5pQD
ze#Mt_?>Q{PAMnt<;7erj{dRwuTFXK8q_sF>==*T$FIjd-R3}SC)g4+US|$bnt(t+W
zIk@Rrh5<XyeS0yk*Y%HlmgJM{ODxi>PnBb`y!}Ive0Ob4joIAR@e*1-?tMfI9c%=M
z?Z(xv8ujlE6|u9uT9=x;1jZA<cW7l00|xKz&CW!c?gaDs^02b6n$o85Da5)-KPU-I
zuSLi6EQby%Drl&2hyI&wLymQ2U?!wSn5-832FnjGWl#Tf={qhDzsVwD17nVo9@%cd
zb1$n|((x=4Vn5YAXMbDkAj1(dg&K<R2)D)FQ3;0H&}hGIn0Y7LBQd=@<38crwWt=1
zmMzI}h9=h2Y=0^{Zow0j1d62e9<D6x?aw^S#-~J#H5w~sI6gKz#0y?0Th<fAjoyMl
zDn*k0Bc5o=I}=5)ir`e7To#(O4ZvFTOJ9ExldJ^(4{6h%Vh6f74lj^?ajXg#wbvC`
zN3pgAa1Y=*R(B`9uG0cUHKsq{EBDsQy}#X=tf0baKx&bC8j`fKib}SZMIQx6!9HPi
z2D1b)b&VN(5gIb3IKZ;q)rJMmyh&RLcIfw1`bdL?^oWl-a*rQC`;HD1q+S?r&L5iZ
z`&#JQD|B|J>1<N?hv6}S-<J4%#NA|b)6$Mxjb~cz`81!Nu8bdzlZWkO(D#Jx8|o{5
zVgfp%ZtLhTmviLqp1)@^Aad}>Wpc4uqec}6lt!6ixljr*j==8;=t*6g<I?%5`*Y}-
z<HAM@Wmbzxze)lTYOA-K6QrVpkXmC~Hij(T<t&s#aI-nkmquiaFIaZebI_V%*g&Z2
zZ@tnndW$+S_}53{^3IhxE9UR{vLlY93l*c+%og}i#_}LU913f5nKM!Xh0K1|b;26z
z{hNMvqW$Z712{5S^!^dGZ<~Va9~@i)LAiu7WNlo1MW6XH<Kf1$O}Hc2HRO8lPM0lg
zT69&dEgT4=PjLl(jkq-_lR5ofqb6z8MyL)7GwsS5kVeu_zG2-nS@67Ipq7~*9NJSE
zPh27X_DGw8X|7&qsNaH23}{JJ^N*k9qqoPO{D~za5dW@{38;8FFeC9qK}jz1O_lH#
zyVNa*oaOs+kG!9#)So8#>V}*@ZdaB3iVpCiPerB%J_#)7J52q|=@B9L1AT=A^YQcJ
zqQEYbEfuPQOF#fIJ6<2uT%UUrBq%c`s9ayJ^?x$#wcEcXY`XU0*D8e>haXIP2%&nW
zL(9tKG?P#vc7)sO=`JUqAURu2tJC$9VAtX_;#^l1#<)Jl`1atG-yURBMt^5+e(xb@
z$_~D!>DBSUpM#`-Xi5-|nACS<Mre5#wRUfIj06{?eQ946Vm)R*F1;WejlOekvP$J*
z;3xdWNPpAufEXT_Saor3i-ul0{_(33hy#5Vt$Khs!rNo`dpp-rlumK-=7r-g(+oB<
zkQ%NkEK+vt!1ofs^r|_YNO{P;+Z{}^T_^i`DCf!1vr4w4_JA@~;RL2*k<Ipn;^Eov
zu@8<4%+a}8+cQ)?2d=Hus_IW$(=&uVA*~Biw8x{4Iiu^k1T5;q@RsgQh?L079OUM%
za==SM#qezp-*n`;XUh!V>O$fIjoIUq>t_th^>2&o#u?wn{($2G9_q?R+hjDuq}UZ=
zM|A>)2C&~Vw;=gudq*oDuQTAwPcD(RG84(gb7C1JQnC<*k%<WpA<?wLdE^`uydQif
zjRF)RBb37^AdQzI!Wx<@HOD^s)N7`Jy9@Eo#Qj@O+qmi@vV!&@`IB+AWB5t?2Gi;|
zo>Plkb(?Ei==VOIh|fpcSjvlO3k}uyH@FM?7*-xplilG@I@FJ4^%-3b+0)6(lHE>d
zGe}dy`h_1?u-ruBZ(YS4zR9tbH2CN!(07`a!5kbmDmop8m)d%oC@bKcWlq$ku&bq@
zA2$sSS8-&ZH2m^i-{Jv}+qa!gIqL88hVSVKM_PBu&ohQ-FzR+ar*;>Szn#$tDu$KT
zC5qs5uPY__5ZD#INK=VpN`<W)M?Y-VGr{1D?BB>7zJr1O!hj=|E2rQI64Z|PJ7aA3
z2USwK8i;WY(bEr=)STTR8O_7%lGE<+U3t`{<gV|e0s_Gp9dg2;$R9-qL3dwpat=NN
zXU5xbO@~g3Izn*Nmm-X*?T3&^)5k|+H)(zzRn+7ZhZ}^<Mi#DR+KDaM>295~yPOW<
zr}hVMwh-<%j|KFk;iwy^2U!fQPW3u)T5=DyZD?T#*_|lHRIHz?3}IUcJd%<wAVs6P
zxA&4S-+U*c@&R(4T}&Gm5kbrNDfWcu(rbkXLE9%6FF<J0xH7#z)MTa1aFY7mdJ9+k
z@xMHxo9D^A;^`lvAR$h95k$G(_5uG81;G=7cOyG8i?n|yw5xp{!3EZ&V|04(H#4Um
z)EYUV_5BhYFH0Rwos;|T`VU4J``#@U-Qx*m+2xsd7kMm+4=u!4m=wva8FI;g4mv&)
zpAL(TRiIbTU~11A_$A>7-tu^9YBcW)Ifuy8%$)3Zgb<_ebPuAqZ^z`)1j!5-f25wX
zJz?3W{L~p^8azS7){}m>|M^#eF>aRA^YmvBaIIKB4DOxLwlwqWt^9CopLf;lacLFr
zyD7D<=elX>n-O|%HFeUI!gcB;($KLJ+a0z$YRNL0A8YDk0Hkj+$Gw9sQl2SH)M}v%
z4IhtX%kjZm2F3*E#566_Q;L6?h~x5^MVl&38FUrH2Ky^@^sB?xUl;Vv<9~lbCaBwd
zdO}Y9R>(KDT4f1c4$C>a{>$zU3jN+^5j`oz=N7^B<X#QRAEVdD5(bbcU*>z4wYbf-
zI$_oESq7jS<|G+`sLYEpj6LjK3y|K2YX2%U21)qnRtBncAomW-h^S@37YZ{uszry~
z+5|;w1w-yA@|tiMw|4J`9C~M%R0>2*z1cVNw;P5VzFRyxu<!4o?{U%!uo|dy>wg|n
zgSOii{$p+R<uB^-uo~N+af+!XXz7U6--ga7IN>xd&>3sL;jd)Gl{ajM12H{}vA6^@
zA*CHiR?MP&G|q6&uZ*;~_~f^BsKU2xl&n;8$=*zj+52%5y@YoENE9KSI_cbY=L=(e
z*v7d%L5+0xJ(QWD&6FHRKCFNDw%7!Rw6+m%yG4S|ma^pF#cmt5KfAe@{Fk4bs<jp)
z(5YOSLtjjVU<M-JH@o^AO$#ee_4Xm(J~)cCHeSHFb)4)cS5NpXYJ|=w_{l|cq8a-f
zH6E|OhxerxDYjCA-<)N@5?13DRV$h<$S__G^9H`&Rs>INo>Z{8`*9HKs^f*8T`kv`
z2@u0S5@NyjU&}QDmq1z>M1=Edz5BD7LxlFpov2~sa#p;`dZ{_~+j^k>YBZ!ITE;Cm
zT4y|^<Swp;$OhFi)v_YSMZwPlL`bwP0O8(!qKQZMp?BY(YCPSNeHYWvset2s*iU6q
z&HEtlRm>M_<ZiZ^c4br(L+0Ja&s&t}mSd)mOZ$xUbYcy0@nj0}?lvf}fzhY5)3%@=
zfsgUewf6Y1c$M_(J>mvQ1Wxcx!yEacx7Ztg?sy6M0&nTSi$e~ObdZ`JyiUJh%Mq%E
z*`pkxz43}!Sbdc6c<qf}5y%9M%W9AOEfp)%VoaQiE(+baYtku&zG?lDOE4@)`(l^U
zV-r_POlI+x-RldR+iGf_fm=Im)(S#JdA4_m+a@=OeM+<O=3?VE$~BgiSBKr<!DpMr
zJ8^6Bpl8nk8v_}>xcqJH`nix6bL4z@P*}ic2H_SQS5v=GC3K|^tJFt52_Ouc-H_IE
z3&lI{)Pz!{jV(vz_}5TgY{e)Op)hZEKWlkxNZ9x5G3q#4Sl}o!%CD{kEp&UGI+9Vm
z35g!}`AdLk$ORl66QmK8(g-bk!f6|(y;6DpCU`Y)w=66etj3CLJTdhCG|0yY))W4U
zk5YHfrftY&t*oU(qNjYo+!dd@Z+__wRA(GisKsDtJ{AxoUpq%PrA6?zOCv^Xieo`q
zdE9ls;8g_1+4r9oHatoZ(o^C6yeM;95!IfY3wkafKjm*9q93~^NrUIx?Kk2WFw7Ev
z4YkG>itPE$;^D>t7}-$9@s0tE1-rg2X;IDR@%INe-@uxR1Jh!OZmpYo;$%AnkLRQa
zW-HTGY|p_YbArM64I`7YM~NjB-G_Mz^wG~=m~_$?{osW)sP<B)z}I>LkG7&_u_zge
zNi4?#pDo}d37lvha!_*{WhMV&gH1R8$fPC-2vQ_|S4Tp^y)aoqhxbg*Nu+3+45YzF
zEl?cz2)rLa#nxsa<}8@77VxZtw&LN+>K<1Ue_$_rKJ5bocMkGfr%4_vA!&JSTTDi;
z8&A;hh70xw#5I&XdI(G0U2x_`{13y|Q(KQ@j5#{<9X;J5auAM(V5U=)A|PSe(dce(
zGWa!~#vVX7!g6O_cX>uRHXaj{q*5cgM57e1Y`&>Vu10^i6*PAVGy-c-pAB|Nuuo)f
zcV*OwV{;IOpa53m5?{ckRW9(UYx>~X0t&Lstw8a`NUZ01*4^PMFE0Vws_1<m>qh_F
zox%zf$UM@}GWc^c#bC=><p347R#xPirR&3fErX!em;(a^9>pKS7d6Pw$=-B;m4>~@
z)0m8!eay$YnR5=yqEnmML3seMw6$P6;Mk#X%xff`RkX<nBioG#cTl2!cW&<1<)0-z
V2POr{zZi}jPn?PUm3uk$e*kndCb<9r

literal 0
HcmV?d00001

diff --git a/tests/fixtures/placeholder.png b/tests/fixtures/placeholder.png
new file mode 100644
index 0000000000000000000000000000000000000000..54cc5909ebf999d7b0dbc85e2916c4a13e967e01
GIT binary patch
literal 2767
zcmcgui8~ZpAD%vybW5d>Y>h<1j4nx8rUo$)jcaLUEY--;rLk*F!@Y6IzKraHn~E4@
zYsS)uX>5}{N-|S+vym}mndYPa;rq_>oaa2xIq!4Mdw%cl{hbqk!_Mm9{uBEF0Kh?*
zwS@x!AaN1^_|MJV65BIAH;c@-2gMt<j+XD=zt76bDkvx@FE6Ll=`}SqB_$<fGMP%H
z#^Hj>wqa5M)`(yLK>FQI-}OXWS`h%)kAzuVaeVNZH^IOtb}9qD&e%++Kl4Xe4F$@m
zKCj0r!8!wQnK5tY;UUCJR^3`jD$ms|#k`<y{DJVe`mX){2_mz%Pc2~jON$qbQzyop
zGPV!;|Fos3=bN*<9~g)ub4$pZujBOKqA@R~Fo!D8OJ0|L28N|h-VqwwMqRpwZ~Q(R
zw^I2XJ1q%;w4_XpX(lF)jO#_yeR!5jvm7C6O7GDGSF%Vo;DA@_#`GU_I@>?58D7QJ
zY8r-{BEeRYR@&l`!3F;0Q=wrc?d<ZAdY0N>SLzdP@l-39T~v7>kTWLuP}<kSh+`Nx
zS;zy&mhcvgGS6CeaEC&#fpyo^23%18qb=XsadCmPH8R(nkT^Q7M_h>#^D6j|(km!p
zX_2^O^PI??86GkWX0m?z9#Q90hhs<l*kpcOF)B$;zJlyKbi74d<6rXK{y<{y75iw=
ztnX@Y>gr;Rb3EmywDk6-BjX10mL~3UaBI{ej9ITLncLheNfhNRUT5kGdwyy;yVf)J
zN&{VH>b-OPI(RR*XwY(`DQ~`it#S$$xX;xe3_@at`|>hHjwk*hv?N{xUCIj74Q7<t
zttvw`=$ZE^Zzw)*dQtx<NxF#$z3)kPuqcD+akX;I%|6BZiI<D~z}vBq&_r0W1{j23
zXOM*4I%P;pKfHdf%nTgWknJL`yA2pt+Ea;7TRS=&<QqU()8qyD4zTJVT8fcKdI|4W
z_`~#w3ts84&L_p8kUogQ-l;ybVN%^m3U&!ix8(TWg2uuWD&e877kg04*8>dEH7q3l
z#QPqm8SZt%HpA<~`(-l719pd#+?kyPdtj8Zu%!!a-KEU3-)F<o5+S5*OcQAYHyHT*
zG25*n8nQoQpsK2N^NRg3mGccdI_m*7N3;UCWw7?LK3XKG=y?ibm3px~<W6baF9u(A
zIPmj9f+avs6>a<=%CFgQvQYL<F2Ag)>%Nuq#4qIom4BB;vI(T$v^ERqO&En3{07|r
zt`S&niU@Cj{At-S=Mz{Hkxy{|zql-qxOKn%t!D`al60$7Zqhw)58A!iRVKgf>Q1tn
zlq3(!5_HbZbkn$r?w=M{*u((?$WY(CQym*yBVY3u<XL@BPp|Y41Pu}Sb0kV6KHEOk
z@PzlM-v#M}NW5JHLD@GNUTKWdZIZ0`jgab9gVxzmO7LZdc)glpOCH3tDqW5%(mIOG
zF!#J&^itT_S)d^qkRcgvu|uE>jt|9#hDxpZnick`Nnu;Gfzdjj(<@vUu~DC2a@`*9
z<mcaVZ5nYE8%e>`$Z+(F@nn*Y9LLs{L$isPTzy)5@C?$G#C)NmrZ`x>*Gne;mcN3j
zhtNsXRaJQx8hM6el&s;|Qpwb4dbykPDkj7^+S<6*$|pB1^)A#-efp;q)<xYDjmSRj
zdA#pQXL`fh^1kNB54{mz)FvkMQU2=+b5bwmw@Hk-IU9<Vo&KXwD)27fvIvmokbS4w
z{Cn-jc60U>6D4!quXkJ-40ITCesB{y#AJ7VQW@|?EW@d*nQ5C!C)d9$yo#9~zwDhJ
zylcJYV{ht7sWH<>TR%{19*K9dc~?EmQj>ra^YjGEyEt4<8X+k3`<XH4?W@h^&W5u|
z{PA2R6Gjht5R#%Xebz{&w>E4c8$~i+cM!deAsM#{e0ng^dqkBn+<;>StU6`wS^KIF
zbt3N6{5d1(R?2G!)@_w9q?O+lGY(yB%&~u1boJ=6&(u5T$?3_yb0XhQcsH@66ihPx
zcE~Fhg)?^z8deR}__l=0QwlRxFY+>tr{ZNguo)DUT795m_VwxvTGeqci7-F!b~Pn%
zZOvy{n!nr=XY3QDkn5%%<(+v##AzVy-FYFAk%nl1jLlOSZknCnK5#u5GWxaBjZ#)w
ze!En5Oj~y}L#QdqWt{CpSYF+1z6RBZ$0Nq^?3NKx7|82XTaUk|mz$zF*R=%$t#w*2
z#Np~*r9>)NQisdcr|+QxS6A;Z)SeA@l5J-7M=RV2;hOO~vtoH&m(-CvRY_y|_2-9&
znjoHd8-ZG6;2O-|kn=N*H_Q~U**}Vn%SJWne6><}nvpy~GyKMc_wAeuEOY+37F6<_
zReC&zy!<d_Y;^JqnzE4!sXD*C)b3UUReA@4?;+RAwuQ^{<pjmi;HISJF41K4#M;ZX
zI`b)=A>y7nMgq?ADSe{R9v@0YJEu@P*Yh{cx`D0f{wia$ht=PhoHXqQR>|*P0xf<#
z^k5Vgc?wlZ-Nc`NMasv8vk{s_1G+`BNV5!2ap|s5K~0Hb<Gq{Ar%OY_fARHudsGhN
z;D#eBFVZ=o=DHoDcB|2%Pm~EQwFgJWZ1WaVZ7?zynNB;tz&28qf$IX7E935_W4y&0
z&7R&#`^<d#Za=HO!e^3gKfoLh)3IMrg&4&dyGIv?-TPf#j~(G!ffQr&zuSe&&gCW|
zRR2gEEwn$ayc>~o6}e`xTv2$f30>%fE8`dT^ZX@6b|i6Y1tjxBFm5sMalvRwXsafQ
zwOjvNN!L5_ygV(g6;~^K4Od^(Y%l%ZS|$1F!OhL)Pgp|W@vW)(5B~<u|EdN?qEJsm
zv2EMk>FQ%E(qhiO3P^<B#=<b&ZG*Fq@p?lrJ}A#}Vs2rPVq+Ci_0_naqBIXyig<&D
z-+rTh``>;Lw!jUwQP$Rk<c_Eo4`?i-8d)-UMnMyX%ZY4U5v|}eT2$WHAPMTZ39}N%
z!^8pN7?PO^OGC9TCInI>YT8<22aRrMEr2ZqK$(mdTk3|6Z~q3vKBC`_Fgl}$UodI5
zJ{q)+2nu<#WtWy#>e9Wb10)KBaZFzhIw<5+-XTI7v-#s3k%L_hUY;HK2;)q!XL>8@
z+sIk06Sf)Ew3q`P2Q(1S&vn8${<9IPi2j%0vYRt*lz6}nT-|C@2u}TH)K9o<l3OZ;
zh}6cmZjqJzhQ6bpq@`MYL_m@2aknd?gziukpBo<Mx4IK6U?)}#s0$1|RrA<xFp-md
z>X``mQWe;peN+mY1Jd@bmX59{s>+I^pJgxD1jN*XFYFcGUW7TQnr9>iOJR#+o}sOS
zu%d4!>qeVq$q^e4DL|Nb!3*l_K{DH0r<0f!XJdVdagFaKKnxX8t!a7G%sSFDNW8k|
zL?s^5^ARYs%nA<C-P@|I8uK;$xe$5)04Sbhd9*L}{{5rgaYt>KrJY3;^wy*Q0-(`K
AlK=n!

literal 0
HcmV?d00001

diff --git a/tests/src/Kernel/AbstractKernelTestBase.php b/tests/src/Kernel/AbstractKernelTestBase.php
new file mode 100644
index 00000000..43f35878
--- /dev/null
+++ b/tests/src/Kernel/AbstractKernelTestBase.php
@@ -0,0 +1,114 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel\Kernel;
+
+use Drupal\Core\Plugin\ContextAwarePluginInterface;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\Tests\oe_whitelabel\Kernel\Traits\RenderTrait;
+use Drupal\Core\Site\Settings;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * Base class for theme's kernel tests.
+ */
+abstract class AbstractKernelTestBase extends KernelTestBase {
+
+  use RenderTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'breakpoint',
+    'image',
+    'oe_bootstrap_theme_helper',
+    'oe_whitelabel_helper',
+    'responsive_image',
+    'system',
+    'twig_field_value',
+    'ui_patterns',
+    'ui_patterns_library',
+    'user',
+    'node',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    $this->installEntitySchema('user');
+    $this->installSchema('system', 'sequences');
+    $this->installConfig(['user']);
+    $this->installConfig([
+      'system',
+      'image',
+      'responsive_image',
+      'oe_whitelabel_helper',
+    ]);
+
+    $this->container->get('theme_installer')->install(['oe_whitelabel']);
+    $this->config('system.theme')->set('default', 'oe_whitelabel')->save();
+    $this->container->set('theme.registry', NULL);
+
+    // @todo Drupal 9 ignores settings in settings.testing.php in kernel tests.
+    // See https://www.drupal.org/project/drupal/issues/3190974. Need to
+    // skip node_modules directory during template scanning because wrong
+    // template files are found (for example,
+    // node_modules/@ecl/twig-component-description-list/description-list.html.twig
+    // instead of templates/field/description-list.html.twig
+    $settings = Settings::getAll();
+    $settings['file_scan_ignore_directories'] = ['node_modules'];
+    new Settings($settings);
+
+    // Call the install hook of the User module which creates the Anonymous user
+    // and User 1. This is needed because the Anonymous user is loaded to
+    // provide the current User context which is needed in places like route
+    // enhancers.
+    // @see CurrentUserContext::getRuntimeContexts().
+    // @see EntityConverter::convert().
+    module_load_include('install', 'user');
+    user_install();
+  }
+
+  /**
+   * Get fixture content.
+   *
+   * @param string $filepath
+   *   File path.
+   *
+   * @return array
+   *   A set of test data.
+   */
+  protected function getFixtureContent(string $filepath): array {
+    return Yaml::parse(file_get_contents(__DIR__ . "/fixtures/{$filepath}"));
+  }
+
+  /**
+   * Builds and returns the renderable array for a block.
+   *
+   * @param string $block_id
+   *   The ID of the block.
+   * @param array $config
+   *   An array of configuration.
+   *
+   * @return array
+   *   A renderable array representing the content of the block.
+   */
+  protected function buildBlock(string $block_id, array $config): array {
+    /** @var \Drupal\Core\Block\BlockBase $plugin */
+    $plugin = $this->container->get('plugin.manager.block')->createInstance($block_id, $config);
+
+    // Inject runtime contexts.
+    if ($plugin instanceof ContextAwarePluginInterface) {
+      $contexts = $this->container->get('context.repository')->getRuntimeContexts($plugin->getContextMapping());
+      $this->container->get('context.handler')->applyContextMapping($plugin, $contexts);
+    }
+
+    return $plugin->build();
+  }
+
+}
diff --git a/tests/src/Kernel/ContentRenderTestBase.php b/tests/src/Kernel/ContentRenderTestBase.php
new file mode 100644
index 00000000..0eb066e9
--- /dev/null
+++ b/tests/src/Kernel/ContentRenderTestBase.php
@@ -0,0 +1,242 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel\Kernel;
+
+use Drupal\media\MediaInterface;
+use Drupal\oe_content_entity\Entity\CorporateEntityInterface;
+use Drupal\oe_content_entity_contact\Entity\Contact;
+use Drupal\oe_content_entity_contact\Entity\ContactInterface;
+use Drupal\Tests\sparql_entity_storage\Traits\SparqlConnectionTrait;
+use Drupal\user\Entity\Role;
+use Drupal\user\RoleInterface;
+
+/**
+ * Base class for testing the content being rendered.
+ */
+abstract class ContentRenderTestBase extends MultilingualAbstractKernelTestBase {
+
+  use SparqlConnectionTrait;
+
+  /**
+   * The node storage.
+   *
+   * @var \Drupal\node\NodeStorageInterface
+   */
+  protected $nodeStorage;
+
+  /**
+   * The node view builder.
+   *
+   * @var \Drupal\Core\Entity\EntityViewBuilderInterface
+   */
+  protected $nodeViewBuilder;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'address',
+    'field',
+    'field_group',
+    'link',
+    'file',
+    'text',
+    'typed_link',
+    'maxlength',
+    'entity_reference',
+    'entity_reference_revisions',
+    'composite_reference',
+    'inline_entity_form',
+    'datetime',
+    'datetime_range',
+    'node',
+    'media',
+    'views',
+    'entity_browser',
+    'media_avportal',
+    'media_avportal_mock',
+    'filter',
+    'oe_media',
+    'oe_media_avportal',
+    'oe_content',
+    'oe_content_entity',
+    'oe_content_entity_contact',
+    'oe_content_entity_organisation',
+    'oe_content_extra',
+    'oe_content_extra_project',
+    'oe_content_timeline_field',
+    'oe_content_news',
+    'oe_content_page',
+    'oe_content_policy',
+    'oe_content_departments_field',
+    'oe_content_documents_field',
+    'oe_content_publication',
+    'oe_content_reference_code_field',
+    'oe_content_featured_media_field',
+    'oe_content_project',
+    'oe_whitelabel_extra_project',
+    'sparql_entity_storage',
+    'rdf_skos',
+    'file_link',
+    'options',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    $this->setUpSparql();
+
+    $this->installEntitySchema('node');
+    $this->installSchema('file', 'file_usage');
+    $this->installSchema('node', ['node_access']);
+    $this->installEntitySchema('media');
+    $this->installEntitySchema('file');
+
+    $this->installConfig([
+      'file',
+      'field',
+      'entity_reference',
+      'entity_reference_revisions',
+      'composite_reference',
+      'node',
+      'media',
+      'filter',
+      'oe_media',
+      'media_avportal',
+      'oe_media_avportal',
+      'typed_link',
+      'address',
+    ]);
+
+    // Importing of configs which related to media av_portal output.
+    $this->container->get('config.installer')->installDefaultConfig('theme', 'oe_whitelabel');
+
+    $this->container->get('module_handler')->loadInclude('oe_content_documents_field', 'install');
+    oe_content_documents_field_install(FALSE);
+
+    $this->installConfig([
+      'oe_content',
+      'oe_content_entity',
+      'oe_content_entity_contact',
+      'oe_content_entity_organisation',
+      'oe_content_timeline_field',
+      'oe_content_departments_field',
+      'oe_content_reference_code_field',
+      'oe_content_featured_media_field',
+      'oe_content_news',
+      'oe_content_page',
+      'oe_content_policy',
+      'oe_content_project',
+      'oe_content_publication',
+      'oe_content_extra',
+      'oe_content_extra_project',
+      'oe_whitelabel_extra_project',
+    ]);
+
+    Role::load(RoleInterface::ANONYMOUS_ID)
+      ->grantPermission('bypass node access')
+      ->grantPermission('view published skos concept entities')
+      ->grantPermission('view media')
+      ->save();
+
+    module_load_include('install', 'oe_content');
+    oe_content_install(FALSE);
+
+    $this->installEntitySchema('skos_concept');
+    $this->installEntitySchema('skos_concept_scheme');
+
+    $this->nodeStorage = $this->container->get('entity_type.manager')->getStorage('node');
+    $this->nodeViewBuilder = $this->container->get('entity_type.manager')->getViewBuilder('node');
+  }
+
+  /**
+   * Creates media image entity.
+   *
+   * @param string $name
+   *   Name of the image media.
+   *
+   * @return \Drupal\media\MediaInterface
+   *   Media image instance.
+   */
+  protected function createMediaImage(string $name): MediaInterface {
+    // Create file instance.
+    $file = file_save_data(file_get_contents(drupal_get_path('theme', 'oe_whitelabel') . '/tests/fixtures/placeholder.png'), "public://placeholder_$name.png");
+    $file->setPermanent();
+    $file->save();
+
+    $media = $this->container->get('entity_type.manager')->getStorage('media')->create([
+      'bundle' => 'image',
+      'name' => "Test image $name",
+      'oe_media_image' => [
+        'target_id' => (int) $file->id(),
+        'alt' => "Alternative text $name",
+      ],
+      'uid' => 0,
+      'status' => 1,
+    ]);
+    $media->save();
+
+    return $media;
+  }
+
+  /**
+   * Creates Contact entity.
+   *
+   * @param string $name
+   *   Entity name. Is used as a parameter for test data.
+   * @param string $bundle
+   *   Entity bundle.
+   * @param int $status
+   *   Entity status.
+   *
+   * @return \Drupal\oe_content_entity_contact\Entity\ContactInterface
+   *   Contact entity.
+   */
+  protected function createContactEntity(string $name, string $bundle, int $status = CorporateEntityInterface::PUBLISHED): ContactInterface {
+    // Create image for contact.
+    $media = $this->createMediaImage($name);
+
+    $contact = Contact::create([
+      'bundle' => $bundle,
+      'name' => $name,
+      'oe_address' => [
+        'country_code' => 'BE',
+        'locality' => 'Brussels',
+        'address_line1' => "Address $name",
+        'postal_code' => '1001',
+      ],
+      'oe_body' => "Body text $name",
+      'oe_email' => "$name@example.com",
+      'oe_fax' => "Fax number $name",
+      'oe_mobile' => "Mobile number $name",
+      'oe_office' => "Office $name",
+      'oe_organisation' => "Organisation $name",
+      'oe_phone' => "Phone number $name",
+      'oe_press_contact_url' => ['uri' => "http://www.example.com/press_contact_$name"],
+      'oe_social_media' => [
+        [
+          'uri' => "http://www.example.com/social_media_$name",
+          'title' => "Social media $name",
+          'link_type' => 'facebook',
+        ],
+      ],
+      'oe_website' => ['uri' => "http://www.example.com/website_$name"],
+      'oe_image' => [
+        [
+          'target_id' => (int) $media->id(),
+          'caption' => "Caption $name",
+        ],
+      ],
+      'status' => $status,
+    ]);
+    $contact->save();
+
+    return $contact;
+  }
+
+}
diff --git a/tests/src/Kernel/MultilingualAbstractKernelTestBase.php b/tests/src/Kernel/MultilingualAbstractKernelTestBase.php
new file mode 100644
index 00000000..62bcf0bd
--- /dev/null
+++ b/tests/src/Kernel/MultilingualAbstractKernelTestBase.php
@@ -0,0 +1,96 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel\Kernel;
+
+use Drupal\locale\SourceString;
+
+/**
+ * Base class for multilingual tests.
+ */
+abstract class MultilingualAbstractKernelTestBase extends AbstractKernelTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'content_translation',
+    'locale',
+    'language',
+    'oe_multilingual',
+    'oe_multilingual_demo',
+    'system',
+    'user',
+    'ui_patterns',
+    'ui_patterns_library',
+    'oe_whitelabel_helper',
+    'image',
+    'breakpoint',
+    'responsive_image',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    $this->installSchema('locale', [
+      'locales_location',
+      'locales_source',
+      'locales_target',
+    ]);
+
+    $this->installConfig([
+      'locale',
+      'language',
+      'content_translation',
+      'oe_multilingual',
+      'image',
+      'responsive_image',
+    ]);
+
+    $this->container->get('module_handler')->loadInclude('oe_multilingual', 'install');
+    oe_multilingual_install(FALSE);
+
+    // Rebuild the container in order to make sure tests pass.
+    // @todo fix test setup so that we can get rid of this line.
+    $this->container->get('kernel')->rebuildContainer();
+  }
+
+  /**
+   * Translate a locale string.
+   *
+   * @param string $string
+   *   The string to be translated.
+   * @param string $translation
+   *   The translation string.
+   * @param string $langcode
+   *   The target language code.
+   */
+  protected function translateLocaleString(string $string, string $translation, string $langcode): void {
+    /** @var \Drupal\locale\StringDatabaseStorage $locale_storage */
+    $locale_storage = $this->container->get('locale.storage');
+    // Find the target string.
+    $locale_string = $locale_storage->findString(['source' => $string]);
+
+    // If the target string is not found, create it.
+    if (!$locale_string) {
+      $locale_string = new SourceString();
+      $locale_string->setString($string);
+      $locale_string->setStorage($locale_storage);
+      $locale_string->save();
+    }
+
+    // Add the translation for the string.
+    $locale_storage->createTranslation([
+      'lid' => $locale_string->lid,
+      'language' => $langcode,
+      'translation' => $translation,
+    ])->save();
+  }
+
+}
diff --git a/tests/src/Kernel/ProjectRenderTest.php b/tests/src/Kernel/ProjectRenderTest.php
new file mode 100644
index 00000000..a7787618
--- /dev/null
+++ b/tests/src/Kernel/ProjectRenderTest.php
@@ -0,0 +1,203 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel\Kernel;
+
+use Drupal\media\Entity\Media;
+use Drupal\node\Entity\Node;
+use Drupal\oe_content_entity_organisation\Entity\Organisation;
+use Drupal\Tests\oe_whitelabel\PatternAssertions\CardAssert;
+use Drupal\Tests\user\Traits\UserCreationTrait;
+
+/**
+ * Tests the project rendering.
+ *
+ * @group batch2
+ */
+class ProjectRenderTest extends ContentRenderTestBase {
+
+  use UserCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'address',
+    'composite_reference',
+    'datetime',
+    'datetime_range',
+    'entity_reference_revisions',
+    'field_group',
+    'file',
+    'image',
+    'inline_entity_form',
+    'link',
+    'maxlength',
+    'media',
+    'node',
+    'oe_content',
+    'oe_content_extra',
+    'oe_content_extra_project',
+    'oe_content_departments_field',
+    'oe_content_documents_field',
+    'oe_content_entity',
+    'oe_content_entity_contact',
+    'oe_content_entity_organisation',
+    'oe_content_extra_project',
+    'oe_content_featured_media_field',
+    'oe_content_project',
+    'oe_content_reference_code_field',
+    'oe_media',
+    'options',
+    'rdf_skos',
+    'system',
+    'user',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    $this->installConfig('oe_content_entity');
+    $this->installEntitySchema('oe_contact');
+    $this->installEntitySchema('oe_organisation');
+
+    module_load_include('install', 'oe_content_documents_field');
+    oe_content_documents_field_install(FALSE);
+
+    module_load_include('install', 'oe_whitelabel_extra_project');
+    oe_whitelabel_extra_project_install(FALSE);
+
+    $this->installConfig([
+      'media',
+      'node',
+      'oe_content',
+      'oe_content_entity',
+      'oe_content_entity_contact',
+      'oe_content_entity_organisation',
+      'oe_content_departments_field',
+      'oe_content_documents_field',
+      'oe_content_reference_code_field',
+      'oe_content_featured_media_field',
+      'oe_content_project',
+      'oe_content_extra_project',
+    ]);
+
+    module_load_include('install', 'oe_content');
+    oe_content_install(FALSE);
+  }
+
+  /**
+   * Test a project being rendered as a teaser.
+   */
+  public function testProjectTeaser(): void {
+    $file = file_save_data(file_get_contents(drupal_get_path('theme', 'oe_whitelabel') . '/tests/fixtures/example_1.jpeg'), 'public://example_1.jpeg');
+    $file->setPermanent();
+    $file->save();
+
+    $media = Media::create([
+      'bundle' => 'image',
+      'name' => 'test image',
+      'oe_media_image' => [
+        'target_id' => $file->id(),
+        'alt' => 'Alternative text',
+        'caption' => 'Caption',
+      ],
+    ]);
+    $media->save();
+
+    $coordinator = Organisation::create([
+      'name' => 'Coordinator 1',
+      'bundle' => 'oe_stakeholder',
+    ]);
+    $coordinator->set('oe_address', [
+      'country_code' => 'BE',
+      'locality' => 'Brussels',
+      'postal_code' => 1000,
+      'address_line1' => 'The street',
+    ]);
+    $coordinator->save();
+
+    $participant = Organisation::create([
+      'name' => 'Participant 1',
+      'bundle' => 'oe_stakeholder',
+    ]);
+    $participant->set('oe_address', [
+      'country_code' => 'BE',
+      'locality' => 'Brussels',
+      'postal_code' => 1000,
+      'address_line1' => 'The street',
+    ]);
+    $participant->save();
+
+    $values = [
+      'type' => 'oe_project',
+      'title' => 'Project 1',
+      'oe_subject' => 'http://data.europa.eu/uxp/1005',
+      'oe_author' => 'http://publications.europa.eu/resource/authority/corporate-body/ACJHR',
+      'oe_content_owner' => 'http://publications.europa.eu/resource/authority/corporate-body/ABEC',
+      'oe_project_locations' => [
+        [
+          'country_code' => 'BE',
+          'locality' => 'Brussels',
+          'postal_code' => 1000,
+        ],
+      ],
+      'body' => 'The body text',
+      'oe_teaser' => 'The teaser text',
+      'oe_project_coordinators' => [
+        [
+          'target_id' => $coordinator->id(),
+          'target_revision_id' => $coordinator->getRevisionId(),
+        ],
+      ],
+      'oe_project_participants' => [
+        [
+          'target_id' => $participant->id(),
+          'target_revision_id' => $participant->getRevisionId(),
+        ],
+      ],
+      'oe_featured_media' => [
+        [
+          'target_id' => $media->id(),
+          'caption' => 'Caption text',
+          'alt' => 'Alternative text',
+        ],
+      ],
+      'oe_project_dates' => [
+        'value' => '2020-05-10',
+        'end_value' => '2025-05-15',
+      ],
+      'status' => 1,
+    ];
+
+    $node = Node::create($values);
+    $node->save();
+
+    $build = $this->nodeViewBuilder->view($node, 'teaser');
+    $html = $this->renderRoot($build);
+
+    $assert = new CardAssert();
+
+    $expected_values = [
+      'title' => 'Project 1',
+      'url' => '/en/node/1',
+      'description' => 'The teaser text',
+      'badges' => ['EU financing'],
+      'image' => [
+        'src' => 'example_1.jpeg',
+        'alt' => 'Alternative text',
+      ],
+      'content' => [
+        '2020',
+        '2025',
+      ],
+    ];
+    $assert->assertPattern($expected_values, $html);
+    $assert->assertVariant('search', $html);
+  }
+
+}
diff --git a/tests/src/Kernel/Traits/RenderTrait.php b/tests/src/Kernel/Traits/RenderTrait.php
new file mode 100644
index 00000000..65c6db71
--- /dev/null
+++ b/tests/src/Kernel/Traits/RenderTrait.php
@@ -0,0 +1,96 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel\Kernel\Traits;
+
+use Symfony\Component\DomCrawler\Crawler;
+
+/**
+ * Helper rendering trait.
+ */
+trait RenderTrait {
+
+  /**
+   * Run various assertion on given HTML string via CSS selectors.
+   *
+   * Specifically:
+   *
+   * - 'count': assert how many times the given HTML elements occur.
+   * - 'equals': assert content of given HTML elements.
+   * - 'contains': assert content contained in given HTML elements.
+   *
+   * Assertions array has to be provided in the following format:
+   *
+   * [
+   *   'count' => [
+   *     '.ecl-page-header' => 1,
+   *   ],
+   *   'equals' => [
+   *     '.ecl-page-header__identity' => 'Digital single market',
+   *   ],
+   *   'contains' => [
+   *     'Digital',
+   *     'single',
+   *     'market',
+   *   ],
+   * ]
+   *
+   * @param string $html
+   *   A render array.
+   * @param array $assertions
+   *   Test assertions.
+   */
+  protected function assertRendering(string $html, array $assertions): void {
+    $crawler = new Crawler($html);
+
+    // Assert presence of given strings.
+    if (isset($assertions['contains'])) {
+      foreach ($assertions['contains'] as $string) {
+        $message = "String '{$string}' not found in:" . PHP_EOL . $html;
+        $this->assertContains($string, $html, $message);
+      }
+    }
+
+    // Assert occurrences of given elements.
+    if (isset($assertions['count'])) {
+      foreach ($assertions['count'] as $name => $expected) {
+        $message = "Wrong number of occurrences found for element '{$name}' in:" . PHP_EOL . $html;
+        $this->assertCount($expected, $crawler->filter($name), $message);
+      }
+    }
+
+    // Assert that a given element content equals a given string.
+    if (isset($assertions['equals'])) {
+      foreach ($assertions['equals'] as $name => $expected) {
+        try {
+          $actual = trim($crawler->filter($name)->html());
+        }
+        catch (\InvalidArgumentException $exception) {
+          $this->fail(sprintf('Element "%s" not found (exception: "%s") in: ' . PHP_EOL . ' %s', $name, $exception->getMessage(), $html));
+        }
+        $this->assertEquals($expected, $actual);
+      }
+    }
+
+  }
+
+  /**
+   * Renders final HTML given a structured array tree.
+   *
+   * @param array $elements
+   *   The structured array describing the data to be rendered.
+   *
+   * @return string
+   *   The rendered HTML.
+   *
+   * @throws \Exception
+   *   When called from inside another renderRoot() call.
+   *
+   * @see \Drupal\Core\Render\RendererInterface::render()
+   */
+  protected function renderRoot(array &$elements): string {
+    return (string) $this->container->get('renderer')->renderRoot($elements);
+  }
+
+}
diff --git a/tests/src/PatternAssertions/BasePatternAssert.php b/tests/src/PatternAssertions/BasePatternAssert.php
index f817c242..4bedfa7b 100644
--- a/tests/src/PatternAssertions/BasePatternAssert.php
+++ b/tests/src/PatternAssertions/BasePatternAssert.php
@@ -19,18 +19,23 @@ abstract class BasePatternAssert extends Assert implements PatternAssertInterfac
    * Assertions extending this class need to return an array containing the
    * assertions to be run for every possible value that can be expected.
    *
+   * @param string $variant
+   *   The variant name that is being checked.
+   *
    * @return array
    *   An array containing the assertions to be run.
    */
-  abstract protected function getAssertions(): array;
+  abstract protected function getAssertions(string $variant): array;
 
   /**
    * Method that asserts the base elements of a rendered pattern.
    *
    * @param string $html
    *   The rendered pattern.
+   * @param string $variant
+   *   The variant being asserted.
    */
-  abstract protected function assertBaseElements(string $html): void;
+  abstract protected function assertBaseElements(string $html, string $variant): void;
 
   /**
    * Returns the variant of the provided rendered pattern.
@@ -193,4 +198,24 @@ abstract class BasePatternAssert extends Assert implements PatternAssertInterfac
     self::assertStringContainsString($expected_image['src'], $element->attr('src'));
   }
 
+  /**
+   * Asserts the badges items of the pattern.
+   *
+   * @param array $badges
+   *   The expected badges item values.
+   * @param \Symfony\Component\DomCrawler\Crawler $crawler
+   *   The DomCrawler where to check the element.
+   */
+  protected function assertBadgesElements(array $badges, Crawler $crawler): void {
+    if (empty($badges)) {
+      $this->assertElementNotExists('.badge', $crawler);
+      return;
+    }
+    $badges_items = $crawler->filter('.mt-2-5');
+    self::assertCount(count($badges), $badges_items);
+    foreach ($badges as $index => $badge) {
+      self::assertEquals($badge, trim($badges_items->eq($index)->text()));
+    }
+  }
+
 }
diff --git a/tests/src/PatternAssertions/CardAssert.php b/tests/src/PatternAssertions/CardAssert.php
new file mode 100644
index 00000000..7179e8b5
--- /dev/null
+++ b/tests/src/PatternAssertions/CardAssert.php
@@ -0,0 +1,126 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\Tests\oe_whitelabel\PatternAssertions;
+
+use Symfony\Component\DomCrawler\Crawler;
+
+/**
+ * Assertions for the card pattern.
+ *
+ * @see ./templates/patterns/card/card.ui_patterns.yml
+ */
+class CardAssert extends BasePatternAssert {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getAssertions($variant): array {
+    return [
+      'title' => [
+        [$this, 'assertElementText'],
+        'div.card.listing-item .card-title a span',
+      ],
+      'url' => [
+        [$this, 'assertElementAttribute'],
+        'div.card.listing-item .card-title a',
+        'href',
+      ],
+      'image' => [
+        [$this, 'assertCardImage'],
+        $variant,
+      ],
+      'description' => [
+        [$this, 'assertElementText'],
+        '.card-text',
+      ],
+      'badges' => [
+        [$this, 'assertBadgesElements'],
+      ],
+      'content' => [
+        [$this, 'assertContent'],
+      ],
+    ];
+  }
+
+  /**
+   * Asserts the image of a card.
+   *
+   * @param array|null $expected_image
+   *   The expected image values.
+   * @param string $variant
+   *   The variant of the pattern being checked.
+   * @param \Symfony\Component\DomCrawler\Crawler $crawler
+   *   The DomCrawler where to check the element.
+   */
+  protected function assertCardImage($expected_image, string $variant, Crawler $crawler): void {
+    if ($variant == 'search') {
+      $image_div = $crawler->filter('div.card div.col-md-3.col-lg-2.rounded.mw-listing-img img.card-img-top');
+      self::assertEquals($expected_image['alt'], $image_div->attr('alt'));
+      self::assertStringContainsString($expected_image['src'], $image_div->attr('src'));
+    }
+    else {
+      $image_div = $crawler->filter('div.card img');
+      self::assertEquals($expected_image['alt'], $image_div->attr('alt'));
+      self::assertStringContainsString($expected_image['src'], $image_div->attr('src'));
+    }
+  }
+
+  /**
+   * Asserts the content of a card.
+   *
+   * @param array $expected_items
+   *   The expected item values.
+   * @param \Symfony\Component\DomCrawler\Crawler $crawler
+   *   The DomCrawler where to check the element.
+   */
+  protected function assertContent(array $expected_items, Crawler $crawler): void {
+    foreach ($expected_items as $expected_item) {
+      self::assertStringContainsString($expected_item, $crawler->html());
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function assertBaseElements(string $html, string $variant): void {
+    $crawler = new Crawler($html);
+    $base_selector = 'article ' . $this->getBaseItemClass($variant);
+    $card = $crawler->filter($base_selector);
+    self::assertCount(1, $card);
+  }
+
+  /**
+   * Returns the base CSS selector for a list item depending on the variant.
+   *
+   * @param string $variant
+   *   The variant being checked.
+   *
+   * @return string
+   *   The base selector for the variant.
+   */
+  protected function getBaseItemClass(string $variant): string {
+    switch ($variant) {
+      case 'search':
+        return 'div.listing-item.card';
+
+      default:
+        return 'div.card';
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   *
+   * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+   */
+  protected function getPatternVariant(string $html): string {
+    $crawler = new Crawler($html);
+    if ($crawler->filter('div.mw-listing-img')) {
+      return 'search';
+    }
+    return 'default';
+  }
+
+}
diff --git a/tests/src/PatternAssertions/ContentBannerAssert.php b/tests/src/PatternAssertions/ContentBannerAssert.php
index d83d8ce8..02d98473 100644
--- a/tests/src/PatternAssertions/ContentBannerAssert.php
+++ b/tests/src/PatternAssertions/ContentBannerAssert.php
@@ -43,24 +43,4 @@ class ContentBannerAssert extends BasePatternAssert {
     self::assertCount(1, $page_header);
   }
 
-  /**
-   * Asserts the badges items of the pattern.
-   *
-   * @param array $badges
-   *   The expected badges item values.
-   * @param \Symfony\Component\DomCrawler\Crawler $crawler
-   *   The DomCrawler where to check the element.
-   */
-  protected function assertBadgesElements(array $badges, Crawler $crawler): void {
-    if (empty($badges)) {
-      $this->assertElementNotExists('.badge', $crawler);
-      return;
-    }
-    $badges_items = $crawler->filter('.mt-2-5');
-    self::assertCount(count($badges), $badges_items);
-    foreach ($badges as $index => $badge) {
-      self::assertEquals($badge, trim($badges_items->eq($index)->text()));
-    }
-  }
-
 }
-- 
GitLab


From 11fe303a1f346c1d69baea9b6f85e41635ff43d1 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Fri, 1 Apr 2022 12:59:35 +0200
Subject: [PATCH 046/152] OEL-1298: Add variant to methods getAssertions and
 assertBaseElements of PatternAssertion files.

---
 tests/src/PatternAssertions/ContentBannerAssert.php    | 4 ++--
 tests/src/PatternAssertions/DescriptionListAssert.php  | 4 ++--
 tests/src/PatternAssertions/InPageNavigationAssert.php | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/tests/src/PatternAssertions/ContentBannerAssert.php b/tests/src/PatternAssertions/ContentBannerAssert.php
index 02d98473..af68fe0e 100644
--- a/tests/src/PatternAssertions/ContentBannerAssert.php
+++ b/tests/src/PatternAssertions/ContentBannerAssert.php
@@ -14,7 +14,7 @@ class ContentBannerAssert extends BasePatternAssert {
   /**
    * {@inheritdoc}
    */
-  protected function getAssertions(): array {
+  protected function getAssertions(string $variant): array {
     return [
       'image' => [
         [$this, 'assertImage'],
@@ -37,7 +37,7 @@ class ContentBannerAssert extends BasePatternAssert {
   /**
    * {@inheritdoc}
    */
-  protected function assertBaseElements(string $html): void {
+  protected function assertBaseElements(string $html, string $variant): void {
     $crawler = new Crawler($html);
     $page_header = $crawler->filter('.bcl-content-banner');
     self::assertCount(1, $page_header);
diff --git a/tests/src/PatternAssertions/DescriptionListAssert.php b/tests/src/PatternAssertions/DescriptionListAssert.php
index b8d376a5..32b22879 100644
--- a/tests/src/PatternAssertions/DescriptionListAssert.php
+++ b/tests/src/PatternAssertions/DescriptionListAssert.php
@@ -16,7 +16,7 @@ class DescriptionListAssert extends BasePatternAssert {
   /**
    * {@inheritdoc}
    */
-  protected function getAssertions(): array {
+  protected function getAssertions(string $variant): array {
     return [
       'items' => [
         [$this, 'assertItems'],
@@ -27,7 +27,7 @@ class DescriptionListAssert extends BasePatternAssert {
   /**
    * {@inheritdoc}
    */
-  protected function assertBaseElements(string $html): void {
+  protected function assertBaseElements(string $html, string $variant): void {
     $crawler = new Crawler($html);
     $field_list_container = $crawler->filter('body');
     self::assertCount(1, $field_list_container);
diff --git a/tests/src/PatternAssertions/InPageNavigationAssert.php b/tests/src/PatternAssertions/InPageNavigationAssert.php
index 43e5e2fa..b2d9bdf9 100644
--- a/tests/src/PatternAssertions/InPageNavigationAssert.php
+++ b/tests/src/PatternAssertions/InPageNavigationAssert.php
@@ -14,7 +14,7 @@ class InPageNavigationAssert extends BasePatternAssert {
   /**
    * {@inheritdoc}
    */
-  protected function getAssertions(): array {
+  protected function getAssertions(string $variant): array {
     return [
       'title' => [
         [$this, 'assertElementText'],
@@ -29,7 +29,7 @@ class InPageNavigationAssert extends BasePatternAssert {
   /**
    * {@inheritdoc}
    */
-  protected function assertBaseElements(string $html): void {
+  protected function assertBaseElements(string $html, string $variant): void {
     $crawler = new Crawler($html);
     $page_header = $crawler->filter('body');
     self::assertCount(1, $page_header);
-- 
GitLab


From d188c3d79d2bd53903e1bd04f2c4aa676f8ad331 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Fri, 1 Apr 2022 16:27:26 +0200
Subject: [PATCH 047/152] OEL-1298: Eliminate classes not used and adapt rest
 of render classes to keep working.

---
 tests/src/Kernel/AbstractKernelTestBase.php   | 80 +---------------
 tests/src/Kernel/ContentRenderTestBase.php    | 91 +-----------------
 .../MultilingualAbstractKernelTestBase.php    | 96 -------------------
 tests/src/Kernel/ProjectRenderTest.php        |  2 +-
 tests/src/Kernel/Traits/RenderTrait.php       | 96 -------------------
 5 files changed, 5 insertions(+), 360 deletions(-)
 delete mode 100644 tests/src/Kernel/MultilingualAbstractKernelTestBase.php
 delete mode 100644 tests/src/Kernel/Traits/RenderTrait.php

diff --git a/tests/src/Kernel/AbstractKernelTestBase.php b/tests/src/Kernel/AbstractKernelTestBase.php
index 43f35878..fb8fed7c 100644
--- a/tests/src/Kernel/AbstractKernelTestBase.php
+++ b/tests/src/Kernel/AbstractKernelTestBase.php
@@ -4,16 +4,13 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\oe_whitelabel\Kernel;
 
-use Drupal\Core\Plugin\ContextAwarePluginInterface;
-use Drupal\KernelTests\KernelTestBase;
-use Drupal\Tests\oe_whitelabel\Kernel\Traits\RenderTrait;
-use Drupal\Core\Site\Settings;
-use Symfony\Component\Yaml\Yaml;
+use Drupal\Tests\oe_bootstrap_theme\Kernel\AbstractKernelTestBase as OebtAbstractKernelTestBase;
+use Drupal\Tests\oe_bootstrap_theme\Kernel\Traits\RenderTrait;
 
 /**
  * Base class for theme's kernel tests.
  */
-abstract class AbstractKernelTestBase extends KernelTestBase {
+abstract class AbstractKernelTestBase extends OebtAbstractKernelTestBase {
 
   use RenderTrait;
 
@@ -21,17 +18,7 @@ abstract class AbstractKernelTestBase extends KernelTestBase {
    * {@inheritdoc}
    */
   protected static $modules = [
-    'breakpoint',
-    'image',
-    'oe_bootstrap_theme_helper',
     'oe_whitelabel_helper',
-    'responsive_image',
-    'system',
-    'twig_field_value',
-    'ui_patterns',
-    'ui_patterns_library',
-    'user',
-    'node',
   ];
 
   /**
@@ -40,13 +27,7 @@ abstract class AbstractKernelTestBase extends KernelTestBase {
   protected function setUp(): void {
     parent::setUp();
 
-    $this->installEntitySchema('user');
-    $this->installSchema('system', 'sequences');
-    $this->installConfig(['user']);
     $this->installConfig([
-      'system',
-      'image',
-      'responsive_image',
       'oe_whitelabel_helper',
     ]);
 
@@ -54,61 +35,6 @@ abstract class AbstractKernelTestBase extends KernelTestBase {
     $this->config('system.theme')->set('default', 'oe_whitelabel')->save();
     $this->container->set('theme.registry', NULL);
 
-    // @todo Drupal 9 ignores settings in settings.testing.php in kernel tests.
-    // See https://www.drupal.org/project/drupal/issues/3190974. Need to
-    // skip node_modules directory during template scanning because wrong
-    // template files are found (for example,
-    // node_modules/@ecl/twig-component-description-list/description-list.html.twig
-    // instead of templates/field/description-list.html.twig
-    $settings = Settings::getAll();
-    $settings['file_scan_ignore_directories'] = ['node_modules'];
-    new Settings($settings);
-
-    // Call the install hook of the User module which creates the Anonymous user
-    // and User 1. This is needed because the Anonymous user is loaded to
-    // provide the current User context which is needed in places like route
-    // enhancers.
-    // @see CurrentUserContext::getRuntimeContexts().
-    // @see EntityConverter::convert().
-    module_load_include('install', 'user');
-    user_install();
-  }
-
-  /**
-   * Get fixture content.
-   *
-   * @param string $filepath
-   *   File path.
-   *
-   * @return array
-   *   A set of test data.
-   */
-  protected function getFixtureContent(string $filepath): array {
-    return Yaml::parse(file_get_contents(__DIR__ . "/fixtures/{$filepath}"));
-  }
-
-  /**
-   * Builds and returns the renderable array for a block.
-   *
-   * @param string $block_id
-   *   The ID of the block.
-   * @param array $config
-   *   An array of configuration.
-   *
-   * @return array
-   *   A renderable array representing the content of the block.
-   */
-  protected function buildBlock(string $block_id, array $config): array {
-    /** @var \Drupal\Core\Block\BlockBase $plugin */
-    $plugin = $this->container->get('plugin.manager.block')->createInstance($block_id, $config);
-
-    // Inject runtime contexts.
-    if ($plugin instanceof ContextAwarePluginInterface) {
-      $contexts = $this->container->get('context.repository')->getRuntimeContexts($plugin->getContextMapping());
-      $this->container->get('context.handler')->applyContextMapping($plugin, $contexts);
-    }
-
-    return $plugin->build();
   }
 
 }
diff --git a/tests/src/Kernel/ContentRenderTestBase.php b/tests/src/Kernel/ContentRenderTestBase.php
index 0eb066e9..b33bcdfc 100644
--- a/tests/src/Kernel/ContentRenderTestBase.php
+++ b/tests/src/Kernel/ContentRenderTestBase.php
@@ -4,10 +4,6 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\oe_whitelabel\Kernel;
 
-use Drupal\media\MediaInterface;
-use Drupal\oe_content_entity\Entity\CorporateEntityInterface;
-use Drupal\oe_content_entity_contact\Entity\Contact;
-use Drupal\oe_content_entity_contact\Entity\ContactInterface;
 use Drupal\Tests\sparql_entity_storage\Traits\SparqlConnectionTrait;
 use Drupal\user\Entity\Role;
 use Drupal\user\RoleInterface;
@@ -15,7 +11,7 @@ use Drupal\user\RoleInterface;
 /**
  * Base class for testing the content being rendered.
  */
-abstract class ContentRenderTestBase extends MultilingualAbstractKernelTestBase {
+abstract class ContentRenderTestBase extends AbstractKernelTestBase {
 
   use SparqlConnectionTrait;
 
@@ -154,89 +150,4 @@ abstract class ContentRenderTestBase extends MultilingualAbstractKernelTestBase
     $this->nodeViewBuilder = $this->container->get('entity_type.manager')->getViewBuilder('node');
   }
 
-  /**
-   * Creates media image entity.
-   *
-   * @param string $name
-   *   Name of the image media.
-   *
-   * @return \Drupal\media\MediaInterface
-   *   Media image instance.
-   */
-  protected function createMediaImage(string $name): MediaInterface {
-    // Create file instance.
-    $file = file_save_data(file_get_contents(drupal_get_path('theme', 'oe_whitelabel') . '/tests/fixtures/placeholder.png'), "public://placeholder_$name.png");
-    $file->setPermanent();
-    $file->save();
-
-    $media = $this->container->get('entity_type.manager')->getStorage('media')->create([
-      'bundle' => 'image',
-      'name' => "Test image $name",
-      'oe_media_image' => [
-        'target_id' => (int) $file->id(),
-        'alt' => "Alternative text $name",
-      ],
-      'uid' => 0,
-      'status' => 1,
-    ]);
-    $media->save();
-
-    return $media;
-  }
-
-  /**
-   * Creates Contact entity.
-   *
-   * @param string $name
-   *   Entity name. Is used as a parameter for test data.
-   * @param string $bundle
-   *   Entity bundle.
-   * @param int $status
-   *   Entity status.
-   *
-   * @return \Drupal\oe_content_entity_contact\Entity\ContactInterface
-   *   Contact entity.
-   */
-  protected function createContactEntity(string $name, string $bundle, int $status = CorporateEntityInterface::PUBLISHED): ContactInterface {
-    // Create image for contact.
-    $media = $this->createMediaImage($name);
-
-    $contact = Contact::create([
-      'bundle' => $bundle,
-      'name' => $name,
-      'oe_address' => [
-        'country_code' => 'BE',
-        'locality' => 'Brussels',
-        'address_line1' => "Address $name",
-        'postal_code' => '1001',
-      ],
-      'oe_body' => "Body text $name",
-      'oe_email' => "$name@example.com",
-      'oe_fax' => "Fax number $name",
-      'oe_mobile' => "Mobile number $name",
-      'oe_office' => "Office $name",
-      'oe_organisation' => "Organisation $name",
-      'oe_phone' => "Phone number $name",
-      'oe_press_contact_url' => ['uri' => "http://www.example.com/press_contact_$name"],
-      'oe_social_media' => [
-        [
-          'uri' => "http://www.example.com/social_media_$name",
-          'title' => "Social media $name",
-          'link_type' => 'facebook',
-        ],
-      ],
-      'oe_website' => ['uri' => "http://www.example.com/website_$name"],
-      'oe_image' => [
-        [
-          'target_id' => (int) $media->id(),
-          'caption' => "Caption $name",
-        ],
-      ],
-      'status' => $status,
-    ]);
-    $contact->save();
-
-    return $contact;
-  }
-
 }
diff --git a/tests/src/Kernel/MultilingualAbstractKernelTestBase.php b/tests/src/Kernel/MultilingualAbstractKernelTestBase.php
deleted file mode 100644
index 62bcf0bd..00000000
--- a/tests/src/Kernel/MultilingualAbstractKernelTestBase.php
+++ /dev/null
@@ -1,96 +0,0 @@
-<?php
-
-declare(strict_types = 1);
-
-namespace Drupal\Tests\oe_whitelabel\Kernel;
-
-use Drupal\locale\SourceString;
-
-/**
- * Base class for multilingual tests.
- */
-abstract class MultilingualAbstractKernelTestBase extends AbstractKernelTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = [
-    'content_translation',
-    'locale',
-    'language',
-    'oe_multilingual',
-    'oe_multilingual_demo',
-    'system',
-    'user',
-    'ui_patterns',
-    'ui_patterns_library',
-    'oe_whitelabel_helper',
-    'image',
-    'breakpoint',
-    'responsive_image',
-  ];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp(): void {
-    parent::setUp();
-
-    $this->installSchema('locale', [
-      'locales_location',
-      'locales_source',
-      'locales_target',
-    ]);
-
-    $this->installConfig([
-      'locale',
-      'language',
-      'content_translation',
-      'oe_multilingual',
-      'image',
-      'responsive_image',
-    ]);
-
-    $this->container->get('module_handler')->loadInclude('oe_multilingual', 'install');
-    oe_multilingual_install(FALSE);
-
-    // Rebuild the container in order to make sure tests pass.
-    // @todo fix test setup so that we can get rid of this line.
-    $this->container->get('kernel')->rebuildContainer();
-  }
-
-  /**
-   * Translate a locale string.
-   *
-   * @param string $string
-   *   The string to be translated.
-   * @param string $translation
-   *   The translation string.
-   * @param string $langcode
-   *   The target language code.
-   */
-  protected function translateLocaleString(string $string, string $translation, string $langcode): void {
-    /** @var \Drupal\locale\StringDatabaseStorage $locale_storage */
-    $locale_storage = $this->container->get('locale.storage');
-    // Find the target string.
-    $locale_string = $locale_storage->findString(['source' => $string]);
-
-    // If the target string is not found, create it.
-    if (!$locale_string) {
-      $locale_string = new SourceString();
-      $locale_string->setString($string);
-      $locale_string->setStorage($locale_storage);
-      $locale_string->save();
-    }
-
-    // Add the translation for the string.
-    $locale_storage->createTranslation([
-      'lid' => $locale_string->lid,
-      'language' => $langcode,
-      'translation' => $translation,
-    ])->save();
-  }
-
-}
diff --git a/tests/src/Kernel/ProjectRenderTest.php b/tests/src/Kernel/ProjectRenderTest.php
index a7787618..49de03a3 100644
--- a/tests/src/Kernel/ProjectRenderTest.php
+++ b/tests/src/Kernel/ProjectRenderTest.php
@@ -184,7 +184,7 @@ class ProjectRenderTest extends ContentRenderTestBase {
 
     $expected_values = [
       'title' => 'Project 1',
-      'url' => '/en/node/1',
+      'url' => '/node/1',
       'description' => 'The teaser text',
       'badges' => ['EU financing'],
       'image' => [
diff --git a/tests/src/Kernel/Traits/RenderTrait.php b/tests/src/Kernel/Traits/RenderTrait.php
deleted file mode 100644
index 65c6db71..00000000
--- a/tests/src/Kernel/Traits/RenderTrait.php
+++ /dev/null
@@ -1,96 +0,0 @@
-<?php
-
-declare(strict_types = 1);
-
-namespace Drupal\Tests\oe_whitelabel\Kernel\Traits;
-
-use Symfony\Component\DomCrawler\Crawler;
-
-/**
- * Helper rendering trait.
- */
-trait RenderTrait {
-
-  /**
-   * Run various assertion on given HTML string via CSS selectors.
-   *
-   * Specifically:
-   *
-   * - 'count': assert how many times the given HTML elements occur.
-   * - 'equals': assert content of given HTML elements.
-   * - 'contains': assert content contained in given HTML elements.
-   *
-   * Assertions array has to be provided in the following format:
-   *
-   * [
-   *   'count' => [
-   *     '.ecl-page-header' => 1,
-   *   ],
-   *   'equals' => [
-   *     '.ecl-page-header__identity' => 'Digital single market',
-   *   ],
-   *   'contains' => [
-   *     'Digital',
-   *     'single',
-   *     'market',
-   *   ],
-   * ]
-   *
-   * @param string $html
-   *   A render array.
-   * @param array $assertions
-   *   Test assertions.
-   */
-  protected function assertRendering(string $html, array $assertions): void {
-    $crawler = new Crawler($html);
-
-    // Assert presence of given strings.
-    if (isset($assertions['contains'])) {
-      foreach ($assertions['contains'] as $string) {
-        $message = "String '{$string}' not found in:" . PHP_EOL . $html;
-        $this->assertContains($string, $html, $message);
-      }
-    }
-
-    // Assert occurrences of given elements.
-    if (isset($assertions['count'])) {
-      foreach ($assertions['count'] as $name => $expected) {
-        $message = "Wrong number of occurrences found for element '{$name}' in:" . PHP_EOL . $html;
-        $this->assertCount($expected, $crawler->filter($name), $message);
-      }
-    }
-
-    // Assert that a given element content equals a given string.
-    if (isset($assertions['equals'])) {
-      foreach ($assertions['equals'] as $name => $expected) {
-        try {
-          $actual = trim($crawler->filter($name)->html());
-        }
-        catch (\InvalidArgumentException $exception) {
-          $this->fail(sprintf('Element "%s" not found (exception: "%s") in: ' . PHP_EOL . ' %s', $name, $exception->getMessage(), $html));
-        }
-        $this->assertEquals($expected, $actual);
-      }
-    }
-
-  }
-
-  /**
-   * Renders final HTML given a structured array tree.
-   *
-   * @param array $elements
-   *   The structured array describing the data to be rendered.
-   *
-   * @return string
-   *   The rendered HTML.
-   *
-   * @throws \Exception
-   *   When called from inside another renderRoot() call.
-   *
-   * @see \Drupal\Core\Render\RendererInterface::render()
-   */
-  protected function renderRoot(array &$elements): string {
-    return (string) $this->container->get('renderer')->renderRoot($elements);
-  }
-
-}
-- 
GitLab


From 0d7331ad362853bdea93d9ae78fb8fc43f71e75b Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Fri, 1 Apr 2022 16:37:00 +0200
Subject: [PATCH 048/152] OEL-1298: Wrap project teaser card in block content
 as per news and event templates.

---
 templates/content/node--oe-project--teaser.html.twig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/templates/content/node--oe-project--teaser.html.twig b/templates/content/node--oe-project--teaser.html.twig
index e73c2f27..8c8b7898 100644
--- a/templates/content/node--oe-project--teaser.html.twig
+++ b/templates/content/node--oe-project--teaser.html.twig
@@ -10,6 +10,7 @@
 {% set _content %}
   <span class="text-muted text-nowrap me-4-5">{{ content.oe_project_dates }}</span>
 {% endset %}
+{% block content %}
 <article{{attributes}}>
   {{ pattern('card', {
     variant: 'search',
@@ -20,3 +21,4 @@
     badges: badges,
   }) }}
 </article>
+{% endblock %}
-- 
GitLab


From 6fbb926e95344476f25457821d52339d43eacfc2 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Fri, 1 Apr 2022 16:58:56 +0200
Subject: [PATCH 049/152] OEL-1298: Change the class title and eliminate batch2
 tag.

---
 tests/src/Kernel/ProjectRenderTest.php | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/tests/src/Kernel/ProjectRenderTest.php b/tests/src/Kernel/ProjectRenderTest.php
index 49de03a3..54e2e72e 100644
--- a/tests/src/Kernel/ProjectRenderTest.php
+++ b/tests/src/Kernel/ProjectRenderTest.php
@@ -6,14 +6,11 @@ namespace Drupal\Tests\oe_whitelabel\Kernel;
 
 use Drupal\media\Entity\Media;
 use Drupal\node\Entity\Node;
-use Drupal\oe_content_entity_organisation\Entity\Organisation;
 use Drupal\Tests\oe_whitelabel\PatternAssertions\CardAssert;
 use Drupal\Tests\user\Traits\UserCreationTrait;
 
 /**
- * Tests the project rendering.
- *
- * @group batch2
+ * Tests the rendering of the teaser view mode of Project content type.
  */
 class ProjectRenderTest extends ContentRenderTestBase {
 
-- 
GitLab


From 9197843bba7fd80f721ae5059e38aee7096ec857 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Fri, 1 Apr 2022 16:59:48 +0200
Subject: [PATCH 050/152] OEL-1298: Eliminate unneeded modules and config at
 ProjectRenderTest.php.

---
 tests/src/Kernel/ProjectRenderTest.php | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/tests/src/Kernel/ProjectRenderTest.php b/tests/src/Kernel/ProjectRenderTest.php
index 54e2e72e..d18ff4cb 100644
--- a/tests/src/Kernel/ProjectRenderTest.php
+++ b/tests/src/Kernel/ProjectRenderTest.php
@@ -36,15 +36,11 @@ class ProjectRenderTest extends ContentRenderTestBase {
     'oe_content',
     'oe_content_extra',
     'oe_content_extra_project',
-    'oe_content_departments_field',
     'oe_content_documents_field',
     'oe_content_entity',
-    'oe_content_entity_contact',
-    'oe_content_entity_organisation',
     'oe_content_extra_project',
     'oe_content_featured_media_field',
     'oe_content_project',
-    'oe_content_reference_code_field',
     'oe_media',
     'options',
     'rdf_skos',
@@ -73,11 +69,7 @@ class ProjectRenderTest extends ContentRenderTestBase {
       'node',
       'oe_content',
       'oe_content_entity',
-      'oe_content_entity_contact',
-      'oe_content_entity_organisation',
-      'oe_content_departments_field',
       'oe_content_documents_field',
-      'oe_content_reference_code_field',
       'oe_content_featured_media_field',
       'oe_content_project',
       'oe_content_extra_project',
-- 
GitLab


From aaf068b07dc33ca4461eccbe35f674161941e6ba Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Fri, 1 Apr 2022 17:00:44 +0200
Subject: [PATCH 051/152] OEL-1298: Eliminate unneeded modules and config at
 ContentRenderTestBase.php.

---
 tests/src/Kernel/ContentRenderTestBase.php | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/tests/src/Kernel/ContentRenderTestBase.php b/tests/src/Kernel/ContentRenderTestBase.php
index b33bcdfc..2784ad01 100644
--- a/tests/src/Kernel/ContentRenderTestBase.php
+++ b/tests/src/Kernel/ContentRenderTestBase.php
@@ -62,13 +62,8 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
     'oe_content_entity_organisation',
     'oe_content_extra',
     'oe_content_extra_project',
-    'oe_content_timeline_field',
-    'oe_content_news',
-    'oe_content_page',
-    'oe_content_policy',
     'oe_content_departments_field',
     'oe_content_documents_field',
-    'oe_content_publication',
     'oe_content_reference_code_field',
     'oe_content_featured_media_field',
     'oe_content_project',
@@ -120,15 +115,10 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
       'oe_content_entity',
       'oe_content_entity_contact',
       'oe_content_entity_organisation',
-      'oe_content_timeline_field',
       'oe_content_departments_field',
       'oe_content_reference_code_field',
       'oe_content_featured_media_field',
-      'oe_content_news',
-      'oe_content_page',
-      'oe_content_policy',
       'oe_content_project',
-      'oe_content_publication',
       'oe_content_extra',
       'oe_content_extra_project',
       'oe_whitelabel_extra_project',
-- 
GitLab


From f7a4c95039d7b14baad3bb9d4c9d27613777e657 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Fri, 1 Apr 2022 17:01:18 +0200
Subject: [PATCH 052/152] OEL-1298: Eliminate unneeded field data of node
 Project at ProjectRenderTest.php.

---
 tests/src/Kernel/ProjectRenderTest.php | 36 --------------------------
 1 file changed, 36 deletions(-)

diff --git a/tests/src/Kernel/ProjectRenderTest.php b/tests/src/Kernel/ProjectRenderTest.php
index d18ff4cb..2666bc07 100644
--- a/tests/src/Kernel/ProjectRenderTest.php
+++ b/tests/src/Kernel/ProjectRenderTest.php
@@ -98,30 +98,6 @@ class ProjectRenderTest extends ContentRenderTestBase {
     ]);
     $media->save();
 
-    $coordinator = Organisation::create([
-      'name' => 'Coordinator 1',
-      'bundle' => 'oe_stakeholder',
-    ]);
-    $coordinator->set('oe_address', [
-      'country_code' => 'BE',
-      'locality' => 'Brussels',
-      'postal_code' => 1000,
-      'address_line1' => 'The street',
-    ]);
-    $coordinator->save();
-
-    $participant = Organisation::create([
-      'name' => 'Participant 1',
-      'bundle' => 'oe_stakeholder',
-    ]);
-    $participant->set('oe_address', [
-      'country_code' => 'BE',
-      'locality' => 'Brussels',
-      'postal_code' => 1000,
-      'address_line1' => 'The street',
-    ]);
-    $participant->save();
-
     $values = [
       'type' => 'oe_project',
       'title' => 'Project 1',
@@ -137,18 +113,6 @@ class ProjectRenderTest extends ContentRenderTestBase {
       ],
       'body' => 'The body text',
       'oe_teaser' => 'The teaser text',
-      'oe_project_coordinators' => [
-        [
-          'target_id' => $coordinator->id(),
-          'target_revision_id' => $coordinator->getRevisionId(),
-        ],
-      ],
-      'oe_project_participants' => [
-        [
-          'target_id' => $participant->id(),
-          'target_revision_id' => $participant->getRevisionId(),
-        ],
-      ],
       'oe_featured_media' => [
         [
           'target_id' => $media->id(),
-- 
GitLab


From 434f568f6785bf2bed90461714af22a11ccb56cc Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Fri, 1 Apr 2022 18:33:42 +0200
Subject: [PATCH 053/152] OEL-1298: Improve description of hook preprocess
 badges at oe_whitelabel_extra_project.module.

---
 .../oe_whitelabel_extra_project.module                    | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 2784e8bb..2fae1f27 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -152,7 +152,13 @@ function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables):
 }
 
 /**
- * Implements hook_preprocess().
+ * Implements hook_preprocess() for project badges.
+ *
+ * This preprocess moves the label from field oe_subject items into badges to
+ * prepare its renderization at the patter-card-variant-search.html.twig.
+ *
+ * @todo remove once the following issue is resolved.
+ * @see https://citnet.tech.ec.europa.eu/CITnet/jira/browse/OEL-1159
  */
 function _oe_whitelabel_extra_project_preprocess_badges(&$variables) {
   /** @var \Drupal\node\NodeInterface $node */
-- 
GitLab


From 163cdb69537e5d3e11ca8111b07e43060edc6fb8 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Fri, 1 Apr 2022 18:41:34 +0200
Subject: [PATCH 054/152] OEL-1298: Simplyfy selectors at CardAssert.php.

---
 tests/src/PatternAssertions/CardAssert.php | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/src/PatternAssertions/CardAssert.php b/tests/src/PatternAssertions/CardAssert.php
index 7179e8b5..2fd4c0b8 100644
--- a/tests/src/PatternAssertions/CardAssert.php
+++ b/tests/src/PatternAssertions/CardAssert.php
@@ -20,11 +20,11 @@ class CardAssert extends BasePatternAssert {
     return [
       'title' => [
         [$this, 'assertElementText'],
-        'div.card.listing-item .card-title a span',
+        '.card-title a span',
       ],
       'url' => [
         [$this, 'assertElementAttribute'],
-        'div.card.listing-item .card-title a',
+        '.card-title a',
         'href',
       ],
       'image' => [
@@ -56,7 +56,7 @@ class CardAssert extends BasePatternAssert {
    */
   protected function assertCardImage($expected_image, string $variant, Crawler $crawler): void {
     if ($variant == 'search') {
-      $image_div = $crawler->filter('div.card div.col-md-3.col-lg-2.rounded.mw-listing-img img.card-img-top');
+      $image_div = $crawler->filter('.mw-listing-img img.card-img-top');
       self::assertEquals($expected_image['alt'], $image_div->attr('alt'));
       self::assertStringContainsString($expected_image['src'], $image_div->attr('src'));
     }
-- 
GitLab


From adc425e5b0aae99bae503328d063c9d65597069c Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Fri, 1 Apr 2022 19:23:26 +0200
Subject: [PATCH 055/152] OEL-1298: Using oe_whitelabel_project_date at teaser
 and adapt test for it.

---
 .../core.entity_view_display.node.oe_project.teaser.yml       | 2 +-
 tests/src/Kernel/ProjectRenderTest.php                        | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml
index e4823928..acf60336 100644
--- a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml
+++ b/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml
@@ -74,7 +74,7 @@ content:
     label: hidden
     settings:
       timezone_override: ''
-      format_type: html_year
+      format_type: oe_whitelabel_project_date
       separator: '-'
     third_party_settings: {  }
     weight: 3
diff --git a/tests/src/Kernel/ProjectRenderTest.php b/tests/src/Kernel/ProjectRenderTest.php
index 2666bc07..ef168005 100644
--- a/tests/src/Kernel/ProjectRenderTest.php
+++ b/tests/src/Kernel/ProjectRenderTest.php
@@ -145,8 +145,8 @@ class ProjectRenderTest extends ContentRenderTestBase {
         'alt' => 'Alternative text',
       ],
       'content' => [
-        '2020',
-        '2025',
+        '10 May 2020',
+        '15 May 2025',
       ],
     ];
     $assert->assertPattern($expected_values, $html);
-- 
GitLab


From e5730d249e4d513ad9b307466225968612849097 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Fri, 1 Apr 2022 20:39:40 +0200
Subject: [PATCH 056/152] OEL-1298: Reorder the modules and config at
 ContentRenderTestBase and ProjectRenderTest.

---
 tests/src/Kernel/ContentRenderTestBase.php | 45 +++++++++++-----------
 tests/src/Kernel/ProjectRenderTest.php     | 38 +-----------------
 2 files changed, 24 insertions(+), 59 deletions(-)

diff --git a/tests/src/Kernel/ContentRenderTestBase.php b/tests/src/Kernel/ContentRenderTestBase.php
index 2784ad01..0561340f 100644
--- a/tests/src/Kernel/ContentRenderTestBase.php
+++ b/tests/src/Kernel/ContentRenderTestBase.php
@@ -34,44 +34,41 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
    */
   public static $modules = [
     'address',
+    'composite_reference',
+    'datetime',
+    'entity_browser',
+    'entity_reference',
+    'entity_reference_revisions',
     'field',
     'field_group',
-    'link',
     'file',
-    'text',
-    'typed_link',
-    'maxlength',
-    'entity_reference',
-    'entity_reference_revisions',
-    'composite_reference',
+    'file_link',
+    'filter',
     'inline_entity_form',
-    'datetime',
-    'datetime_range',
-    'node',
+    'link',
     'media',
-    'views',
-    'entity_browser',
     'media_avportal',
     'media_avportal_mock',
-    'filter',
-    'oe_media',
-    'oe_media_avportal',
+    'node',
     'oe_content',
+    'oe_content_departments_field',
+    'oe_content_documents_field',
     'oe_content_entity',
     'oe_content_entity_contact',
     'oe_content_entity_organisation',
     'oe_content_extra',
     'oe_content_extra_project',
-    'oe_content_departments_field',
-    'oe_content_documents_field',
-    'oe_content_reference_code_field',
     'oe_content_featured_media_field',
     'oe_content_project',
-    'oe_whitelabel_extra_project',
-    'sparql_entity_storage',
-    'rdf_skos',
-    'file_link',
+    'oe_content_reference_code_field',
+    'oe_media',
+    'oe_media_avportal',
     'options',
+    'rdf_skos',
+    'sparql_entity_storage',
+    'text',
+    'typed_link',
+    'views',
   ];
 
   /**
@@ -110,6 +107,9 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
     $this->container->get('module_handler')->loadInclude('oe_content_documents_field', 'install');
     oe_content_documents_field_install(FALSE);
 
+    $this->installEntitySchema('oe_contact');
+    $this->installEntitySchema('oe_organisation');
+
     $this->installConfig([
       'oe_content',
       'oe_content_entity',
@@ -121,7 +121,6 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
       'oe_content_project',
       'oe_content_extra',
       'oe_content_extra_project',
-      'oe_whitelabel_extra_project',
     ]);
 
     Role::load(RoleInterface::ANONYMOUS_ID)
diff --git a/tests/src/Kernel/ProjectRenderTest.php b/tests/src/Kernel/ProjectRenderTest.php
index ef168005..3894ed39 100644
--- a/tests/src/Kernel/ProjectRenderTest.php
+++ b/tests/src/Kernel/ProjectRenderTest.php
@@ -20,30 +20,11 @@ class ProjectRenderTest extends ContentRenderTestBase {
    * {@inheritdoc}
    */
   public static $modules = [
-    'address',
-    'composite_reference',
-    'datetime',
     'datetime_range',
-    'entity_reference_revisions',
-    'field_group',
-    'file',
     'image',
-    'inline_entity_form',
-    'link',
-    'maxlength',
-    'media',
-    'node',
-    'oe_content',
     'oe_content_extra',
     'oe_content_extra_project',
-    'oe_content_documents_field',
-    'oe_content_entity',
-    'oe_content_extra_project',
-    'oe_content_featured_media_field',
-    'oe_content_project',
-    'oe_media',
-    'options',
-    'rdf_skos',
+    'oe_whitelabel_extra_project',
     'system',
     'user',
   ];
@@ -54,29 +35,14 @@ class ProjectRenderTest extends ContentRenderTestBase {
   protected function setUp(): void {
     parent::setUp();
 
-    $this->installConfig('oe_content_entity');
-    $this->installEntitySchema('oe_contact');
-    $this->installEntitySchema('oe_organisation');
-
-    module_load_include('install', 'oe_content_documents_field');
-    oe_content_documents_field_install(FALSE);
-
     module_load_include('install', 'oe_whitelabel_extra_project');
     oe_whitelabel_extra_project_install(FALSE);
 
     $this->installConfig([
-      'media',
-      'node',
-      'oe_content',
-      'oe_content_entity',
-      'oe_content_documents_field',
-      'oe_content_featured_media_field',
-      'oe_content_project',
       'oe_content_extra_project',
+      'oe_whitelabel_extra_project',
     ]);
 
-    module_load_include('install', 'oe_content');
-    oe_content_install(FALSE);
   }
 
   /**
-- 
GitLab


From a4a63be2b82d3ce6d796ae1487c4ddba382056ad Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Sat, 2 Apr 2022 09:11:25 +0200
Subject: [PATCH 057/152] OEL-1298: Eliminate extra line and change name to
 BootstrapKernelTestBase at AbstractKernelTestBase.php.

---
 tests/src/Kernel/AbstractKernelTestBase.php | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/tests/src/Kernel/AbstractKernelTestBase.php b/tests/src/Kernel/AbstractKernelTestBase.php
index fb8fed7c..25b39ba8 100644
--- a/tests/src/Kernel/AbstractKernelTestBase.php
+++ b/tests/src/Kernel/AbstractKernelTestBase.php
@@ -4,13 +4,13 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\oe_whitelabel\Kernel;
 
-use Drupal\Tests\oe_bootstrap_theme\Kernel\AbstractKernelTestBase as OebtAbstractKernelTestBase;
+use Drupal\Tests\oe_bootstrap_theme\Kernel\AbstractKernelTestBase as BootstrapKernelTestBase;
 use Drupal\Tests\oe_bootstrap_theme\Kernel\Traits\RenderTrait;
 
 /**
  * Base class for theme's kernel tests.
  */
-abstract class AbstractKernelTestBase extends OebtAbstractKernelTestBase {
+abstract class AbstractKernelTestBase extends BootstrapKernelTestBase {
 
   use RenderTrait;
 
@@ -34,7 +34,6 @@ abstract class AbstractKernelTestBase extends OebtAbstractKernelTestBase {
     $this->container->get('theme_installer')->install(['oe_whitelabel']);
     $this->config('system.theme')->set('default', 'oe_whitelabel')->save();
     $this->container->set('theme.registry', NULL);
-
   }
 
 }
-- 
GitLab


From 77d02abed8c7cceaff805baee25dc5471083940d Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Sat, 2 Apr 2022 09:14:52 +0200
Subject: [PATCH 058/152] OEL-1298: Eliminate modules and config installation
 at ContentRenderTestBase.php.

---
 tests/src/Kernel/ContentRenderTestBase.php | 44 ++--------------------
 1 file changed, 3 insertions(+), 41 deletions(-)

diff --git a/tests/src/Kernel/ContentRenderTestBase.php b/tests/src/Kernel/ContentRenderTestBase.php
index 0561340f..7fdf5e33 100644
--- a/tests/src/Kernel/ContentRenderTestBase.php
+++ b/tests/src/Kernel/ContentRenderTestBase.php
@@ -15,13 +15,6 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
 
   use SparqlConnectionTrait;
 
-  /**
-   * The node storage.
-   *
-   * @var \Drupal\node\NodeStorageInterface
-   */
-  protected $nodeStorage;
-
   /**
    * The node view builder.
    *
@@ -36,7 +29,6 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
     'address',
     'composite_reference',
     'datetime',
-    'entity_browser',
     'entity_reference',
     'entity_reference_revisions',
     'field',
@@ -47,8 +39,6 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
     'inline_entity_form',
     'link',
     'media',
-    'media_avportal',
-    'media_avportal_mock',
     'node',
     'oe_content',
     'oe_content_departments_field',
@@ -62,13 +52,10 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
     'oe_content_project',
     'oe_content_reference_code_field',
     'oe_media',
-    'oe_media_avportal',
     'options',
     'rdf_skos',
     'sparql_entity_storage',
     'text',
-    'typed_link',
-    'views',
   ];
 
   /**
@@ -81,39 +68,18 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
 
     $this->installEntitySchema('node');
     $this->installSchema('file', 'file_usage');
-    $this->installSchema('node', ['node_access']);
     $this->installEntitySchema('media');
     $this->installEntitySchema('file');
 
-    $this->installConfig([
-      'file',
-      'field',
-      'entity_reference',
-      'entity_reference_revisions',
-      'composite_reference',
-      'node',
-      'media',
-      'filter',
-      'oe_media',
-      'media_avportal',
-      'oe_media_avportal',
-      'typed_link',
-      'address',
-    ]);
-
-    // Importing of configs which related to media av_portal output.
-    $this->container->get('config.installer')->installDefaultConfig('theme', 'oe_whitelabel');
-
     $this->container->get('module_handler')->loadInclude('oe_content_documents_field', 'install');
     oe_content_documents_field_install(FALSE);
 
-    $this->installEntitySchema('oe_contact');
-    $this->installEntitySchema('oe_organisation');
-
     $this->installConfig([
+      'node',
+      'filter',
+      'oe_media',
       'oe_content',
       'oe_content_entity',
-      'oe_content_entity_contact',
       'oe_content_entity_organisation',
       'oe_content_departments_field',
       'oe_content_reference_code_field',
@@ -132,10 +98,6 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
     module_load_include('install', 'oe_content');
     oe_content_install(FALSE);
 
-    $this->installEntitySchema('skos_concept');
-    $this->installEntitySchema('skos_concept_scheme');
-
-    $this->nodeStorage = $this->container->get('entity_type.manager')->getStorage('node');
     $this->nodeViewBuilder = $this->container->get('entity_type.manager')->getViewBuilder('node');
   }
 
-- 
GitLab


From c9424f3427562648214ac7d0edf7f132bcb3dd3c Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Sat, 2 Apr 2022 09:16:38 +0200
Subject: [PATCH 059/152] OEL-1298: Eliminate fields from oe_project node
 creation at ProjectRenderTest.

---
 tests/src/Kernel/ProjectRenderTest.php | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/tests/src/Kernel/ProjectRenderTest.php b/tests/src/Kernel/ProjectRenderTest.php
index 3894ed39..16b1fbb1 100644
--- a/tests/src/Kernel/ProjectRenderTest.php
+++ b/tests/src/Kernel/ProjectRenderTest.php
@@ -68,16 +68,6 @@ class ProjectRenderTest extends ContentRenderTestBase {
       'type' => 'oe_project',
       'title' => 'Project 1',
       'oe_subject' => 'http://data.europa.eu/uxp/1005',
-      'oe_author' => 'http://publications.europa.eu/resource/authority/corporate-body/ACJHR',
-      'oe_content_owner' => 'http://publications.europa.eu/resource/authority/corporate-body/ABEC',
-      'oe_project_locations' => [
-        [
-          'country_code' => 'BE',
-          'locality' => 'Brussels',
-          'postal_code' => 1000,
-        ],
-      ],
-      'body' => 'The body text',
       'oe_teaser' => 'The teaser text',
       'oe_featured_media' => [
         [
-- 
GitLab


From c856df26fb6a6ebd48b7a971f20a7eadbd33cf7d Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Sat, 2 Apr 2022 09:20:22 +0200
Subject: [PATCH 060/152] OEL-1298: Change description of hook preprocess
 badges and change when is called.

---
 .../oe_whitelabel_extra_project.module          | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 2fae1f27..25ef6915 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -51,8 +51,12 @@ function oe_whitelabel_extra_project_preprocess_node__oe_project(&$variables) {
     return;
   }
   _oe_whitelabel_extra_project_preprocess_featured_media($variables);
-  _oe_whitelabel_extra_project_preprocess_inpage_nav($variables);
-  _oe_whitelabel_extra_project_preprocess_badges($variables);
+  if ($variables['view_mode'] === 'full') {
+    _oe_whitelabel_extra_project_preprocess_inpage_nav($variables);
+  }
+  if ($variables['view_mode'] === 'teaser') {
+    _oe_whitelabel_extra_project_preprocess_badges($variables);
+  }
 }
 
 /**
@@ -152,13 +156,12 @@ function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables):
 }
 
 /**
- * Implements hook_preprocess() for project badges.
+ * Implements hook_preprocess() for project teaser badges.
  *
- * This preprocess moves the label from field oe_subject items into badges to
- * prepare its renderization at the patter-card-variant-search.html.twig.
+ * The project teaser is themed with 'card' pattern 'search' variant,
+ * this expects a list of labels keyed by '#title' for the badges.
  *
- * @todo remove once the following issue is resolved.
- * @see https://citnet.tech.ec.europa.eu/CITnet/jira/browse/OEL-1159
+ * @todo Remove once the OEL-1159 issue is resolved.
  */
 function _oe_whitelabel_extra_project_preprocess_badges(&$variables) {
   /** @var \Drupal\node\NodeInterface $node */
-- 
GitLab


From bc262212f787363041105d55e40d948e3cc67ad0 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Mon, 4 Apr 2022 08:56:37 +0200
Subject: [PATCH 061/152] OEL-1298: Eliminate placeholder.png.

---
 tests/fixtures/placeholder.png | Bin 2767 -> 0 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 tests/fixtures/placeholder.png

diff --git a/tests/fixtures/placeholder.png b/tests/fixtures/placeholder.png
deleted file mode 100644
index 54cc5909ebf999d7b0dbc85e2916c4a13e967e01..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 2767
zcmcgui8~ZpAD%vybW5d>Y>h<1j4nx8rUo$)jcaLUEY--;rLk*F!@Y6IzKraHn~E4@
zYsS)uX>5}{N-|S+vym}mndYPa;rq_>oaa2xIq!4Mdw%cl{hbqk!_Mm9{uBEF0Kh?*
zwS@x!AaN1^_|MJV65BIAH;c@-2gMt<j+XD=zt76bDkvx@FE6Ll=`}SqB_$<fGMP%H
z#^Hj>wqa5M)`(yLK>FQI-}OXWS`h%)kAzuVaeVNZH^IOtb}9qD&e%++Kl4Xe4F$@m
zKCj0r!8!wQnK5tY;UUCJR^3`jD$ms|#k`<y{DJVe`mX){2_mz%Pc2~jON$qbQzyop
zGPV!;|Fos3=bN*<9~g)ub4$pZujBOKqA@R~Fo!D8OJ0|L28N|h-VqwwMqRpwZ~Q(R
zw^I2XJ1q%;w4_XpX(lF)jO#_yeR!5jvm7C6O7GDGSF%Vo;DA@_#`GU_I@>?58D7QJ
zY8r-{BEeRYR@&l`!3F;0Q=wrc?d<ZAdY0N>SLzdP@l-39T~v7>kTWLuP}<kSh+`Nx
zS;zy&mhcvgGS6CeaEC&#fpyo^23%18qb=XsadCmPH8R(nkT^Q7M_h>#^D6j|(km!p
zX_2^O^PI??86GkWX0m?z9#Q90hhs<l*kpcOF)B$;zJlyKbi74d<6rXK{y<{y75iw=
ztnX@Y>gr;Rb3EmywDk6-BjX10mL~3UaBI{ej9ITLncLheNfhNRUT5kGdwyy;yVf)J
zN&{VH>b-OPI(RR*XwY(`DQ~`it#S$$xX;xe3_@at`|>hHjwk*hv?N{xUCIj74Q7<t
zttvw`=$ZE^Zzw)*dQtx<NxF#$z3)kPuqcD+akX;I%|6BZiI<D~z}vBq&_r0W1{j23
zXOM*4I%P;pKfHdf%nTgWknJL`yA2pt+Ea;7TRS=&<QqU()8qyD4zTJVT8fcKdI|4W
z_`~#w3ts84&L_p8kUogQ-l;ybVN%^m3U&!ix8(TWg2uuWD&e877kg04*8>dEH7q3l
z#QPqm8SZt%HpA<~`(-l719pd#+?kyPdtj8Zu%!!a-KEU3-)F<o5+S5*OcQAYHyHT*
zG25*n8nQoQpsK2N^NRg3mGccdI_m*7N3;UCWw7?LK3XKG=y?ibm3px~<W6baF9u(A
zIPmj9f+avs6>a<=%CFgQvQYL<F2Ag)>%Nuq#4qIom4BB;vI(T$v^ERqO&En3{07|r
zt`S&niU@Cj{At-S=Mz{Hkxy{|zql-qxOKn%t!D`al60$7Zqhw)58A!iRVKgf>Q1tn
zlq3(!5_HbZbkn$r?w=M{*u((?$WY(CQym*yBVY3u<XL@BPp|Y41Pu}Sb0kV6KHEOk
z@PzlM-v#M}NW5JHLD@GNUTKWdZIZ0`jgab9gVxzmO7LZdc)glpOCH3tDqW5%(mIOG
zF!#J&^itT_S)d^qkRcgvu|uE>jt|9#hDxpZnick`Nnu;Gfzdjj(<@vUu~DC2a@`*9
z<mcaVZ5nYE8%e>`$Z+(F@nn*Y9LLs{L$isPTzy)5@C?$G#C)NmrZ`x>*Gne;mcN3j
zhtNsXRaJQx8hM6el&s;|Qpwb4dbykPDkj7^+S<6*$|pB1^)A#-efp;q)<xYDjmSRj
zdA#pQXL`fh^1kNB54{mz)FvkMQU2=+b5bwmw@Hk-IU9<Vo&KXwD)27fvIvmokbS4w
z{Cn-jc60U>6D4!quXkJ-40ITCesB{y#AJ7VQW@|?EW@d*nQ5C!C)d9$yo#9~zwDhJ
zylcJYV{ht7sWH<>TR%{19*K9dc~?EmQj>ra^YjGEyEt4<8X+k3`<XH4?W@h^&W5u|
z{PA2R6Gjht5R#%Xebz{&w>E4c8$~i+cM!deAsM#{e0ng^dqkBn+<;>StU6`wS^KIF
zbt3N6{5d1(R?2G!)@_w9q?O+lGY(yB%&~u1boJ=6&(u5T$?3_yb0XhQcsH@66ihPx
zcE~Fhg)?^z8deR}__l=0QwlRxFY+>tr{ZNguo)DUT795m_VwxvTGeqci7-F!b~Pn%
zZOvy{n!nr=XY3QDkn5%%<(+v##AzVy-FYFAk%nl1jLlOSZknCnK5#u5GWxaBjZ#)w
ze!En5Oj~y}L#QdqWt{CpSYF+1z6RBZ$0Nq^?3NKx7|82XTaUk|mz$zF*R=%$t#w*2
z#Np~*r9>)NQisdcr|+QxS6A;Z)SeA@l5J-7M=RV2;hOO~vtoH&m(-CvRY_y|_2-9&
znjoHd8-ZG6;2O-|kn=N*H_Q~U**}Vn%SJWne6><}nvpy~GyKMc_wAeuEOY+37F6<_
zReC&zy!<d_Y;^JqnzE4!sXD*C)b3UUReA@4?;+RAwuQ^{<pjmi;HISJF41K4#M;ZX
zI`b)=A>y7nMgq?ADSe{R9v@0YJEu@P*Yh{cx`D0f{wia$ht=PhoHXqQR>|*P0xf<#
z^k5Vgc?wlZ-Nc`NMasv8vk{s_1G+`BNV5!2ap|s5K~0Hb<Gq{Ar%OY_fARHudsGhN
z;D#eBFVZ=o=DHoDcB|2%Pm~EQwFgJWZ1WaVZ7?zynNB;tz&28qf$IX7E935_W4y&0
z&7R&#`^<d#Za=HO!e^3gKfoLh)3IMrg&4&dyGIv?-TPf#j~(G!ffQr&zuSe&&gCW|
zRR2gEEwn$ayc>~o6}e`xTv2$f30>%fE8`dT^ZX@6b|i6Y1tjxBFm5sMalvRwXsafQ
zwOjvNN!L5_ygV(g6;~^K4Od^(Y%l%ZS|$1F!OhL)Pgp|W@vW)(5B~<u|EdN?qEJsm
zv2EMk>FQ%E(qhiO3P^<B#=<b&ZG*Fq@p?lrJ}A#}Vs2rPVq+Ci_0_naqBIXyig<&D
z-+rTh``>;Lw!jUwQP$Rk<c_Eo4`?i-8d)-UMnMyX%ZY4U5v|}eT2$WHAPMTZ39}N%
z!^8pN7?PO^OGC9TCInI>YT8<22aRrMEr2ZqK$(mdTk3|6Z~q3vKBC`_Fgl}$UodI5
zJ{q)+2nu<#WtWy#>e9Wb10)KBaZFzhIw<5+-XTI7v-#s3k%L_hUY;HK2;)q!XL>8@
z+sIk06Sf)Ew3q`P2Q(1S&vn8${<9IPi2j%0vYRt*lz6}nT-|C@2u}TH)K9o<l3OZ;
zh}6cmZjqJzhQ6bpq@`MYL_m@2aknd?gziukpBo<Mx4IK6U?)}#s0$1|RrA<xFp-md
z>X``mQWe;peN+mY1Jd@bmX59{s>+I^pJgxD1jN*XFYFcGUW7TQnr9>iOJR#+o}sOS
zu%d4!>qeVq$q^e4DL|Nb!3*l_K{DH0r<0f!XJdVdagFaKKnxX8t!a7G%sSFDNW8k|
zL?s^5^ARYs%nA<C-P@|I8uK;$xe$5)04Sbhd9*L}{{5rgaYt>KrJY3;^wy*Q0-(`K
AlK=n!

-- 
GitLab


From 8b920d85831a9a8c8eb9b46fee16150cc69544ea Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Mon, 4 Apr 2022 09:17:53 +0200
Subject: [PATCH 062/152] OEL-1298: Move extra-content module and config to
 ProjectRenderTest.

---
 tests/src/Kernel/ContentRenderTestBase.php |  8 --------
 tests/src/Kernel/ProjectRenderTest.php     | 10 +++++++---
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/tests/src/Kernel/ContentRenderTestBase.php b/tests/src/Kernel/ContentRenderTestBase.php
index 7fdf5e33..8d83aa84 100644
--- a/tests/src/Kernel/ContentRenderTestBase.php
+++ b/tests/src/Kernel/ContentRenderTestBase.php
@@ -46,10 +46,6 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
     'oe_content_entity',
     'oe_content_entity_contact',
     'oe_content_entity_organisation',
-    'oe_content_extra',
-    'oe_content_extra_project',
-    'oe_content_featured_media_field',
-    'oe_content_project',
     'oe_content_reference_code_field',
     'oe_media',
     'options',
@@ -83,10 +79,6 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
       'oe_content_entity_organisation',
       'oe_content_departments_field',
       'oe_content_reference_code_field',
-      'oe_content_featured_media_field',
-      'oe_content_project',
-      'oe_content_extra',
-      'oe_content_extra_project',
     ]);
 
     Role::load(RoleInterface::ANONYMOUS_ID)
diff --git a/tests/src/Kernel/ProjectRenderTest.php b/tests/src/Kernel/ProjectRenderTest.php
index 16b1fbb1..b9e507cc 100644
--- a/tests/src/Kernel/ProjectRenderTest.php
+++ b/tests/src/Kernel/ProjectRenderTest.php
@@ -22,6 +22,8 @@ class ProjectRenderTest extends ContentRenderTestBase {
   public static $modules = [
     'datetime_range',
     'image',
+    'oe_content_featured_media_field',
+    'oe_content_project',
     'oe_content_extra',
     'oe_content_extra_project',
     'oe_whitelabel_extra_project',
@@ -35,14 +37,16 @@ class ProjectRenderTest extends ContentRenderTestBase {
   protected function setUp(): void {
     parent::setUp();
 
-    module_load_include('install', 'oe_whitelabel_extra_project');
-    oe_whitelabel_extra_project_install(FALSE);
-
     $this->installConfig([
+      'oe_content_featured_media_field',
+      'oe_content_project',
+      'oe_content_extra',
       'oe_content_extra_project',
       'oe_whitelabel_extra_project',
     ]);
 
+    module_load_include('install', 'oe_whitelabel_extra_project');
+    oe_whitelabel_extra_project_install(FALSE);
   }
 
   /**
-- 
GitLab


From 3fced36ec7ea41c4b91669c18fedcf7eb68a5f0e Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Mon, 4 Apr 2022 09:21:49 +0200
Subject: [PATCH 063/152] OEL-1298: Fix method getPatternVariant at
 CardAssert.php.

---
 tests/src/PatternAssertions/CardAssert.php | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/tests/src/PatternAssertions/CardAssert.php b/tests/src/PatternAssertions/CardAssert.php
index 2fd4c0b8..c34755fc 100644
--- a/tests/src/PatternAssertions/CardAssert.php
+++ b/tests/src/PatternAssertions/CardAssert.php
@@ -112,12 +112,10 @@ class CardAssert extends BasePatternAssert {
 
   /**
    * {@inheritdoc}
-   *
-   * @SuppressWarnings(PHPMD.CyclomaticComplexity)
    */
   protected function getPatternVariant(string $html): string {
     $crawler = new Crawler($html);
-    if ($crawler->filter('div.mw-listing-img')) {
+    if ($crawler->filter('div.listing-item')->count() > 0) {
       return 'search';
     }
     return 'default';
-- 
GitLab


From 10e74e37621c52f6b2ed9135edbbd6ddc54fb67d Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Mon, 4 Apr 2022 09:28:35 +0200
Subject: [PATCH 064/152] OEL-1298: Fix CardAssert's assertBaseElements method
 and add comment to assertContent method.

---
 tests/src/PatternAssertions/CardAssert.php | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tests/src/PatternAssertions/CardAssert.php b/tests/src/PatternAssertions/CardAssert.php
index c34755fc..b17de326 100644
--- a/tests/src/PatternAssertions/CardAssert.php
+++ b/tests/src/PatternAssertions/CardAssert.php
@@ -77,6 +77,8 @@ class CardAssert extends BasePatternAssert {
    */
   protected function assertContent(array $expected_items, Crawler $crawler): void {
     foreach ($expected_items as $expected_item) {
+      // There's no wrapping element in content that can be targeted,
+      // so we are checking that the expected items are present.
       self::assertStringContainsString($expected_item, $crawler->html());
     }
   }
@@ -86,8 +88,7 @@ class CardAssert extends BasePatternAssert {
    */
   protected function assertBaseElements(string $html, string $variant): void {
     $crawler = new Crawler($html);
-    $base_selector = 'article ' . $this->getBaseItemClass($variant);
-    $card = $crawler->filter($base_selector);
+    $card = $crawler->filter($this->getBaseItemClass($variant));
     self::assertCount(1, $card);
   }
 
-- 
GitLab


From b786a1d442bf8fd5c5f62cf47376c913fd4145e8 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Mon, 4 Apr 2022 09:34:58 +0200
Subject: [PATCH 065/152] OEL-1298: Fix description of proprocess badges and
 add void as return.

---
 .../oe_whitelabel_extra_project.module                     | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 25ef6915..54d72584 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -156,14 +156,17 @@ function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables):
 }
 
 /**
- * Implements hook_preprocess() for project teaser badges.
+ * Helper function to preprocess the project teaser badges.
  *
  * The project teaser is themed with 'card' pattern 'search' variant,
  * this expects a list of labels keyed by '#title' for the badges.
  *
  * @todo Remove once the OEL-1159 issue is resolved.
+ *
+ * @param array $variables
+ *   Render array variables.
  */
-function _oe_whitelabel_extra_project_preprocess_badges(&$variables) {
+function _oe_whitelabel_extra_project_preprocess_badges(array &$variables): void {
   /** @var \Drupal\node\NodeInterface $node */
   $node = $variables['node'];
 
-- 
GitLab


From 6d4986a20b6408d06bb8de2386e47ba0f0f53470 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Mon, 4 Apr 2022 10:25:52 +0200
Subject: [PATCH 066/152] OEL-1298: Add reference to left-right for search card
 variant test at CardAssert.php.

---
 tests/src/PatternAssertions/CardAssert.php | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/tests/src/PatternAssertions/CardAssert.php b/tests/src/PatternAssertions/CardAssert.php
index b17de326..00afdb6c 100644
--- a/tests/src/PatternAssertions/CardAssert.php
+++ b/tests/src/PatternAssertions/CardAssert.php
@@ -40,6 +40,7 @@ class CardAssert extends BasePatternAssert {
       ],
       'content' => [
         [$this, 'assertContent'],
+        $variant,
       ],
     ];
   }
@@ -56,7 +57,7 @@ class CardAssert extends BasePatternAssert {
    */
   protected function assertCardImage($expected_image, string $variant, Crawler $crawler): void {
     if ($variant == 'search') {
-      $image_div = $crawler->filter('.mw-listing-img img.card-img-top');
+      $image_div = $crawler->filter('.row .col-md-3.mw-listing-img img.card-img-top');
       self::assertEquals($expected_image['alt'], $image_div->attr('alt'));
       self::assertStringContainsString($expected_image['src'], $image_div->attr('src'));
     }
@@ -72,14 +73,21 @@ class CardAssert extends BasePatternAssert {
    *
    * @param array $expected_items
    *   The expected item values.
+   * @param string $variant
+   *   The variant of the pattern being checked.
    * @param \Symfony\Component\DomCrawler\Crawler $crawler
    *   The DomCrawler where to check the element.
    */
-  protected function assertContent(array $expected_items, Crawler $crawler): void {
+  protected function assertContent(array $expected_items, string $variant, Crawler $crawler): void {
+    // There's no wrapping element in content that can be targeted,
+    // so we are checking that the expected items are present.
     foreach ($expected_items as $expected_item) {
-      // There's no wrapping element in content that can be targeted,
-      // so we are checking that the expected items are present.
-      self::assertStringContainsString($expected_item, $crawler->html());
+      if ($variant == 'search') {
+        self::assertStringContainsString($expected_item, $crawler->filter('.row .col-md-9')->html());
+      }
+      else {
+        self::assertStringContainsString($expected_item, $crawler->html());
+      }
     }
   }
 
-- 
GitLab


From ea12fd578e02615b96c1211f40e741078b6b74f1 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Mon, 4 Apr 2022 11:12:11 +0200
Subject: [PATCH 067/152] OEL-1298: Eliminate image management for teaser view
 mode of project.

---
 .../oe_whitelabel_extra_project.module                      | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 54d72584..b76fd23f 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -107,12 +107,6 @@ function _oe_whitelabel_extra_project_preprocess_featured_media(&$variables) {
 
   $thumbnail = $media->get('thumbnail')->first();
   $variables['image'] = ImageValueObject::fromImageItem($thumbnail);
-  if ($variables['view_mode'] == 'teaser') {
-    $variables['image'] = [
-      'path' => $variables['image']->getSource(),
-      'alt' => $variables['image']->getAlt(),
-    ];
-  }
 
   $cacheability->applyTo($variables);
 }
-- 
GitLab


From d8fb605d0f1b1b06d207e60377a1c795b523c94d Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Mon, 4 Apr 2022 12:32:46 +0200
Subject: [PATCH 068/152] OEL-1298: Put back the #markup management for image
 and add a todo for OEL-1159.

---
 .../oe_whitelabel_extra_project.module                     | 7 +++++++
 tests/src/Kernel/ProjectRenderTest.php                     | 3 ++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index b76fd23f..98ad2985 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -108,6 +108,13 @@ function _oe_whitelabel_extra_project_preprocess_featured_media(&$variables) {
   $thumbnail = $media->get('thumbnail')->first();
   $variables['image'] = ImageValueObject::fromImageItem($thumbnail);
 
+  // @todo Remove once the OEL-1159 issue is resolved.
+  if ($variables['view_mode'] == 'teaser') {
+    $variables['image'] = [
+      '#markup' => $variables['image']->getSource(),
+    ];
+  }
+
   $cacheability->applyTo($variables);
 }
 
diff --git a/tests/src/Kernel/ProjectRenderTest.php b/tests/src/Kernel/ProjectRenderTest.php
index b9e507cc..ca3ab1cc 100644
--- a/tests/src/Kernel/ProjectRenderTest.php
+++ b/tests/src/Kernel/ProjectRenderTest.php
@@ -95,6 +95,7 @@ class ProjectRenderTest extends ContentRenderTestBase {
 
     $assert = new CardAssert();
 
+    // @todo Once the OEL-1159 issue is resolved, then add text to alt.
     $expected_values = [
       'title' => 'Project 1',
       'url' => '/node/1',
@@ -102,7 +103,7 @@ class ProjectRenderTest extends ContentRenderTestBase {
       'badges' => ['EU financing'],
       'image' => [
         'src' => 'example_1.jpeg',
-        'alt' => 'Alternative text',
+        'alt' => '',
       ],
       'content' => [
         '10 May 2020',
-- 
GitLab


From 0e3213d12a1a728f78ffa7ed66e8a394b88fed26 Mon Sep 17 00:00:00 2001
From: Abel Santos <abel.santos.corral@gmail.com>
Date: Mon, 4 Apr 2022 14:16:07 +0200
Subject: [PATCH 069/152] OEL-1298: Move elements into install.

---
 .../core.entity_view_display.node.oe_project.full.yml           | 0
 .../core.entity_view_display.node.oe_project.teaser.yml         | 0
 .../oe_whitelabel_extra_project.info.yml                        | 2 ++
 .../oe_whitelabel_extra_project.install                         | 2 --
 4 files changed, 2 insertions(+), 2 deletions(-)
 rename modules/oe_whitelabel_extra_project/config/{overrides => install}/core.entity_view_display.node.oe_project.full.yml (100%)
 rename modules/oe_whitelabel_extra_project/config/{overrides => install}/core.entity_view_display.node.oe_project.teaser.yml (100%)

diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
similarity index 100%
rename from modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.full.yml
rename to modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
diff --git a/modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.teaser.yml
similarity index 100%
rename from modules/oe_whitelabel_extra_project/config/overrides/core.entity_view_display.node.oe_project.teaser.yml
rename to modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.teaser.yml
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
index 2a216223..28906097 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
@@ -10,3 +10,5 @@ dependencies:
 config_devel:
   install:
     - core.date_format.oe_whitelabel_project_date
+    - core.entity_view_display.node.oe_project.full
+    - core.entity_view_display.node.oe_project.teaser
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
index b9d87a18..7b2e1b67 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
@@ -23,8 +23,6 @@ function oe_whitelabel_extra_project_install($is_syncing): void {
   $configs = [
     'core.entity_form_display.node.oe_project.default',
     'core.entity_form_display.oe_organisation.oe_cx_project_stakeholder.default',
-    'core.entity_view_display.node.oe_project.full',
-    'core.entity_view_display.node.oe_project.teaser',
     'core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default',
   ];
 
-- 
GitLab


From db53be7b22df37e810243543de3f9b195afc850f Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 6 Apr 2022 21:11:08 +0200
Subject: [PATCH 070/152] OEL-1394: Align with new version of card pattern.

---
 .../oe_whitelabel_extra_project.module        | 37 -------------------
 .../node--oe-project--teaser.html.twig        | 19 +++++++---
 2 files changed, 14 insertions(+), 42 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 98ad2985..b676f242 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -54,9 +54,6 @@ function oe_whitelabel_extra_project_preprocess_node__oe_project(&$variables) {
   if ($variables['view_mode'] === 'full') {
     _oe_whitelabel_extra_project_preprocess_inpage_nav($variables);
   }
-  if ($variables['view_mode'] === 'teaser') {
-    _oe_whitelabel_extra_project_preprocess_badges($variables);
-  }
 }
 
 /**
@@ -108,13 +105,6 @@ function _oe_whitelabel_extra_project_preprocess_featured_media(&$variables) {
   $thumbnail = $media->get('thumbnail')->first();
   $variables['image'] = ImageValueObject::fromImageItem($thumbnail);
 
-  // @todo Remove once the OEL-1159 issue is resolved.
-  if ($variables['view_mode'] == 'teaser') {
-    $variables['image'] = [
-      '#markup' => $variables['image']->getSource(),
-    ];
-  }
-
   $cacheability->applyTo($variables);
 }
 
@@ -155,30 +145,3 @@ function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables):
   }
 
 }
-
-/**
- * Helper function to preprocess the project teaser badges.
- *
- * The project teaser is themed with 'card' pattern 'search' variant,
- * this expects a list of labels keyed by '#title' for the badges.
- *
- * @todo Remove once the OEL-1159 issue is resolved.
- *
- * @param array $variables
- *   Render array variables.
- */
-function _oe_whitelabel_extra_project_preprocess_badges(array &$variables): void {
-  /** @var \Drupal\node\NodeInterface $node */
-  $node = $variables['node'];
-
-  if ($node->get('oe_subject')->isEmpty()) {
-    return;
-  }
-
-  $variables['badges'] = [];
-  foreach ($node->get('oe_subject') as $item) {
-    $variables['badges'][] = [
-      '#title' => $item->entity->label(),
-    ];
-  }
-}
diff --git a/templates/content/node--oe-project--teaser.html.twig b/templates/content/node--oe-project--teaser.html.twig
index 8c8b7898..0c2f5939 100644
--- a/templates/content/node--oe-project--teaser.html.twig
+++ b/templates/content/node--oe-project--teaser.html.twig
@@ -7,18 +7,27 @@
 {% set _title %}
   <a class="standalone" href="{{ url }}">{{ label }}</a>
 {% endset %}
-{% set _content %}
-  <span class="text-muted text-nowrap me-4-5">{{ content.oe_project_dates }}</span>
-{% endset %}
+{% set _badges = [] %}
+{% for _item in content.oe_subject|field_value %}
+  {% set _badges = _badges|merge([{
+    label: _item,
+  }]) %}
+{% endfor %}
 {% block content %}
 <article{{attributes}}>
   {{ pattern('card', {
     variant: 'search',
     title: _title,
     text: content.oe_teaser,
-    image: image,
+    image: {
+      path: image.src,
+      alt: image.alt,
+    },
+    meta: [
+      content.oe_project_dates|field_value,
+    ],
     content: _content,
-    badges: badges,
+    badges: _badges,
   }) }}
 </article>
 {% endblock %}
-- 
GitLab


From f036280703c282f57ef6eb6fa8f06a485945c755 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 6 Apr 2022 21:16:32 +0200
Subject: [PATCH 071/152] OEL-1394: Add inline var doc for field item.

---
 .../oe_whitelabel_extra_project.module                           | 1 +
 1 file changed, 1 insertion(+)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index b676f242..d0cf9fe4 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -102,6 +102,7 @@ function _oe_whitelabel_extra_project_preprocess_featured_media(&$variables) {
     return;
   }
 
+  /** @var \Drupal\image\Plugin\Field\FieldType\ImageItem $thumbnail */
   $thumbnail = $media->get('thumbnail')->first();
   $variables['image'] = ImageValueObject::fromImageItem($thumbnail);
 
-- 
GitLab


From e3c058289100f67a1e135e2e780bfa783af9da64 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 6 Apr 2022 21:17:50 +0200
Subject: [PATCH 072/152] OEL-1394: Remove field wrapper div on oe_teaser in
 teaser view mode.

---
 templates/content/node--oe-project--teaser.html.twig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/content/node--oe-project--teaser.html.twig b/templates/content/node--oe-project--teaser.html.twig
index 0c2f5939..f01553e0 100644
--- a/templates/content/node--oe-project--teaser.html.twig
+++ b/templates/content/node--oe-project--teaser.html.twig
@@ -18,7 +18,7 @@
   {{ pattern('card', {
     variant: 'search',
     title: _title,
-    text: content.oe_teaser,
+    text: content.oe_teaser|field_value,
     image: {
       path: image.src,
       alt: image.alt,
-- 
GitLab


From c383d64f9ffd8351391284cb7e39a4989f7d41be Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Thu, 7 Apr 2022 12:33:16 +0200
Subject: [PATCH 073/152] OEL-1394: Enable twig_field_value in kernel test,
 after template changes.

---
 tests/src/Kernel/ProjectRenderTest.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/src/Kernel/ProjectRenderTest.php b/tests/src/Kernel/ProjectRenderTest.php
index ca3ab1cc..cae9cde3 100644
--- a/tests/src/Kernel/ProjectRenderTest.php
+++ b/tests/src/Kernel/ProjectRenderTest.php
@@ -28,6 +28,7 @@ class ProjectRenderTest extends ContentRenderTestBase {
     'oe_content_extra_project',
     'oe_whitelabel_extra_project',
     'system',
+    'twig_field_value',
     'user',
   ];
 
-- 
GitLab


From 377705f34122a7a3c98c3f421b5f234706c5bd35 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Thu, 7 Apr 2022 12:42:34 +0200
Subject: [PATCH 074/152] OEL-1394: Image 'alt' value is no longer empty in
 test.

---
 tests/src/Kernel/ProjectRenderTest.php | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tests/src/Kernel/ProjectRenderTest.php b/tests/src/Kernel/ProjectRenderTest.php
index cae9cde3..17d06e3b 100644
--- a/tests/src/Kernel/ProjectRenderTest.php
+++ b/tests/src/Kernel/ProjectRenderTest.php
@@ -96,7 +96,6 @@ class ProjectRenderTest extends ContentRenderTestBase {
 
     $assert = new CardAssert();
 
-    // @todo Once the OEL-1159 issue is resolved, then add text to alt.
     $expected_values = [
       'title' => 'Project 1',
       'url' => '/node/1',
@@ -104,7 +103,7 @@ class ProjectRenderTest extends ContentRenderTestBase {
       'badges' => ['EU financing'],
       'image' => [
         'src' => 'example_1.jpeg',
-        'alt' => '',
+        'alt' => 'Alternative text',
       ],
       'content' => [
         '10 May 2020',
-- 
GitLab


From 8032ce20d21934ef13d10987291bb060bb985906 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Wed, 6 Apr 2022 18:43:47 +0200
Subject: [PATCH 075/152] OEL-1241: Export full viewmode.

---
 .../install/core.entity_view_display.node.oe_project.full.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
index b57e9f20..354d14d5 100644
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
@@ -126,7 +126,7 @@ content:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 7
+    weight: 6
     region: content
   oe_cx_objective:
     type: text_default
@@ -190,7 +190,7 @@ content:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 6
+    weight: 7
     region: content
   oe_project_website:
     type: link
-- 
GitLab


From 60df815eb8b3fbfd4ebbfa119b48941e9dd37160 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 8 Apr 2022 16:00:11 +0200
Subject: [PATCH 076/152] OEL-1421: Update inpage navigation for project
 details.

---
 .../oe_whitelabel_extra_project.module             | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index d0cf9fe4..b2735be2 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -118,14 +118,24 @@ function _oe_whitelabel_extra_project_preprocess_featured_media(&$variables) {
 function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables): void {
   /** @var \Drupal\node\NodeInterface $node */
   $node = $variables['node'];
-
   $variables['inpage_navigation_links'] = [];
+  $variables['project_details_group'] = FALSE;
+
+  // Get field groups.
+  foreach ($variables['elements']['#fieldgroups'] as $group) {
+    foreach ($group->children as $field) {
+      if (isset($node->{$field}) && !empty($node->{$field}->getValue())) {
+        $variables['project_details_group'] = TRUE;
+      }
+    }
+  }
+
   $fields = [
     'oe_summary',
     'oe_cx_objective',
     'oe_cx_impacts',
-    'oe_project_participants',
     'oe_cx_lead_contributors',
+    'oe_project_participants',
     'oe_cx_achievements_and_milestone',
   ];
   foreach ($variables['content'] as &$item) {
-- 
GitLab


From e61acef10bb84254019f47295d187a358b6eb170 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Fri, 8 Apr 2022 16:00:30 +0200
Subject: [PATCH 077/152] OEL-1421: Update twig templates.

---
 .../content/node--oe-project--full.html.twig  |  9 ++---
 .../node--oe-project--teaser.html.twig        | 37 +++++++++++--------
 2 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 7cb861db..01a02097 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -27,13 +27,10 @@
     {{ field }}
   {% endif %}
 {% endmacro %}
-{% set _project_details %}
-  {{ content.group_project_details }}
-{% endset %}
-{% if _project_details|trim is not empty %}
+{% if project_details_group|trim is not empty %}
   {% set _project_details %}
     <div id="project-details">
-      {{ _project_details }}
+      {{ content.group_project_details }}
     </div>
   {% endset %}
   {% set inpage_navigation_links = [{
@@ -47,8 +44,8 @@
     {{ _self.field_with_header(content.oe_summary) }}
     {{ _self.field_with_header(content.oe_cx_objective) }}
     {{ _self.field_with_header(content.oe_cx_impacts) }}
-    {{ _self.field_with_header(content.oe_project_participants) }}
     {{ _self.field_with_header(content.oe_cx_lead_contributors) }}
+    {{ _self.field_with_header(content.oe_project_participants) }}
     {{ _self.field_with_header(content.oe_cx_achievements_and_milestone) }}
   {% endblock %}
 {% endset %}
diff --git a/templates/content/node--oe-project--teaser.html.twig b/templates/content/node--oe-project--teaser.html.twig
index f01553e0..5ad60641 100644
--- a/templates/content/node--oe-project--teaser.html.twig
+++ b/templates/content/node--oe-project--teaser.html.twig
@@ -13,21 +13,26 @@
     label: _item,
   }]) %}
 {% endfor %}
+{% if content.oe_project_dates|field_value is not empty %}
+  {% set _content %}
+    <span class="text-muted text-nowrap me-4-5">{{ content.oe_project_dates }}</span>
+  {% endset %}
+{% endif %}
+{% if image is not empty %}
+  {% set _image = {
+    path: image.src,
+    alt: image.alt,
+  } %}
+{% endif %}
 {% block content %}
-<article{{attributes}}>
-  {{ pattern('card', {
-    variant: 'search',
-    title: _title,
-    text: content.oe_teaser|field_value,
-    image: {
-      path: image.src,
-      alt: image.alt,
-    },
-    meta: [
-      content.oe_project_dates|field_value,
-    ],
-    content: _content,
-    badges: _badges,
-  }) }}
-</article>
+  <article{{attributes}}>
+    {{ pattern('card', {
+      variant: 'search',
+      title: _title,
+      text: content.oe_teaser|field_value,
+      image: _image,
+      content: _content,
+      badges: _badges,
+    }) }}
+  </article>
 {% endblock %}
-- 
GitLab


From 8485f25985e19362eafd5e00dfac11fd37d835a9 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Mon, 11 Apr 2022 14:56:16 +0200
Subject: [PATCH 078/152] OEL-1421: Update teaser template.

---
 templates/content/node--oe-project--teaser.html.twig | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/templates/content/node--oe-project--teaser.html.twig b/templates/content/node--oe-project--teaser.html.twig
index 5ad60641..955fe398 100644
--- a/templates/content/node--oe-project--teaser.html.twig
+++ b/templates/content/node--oe-project--teaser.html.twig
@@ -18,19 +18,16 @@
     <span class="text-muted text-nowrap me-4-5">{{ content.oe_project_dates }}</span>
   {% endset %}
 {% endif %}
-{% if image is not empty %}
-  {% set _image = {
-    path: image.src,
-    alt: image.alt,
-  } %}
-{% endif %}
 {% block content %}
   <article{{attributes}}>
     {{ pattern('card', {
       variant: 'search',
       title: _title,
       text: content.oe_teaser|field_value,
-      image: _image,
+      image: (image is not empty) ? image|merge({
+        path: image.src,
+        alt: image.alt,
+      }) : {},
       content: _content,
       badges: _badges,
     }) }}
-- 
GitLab


From 4770ea4808ab694db06fb20b6e71b597cb511aea Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Mon, 11 Apr 2022 15:43:03 +0200
Subject: [PATCH 079/152] OEL-1421: Update teaser template to remove alt from
 image.

---
 templates/content/node--oe-project--teaser.html.twig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/templates/content/node--oe-project--teaser.html.twig b/templates/content/node--oe-project--teaser.html.twig
index 955fe398..94051145 100644
--- a/templates/content/node--oe-project--teaser.html.twig
+++ b/templates/content/node--oe-project--teaser.html.twig
@@ -26,7 +26,6 @@
       text: content.oe_teaser|field_value,
       image: (image is not empty) ? image|merge({
         path: image.src,
-        alt: image.alt,
       }) : {},
       content: _content,
       badges: _badges,
-- 
GitLab


From db9205b9505874931b89dc0c0299ef8455336138 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Tue, 12 Apr 2022 17:24:36 +0200
Subject: [PATCH 080/152] OEL-1246: Remove logic for group detail title.

---
 .../oe_whitelabel_extra_project.module                 | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index b2735be2..2277e189 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -119,16 +119,6 @@ function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables):
   /** @var \Drupal\node\NodeInterface $node */
   $node = $variables['node'];
   $variables['inpage_navigation_links'] = [];
-  $variables['project_details_group'] = FALSE;
-
-  // Get field groups.
-  foreach ($variables['elements']['#fieldgroups'] as $group) {
-    foreach ($group->children as $field) {
-      if (isset($node->{$field}) && !empty($node->{$field}->getValue())) {
-        $variables['project_details_group'] = TRUE;
-      }
-    }
-  }
 
   $fields = [
     'oe_summary',
-- 
GitLab


From 2baf4e9f876e8d28b7a761ad76dc8d3d2438836d Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Tue, 12 Apr 2022 17:25:06 +0200
Subject: [PATCH 081/152] OEL-1246: Update templates to remove logic for detail
 group.

---
 templates/content/node--oe-project--full.html.twig   | 11 ++++++++---
 templates/content/node--oe-project--teaser.html.twig |  9 +++++----
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 01a02097..12ee4bd8 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -27,15 +27,20 @@
     {{ field }}
   {% endif %}
 {% endmacro %}
-{% if project_details_group|trim is not empty %}
+{% set _project_details %}
+  {{ content.group_project_details }}
+{% endset %}
+{% if _project_details|striptags|trim is not empty %}
+  {% set _project_details_title = 'Project details'|t %}
   {% set _project_details %}
+    <h3 class="fw-bold mb-4">{{ _project_details_title }}</h3>
     <div id="project-details">
-      {{ content.group_project_details }}
+      {{ _project_details }}
     </div>
   {% endset %}
   {% set inpage_navigation_links = [{
     'path': '#project-details',
-    'label': content.group_project_details['#title'],
+    'label': _project_details_title,
   }]|merge(inpage_navigation_links) %}
 {% endif %}
 {% set inpage_navigation_fields %}
diff --git a/templates/content/node--oe-project--teaser.html.twig b/templates/content/node--oe-project--teaser.html.twig
index 94051145..dc13a497 100644
--- a/templates/content/node--oe-project--teaser.html.twig
+++ b/templates/content/node--oe-project--teaser.html.twig
@@ -8,15 +8,16 @@
   <a class="standalone" href="{{ url }}">{{ label }}</a>
 {% endset %}
 {% set _badges = [] %}
+{% set _meta = [] %}
 {% for _item in content.oe_subject|field_value %}
   {% set _badges = _badges|merge([{
     label: _item,
   }]) %}
 {% endfor %}
 {% if content.oe_project_dates|field_value is not empty %}
-  {% set _content %}
-    <span class="text-muted text-nowrap me-4-5">{{ content.oe_project_dates }}</span>
-  {% endset %}
+  {% set _meta = _meta|merge([
+    content.oe_project_dates|field_value,
+  ]) %}
 {% endif %}
 {% block content %}
   <article{{attributes}}>
@@ -27,7 +28,7 @@
       image: (image is not empty) ? image|merge({
         path: image.src,
       }) : {},
-      content: _content,
+      meta: _meta,
       badges: _badges,
     }) }}
   </article>
-- 
GitLab


From 43a36f9aee15cb404d7e48b6b4d31a0a9846e1b9 Mon Sep 17 00:00:00 2001
From: Sergio Elvira Perez <sergioelviraperez@gmail.com>
Date: Tue, 12 Apr 2022 17:39:59 +0200
Subject: [PATCH 082/152] OEL-1246: Update entity view display.

---
 .../install/core.entity_view_display.node.oe_project.full.yml   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
index 354d14d5..7adc487c 100644
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
@@ -55,7 +55,7 @@ third_party_settings:
         show_empty_fields: false
         id: ''
         element: div
-        show_label: true
+        show_label: false
         label_element: h3
         label_element_classes: 'fw-bold mb-4'
         attributes: ''
-- 
GitLab


From 61e6940fd07f5a5647d172e36b71e194177f01a6 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Tue, 10 May 2022 18:01:45 +0200
Subject: [PATCH 083/152] OEL-1293: Pass additional argument to
 ConfigImporter::importMultiple().

---
 .../oe_whitelabel_extra_project.install                         | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
index 7b2e1b67..782c6ebd 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.install
@@ -26,5 +26,5 @@ function oe_whitelabel_extra_project_install($is_syncing): void {
     'core.entity_view_display.oe_organisation.oe_cx_project_stakeholder.default',
   ];
 
-  ConfigImporter::importMultiple('oe_whitelabel_extra_project', '/config/overrides/', $configs);
+  ConfigImporter::importMultiple('module', 'oe_whitelabel_extra_project', '/config/overrides/', $configs);
 }
-- 
GitLab


From 2a1963ed795f8235f9fd0823573bb508c5a2db5b Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 22:42:42 +0200
Subject: [PATCH 084/152] OEL-1371: Reorder imports in
 ContentProjectRenderTest.

---
 tests/src/Functional/ContentProjectRenderTest.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index 160784e6..e7a5c486 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -9,9 +9,9 @@ use Drupal\file\Entity\File;
 use Drupal\media\Entity\Media;
 use Drupal\oe_content_entity\Entity\CorporateEntityInterface;
 use Drupal\oe_content_entity_organisation\Entity\OrganisationInterface;
-use Drupal\Tests\oe_whitelabel\PatternAssertions\InPageNavigationAssert;
-use Drupal\Tests\oe_whitelabel\PatternAssertions\DescriptionListAssert;
 use Drupal\Tests\oe_whitelabel\PatternAssertions\ContentBannerAssert;
+use Drupal\Tests\oe_whitelabel\PatternAssertions\DescriptionListAssert;
+use Drupal\Tests\oe_whitelabel\PatternAssertions\InPageNavigationAssert;
 use Drupal\Tests\sparql_entity_storage\Traits\SparqlConnectionTrait;
 use Drupal\Tests\TestFileCreationTrait;
 
-- 
GitLab


From ebe3ad7bb6f839af9eed36baa4554a008c73dd72 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Tue, 26 Apr 2022 02:17:58 +0200
Subject: [PATCH 085/152] OEL-1371: Remove parts from ContentProjectRenderTest
 that are already done in the parent class.

---
 tests/src/Functional/ContentProjectRenderTest.php | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index e7a5c486..7e828488 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -12,7 +12,6 @@ use Drupal\oe_content_entity_organisation\Entity\OrganisationInterface;
 use Drupal\Tests\oe_whitelabel\PatternAssertions\ContentBannerAssert;
 use Drupal\Tests\oe_whitelabel\PatternAssertions\DescriptionListAssert;
 use Drupal\Tests\oe_whitelabel\PatternAssertions\InPageNavigationAssert;
-use Drupal\Tests\sparql_entity_storage\Traits\SparqlConnectionTrait;
 use Drupal\Tests\TestFileCreationTrait;
 
 /**
@@ -20,7 +19,6 @@ use Drupal\Tests\TestFileCreationTrait;
  */
 class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
 
-  use SparqlConnectionTrait;
   use TestFileCreationTrait;
 
   /**
@@ -35,7 +33,6 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
    */
   protected function setUp(): void {
     parent::setUp();
-    $this->setUpSparql();
 
     $admin = $this->createUser([], NULL, TRUE);
     $this->drupalLogin($admin);
-- 
GitLab


From f209be48573f4781f351150c035b6e7096dc0763 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Tue, 26 Apr 2022 01:25:17 +0200
Subject: [PATCH 086/152] OEL-1371: Remove unused variable $page in
 ContentProjectRenderTest.

---
 tests/src/Functional/ContentProjectRenderTest.php | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index 7e828488..d9963eca 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -43,7 +43,6 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
    */
   public function testProjectRendering(): void {
     $assert_session = $this->assertSession();
-    $page = $this->getSession()->getPage();
 
     // Create a media entity.
     // Create file and media.
-- 
GitLab


From bfcd662f18921055bad71f1a85095e67bae2ad62 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 22:07:47 +0200
Subject: [PATCH 087/152] OEL-1371: Rename vars in ContentProjectRenderTest.

---
 .../Functional/ContentProjectRenderTest.php   | 32 +++++++++----------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index d9963eca..a81b6ef7 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -104,8 +104,8 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     $node->save();
     $this->drupalGet($node->toUrl());
 
-    // Assert page header - metadata.
-    $page_header = $assert_session->elementExists('css', '.bcl-content-banner');
+    // Assert content banner.
+    $content_banner = $assert_session->elementExists('css', '.bcl-content-banner');
     $assert = new ContentBannerAssert();
     $expected_values = [
       'image' => [
@@ -116,10 +116,10 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       'title' => 'Test project node',
       'description' => 'Test project node',
     ];
-    $assert->assertPattern($expected_values, $page_header->getOuterHtml());
+    $assert->assertPattern($expected_values, $content_banner->getOuterHtml());
 
-    // Assert navigation.
-    $navigation = $this->assertSession()->elementExists('css', 'nav.bcl-inpage-navigation');
+    // Assert in-page navigation.
+    $inpage_nav = $this->assertSession()->elementExists('css', 'nav.bcl-inpage-navigation');
     $inpage_nav_assert = new InPageNavigationAssert();
     $inpage_nav_expected_values = [
       'title' => 'Page content',
@@ -150,7 +150,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
         ],
       ],
     ];
-    $inpage_nav_assert->assertPattern($inpage_nav_expected_values, $navigation->getOuterHtml());
+    $inpage_nav_assert->assertPattern($inpage_nav_expected_values, $inpage_nav->getOuterHtml());
 
     // Assert top region - Project details.
     $project_data = $assert_session->elementExists('css', '.col-md-9');
@@ -160,7 +160,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     $this->assertCount(5, $description_lists);
 
     // Period list group.
-    $field_list_assert = new DescriptionListAssert();
+    $description_list_assert = new DescriptionListAssert();
     $first_field_list_expected_values = [
       'items' => [
         [
@@ -170,10 +170,10 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       ],
     ];
     $field_list_html = $description_lists[0]->getHtml();
-    $field_list_assert->assertPattern($first_field_list_expected_values, $field_list_html);
+    $description_list_assert->assertPattern($first_field_list_expected_values, $field_list_html);
 
     // Assert budget list group.
-    $field_list_assert = new DescriptionListAssert();
+    $description_list_assert = new DescriptionListAssert();
     $second_field_list_expected_values = [
       'items' => [
         [
@@ -187,10 +187,10 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       ],
     ];
     $field_list_html = $description_lists[1]->getHtml();
-    $field_list_assert->assertPattern($second_field_list_expected_values, $field_list_html);
+    $description_list_assert->assertPattern($second_field_list_expected_values, $field_list_html);
 
     // Assert details list group.
-    $field_list_assert = new DescriptionListAssert();
+    $description_list_assert = new DescriptionListAssert();
     $third_field_list_expected_values = [
       'items' => [
         [
@@ -208,10 +208,10 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       ],
     ];
     $field_list_html = $description_lists[2]->getHtml();
-    $field_list_assert->assertPattern($third_field_list_expected_values, $field_list_html);
+    $description_list_assert->assertPattern($third_field_list_expected_values, $field_list_html);
 
     // Assert coordinators list group.
-    $field_list_assert = new DescriptionListAssert();
+    $description_list_assert = new DescriptionListAssert();
     $fourth_field_list_expected_values = [
       'items' => [
         [
@@ -221,10 +221,10 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       ],
     ];
     $field_list_html = $description_lists[3]->getHtml();
-    $field_list_assert->assertPattern($fourth_field_list_expected_values, $field_list_html);
+    $description_list_assert->assertPattern($fourth_field_list_expected_values, $field_list_html);
 
     // Assert participants list group.
-    $field_list_assert = new DescriptionListAssert();
+    $description_list_assert = new DescriptionListAssert();
     $fifth_field_list_expected_values = [
       'items' => [
         [
@@ -242,7 +242,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       ],
     ];
     $field_list_html = $description_lists[4]->getHtml();
-    $field_list_assert->assertPattern($fifth_field_list_expected_values, $field_list_html);
+    $description_list_assert->assertPattern($fifth_field_list_expected_values, $field_list_html);
   }
 
   /**
-- 
GitLab


From b9b1c746c4322a76e7ac3cb1742334d1aba0a02b Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 22:09:15 +0200
Subject: [PATCH 088/152] OEL-1371: Reuse the same instance of
 DescriptionListAssert in ContentProjectRenderTest.

---
 tests/src/Functional/ContentProjectRenderTest.php | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index a81b6ef7..1f99e9ad 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -159,8 +159,9 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     $description_lists = $project_data->findAll('css', '.grid-3-9');
     $this->assertCount(5, $description_lists);
 
-    // Period list group.
     $description_list_assert = new DescriptionListAssert();
+
+    // Period list group.
     $first_field_list_expected_values = [
       'items' => [
         [
@@ -173,7 +174,6 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     $description_list_assert->assertPattern($first_field_list_expected_values, $field_list_html);
 
     // Assert budget list group.
-    $description_list_assert = new DescriptionListAssert();
     $second_field_list_expected_values = [
       'items' => [
         [
@@ -190,7 +190,6 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     $description_list_assert->assertPattern($second_field_list_expected_values, $field_list_html);
 
     // Assert details list group.
-    $description_list_assert = new DescriptionListAssert();
     $third_field_list_expected_values = [
       'items' => [
         [
@@ -211,7 +210,6 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     $description_list_assert->assertPattern($third_field_list_expected_values, $field_list_html);
 
     // Assert coordinators list group.
-    $description_list_assert = new DescriptionListAssert();
     $fourth_field_list_expected_values = [
       'items' => [
         [
@@ -224,7 +222,6 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     $description_list_assert->assertPattern($fourth_field_list_expected_values, $field_list_html);
 
     // Assert participants list group.
-    $description_list_assert = new DescriptionListAssert();
     $fifth_field_list_expected_values = [
       'items' => [
         [
-- 
GitLab


From 6707966f7a0326ff3c316e5ac3e2dc18d36b553a Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 19:22:12 +0200
Subject: [PATCH 089/152] OEL-1371: Drop pointless local variables in
 ContentProjectRenderTest.

---
 .../Functional/ContentProjectRenderTest.php   | 40 +++++++------------
 1 file changed, 14 insertions(+), 26 deletions(-)

diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index 1f99e9ad..dd068a78 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -107,7 +107,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     // Assert content banner.
     $content_banner = $assert_session->elementExists('css', '.bcl-content-banner');
     $assert = new ContentBannerAssert();
-    $expected_values = [
+    $assert->assertPattern([
       'image' => [
         'alt' => 'Image test alt',
         'src' => 'image-test.png',
@@ -115,13 +115,12 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       'badges' => ['wood industry'],
       'title' => 'Test project node',
       'description' => 'Test project node',
-    ];
-    $assert->assertPattern($expected_values, $content_banner->getOuterHtml());
+    ], $content_banner->getOuterHtml());
 
     // Assert in-page navigation.
     $inpage_nav = $this->assertSession()->elementExists('css', 'nav.bcl-inpage-navigation');
     $inpage_nav_assert = new InPageNavigationAssert();
-    $inpage_nav_expected_values = [
+    $inpage_nav_assert->assertPattern([
       'title' => 'Page content',
       'links' => [
         [
@@ -149,8 +148,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
           'href' => '#oe-project-oe-cx-achievements-and-milestone',
         ],
       ],
-    ];
-    $inpage_nav_assert->assertPattern($inpage_nav_expected_values, $inpage_nav->getOuterHtml());
+    ], $inpage_nav->getOuterHtml());
 
     // Assert top region - Project details.
     $project_data = $assert_session->elementExists('css', '.col-md-9');
@@ -162,19 +160,17 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     $description_list_assert = new DescriptionListAssert();
 
     // Period list group.
-    $first_field_list_expected_values = [
+    $description_list_assert->assertPattern([
       'items' => [
         [
           'term' => 'Project period',
           'definition' => "10 May 2020\n - 15 May 2025",
         ],
       ],
-    ];
-    $field_list_html = $description_lists[0]->getHtml();
-    $description_list_assert->assertPattern($first_field_list_expected_values, $field_list_html);
+    ], $description_lists[0]->getHtml());
 
     // Assert budget list group.
-    $second_field_list_expected_values = [
+    $description_list_assert->assertPattern([
       'items' => [
         [
           'term' => 'Overall budget',
@@ -185,12 +181,10 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
           'definition' => '€100,00',
         ],
       ],
-    ];
-    $field_list_html = $description_lists[1]->getHtml();
-    $description_list_assert->assertPattern($second_field_list_expected_values, $field_list_html);
+    ], $description_lists[1]->getHtml());
 
     // Assert details list group.
-    $third_field_list_expected_values = [
+    $description_list_assert->assertPattern([
       'items' => [
         [
           'term' => 'Website',
@@ -205,24 +199,20 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
           'definition' => 'Project reference',
         ],
       ],
-    ];
-    $field_list_html = $description_lists[2]->getHtml();
-    $description_list_assert->assertPattern($third_field_list_expected_values, $field_list_html);
+    ], $description_lists[2]->getHtml());
 
     // Assert coordinators list group.
-    $fourth_field_list_expected_values = [
+    $description_list_assert->assertPattern([
       'items' => [
         [
           'term' => 'Coordinators',
           'definition' => 'coordinator',
         ],
       ],
-    ];
-    $field_list_html = $description_lists[3]->getHtml();
-    $description_list_assert->assertPattern($fourth_field_list_expected_values, $field_list_html);
+    ], $description_lists[3]->getHtml());
 
     // Assert participants list group.
-    $fifth_field_list_expected_values = [
+    $description_list_assert->assertPattern([
       'items' => [
         [
           'term' => 'Name',
@@ -237,9 +227,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
           'definition' => '€22,30',
         ],
       ],
-    ];
-    $field_list_html = $description_lists[4]->getHtml();
-    $description_list_assert->assertPattern($fifth_field_list_expected_values, $field_list_html);
+    ], $description_lists[4]->getHtml());
   }
 
   /**
-- 
GitLab


From b1fe006400230cc0e236c779d0bad118f88633db Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 19:22:55 +0200
Subject: [PATCH 090/152] OEL-1371: Use anonymous user instead of admin in
 ContentProjectRenderTest.

---
 tests/src/Functional/ContentProjectRenderTest.php | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index dd068a78..a6aa351c 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -13,6 +13,8 @@ use Drupal\Tests\oe_whitelabel\PatternAssertions\ContentBannerAssert;
 use Drupal\Tests\oe_whitelabel\PatternAssertions\DescriptionListAssert;
 use Drupal\Tests\oe_whitelabel\PatternAssertions\InPageNavigationAssert;
 use Drupal\Tests\TestFileCreationTrait;
+use Drupal\user\Entity\Role;
+use Drupal\user\RoleInterface;
 
 /**
  * Tests that our Project content type renders correctly.
@@ -34,8 +36,12 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
   protected function setUp(): void {
     parent::setUp();
 
-    $admin = $this->createUser([], NULL, TRUE);
-    $this->drupalLogin($admin);
+    Role::load(RoleInterface::ANONYMOUS_ID)
+      ->grantPermission('bypass node access')
+      ->grantPermission('view published skos concept entities')
+      ->grantPermission('view media')
+      ->grantPermission('view published oe_organisation')
+      ->save();
   }
 
   /**
-- 
GitLab


From 8ec7f37232b8c044febc76b2b7de5c08792e8581 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 4 Apr 2022 23:20:37 +0200
Subject: [PATCH 091/152] OEL-1371: Add type hints on preprocess functions.

---
 .../oe_whitelabel_extra_project.module                        | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 2277e189..89589960 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -46,7 +46,7 @@ function oe_whitelabel_extra_project_preprocess_pattern_description_list(array &
 /**
  * Implements template_preprocess_node() for the project node type.
  */
-function oe_whitelabel_extra_project_preprocess_node__oe_project(&$variables) {
+function oe_whitelabel_extra_project_preprocess_node__oe_project(array &$variables): void {
   if ($variables['view_mode'] !== 'full' && $variables['view_mode'] !== 'teaser') {
     return;
   }
@@ -59,7 +59,7 @@ function oe_whitelabel_extra_project_preprocess_node__oe_project(&$variables) {
 /**
  * Implements hook_preprocess().
  */
-function _oe_whitelabel_extra_project_preprocess_featured_media(&$variables) {
+function _oe_whitelabel_extra_project_preprocess_featured_media(array &$variables): void {
   /** @var \Drupal\node\NodeInterface $node */
   $node = $variables['node'];
 
-- 
GitLab


From e847ffa0c9242774f580a440505a6329e6329781 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 4 Apr 2022 11:21:49 +0200
Subject: [PATCH 092/152] OEL-1371: Split and clean up preprocess functions for
 project.

---
 .../oe_whitelabel_extra_project.module        | 26 +++++++++++--------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 89589960..8d0fad72 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -44,20 +44,25 @@ function oe_whitelabel_extra_project_preprocess_pattern_description_list(array &
 }
 
 /**
- * Implements template_preprocess_node() for the project node type.
+ * Implements hook_preprocess_node() for the project full view mode.
  */
-function oe_whitelabel_extra_project_preprocess_node__oe_project(array &$variables): void {
-  if ($variables['view_mode'] !== 'full' && $variables['view_mode'] !== 'teaser') {
-    return;
-  }
+function oe_whitelabel_extra_project_preprocess_node__oe_project__full(array &$variables): void {
   _oe_whitelabel_extra_project_preprocess_featured_media($variables);
-  if ($variables['view_mode'] === 'full') {
-    _oe_whitelabel_extra_project_preprocess_inpage_nav($variables);
-  }
+  _oe_whitelabel_extra_project_preprocess_inpage_nav($variables);
 }
 
 /**
- * Implements hook_preprocess().
+ * Implements hook_preprocess_node() for the project teaser.
+ */
+function oe_whitelabel_extra_project_preprocess_node__oe_project__teaser(array &$variables): void {
+  _oe_whitelabel_extra_project_preprocess_featured_media($variables);
+}
+
+/**
+ * Creates an image value object in $variables['image'].
+ *
+ * @param array $variables
+ *   Variables from hook_preprocess_node().
  */
 function _oe_whitelabel_extra_project_preprocess_featured_media(array &$variables): void {
   /** @var \Drupal\node\NodeInterface $node */
@@ -113,7 +118,7 @@ function _oe_whitelabel_extra_project_preprocess_featured_media(array &$variable
  * Helper function to preprocess the inpage navigation pattern fields.
  *
  * @param array $variables
- *   Render array variables.
+ *   Variables from hook_preprocess_node().
  */
 function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables): void {
   /** @var \Drupal\node\NodeInterface $node */
@@ -144,5 +149,4 @@ function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables):
       'label' => $node->{$item['#field_name']}->getFieldDefinition()->getLabel(),
     ];
   }
-
 }
-- 
GitLab


From 4dcbdff68958e8f21065b2dcc926d27183371c55 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 15 Apr 2022 21:28:21 +0200
Subject: [PATCH 093/152] OEL-1371: Move part of project into content banner.

---
 ...tity_view_display.node.oe_project.full.yml | 17 +---
 ...ay.node.oe_project.oe_w_content_banner.yml | 85 +++++++++++++++++++
 .../oe_whitelabel_extra_project.info.yml      |  1 +
 .../oe_whitelabel_extra_project.module        |  8 +-
 .../content/node--oe-project--full.html.twig  | 17 ----
 ...-oe-project--oe-w-content-banner.html.twig | 23 +++++
 .../Functional/ContentProjectRenderTest.php   |  1 +
 7 files changed, 119 insertions(+), 33 deletions(-)
 create mode 100644 modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.oe_w_content_banner.yml
 create mode 100644 templates/content/node--oe-project--oe-w-content-banner.html.twig

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
index 7adc487c..bd953cd2 100644
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
@@ -212,14 +212,6 @@ content:
     third_party_settings: {  }
     weight: 5
     region: content
-  oe_subject:
-    type: skos_concept_entity_reference_label
-    label: hidden
-    settings:
-      link: false
-    third_party_settings: {  }
-    weight: 1
-    region: content
   oe_summary:
     type: text_default
     label: hidden
@@ -227,13 +219,6 @@ content:
     third_party_settings: {  }
     weight: 3
     region: content
-  oe_teaser:
-    type: text_default
-    label: hidden
-    settings: {  }
-    third_party_settings: {  }
-    weight: 0
-    region: content
 hidden:
   body: true
   langcode: true
@@ -251,3 +236,5 @@ hidden:
   oe_project_locations: true
   oe_project_result_files: true
   oe_project_results: true
+  oe_subject: true
+  oe_teaser: true
diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.oe_w_content_banner.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.oe_w_content_banner.yml
new file mode 100644
index 00000000..d5532416
--- /dev/null
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.oe_w_content_banner.yml
@@ -0,0 +1,85 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - core.entity_view_mode.node.oe_w_content_banner
+    - field.field.node.oe_project.body
+    - field.field.node.oe_project.oe_cx_achievements_and_milestone
+    - field.field.node.oe_project.oe_cx_gallery
+    - field.field.node.oe_project.oe_cx_impacts
+    - field.field.node.oe_project.oe_cx_lead_contributors
+    - field.field.node.oe_project.oe_cx_objective
+    - field.field.node.oe_project.oe_departments
+    - field.field.node.oe_project.oe_documents
+    - field.field.node.oe_project.oe_featured_media
+    - field.field.node.oe_project.oe_project_budget
+    - field.field.node.oe_project.oe_project_budget_eu
+    - field.field.node.oe_project.oe_project_calls
+    - field.field.node.oe_project.oe_project_contact
+    - field.field.node.oe_project.oe_project_coordinators
+    - field.field.node.oe_project.oe_project_dates
+    - field.field.node.oe_project.oe_project_funding_programme
+    - field.field.node.oe_project.oe_project_locations
+    - field.field.node.oe_project.oe_project_participants
+    - field.field.node.oe_project.oe_project_result_files
+    - field.field.node.oe_project.oe_project_results
+    - field.field.node.oe_project.oe_project_website
+    - field.field.node.oe_project.oe_reference_code
+    - field.field.node.oe_project.oe_subject
+    - field.field.node.oe_project.oe_summary
+    - field.field.node.oe_project.oe_teaser
+    - node.type.oe_project
+  module:
+    - rdf_skos
+    - text
+    - user
+id: node.oe_project.oe_w_content_banner
+targetEntityType: node
+bundle: oe_project
+mode: oe_w_content_banner
+content:
+  oe_subject:
+    type: skos_concept_entity_reference_label
+    label: hidden
+    settings:
+      link: false
+    third_party_settings: {  }
+    weight: 1
+    region: content
+  oe_teaser:
+    type: text_default
+    label: hidden
+    settings: {  }
+    third_party_settings: {  }
+    weight: 0
+    region: content
+hidden:
+  body: true
+  langcode: true
+  links: true
+  oe_content_content_owner: true
+  oe_content_legacy_link: true
+  oe_content_navigation_title: true
+  oe_content_short_title: true
+  oe_cx_achievements_and_milestone: true
+  oe_cx_gallery: true
+  oe_cx_impacts: true
+  oe_cx_lead_contributors: true
+  oe_cx_objective: true
+  oe_departments: true
+  oe_documents: true
+  oe_featured_media: true
+  oe_project_budget: true
+  oe_project_budget_eu: true
+  oe_project_calls: true
+  oe_project_contact: true
+  oe_project_coordinators: true
+  oe_project_dates: true
+  oe_project_funding_programme: true
+  oe_project_locations: true
+  oe_project_participants: true
+  oe_project_result_files: true
+  oe_project_results: true
+  oe_project_website: true
+  oe_reference_code: true
+  oe_summary: true
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
index 28906097..0ec08ee9 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.info.yml
@@ -11,4 +11,5 @@ config_devel:
   install:
     - core.date_format.oe_whitelabel_project_date
     - core.entity_view_display.node.oe_project.full
+    - core.entity_view_display.node.oe_project.oe_w_content_banner
     - core.entity_view_display.node.oe_project.teaser
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 8d0fad72..afe742db 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -47,10 +47,16 @@ function oe_whitelabel_extra_project_preprocess_pattern_description_list(array &
  * Implements hook_preprocess_node() for the project full view mode.
  */
 function oe_whitelabel_extra_project_preprocess_node__oe_project__full(array &$variables): void {
-  _oe_whitelabel_extra_project_preprocess_featured_media($variables);
   _oe_whitelabel_extra_project_preprocess_inpage_nav($variables);
 }
 
+/**
+ * Implements hook_preprocess_node() for the project content banner view mode.
+ */
+function oe_whitelabel_extra_project_preprocess_node__oe_project__oe_w_content_banner(array &$variables): void {
+  _oe_whitelabel_extra_project_preprocess_featured_media($variables);
+}
+
 /**
  * Implements hook_preprocess_node() for the project teaser.
  */
diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 12ee4bd8..7913dedf 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -4,23 +4,6 @@
  * Project full display.
  */
 #}
-{% if not content.oe_subject.isEmpty() %}
-  {% set _badges = [] %}
-  {% for _badge in content.oe_subject|field_value %}
-    {% set _badges = _badges|merge([{
-      label: _badge|raw,
-      rounded_pill: true,
-    }]) %}
-  {% endfor %}
-{% endif %}
-{{ pattern('content_banner', {
-  background: 'gray',
-  title: label,
-  content: content.oe_teaser,
-  image: image,
-  attributes: create_attribute().addClass(['ps-0']),
-  badges: _badges,
-}) }}
 {% macro field_with_header(field) %}
   {% if field|field_value is not empty %}
     <h3 class="fw-bold mb-4 pt-3" id="{{ field['#inpage_nav_id'] }}">{{ field|field_label }}</h3>
diff --git a/templates/content/node--oe-project--oe-w-content-banner.html.twig b/templates/content/node--oe-project--oe-w-content-banner.html.twig
new file mode 100644
index 00000000..93eb4aab
--- /dev/null
+++ b/templates/content/node--oe-project--oe-w-content-banner.html.twig
@@ -0,0 +1,23 @@
+{#
+/**
+ * @file
+ * Project content banner display.
+ */
+#}
+{% if not content.oe_subject.isEmpty() %}
+  {% set _badges = [] %}
+  {% for _badge in content.oe_subject|field_value %}
+    {% set _badges = _badges|merge([{
+      label: _badge|raw,
+      rounded_pill: true,
+    }]) %}
+  {% endfor %}
+{% endif %}
+{{ pattern('content_banner', {
+  background: 'gray',
+  title: label,
+  content: content.oe_teaser,
+  image: image,
+  attributes: create_attribute().addClass(['ps-0']),
+  badges: _badges,
+}) }}
diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index a6aa351c..ef084893 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -27,6 +27,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
    * {@inheritdoc}
    */
   public static $modules = [
+    'block',
     'oe_whitelabel_extra_project',
   ];
 
-- 
GitLab


From 6cf88c2ab5550a948520520837bc3d0b7f5cd36e Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 15 Apr 2022 21:35:28 +0200
Subject: [PATCH 094/152] OEL-1371: Simplify code for badges in project content
 banner.

---
 ...node--oe-project--oe-w-content-banner.html.twig | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/templates/content/node--oe-project--oe-w-content-banner.html.twig b/templates/content/node--oe-project--oe-w-content-banner.html.twig
index 93eb4aab..0b43de21 100644
--- a/templates/content/node--oe-project--oe-w-content-banner.html.twig
+++ b/templates/content/node--oe-project--oe-w-content-banner.html.twig
@@ -4,20 +4,14 @@
  * Project content banner display.
  */
 #}
-{% if not content.oe_subject.isEmpty() %}
-  {% set _badges = [] %}
-  {% for _badge in content.oe_subject|field_value %}
-    {% set _badges = _badges|merge([{
-      label: _badge|raw,
-      rounded_pill: true,
-    }]) %}
-  {% endfor %}
-{% endif %}
 {{ pattern('content_banner', {
   background: 'gray',
   title: label,
   content: content.oe_teaser,
   image: image,
   attributes: create_attribute().addClass(['ps-0']),
-  badges: _badges,
+  badges: content.oe_subject ? content.oe_subject|field_value|default([])|map(_item => {
+    label: _item|raw,
+    rounded_pill: true,
+  }),
 }) }}
-- 
GitLab


From 76b4f98690649b2ac118856935f5ac8504e3212f Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 15 Apr 2022 21:35:56 +0200
Subject: [PATCH 095/152] OEL-1371: Clear out empty badges in project content
 banner.

---
 .../content/node--oe-project--oe-w-content-banner.html.twig     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/content/node--oe-project--oe-w-content-banner.html.twig b/templates/content/node--oe-project--oe-w-content-banner.html.twig
index 0b43de21..8bc98cb7 100644
--- a/templates/content/node--oe-project--oe-w-content-banner.html.twig
+++ b/templates/content/node--oe-project--oe-w-content-banner.html.twig
@@ -13,5 +13,5 @@
   badges: content.oe_subject ? content.oe_subject|field_value|default([])|map(_item => {
     label: _item|raw,
     rounded_pill: true,
-  }),
+  })|filter(_badge => _badge.label|drupal_escape|striptags|trim is not empty),
 }) }}
-- 
GitLab


From 8fb0e8c444037e3100c884dd2d5d0511b9b43b3c Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 15:26:36 +0200
Subject: [PATCH 096/152] OEL-1371: Remove pointless '|raw' for badges in
 content banner.

---
 .../content/node--oe-project--oe-w-content-banner.html.twig     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/content/node--oe-project--oe-w-content-banner.html.twig b/templates/content/node--oe-project--oe-w-content-banner.html.twig
index 8bc98cb7..4c6d6341 100644
--- a/templates/content/node--oe-project--oe-w-content-banner.html.twig
+++ b/templates/content/node--oe-project--oe-w-content-banner.html.twig
@@ -11,7 +11,7 @@
   image: image,
   attributes: create_attribute().addClass(['ps-0']),
   badges: content.oe_subject ? content.oe_subject|field_value|default([])|map(_item => {
-    label: _item|raw,
+    label: _item,
     rounded_pill: true,
   })|filter(_badge => _badge.label|drupal_escape|striptags|trim is not empty),
 }) }}
-- 
GitLab


From 18772c630a21e8b36322611cb6278243c27dec97 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 15 Apr 2022 23:32:06 +0200
Subject: [PATCH 097/152] OEL-1371: Add some blank lines for readability.

---
 templates/content/node--oe-project--full.html.twig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 7913dedf..7740e814 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -10,9 +10,11 @@
     {{ field }}
   {% endif %}
 {% endmacro %}
+
 {% set _project_details %}
   {{ content.group_project_details }}
 {% endset %}
+
 {% if _project_details|striptags|trim is not empty %}
   {% set _project_details_title = 'Project details'|t %}
   {% set _project_details %}
@@ -26,6 +28,7 @@
     'label': _project_details_title,
   }]|merge(inpage_navigation_links) %}
 {% endif %}
+
 {% set inpage_navigation_fields %}
   {% block inpage_navigation_content %}
     {{ _project_details }}
@@ -37,6 +40,7 @@
     {{ _self.field_with_header(content.oe_cx_achievements_and_milestone) }}
   {% endblock %}
 {% endset %}
+
 <div class="mt-md-4-75 mt-4">
   {{ pattern('inpage_navigation', {
     title: 'Page content'|t,
-- 
GitLab


From 26c77924cf74f723cf7e64e3253c9bfae685fd8e Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 15 Apr 2022 21:53:46 +0200
Subject: [PATCH 098/152] OEL-1371: Put project details id on the heading, drop
 the div below.

---
 templates/content/node--oe-project--full.html.twig | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 7740e814..c49ad104 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -18,10 +18,8 @@
 {% if _project_details|striptags|trim is not empty %}
   {% set _project_details_title = 'Project details'|t %}
   {% set _project_details %}
-    <h3 class="fw-bold mb-4">{{ _project_details_title }}</h3>
-    <div id="project-details">
-      {{ _project_details }}
-    </div>
+    <h3 class="fw-bold mb-4" id="project-details">{{ _project_details_title }}</h3>
+    {{ _project_details }}
   {% endset %}
   {% set inpage_navigation_links = [{
     'path': '#project-details',
-- 
GitLab


From ff1a618cf45c5676f0a43a31ee64d9ef5daa1f9a Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 15 Apr 2022 21:55:51 +0200
Subject: [PATCH 099/152] OEL-1371: Render only subgroups/children of
 group_project_details, not the group wrapper.

---
 templates/content/node--oe-project--full.html.twig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index c49ad104..b90764e7 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -12,10 +12,10 @@
 {% endmacro %}
 
 {% set _project_details %}
-  {{ content.group_project_details }}
+  {{ content.group_project_details|filter((subgroup, key) => key|first != '#') }}
 {% endset %}
 
-{% if _project_details|striptags|trim is not empty %}
+{% if _project_details|trim is not empty %}
   {% set _project_details_title = 'Project details'|t %}
   {% set _project_details %}
     <h3 class="fw-bold mb-4" id="project-details">{{ _project_details_title }}</h3>
-- 
GitLab


From 380e2915774e1632ee2dde417f449caa2162db8f Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 15 Apr 2022 23:23:16 +0200
Subject: [PATCH 100/152] OEL-1371: Split the header macro.

---
 templates/content/node--oe-project--full.html.twig | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index b90764e7..b23f01d6 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -4,10 +4,16 @@
  * Project full display.
  */
 #}
+{% macro header(title, id) %}
+  {% set attributes = id ? create_attribute({'id': id}) %}
+  <h3 class="fw-bold mb-4 pt-3"{{ attributes }}>{{ title }}</h3>
+{% endmacro %}
+
 {% macro field_with_header(field) %}
-  {% if field|field_value is not empty %}
-    <h3 class="fw-bold mb-4 pt-3" id="{{ field['#inpage_nav_id'] }}">{{ field|field_label }}</h3>
-    {{ field }}
+  {% set _content %}{{ field|field_value }}{% endset %}
+  {% if _content|trim %}
+    {{ _self.header(field|field_label, field['#inpage_nav_id'] ?? null) }}
+    {{ _content }}
   {% endif %}
 {% endmacro %}
 
-- 
GitLab


From 288945d537619a67bde001e41261dadf8c65db98 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 15 Apr 2022 23:24:12 +0200
Subject: [PATCH 101/152] OEL-1371: Use margin-top instead of padding-top for
 headings.

We need to use mt-4-5 instead of pt-3, to compensate for margin collapse.
---
 templates/content/node--oe-project--full.html.twig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index b23f01d6..1a3f8a0d 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -6,7 +6,7 @@
 #}
 {% macro header(title, id) %}
   {% set attributes = id ? create_attribute({'id': id}) %}
-  <h3 class="fw-bold mb-4 pt-3"{{ attributes }}>{{ title }}</h3>
+  <h3 class="fw-bold mb-4 mt-4-5"{{ attributes }}>{{ title }}</h3>
 {% endmacro %}
 
 {% macro field_with_header(field) %}
-- 
GitLab


From 266f2cadaaf0c0d1f56d78a03568eeaf9f84b7ed Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 15 Apr 2022 23:28:48 +0200
Subject: [PATCH 102/152] OEL-1371: Absorb top margin if first element is not
 project details.

---
 templates/content/node--oe-project--full.html.twig | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 1a3f8a0d..672bc797 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -34,6 +34,11 @@
 {% endif %}
 
 {% set inpage_navigation_fields %}
+  {#
+    Reliably absorb top margin of first element.
+    @todo Add a utility class 'eat-margin-top' with :before style.
+  #}
+  <div class="h-0 invisible mt-n5 mb-5"></div>
   {% block inpage_navigation_content %}
     {{ _project_details }}
     {{ _self.field_with_header(content.oe_summary) }}
-- 
GitLab


From 44cdf9dc8488e305800ccecf8dc419005dda1489 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 15 Apr 2022 23:29:13 +0200
Subject: [PATCH 103/152] OEL-1371: Also use macro for project details header.

The top margin is ok, it will be absorbed.
---
 templates/content/node--oe-project--full.html.twig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 672bc797..d33bafe9 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -24,7 +24,7 @@
 {% if _project_details|trim is not empty %}
   {% set _project_details_title = 'Project details'|t %}
   {% set _project_details %}
-    <h3 class="fw-bold mb-4" id="project-details">{{ _project_details_title }}</h3>
+    {{ _self.header(_project_details_title, 'project-details') }}
     {{ _project_details }}
   {% endset %}
   {% set inpage_navigation_links = [{
-- 
GitLab


From 2a6c7a9c73c6c8231dc6b12d19ebabf655c3d3ce Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Sat, 16 Apr 2022 05:41:21 +0200
Subject: [PATCH 104/152] OEL-1371: Reorder imports.

---
 .../oe_whitelabel_extra_project.module                          | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index afe742db..7b44f419 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -7,12 +7,12 @@
 
 declare(strict_types =  1);
 
+use Drupal\Component\Utility\Html;
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\media\MediaInterface;
 use Drupal\media\Plugin\media\Source\Image;
 use Drupal\media\Plugin\media\Source\OEmbed;
 use Drupal\oe_bootstrap_theme\ValueObject\ImageValueObject;
-use Drupal\Component\Utility\Html;
 
 /**
  * Implements hook_preprocess_HOOK() for "pattern_description_list".
-- 
GitLab


From 0f5535a4a9beee7008e427a58361393ea932c9db Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Sat, 16 Apr 2022 05:51:05 +0200
Subject: [PATCH 105/152] OEL-1371: Use dynamic element for project status and
 progress.

---
 ...tity_view_display.node.oe_project.full.yml |  36 +----
 .../oe_whitelabel_extra_project.module        |  64 ++++++++
 oe_whitelabel.libraries.yml                   |   7 +
 resources/js/oe_whitelabel.project_status.js  | 132 +++++++++++++++
 .../content/node--oe-project--full.html.twig  |   4 +
 .../Functional/ContentProjectRenderTest.php   | 152 +++++++++++++++---
 6 files changed, 348 insertions(+), 47 deletions(-)
 create mode 100644 resources/js/oe_whitelabel.project_status.js

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
index bd953cd2..2f2eeaf2 100644
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
@@ -30,7 +30,6 @@ dependencies:
     - field.field.node.oe_project.oe_teaser
     - node.type.oe_project
   module:
-    - datetime_range
     - entity_reference_revisions
     - field_group
     - link
@@ -41,14 +40,13 @@ third_party_settings:
   field_group:
     group_project_details:
       children:
-        - group_period
         - group_budget
         - group_website
         - group_coordinators
       label: 'Project details'
       parent_name: ''
       region: content
-      weight: 2
+      weight: 0
       format_type: html_element
       format_settings:
         classes: ''
@@ -70,15 +68,6 @@ third_party_settings:
       weight: 3
       format_type: oe_whitelabel_helper_description_list_pattern
       format_settings: {  }
-    group_period:
-      children:
-        - oe_project_dates
-      label: Period
-      parent_name: group_project_details
-      region: content
-      weight: 0
-      format_type: oe_whitelabel_helper_description_list_pattern
-      format_settings: {  }
     group_budget:
       children:
         - oe_project_budget
@@ -110,14 +99,14 @@ content:
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 8
+    weight: 6
     region: content
   oe_cx_impacts:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 5
+    weight: 3
     region: content
   oe_cx_lead_contributors:
     type: entity_reference_revisions_entity_view
@@ -126,14 +115,14 @@ content:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 6
+    weight: 4
     region: content
   oe_cx_objective:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 4
+    weight: 2
     region: content
   oe_project_budget:
     type: number_decimal
@@ -165,16 +154,6 @@ content:
     third_party_settings: {  }
     weight: 4
     region: content
-  oe_project_dates:
-    type: daterange_default
-    label: hidden
-    settings:
-      timezone_override: ''
-      format_type: oe_whitelabel_project_date
-      separator: '-'
-    third_party_settings: {  }
-    weight: 1
-    region: content
   oe_project_funding_programme:
     type: skos_concept_entity_reference_label
     label: hidden
@@ -190,7 +169,7 @@ content:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 7
+    weight: 5
     region: content
   oe_project_website:
     type: link
@@ -217,7 +196,7 @@ content:
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 3
+    weight: 1
     region: content
 hidden:
   body: true
@@ -233,6 +212,7 @@ hidden:
   oe_featured_media: true
   oe_project_calls: true
   oe_project_contact: true
+  oe_project_dates: true
   oe_project_locations: true
   oe_project_result_files: true
   oe_project_results: true
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 7b44f419..205d9907 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -9,6 +9,8 @@ declare(strict_types =  1);
 
 use Drupal\Component\Utility\Html;
 use Drupal\Core\Cache\CacheableMetadata;
+use Drupal\Core\Datetime\DrupalDateTime;
+use Drupal\Core\Template\Attribute;
 use Drupal\media\MediaInterface;
 use Drupal\media\Plugin\media\Source\Image;
 use Drupal\media\Plugin\media\Source\OEmbed;
@@ -48,6 +50,7 @@ function oe_whitelabel_extra_project_preprocess_pattern_description_list(array &
  */
 function oe_whitelabel_extra_project_preprocess_node__oe_project__full(array &$variables): void {
   _oe_whitelabel_extra_project_preprocess_inpage_nav($variables);
+  _oe_whitelabel_extra_project_preprocess_status_and_progress($variables);
 }
 
 /**
@@ -156,3 +159,64 @@ function _oe_whitelabel_extra_project_preprocess_inpage_nav(array &$variables):
     ];
   }
 }
+
+/**
+ * Adds variables for the project status.
+ *
+ * @param array $variables
+ *   Variables from hook_preprocess_node().
+ */
+function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$variables): void {
+  /** @var \Drupal\node\NodeInterface $node */
+  $node = $variables['node'];
+  /** @var \Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem|null $date_range_item */
+  $date_range_item = $node->get('oe_project_dates')->first();
+  if ($date_range_item === NULL) {
+    return;
+  }
+  $status_keys = ['planned', 'ongoing', 'closed'];
+  $status_labels = [t('Planned'), t('Ongoing'), t('Closed')];
+
+  if (!$date_range_item->value || !$date_range_item->end_value) {
+    // One of the fields is empty.
+    return;
+  }
+
+  // Dates only store the date, not the time.
+  // Use the site-wide configured timezone, not a user-specific timezone.
+  /* @see \Drupal\system\TimeZoneResolver::getTimeZone() */
+  /** @var string $timezone */
+  $timezone = \Drupal::config('system.date')->get('timezone.default') ?? 'UTC';
+  $get_timestamp = static function (string $date_string) use ($timezone): int {
+    return (new DrupalDateTime($date_string, $timezone))->getTimestamp();
+  };
+  // Project starts at the beginning of the first day at 00:00.
+  $t_start = $get_timestamp($date_range_item->value);
+  // Project ends at the end of the last day at 24:00.
+  $t_end = $get_timestamp($date_range_item->end_value . ' +1 day');
+
+  if ($t_start >= $t_end) {
+    // Cannot show a progress bar if start and end timestamp are the same.
+    return;
+  }
+
+  $t_now = \Drupal::time()->getCurrentTime();
+  $status_id = ($t_now > $t_start) + ($t_now > $t_end);
+  $progress_01 = max(0, min(1, ($t_now - $t_start) / ($t_end - $t_start)));
+  $variables['project_status_args'] = [
+    'status' => $status_keys[$status_id],
+    'start_date' => $date_range_item->value,
+    'start_label' => t('Start'),
+    'end_date' => $date_range_item->end_value,
+    'end_label' => t('End'),
+    'label' => t('Status'),
+    'badge' => $status_labels[$status_id],
+    // Steps of 0.5 are smaller than a pixel, without too many decimals.
+    'progress' => round($progress_01 * 200) / 2,
+    'attributes' => new Attribute([
+      'data-start-timestamp' => $t_start,
+      'data-end-timestamp' => $t_end,
+      'data-status-labels' => implode('|', $status_labels),
+    ]),
+  ];
+}
diff --git a/oe_whitelabel.libraries.yml b/oe_whitelabel.libraries.yml
index 3243b9da..1a029ba9 100644
--- a/oe_whitelabel.libraries.yml
+++ b/oe_whitelabel.libraries.yml
@@ -3,3 +3,10 @@ style:
   css:
     theme:
       assets/css/oe_whitelabel.style.min.css: {}
+
+project_status:
+  version: VERSION
+  js:
+    resources/js/oe_whitelabel.project_status.js: {}
+  dependencies:
+    - core/jquery.once
diff --git a/resources/js/oe_whitelabel.project_status.js b/resources/js/oe_whitelabel.project_status.js
new file mode 100644
index 00000000..7e3fdd90
--- /dev/null
+++ b/resources/js/oe_whitelabel.project_status.js
@@ -0,0 +1,132 @@
+/**
+ * @file
+ * Attaches behaviors for the project status element.
+ */
+(function (bootstrap, Drupal, $) {
+
+  const colorClasses = [
+    'bg-secondary',
+    'bg-info',
+    'bg-dark',
+  ];
+
+  /**
+   * @param {int} msBegin
+   *   Start timestamp in milliseconds.
+   * @param {int} msEnd
+   *   End timestamp in milliseconds.
+   * @param {function(0|1|2)} setStatus
+   *   Callback to set the status: 0 = planned, 1 = ongoing, 2 = closed.
+   */
+  function animateStatus(msBegin, msEnd, setStatus) {
+    const msNow = Date.now();
+    if (msNow < msBegin) {
+      setStatus(0);
+      window.setTimeout(setStatus, msBegin - msNow, 1);
+      window.setTimeout(setStatus, msEnd - msNow, 2);
+    }
+    else if (msNow < msEnd) {
+      setStatus(1);
+      window.setTimeout(setStatus, msEnd - msNow, 2);
+    }
+    else {
+      setStatus(2);
+    }
+  }
+
+  /**
+   * @param {int} msBegin
+   *   Start timestamp in milliseconds.
+   * @param {int} msEnd
+   *   End timestamp in milliseconds.
+   * @param {int} nTicks
+   *   Number of sub-intervals.
+   * @param {function(int)} setProgress
+   *   Callback to be called on each tick.
+   *   The parameter is a value within the [0..nTicks] interval.
+   */
+  function animateProgress(msBegin, msEnd, nTicks, setProgress) {
+    const msNow = Date.now();
+    const msTick = (msEnd - msBegin) / nTicks;
+    const tickNext = Math.ceil((msNow - msBegin) / msTick);
+
+    if (tickNext >= nTicks) {
+      setProgress(nTicks);
+      return;
+    }
+
+    // Compute a delay for the start of the interval.
+    const msIntervalDelay = msBegin - msNow + Math.max(0, tickNext) * msTick;
+
+    // Register a repeated interval.
+    window.setTimeout(function () {
+      let tick = Math.max(0, tickNext);
+      setProgress(tick);
+      if (tick >= nTicks) {
+        return;
+      }
+      ++tick;
+      const intervalId = window.setInterval(function () {
+        setProgress(tick);
+        if (tick >= nTicks) {
+          clearInterval(intervalId);
+        }
+        ++tick;
+      }, msTick);
+    }, msIntervalDelay);
+
+    // Set initial progress.
+    setProgress(Math.max(0, tickNext - 1));
+  }
+
+  /**
+   * Animates the project status badge and progress bar.
+   *
+   * @type {Drupal~behavior}
+   *
+   * @prop {Drupal~behaviorAttach} attach
+   *   Initialises the behavior.
+   */
+  Drupal.behaviors.projectStatus = {
+    attach: function (context) {
+      $('.bcl-project-status', context).once('bcl-project-status').each(function () {
+        const $element = $(this);
+        let msBegin = $element.data('start-timestamp') * 1000;
+        let msEnd = $element.data('end-timestamp') * 1000;
+        const statusLabels = $element.data('status-labels').split('|');
+
+        // Process the status label.
+        $('.badge', this).each(function () {
+          const $element = $(this);
+          animateStatus(msBegin, msEnd, function (status) {
+            $element.removeClass(colorClasses);
+            $element.addClass(colorClasses[status]);
+            if (statusLabels) {
+              $element.html(statusLabels[status]);
+            }
+          });
+        });
+
+        // Process the progress bar.
+        $('.progress-bar', this).each(function () {
+          const $element = $(this);
+          animateStatus(msBegin, msEnd, function (status) {
+            $element.removeClass(colorClasses);
+            $element.addClass(colorClasses[status]);
+          });
+          // Disable css transition.
+          // It looks bad for the initial setting, and afterwards it does not help.
+          $element.css('transition', false);
+          const factor = 2;
+          animateProgress(msBegin, msEnd, factor * 100, function (tick) {
+            const percent = tick / factor;
+            $element.css('width', percent + '%');
+            $element.attr('aria-valuenow', percent);
+            $element.attr('aria-label', percent);
+          });
+        });
+      });
+    }
+  };
+
+})(bootstrap, Drupal, jQuery);
diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index d33bafe9..15bc26c8 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -18,6 +18,10 @@
 {% endmacro %}
 
 {% set _project_details %}
+  {% if project_status_args is not empty %}
+    {{ attach_library('oe_whitelabel/project_status') }}
+    {% include '@oe-bcl/project-status' with project_status_args only %}
+  {% endif %}
   {{ content.group_project_details|filter((subgroup, key) => key|first != '#') }}
 {% endset %}
 
diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index ef084893..699e39cd 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -4,9 +4,11 @@ declare(strict_types = 1);
 
 namespace Drupal\Tests\oe_whitelabel\Functional;
 
+use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\file\Entity\File;
 use Drupal\media\Entity\Media;
+use Drupal\node\NodeInterface;
 use Drupal\oe_content_entity\Entity\CorporateEntityInterface;
 use Drupal\oe_content_entity_organisation\Entity\OrganisationInterface;
 use Drupal\Tests\oe_whitelabel\PatternAssertions\ContentBannerAssert;
@@ -43,6 +45,10 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       ->grantPermission('view media')
       ->grantPermission('view published oe_organisation')
       ->save();
+
+    $this->config('system.date')
+      ->set('timezone.default', 'Europe/Brussels')
+      ->save();
   }
 
   /**
@@ -157,24 +163,16 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       ],
     ], $inpage_nav->getOuterHtml());
 
-    // Assert top region - Project details.
-    $project_data = $assert_session->elementExists('css', '.col-md-9');
+    // Select the content column next to the in-page navigation.
+    $project_content = $assert_session->elementExists('css', '.col-md-9');
 
-    // Assert the description blocks inside the Project details.
-    $description_lists = $project_data->findAll('css', '.grid-3-9');
-    $this->assertCount(5, $description_lists);
+    $this->assertProjectStatusTimestampsAsDateStrings('2020-05-10 00:00:00', '2025-05-16 00:00:00');
 
-    $description_list_assert = new DescriptionListAssert();
+    // Select the description blocks inside the Project details.
+    $description_lists = $project_content->findAll('css', '.grid-3-9');
+    $this->assertCount(4, $description_lists);
 
-    // Period list group.
-    $description_list_assert->assertPattern([
-      'items' => [
-        [
-          'term' => 'Project period',
-          'definition' => "10 May 2020\n - 15 May 2025",
-        ],
-      ],
-    ], $description_lists[0]->getHtml());
+    $description_list_assert = new DescriptionListAssert();
 
     // Assert budget list group.
     $description_list_assert->assertPattern([
@@ -188,7 +186,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
           'definition' => '€100,00',
         ],
       ],
-    ], $description_lists[1]->getHtml());
+    ], $description_lists[0]->getHtml());
 
     // Assert details list group.
     $description_list_assert->assertPattern([
@@ -206,7 +204,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
           'definition' => 'Project reference',
         ],
       ],
-    ], $description_lists[2]->getHtml());
+    ], $description_lists[1]->getHtml());
 
     // Assert coordinators list group.
     $description_list_assert->assertPattern([
@@ -216,7 +214,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
           'definition' => 'coordinator',
         ],
       ],
-    ], $description_lists[3]->getHtml());
+    ], $description_lists[2]->getHtml());
 
     // Assert participants list group.
     $description_list_assert->assertPattern([
@@ -234,7 +232,33 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
           'definition' => '€22,30',
         ],
       ],
-    ], $description_lists[4]->getHtml());
+    ], $description_lists[3]->getHtml());
+
+    // Set a project period that is fully in the past.
+    // @todo Enable web driver testing for javascript behavior.
+    $this->setProjectDateRange($node, '2019-03-07', '2019-03-21');
+    $node->save();
+    $this->drupalGet($node->toUrl());
+
+    $this->assertProjectStatusTimestampsAsDateStrings('2019-03-07 00:00:00', '2019-03-22 00:00:00');
+    $this->assertProjectStatus('bg-dark', 'Closed');
+    $this->assertProjectProgress(100);
+
+    // Set a project period that is ongoing.
+    $this->setProjectDateRange($node, '-5 day', '+15 days');
+    $node->save();
+    $this->drupalGet($node->toUrl());
+
+    $this->assertProjectStatus('bg-info', 'Ongoing');
+    $this->assertProjectProgress(15, 35);
+
+    // Set a project period that is fully in the future.
+    $this->setProjectDateRange($node, '+5 days', '+12 days');
+    $node->save();
+    $this->drupalGet($node->toUrl());
+
+    $this->assertProjectStatus('bg-secondary', 'Planned');
+    $this->assertProjectProgress(0);
   }
 
   /**
@@ -279,4 +303,94 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     return \Drupal::entityTypeManager()->getStorage($entity_type_id);
   }
 
+  /**
+   * Updates the project date, saves the node, and refreshes the page.
+   *
+   * @param \Drupal\node\NodeInterface $node
+   *   Node to update.
+   * @param string $begin
+   *   Start date string.
+   * @param string $end
+   *   End date string.
+   */
+  protected function setProjectDateRange(NodeInterface $node, string $begin, string $end): void {
+    $node->oe_project_dates = [
+      'value' => (new DrupalDateTime($begin, 'Europe/Brussels'))->format('Y-m-d'),
+      'end_value' => (new DrupalDateTime($end, 'Europe/Brussels'))->format('Y-m-d'),
+    ];
+    $node->save();
+    $this->drupalGet($node->toUrl());
+  }
+
+  /**
+   * Asserts start and end timestamp in project status section.
+   *
+   * @param string $begin
+   *   Expected start date string as 'Y-m-d H:i:s'.
+   * @param string $end
+   *   Expected end date string as 'Y-m-d H:i:s'.
+   */
+  protected function assertProjectStatusTimestampsAsDateStrings(string $begin, string $end): void {
+    $status_section = $this->assertSession()->elementExists('css', '.bcl-project-status');
+    $t_begin = (int) $status_section->getAttribute('data-start-timestamp');
+    $t_end = (int) $status_section->getAttribute('data-end-timestamp');
+    $this->assertTimestampAsDateString($begin, $t_begin, 'Europe/Brussels');
+    $this->assertTimestampAsDateString($end, $t_end, 'Europe/Brussels');
+  }
+
+  /**
+   * Asserts a timestamp matches a date string in a given timezone.
+   *
+   * @param string $expected
+   *   Expected date string as 'Y-m-d H:i:s'.
+   * @param int $timestamp
+   *   Actual timestamp.
+   * @param string $timezone
+   *   Timezone for the conversion.
+   */
+  protected function assertTimestampAsDateString(string $expected, int $timestamp, string $timezone): void {
+    $this->assertSame(
+      $expected,
+      DrupalDateTime::createFromTimestamp($timestamp, $timezone)
+        ->format('Y-m-d H:i:s'),
+    );
+  }
+
+  /**
+   * Asserts the state of the status badge and the color of the progress bar.
+   *
+   * @param string $color_class
+   *   Expected color class.
+   * @param string $status_text
+   *   Expected status text.
+   */
+  protected function assertProjectStatus(string $color_class, string $status_text): void {
+    $status_badge = $this->assertSession()->elementExists('css', '.bcl-project-status .badge');
+    $this->assertTrue($status_badge->hasClass($color_class));
+    $this->assertSame($status_text, $status_badge->getText());
+    $progress_bar = $this->assertSession()->elementExists('css', '.bcl-project-status .progress-bar');
+    $this->assertTrue($progress_bar->hasClass($color_class));
+  }
+
+  /**
+   * Asserts the value of the progress bar.
+   *
+   * @param int $min
+   *   Minimum progress in percent.
+   * @param int|null $max
+   *   Maximum progress in percent.
+   */
+  protected function assertProjectProgress(int $min, int $max = NULL): void {
+    $progress_bar = $this->assertSession()->elementExists('css', '.bcl-project-status .progress-bar');
+    $progress_string = $progress_bar->getAttribute('aria-valuenow');
+    $this->assertStringContainsString("width: $progress_string%", $progress_bar->getAttribute('style'));
+    if ($max === NULL) {
+      $this->assertSame((string) $min, $progress_string);
+    }
+    else {
+      $this->assertGreaterThanOrEqual($min, (float) $progress_string);
+      $this->assertLessThanOrEqual($max, (float) $progress_string);
+    }
+  }
+
 }
-- 
GitLab


From 220410952d8a66332cea6664bc53387d3ea5824b Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 14:05:54 +0200
Subject: [PATCH 106/152] OEL-1371: Hide the progress and status for users with
 js disabled.

This is a basic solution that will cause page jumping for users with js enabled.
---
 .../oe_whitelabel_extra_project.module                         | 2 ++
 resources/js/oe_whitelabel.project_status.js                   | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 205d9907..41092f9e 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -217,6 +217,8 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
       'data-start-timestamp' => $t_start,
       'data-end-timestamp' => $t_end,
       'data-status-labels' => implode('|', $status_labels),
+      // Hide for non-js users, to avoid showing wrong/outdated information.
+      'class' => ['d-none'],
     ]),
   ];
 }
diff --git a/resources/js/oe_whitelabel.project_status.js b/resources/js/oe_whitelabel.project_status.js
index 7e3fdd90..87c66e8a 100644
--- a/resources/js/oe_whitelabel.project_status.js
+++ b/resources/js/oe_whitelabel.project_status.js
@@ -125,6 +125,9 @@
             $element.attr('aria-label', percent);
           });
         });
+
+        // Reveal the entire section.
+        $element.removeClass('d-none');
       });
     }
   };
-- 
GitLab


From b463a034b63342ca87e1485544774658c60af8b5 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 13:22:23 +0200
Subject: [PATCH 107/152] OEL-1371: Temporarily set a shorter interval for
 testing. Revert this!

---
 resources/js/oe_whitelabel.project_status.js | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/resources/js/oe_whitelabel.project_status.js b/resources/js/oe_whitelabel.project_status.js
index 87c66e8a..8af7964f 100644
--- a/resources/js/oe_whitelabel.project_status.js
+++ b/resources/js/oe_whitelabel.project_status.js
@@ -94,6 +94,10 @@
         let msBegin = $element.data('start-timestamp') * 1000;
         let msEnd = $element.data('end-timestamp') * 1000;
         const statusLabels = $element.data('status-labels').split('|');
+        // Temporarily set a much shorter interval for a visible animation.
+        // @todo Remove this.
+        msBegin = Date.now() + 2000;
+        msEnd = Date.now() + 9000;
 
         // Process the status label.
         $('.badge', this).each(function () {
-- 
GitLab


From 2242df7f93c7c637cb5c8325e22266f6181b48da Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 13:23:26 +0200
Subject: [PATCH 108/152] OEL-1371: Revert the shorter interval for testing.

---
 resources/js/oe_whitelabel.project_status.js | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/resources/js/oe_whitelabel.project_status.js b/resources/js/oe_whitelabel.project_status.js
index 8af7964f..87c66e8a 100644
--- a/resources/js/oe_whitelabel.project_status.js
+++ b/resources/js/oe_whitelabel.project_status.js
@@ -94,10 +94,6 @@
         let msBegin = $element.data('start-timestamp') * 1000;
         let msEnd = $element.data('end-timestamp') * 1000;
         const statusLabels = $element.data('status-labels').split('|');
-        // Temporarily set a much shorter interval for a visible animation.
-        // @todo Remove this.
-        msBegin = Date.now() + 2000;
-        msEnd = Date.now() + 9000;
 
         // Process the status label.
         $('.badge', this).each(function () {
-- 
GitLab


From 12890626327977733137b455e0c9e9e7edc4a895 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Sat, 16 Apr 2022 05:47:33 +0200
Subject: [PATCH 109/152] OEL-1371: Add BCL component for project
 contributions.

---
 ...tity_view_display.node.oe_project.full.yml | 33 ++++++++++++-------
 .../oe_whitelabel_extra_project.module        | 24 ++++++++++++++
 .../content/node--oe-project--full.html.twig  | 33 +++++++++++++++++++
 .../Functional/ContentProjectRenderTest.php   | 13 +++++---
 4 files changed, 87 insertions(+), 16 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
index 2f2eeaf2..b2aadc3d 100644
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
@@ -40,13 +40,12 @@ third_party_settings:
   field_group:
     group_project_details:
       children:
-        - group_budget
         - group_website
         - group_coordinators
       label: 'Project details'
       parent_name: ''
       region: content
-      weight: 0
+      weight: 1
       format_type: html_element
       format_settings:
         classes: ''
@@ -73,11 +72,21 @@ third_party_settings:
         - oe_project_budget
         - oe_project_budget_eu
       label: Budget
-      parent_name: group_project_details
+      parent_name: ''
       region: content
-      weight: 1
-      format_type: oe_whitelabel_helper_description_list_pattern
-      format_settings: {  }
+      weight: 0
+      format_type: html_element
+      format_settings:
+        classes: ''
+        show_empty_fields: false
+        id: ''
+        element: div
+        show_label: false
+        label_element: h3
+        label_element_classes: ''
+        attributes: ''
+        effect: none
+        speed: fast
     group_website:
       children:
         - oe_project_website
@@ -99,14 +108,14 @@ content:
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 6
+    weight: 7
     region: content
   oe_cx_impacts:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 3
+    weight: 4
     region: content
   oe_cx_lead_contributors:
     type: entity_reference_revisions_entity_view
@@ -115,14 +124,14 @@ content:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 4
+    weight: 5
     region: content
   oe_cx_objective:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 2
+    weight: 3
     region: content
   oe_project_budget:
     type: number_decimal
@@ -169,7 +178,7 @@ content:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 5
+    weight: 6
     region: content
   oe_project_website:
     type: link
@@ -196,7 +205,7 @@ content:
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 1
+    weight: 2
     region: content
 hidden:
   body: true
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 41092f9e..119b0565 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -51,6 +51,7 @@ function oe_whitelabel_extra_project_preprocess_pattern_description_list(array &
 function oe_whitelabel_extra_project_preprocess_node__oe_project__full(array &$variables): void {
   _oe_whitelabel_extra_project_preprocess_inpage_nav($variables);
   _oe_whitelabel_extra_project_preprocess_status_and_progress($variables);
+  _oe_whitelabel_extra_project_preprocess_contributions($variables);
 }
 
 /**
@@ -222,3 +223,26 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
     ]),
   ];
 }
+
+/**
+ * Adds variables for the project contributions chart.
+ *
+ * @param array $variables
+ *   Variables from hook_preprocess_node().
+ */
+function _oe_whitelabel_extra_project_preprocess_contributions(array &$variables): void {
+  /** @var \Drupal\node\NodeInterface $node */
+  $node = $variables['node'];
+  /** @var \Drupal\Core\Field\Plugin\Field\FieldType\FloatItem|null $overall_budget_item */
+  $overall_budget = $node->get('oe_project_budget')->value;
+  /** @var \Drupal\Core\Field\Plugin\Field\FieldType\FloatItem|null $eu_budget_item */
+  $eu_budget = $node->get('oe_project_budget_eu')->value;
+  if ($overall_budget === NULL || !$eu_budget === NULL
+    || $overall_budget <= 0 || $eu_budget < 0
+    || $eu_budget > $overall_budget
+  ) {
+    // Missing field value, or values are not suitable for a chart.
+    return;
+  }
+  $variables['corporate_contributions'] = (int) round($eu_budget / $overall_budget * 10) * 10;
+}
diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 15bc26c8..59d21d18 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -22,6 +22,39 @@
     {{ attach_library('oe_whitelabel/project_status') }}
     {% include '@oe-bcl/project-status' with project_status_args only %}
   {% endif %}
+  {% if content.group_budget is not empty %}
+    {% set _contribution_legend_args = {
+      'variant': 'horizontal',
+      'items': content.group_budget|filter(
+        (item, key) => key|first != '#' and item|field_value is not empty
+      )|map((item, key) => {
+        'term': [{
+          'label': item|field_label,
+          'color': (corporate_contributions is defined) ? (key == 'oe_project_budget') ? "bg-gray-400" : "bg-primary",
+        }],
+        'definition': [{
+          'label': item|field_value,
+        }],
+      }),
+    } %}
+    {% if corporate_contributions is defined %}
+      {% include '@oe-bcl/project-status/project-contributions' with {
+        'corporate_contributions': corporate_contributions,
+        'chart': true,
+        'legend': _contribution_legend_args,
+      } only %}
+    {% else %}
+      {#
+        The contributions pie chart cannot be drawn, possibly because there is
+        only one budget field filled in.
+        Call the BCL component, not the pattern, because parameters already have
+        the required structure for BCL.
+      #}
+      {% include '@oe-bcl/description-list' with _contribution_legend_args|merge({
+        'attributes': create_attribute().addClass('border-bottom'),
+      }) only %}
+    {% endif %}
+  {% endif %}
   {{ content.group_project_details|filter((subgroup, key) => key|first != '#') }}
 {% endset %}
 
diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index 699e39cd..65340539 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -95,8 +95,8 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
         'value' => '2020-05-10',
         'end_value' => '2025-05-15',
       ],
-      'oe_project_budget' => '100',
-      'oe_project_budget_eu' => '100',
+      'oe_project_budget' => '200',
+      'oe_project_budget_eu' => '70',
       'oe_project_website' => [
         [
           'uri' => 'http://example.com',
@@ -168,6 +168,11 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
 
     $this->assertProjectStatusTimestampsAsDateStrings('2020-05-10 00:00:00', '2025-05-16 00:00:00');
 
+    $contributions_chart = $assert_session->elementExists('css', '.bcl-project-contributions .circular-progress');
+    // The correct value would be 35, but it is rounded up to 40, because no
+    // utility classes are available for smaller increments.
+    $this->assertSame('40', $contributions_chart->getAttribute('data-percentage'));
+
     // Select the description blocks inside the Project details.
     $description_lists = $project_content->findAll('css', '.grid-3-9');
     $this->assertCount(4, $description_lists);
@@ -179,11 +184,11 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
       'items' => [
         [
           'term' => 'Overall budget',
-          'definition' => '€100,00',
+          'definition' => '€200,00',
         ],
         [
           'term' => 'EU contribution',
-          'definition' => '€100,00',
+          'definition' => '€70,00',
         ],
       ],
     ], $description_lists[0]->getHtml());
-- 
GitLab


From 2fc150ef6748f71700546d16c95de58d94db4583 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 17:05:38 +0200
Subject: [PATCH 110/152] OEL-1371: Apply spaceless in project template.

---
 templates/content/node--oe-project--full.html.twig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 59d21d18..0f6fde7f 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -4,6 +4,8 @@
  * Project full display.
  */
 #}
+{% apply spaceless %}
+
 {% macro header(title, id) %}
   {% set attributes = id ? create_attribute({'id': id}) %}
   <h3 class="fw-bold mb-4 mt-4-5"{{ attributes }}>{{ title }}</h3>
@@ -96,3 +98,4 @@
   }) }}
 </div>
 
+{% endapply %}
-- 
GitLab


From 0aeaee8682d62f7352da587c6783dfc1045b8992 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 13:13:25 +0200
Subject: [PATCH 111/152] OEL-1371: Rename twig variable
 'inpage_navigation_fields' -> 'inpage_navigation_content'.

---
 templates/content/node--oe-project--full.html.twig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 0f6fde7f..74b02221 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -72,7 +72,7 @@
   }]|merge(inpage_navigation_links) %}
 {% endif %}
 
-{% set inpage_navigation_fields %}
+{% set inpage_navigation_content %}
   {#
     Reliably absorb top margin of first element.
     @todo Add a utility class 'eat-margin-top' with :before style.
@@ -93,7 +93,7 @@
   {{ pattern('inpage_navigation', {
     title: 'Page content'|t,
     links: inpage_navigation_links,
-    content: inpage_navigation_fields,
+    content: inpage_navigation_content,
     full_layout: true,
   }) }}
 </div>
-- 
GitLab


From 2ef64aff178517f6a0b599292626091dc0b56e99 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 13:14:00 +0200
Subject: [PATCH 112/152] OEL-1371: Twig array keys in quotes.

---
 .../content/node--oe-project--full.html.twig     |  8 ++++----
 ...de--oe-project--oe-w-content-banner.html.twig | 16 ++++++++--------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 74b02221..bc513e61 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -91,10 +91,10 @@
 
 <div class="mt-md-4-75 mt-4">
   {{ pattern('inpage_navigation', {
-    title: 'Page content'|t,
-    links: inpage_navigation_links,
-    content: inpage_navigation_content,
-    full_layout: true,
+    'title': 'Page content'|t,
+    'links': inpage_navigation_links,
+    'content': inpage_navigation_content,
+    'full_layout': true,
   }) }}
 </div>
 
diff --git a/templates/content/node--oe-project--oe-w-content-banner.html.twig b/templates/content/node--oe-project--oe-w-content-banner.html.twig
index 4c6d6341..a6b56ad4 100644
--- a/templates/content/node--oe-project--oe-w-content-banner.html.twig
+++ b/templates/content/node--oe-project--oe-w-content-banner.html.twig
@@ -5,13 +5,13 @@
  */
 #}
 {{ pattern('content_banner', {
-  background: 'gray',
-  title: label,
-  content: content.oe_teaser,
-  image: image,
-  attributes: create_attribute().addClass(['ps-0']),
-  badges: content.oe_subject ? content.oe_subject|field_value|default([])|map(_item => {
-    label: _item,
-    rounded_pill: true,
+  'background': 'gray',
+  'title': label,
+  'content': content.oe_teaser,
+  'image': image,
+  'attributes': create_attribute().addClass(['ps-0']),
+  'badges': content.oe_subject ? content.oe_subject|field_value|default([])|map(_item => {
+    'label': _item,
+    'rounded_pill': true,
   })|filter(_badge => _badge.label|drupal_escape|striptags|trim is not empty),
 }) }}
-- 
GitLab


From 2f2d8700ea6b756df9a2e3ba0c506d71c79e803d Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Mon, 25 Apr 2022 13:45:36 +0200
Subject: [PATCH 113/152] OEL-1371: Fix padding-bottom on description lists
 with border-bottom.

---
 .../oe_whitelabel_extra_project.module                           | 1 +
 1 file changed, 1 insertion(+)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 119b0565..7ee93e71 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -40,6 +40,7 @@ function oe_whitelabel_extra_project_preprocess_pattern_description_list(array &
         /** @var \Drupal\Core\Template\Attribute $attributes */
         $attributes = $variables['attributes'];
         $attributes->addClass('border-bottom');
+        $attributes->addClass('pb-3');
         break;
     }
   }
-- 
GitLab


From 5b447808fe42b3710a096665c6c6651dff1a10dc Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Tue, 26 Apr 2022 02:06:02 +0200
Subject: [PATCH 114/152] OEL-1371: Set up selenium.

---
 .drone.yml         | 10 ++++++++++
 docker-compose.yml | 20 ++++++++++++++++++++
 phpunit.xml.dist   |  1 +
 runner.yml.dist    |  8 ++++++++
 4 files changed, 39 insertions(+)

diff --git a/.drone.yml b/.drone.yml
index 105c3b95..bc123a89 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -29,6 +29,16 @@ services:
     environment:
       - SPARQL_UPDATE=true
       - DBA_PASSWORD=dba
+  selenium:
+    image: registry.fpfis.eu/fpfis/selenium:standalone-chrome-3.141.59-oxygen
+    environment:
+      - DISPLAY=:99
+      - SE_OPTS=-debug
+      - DISPLAY=:99
+      - SCREEN_WIDTH=1280
+      - SCREEN_HEIGHT=800
+      - NODE_MAX_INSTANCES=5
+      - NODE_MAX_SESSION=5
 
 pipeline:
   npm-build:
diff --git a/docker-compose.yml b/docker-compose.yml
index 6eb4b18e..1b7cab0b 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -23,6 +23,26 @@ services:
       MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
     # ports:
     #   - 3306:3306
+
+  # If you would like to see what is going on you can run the following on your host:
+  # docker run --rm -p 4444:4444 -p 5900:5900 --network="host" selenium/standalone-chrome-debug:latest
+  # Newer version of this image might run into this issue:
+  # @link https://github.com/elgalu/docker-selenium/issues/20
+  selenium:
+    image: selenium/standalone-chrome-debug:3.141.59-oxygen
+    environment:
+      - DISPLAY=:99
+      - SE_OPTS=-debug
+      - SCREEN_WIDTH=1280
+      - SCREEN_HEIGHT=800
+      - VNC_NO_PASSWORD=1
+    ports:
+      - '4444:4444'
+      - '5900:5900'
+    expose:
+      - '4444'
+    shm_size: 2g
+
   node:
     image: node:14.17.3
     user: "node"
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index f5e72617..efe43058 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -7,6 +7,7 @@
     <env name="SIMPLETEST_BASE_URL" value="${drupal.base_url}"/>
     <env name="SIMPLETEST_SPARQL_DB" value="sparql://${drupal.sparql.host}:${drupal.sparql.port}/?module=sparql_entity_storage"/>
     <env name="SIMPLETEST_DB" value="mysql://${drupal.database.user}:${drupal.database.password}@${drupal.database.host}:${drupal.database.port}/${drupal.database.name}"/>
+    <env name="MINK_DRIVER_ARGS_WEBDRIVER" value='["${selenium.browser}", null, "${selenium.host}:${selenium.port}/wd/hub"]'/>
   </php>
   <testsuites>
     <testsuite name="OpenEuropa Whitelabel Theme">
diff --git a/runner.yml.dist b/runner.yml.dist
index 738915c5..604f3809 100644
--- a/runner.yml.dist
+++ b/runner.yml.dist
@@ -51,6 +51,12 @@ drupal:
           port: ${drupal.sparql.port}
           namespace: 'Drupal\sparql_entity_storage\Driver\Database\sparql'
           driver: 'sparql'
+
+selenium:
+  host: "http://selenium"
+  port: "4444"
+  browser: "chrome"
+
 commands:
   drupal:site-setup:
     - { task: "run", command: "drupal:symlink-project" }
@@ -59,6 +65,8 @@ commands:
     - { task: "run", command: "setup:phpunit" }
   setup:phpunit:
     - { task: "process", source: "phpunit.xml.dist", destination: "phpunit.xml" }
+    # Generate settings.testing.php, it will be used when running functional tests.
+    - { task: "process-php", type: "write", config: "drupal.settings", source: "${drupal.root}/sites/default/default.settings.php", destination: "${drupal.root}/sites/default/settings.testing.php", override: true }
 
 release:
   tasks:
-- 
GitLab


From 50a5e3b776b1f42c426cf3d6cc39b1386581fc65 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Tue, 26 Apr 2022 02:15:31 +0200
Subject: [PATCH 115/152] OEL-1371: Test front-end javascript using
 WebDriverTestBase.

---
 .../Functional/ContentProjectRenderTest.php   | 41 ++++++++++++++++++-
 1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index 65340539..71216fa8 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -7,6 +7,7 @@ namespace Drupal\Tests\oe_whitelabel\Functional;
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\file\Entity\File;
+use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
 use Drupal\media\Entity\Media;
 use Drupal\node\NodeInterface;
 use Drupal\oe_content_entity\Entity\CorporateEntityInterface;
@@ -14,6 +15,7 @@ use Drupal\oe_content_entity_organisation\Entity\OrganisationInterface;
 use Drupal\Tests\oe_whitelabel\PatternAssertions\ContentBannerAssert;
 use Drupal\Tests\oe_whitelabel\PatternAssertions\DescriptionListAssert;
 use Drupal\Tests\oe_whitelabel\PatternAssertions\InPageNavigationAssert;
+use Drupal\Tests\sparql_entity_storage\Traits\SparqlConnectionTrait;
 use Drupal\Tests\TestFileCreationTrait;
 use Drupal\user\Entity\Role;
 use Drupal\user\RoleInterface;
@@ -21,10 +23,16 @@ use Drupal\user\RoleInterface;
 /**
  * Tests that our Project content type renders correctly.
  */
-class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
+class ContentProjectRenderTest extends WebDriverTestBase {
 
+  use SparqlConnectionTrait;
   use TestFileCreationTrait;
 
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'oe_whitelabel';
+
   /**
    * {@inheritdoc}
    */
@@ -38,6 +46,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
    */
   protected function setUp(): void {
     parent::setUp();
+    $this->setUpSparql();
 
     Role::load(RoleInterface::ANONYMOUS_ID)
       ->grantPermission('bypass node access')
@@ -167,6 +176,7 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     $project_content = $assert_session->elementExists('css', '.col-md-9');
 
     $this->assertProjectStatusTimestampsAsDateStrings('2020-05-10 00:00:00', '2025-05-16 00:00:00');
+    $this->waitProjectStatusReveal();
 
     $contributions_chart = $assert_session->elementExists('css', '.bcl-project-contributions .circular-progress');
     // The correct value would be 35, but it is rounded up to 40, because no
@@ -240,7 +250,6 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     ], $description_lists[3]->getHtml());
 
     // Set a project period that is fully in the past.
-    // @todo Enable web driver testing for javascript behavior.
     $this->setProjectDateRange($node, '2019-03-07', '2019-03-21');
     $node->save();
     $this->drupalGet($node->toUrl());
@@ -249,6 +258,11 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     $this->assertProjectStatus('bg-dark', 'Closed');
     $this->assertProjectProgress(100);
 
+    // Let javascript update the progress.
+    $this->waitProjectStatusReveal();
+    $this->assertProjectStatus('bg-dark', 'Closed');
+    $this->assertProjectProgress(100);
+
     // Set a project period that is ongoing.
     $this->setProjectDateRange($node, '-5 day', '+15 days');
     $node->save();
@@ -257,6 +271,11 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     $this->assertProjectStatus('bg-info', 'Ongoing');
     $this->assertProjectProgress(15, 35);
 
+    $this->waitProjectStatusReveal();
+
+    $this->assertProjectStatus('bg-info', 'Ongoing');
+    $this->assertProjectProgress(15, 35);
+
     // Set a project period that is fully in the future.
     $this->setProjectDateRange($node, '+5 days', '+12 days');
     $node->save();
@@ -264,6 +283,11 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
 
     $this->assertProjectStatus('bg-secondary', 'Planned');
     $this->assertProjectProgress(0);
+
+    $this->waitProjectStatusReveal();
+
+    $this->assertProjectStatus('bg-secondary', 'Planned');
+    $this->assertProjectProgress(0);
   }
 
   /**
@@ -361,6 +385,19 @@ class ContentProjectRenderTest extends WhitelabelBrowserTestBase {
     );
   }
 
+  /**
+   * Waits for the project status to be revealed by js.
+   */
+  protected function waitProjectStatusReveal(): void {
+    $status_section = $this->assertSession()->elementExists('css', '.bcl-project-status');
+    // Assert that the element starts hidden.
+    $this->assertTrue($status_section->hasClass('d-none'));
+    // Assert that the element is revealed through javascript.
+    $this->assertTrue($this->getSession()->wait(10000, "!jQuery('.bcl-project-status').hasClass('d-none')"));
+    // The following check is redundant, and is only added for transparency.
+    $this->assertFalse($status_section->hasClass('d-none'));
+  }
+
   /**
    * Asserts the state of the status badge and the color of the progress bar.
    *
-- 
GitLab


From e700a26ea3cb60497d1da0fc168f9842189a9aa7 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Tue, 26 Apr 2022 13:07:05 +0200
Subject: [PATCH 116/152] OEL-1371: Initial javascript already runs before
 first assertions, no need for wait().

---
 .../Functional/ContentProjectRenderTest.php   | 41 ++++++-------------
 1 file changed, 12 insertions(+), 29 deletions(-)

diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index 71216fa8..cfd17d05 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -176,7 +176,7 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     $project_content = $assert_session->elementExists('css', '.col-md-9');
 
     $this->assertProjectStatusTimestampsAsDateStrings('2020-05-10 00:00:00', '2025-05-16 00:00:00');
-    $this->waitProjectStatusReveal();
+    $this->assertProjectStatusRevealed();
 
     $contributions_chart = $assert_session->elementExists('css', '.bcl-project-contributions .circular-progress');
     // The correct value would be 35, but it is rounded up to 40, because no
@@ -255,11 +255,7 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     $this->drupalGet($node->toUrl());
 
     $this->assertProjectStatusTimestampsAsDateStrings('2019-03-07 00:00:00', '2019-03-22 00:00:00');
-    $this->assertProjectStatus('bg-dark', 'Closed');
-    $this->assertProjectProgress(100);
-
-    // Let javascript update the progress.
-    $this->waitProjectStatusReveal();
+    $this->assertProjectStatusRevealed();
     $this->assertProjectStatus('bg-dark', 'Closed');
     $this->assertProjectProgress(100);
 
@@ -268,11 +264,7 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     $node->save();
     $this->drupalGet($node->toUrl());
 
-    $this->assertProjectStatus('bg-info', 'Ongoing');
-    $this->assertProjectProgress(15, 35);
-
-    $this->waitProjectStatusReveal();
-
+    $this->assertProjectStatusRevealed();
     $this->assertProjectStatus('bg-info', 'Ongoing');
     $this->assertProjectProgress(15, 35);
 
@@ -281,11 +273,7 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     $node->save();
     $this->drupalGet($node->toUrl());
 
-    $this->assertProjectStatus('bg-secondary', 'Planned');
-    $this->assertProjectProgress(0);
-
-    $this->waitProjectStatusReveal();
-
+    $this->assertProjectStatusRevealed();
     $this->assertProjectStatus('bg-secondary', 'Planned');
     $this->assertProjectProgress(0);
   }
@@ -351,6 +339,14 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     $this->drupalGet($node->toUrl());
   }
 
+  /**
+   * Asserts that the d-none class has been removed from project status.
+   */
+  protected function assertProjectStatusRevealed(): void {
+    $status_section = $this->assertSession()->elementExists('css', '.bcl-project-status');
+    $this->assertFalse($status_section->hasClass('d-none'));
+  }
+
   /**
    * Asserts start and end timestamp in project status section.
    *
@@ -385,19 +381,6 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     );
   }
 
-  /**
-   * Waits for the project status to be revealed by js.
-   */
-  protected function waitProjectStatusReveal(): void {
-    $status_section = $this->assertSession()->elementExists('css', '.bcl-project-status');
-    // Assert that the element starts hidden.
-    $this->assertTrue($status_section->hasClass('d-none'));
-    // Assert that the element is revealed through javascript.
-    $this->assertTrue($this->getSession()->wait(10000, "!jQuery('.bcl-project-status').hasClass('d-none')"));
-    // The following check is redundant, and is only added for transparency.
-    $this->assertFalse($status_section->hasClass('d-none'));
-  }
-
   /**
    * Asserts the state of the status badge and the color of the progress bar.
    *
-- 
GitLab


From c0b87f7ab64110e2fe83b51264b1db9cadc92a96 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Tue, 26 Apr 2022 13:07:31 +0200
Subject: [PATCH 117/152] OEL-1371: Use getHtml(), because for some reason
 getText() returns empty string.

---
 tests/src/Functional/ContentProjectRenderTest.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/Functional/ContentProjectRenderTest.php
index cfd17d05..e51287a0 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/Functional/ContentProjectRenderTest.php
@@ -392,7 +392,7 @@ class ContentProjectRenderTest extends WebDriverTestBase {
   protected function assertProjectStatus(string $color_class, string $status_text): void {
     $status_badge = $this->assertSession()->elementExists('css', '.bcl-project-status .badge');
     $this->assertTrue($status_badge->hasClass($color_class));
-    $this->assertSame($status_text, $status_badge->getText());
+    $this->assertSame($status_text, $status_badge->getHtml());
     $progress_bar = $this->assertSession()->elementExists('css', '.bcl-project-status .progress-bar');
     $this->assertTrue($progress_bar->hasClass($color_class));
   }
-- 
GitLab


From a8d0891b6955462acd517a75505aabc86b463111 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Tue, 26 Apr 2022 13:02:43 +0200
Subject: [PATCH 118/152] OEL-1371: Insert placeholder values for non-js to
 make tests fail if js does not run.

---
 .../oe_whitelabel_extra_project.module          | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 7ee93e71..cf067d36 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -176,7 +176,6 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
   if ($date_range_item === NULL) {
     return;
   }
-  $status_keys = ['planned', 'ongoing', 'closed'];
   $status_labels = [t('Planned'), t('Ongoing'), t('Closed')];
 
   if (!$date_range_item->value || !$date_range_item->end_value) {
@@ -202,19 +201,21 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
     return;
   }
 
-  $t_now = \Drupal::time()->getCurrentTime();
-  $status_id = ($t_now > $t_start) + ($t_now > $t_end);
-  $progress_01 = max(0, min(1, ($t_now - $t_start) / ($t_end - $t_start)));
+  // Values for the 'bcl-project-status' component.
+  // Some values contain placeholders that will be updated with javascript.
+  // This makes sure that tests will fail if js does not run.
   $variables['project_status_args'] = [
-    'status' => $status_keys[$status_id],
+    // Placeholder value.
+    'status' => 'ongoing',
     'start_date' => $date_range_item->value,
     'start_label' => t('Start'),
     'end_date' => $date_range_item->end_value,
     'end_label' => t('End'),
     'label' => t('Status'),
-    'badge' => $status_labels[$status_id],
-    // Steps of 0.5 are smaller than a pixel, without too many decimals.
-    'progress' => round($progress_01 * 200) / 2,
+    // Placeholder value.
+    'badge' => '?',
+    // Placeholder value.
+    'progress' => 5,
     'attributes' => new Attribute([
       'data-start-timestamp' => $t_start,
       'data-end-timestamp' => $t_end,
-- 
GitLab


From 3a8d32ecdeef1297612bdeba07f8b230825e796c Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 12:28:38 +0200
Subject: [PATCH 119/152] OEL-1371: Use <article> wrapper, and don't add
 margin-top.

---
 templates/content/node--oe-project--full.html.twig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index bc513e61..646a75ae 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -89,13 +89,13 @@
   {% endblock %}
 {% endset %}
 
-<div class="mt-md-4-75 mt-4">
+<article{{ attributes }}>
   {{ pattern('inpage_navigation', {
     'title': 'Page content'|t,
     'links': inpage_navigation_links,
     'content': inpage_navigation_content,
     'full_layout': true,
   }) }}
-</div>
+</article>
 
 {% endapply %}
-- 
GitLab


From 2c77553e6b800df66106b00d172fe8a3141d8e25 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 12:30:39 +0200
Subject: [PATCH 120/152] OEL-1371: Don't link the funding programme.

---
 .../install/core.entity_view_display.node.oe_project.full.yml   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
index b2aadc3d..adec918a 100644
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
@@ -167,7 +167,7 @@ content:
     type: skos_concept_entity_reference_label
     label: hidden
     settings:
-      link: true
+      link: false
     third_party_settings: {  }
     weight: 4
     region: content
-- 
GitLab


From 612c282780d9d0e5f482d6f651b85ab7cef48c39 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 12:51:54 +0200
Subject: [PATCH 121/152] OEL-1371: Add function docs in javascript.

---
 resources/js/oe_whitelabel.project_status.js | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/resources/js/oe_whitelabel.project_status.js b/resources/js/oe_whitelabel.project_status.js
index 87c66e8a..9b952e0d 100644
--- a/resources/js/oe_whitelabel.project_status.js
+++ b/resources/js/oe_whitelabel.project_status.js
@@ -11,6 +11,8 @@
   ];
 
   /**
+   * Passes an updated status value to a function at given timestamps.
+   *
    * @param {int} msBegin
    *   Start timestamp in milliseconds.
    * @param {int} msEnd
@@ -35,6 +37,8 @@
   }
 
   /**
+   * Passes an updated progress value to a function at a series of timestamps.
+   *
    * @param {int} msBegin
    *   Start timestamp in milliseconds.
    * @param {int} msEnd
-- 
GitLab


From f534e55df7143f7615773b07080e3f554825a93a Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 13:19:01 +0200
Subject: [PATCH 122/152] OEL-1371: Add @todo note because setInterval() only
 works for up to 10 years duration.

---
 resources/js/oe_whitelabel.project_status.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/resources/js/oe_whitelabel.project_status.js b/resources/js/oe_whitelabel.project_status.js
index 9b952e0d..3ed12dc7 100644
--- a/resources/js/oe_whitelabel.project_status.js
+++ b/resources/js/oe_whitelabel.project_status.js
@@ -21,6 +21,7 @@
    *   Callback to set the status: 0 = planned, 1 = ongoing, 2 = closed.
    */
   function animateStatus(msBegin, msEnd, setStatus) {
+    // @todo setTimeout() only works properly for durations up to ~10 years.
     const msNow = Date.now();
     if (msNow < msBegin) {
       setStatus(0);
@@ -63,6 +64,7 @@
     const msIntervalDelay = msBegin - msNow + Math.max(0, tickNext) * msTick;
 
     // Register a repeated interval.
+    // @todo setTimeout() only works properly for durations up to ~10 years.
     window.setTimeout(function () {
       let tick = Math.max(0, tickNext);
       setProgress(tick);
-- 
GitLab


From e9250b62eef5fbd8e7cfbf76524e0599a13aa84e Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 13:21:53 +0200
Subject: [PATCH 123/152] OEL-1371: Use const for msBegin / msEnd.

---
 resources/js/oe_whitelabel.project_status.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/resources/js/oe_whitelabel.project_status.js b/resources/js/oe_whitelabel.project_status.js
index 3ed12dc7..0b3b0520 100644
--- a/resources/js/oe_whitelabel.project_status.js
+++ b/resources/js/oe_whitelabel.project_status.js
@@ -97,8 +97,8 @@
     attach: function (context) {
       $('.bcl-project-status', context).once('bcl-project-status').each(function () {
         const $element = $(this);
-        let msBegin = $element.data('start-timestamp') * 1000;
-        let msEnd = $element.data('end-timestamp') * 1000;
+        const msBegin = $element.data('start-timestamp') * 1000;
+        const msEnd = $element.data('end-timestamp') * 1000;
         const statusLabels = $element.data('status-labels').split('|');
 
         // Process the status label.
-- 
GitLab


From c95c39c89271e2bc1a33b971563f2055ebc21826 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 13:55:19 +0200
Subject: [PATCH 124/152] OEL-1371: Don't animate the js.

---
 resources/js/oe_whitelabel.project_status.js | 107 +++----------------
 1 file changed, 14 insertions(+), 93 deletions(-)

diff --git a/resources/js/oe_whitelabel.project_status.js b/resources/js/oe_whitelabel.project_status.js
index 0b3b0520..5e70180a 100644
--- a/resources/js/oe_whitelabel.project_status.js
+++ b/resources/js/oe_whitelabel.project_status.js
@@ -10,81 +10,6 @@
     'bg-dark',
   ];
 
-  /**
-   * Passes an updated status value to a function at given timestamps.
-   *
-   * @param {int} msBegin
-   *   Start timestamp in milliseconds.
-   * @param {int} msEnd
-   *   End timestamp in milliseconds.
-   * @param {function(0|1|2)} setStatus
-   *   Callback to set the status: 0 = planned, 1 = ongoing, 2 = closed.
-   */
-  function animateStatus(msBegin, msEnd, setStatus) {
-    // @todo setTimeout() only works properly for durations up to ~10 years.
-    const msNow = Date.now();
-    if (msNow < msBegin) {
-      setStatus(0);
-      window.setTimeout(setStatus, msBegin - msNow, 1);
-      window.setTimeout(setStatus, msEnd - msNow, 2);
-    }
-    else if (msNow < msEnd) {
-      setStatus(1);
-      window.setTimeout(setStatus, msEnd - msNow, 2);
-    }
-    else {
-      setStatus(2);
-    }
-  }
-
-  /**
-   * Passes an updated progress value to a function at a series of timestamps.
-   *
-   * @param {int} msBegin
-   *   Start timestamp in milliseconds.
-   * @param {int} msEnd
-   *   End timestamp in milliseconds.
-   * @param {int} nTicks
-   *   Number of sub-intervals.
-   * @param {function(int)} setProgress
-   *   Callback to be called on each tick.
-   *   The parameter is a value within the [0..nTicks] interval.
-   */
-  function animateProgress(msBegin, msEnd, nTicks, setProgress) {
-    const msNow = Date.now();
-    const msTick = (msEnd - msBegin) / nTicks;
-    const tickNext = Math.ceil((msNow - msBegin) / msTick);
-
-    if (tickNext >= nTicks) {
-      setProgress(nTicks);
-      return;
-    }
-
-    // Compute a delay for the start of the interval.
-    const msIntervalDelay = msBegin - msNow + Math.max(0, tickNext) * msTick;
-
-    // Register a repeated interval.
-    // @todo setTimeout() only works properly for durations up to ~10 years.
-    window.setTimeout(function () {
-      let tick = Math.max(0, tickNext);
-      setProgress(tick);
-      if (tick >= nTicks) {
-        return;
-      }
-      ++tick;
-      const intervalId = window.setInterval(function () {
-        setProgress(tick);
-        if (tick >= nTicks) {
-          clearInterval(intervalId);
-        }
-        ++tick;
-      }, msTick);
-    }, msIntervalDelay);
-
-    // Set initial progress.
-    setProgress(Math.max(0, tickNext - 1));
-  }
-
   /**
    * Animates the project status badge and progress bar.
    *
@@ -100,36 +25,32 @@
         const msBegin = $element.data('start-timestamp') * 1000;
         const msEnd = $element.data('end-timestamp') * 1000;
         const statusLabels = $element.data('status-labels').split('|');
+        const msNow = Date.now();
+        const status = (msNow >= msBegin) + (msNow > msEnd);
+        const progress01 = Math.max(0, Math.min(1, (msNow - msBegin) / (msEnd - msBegin)));
+        const percent = Math.round(progress01 * 200) / 2;
 
         // Process the status label.
         $('.badge', this).each(function () {
           const $element = $(this);
-          animateStatus(msBegin, msEnd, function (status) {
-            $element.removeClass(colorClasses);
-            $element.addClass(colorClasses[status]);
-            if (statusLabels) {
-              $element.html(statusLabels[status]);
-            }
-          });
+          $element.removeClass(colorClasses);
+          $element.addClass(colorClasses[status]);
+          if (statusLabels) {
+            $element.html(statusLabels[status]);
+          }
         });
 
         // Process the progress bar.
         $('.progress-bar', this).each(function () {
           const $element = $(this);
-          animateStatus(msBegin, msEnd, function (status) {
-            $element.removeClass(colorClasses);
-            $element.addClass(colorClasses[status]);
-          });
+          $element.removeClass(colorClasses);
+          $element.addClass(colorClasses[status]);
           // Disable css transition.
           // It looks bad for the initial setting, and afterwards it does not help.
           $element.css('transition', false);
-          const factor = 2;
-          animateProgress(msBegin, msEnd, factor * 100, function (tick) {
-            const percent = tick / factor;
-            $element.css('width', percent + '%');
-            $element.attr('aria-valuenow', percent);
-            $element.attr('aria-label', percent);
-          });
+          $element.css('width', percent + '%');
+          $element.attr('aria-valuenow', percent);
+          $element.attr('aria-label', percent);
         });
 
         // Reveal the entire section.
-- 
GitLab


From 967cda81574445749fa9a6ab50642cb1d82ad6d1 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 14:36:08 +0200
Subject: [PATCH 125/152] OEL-1371: Use formatted dates.

---
 ...tity_view_display.node.oe_project.full.yml | 28 +++++++++++++------
 .../oe_whitelabel_extra_project.module        | 20 +++++++++++--
 2 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
index adec918a..8088900d 100644
--- a/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
+++ b/modules/oe_whitelabel_extra_project/config/install/core.entity_view_display.node.oe_project.full.yml
@@ -30,6 +30,7 @@ dependencies:
     - field.field.node.oe_project.oe_teaser
     - node.type.oe_project
   module:
+    - datetime_range
     - entity_reference_revisions
     - field_group
     - link
@@ -45,7 +46,7 @@ third_party_settings:
       label: 'Project details'
       parent_name: ''
       region: content
-      weight: 1
+      weight: 2
       format_type: html_element
       format_settings:
         classes: ''
@@ -74,7 +75,7 @@ third_party_settings:
       label: Budget
       parent_name: ''
       region: content
-      weight: 0
+      weight: 1
       format_type: html_element
       format_settings:
         classes: ''
@@ -108,14 +109,14 @@ content:
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 7
+    weight: 8
     region: content
   oe_cx_impacts:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 4
+    weight: 5
     region: content
   oe_cx_lead_contributors:
     type: entity_reference_revisions_entity_view
@@ -124,14 +125,14 @@ content:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 5
+    weight: 6
     region: content
   oe_cx_objective:
     type: text_default
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 3
+    weight: 4
     region: content
   oe_project_budget:
     type: number_decimal
@@ -163,6 +164,16 @@ content:
     third_party_settings: {  }
     weight: 4
     region: content
+  oe_project_dates:
+    type: daterange_default
+    label: hidden
+    settings:
+      timezone_override: ''
+      format_type: oe_whitelabel_project_date
+      separator: '-'
+    third_party_settings: {  }
+    weight: 0
+    region: content
   oe_project_funding_programme:
     type: skos_concept_entity_reference_label
     label: hidden
@@ -178,7 +189,7 @@ content:
       view_mode: default
       link: ''
     third_party_settings: {  }
-    weight: 6
+    weight: 7
     region: content
   oe_project_website:
     type: link
@@ -205,7 +216,7 @@ content:
     label: hidden
     settings: {  }
     third_party_settings: {  }
-    weight: 2
+    weight: 3
     region: content
 hidden:
   body: true
@@ -221,7 +232,6 @@ hidden:
   oe_featured_media: true
   oe_project_calls: true
   oe_project_contact: true
-  oe_project_dates: true
   oe_project_locations: true
   oe_project_result_files: true
   oe_project_results: true
diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index cf067d36..40c09445 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -201,15 +201,31 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
     return;
   }
 
+  // Use the formatted field values for start / end date.
+  $element = $variables['elements']['oe_project_dates'][0];
+  if ($element['#theme'] ?? NULL === 'time') {
+    // Project lasts a single day.
+    $start_date_element = $element;
+    $end_date_element = $element;
+  }
+  elseif (isset($element['start_date']['#theme'], $element['end_date']['#theme'])) {
+    // Project lasts multiple days.
+    $start_date_element = $element['start_date'];
+    $end_date_element = $element['end_date'];
+  }
+  else {
+    return;
+  }
+
   // Values for the 'bcl-project-status' component.
   // Some values contain placeholders that will be updated with javascript.
   // This makes sure that tests will fail if js does not run.
   $variables['project_status_args'] = [
     // Placeholder value.
     'status' => 'ongoing',
-    'start_date' => $date_range_item->value,
+    'start_date' => $start_date_element,
     'start_label' => t('Start'),
-    'end_date' => $date_range_item->end_value,
+    'end_date' => $end_date_element,
     'end_label' => t('End'),
     'label' => t('Status'),
     // Placeholder value.
-- 
GitLab


From a93cdebee0bd401ddfc080c5fe64640c5e1ec67e Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 14:47:27 +0200
Subject: [PATCH 126/152] OEL-1371: Remove a wrong negation -> hide pie chart
 if eu budget is NULL.

---
 .../oe_whitelabel_extra_project.module                          | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 40c09445..74751c03 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -255,7 +255,7 @@ function _oe_whitelabel_extra_project_preprocess_contributions(array &$variables
   $overall_budget = $node->get('oe_project_budget')->value;
   /** @var \Drupal\Core\Field\Plugin\Field\FieldType\FloatItem|null $eu_budget_item */
   $eu_budget = $node->get('oe_project_budget_eu')->value;
-  if ($overall_budget === NULL || !$eu_budget === NULL
+  if ($overall_budget === NULL || $eu_budget === NULL
     || $overall_budget <= 0 || $eu_budget < 0
     || $eu_budget > $overall_budget
   ) {
-- 
GitLab


From e9992bb28c5773d7885de27b9cd3ac9995d05c44 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 15:15:42 +0200
Subject: [PATCH 127/152] OEL-1371: Simplify project contributions, relying
 fully on BCL component.

---
 .../oe_whitelabel_extra_project.module        | 52 +++++++++++++++++--
 .../content/node--oe-project--full.html.twig  | 34 +-----------
 2 files changed, 49 insertions(+), 37 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 74751c03..b145c8a2 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -249,18 +249,60 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
  *   Variables from hook_preprocess_node().
  */
 function _oe_whitelabel_extra_project_preprocess_contributions(array &$variables): void {
+  $legend_items = [];
+  foreach ([
+    'oe_project_budget' => 'bg-gray-400',
+    'oe_project_budget_eu' => 'bg-primary',
+  ] as $field_name => $bg_class) {
+    $field_element = $variables['elements'][$field_name] ?? NULL;
+    if (!isset($field_element[0])) {
+      continue;
+    }
+    $legend_items[] = [
+      'term' => [
+        [
+          'label' => $field_element['#title'],
+          'color' => $bg_class,
+        ],
+      ],
+      'definition' => [
+        [
+          // Render only the field value, without field wrappers.
+          'label' => $field_element[0],
+        ],
+      ],
+    ];
+  }
+
+  if (!$legend_items) {
+    return;
+  }
+
+  $variables['contributions_args'] = [
+    'corporate_contributions' => NULL,
+    'chart' => FALSE,
+    'legend' => [
+      'variant' => 'horizontal',
+      'items' => $legend_items,
+    ],
+  ];
+
   /** @var \Drupal\node\NodeInterface $node */
   $node = $variables['node'];
-  /** @var \Drupal\Core\Field\Plugin\Field\FieldType\FloatItem|null $overall_budget_item */
   $overall_budget = $node->get('oe_project_budget')->value;
-  /** @var \Drupal\Core\Field\Plugin\Field\FieldType\FloatItem|null $eu_budget_item */
   $eu_budget = $node->get('oe_project_budget_eu')->value;
+
   if ($overall_budget === NULL || $eu_budget === NULL
     || $overall_budget <= 0 || $eu_budget < 0
-    || $eu_budget > $overall_budget
+    || $overall_budget < $eu_budget
   ) {
-    // Missing field value, or values are not suitable for a chart.
+    // No pie chart can be drawn with these values.
     return;
   }
-  $variables['corporate_contributions'] = (int) round($eu_budget / $overall_budget * 10) * 10;
+
+  $ratio_01 = max(0, min(1, $eu_budget / $overall_budget));
+  $percent = (int) round($ratio_01 * 10) * 10;
+
+  $variables['contributions_args']['corporate_contributions'] = $percent;
+  $variables['contributions_args']['chart'] = TRUE;
 }
diff --git a/templates/content/node--oe-project--full.html.twig b/templates/content/node--oe-project--full.html.twig
index 646a75ae..5a9999f9 100644
--- a/templates/content/node--oe-project--full.html.twig
+++ b/templates/content/node--oe-project--full.html.twig
@@ -24,38 +24,8 @@
     {{ attach_library('oe_whitelabel/project_status') }}
     {% include '@oe-bcl/project-status' with project_status_args only %}
   {% endif %}
-  {% if content.group_budget is not empty %}
-    {% set _contribution_legend_args = {
-      'variant': 'horizontal',
-      'items': content.group_budget|filter(
-        (item, key) => key|first != '#' and item|field_value is not empty
-      )|map((item, key) => {
-        'term': [{
-          'label': item|field_label,
-          'color': (corporate_contributions is defined) ? (key == 'oe_project_budget') ? "bg-gray-400" : "bg-primary",
-        }],
-        'definition': [{
-          'label': item|field_value,
-        }],
-      }),
-    } %}
-    {% if corporate_contributions is defined %}
-      {% include '@oe-bcl/project-status/project-contributions' with {
-        'corporate_contributions': corporate_contributions,
-        'chart': true,
-        'legend': _contribution_legend_args,
-      } only %}
-    {% else %}
-      {#
-        The contributions pie chart cannot be drawn, possibly because there is
-        only one budget field filled in.
-        Call the BCL component, not the pattern, because parameters already have
-        the required structure for BCL.
-      #}
-      {% include '@oe-bcl/description-list' with _contribution_legend_args|merge({
-        'attributes': create_attribute().addClass('border-bottom'),
-      }) only %}
-    {% endif %}
+  {% if contributions_args is defined %}
+    {% include '@oe-bcl/project-status/project-contributions' with contributions_args only %}
   {% endif %}
   {{ content.group_project_details|filter((subgroup, key) => key|first != '#') }}
 {% endset %}
-- 
GitLab


From 8d3cb57fb8fe4e27b687d0f327b6ed881de3c078 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 15:20:38 +0200
Subject: [PATCH 128/152] OEL-1371: Move the js test into
 'FunctionalJavascript' namespace.

---
 .../ContentProjectRenderTest.php                                | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename tests/src/{Functional => FunctionalJavascript}/ContentProjectRenderTest.php (99%)

diff --git a/tests/src/Functional/ContentProjectRenderTest.php b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
similarity index 99%
rename from tests/src/Functional/ContentProjectRenderTest.php
rename to tests/src/FunctionalJavascript/ContentProjectRenderTest.php
index e51287a0..3eee2ff2 100644
--- a/tests/src/Functional/ContentProjectRenderTest.php
+++ b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
@@ -2,7 +2,7 @@
 
 declare(strict_types = 1);
 
-namespace Drupal\Tests\oe_whitelabel\Functional;
+namespace Drupal\Tests\oe_whitelabel\FunctionalJavascript;
 
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Entity\EntityStorageInterface;
-- 
GitLab


From fefd8bc762d14fc86278885bfff3d6e074a6a7ac Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 15:22:46 +0200
Subject: [PATCH 129/152] OEL-1371: Don't save and refresh inside
 setProjectDateRange().

---
 tests/src/FunctionalJavascript/ContentProjectRenderTest.php | 2 --
 1 file changed, 2 deletions(-)

diff --git a/tests/src/FunctionalJavascript/ContentProjectRenderTest.php b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
index 3eee2ff2..580081dd 100644
--- a/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
+++ b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
@@ -335,8 +335,6 @@ class ContentProjectRenderTest extends WebDriverTestBase {
       'value' => (new DrupalDateTime($begin, 'Europe/Brussels'))->format('Y-m-d'),
       'end_value' => (new DrupalDateTime($end, 'Europe/Brussels'))->format('Y-m-d'),
     ];
-    $node->save();
-    $this->drupalGet($node->toUrl());
   }
 
   /**
-- 
GitLab


From 641598545bb9a1aa02783b7333a16188c0930495 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 15:23:18 +0200
Subject: [PATCH 130/152] OEL-1371: Rename assertion method ->
 assertProjectStatusVisible().

---
 .../FunctionalJavascript/ContentProjectRenderTest.php  | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tests/src/FunctionalJavascript/ContentProjectRenderTest.php b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
index 580081dd..49718a5b 100644
--- a/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
+++ b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
@@ -176,7 +176,7 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     $project_content = $assert_session->elementExists('css', '.col-md-9');
 
     $this->assertProjectStatusTimestampsAsDateStrings('2020-05-10 00:00:00', '2025-05-16 00:00:00');
-    $this->assertProjectStatusRevealed();
+    $this->assertProjectStatusVisible();
 
     $contributions_chart = $assert_session->elementExists('css', '.bcl-project-contributions .circular-progress');
     // The correct value would be 35, but it is rounded up to 40, because no
@@ -255,7 +255,7 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     $this->drupalGet($node->toUrl());
 
     $this->assertProjectStatusTimestampsAsDateStrings('2019-03-07 00:00:00', '2019-03-22 00:00:00');
-    $this->assertProjectStatusRevealed();
+    $this->assertProjectStatusVisible();
     $this->assertProjectStatus('bg-dark', 'Closed');
     $this->assertProjectProgress(100);
 
@@ -264,7 +264,7 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     $node->save();
     $this->drupalGet($node->toUrl());
 
-    $this->assertProjectStatusRevealed();
+    $this->assertProjectStatusVisible();
     $this->assertProjectStatus('bg-info', 'Ongoing');
     $this->assertProjectProgress(15, 35);
 
@@ -273,7 +273,7 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     $node->save();
     $this->drupalGet($node->toUrl());
 
-    $this->assertProjectStatusRevealed();
+    $this->assertProjectStatusVisible();
     $this->assertProjectStatus('bg-secondary', 'Planned');
     $this->assertProjectProgress(0);
   }
@@ -340,7 +340,7 @@ class ContentProjectRenderTest extends WebDriverTestBase {
   /**
    * Asserts that the d-none class has been removed from project status.
    */
-  protected function assertProjectStatusRevealed(): void {
+  protected function assertProjectStatusVisible(): void {
     $status_section = $this->assertSession()->elementExists('css', '.bcl-project-status');
     $this->assertFalse($status_section->hasClass('d-none'));
   }
-- 
GitLab


From 0ff1731c85e23bc4f2c9eff3c58451abedf0f326 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 15:36:40 +0200
Subject: [PATCH 131/152] OEL-1371: Attempt to make chained twig filters more
 readable.

---
 .../node--oe-project--oe-w-content-banner.html.twig  | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/templates/content/node--oe-project--oe-w-content-banner.html.twig b/templates/content/node--oe-project--oe-w-content-banner.html.twig
index a6b56ad4..b5bd4030 100644
--- a/templates/content/node--oe-project--oe-w-content-banner.html.twig
+++ b/templates/content/node--oe-project--oe-w-content-banner.html.twig
@@ -10,8 +10,12 @@
   'content': content.oe_teaser,
   'image': image,
   'attributes': create_attribute().addClass(['ps-0']),
-  'badges': content.oe_subject ? content.oe_subject|field_value|default([])|map(_item => {
-    'label': _item,
-    'rounded_pill': true,
-  })|filter(_badge => _badge.label|drupal_escape|striptags|trim is not empty),
+  'badges': content.oe_subject ? (content.oe_subject
+    |field_value|default([])
+    |filter(_item => _item|drupal_escape|striptags|trim is not empty)
+    |map(_item => {
+      'label': _item,
+      'rounded_pill': true,
+    })
+  ),
 }) }}
-- 
GitLab


From 567764dc222042b00213830fa43e8aeca441cca4 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 15:42:39 +0200
Subject: [PATCH 132/152] OEL-1371: The ternary expression for badges is not
 needed.

---
 .../content/node--oe-project--oe-w-content-banner.html.twig  | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/templates/content/node--oe-project--oe-w-content-banner.html.twig b/templates/content/node--oe-project--oe-w-content-banner.html.twig
index b5bd4030..f5c8aeb9 100644
--- a/templates/content/node--oe-project--oe-w-content-banner.html.twig
+++ b/templates/content/node--oe-project--oe-w-content-banner.html.twig
@@ -10,12 +10,11 @@
   'content': content.oe_teaser,
   'image': image,
   'attributes': create_attribute().addClass(['ps-0']),
-  'badges': content.oe_subject ? (content.oe_subject
+  'badges': content.oe_subject
     |field_value|default([])
     |filter(_item => _item|drupal_escape|striptags|trim is not empty)
     |map(_item => {
       'label': _item,
       'rounded_pill': true,
-    })
-  ),
+    }),
 }) }}
-- 
GitLab


From 8c7d7102c3176213f9b8e548bd02c54105acedc5 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 15:44:29 +0200
Subject: [PATCH 133/152] OEL-1371: Add quotes for start/end in comment.

---
 tests/src/FunctionalJavascript/ContentProjectRenderTest.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/src/FunctionalJavascript/ContentProjectRenderTest.php b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
index 49718a5b..4c8cdc14 100644
--- a/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
+++ b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
@@ -346,7 +346,7 @@ class ContentProjectRenderTest extends WebDriverTestBase {
   }
 
   /**
-   * Asserts start and end timestamp in project status section.
+   * Asserts 'start' and 'end' timestamp in project status section.
    *
    * @param string $begin
    *   Expected start date string as 'Y-m-d H:i:s'.
-- 
GitLab


From da39123108719cf5e45671724bec8a4be0292a87 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 15:54:29 +0200
Subject: [PATCH 134/152] OEL-1371: Move variable initialization, and merge
 ifs.

---
 .../oe_whitelabel_extra_project.module                   | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index b145c8a2..2878af9d 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -173,12 +173,7 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
   $node = $variables['node'];
   /** @var \Drupal\datetime_range\Plugin\Field\FieldType\DateRangeItem|null $date_range_item */
   $date_range_item = $node->get('oe_project_dates')->first();
-  if ($date_range_item === NULL) {
-    return;
-  }
-  $status_labels = [t('Planned'), t('Ongoing'), t('Closed')];
-
-  if (!$date_range_item->value || !$date_range_item->end_value) {
+  if ($date_range_item === NULL || !$date_range_item->value || !$date_range_item->end_value) {
     // One of the fields is empty.
     return;
   }
@@ -217,6 +212,8 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
     return;
   }
 
+  $status_labels = [t('Planned'), t('Ongoing'), t('Closed')];
+
   // Values for the 'bcl-project-status' component.
   // Some values contain placeholders that will be updated with javascript.
   // This makes sure that tests will fail if js does not run.
-- 
GitLab


From 3919738e178ebaca62a171fdae526247607335ce Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 16:10:50 +0200
Subject: [PATCH 135/152] OEL-1371: Restore server-side calculation of status
 and progress.

---
 .../oe_whitelabel_extra_project.module          | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 2878af9d..9a419ef9 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -212,23 +212,24 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
     return;
   }
 
+  $status_keys = ['planned', 'ongoing', 'closed'];
   $status_labels = [t('Planned'), t('Ongoing'), t('Closed')];
 
+  $t_now = \Drupal::time()->getCurrentTime();
+  $status_id = ($t_now > $t_start) + ($t_now > $t_end);
+  $progress_01 = max(0, min(1, ($t_now - $t_start) / ($t_end - $t_start)));
+
   // Values for the 'bcl-project-status' component.
-  // Some values contain placeholders that will be updated with javascript.
-  // This makes sure that tests will fail if js does not run.
   $variables['project_status_args'] = [
-    // Placeholder value.
-    'status' => 'ongoing',
+    'status' => $status_keys[$status_id],
     'start_date' => $start_date_element,
     'start_label' => t('Start'),
     'end_date' => $end_date_element,
     'end_label' => t('End'),
     'label' => t('Status'),
-    // Placeholder value.
-    'badge' => '?',
-    // Placeholder value.
-    'progress' => 5,
+    'badge' => $status_labels[$status_id],
+    // Steps of 0.5 are smaller than a pixel, without too many decimals.
+    'progress' => round($progress_01 * 200) / 2,
     'attributes' => new Attribute([
       'data-start-timestamp' => $t_start,
       'data-end-timestamp' => $t_end,
-- 
GitLab


From 8b30df30d7c480f4ac11cec00e06c8c753888990 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Wed, 27 Apr 2022 17:14:25 +0200
Subject: [PATCH 136/152] OEL-1371: Use datetime_testing to make tests fail
 with js disabled.

---
 composer.json                                 |  1 +
 .../ContentProjectRenderTest.php              | 22 +++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/composer.json b/composer.json
index 0bf85068..b6633438 100644
--- a/composer.json
+++ b/composer.json
@@ -21,6 +21,7 @@
         "drupal/core-composer-scaffold": "^9.2",
         "drupal/core-dev": "^9.2",
         "drupal/ctools": "^3.7",
+        "drupal/datetime_testing": "^1.0@beta",
         "drupal/description_list_field": "^1.0@alpha",
         "drupal/drupal-extension": "~4.1",
         "drupal/entity_reference_revisions": "^1.9",
diff --git a/tests/src/FunctionalJavascript/ContentProjectRenderTest.php b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
index 4c8cdc14..9f74c514 100644
--- a/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
+++ b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
@@ -6,6 +6,7 @@ namespace Drupal\Tests\oe_whitelabel\FunctionalJavascript;
 
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\datetime_testing\TestTimeInterface;
 use Drupal\file\Entity\File;
 use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
 use Drupal\media\Entity\Media;
@@ -38,6 +39,7 @@ class ContentProjectRenderTest extends WebDriverTestBase {
    */
   public static $modules = [
     'block',
+    'datetime_testing',
     'oe_whitelabel_extra_project',
   ];
 
@@ -252,6 +254,8 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     // Set a project period that is fully in the past.
     $this->setProjectDateRange($node, '2019-03-07', '2019-03-21');
     $node->save();
+    // Manipulate the server time to a date even further in the past.
+    $this->getTestTimeObject()->setTime('2017-01-01');
     $this->drupalGet($node->toUrl());
 
     $this->assertProjectStatusTimestampsAsDateStrings('2019-03-07 00:00:00', '2019-03-22 00:00:00');
@@ -262,6 +266,8 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     // Set a project period that is ongoing.
     $this->setProjectDateRange($node, '-5 day', '+15 days');
     $node->save();
+    // Manipulate the server time to a date far in the past.
+    $this->getTestTimeObject()->setTime('2017-01-01');
     $this->drupalGet($node->toUrl());
 
     $this->assertProjectStatusVisible();
@@ -271,6 +277,8 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     // Set a project period that is fully in the future.
     $this->setProjectDateRange($node, '+5 days', '+12 days');
     $node->save();
+    // Manipulate the server time to a date further in the future.
+    $this->getTestTimeObject()->setTime('+40 days');
     $this->drupalGet($node->toUrl());
 
     $this->assertProjectStatusVisible();
@@ -416,4 +424,18 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     }
   }
 
+  /**
+   * Gets the overridden time object to manipulate time.
+   *
+   * This is in a custom method for better static analysis.
+   *
+   * @return \Drupal\datetime_testing\TestTimeInterface
+   *   Overridden time object.
+   */
+  protected function getTestTimeObject(): TestTimeInterface {
+    $time = \Drupal::time();
+    $this->assertInstanceOf(TestTimeInterface::class, $time);
+    return $time;
+  }
+
 }
-- 
GitLab


From eef9c79a510025961d7367547a1c96d2fe2eb358 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Thu, 28 Apr 2022 14:12:19 +0200
Subject: [PATCH 137/152] OEL-1371: Explain and enhance defensive code in
 preprocess.

---
 .../oe_whitelabel_extra_project.module                       | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 9a419ef9..c98b07f1 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -192,12 +192,12 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
   $t_end = $get_timestamp($date_range_item->end_value . ' +1 day');
 
   if ($t_start >= $t_end) {
-    // Cannot show a progress bar if start and end timestamp are the same.
+    // Invalid date range. No progress or status can be shown.
     return;
   }
 
   // Use the formatted field values for start / end date.
-  $element = $variables['elements']['oe_project_dates'][0];
+  $element = $variables['elements']['oe_project_dates'][0] ?? [];
   if ($element['#theme'] ?? NULL === 'time') {
     // Project lasts a single day.
     $start_date_element = $element;
@@ -209,6 +209,7 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
     $end_date_element = $element['end_date'];
   }
   else {
+    // Empty or incomplete date range. No progress or status can be shown.
     return;
   }
 
-- 
GitLab


From 89ece87b21171ed9d1acbc208ead0cb22cc9a86a Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Thu, 28 Apr 2022 14:13:02 +0200
Subject: [PATCH 138/152] OEL-1371: Don't remove CSS transition on progress
 bar.

The transition would be pointless, but it does not happen anyway if the element is hidden on page load.
---
 resources/js/oe_whitelabel.project_status.js | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/resources/js/oe_whitelabel.project_status.js b/resources/js/oe_whitelabel.project_status.js
index 5e70180a..3bdfeb14 100644
--- a/resources/js/oe_whitelabel.project_status.js
+++ b/resources/js/oe_whitelabel.project_status.js
@@ -45,9 +45,6 @@
           const $element = $(this);
           $element.removeClass(colorClasses);
           $element.addClass(colorClasses[status]);
-          // Disable css transition.
-          // It looks bad for the initial setting, and afterwards it does not help.
-          $element.css('transition', false);
           $element.css('width', percent + '%');
           $element.attr('aria-valuenow', percent);
           $element.attr('aria-label', percent);
-- 
GitLab


From b42a233a3081be985ebc15a5d0819ed45b689335 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Thu, 28 Apr 2022 14:57:57 +0200
Subject: [PATCH 139/152] OEL-1371: Drop the datetime_testing in test.

---
 composer.json                                 |  1 -
 .../ContentProjectRenderTest.php              | 22 -------------------
 2 files changed, 23 deletions(-)

diff --git a/composer.json b/composer.json
index b6633438..0bf85068 100644
--- a/composer.json
+++ b/composer.json
@@ -21,7 +21,6 @@
         "drupal/core-composer-scaffold": "^9.2",
         "drupal/core-dev": "^9.2",
         "drupal/ctools": "^3.7",
-        "drupal/datetime_testing": "^1.0@beta",
         "drupal/description_list_field": "^1.0@alpha",
         "drupal/drupal-extension": "~4.1",
         "drupal/entity_reference_revisions": "^1.9",
diff --git a/tests/src/FunctionalJavascript/ContentProjectRenderTest.php b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
index 9f74c514..4c8cdc14 100644
--- a/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
+++ b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
@@ -6,7 +6,6 @@ namespace Drupal\Tests\oe_whitelabel\FunctionalJavascript;
 
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Entity\EntityStorageInterface;
-use Drupal\datetime_testing\TestTimeInterface;
 use Drupal\file\Entity\File;
 use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
 use Drupal\media\Entity\Media;
@@ -39,7 +38,6 @@ class ContentProjectRenderTest extends WebDriverTestBase {
    */
   public static $modules = [
     'block',
-    'datetime_testing',
     'oe_whitelabel_extra_project',
   ];
 
@@ -254,8 +252,6 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     // Set a project period that is fully in the past.
     $this->setProjectDateRange($node, '2019-03-07', '2019-03-21');
     $node->save();
-    // Manipulate the server time to a date even further in the past.
-    $this->getTestTimeObject()->setTime('2017-01-01');
     $this->drupalGet($node->toUrl());
 
     $this->assertProjectStatusTimestampsAsDateStrings('2019-03-07 00:00:00', '2019-03-22 00:00:00');
@@ -266,8 +262,6 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     // Set a project period that is ongoing.
     $this->setProjectDateRange($node, '-5 day', '+15 days');
     $node->save();
-    // Manipulate the server time to a date far in the past.
-    $this->getTestTimeObject()->setTime('2017-01-01');
     $this->drupalGet($node->toUrl());
 
     $this->assertProjectStatusVisible();
@@ -277,8 +271,6 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     // Set a project period that is fully in the future.
     $this->setProjectDateRange($node, '+5 days', '+12 days');
     $node->save();
-    // Manipulate the server time to a date further in the future.
-    $this->getTestTimeObject()->setTime('+40 days');
     $this->drupalGet($node->toUrl());
 
     $this->assertProjectStatusVisible();
@@ -424,18 +416,4 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     }
   }
 
-  /**
-   * Gets the overridden time object to manipulate time.
-   *
-   * This is in a custom method for better static analysis.
-   *
-   * @return \Drupal\datetime_testing\TestTimeInterface
-   *   Overridden time object.
-   */
-  protected function getTestTimeObject(): TestTimeInterface {
-    $time = \Drupal::time();
-    $this->assertInstanceOf(TestTimeInterface::class, $time);
-    return $time;
-  }
-
 }
-- 
GitLab


From ead2bf7c70bb1d3b9e38e3c1a6a8fec309323a4e Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Thu, 28 Apr 2022 14:58:29 +0200
Subject: [PATCH 140/152] OEL-1371: Drop server-side calculation of status and
 progress. Back to placeholder values.

---
 .../oe_whitelabel_extra_project.module          | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index c98b07f1..2d6b2269 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -213,24 +213,23 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
     return;
   }
 
-  $status_keys = ['planned', 'ongoing', 'closed'];
   $status_labels = [t('Planned'), t('Ongoing'), t('Closed')];
 
-  $t_now = \Drupal::time()->getCurrentTime();
-  $status_id = ($t_now > $t_start) + ($t_now > $t_end);
-  $progress_01 = max(0, min(1, ($t_now - $t_start) / ($t_end - $t_start)));
-
   // Values for the 'bcl-project-status' component.
+  // Some values contain placeholders that will be updated with javascript.
+  // This makes sure that tests will fail if js does not run.
   $variables['project_status_args'] = [
-    'status' => $status_keys[$status_id],
+    // Placeholder value.
+    'status' => 'ongoing',
     'start_date' => $start_date_element,
     'start_label' => t('Start'),
     'end_date' => $end_date_element,
     'end_label' => t('End'),
     'label' => t('Status'),
-    'badge' => $status_labels[$status_id],
-    // Steps of 0.5 are smaller than a pixel, without too many decimals.
-    'progress' => round($progress_01 * 200) / 2,
+    // Placeholder value.
+    'badge' => '?',
+    // Placeholder value.
+    'progress' => 5,
     'attributes' => new Attribute([
       'data-start-timestamp' => $t_start,
       'data-end-timestamp' => $t_end,
-- 
GitLab


From c0d73ebb395390fb6a440ef86e4b8539cd5a9801 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Thu, 28 Apr 2022 15:00:37 +0200
Subject: [PATCH 141/152] OEL-1371: Change placeholder values to be more
 neutral.

---
 .../oe_whitelabel_extra_project.module                    | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 2d6b2269..3e02ed40 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -220,16 +220,16 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
   // This makes sure that tests will fail if js does not run.
   $variables['project_status_args'] = [
     // Placeholder value.
-    'status' => 'ongoing',
+    'status' => 'planned',
     'start_date' => $start_date_element,
     'start_label' => t('Start'),
     'end_date' => $end_date_element,
     'end_label' => t('End'),
     'label' => t('Status'),
     // Placeholder value.
-    'badge' => '?',
-    // Placeholder value.
-    'progress' => 5,
+    'badge' => '',
+    // Placeholder value, identical to 'planned'.
+    'progress' => 0,
     'attributes' => new Attribute([
       'data-start-timestamp' => $t_start,
       'data-end-timestamp' => $t_end,
-- 
GitLab


From ce7afd1444dae9c1a4eb6546a27bb83c0ec50b7b Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Thu, 28 Apr 2022 16:29:14 +0200
Subject: [PATCH 142/152] OEL-1371: Use non-empty badge label to make it show
 up.

---
 .../oe_whitelabel_extra_project.module                          | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 3e02ed40..53693284 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -227,7 +227,7 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
     'end_label' => t('End'),
     'label' => t('Status'),
     // Placeholder value.
-    'badge' => '',
+    'badge' => '&ellipsis;',
     // Placeholder value, identical to 'planned'.
     'progress' => 0,
     'attributes' => new Attribute([
-- 
GitLab


From 9c796642efbcd8d53c4171dc7e105ffd34f87e8b Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 6 May 2022 00:24:17 +0200
Subject: [PATCH 143/152] OEL-1371: Invalidate cache when site timezone
 changes.

---
 .../oe_whitelabel_extra_project.module                   | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 53693284..427cdc4b 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -181,8 +181,15 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
   // Dates only store the date, not the time.
   // Use the site-wide configured timezone, not a user-specific timezone.
   /* @see \Drupal\system\TimeZoneResolver::getTimeZone() */
+  $system_date_config = \Drupal::config('system.date');
   /** @var string $timezone */
-  $timezone = \Drupal::config('system.date')->get('timezone.default') ?? 'UTC';
+  $timezone = $system_date_config->get('timezone.default') ?? 'UTC';
+
+  // Invalidate cache when site timezone is changed.
+  CacheableMetadata::createFromRenderArray($variables)
+    ->addCacheableDependency($system_date_config)
+    ->applyTo($variables);
+
   $get_timestamp = static function (string $date_string) use ($timezone): int {
     return (new DrupalDateTime($date_string, $timezone))->getTimestamp();
   };
-- 
GitLab


From 32ff5754bf2ad0166760267e40f6572f12d3315f Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 6 May 2022 00:27:16 +0200
Subject: [PATCH 144/152] OEL-1371: No multiline array as foreach value.

---
 .../oe_whitelabel_extra_project.module                     | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 427cdc4b..006f65a5 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -254,11 +254,12 @@ function _oe_whitelabel_extra_project_preprocess_status_and_progress(array &$var
  *   Variables from hook_preprocess_node().
  */
 function _oe_whitelabel_extra_project_preprocess_contributions(array &$variables): void {
-  $legend_items = [];
-  foreach ([
+  $field_bg_classes = [
     'oe_project_budget' => 'bg-gray-400',
     'oe_project_budget_eu' => 'bg-primary',
-  ] as $field_name => $bg_class) {
+  ];
+  $legend_items = [];
+  foreach ($field_bg_classes as $field_name => $bg_class) {
     $field_element = $variables['elements'][$field_name] ?? NULL;
     if (!isset($field_element[0])) {
       continue;
-- 
GitLab


From 04d7fe11660ce530dea0f22ac26d6d55f0daf960 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 6 May 2022 00:27:43 +0200
Subject: [PATCH 145/152] OEL-1371: Each condition part on a separate line.

---
 .../oe_whitelabel_extra_project.module                      | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 006f65a5..189a64dc 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -298,8 +298,10 @@ function _oe_whitelabel_extra_project_preprocess_contributions(array &$variables
   $overall_budget = $node->get('oe_project_budget')->value;
   $eu_budget = $node->get('oe_project_budget_eu')->value;
 
-  if ($overall_budget === NULL || $eu_budget === NULL
-    || $overall_budget <= 0 || $eu_budget < 0
+  if ($overall_budget === NULL
+    || $eu_budget === NULL
+    || $overall_budget <= 0
+    || $eu_budget < 0
     || $overall_budget < $eu_budget
   ) {
     // No pie chart can be drawn with these values.
-- 
GitLab


From f88bf9e4b586778f461f5c51f53727baa4c3cb9d Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 6 May 2022 00:45:03 +0200
Subject: [PATCH 146/152] OEL-1371: Drop unnecessary clamping for contribution
 calculation.

---
 .../oe_whitelabel_extra_project.module                         | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 189a64dc..025cfb7b 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -308,7 +308,8 @@ function _oe_whitelabel_extra_project_preprocess_contributions(array &$variables
     return;
   }
 
-  $ratio_01 = max(0, min(1, $eu_budget / $overall_budget));
+  // The ratio will be in the range of 0..1, thanks to the checks above.
+  $ratio_01 = $eu_budget / $overall_budget;
   $percent = (int) round($ratio_01 * 10) * 10;
 
   $variables['contributions_args']['corporate_contributions'] = $percent;
-- 
GitLab


From 95864bf817be2b077988863bf8bfe81f1c2c22b8 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 6 May 2022 00:45:19 +0200
Subject: [PATCH 147/152] OEL-1371: Explain rounding to 10% steps.

---
 .../oe_whitelabel_extra_project.module                          | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
index 025cfb7b..2300a0dc 100644
--- a/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
+++ b/modules/oe_whitelabel_extra_project/oe_whitelabel_extra_project.module
@@ -310,6 +310,8 @@ function _oe_whitelabel_extra_project_preprocess_contributions(array &$variables
 
   // The ratio will be in the range of 0..1, thanks to the checks above.
   $ratio_01 = $eu_budget / $overall_budget;
+  // Convert to percent.
+  // The pie chart only supports multiples of 10%.
   $percent = (int) round($ratio_01 * 10) * 10;
 
   $variables['contributions_args']['corporate_contributions'] = $percent;
-- 
GitLab


From 421194dd7c4ac92c997abd20991f5d1fc1cfeaf5 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 6 May 2022 00:52:55 +0200
Subject: [PATCH 148/152] OEL-1371: Explain status index and progress in js.

---
 resources/js/oe_whitelabel.project_status.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/resources/js/oe_whitelabel.project_status.js b/resources/js/oe_whitelabel.project_status.js
index 3bdfeb14..e59a6cc3 100644
--- a/resources/js/oe_whitelabel.project_status.js
+++ b/resources/js/oe_whitelabel.project_status.js
@@ -26,7 +26,9 @@
         const msEnd = $element.data('end-timestamp') * 1000;
         const statusLabels = $element.data('status-labels').split('|');
         const msNow = Date.now();
+        // Calculate a status id: planned = 0, ongoing = 1, closed = 2.
         const status = (msNow >= msBegin) + (msNow > msEnd);
+        // Calculate a progress: planned = 0, ongoing = 0..1, closed = 1.
         const progress01 = Math.max(0, Math.min(1, (msNow - msBegin) / (msEnd - msBegin)));
         const percent = Math.round(progress01 * 200) / 2;
 
-- 
GitLab


From 70875a4626b3e6facf2d152007cddbc82655a966 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 6 May 2022 00:53:13 +0200
Subject: [PATCH 149/152] OEL-1371: Round to 1% instead of 0.5%, and explain
 why.

---
 resources/js/oe_whitelabel.project_status.js | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/resources/js/oe_whitelabel.project_status.js b/resources/js/oe_whitelabel.project_status.js
index e59a6cc3..d50085f6 100644
--- a/resources/js/oe_whitelabel.project_status.js
+++ b/resources/js/oe_whitelabel.project_status.js
@@ -30,7 +30,9 @@
         const status = (msNow >= msBegin) + (msNow > msEnd);
         // Calculate a progress: planned = 0, ongoing = 0..1, closed = 1.
         const progress01 = Math.max(0, Math.min(1, (msNow - msBegin) / (msEnd - msBegin)));
-        const percent = Math.round(progress01 * 200) / 2;
+        // Convert to percent: planned = 0%, ongoing = 0%..100%, closed = 100%.
+        // Round to 1%, to avoid overwhelming float digits in aria attributes.
+        const percent = Math.round(progress01 * 100);
 
         // Process the status label.
         $('.badge', this).each(function () {
-- 
GitLab


From fdf3d3ddc24a6935c00b9605db97350806988f46 Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 6 May 2022 01:03:08 +0200
Subject: [PATCH 150/152] OEL-1371: No need to have if() for statusLabels.

---
 resources/js/oe_whitelabel.project_status.js | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/resources/js/oe_whitelabel.project_status.js b/resources/js/oe_whitelabel.project_status.js
index d50085f6..22b701e2 100644
--- a/resources/js/oe_whitelabel.project_status.js
+++ b/resources/js/oe_whitelabel.project_status.js
@@ -39,9 +39,7 @@
           const $element = $(this);
           $element.removeClass(colorClasses);
           $element.addClass(colorClasses[status]);
-          if (statusLabels) {
-            $element.html(statusLabels[status]);
-          }
+          $element.html(statusLabels[status]);
         });
 
         // Process the progress bar.
-- 
GitLab


From 14133e5cc1120f10bf63af087b8e4e2c954410ca Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 6 May 2022 01:27:10 +0200
Subject: [PATCH 151/152] OEL-1371: Remove unnecessary permission in test.

---
 tests/src/FunctionalJavascript/ContentProjectRenderTest.php | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tests/src/FunctionalJavascript/ContentProjectRenderTest.php b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
index 4c8cdc14..7e429f8d 100644
--- a/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
+++ b/tests/src/FunctionalJavascript/ContentProjectRenderTest.php
@@ -49,7 +49,6 @@ class ContentProjectRenderTest extends WebDriverTestBase {
     $this->setUpSparql();
 
     Role::load(RoleInterface::ANONYMOUS_ID)
-      ->grantPermission('bypass node access')
       ->grantPermission('view published skos concept entities')
       ->grantPermission('view media')
       ->grantPermission('view published oe_organisation')
-- 
GitLab


From 97ad1c4e989e23640d04a714f3d281e301acbe4a Mon Sep 17 00:00:00 2001
From: Andreas Hennings <andreas@dqxtech.net>
Date: Fri, 6 May 2022 01:34:36 +0200
Subject: [PATCH 152/152] OEL-1371: Also remove 'bypass node access' in
 ContentRenderTestBase.

---
 tests/src/Kernel/ContentRenderTestBase.php | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tests/src/Kernel/ContentRenderTestBase.php b/tests/src/Kernel/ContentRenderTestBase.php
index 8d83aa84..bee23bde 100644
--- a/tests/src/Kernel/ContentRenderTestBase.php
+++ b/tests/src/Kernel/ContentRenderTestBase.php
@@ -82,7 +82,6 @@ abstract class ContentRenderTestBase extends AbstractKernelTestBase {
     ]);
 
     Role::load(RoleInterface::ANONYMOUS_ID)
-      ->grantPermission('bypass node access')
       ->grantPermission('view published skos concept entities')
       ->grantPermission('view media')
       ->save();
-- 
GitLab