Skip to content

Commit

Permalink
Merge pull request #118 from numerique-gouv/components-3
Browse files Browse the repository at this point in the history
Ajout/mise à jour de composants : cartes
  • Loading branch information
Ash-Crow authored May 28, 2024
2 parents a9ca8a4 + 7111e5b commit 0ec3bf1
Show file tree
Hide file tree
Showing 20 changed files with 10,290 additions and 206 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
- name: ✨ Black, isort, flake8 & djlint
run: |
make quality
- name: 🚧 Check pending migrations
- name: 🚧 Check pending migrations # continue-on-error: true
run: |
poetry run django-admin makemigrations --check --dry-run --noinput
- name: 🤹‍ Run the unit tests
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,4 @@ dmypy.json
# Project-specific stuff
config.json
cron.json
temp.json

Large diffs are not rendered by default.

213 changes: 182 additions & 31 deletions content_manager/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
from django.conf import settings
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from dsfr.constants import COLOR_CHOICES, COLOR_CHOICES_ILLUSTRATION, COLOR_CHOICES_SYSTEM
from dsfr.constants import COLOR_CHOICES, COLOR_CHOICES_ILLUSTRATION, COLOR_CHOICES_SYSTEM, IMAGE_RATIOS
from wagtail import blocks
from wagtail.blocks import StructValue
from wagtail.documents.blocks import DocumentChooserBlock
from wagtail.images.blocks import ImageChooserBlock
from wagtailmarkdown.blocks import MarkdownBlock

from content_manager.constants import HEADING_CHOICES, LEVEL_CHOICES
from content_manager.constants import HEADING_CHOICES, HORIZONTAL_CARD_IMAGE_RATIOS, LEVEL_CHOICES
from content_manager.widgets import DsfrIconPickerWidget


Expand Down Expand Up @@ -55,6 +56,46 @@ class Meta:
icon = "link"


class LinksVerticalListBlock(blocks.StreamBlock):
link = LinkBlock(label=_("Link"))

class Meta:
icon = "list-ul"
template = "content_manager/blocks/links_vertical_list.html"


button_type_choices = (
("fr-btn", _("Primary")),
("fr-btn fr-btn--secondary", _("Secundary")),
("fr-btn fr-btn--tertiary", _("Tertiary")),
("fr-btn fr-btn--tertiary-no-outline", _("Tertiary without border")),
)


class ButtonBlock(LinkBlock):
button_type = blocks.ChoiceBlock(label=_("Button type"), choices=button_type_choices, required=False)

class Meta:
value_class = LinkStructValue
icon = "link"


class ButtonsHorizontalListBlock(blocks.StreamBlock):
button = ButtonBlock(label=_("Button"))

class Meta:
icon = "list-ul"
template = "content_manager/blocks/buttons_horizontal_list.html"


class ButtonsVerticalListBlock(blocks.StreamBlock):
button = ButtonBlock(label=_("Button"))

class Meta:
icon = "list-ul"
template = "content_manager/blocks/buttons_vertical_list.html"


class IconPickerBlock(blocks.FieldBlock):
def __init__(self, required=True, help_text=None, validators=(), **kwargs):
self.field_options = {
Expand All @@ -78,12 +119,9 @@ class Meta:

## Badges and Tags
badge_level_choices = (
COLOR_CHOICES_SYSTEM
+ [
("new", _("New")),
("grey", _("Grey")),
]
+ COLOR_CHOICES_ILLUSTRATION
("", [("new", _("New")), ("grey", _("Grey"))]),
(_("System colors"), COLOR_CHOICES_SYSTEM),
(_("Illustration colors"), COLOR_CHOICES_ILLUSTRATION),
)


Expand Down Expand Up @@ -128,6 +166,135 @@ class Meta:
template = "content_manager/blocks/tags_list.html"


## Cards


class CardstructValue(StructValue):
def enlarge_link(self):
"""
Determine if we need (and can) enlarge the link on the card.
This requires:
- That a link is present
- That no other link is used on the card (such as a tag with a link, or a call-to-action)
"""
url = self.get("url")
document = self.get("document")
top_detail_badges_tags = self.get("top_detail_badges_tags")
call_to_action = self.get("call_to_action")

if not (url or document):
return False

enlarge = True
if len(call_to_action):
enlarge = False
elif len(top_detail_badges_tags) and top_detail_badges_tags.raw_data[0]["type"] == "tags":
tags_list = top_detail_badges_tags.raw_data[0]["value"]
for tag in tags_list:
if tag["value"]["link"]["page"] is not None or tag["value"]["link"]["external_url"] != "":
enlarge = False

return enlarge

def image_classes(self):
"""
Determine the image classes for a vertical card. Not used in horizontal card.
"""
ratio_class = self.get("image_ratio")

if ratio_class:
image_classes = f"fr-responsive-img {ratio_class}"
else:
image_classes = "fr-responsive-img"

return image_classes


class CardBlock(blocks.StructBlock):
title = blocks.CharBlock(label=_("Title"))
heading_tag = blocks.ChoiceBlock(
label=_("Heading level"),
choices=HEADING_CHOICES,
default="h3",
help_text=_("Adapt to the page layout. Defaults to heading 3."),
)
description = blocks.TextBlock(label=_("Content"), help_text=_("Can contain HTML."), required=False)
image = ImageChooserBlock(label=_("Image"), required=False)
image_ratio = blocks.ChoiceBlock(
label=_("Image ratio"),
choices=IMAGE_RATIOS,
required=False,
default="h3",
)
image_badge = BadgesListBlock(
label=_("Image area badge"), required=False, help_text=_("Only used if the card has an image."), max_num=1
)
url = blocks.URLBlock(label=_("Link"), required=False, group="target")
document = DocumentChooserBlock(
label=_("or Document"),
help_text=_("Select a document to make the card link to it (if the 'Link' field is not populated.)"),
required=False,
group="target",
)
top_detail_text = blocks.CharBlock(label=_("Top detail: text"), required=False)
top_detail_icon = IconPickerBlock(label=_("Top detail: icon"), required=False)
top_detail_badges_tags = blocks.StreamBlock(
[
("badges", BadgesListBlock()),
("tags", TagListBlock()),
],
label=_("Top detail: badges or tags"),
max_num=1,
required=False,
)
bottom_detail_text = blocks.CharBlock(
label=_("Bottom detail: text"),
help_text=_("Incompatible with the bottom call-to-action"),
required=False,
)
bottom_detail_icon = IconPickerBlock(label=_("Bottom detail: icon"), required=False)
call_to_action = blocks.StreamBlock(
[
("links", LinksVerticalListBlock()),
("buttons", ButtonsHorizontalListBlock()),
],
label=_("Bottom call-to-action: links or buttons"),
help_text=_("Incompatible with the bottom detail text"),
max_num=1,
required=False,
)
grey_background = blocks.BooleanBlock(label=_("Card with grey background"), required=False)
no_background = blocks.BooleanBlock(label=_("Card without background"), required=False)
no_border = blocks.BooleanBlock(label=_("Card without border"), required=False)
shadow = blocks.BooleanBlock(label=_("Card with a shadow"), required=False)

class Meta:
icon = "tablet-alt"
template = "content_manager/blocks/card.html"
value_class = CardstructValue


class HorizontalCardBlock(CardBlock):
image_ratio = blocks.ChoiceBlock(
label=_("Image ratio"),
choices=HORIZONTAL_CARD_IMAGE_RATIOS,
required=False,
default="h3",
)

class Meta:
icon = "tablet-alt"
template = "content_manager/blocks/card_horizontal.html"
value_class = CardstructValue


class VerticalCardBlock(CardBlock):
class Meta:
icon = "tablet-alt"
template = "content_manager/blocks/card_vertical.html"
value_class = CardstructValue


## Basic blocks
class AccordionBlock(blocks.StructBlock):
title = blocks.CharBlock(label=_("Title"))
Expand Down Expand Up @@ -162,23 +329,6 @@ class CalloutBlock(blocks.StructBlock):
)


class CardBlock(blocks.StructBlock):
title = blocks.CharBlock(label=_("Title"))
description = blocks.TextBlock(label=_("Content"))
image = ImageChooserBlock(label=_("Image"), required=False)
url = blocks.URLBlock(label=_("Link"), required=False, group="target")
document = DocumentChooserBlock(
label=_("or Document"),
help_text=_("Select a document to make the card link to it (if the 'Link' field is not populated.)"),
required=False,
group="target",
)

class Meta:
icon = "tablet-alt"
template = "content_manager/blocks/card.html"


class IframeBlock(blocks.StructBlock):
title = blocks.CharBlock(
label=_("Title"),
Expand Down Expand Up @@ -350,7 +500,7 @@ class Meta:


class MultiColumnsBlock(CommonStreamBlock):
card = CardBlock(label=_("Vertical card"))
card = VerticalCardBlock(label=_("Vertical card"))

class Meta:
icon = "dots-horizontal"
Expand All @@ -366,7 +516,9 @@ class MultiColumnsWithTitleBlock(blocks.StructBlock):
bg_color = blocks.RegexBlock(
label=_("Background color, hexadecimal format (obsolete)"),
regex=r"^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$",
help_text="(This field is obsolete and will be removed in the near future. Replace it with the background picture)", # noqa
help_text=_(
"This field is obsolete and will be removed in the near future. Replace it with the background color." # noqa
),
error_messages={"invalid": _("Incorrect color format, must be #fff or #f5f5f5")},
required=False,
)
Expand All @@ -387,6 +539,7 @@ class Meta:

class FullWidthBlock(CommonStreamBlock):
image_and_text = ImageAndTextBlock(label=_("Image and text"))
card = HorizontalCardBlock(label=_("Horizontal card"))

class Meta:
icon = "minus"
Expand All @@ -410,14 +563,12 @@ class Meta:
("paragraph", blocks.RichTextBlock(label=_("Rich text"))),
("badges_list", BadgesListBlock(label=_("Badge list"))),
("image", ImageBlock()),
(
"imageandtext",
ImageAndTextBlock(label=_("Image and text")),
),
("imageandtext", ImageAndTextBlock(label=_("Image and text"))),
("alert", AlertBlock(label=_("Alert message"))),
("callout", CalloutBlock(label=_("Callout"))),
("quote", QuoteBlock(label=_("Quote"))),
("video", VideoBlock(label=_("Video"))),
("card", HorizontalCardBlock(label=_("Horizontal card"))),
("accordions", AccordionsBlock(label=_("Accordions"))),
("stepper", StepperBlock(label=_("Stepper"))),
("tags_list", TagListBlock(label=_("Tag list"))),
Expand Down
5 changes: 5 additions & 0 deletions content_manager/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@
("info", "Information"),
("warning", "Attention"),
]

HORIZONTAL_CARD_IMAGE_RATIOS = [
("fr-card--horizontal-tier", "1/3"),
("fr-card--horizontal-half", "50/50"),
]
Binary file modified content_manager/locale/fr/LC_MESSAGES/django.mo
Binary file not shown.
Loading

0 comments on commit 0ec3bf1

Please sign in to comment.