From c2676af857a41440e05e03038d85a540dcca3ce2 Mon Sep 17 00:00:00 2001
From: Srishti-j18 <srishti33164jaiswal@gmail.com>
Date: Sat, 30 Nov 2024 13:42:25 +0530
Subject: [PATCH] Ensure new ListBlock instances get created with unique IDs

Fixes #10074
---
 CHANGELOG.txt                                           | 1 +
 client/src/components/StreamField/blocks/ListBlock.js   | 9 +++++----
 client/src/components/StreamField/blocks/StreamBlock.js | 8 ++++----
 docs/releases/6.4.md                                    | 1 +
 4 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 2622cf5b4b..602d849422 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -29,6 +29,7 @@ Changelog
  * Fix: Ensure the accessible labels and tooltips reflect the correct private/public status on the live link button within pages after changing the privacy (Ayaan Qadri)
  * Fix: Fix empty `th` (table heading) elements that are not compliant with accessibility standards (Jai Vignesh J)
  * Fix: Ensure `MultipleChooserPanel` using images or documents work when nested within an `InlinePanel` when no other choosers are in use within the model (Elhussein Almasri)
+ * Fix: Ensure new `ListBlock` instances get created with unique IDs in the admin client for accessibility and mini-map element references (Srishti Jaiswal)
  * Docs: Move the model reference page from reference/pages to the references section as it covers all Wagtail core models (Srishti Jaiswal)
  * Docs: Move the panels reference page from references/pages to the references section as panels are available for any model editing, merge panels API into this page (Srishti Jaiswal)
  * Docs: Move the tags documentation to standalone advanced topic, instead of being inside the reference/pages section (Srishti Jaiswal)
diff --git a/client/src/components/StreamField/blocks/ListBlock.js b/client/src/components/StreamField/blocks/ListBlock.js
index fa4590cfcd..1840d72912 100644
--- a/client/src/components/StreamField/blocks/ListBlock.js
+++ b/client/src/components/StreamField/blocks/ListBlock.js
@@ -20,7 +20,7 @@ import {
 class ListChild extends BaseSequenceChild {
   getState() {
     return {
-      id: this.id,
+      id: this.id || null,
       value: this.block.getState(),
     };
   }
@@ -31,7 +31,7 @@ class ListChild extends BaseSequenceChild {
 
   setState({ value, id }) {
     this.block.setState(value);
-    this.id = id;
+    this.id = id === undefined ? null : id;
   }
 
   setValue(value) {
@@ -142,7 +142,8 @@ export class ListBlock extends BaseSequenceBlock {
   setState(blocks) {
     this.clear();
     blocks.forEach(({ value, id }, i) => {
-      this.insert(value, i, { id: id || uuidv4() });
+      const validId = id === undefined ? uuidv4() : id;
+      this.insert(value, i, { id: id || validId });
     });
   }
 
@@ -154,7 +155,7 @@ export class ListBlock extends BaseSequenceBlock {
   _getChildDataForInsertion() {
     const blockDef = this.blockDef.childBlockDef;
     const initialState = this.blockDef.initialChildState;
-    return [blockDef, initialState];
+    return [blockDef, initialState, uuidv4()];
   }
 
   _createChild(
diff --git a/client/src/components/StreamField/blocks/StreamBlock.js b/client/src/components/StreamField/blocks/StreamBlock.js
index b615d02b08..31a8b9634e 100644
--- a/client/src/components/StreamField/blocks/StreamBlock.js
+++ b/client/src/components/StreamField/blocks/StreamBlock.js
@@ -35,7 +35,7 @@ class StreamChild extends BaseSequenceChild {
     return {
       type: this.type,
       value: this.block.getState(),
-      id: this.id,
+      id: this.id || null,
     };
   }
 
@@ -49,14 +49,14 @@ class StreamChild extends BaseSequenceChild {
   setState({ type, value, id }) {
     this.type = type;
     this.block.setState(value);
-    this.id = id;
+    this.id = id === undefined ? null : id;
   }
 
   getValue() {
     return {
       type: this.type,
       value: this.block.getValue(),
-      id: this.id,
+      id: this.id || null,
     };
   }
 
@@ -389,7 +389,7 @@ export class StreamBlock extends BaseSequenceBlock {
     );
     child.setState({
       type: initialState.type,
-      id: initialState.id,
+      id: initialState.id || null,
       value: valueBefore,
     });
     const oldContentPath = child.getContentPath();
diff --git a/docs/releases/6.4.md b/docs/releases/6.4.md
index 664d2b823d..57e2b9b960 100644
--- a/docs/releases/6.4.md
+++ b/docs/releases/6.4.md
@@ -41,6 +41,7 @@ depth: 1
  * Ensure the accessible labels and tooltips reflect the correct private/public status on the live link button within pages after changing the privacy (Ayaan Qadri)
  * Fix empty `th` (table heading) elements that are not compliant with accessibility standards (Jai Vignesh J)
  * Ensure `MultipleChooserPanel` using images or documents work when nested within an `InlinePanel` when no other choosers are in use within the model (Elhussein Almasri)
+ * Ensure new `ListBlock` instances get created with unique IDs in the admin client for accessibility and mini-map element references (Srishti Jaiswal)
 
 ### Documentation