Skip to content

Commit

Permalink
timeline
Browse files Browse the repository at this point in the history
  • Loading branch information
WolfyWin committed Nov 27, 2023
1 parent d56d32c commit 803f6a0
Show file tree
Hide file tree
Showing 29 changed files with 424 additions and 143 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ public function updateProgressionAction(Flashcard $card, User $user, Request $re
$node = $deck->getResourceNode();
$resourceUserEvaluation = $this->evaluationManager->getResourceUserEvaluation($node, $user);

// Mise à jour de la progression de la carte
$this->evaluationManager->updateCardDrawnProgression($card, $user, $request->get('isSuccessful'));

$attempt = $this->resourceEvalRepo->findOneInProgress($node, $user);
Expand Down
15 changes: 15 additions & 0 deletions src/plugin/flashcard/Entity/FlashcardDeck.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ class FlashcardDeck extends AbstractResource
*/
private ?string $wrongButtonLabel = null;

/**
* @ORM\Column(type="boolean")
*/
private bool $showLeitnerRules = false;

public function __construct()
{
parent::__construct();
Expand Down Expand Up @@ -142,4 +147,14 @@ public function setWrongButtonLabel(?string $wrongButtonLabel): void
{
$this->wrongButtonLabel = $wrongButtonLabel;
}

public function getShowLeitnerRules(): bool
{
return $this->showLeitnerRules;
}

public function setShowLeitnerRules(bool $showLeitnerRules): void
{
$this->showLeitnerRules = $showLeitnerRules;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Claroline\FlashcardBundle\Installation\Migrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated migration based on mapping information: modify it with caution.
*
* Generation date: 2023/11/27 10:51:17
*/
final class Version20231127105116 extends AbstractMigration
{
public function up(Schema $schema): void
{
$this->addSql('
ALTER TABLE claro_flashcard_deck
ADD showLeitnerRules TINYINT(1) NOT NULL
');
}

public function down(Schema $schema): void
{
$this->addSql('
ALTER TABLE claro_flashcard_deck
DROP showLeitnerRules
');
}
}
1 change: 0 additions & 1 deletion src/plugin/flashcard/Manager/EvaluationManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ public function update(ResourceEvaluation $attempt, $attemptCards): ResourceEval
}
}

// Pas de cartes restantes pour cette session, on passe a la session suivante
if (0 === count($cardsArray)) {
++$session;
}
Expand Down
22 changes: 4 additions & 18 deletions src/plugin/flashcard/Manager/FlashcardManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
$cardsSessionIds = $attempt ? $attempt->getData()['cardsSessionIds'] ?? [] : [];
$cardsAnsweredIds = $attempt ? $attempt->getData()['cardsAnsweredIds'] ?? [] : [];

// Récup des entités cartes de la tentative
$cards = array_map(function ($card) {
return $this->om->getRepository(CardDrawnProgression::class)->findOneBy([
'id' => $card['id'],
Expand All @@ -113,7 +112,6 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
]);
}, $cardsAnsweredIds);

// Création d'une nouvelle tentative si nécessaire
if (!$attempt) {
$attempt = $this->resourceEvalManager->createAttempt($node, $user, [
'status' => AbstractEvaluation::STATUS_OPENED,
Expand All @@ -127,7 +125,10 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
]);
}

// Récupération des cartes de la tentative
if (0 === count($deck->getCards())) {
return $attempt;
}

$attemptCards = self::shuffleCardByAttempt($deck->getCards(), $attempt, $deck->getDraw());
foreach ($attemptCards as $card) {
$progression = $this->om->getRepository(CardDrawnProgression::class)->findOneBy([
Expand All @@ -149,15 +150,13 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
}
}

// Filtrage des cartes pour la session
$cardsSession = [];
foreach ($cards as $cardProgression) {
if ($this->keepCardInSession($session, $cardProgression)) {
$cardsSession[] = $cardProgression;
}
}

// Ajout des cartes de la session 1
if (0 === count($cardsSession) && 1 === $session) {
$attempt = $this->resourceEvalManager->updateAttempt($attempt, [
'status' => AbstractEvaluation::STATUS_OPENED,
Expand All @@ -177,7 +176,6 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
]);
}

// Suppression des cartes répondues de la liste des cartes de la session
foreach ($cardsAnswered as $cardProgression) {
foreach ($cardsSession as $key => $cardSession) {
if ($cardProgression->getId() === $cardSession->getId()) {
Expand All @@ -187,22 +185,17 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
}
}

// Incrément de la session et réinitialisation des cartes si nécessaire
while (0 === count($cardsSession) && $session < 7) {
++$session;

$cardsSession = [];
$cardsAnswered = [];

// Filtrage des cartes pour la nouvelle session
foreach ($cards as $cardProgression) {
if ($this->keepCardInSession($session, $cardProgression)) {
$cardsSession[] = $cardProgression;
}
}
}

// Calcul de la progression
$successfulCards = 0;
$totalCards = count($cardsSession) + count($cardsAnswered);
foreach ($cardsAnswered as $cardProgression) {
Expand All @@ -211,11 +204,9 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
if (0 === $totalCards) {
$progression = 0;
} else {
// Transformation du résultat en integer car round() retourne un float
$progression = (int) min(round($successfulCards / $totalCards * 100), 100);
}

// Vérification du status
if (7 === $session && 0 === count($cardsSession)) {
if (100 === $progression) {
$status = AbstractEvaluation::STATUS_COMPLETED;
Expand All @@ -226,7 +217,6 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
$status = AbstractEvaluation::STATUS_INCOMPLETE;
}

// Mise à jour de la tentative
$attempt = $this->resourceEvalManager->updateAttempt($attempt, [
'status' => $status,
'progression' => $progression,
Expand All @@ -244,9 +234,7 @@ public function calculateSession(?ResourceEvaluation $attempt, FlashcardDeck $de
],
]);

// Si on n'a pas de page de début ni de fin
if (!$deck->getShowOverview() && !$deck->getShowEndPage()) {
// On recrée une nouvelle tentative directement une fois la précédente terminée pour enchainer
if (AbstractEvaluation::STATUS_COMPLETED === $status || AbstractEvaluation::STATUS_FAILED === $status) {
$attempt = $this->calculateSession(null, $deck, $user);
}
Expand All @@ -261,7 +249,6 @@ public function answerSessionCard(ResourceEvaluation $attempt, CardDrawnProgress
$cardsSessionIds = $attempt->getData()['cardsSessionIds'] ?? [];
$cardsAnsweredIds = $attempt->getData()['cardsAnsweredIds'] ?? [];

// Deserialization des cartes de la tentative
$cards = array_map(function ($card) {
return $this->om->getRepository(CardDrawnProgression::class)->findOneBy([
'id' => $card['id'],
Expand All @@ -272,7 +259,6 @@ public function answerSessionCard(ResourceEvaluation $attempt, CardDrawnProgress
$cardsAnsweredIds[] = $cardProgression->getId();
}

// Mise à jour de la tentative
return $this->resourceEvalManager->updateAttempt($attempt, [
'status' => $attempt->getStatus(),
'progression' => $attempt->getProgression(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Card.propTypes = {
actions: T.func,
card: T.shape(
CardTypes.propTypes
).isRequired
)
}

export {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const FlashcardMenu = props =>
/>

FlashcardMenu.propTypes = {
// from menu
opened: T.bool.isRequired,
toggle: T.func.isRequired,
autoClose: T.func.isRequired
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import {trans} from '#/main/app/intl/translation'
import {LINK_BUTTON} from '#/main/app/buttons'
import {ResourceOverview} from '#/main/core/resource/components/overview'
import {ResourceEvaluation as ResourceEvaluationTypes} from '#/main/evaluation/resource/prop-types'
import {FlashcardInfo} from '#/plugin/flashcard/resources/flashcard/components/info'

import {Timeline} from '#/plugin/flashcard/resources/flashcard/components/timeline'
import {LeitnerRules} from '#/plugin/flashcard/resources/flashcard/components/rules'
import {FlashcardDeck as FlashcardDeckTypes} from '#/plugin/flashcard/resources/flashcard/prop-types'

const Overview = (props) => {
Expand Down Expand Up @@ -57,9 +59,19 @@ const Overview = (props) => {
[trans('session_status', {}, 'flashcard'), statusText]
]}
>
<FlashcardInfo
flashcardProgression={props.attempt.data.cards}

<Timeline
session={session}
started={sessionStarted}
completed={sessionCompleted}
/>

{props.flashcardDeck.showLeitnerRules &&
<LeitnerRules
session={session}
completed={sessionCompleted}
/>
}
</ResourceOverview>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react'
import classes from 'classnames'
import {PropTypes as T} from 'prop-types'

import {trans} from '#/main/app/intl'
import {getIcon, getRule} from '#/plugin/flashcard/resources/flashcard/utils'

const SessionRule= props => {
const icon = getIcon(props.index)
const rule = getRule(props.index)

let classList = ['icon-with-text-right']
if (props.index < props.session || (props.index === props.session && props.completed)) {
classList.push('session-rule-done')
}

return (
<li className="session-rule">
<div className={classes(classList)}>
{icon}
</div>
<div className="">
Session {props.index} : {trans('session_cards_start', {}, 'flashcard') + ' ' + rule}.
</div>
</li>
)
}

SessionRule.propTypes = {
session: T.number,
rule: T.number,
completed: T.bool,
index: T.number
}

const LeitnerRules = (props) => (
<ul
className="sessions-rules">
{Array.from({length: 7}, (_, index) => (
<SessionRule
key={index}
session={props.session}
completed={props.completed}
index={index + 1}
/>
))}
</ul>
)

LeitnerRules.propTypes = {
session: T.number,
completed: T.bool
}

export {
LeitnerRules
}
Loading

0 comments on commit 803f6a0

Please sign in to comment.