-
Notifications
You must be signed in to change notification settings - Fork 24
Leader rejection #876
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
base: main
Are you sure you want to change the base?
Leader rejection #876
Changes from all commits
214ad7b
b119d2e
44464db
fc56d45
5cca7e4
6177801
f972a8d
3019be8
de581c6
1d73017
eeb37bd
c61c654
1c0835d
db9a3e4
3c7b5bf
d581a84
be7637e
293061e
1e9f7bb
bebfd14
da1b34b
70564f1
2517f0d
724a80a
8e72519
28b9a32
d8056a9
7dee7db
a48cd4b
3620dbe
86d9814
ea14302
3eed571
ad35be9
16fe8ff
3e07517
5917364
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,7 @@ import { | |
| createAssetAllocationStage, | ||
| createChatStage, | ||
| createRankingStage, | ||
| createLRRankingStage, | ||
| createInfoStage, | ||
| createFlipCardStage, | ||
| createMultiAssetAllocationStage, | ||
|
|
@@ -41,6 +42,10 @@ import { | |
| getLASStageConfigs, | ||
| getAnonLASStageConfigs, | ||
| } from '../../shared/templates/lost_at_sea'; | ||
| import { | ||
| LR_METADATA, | ||
| getLeadershipRejectionStageConfigs, | ||
| } from '../../shared/templates/leader_rejection_template'; | ||
| import { | ||
| getChipMetadata, | ||
| getChipNegotiationStageConfigs, | ||
|
|
@@ -173,7 +178,7 @@ export class StageBuilderDialog extends MobxLitElement { | |
| configuration! | ||
| </div> | ||
| <div class="card-gallery-wrapper"> | ||
| ${this.renderFlipCardTemplateCard()} | ||
| ${this.renderLRCard()} ${this.renderFlipCardTemplateCard()} | ||
| ${this.renderFruitTestTemplateCard()} | ||
| ${this.renderConditionalSurveyTemplateCard()} | ||
| ${this.renderStockInfoGameCard()} | ||
|
|
@@ -242,8 +247,8 @@ export class StageBuilderDialog extends MobxLitElement { | |
| ${this.renderTransferCard()} ${this.renderSurveyCard()} | ||
| ${this.renderSurveyPerParticipantCard()} | ||
| ${this.renderComprehensionCard()} ${this.renderRankingCard()} | ||
| ${this.renderRevealCard()} ${this.renderPayoutCard()} | ||
| ${this.renderRoleCard()} | ||
| ${this.renderLRRankingCard()} ${this.renderRevealCard()} | ||
| ${this.renderPayoutCard()} ${this.renderRoleCard()} | ||
| </div> | ||
| </div> | ||
|
|
||
|
|
@@ -301,6 +306,25 @@ export class StageBuilderDialog extends MobxLitElement { | |
| `; | ||
| } | ||
|
|
||
| private renderLRCard() { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here and elsewhere, it won't be immediately clear to the reader of the code that "LR" means "Leader Rejection". Recommend spelling it out everywhere. (The |
||
| const metadata = LR_METADATA; | ||
| const configs = getLeadershipRejectionStageConfigs(); | ||
|
|
||
| const addGame = () => { | ||
| this.addGame(metadata, configs); | ||
| }; | ||
|
|
||
| return html` | ||
| <div class="card" @click=${addGame}> | ||
| <div class="title">${metadata.name}</div> | ||
| <div> | ||
| ${metadata.description} | ||
| <div></div> | ||
| </div> | ||
| </div> | ||
| `; | ||
| } | ||
|
|
||
| private renderAgentIntegrationCard() { | ||
| const addTemplate = () => { | ||
| this.addTemplate(getAgentParticipantIntegrationTemplate()); | ||
|
|
@@ -508,6 +532,22 @@ export class StageBuilderDialog extends MobxLitElement { | |
| `; | ||
| } | ||
|
|
||
| private renderLRRankingCard() { | ||
| const addStage = () => { | ||
| this.addStage(createLRRankingStage()); | ||
| }; | ||
|
|
||
| return html` | ||
| <div class="card" @click=${addStage}> | ||
| <div class="title">🗳️ LR Triggering Selection Logic</div> | ||
| <div> | ||
| TODO: Stage that triggers the selection of a leader based on candidacy | ||
| and performance in two initial tasks | ||
| </div> | ||
| </div> | ||
| `; | ||
| } | ||
|
|
||
| private renderRevealCard() { | ||
| const addStage = () => { | ||
| this.addStage(createRevealStage()); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| import '../participant_profile/profile_display'; | ||
|
|
||
| import {MobxLitElement} from '@adobe/lit-mobx'; | ||
| import {CSSResultGroup, html, nothing} from 'lit'; | ||
| import {customElement, property} from 'lit/decorators.js'; | ||
|
|
||
| import {LRRankingStagePublicData} from '@deliberation-lab/utils'; | ||
| import {core} from '../../core/core'; | ||
| import {ParticipantService} from '../../services/participant.service'; | ||
| import {styles} from './ranking_reveal_view.scss'; | ||
| import {getParticipantInlineDisplay} from '../../shared/participant.utils'; | ||
|
|
||
| import {CohortService} from '../../services/cohort.service'; | ||
|
|
||
| /** Leader selection reveal view */ | ||
| @customElement('leader-reveal-view') | ||
| export class LeaderRevealView extends MobxLitElement { | ||
| static override styles: CSSResultGroup = [styles]; | ||
|
|
||
| private readonly participantService = core.getService(ParticipantService); | ||
| private readonly cohortService = core.getService(CohortService); | ||
|
|
||
| @property() publicData: LRRankingStagePublicData | undefined = undefined; | ||
|
|
||
| override render() { | ||
| if (!this.publicData) return html`<p><em>Waiting for results...</em></p>`; | ||
|
|
||
| const leaderStatusMap = this.publicData.leaderStatusMap || {}; | ||
| const winnerId = this.publicData.winnerId || ''; | ||
| const participantId = this.participantService.profile?.publicId ?? ''; // ✅ FIXED | ||
| const status = leaderStatusMap[participantId] ?? 'waiting'; | ||
|
|
||
| const messages: Record<string, string> = { | ||
| candidate_accepted: '✅ You applied and were selected as leader!', | ||
| candidate_rejected: '❌ You applied but were not selected.', | ||
| non_candidate_accepted: | ||
| '✅ You did not apply, but since no one else did, you were selected!', | ||
| non_candidate_rejected: '❌ You did not apply and were not selected.', | ||
| non_candidate_hypo_selected: | ||
| '💡 You did not apply, but had you done so, you would have been selected.', | ||
| non_candidate_hypo_rejected: | ||
| 'ℹ️ You did not apply, and even if you had, you would not have been selected.', | ||
| waiting: '⏳ Waiting for results...', | ||
| }; | ||
|
|
||
| // 🔍 Determine whether to show who the leader is | ||
| const showWinner = | ||
| winnerId && participantId !== winnerId && status !== 'waiting'; | ||
|
|
||
| // 🔍 Convert winnerId → "Participant 7506" | ||
| let winnerPretty: string | null = null; | ||
| if (showWinner) { | ||
| const winnerProfile = this.cohortService.participantMap?.[winnerId]; | ||
| if (winnerProfile) { | ||
| winnerPretty = getParticipantInlineDisplay(winnerProfile); // 👈 magic happens here | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What magic happens? |
||
| } else { | ||
| winnerPretty = winnerId; // fallback (should rarely happen) | ||
| } | ||
| } | ||
|
|
||
| console.log('[LeaderRevealView] my ID:', participantId); | ||
| console.log('[LeaderRevealView] all keys:', Object.keys(leaderStatusMap)); | ||
| console.log( | ||
| '[LeaderRevealView] publicData snapshot:', | ||
| JSON.parse(JSON.stringify(this.publicData)), | ||
| ); | ||
|
|
||
| return html` | ||
| <div class="leader-status-block"> | ||
| <h3>Leader Selection Result</h3> | ||
| <p>${messages[status] ?? messages.waiting}</p> | ||
| ${showWinner && winnerPretty | ||
| ? html` | ||
| <p style="margin-top: 12px; font-size: 0.95em; opacity: 0.8;"> | ||
| ⭐ <strong>${winnerPretty}</strong> was selected as the leader. | ||
| </p> | ||
| ` | ||
| : nothing} | ||
| </div> | ||
| `; | ||
| } | ||
| } | ||
|
|
||
| declare global { | ||
| interface HTMLElementTagNameMap { | ||
| 'leader-reveal-view': LeaderRevealView; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| import {MobxLitElement} from '@adobe/lit-mobx'; | ||
| import {html, nothing} from 'lit'; | ||
| import {customElement, property} from 'lit/decorators.js'; | ||
|
|
||
| import {core} from '../../core/core'; | ||
| import {ParticipantService} from '../../services/participant.service'; | ||
| import {RankingStageConfig} from '@deliberation-lab/utils'; | ||
|
|
||
| @customElement('lr-info-ranking-view') | ||
| export class LRInfoRankingView extends MobxLitElement { | ||
| @property() stage!: RankingStageConfig; | ||
|
|
||
| private readonly participantService = core.getService(ParticipantService); | ||
|
|
||
| override render() { | ||
| if (!this.stage) return nothing; | ||
|
|
||
| return html` | ||
| <div class="lr-info-wrapper"> | ||
| <h3>${this.stage.name}</h3> | ||
| <p>This is an information-only page. No ranking is required.</p> | ||
|
|
||
| <button @click=${this.next}>Next</button> | ||
| </div> | ||
| `; | ||
| } | ||
|
|
||
| private async next() { | ||
| // Submit empty ranking list → triggers LR logic | ||
| const ps = this.participantService; | ||
| await ps.updateRankingStageParticipantAnswer( | ||
| this.stage.id, | ||
| [], // very important! | ||
| ); | ||
|
|
||
| await ps.progressToNextStage(); | ||
| } | ||
| } | ||
|
|
||
| declare global { | ||
| interface HTMLElementTagNameMap { | ||
| 'lr-info-ranking-view': LRInfoRankingView; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -296,8 +296,9 @@ export class PayoutView extends MobxLitElement { | |
| <div class="row"> | ||
| <div> | ||
| ${rankingWinner !== null | ||
| ? `Election winner's answer:` | ||
| : 'Your answer:'} | ||
| ? `Leader's answer:` | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like it would affect experiments other than Leader Rejection. |
||
| : //? `Election winner's answer:` | ||
| 'Your answer:'} | ||
| </div> | ||
| <div class="chip secondary">${participantAnswer?.text ?? ''}</div> | ||
| </div> | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to edit this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @jimbojw , no I think this was an unintended IDE auto-formatting change