Skip to content

Commit

Permalink
Merge pull request #484 from con2/feat/program-v2-dimension-flags
Browse files Browse the repository at this point in the history
Dimension flags, location in scheduleItem and color in DimensionValue
  • Loading branch information
japsu committed Jun 1, 2024
2 parents 83498a5 + 4a84c1f commit 1a224b5
Show file tree
Hide file tree
Showing 21 changed files with 424 additions and 296 deletions.
2 changes: 1 addition & 1 deletion backend/core/static_src/less/tracon_categories.less
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
}

.schedule .color7 {
background-color: rgb(41, 141, 166);
background-color: #298da6;
}

.schedule .sisainen {
Expand Down
19 changes: 19 additions & 0 deletions backend/program_v2/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,22 @@
en=["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
sv=["måndag", "tisdag", "onsdag", "torsdag", "fredag", "lördag", "söndag"],
)


DEFAULT_COLORS = dict(
color1="#5eb95e",
color2="#8058a5",
color3="#0e90d2",
color4="#dd514c",
color5="#f37b1d",
color6="#ff50b8",
color7="#298da6",
# these correspond to color1–5
muu="#5eb95e",
rope="#8058a5",
anime="#0e90d2",
cosplay="#dd514c",
miitti="#f37b1d",
# this used to be striped background but let's make it gray
sisainen="#999999",
)
14 changes: 12 additions & 2 deletions backend/program_v2/graphql/dimension.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ class DimensionType(DjangoObjectType):

class Meta:
model = Dimension
fields = ("slug", "values")
fields = (
"slug",
"values",
"is_multi_value",
"is_list_filter",
"is_shown_in_detail",
"is_negative_selection",
)


class DimensionValueType(DjangoObjectType):
Expand All @@ -25,7 +32,10 @@ class DimensionValueType(DjangoObjectType):

class Meta:
model = DimensionValue
fields = ("slug",)
fields = (
"slug",
"color",
)


class ProgramDimensionValueType(DjangoObjectType):
Expand Down
47 changes: 35 additions & 12 deletions backend/program_v2/graphql/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,6 @@ class Meta:
model = ProgramV2EventMeta
fields = ("skip_offer_form_selection", "location_dimension")

programs = graphene.List(
graphene.NonNull(ProgramType),
filters=graphene.List(DimensionFilterInput),
favorites_only=graphene.Boolean(),
hide_past=graphene.Boolean(),
)

@staticmethod
def resolve_programs(
meta: ProgramV2EventMeta,
Expand All @@ -53,7 +46,12 @@ def resolve_programs(
hide_past=hide_past,
).filter_program(programs, user=request.user)

dimensions = graphene.List(graphene.NonNull(DimensionType))
programs = graphene.NonNull(
graphene.List(graphene.NonNull(ProgramType)),
filters=graphene.List(DimensionFilterInput),
favorites_only=graphene.Boolean(),
hide_past=graphene.Boolean(),
)

@staticmethod
def resolve_program(meta: ProgramV2EventMeta, info, slug: str):
Expand All @@ -62,10 +60,33 @@ def resolve_program(meta: ProgramV2EventMeta, info, slug: str):
program = graphene.Field(ProgramType, slug=graphene.String(required=True))

@staticmethod
def resolve_dimensions(meta: ProgramV2EventMeta, info):
return Dimension.objects.filter(event=meta.event)
def resolve_dimensions(
meta: ProgramV2EventMeta,
info,
is_list_filter: bool = False,
is_shown_in_detail: bool = False,
):
"""
`is_list_filter` - only return dimensions that are shown in the list filter.
`is_shown_in_detail` - only return dimensions that are shown in the detail view.
If you supply both, you only get their intersection.
"""
dimensions = Dimension.objects.filter(event=meta.event)

offer_forms = graphene.List(graphene.NonNull(OfferFormType), include_inactive=graphene.Boolean())
if is_list_filter:
dimensions = dimensions.filter(is_list_filter=True)

if is_shown_in_detail:
dimensions = dimensions.filter(is_shown_in_detail=True)

return dimensions

dimensions = graphene.NonNull(
graphene.List(graphene.NonNull(DimensionType)),
is_list_filter=graphene.Boolean(),
is_shown_in_detail=graphene.Boolean(),
description=normalize_whitespace(resolve_dimensions.__doc__ or ""),
)

@staticmethod
def resolve_offer_forms(meta: ProgramV2EventMeta, info, include_inactive: bool = False):
Expand All @@ -77,12 +98,14 @@ def resolve_offer_forms(meta: ProgramV2EventMeta, info, include_inactive: bool =

return qs

offer_form = graphene.Field(OfferFormType, slug=graphene.String(required=True))
offer_forms = graphene.List(graphene.NonNull(OfferFormType), include_inactive=graphene.Boolean())

@staticmethod
def resolve_offer_form(meta: ProgramV2EventMeta, info, slug: str):
return OfferForm.objects.get(event=meta.event, slug=slug)

offer_form = graphene.Field(OfferFormType, slug=graphene.String(required=True))

@staticmethod
def resolve_calendar_export_link(meta: ProgramV2EventMeta, info):
"""
Expand Down
59 changes: 47 additions & 12 deletions backend/program_v2/graphql/program.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
from core.utils.locale_utils import get_message_in_language
from core.utils.text_utils import normalize_whitespace
from graphql_api.language import DEFAULT_LANGUAGE
from graphql_api.utils import resolve_localized_field

from ..models import Program
from .dimension import ProgramDimensionValueType

# imported for side effects (register object type used by django object type fields)
from .schedule import ScheduleItemType # noqa: F401
Expand Down Expand Up @@ -135,18 +137,17 @@ def resolve_cached_hosts(parent: Program, info):

cached_hosts = graphene.NonNull(graphene.String)

@staticmethod
def resolve_location(parent: Program, info, lang=DEFAULT_LANGUAGE):
"""
Get the location of the program in the format it should be displayed in to the participant.
Currently this simply returns the value of the location dimension in the language specified.
In the future, also a freeform location field could be supported.
"""
return parent.get_location(lang) or ""
resolve_location = resolve_localized_field("cached_location")

location = graphene.NonNull(
graphene.String,
description=normalize_whitespace(resolve_location.__doc__ or ""),
location = graphene.String(
description=normalize_whitespace(
"""
Supplied for convenience. Prefer scheduleItem.location if possible.
Caveat: When a program item has multiple schedule items, they may be in different locations.
In such cases, a comma separated list of locations is returned.
"""
),
lang=graphene.String(),
)

@staticmethod
Expand Down Expand Up @@ -220,13 +221,47 @@ def resolve_calendar_export_link(program: Program, info):
),
)

@staticmethod
def resolve_dimensions(
program: Program,
info,
is_list_filter: bool = False,
is_shown_in_detail: bool = False,
):
"""
`is_list_filter` - only return dimensions that are shown in the list filter.
`is_shown_in_detail` - only return dimensions that are shown in the detail view.
If you supply both, you only get their intersection.
"""
pdvs = program.dimensions.all()

if is_list_filter:
pdvs = pdvs.filter(dimension__is_list_filter=True)

if is_shown_in_detail:
pdvs = pdvs.filter(dimension__is_shown_in_detail=True)

return pdvs

dimensions = graphene.NonNull(
graphene.List(graphene.NonNull(ProgramDimensionValueType)),
is_list_filter=graphene.Boolean(),
is_shown_in_detail=graphene.Boolean(),
description=normalize_whitespace(resolve_dimensions.__doc__ or ""),
)

@staticmethod
def resolve_color(program: Program, info):
return program.cached_color

color = graphene.NonNull(graphene.String)

class Meta:
model = Program
fields = (
"title",
"slug",
"description",
"dimensions",
"cached_dimensions",
"schedule_items",
"cached_earliest_start_time",
Expand Down
9 changes: 7 additions & 2 deletions backend/program_v2/graphql/schedule.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import graphene
from graphene_django import DjangoObjectType

from graphql_api.utils import resolve_localized_field

from ..models import (
ScheduleItem,
)
Expand All @@ -19,7 +21,7 @@ def resolve_length_minutes(parent: ScheduleItem, info):

@staticmethod
def resolve_end_time(parent: ScheduleItem, info):
return parent.end_time
return parent.cached_end_time

end_time = graphene.NonNull(graphene.DateTime)

Expand All @@ -31,6 +33,9 @@ def resolve_start_time_unix_seconds(parent: ScheduleItem, info):

@staticmethod
def resolve_end_time_unix_seconds(parent: ScheduleItem, info):
return int(parent.end_time.timestamp())
return int(parent.cached_end_time.timestamp())

end_time_unix_seconds = graphene.NonNull(graphene.Int)

resolve_location = resolve_localized_field("cached_location")
location = graphene.String(lang=graphene.String())
3 changes: 3 additions & 0 deletions backend/program_v2/handlers/dimension.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ def program_dimension_value_post_save(sender, instance: ProgramDimensionValue, *
program = instance.program
program.refresh_cached_dimensions()

for schedule_item in program.schedule_items.all():
schedule_item.refresh_cached_fields()


@receiver(pre_save, sender=(Dimension, DimensionValue))
def dimension_pre_save(sender, instance: Dimension | DimensionValue, **kwargs):
Expand Down
7 changes: 6 additions & 1 deletion backend/program_v2/importers/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from ..consts import (
CATEGORY_DIMENSION_TITLE_LOCALIZED,
DATE_DIMENSION_TITLE_LOCALIZED,
DEFAULT_COLORS,
ROOM_DIMENSION_TITLE_LOCALIZED,
TAG_DIMENSION_TITLE_LOCALIZED,
WEEKDAYS_LOCALIZED,
Expand Down Expand Up @@ -88,7 +89,11 @@ def get_dimensions(self) -> list[DimensionDTO]:
slug="category",
title=CATEGORY_DIMENSION_TITLE_LOCALIZED,
choices=[
DimensionValueDTO(slug=category.slug, title={self.language: category.title})
DimensionValueDTO(
slug=category.slug,
title={self.language: category.title},
color=DEFAULT_COLORS.get(category.style, ""),
)
for category in Category.objects.filter(event=self.event)
],
),
Expand Down
13 changes: 11 additions & 2 deletions backend/program_v2/importers/solmukohta2024.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from programme.models.programme import Programme
from programme.models.tag import Tag

from ..consts import DEFAULT_COLORS
from ..models.dimension import DimensionDTO, DimensionValueDTO
from .default import DefaultImporter

Expand Down Expand Up @@ -143,15 +144,23 @@ def get_dimensions(self):
slug="sk-type",
title={"en": "Program type (Solmukohta)", "fi": "Ohjelman tyyppi (Solmukohta)"},
choices=[
DimensionValueDTO(slug=normalize_sk_type_value(category.slug), title={"en": category.title})
DimensionValueDTO(
slug=normalize_sk_type_value(category.slug),
title={"en": category.title},
color=DEFAULT_COLORS.get(category.style, ""),
)
for category in Category.objects.filter(event=self.event).exclude(slug="aweek-program")
],
),
DimensionDTO(
slug="aw-type",
title={"en": "Program type (A Week)", "fi": "Ohjelman tyyppi (A Week)"},
choices=[
DimensionValueDTO(slug=normalislug(tag.slug), title={"en": tag.title[len("A Week - ") :]})
DimensionValueDTO(
slug=normalislug(tag.slug),
title={"en": tag.title[len("A Week - ") :]},
color=DEFAULT_COLORS["color6"],
)
for tag in Tag.objects.filter(event=self.event, title__startswith="A Week")
],
),
Expand Down
Loading

0 comments on commit 1a224b5

Please sign in to comment.