Skip to content

Commit 7967ed8

Browse files
[FEATURE] Gérer l'affichage du bouton "Suivant" avec des éléments répondables (PIX-12856)
#9226
2 parents 36f2e18 + 69a75cb commit 7967ed8

File tree

2 files changed

+204
-2
lines changed

2 files changed

+204
-2
lines changed

mon-pix/app/components/module/stepper.gjs

+22-2
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,31 @@ export default class ModulixStepper extends Component {
2424
return this.stepsToDisplay.length < this.args.steps.length;
2525
}
2626

27+
get answerableElementsInCurrentStep() {
28+
const currentStep = this.stepsToDisplay[this.stepsToDisplay.length - 1];
29+
return currentStep.elements.filter((element) => element.isAnswerable);
30+
}
31+
32+
get allAnswerableElementsAreAnsweredInCurrentStep() {
33+
return this.answerableElementsInCurrentStep.every((element) => {
34+
return this.args.passage.getLastCorrectionForElement(element) !== undefined;
35+
});
36+
}
37+
38+
get shouldDisplayNextButton() {
39+
return this.hasNextStep && this.allAnswerableElementsAreAnsweredInCurrentStep;
40+
}
41+
2742
<template>
2843
{{#each this.stepsToDisplay as |step index|}}
29-
<Step @step={{step}} @currentStep={{inc index}} @totalSteps={{@steps.length}} />
44+
<Step
45+
@step={{step}}
46+
@currentStep={{inc index}}
47+
@totalSteps={{@steps.length}}
48+
@getLastCorrectionForElement={{@getLastCorrectionForElement}}
49+
/>
3050
{{/each}}
31-
{{#if this.hasNextStep}}
51+
{{#if this.shouldDisplayNextButton}}
3252
<PixButton @size="large" @variant="primary" @iconAfter="arrow-down" @triggerAction={{this.displayNextStep}}>{{t
3353
"pages.modulix.buttons.stepper.next"
3454
}}

mon-pix/tests/integration/components/module/stepper_test.gjs

+182
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,188 @@ module('Integration | Component | Module | Stepper', function (hooks) {
4040
assert.dom(screen.getByRole('button', { name: this.intl.t('pages.modulix.buttons.stepper.next') })).exists();
4141
});
4242

43+
module('When step contains answerable elements', function () {
44+
module('When the only answerable element is unanswered', function () {
45+
test('should not display the Next button', async function (assert) {
46+
// given
47+
const steps = [
48+
{
49+
elements: [
50+
{
51+
id: 'd0690f26-978c-41c3-9a21-da931857739c',
52+
instruction: 'Instruction',
53+
proposals: [
54+
{ id: '1', content: 'radio1' },
55+
{ id: '2', content: 'radio2' },
56+
],
57+
isAnswerable: true,
58+
type: 'qcu',
59+
},
60+
],
61+
},
62+
{
63+
elements: [
64+
{
65+
id: '768441a5-a7d6-4987-ada9-7253adafd842',
66+
type: 'text',
67+
content: '<p>Text 2</p>',
68+
isAnswerable: false,
69+
},
70+
],
71+
},
72+
];
73+
function getLastCorrectionForElementStub() {}
74+
75+
const store = this.owner.lookup('service:store');
76+
const passage = store.createRecord('passage');
77+
passage.getLastCorrectionForElement = getLastCorrectionForElementStub;
78+
79+
// when
80+
const screen = await render(
81+
<template>
82+
<ModulixStepper
83+
@passage={{passage}}
84+
@steps={{steps}}
85+
@getLastCorrectionForElement={{getLastCorrectionForElementStub}}
86+
/>
87+
</template>,
88+
);
89+
90+
// then
91+
assert
92+
.dom(screen.queryByRole('button', { name: this.intl.t('pages.modulix.buttons.stepper.next') }))
93+
.doesNotExist();
94+
});
95+
});
96+
97+
module('When at least one of the answerable elements is unanswered', function () {
98+
test('should not display the Next button', async function (assert) {
99+
// given
100+
const steps = [
101+
{
102+
elements: [
103+
{
104+
id: 'd0690f26-978c-41c3-9a21-da931857739c',
105+
instruction: 'Instruction',
106+
proposals: [
107+
{ id: '1', content: 'radio1' },
108+
{ id: '2', content: 'radio2' },
109+
],
110+
isAnswerable: true,
111+
type: 'qcu',
112+
},
113+
{
114+
id: '69f08624-6e63-4be1-b662-6e6bc820d99f',
115+
instruction: 'Instruction',
116+
proposals: [
117+
{ id: '1', content: 'radio3' },
118+
{ id: '2', content: 'radio4' },
119+
],
120+
isAnswerable: true,
121+
type: 'qcu',
122+
},
123+
],
124+
},
125+
{
126+
elements: [
127+
{
128+
id: '768441a5-a7d6-4987-ada9-7253adafd842',
129+
type: 'text',
130+
content: '<p>Text 2</p>',
131+
isAnswerable: false,
132+
},
133+
],
134+
},
135+
];
136+
function getLastCorrectionForElementStub(element) {
137+
if (element.id === 'd0690f26-978c-41c3-9a21-da931857739c') {
138+
return Symbol('Correction');
139+
} else {
140+
return undefined;
141+
}
142+
}
143+
144+
const store = this.owner.lookup('service:store');
145+
const passage = store.createRecord('passage');
146+
passage.getLastCorrectionForElement = getLastCorrectionForElementStub;
147+
148+
// when
149+
const screen = await render(
150+
<template>
151+
<ModulixStepper
152+
@passage={{passage}}
153+
@steps={{steps}}
154+
@getLastCorrectionForElement={{getLastCorrectionForElementStub}}
155+
/>
156+
</template>,
157+
);
158+
159+
// then
160+
assert
161+
.dom(screen.queryByRole('button', { name: this.intl.t('pages.modulix.buttons.stepper.next') }))
162+
.doesNotExist();
163+
});
164+
});
165+
166+
module('When all answerable elements are answered', function () {
167+
test('should display the next button', async function (assert) {
168+
// given
169+
const steps = [
170+
{
171+
elements: [
172+
{
173+
id: 'd0690f26-978c-41c3-9a21-da931857739c',
174+
instruction: 'Instruction',
175+
proposals: [
176+
{ id: '1', content: 'radio1' },
177+
{ id: '2', content: 'radio2' },
178+
],
179+
isAnswerable: true,
180+
type: 'qcu',
181+
},
182+
],
183+
},
184+
{
185+
elements: [
186+
{
187+
id: '768441a5-a7d6-4987-ada9-7253adafd842',
188+
type: 'text',
189+
content: '<p>Text 2</p>',
190+
isAnswerable: false,
191+
},
192+
],
193+
},
194+
];
195+
function getLastCorrectionForElementStub() {}
196+
197+
const store = this.owner.lookup('service:store');
198+
const passage = store.createRecord('passage');
199+
const correction = store.createRecord('correction-response');
200+
store.createRecord('element-answer', {
201+
elementId: 'd0690f26-978c-41c3-9a21-da931857739c',
202+
correction,
203+
passage,
204+
});
205+
206+
// when
207+
const screen = await render(
208+
<template>
209+
<ModulixStepper
210+
@passage={{passage}}
211+
@steps={{steps}}
212+
@getLastCorrectionForElement={{getLastCorrectionForElementStub}}
213+
/>
214+
</template>,
215+
);
216+
217+
// then
218+
assert
219+
.dom(screen.queryByRole('button', { name: this.intl.t('pages.modulix.buttons.stepper.next') }))
220+
.exists();
221+
});
222+
});
223+
});
224+
43225
module('When user clicks on the Next button', function () {
44226
test('should display the next step', async function (assert) {
45227
// given

0 commit comments

Comments
 (0)