From 771631de249c1b867b378355ea85c5c2aacd4316 Mon Sep 17 00:00:00 2001 From: rouxxi Date: Tue, 14 Jan 2025 15:52:37 +0100 Subject: [PATCH 1/3] style(junior): change layout of challenges Challenge layout is adapted according to the list of contained elements: * form * illustration * embed If the challenge contains 2 elements, the layout has 2 columns. 60% of the width is assigned to the embedded element if there is one. Else, each column has 50% width. --- junior/app/components/card-wrapper.gjs | 5 + .../challenge/challenge-content.gjs | 128 +++++++++--------- junior/app/components/challenge/challenge.gjs | 2 +- .../challenge/content/challenge-media.gjs | 56 ++++---- junior/app/models/challenge.js | 20 +-- junior/app/styles/app.scss | 1 + .../app/styles/components/card-wrapper.scss | 7 + .../challenge/challenge-actions.scss | 2 +- .../challenge/challenge-content.scss | 43 +++--- .../integration/challenge-content_test.gjs | 23 ++-- junior/tests/unit/models/challenge-test.js | 21 +-- mon-pix/tests/unit/models/challenge-test.js | 2 +- 12 files changed, 162 insertions(+), 148 deletions(-) create mode 100644 junior/app/components/card-wrapper.gjs create mode 100644 junior/app/styles/components/card-wrapper.scss diff --git a/junior/app/components/card-wrapper.gjs b/junior/app/components/card-wrapper.gjs new file mode 100644 index 00000000000..af16ad837e7 --- /dev/null +++ b/junior/app/components/card-wrapper.gjs @@ -0,0 +1,5 @@ + diff --git a/junior/app/components/challenge/challenge-content.gjs b/junior/app/components/challenge/challenge-content.gjs index 7ea4832d4b4..3303e4e33b6 100644 --- a/junior/app/components/challenge/challenge-content.gjs +++ b/junior/app/components/challenge/challenge-content.gjs @@ -2,6 +2,7 @@ import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { or } from 'ember-truth-helpers'; +import CardWrapper from '../card-wrapper'; import AutoReply from './content/auto-reply'; import ChallengeActions from './content/challenge-actions'; import ChallengeMedia from './content/challenge-media'; @@ -23,17 +24,28 @@ export default class ChallengeContent extends Component { }); } - get isMediaWithForm() { + get shouldDisplayMultipleElements() { const challenge = this.args.challenge; - return challenge.hasForm && this.hasMedia && challenge.hasType; + const hasMediaAndForm = challenge.hasForm && challenge.hasMedia && challenge.hasType; + const hasIllustrationAndEmbed = challenge.illustrationUrl && challenge.hasEmbed; + const hasIllustrationAndWebComponent = challenge.illustrationUrl && challenge.hasWebComponent; + const hasFormAndEmbed = challenge.hasForm && challenge.hasEmbed; + + return hasMediaAndForm || hasIllustrationAndEmbed || hasIllustrationAndWebComponent || hasFormAndEmbed; } - get hasMedia() { - return ( - this.args.challenge.illustrationUrl || - this.args.challenge.hasValidEmbedDocument || - this.args.challenge.hasWebComponent - ); + get challengeContentClassname() { + const hasIllustrationAndEmbed = this.args.challenge.illustrationUrl && this.args.challenge.hasEmbed; + let classname = ''; + + if (this.shouldDisplayMultipleElements) { + classname = 'challenge-content__grid-multiple-element'; + + if (hasIllustrationAndEmbed) { + classname += ' challenge-content__grid-multiple-element--1x-2x'; + } + } + return classname; } get shouldDisplayRebootButton() { @@ -41,54 +53,43 @@ export default class ChallengeContent extends Component { } } diff --git a/junior/app/components/challenge/challenge.gjs b/junior/app/components/challenge/challenge.gjs index 4026bcc52b1..537999344d5 100644 --- a/junior/app/components/challenge/challenge.gjs +++ b/junior/app/components/challenge/challenge.gjs @@ -37,7 +37,7 @@ export default class Challenge extends Component { } get disableLessonButton() { - return this.args.challenge.hasValidEmbedDocument ? this.answerValue === null || this.answerValue === '' : false; + return this.args.challenge.hasEmbed ? this.answerValue === null || this.answerValue === '' : false; } get robotMood() { diff --git a/junior/app/components/challenge/content/challenge-media.gjs b/junior/app/components/challenge/content/challenge-media.gjs index 7e3e2c04110..efb0631ccdd 100644 --- a/junior/app/components/challenge/content/challenge-media.gjs +++ b/junior/app/components/challenge/content/challenge-media.gjs @@ -18,32 +18,34 @@ export default class ChallengeMedia extends Component { } } diff --git a/junior/app/models/challenge.js b/junior/app/models/challenge.js index 4528e9f6856..a0b182634dd 100644 --- a/junior/app/models/challenge.js +++ b/junior/app/models/challenge.js @@ -33,21 +33,19 @@ export default class Challenge extends Model { @hasMany('activity-answer', { async: true, inverse: 'challenge' }) activityAnswers; @computed('embedHeight', 'embedTitle', 'embedUrl', 'hasWebComponent') - get hasValidEmbedDocument() { + get hasEmbed() { const embedUrl = this.embedUrl; - return ( - !!embedUrl && - !!this.embedTitle && - !!this.embedHeight && - !this.hasWebComponent && - embedUrl.toLowerCase().indexOf('https://') === 0 - ); // fixes bug on IE: startsWith in not supported (PR #242) + return !!embedUrl && !!this.embedTitle && !this.hasWebComponent && embedUrl.toLowerCase().indexOf('https://') === 0; // fixes bug on IE: startsWith in not supported (PR #242) } get hasWebComponent() { return !!this.webComponentProps && !!this.webComponentTagName; } + get isLesson() { + return !!this.focused; + } + get isQROC() { return this.autoReply === false && this.type === 'QROC'; } @@ -65,10 +63,14 @@ export default class Challenge extends Model { } get hasForm() { - return this.autoReply === false; + return this.isQROC || this.isQROCM || this.isQCM || this.isQCU; } get hasType() { return !!this.type; } + + get hasMedia() { + return this.illustrationUrl || this.hasEmbed || this.hasWebComponent; + } } diff --git a/junior/app/styles/app.scss b/junior/app/styles/app.scss index e7f77773950..eee899e72f4 100644 --- a/junior/app/styles/app.scss +++ b/junior/app/styles/app.scss @@ -21,6 +21,7 @@ @use 'components/device-warning-modal' as *; @use 'components/mission-card/card' as *; @use 'components/bubble' as *; +@use 'components/card-wrapper' as *; @use 'components/footer' as *; @use 'components/issue' as *; @use 'components/identified-learner' as *; diff --git a/junior/app/styles/components/card-wrapper.scss b/junior/app/styles/components/card-wrapper.scss new file mode 100644 index 00000000000..941fc7f49fe --- /dev/null +++ b/junior/app/styles/components/card-wrapper.scss @@ -0,0 +1,7 @@ +.card-wrapper { + height: fit-content; + padding: var(--pix-spacing-4x); + background-color: var(--pix-neutral-0); + border-radius: 24px; + box-shadow: 0 0 1px 0 var(--pix-primary-500), 8px 8px 32px -8px rgb(63 125 216 / 35%) +} diff --git a/junior/app/styles/components/challenge/challenge-actions.scss b/junior/app/styles/components/challenge/challenge-actions.scss index 694b1b85b4f..9a0aa8f9a4c 100644 --- a/junior/app/styles/components/challenge/challenge-actions.scss +++ b/junior/app/styles/components/challenge/challenge-actions.scss @@ -1,7 +1,7 @@ .challenge-actions { display: flex; justify-content: space-between; - margin: var(--pix-spacing-8x) auto; + height: fit-content; button:only-child { margin-left: auto; diff --git a/junior/app/styles/components/challenge/challenge-content.scss b/junior/app/styles/components/challenge/challenge-content.scss index c24ea35dc5e..8ca60cb5565 100644 --- a/junior/app/styles/components/challenge/challenge-content.scss +++ b/junior/app/styles/components/challenge/challenge-content.scss @@ -1,8 +1,10 @@ @use 'pix-design-tokens/breakpoints'; .challenge-content { - display: flex; - gap: var(--pix-spacing-6x); + display: grid; + grid-row-gap: var(--pix-spacing-4x); + grid-column-gap: var(--pix-spacing-6x); + grid-template-columns: 1fr; margin: 16px 140px 0; transition: all 0.4s; @@ -10,36 +12,37 @@ margin: 16px 120px 0; } - &--single-display { - flex-direction: column; - } + &__grid-multiple-element { + grid-template-areas: + "illu form" + "illu actions"; + grid-template-columns: 1fr 1fr; - &__media, - &__proposals { - flex: 1; - } + &--1x-2x { + grid-template-columns: 40% 60%; + } - &__media { - &--framed { - padding: var(--pix-spacing-4x); - background-color: var(--pix-neutral-0); - border-radius: 24px; - box-shadow: 0 0 1px 0 var(--pix-primary-500), 8px 8px 32px -8px rgb(63 125 216 / 35%); + div:nth-child(1) { + grid-area: illu; } - } - &__qrocm { - align-items: center; + div:nth-child(2) { + grid-area: form; + } + + div:nth-child(3) { + grid-area: actions; + } } - &__qcm, &__qcu { + &__form { display: flex; justify-content: center; width: 100%; } &__autoreply { - width: 0; + display: none; } } diff --git a/junior/tests/integration/challenge-content_test.gjs b/junior/tests/integration/challenge-content_test.gjs index 32332c0a63b..f6f5b76aec6 100644 --- a/junior/tests/integration/challenge-content_test.gjs +++ b/junior/tests/integration/challenge-content_test.gjs @@ -10,7 +10,7 @@ module('Integration | Component | challenge item', function (hooks) { setupIntlRenderingTest(hooks); test('displays embed', async function (assert) { - const challenge = { hasValidEmbedDocument: true, autoReply: true }; + const challenge = { hasEmbed: true, autoReply: true }; await render(); assert.dom('.challenge-embed-simulator').exists(); @@ -27,43 +27,44 @@ module('Integration | Component | challenge item', function (hooks) { }); test('displays image', async function (assert) { - const challenge = { hasValidEmbedDocument: false, autoReply: false, illustrationUrl: 'https://pix.fr' }; + const challenge = { hasEmbed: false, autoReply: false, illustrationUrl: 'https://pix.fr' }; await render(); assert.dom('.challenge-media__placeholder').exists(); }); test('displays qroc', async function (assert) { - const challenge = { hasValidEmbedDocument: false, autoReply: false, isQROC: true, proposals: 'number' }; + const challenge = { hasForm: true, hasEmbed: false, autoReply: false, isQROC: true, proposals: 'number' }; await render(); - assert.dom('.challenge-content__qrocm').exists(); + assert.dom('.challenge-content-proposals').exists(); }); test('displays qrocm', async function (assert) { - const challenge = { hasValidEmbedDocument: false, autoReply: false, isQROCM: true, proposals: 'number' }; + const challenge = { hasForm: true, hasEmbed: false, autoReply: false, isQROCM: true, proposals: 'number' }; await render(); - assert.dom('.challenge-content__qrocm').exists(); + assert.dom('.challenge-content-proposals').exists(); }); test('displays qcu', async function (assert) { - const challenge = { hasValidEmbedDocument: false, autoReply: false, isQCU: true }; + const challenge = { hasForm: true, hasEmbed: false, autoReply: false, isQCU: true }; await render(); - assert.dom('.challenge-content__qcu').exists(); + assert.dom('.challenge-content-proposals__qcu-radios').exists(); }); test('displays qcm', async function (assert) { - const challenge = { hasValidEmbedDocument: false, autoReply: false, isQCM: true }; + const challenge = { hasForm: true, hasEmbed: false, autoReply: false, isQCM: true }; await render(); - assert.dom('.challenge-content__qcm').exists(); + assert.dom('.challenge-content-proposals__qcm-checkboxes').exists(); }); test('displays lesson', async function (assert) { const challenge = { - hasValidEmbedDocument: true, + isLesson: true, + hasEmbed: true, autoReply: false, focused: true, }; diff --git a/junior/tests/unit/models/challenge-test.js b/junior/tests/unit/models/challenge-test.js index 1b45d08fca9..3319fdf751b 100644 --- a/junior/tests/unit/models/challenge-test.js +++ b/junior/tests/unit/models/challenge-test.js @@ -11,43 +11,32 @@ module('Unit | Model | Challenge', function (hooks) { store = this.owner.lookup('service:store'); }); - module('#hasValidEmbedDocument', function () { + module('#hasEmbed', function () { test('should be true when all attributes are correctly provided', function (assert) { const challenge = store.createRecord('challenge', { embedUrl: 'https://pix.fr', embedTitle: 'Amazing Pix Embed', - embedHeight: 800, }); - assert.true(challenge.hasValidEmbedDocument); + assert.true(challenge.hasEmbed); }); test('should be false when embedUrl does not start with "https://"', function (assert) { const challenge = store.createRecord('challenge', { embedUrl: 'http://pix.fr', embedTitle: 'Amazing Pix Embed', - embedHeight: 800, }); - assert.false(challenge.hasValidEmbedDocument); + assert.false(challenge.hasEmbed); }); test('should be false when embedUrl is not provided', function (assert) { const challenge = store.createRecord('challenge', { embedTitle: 'Amazing Pix Embed', - embedHeight: 800, }); - assert.false(challenge.hasValidEmbedDocument); + assert.false(challenge.hasEmbed); }); test('should be false when embedTitle is not provided', function (assert) { const challenge = store.createRecord('challenge', { embedUrl: 'https://pix.fr', - embedHeight: 800, }); - assert.false(challenge.hasValidEmbedDocument); - }); - test('should be false when embedHeight is not provided', function (assert) { - const challenge = store.createRecord('challenge', { - embedUrl: 'https://pix.fr', - embedTitle: 'Amazing Pix Embed', - }); - assert.false(challenge.hasValidEmbedDocument); + assert.false(challenge.hasEmbed); }); }); diff --git a/mon-pix/tests/unit/models/challenge-test.js b/mon-pix/tests/unit/models/challenge-test.js index e17f81aba69..5d5d85922f2 100644 --- a/mon-pix/tests/unit/models/challenge-test.js +++ b/mon-pix/tests/unit/models/challenge-test.js @@ -98,7 +98,7 @@ module('Unit | Model | Challenge', function (hooks) { }); }); - module('Computed property #hasValidEmbedDocument', function (hooks) { + module('Computed property #hasEmbed', function (hooks) { let embedOptions; hooks.beforeEach(function () { From eab889c2627ffe01c866617f9746185250f8111c Mon Sep 17 00:00:00 2001 From: Aurelie Crouillebois Date: Tue, 21 Jan 2025 17:11:15 +0100 Subject: [PATCH 2/3] style(junior): set 60/40 layout on embed+form challenges --- .../components/challenge/challenge-content.gjs | 7 ++++++- .../components/challenge/challenge-content.scss | 16 ++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/junior/app/components/challenge/challenge-content.gjs b/junior/app/components/challenge/challenge-content.gjs index 3303e4e33b6..db73b14efef 100644 --- a/junior/app/components/challenge/challenge-content.gjs +++ b/junior/app/components/challenge/challenge-content.gjs @@ -36,13 +36,18 @@ export default class ChallengeContent extends Component { get challengeContentClassname() { const hasIllustrationAndEmbed = this.args.challenge.illustrationUrl && this.args.challenge.hasEmbed; + const hasEmbedAndForm = this.args.challenge.hasEmbed && this.args.challenge.hasForm; let classname = ''; if (this.shouldDisplayMultipleElements) { classname = 'challenge-content__grid-multiple-element'; if (hasIllustrationAndEmbed) { - classname += ' challenge-content__grid-multiple-element--1x-2x'; + classname += ' challenge-content__grid-multiple-element--40-60'; + } + + if (hasEmbedAndForm) { + classname += ' challenge-content__grid-multiple-element--60-40'; } } return classname; diff --git a/junior/app/styles/components/challenge/challenge-content.scss b/junior/app/styles/components/challenge/challenge-content.scss index 8ca60cb5565..5c64bcae222 100644 --- a/junior/app/styles/components/challenge/challenge-content.scss +++ b/junior/app/styles/components/challenge/challenge-content.scss @@ -14,20 +14,24 @@ &__grid-multiple-element { grid-template-areas: - "illu form" - "illu actions"; + "left right" + "left actions"; grid-template-columns: 1fr 1fr; - &--1x-2x { - grid-template-columns: 40% 60%; + &--40-60 { + grid-template-columns: 2fr 3fr; + } + + &--60-40 { + grid-template-columns: 3fr 2fr; } div:nth-child(1) { - grid-area: illu; + grid-area: left; } div:nth-child(2) { - grid-area: form; + grid-area: right; } div:nth-child(3) { From 8f3d3b1bf49db24443bddc2c5604c750c5ca46d9 Mon Sep 17 00:00:00 2001 From: Aurelie Crouillebois Date: Tue, 21 Jan 2025 17:11:56 +0100 Subject: [PATCH 3/3] feat(junior): update success/failure robot messages --- junior/translations/fr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/junior/translations/fr.json b/junior/translations/fr.json index a7a3f69dcce..81c2f6f7e94 100644 --- a/junior/translations/fr.json +++ b/junior/translations/fr.json @@ -58,8 +58,8 @@ "placeholder": "Chargement en cours" }, "messages": { - "correct-answer": "Bien joué, tu as répondu correctement !", - "wrong-answer": "Mauvaise réponse. Tu peux passer à la suite." + "correct-answer": "Bien joué, tu as répondu correctement ! Tu peux continuer.", + "wrong-answer": "Mauvaise réponse. Tu peux continuer." }, "qcm-error": "Attention, sélectionne plusieurs réponses !", "qcm-hint": "Sélectionne plusieurs réponses.",