From f9b363c090f156cbc025e523f4f37410fab0003e Mon Sep 17 00:00:00 2001
From: Lauri Eskola <lauri.eskola@acquia.com>
Date: Fri, 28 Jul 2023 09:58:42 +0300
Subject: [PATCH] Issue #3375887 by srishtiiee, Berdir, Utkarsh_33: Add a
 weight for the options within a field category

---
 .../Core/Field/Annotation/FieldType.php       |  7 ++++
 .../Plugin/Field/FieldType/DecimalItem.php    |  1 +
 .../Plugin/Field/FieldType/FloatItem.php      |  1 +
 .../Plugin/Field/FieldType/IntegerItem.php    |  1 +
 .../field_ui/src/Form/FieldStorageAddForm.php |  5 ++-
 .../FunctionalJavascript/ManageFieldsTest.php | 38 +++++++++++++++++++
 .../Plugin/Field/FieldType/ListFloatItem.php  |  1 +
 .../Field/FieldType/ListIntegerItem.php       |  1 +
 .../Plugin/Field/FieldType/ListStringItem.php |  1 +
 9 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/core/lib/Drupal/Core/Field/Annotation/FieldType.php b/core/lib/Drupal/Core/Field/Annotation/FieldType.php
index 8bf54cb585db..4dcb51ee6083 100644
--- a/core/lib/Drupal/Core/Field/Annotation/FieldType.php
+++ b/core/lib/Drupal/Core/Field/Annotation/FieldType.php
@@ -57,6 +57,13 @@ class FieldType extends DataType {
    */
   public $category = '';
 
+  /**
+   * The weight of the field type.
+   *
+   * @var int
+   */
+  public $weight = 0;
+
   /**
    * The plugin_id of the default widget for this field type.
    *
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DecimalItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DecimalItem.php
index 98f0f8318100..561a2d9151a6 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DecimalItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/DecimalItem.php
@@ -20,6 +20,7 @@
  *     @Translation("For example, 12.34 km or € when used for further detailed calculations (such as summing many of these)"),
  *   },
  *   category = "number",
+ *   weight = -30,
  *   default_widget = "number",
  *   default_formatter = "number_decimal"
  * )
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php
index 797543255ee7..2e120c0ad1d4 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/FloatItem.php
@@ -19,6 +19,7 @@
  *     @Translation("For example, 123.4 km when used in imprecise contexts such as a walking trail distance"),
  *   },
  *   category = "number",
+ *   weight = -10,
  *   default_widget = "number",
  *   default_formatter = "number_decimal"
  * )
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
index b927a4de8f1c..dcb4275d9d8e 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/IntegerItem.php
@@ -18,6 +18,7 @@
  *     @Translation("For example, 123"),
  *   },
  *   category = "number",
+ *   weight = -50,
  *   default_widget = "number",
  *   default_formatter = "number_integer"
  * )
diff --git a/core/modules/field_ui/src/Form/FieldStorageAddForm.php b/core/modules/field_ui/src/Form/FieldStorageAddForm.php
index 69d353f8ed88..e7582d706a74 100644
--- a/core/modules/field_ui/src/Form/FieldStorageAddForm.php
+++ b/core/modules/field_ui/src/Form/FieldStorageAddForm.php
@@ -292,6 +292,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t
               '#items' => $unique_definitions[$selected_field_type][$option_key]['description'],
             ],
             '#id' => $option['unique_identifier'],
+            '#weight' => $option['weight'],
             '#parents' => ['group_field_options_wrapper'],
             '#attributes' => [
               'class' => ['field-option-radio'],
@@ -307,8 +308,10 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t
             $radio_element['#title'] = 'Other';
             $radio_element['#weight'] = 10;
           }
-          $form['group_field_options_wrapper']['fields'][$option['unique_identifier']] = $radio_element;
+          $group_field_options[$option['unique_identifier']] = $radio_element;
         }
+        uasort($group_field_options, [SortArray::class, 'sortByWeightProperty']);
+        $form['group_field_options_wrapper']['fields'] += $group_field_options;
       }
     }
     $field_prefix = $this->config('field_ui.settings')->get('field_prefix');
diff --git a/core/modules/field_ui/tests/src/FunctionalJavascript/ManageFieldsTest.php b/core/modules/field_ui/tests/src/FunctionalJavascript/ManageFieldsTest.php
index e61606d55245..ab3d845c66a1 100644
--- a/core/modules/field_ui/tests/src/FunctionalJavascript/ManageFieldsTest.php
+++ b/core/modules/field_ui/tests/src/FunctionalJavascript/ManageFieldsTest.php
@@ -25,6 +25,7 @@ class ManageFieldsTest extends WebDriverTestBase {
     'field_ui',
     'field_test',
     'block',
+    'options',
   ];
 
   /**
@@ -242,4 +243,41 @@ public function testAddField() {
     $this->assertEquals('test_field', $field_storage->getType());
   }
 
+  /**
+   * Tests the order in which the field types appear in the form.
+   */
+  public function testFieldTypeOrder() {
+    $this->drupalget('admin/structure/types/manage/article/fields/add-field');
+    $page = $this->getSession()->getPage();
+    $field_type_categories = [
+      'selection_list',
+      'number',
+    ];
+    foreach ($field_type_categories as $field_type_category) {
+      // Select the group card.
+      $group_field_card = $page->find('css', "[name='new_storage_type'][value='$field_type_category']");
+      $group_field_card->click();
+      $this->assertSession()->assertWaitOnAjaxRequest();
+      $field_types = $page->findAll('css', '.subfield-option .option');
+      $field_type_labels = [];
+      foreach ($field_types as $field_type) {
+        $field_type_labels[] = $field_type->getText();
+      }
+      $expected_field_types = match ($field_type_category) {
+        'selection_list' => [
+          'List (text)',
+          'List (integer)',
+          'List (float)',
+        ],
+        'number' => [
+          'Number (integer)',
+          'Number (decimal)',
+          'Number (float)',
+        ],
+      };
+      // Assert that the field type options are displayed as per their weights.
+      $this->assertSame($expected_field_types, $field_type_labels);
+    }
+  }
+
 }
diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php
index 26388d3aba6f..d2539dd66d18 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php
@@ -20,6 +20,7 @@
  *     @Translation("For example, 'Fraction': 0 => 0, .25 => 1/4, .75 => 3/4, 1 => 1"),
  *   },
  *   category = "selection_list",
+ *   weight = -10,
  *   default_widget = "options_select",
  *   default_formatter = "list_default",
  * )
diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php
index cf4674880e7e..5132bb6c6574 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php
@@ -20,6 +20,7 @@
  *     @Translation("For example, 'Lifetime in days': 1 => 1 day, 7 => 1 week, 31 => 1 month"),
  *   },
  *   category = "selection_list",
+ *   weight = -30,
  *   default_widget = "options_select",
  *   default_formatter = "list_default",
  * )
diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php
index ca4f5d22229d..e3af421ff4a0 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php
@@ -20,6 +20,7 @@
  *     @Translation("For example, 'US States': IL => Illinois, IA => Iowa, IN => Indiana"),
  *   },
  *   category = "selection_list",
+ *   weight = -50,
  *   default_widget = "options_select",
  *   default_formatter = "list_default",
  * )
-- 
GitLab