Skip to content

Commit a3e9b35

Browse files
committed
Add ability to show accepted speakers/proposals
1 parent b652530 commit a3e9b35

File tree

23 files changed

+286
-63
lines changed

23 files changed

+286
-63
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from typing import Self
2+
import strawberry
3+
from api.cms.page.registry import register_page_block
4+
import enum
5+
6+
7+
@strawberry.enum
8+
class DynamicContentDisplaySectionSource(enum.Enum):
9+
speakers = "speakers"
10+
keynoters = "keynoters"
11+
accepted_proposals = "accepted_proposals"
12+
13+
14+
@register_page_block()
15+
@strawberry.type
16+
class DynamicContentDisplaySection:
17+
id: strawberry.ID
18+
source: DynamicContentDisplaySectionSource
19+
20+
@classmethod
21+
def from_block(cls, block) -> Self:
22+
return cls(
23+
id=block.id,
24+
source=DynamicContentDisplaySectionSource(block.value["source"]),
25+
)

backend/api/conferences/types.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,21 @@ def proposal_tags(self, info: Info) -> list[SubmissionTag]:
221221
return self.proposal_tags.all()
222222

223223
@strawberry.field(permission_classes=[CanSeeSubmissions])
224-
def submissions(self, info: Info) -> list[Submission] | None:
225-
return self.submissions.filter(
226-
status__in=(
227-
SubmissionModel.STATUS.proposed,
228-
SubmissionModel.STATUS.accepted,
224+
def submissions(
225+
self, info: Info, only_accepted: bool = False
226+
) -> list[Submission] | None:
227+
qs = self.submissions
228+
if only_accepted:
229+
qs = qs.filter(status=SubmissionModel.STATUS.accepted)
230+
else:
231+
qs = qs.filter(
232+
status__in=(
233+
SubmissionModel.STATUS.proposed,
234+
SubmissionModel.STATUS.accepted,
235+
)
229236
)
230-
).select_related("audience_level", "duration", "type", "topic")
237+
238+
return qs.select_related("audience_level", "duration", "type", "topic")
231239

232240
@strawberry.field
233241
def events(self, info: Info) -> list[Event]:

backend/api/participants/queries.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,14 @@
1616

1717
@strawberry.field
1818
def participant(
19-
info: Info, user_id: strawberry.ID, conference: str
19+
info: Info, id: strawberry.ID, conference: str
2020
) -> Optional[Participant]:
21-
user = info.context.request.user
22-
decoded_id = decode_hashid(user_id, salt=settings.USER_ID_HASH_SALT, min_length=6)
21+
decoded_id = decode_hashid(id, salt=settings.USER_ID_HASH_SALT, min_length=6)
2322
participant = ParticipantModel.objects.filter(
24-
conference__code=conference, user_id=decoded_id
23+
conference__code=conference, id=decoded_id
2524
).first()
2625

27-
if not participant or (
28-
not participant.public_profile and (not user or participant.user_id != user.id)
29-
):
30-
# Profile doesn't exist, or
31-
# Profile is not public, and the person requesting it is not the owner
26+
if not participant:
3227
return None
3328

3429
return Participant.from_model(participant)

backend/api/participants/types.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
@strawberry.type
1111
class Participant:
1212
id: ID
13-
user_id: ID
1413
bio: str
1514
website: str
1615
photo: str | None
@@ -21,7 +20,6 @@ class Participant:
2120
linkedin_url: str
2221
facebook_url: str
2322
mastodon_handle: str
24-
speaker_id: strawberry.Private[int]
2523
fullname: str
2624
speaker_availabilities: JSON
2725

@@ -46,8 +44,6 @@ def previous_talk_video(self, info) -> Optional[str]:
4644
def from_model(cls, instance):
4745
return cls(
4846
id=instance.hashid,
49-
user_id=instance.user_id,
50-
speaker_id=instance.user_id,
5147
fullname=instance.user.fullname,
5248
photo=instance.photo_url,
5349
photo_id=instance.photo_file_id,

backend/api/permissions.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,12 @@ def has_permission(self, source, info, **kwargs):
3838
class CanSeeSubmissions(BasePermission):
3939
message = "You need to have a ticket to see submissions"
4040

41-
def has_permission(self, conference, info):
41+
def has_permission(self, conference, info, *args, **kwargs):
4242
user = info.context.request.user
4343

44+
if kwargs.get("only_accepted", False):
45+
return True
46+
4447
if not user.is_authenticated:
4548
return False
4649

backend/api/submissions/types.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from participants.models import Participant as ParticipantModel
2+
from api.participants.types import Participant
13
import strawberry
24
from strawberry.types.field import StrawberryField
35
from strawberry.types import Info
@@ -126,17 +128,16 @@ def abstract(self, language: str, info: Info) -> str | None:
126128
return self.abstract.localize(language)
127129

128130
@strawberry.field
129-
def speaker(self, info: Info) -> SubmissionSpeaker | None:
131+
def speaker(self, info: Info) -> Participant | None:
130132
if not CanSeeSubmissionRestrictedFields().has_permission(
131133
self, info, is_speaker_data=True
132134
):
133135
return None
134136

135-
return SubmissionSpeaker(
136-
id=self.speaker_id,
137-
full_name=self.speaker.full_name,
138-
gender=self.speaker.gender,
139-
)
137+
participant = ParticipantModel.objects.filter(
138+
user_id=self.speaker_id, conference_id=self.conference_id
139+
).first()
140+
return Participant.from_model(participant) if participant else None
140141

141142
@strawberry.field
142143
def id(self, info) -> strawberry.ID:
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from wagtail import blocks
2+
3+
4+
class DynamicContentDisplaySection(blocks.StructBlock):
5+
source = blocks.ChoiceBlock(
6+
choices=[
7+
("speakers", "Speakers"),
8+
("keynoters", "Keynoters"),
9+
("accepted_proposals", "Accepted Proposals"),
10+
],
11+
)

backend/cms/components/page/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from cms.components.page.blocks.dynamic_content_display_section import (
2+
DynamicContentDisplaySection,
3+
)
14
from cms.components.page.blocks.homepage_hero import HomepageHero
25
from cms.components.page.blocks.sponsors_section import SponsorsSection
36
from cms.components.home.blocks.home_intro_section import HomeIntroSection
@@ -37,6 +40,7 @@ class BodyBlock(blocks.StreamBlock):
3740
checkout_section = CheckoutSection()
3841
live_streaming_section = LiveStreamingSection()
3942
homepage_hero = HomepageHero()
43+
dynamic_content_display_section = DynamicContentDisplaySection()
4044

4145

4246
class GenericPage(CustomHeadlessMixin, Page):

backend/custom_admin/src/components/fragments/submission.graphql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ fragment SubmissionFragment on Submission {
1717
}
1818
speaker {
1919
id
20-
fullName
20+
fullname
2121
}
2222
}

backend/custom_admin/src/components/schedule-builder/add-item-modal/proposal-preview.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const ProposalPreview = ({ proposal }: Props) => {
2020
info={[
2121
{ label: "Type", value: proposal.type.name },
2222
{ label: "Duration", value: `${proposal.duration.duration} mins` },
23-
{ label: "Speaker", value: proposal.speaker.fullName },
23+
{ label: "Speaker", value: proposal.speaker.fullname },
2424
]}
2525
/>
2626
<AddActions proposal={proposal} />

0 commit comments

Comments
 (0)