Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Looping 2.5 | Repeating Blocks for List Items #1106

Merged
merged 114 commits into from
Jun 26, 2023
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
443d266
Initial repeating blocks test schema
kylelawsonAND Apr 25, 2023
08fed55
Schema for repeating blocks and section summary incomplete + ListColl…
kylelawsonAND Apr 27, 2023
4ab2f3f
Repeating blocks are presented to the user and can be answered howeve…
kylelawsonAND Apr 28, 2023
4311b76
List Collector now always enters add_block & both add_block and edit_…
kylelawsonAND May 2, 2023
66c3e1a
Merge branch 'main' into feat/looping-2.5-simple-list-collector
kylelawsonAND May 2, 2023
3e952d8
make format
kylelawsonAND May 2, 2023
d0b49d6
edit_block does not lead to repeating_blocks. All repeating_blocks sh…
kylelawsonAND May 3, 2023
fe76286
Merge remote-tracking branch 'origin/main' into feat/looping-2.5
kylelawsonAND May 4, 2023
ba48c67
Merge branch 'feat/looping-2.5' into feat/looping-2.5-simple-list-col…
kylelawsonAND May 4, 2023
ada2974
Blocks in repeating_blocks calculated upfront. Answers from repeating…
kylelawsonAND May 4, 2023
63611a1
Reverting list_collector handler and fixing invalid use of set
kylelawsonAND May 4, 2023
508101c
Return to summary reused throughout ListActions
kylelawsonAND May 5, 2023
281c470
Adding list item completion progress to progress_store and loading th…
kylelawsonAND May 15, 2023
7bda62b
Looping 2.5 - Simple Repeating Blocks in List Collector (No Item Prog…
kylelawsonAND May 16, 2023
641eea5
Merge branch 'main' into feat/looping-2.5
kylelawsonAND May 16, 2023
06569ac
Merge branch 'feat/looping-2.5' into feat/looping-2.5-list-item-progress
kylelawsonAND May 16, 2023
80e0ac1
Fixing existing questionnaire store tests broken by adding list item …
kylelawsonAND May 16, 2023
3387d04
Added remove list item progress to progress store and called from que…
kylelawsonAND May 16, 2023
551ff4f
List Item Progress tracked with the section and list item id keyed pr…
kylelawsonAND May 17, 2023
bf6134e
List Item Progress starts with list item add, adding the add block to…
kylelawsonAND May 17, 2023
08b0304
Make response expiry date mandatory (#1104)
petechd May 18, 2023
fa0a1d7
Reverting change to serialize() method naming + removing dev only chn…
kylelawsonAND May 18, 2023
18d09f4
Bind additional contexts to flush requests (#1108)
petechd May 18, 2023
6f3109b
Addressing comments to simplify progress evaluation logic + adding ca…
kylelawsonAND May 19, 2023
cee23dc
Schemas v3.56.0 (#1110)
MebinAbraham May 23, 2023
b35d6ec
Addressing comments regarding common usage of first incomplete repeat…
kylelawsonAND May 23, 2023
6557ef0
Augmenting comment in capture_dependent_sections_for_list(self, list_…
kylelawsonAND May 23, 2023
800c15f
Bug fix to repeating block cache, list section deps reverted to dict …
kylelawsonAND May 24, 2023
ddd30d3
Removing get_completed_block_ids from questionnaire store updater as …
kylelawsonAND May 24, 2023
5b64601
Preliminary impl for list item row icons - breaks tests
kylelawsonAND May 24, 2023
e70f16c
Merge branch 'main' into feat/looping-2.5
kylelawsonAND May 25, 2023
2462682
Feat/looping 2.5 list item progress (#1105)
kylelawsonAND May 25, 2023
aa0008d
Merge branch 'feat/looping-2.5' into feat/looping-2.5-list-item-progr…
kylelawsonAND May 25, 2023
5b561d9
Fixing tests broken by list collector icon render changes
kylelawsonAND May 25, 2023
5b35bff
Fixing incorrect formatting and rewording a type hint
kylelawsonAND May 25, 2023
127b3eb
Cleaned up evaluation of list item icon.
kylelawsonAND May 25, 2023
36fb6c7
Schemas v3.57.0 (#1113)
MebinAbraham May 25, 2023
b360362
Reverting accidental reversion of a file
kylelawsonAND May 25, 2023
fdc0f75
Schemas v3.57.1 (#1115)
MebinAbraham May 26, 2023
c2439d8
Schemas v3.58.0 (#1116)
MebinAbraham May 26, 2023
cc12488
Implement "progress" value source (#1044)
ONS-Guilhem-Forey May 26, 2023
82b2abe
Fix handling of invalid values in form numerical inputs (#1111)
petechd May 30, 2023
ccc82dd
Passing only section id and bool for repeating blocks for list contex…
kylelawsonAND May 30, 2023
c9e928f
Adding missing list context constructor arg
kylelawsonAND May 30, 2023
9014456
Enforcing kwargs on _build_list_items_context
kylelawsonAND May 30, 2023
8c1272d
Merge branch 'main' into feat/looping-2.5
kylelawsonAND May 30, 2023
b37363a
Merge conflict resolution with main.
kylelawsonAND May 30, 2023
5824f3f
Running make format
kylelawsonAND May 30, 2023
0dafeb1
Adding list collector with repeating blocks fixture and testing the r…
kylelawsonAND May 31, 2023
fe398e2
Completing unit testing of additions to QuestionnaireSchema
kylelawsonAND May 31, 2023
f404619
Update Chromedriver to version 113 (#1118)
katie-gardner Jun 1, 2023
278a464
ListContext unit tests
kylelawsonAND Jun 1, 2023
eee27b1
Updating list collector summary to correctly acquire related answers …
kylelawsonAND Jun 2, 2023
4b9050a
Enforcing kwargs on update_section_status and make format
kylelawsonAND Jun 2, 2023
12fb8ff
Feat/Grand calculated summary (#1107)
katie-gardner Jun 2, 2023
69cfc90
Integration tests started
kylelawsonAND Jun 5, 2023
d5f7173
Fix dynamic answers functional test (#1121)
petechd Jun 6, 2023
d76e9de
Repeating blocks integration test suite complete
kylelawsonAND Jun 6, 2023
ab19672
Schemas v3.59.0 (#1130)
berroar Jun 7, 2023
ffbc72d
Make format
kylelawsonAND Jun 8, 2023
f045fd8
running and fixing mypy
kylelawsonAND Jun 8, 2023
7bc7881
Merge branch 'main' into feat/looping-2.5
kylelawsonAND Jun 8, 2023
e3c8379
Merge with main and format and lint
kylelawsonAND Jun 8, 2023
accdc6a
Fixing linting errors and pointing to relevant validator
kylelawsonAND Jun 8, 2023
3ad65a6
Fixing validator tag typo
kylelawsonAND Jun 8, 2023
a2986c0
Schemas v3.60.0 (#1133)
berroar Jun 8, 2023
0518298
Fixing mocker patch of renamed method
kylelawsonAND Jun 8, 2023
3b9934a
make format
kylelawsonAND Jun 8, 2023
090e652
Update to chromedriver v114 (#1134)
berroar Jun 9, 2023
f035587
Functional test progress
kylelawsonAND Jun 9, 2023
1dcf278
Add DESNZ theme (#1131)
petechd Jun 12, 2023
d04325c
Schemas v3.61.0 (#1139)
berroar Jun 13, 2023
7ba801e
Adding functional test for editing repeating block answers from secti…
kylelawsonAND Jun 13, 2023
cb61664
Asserting completing list items in func tests and editing from sectio…
kylelawsonAND Jun 14, 2023
da95c6b
Merge branch 'main' into feat/looping-2.5
kylelawsonAND Jun 14, 2023
dee36f5
Misc type hinting
kylelawsonAND Jun 14, 2023
f4a4939
Misc type hinting
kylelawsonAND Jun 14, 2023
7772bdc
Formatting
kylelawsonAND Jun 14, 2023
6326c5d
Consolidating duplicate func test helper method and fixing typos.
kylelawsonAND Jun 14, 2023
d1e0a4a
Merge branch 'feature-prepop' into feat/looping-2.5
kylelawsonAND Jun 15, 2023
cdd794b
Linting, formatting and merging with feat prepop.
kylelawsonAND Jun 15, 2023
398156a
Fixing broken tests
kylelawsonAND Jun 15, 2023
7b337f1
Merge branch 'feature-prepop' into feat/looping-2.5
kylelawsonAND Jun 15, 2023
6b54da6
Merge branch 'main' into feature-prepop-update-with-main
kylelawsonAND Jun 15, 2023
af56745
Linting, formatting and cleaning up merge with main
kylelawsonAND Jun 15, 2023
af51ddd
Merge branch 'feature-prepop-update-with-main' into feat/looping-2.5
kylelawsonAND Jun 16, 2023
9e27f42
Merge branch 'feature-prepop' into feat/looping-2.5
kylelawsonAND Jun 16, 2023
4f4e416
ListRepeatingBlock now extends to ListAction and does not invoke pare…
kylelawsonAND Jun 16, 2023
59a2071
Addressing PR comments 16-6-23
kylelawsonAND Jun 16, 2023
b4eb3f4
Reverting local test changes.
kylelawsonAND Jun 16, 2023
4316be3
Reverting local test changes by formatting
kylelawsonAND Jun 16, 2023
20975e9
Reverting local test changes by formatting
kylelawsonAND Jun 16, 2023
6f947e5
Adding additional docs and type hints to ProgressStore
kylelawsonAND Jun 19, 2023
8ffe90a
Addressing PR comments.
kylelawsonAND Jun 19, 2023
c3b2425
Fixing list collector (no RP) icons
kylelawsonAND Jun 19, 2023
62ebf67
Removing person icon change.
kylelawsonAND Jun 19, 2023
377b218
Adding repeating blocks to the submission payload and renaming list n…
kylelawsonAND Jun 20, 2023
e090354
Adding test coverage for repeating block answers in submission payload.
kylelawsonAND Jun 20, 2023
5eb24da
Reformat
kylelawsonAND Jun 20, 2023
f1aa2f7
Adding func test and schema for a repeating blocks LC on a hub questi…
kylelawsonAND Jun 20, 2023
1a0942e
Fixing test broken in prev commit.
kylelawsonAND Jun 21, 2023
55f72ac
Reformatting.
kylelawsonAND Jun 21, 2023
8ad4cd7
Updating naming of progress store methods follwoing convos.
kylelawsonAND Jun 21, 2023
175de45
Updating comment
kylelawsonAND Jun 22, 2023
6b5460b
Updating comment
kylelawsonAND Jun 22, 2023
d74b098
Formatting
kylelawsonAND Jun 22, 2023
539346c
Addressing comments
kylelawsonAND Jun 22, 2023
a9f9b5f
Remvovign whitespace from schema
kylelawsonAND Jun 22, 2023
59db77c
Amending naming and type hinting in list collector block summary and…
kylelawsonAND Jun 23, 2023
50bec33
Changing to unit and currency in simple RB schema.
kylelawsonAND Jun 23, 2023
fc1551c
Formatting
kylelawsonAND Jun 23, 2023
4bd1f26
Removing redundant test schema
kylelawsonAND Jun 26, 2023
b5f2b87
Using latest validator
kylelawsonAND Jun 26, 2023
0a671f8
Merge branch 'feature-prepop' into feat/looping-2.5
kylelawsonAND Jun 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .schemas-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v3.55.0
v3.58.0
3 changes: 2 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pytest-mock = "*"

[packages]
colorama = "*"
flask = "*"
flask = "==2.2.2"
flask-babel = "*"
flask-login = "*"
flask-wtf = "*"
Expand Down Expand Up @@ -72,6 +72,7 @@ google-cloud-tasks = "*"
simplejson = "*"
markupsafe = "*"
pdfkit = "*"
ordered-set = "*"

[requires]
python_version = "3.10"
Expand Down
1,734 changes: 873 additions & 861 deletions Pipfile.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/data_models/metadata_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ class MetadataProxy:
case_id: str
collection_exercise_sid: str
response_id: str
response_expires_at: datetime
survey_metadata: Optional[SurveyMetadata] = None
schema_url: Optional[str] = None
schema_name: Optional[str] = None
language_code: Optional[str] = None
response_expires_at: Optional[datetime] = None
channel: Optional[str] = None
region_code: Optional[str] = None
version: Optional[AuthPayloadVersion] = None
Expand Down
35 changes: 25 additions & 10 deletions app/data_models/progress_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class ProgressStore:
"""

def __init__(
self, in_progress_sections: Optional[Iterable[ProgressDictType]] = None
self, in_progress_sections: Iterable[ProgressDictType] | None = None
) -> None:
"""
Instantiate a ProgressStore object that tracks the status of sections and its completed blocks
Expand Down Expand Up @@ -111,16 +111,16 @@ def section_keys(

def update_section_status(
self, section_status: str, section_id: str, list_item_id: Optional[str] = None
) -> None:
) -> bool:
updated = False
section_key = (section_id, list_item_id)
if section_key in self._progress:
self._progress[section_key].status = section_status
self._is_dirty = True
if self._progress[section_key].status != section_status:
updated = True
self._progress[section_key].status = section_status
self._is_dirty = True

elif (
section_status == CompletionStatus.INDIVIDUAL_RESPONSE_REQUESTED
and section_key not in self._progress
):
elif section_status == CompletionStatus.INDIVIDUAL_RESPONSE_REQUESTED:
self._progress[section_key] = Progress(
section_id=section_id,
list_item_id=list_item_id,
Expand All @@ -129,6 +129,8 @@ def update_section_status(
)
self._is_dirty = True

return updated

def get_section_status(
self, section_id: str, list_item_id: Optional[str] = None
) -> str:
Expand All @@ -138,8 +140,19 @@ def get_section_status(

return CompletionStatus.NOT_STARTED

def get_block_status(
self, *, block_id: str, section_id: str, list_item_id: str | None = None
) -> str:
section_blocks = self.get_completed_block_ids(
section_id=section_id, list_item_id=list_item_id
)
if block_id in section_blocks:
return CompletionStatus.COMPLETED

return CompletionStatus.NOT_STARTED

def get_completed_block_ids(
self, section_id: str, list_item_id: Optional[str] = None
self, *, section_id: str, list_item_id: str | None = None
) -> list[str]:
section_key = (section_id, list_item_id)
if section_key in self._progress:
Expand All @@ -151,7 +164,9 @@ def add_completed_location(self, location: Location) -> None:
section_id = location.section_id
list_item_id = location.list_item_id

completed_block_ids = self.get_completed_block_ids(section_id, list_item_id)
completed_block_ids = self.get_completed_block_ids(
section_id=section_id, list_item_id=list_item_id
)

if location.block_id not in completed_block_ids:
completed_block_ids.append(location.block_id) # type: ignore
Expand Down
6 changes: 2 additions & 4 deletions app/data_models/questionnaire_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,10 @@ def save(self) -> None:
collection_exercise_sid = (
self.collection_exercise_sid or self._metadata["collection_exercise_sid"]
)
response_expires_at = self._metadata.get("response_expires_at")
response_expires_at = self._metadata["response_expires_at"]
self._storage.save(
data=data,
collection_exercise_sid=collection_exercise_sid,
submitted_at=self.submitted_at,
expires_at=parse_iso_8601_datetime(response_expires_at)
if response_expires_at
else None,
expires_at=parse_iso_8601_datetime(response_expires_at),
)
7 changes: 2 additions & 5 deletions app/forms/fields/decimal_field_with_separator.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from decimal import Decimal, InvalidOperation

from babel import numbers
from wtforms import DecimalField

from app.settings import DEFAULT_LOCALE
from app.helpers.form_helpers import sanitise_number


class DecimalFieldWithSeparator(DecimalField):
Expand All @@ -23,8 +22,6 @@ def __init__(self, **kwargs):
def process_formdata(self, valuelist):
if valuelist:
try:
self.data = Decimal(
valuelist[0].replace(numbers.get_group_symbol(DEFAULT_LOCALE), "")
)
self.data = Decimal(sanitise_number(valuelist[0]))
except (ValueError, TypeError, InvalidOperation):
pass
7 changes: 2 additions & 5 deletions app/forms/fields/integer_field_with_separator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from babel import numbers
from wtforms import IntegerField

from app.settings import DEFAULT_LOCALE
from app.helpers.form_helpers import sanitise_number


class IntegerFieldWithSeparator(IntegerField):
Expand All @@ -21,8 +20,6 @@ def __init__(self, **kwargs):
def process_formdata(self, valuelist):
if valuelist:
try:
self.data = int(
valuelist[0].replace(numbers.get_group_symbol(DEFAULT_LOCALE), "")
)
self.data = int(sanitise_number(valuelist[0]))
except ValueError:
pass
44 changes: 12 additions & 32 deletions app/forms/validators.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import math
import re
from datetime import datetime, timezone
from decimal import Decimal, InvalidOperation
Expand All @@ -19,10 +20,14 @@
DecimalFieldWithSeparator,
IntegerFieldWithSeparator,
)
from app.jinja_filters import format_number, get_formatted_currency
from app.helpers.form_helpers import (
format_message_with_title,
format_playback_value,
sanitise_mobile_number,
sanitise_number,
)
from app.questionnaire.questionnaire_store_updater import QuestionnaireStoreUpdater
from app.questionnaire.rules.utils import parse_datetime
from app.utilities import safe_content

if TYPE_CHECKING:
from app.forms.questionnaire_form import QuestionnaireForm # pragma: no cover
Expand All @@ -49,15 +54,12 @@ def __call__(
field: Union[DecimalFieldWithSeparator, IntegerFieldWithSeparator],
) -> None:
try:
Decimal(
field.raw_data[0].replace(
numbers.get_group_symbol(flask_babel.get_locale()), ""
)
)
# number is sanitised to guard against inputs like `,NaN_` etc
number = Decimal(sanitise_number(number=field.raw_data[0]))
except (ValueError, TypeError, InvalidOperation, AttributeError) as exc:
raise validators.StopValidation(self.message) from exc

if "e" in field.raw_data[0].lower():
if "e" in field.raw_data[0].lower() or math.isnan(number):
raise validators.StopValidation(self.message)


Expand Down Expand Up @@ -126,6 +128,7 @@ def __call__(
field: Union[DecimalFieldWithSeparator, IntegerFieldWithSeparator],
) -> None:
value: Union[int, Decimal] = field.data

if value is not None:
error_message = self.validate_minimum(value) or self.validate_maximum(value)
if error_message:
Expand Down Expand Up @@ -179,11 +182,7 @@ def __init__(self, max_decimals: int = 0, messages: OptionalMessage = None):
def __call__(
self, form: "QuestionnaireForm", field: DecimalFieldWithSeparator
) -> None:
data = (
field.raw_data[0]
.replace(numbers.get_group_symbol(flask_babel.get_locale()), "")
.replace(" ", "")
)
data = sanitise_number(field.raw_data[0])
decimal_symbol = numbers.get_decimal_symbol(flask_babel.get_locale())
if data and decimal_symbol in data:
if self.max_decimals == 0:
Expand Down Expand Up @@ -450,20 +449,6 @@ def _is_valid(
raise NotImplementedError(f"Condition '{condition}' is not implemented")


def format_playback_value(
value: Union[float, Decimal], currency: Optional[str] = None
) -> str:
if currency:
return get_formatted_currency(value, currency)

formatted_number: str = format_number(value)
return formatted_number


def format_message_with_title(error_message: str, question_title: str) -> str:
return error_message % {"question_title": safe_content(question_title)}


class MutuallyExclusiveCheck:
def __init__(self, question_title: str, messages: OptionalMessage = None):
self.messages = {**error_messages, **(messages or {})}
Expand Down Expand Up @@ -492,11 +477,6 @@ def __call__(
raise validators.ValidationError(message)


def sanitise_mobile_number(data: str) -> str:
data = re.sub(r"[\s.,\t\-{}\[\]()/]", "", data)
return re.sub(r"^(0{1,2}44|\+44|0)", "", data)


class MobileNumberCheck:
def __init__(self, message: OptionalMessage = None):
self.message = message or error_messages["INVALID_MOBILE_NUMBER"]
Expand Down
33 changes: 33 additions & 0 deletions app/helpers/form_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import re
from decimal import Decimal

import flask_babel
from babel import numbers

from app.jinja_filters import format_number, get_formatted_currency
from app.utilities import safe_content


def sanitise_number(number: str) -> str:
return (
number.replace(numbers.get_group_symbol(flask_babel.get_locale()), "")
.replace("_", "")
.replace(" ", "")
)


def sanitise_mobile_number(data: str) -> str:
data = re.sub(r"[\s.,\t\-{}\[\]()/]", "", data)
return re.sub(r"^(0{1,2}44|\+44|0)", "", data)


def format_playback_value(value: float | Decimal, currency: str | None = None) -> str:
if currency:
return get_formatted_currency(value, currency)

formatted_number: str = format_number(value)
return formatted_number


def format_message_with_title(error_message: str, question_title: str) -> str:
return error_message % {"question_title": safe_content(question_title)}
31 changes: 22 additions & 9 deletions app/jinja_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import re
from datetime import datetime
from decimal import Decimal
from typing import Any, Callable, Mapping, Optional, Union
from typing import Any, Callable, Literal, Mapping, Optional, TypeAlias, Union

import flask
import flask_babel
Expand All @@ -18,6 +18,7 @@
blueprint = flask.Blueprint("filters", __name__)
FormType = Mapping[str, Mapping[str, Any]]
AnswerType = Mapping[str, Any]
UnitLengthType: TypeAlias = Literal["short", "long", "narrow"]


def mark_safe(context: nodes.EvalContext, value: str) -> Union[Markup, str]:
Expand Down Expand Up @@ -69,7 +70,9 @@ def format_percentage(value: Union[int, float, Decimal]) -> str:


def format_unit(
unit: str, value: Union[int, float, Decimal], length: str = "short"
unit: str,
value: int | float | Decimal,
length: UnitLengthType = "short",
) -> str:
formatted_unit: str = units.format_unit(
value=value,
Expand All @@ -80,7 +83,7 @@ def format_unit(
return formatted_unit


def format_unit_input_label(unit: str, unit_length: str = "short") -> str:
def format_unit_input_label(unit: str, unit_length: UnitLengthType = "short") -> str:
"""
This function is used to only get the unit of measurement text. If the unit_length
is long then only the plural form of the word is returned (e.g., Hours, Years, etc).
Expand All @@ -97,8 +100,9 @@ def format_unit_input_label(unit: str, unit_length: str = "short") -> str:
locale=flask_babel.get_locale(),
).replace("2 ", "")
else:
# Type ignore: We pass an empty string as the value so that we just return the unit label
unit_label = units.format_unit(
value="",
value="", # type: ignore
measurement_unit=unit,
length=unit_length,
locale=flask_babel.get_locale(),
Expand Down Expand Up @@ -183,7 +187,10 @@ def get_format_date_range(start_date: Markup, end_date: Markup) -> Markup:

@blueprint.app_context_processor
def format_unit_processor() -> (
dict[str, Callable[[str, Union[int, Decimal], str], str]]
dict[
str,
Callable[[str, int | float | Decimal, UnitLengthType], str],
]
):
return {"format_unit": format_unit}

Expand Down Expand Up @@ -575,7 +582,6 @@ def map_summary_item_config(
calculated_question: Optional[dict[str, list]],
remove_link_text: str | None = None,
remove_link_aria_label: str | None = None,
icon: Optional[str] = None,
) -> list[Union[dict[str, list], SummaryRow]]:
rows: list[Union[dict[str, list], SummaryRow]] = []

Expand All @@ -594,7 +600,6 @@ def map_summary_item_config(
else:
list_collector_rows = map_list_collector_config(
list_items=block["list"]["list_items"],
icon=icon,
edit_link_text=edit_link_text,
edit_link_aria_label=edit_link_aria_label,
remove_link_text=remove_link_text,
Expand All @@ -620,8 +625,8 @@ def map_summary_item_config_processor() -> dict[str, Callable]:
# pylint: disable=too-many-locals
@blueprint.app_template_filter() # type: ignore
def map_list_collector_config(
list_items: list[dict[str, Union[str, int]]],
icon: Optional[str],
list_items: list[dict[str, str | int]],
render_icon: bool = False,
edit_link_text: str = "",
edit_link_aria_label: str = "",
remove_link_text: Optional[str] = None,
Expand Down Expand Up @@ -676,6 +681,14 @@ def map_list_collector_config(
}
)

icon = (
petechd marked this conversation as resolved.
Show resolved Hide resolved
"check"
if render_icon
and list_item.get("repeating_blocks")
and list_item.get("is_complete")
else None
)

row_item = {
"iconType": icon,
"actions": actions,
Expand Down
Loading