Skip to content

Commit

Permalink
feat(slideshow) : #MAG-545 add sections slides (#392)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Florent Mariotti <[email protected]>
  • Loading branch information
FlorentMr and Florent Mariotti authored Feb 27, 2025
1 parent 0ef51d9 commit 6a15457
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 29 deletions.
15 changes: 15 additions & 0 deletions backend/src/main/java/fr/cgi/magneto/model/Section.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package fr.cgi.magneto.model;

import fr.cgi.magneto.core.constants.Field;
import fr.cgi.magneto.model.cards.Card;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

Expand All @@ -13,6 +14,7 @@ public class Section implements Model {
private List<String> cardIds;
private String boardId;
private Boolean displayed;
private List<Card> cards;

@SuppressWarnings("unchecked")
public Section(JsonObject section) {
Expand All @@ -22,6 +24,8 @@ public Section(JsonObject section) {
this.boardId = section.getString(Field.BOARDID);
if (section.containsKey(Field.DISPLAYED))
this.displayed = section.getBoolean(Field.DISPLAYED);
if (section.containsKey(Field.CARDS))
this.cards = section.getJsonArray(Field.CARDS).getList();
}

public Section() {
Expand Down Expand Up @@ -87,6 +91,15 @@ public void setDisplayed(boolean displayed) {
this.displayed = displayed;
}

public List<Card> getCards() {
return cards;
}

public Section setCards(List<Card> cards) {
this.cards = cards;
return this;
}

@Override
public JsonObject toJson() {
JsonObject json = new JsonObject()
Expand All @@ -96,6 +109,8 @@ public JsonObject toJson() {
.put(Field.BOARDID, this.getBoardId());
if (this.displayed != null)
json.put(Field.DISPLAYED, this.getDisplayed());
if (this.cards != null)
json.put(Field.CARDS, this.getCards());
return json;
}

Expand Down
37 changes: 28 additions & 9 deletions backend/src/main/java/fr/cgi/magneto/model/slides/SlideText.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,41 @@ public Object createApacheSlide(XSLFSlide newSlide) {
return newSlide;
}

private static boolean isBodyEmptyOrContainsEmptyParagraph(Element body) {
// Vérifier si le body est vide
if (body.children().isEmpty()) {
return true;
}

// Vérifier si le body ne contient qu'une balise <p></p> vide
if (body.children().size() == 1) {
Element child = body.child(0);
if (child.tagName().equals("p") && child.html().trim().isEmpty()) {
return true;
}
}

return false;
}

private void processHtmlContent(XSLFTextBox textBox, Element element) {
if (textBox.getTextParagraphs().isEmpty()) {
textBox.addNewTextParagraph();
}

for (Node node : element.childNodes()) {
if (node instanceof Element) {
Element elem = (Element) node;
XSLFTextParagraph para = textBox.addNewTextParagraph();
XSLFTextRun run = para.addNewTextRun();
if (!isBodyEmptyOrContainsEmptyParagraph(element)) {
for (Node node : element.childNodes()) {
if (node instanceof Element) {
Element elem = (Element) node;
XSLFTextParagraph para = textBox.addNewTextParagraph();
XSLFTextRun run = para.addNewTextRun();

processStyle(elem, para, run);
processStyle(elem, para, run);

String text = elem.text().trim();
if (!text.isEmpty()) {
run.setText(text);
String text = elem.text().trim();
if (!text.isEmpty()) {
run.setText(text);
}
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions backend/src/main/java/fr/cgi/magneto/service/CardService.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,16 @@ void removeCardSectionWithLocked(CardPayload updateCard, String oldBoardId, Futu
*/
Future<JsonObject> getAllCardsBySection(Section section, Integer page, UserInfos user);

/**
* Get all cards by section, without the count and returning the list directly
*
* @param section Section object
* @param page Page number
* @param user {@link UserInfos} User info
* @return Future {@link Future <List<Card>>} containing the cards corresponding to the board identifier
*/
Future<List<Card>> getAllCardsBySectionSimple(Section section, Integer page, UserInfos user);

/**
* Duplicate cards
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ public interface SectionService {
*/
Future<List<Section>> getSectionsByBoardId(String boardId);

Future<List<Section>> createSectionWithCards(Board board, UserInfos user);

/**
*
* @param board board of the sections
* @param board board of the sections
* @param isReadOnly
* @return
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,22 @@ public Future<JsonObject> getAllCardsBySection(Section section, Integer page, Us
return promise.future();
}

@Override
public Future<List<Card>> getAllCardsBySectionSimple(Section section, Integer page, UserInfos user) {
Promise<List<Card>> promise = Promise.promise();

fetchAllCardsBySection(section, page, user)
.compose(this::setMetadataCards)
.onFailure(fail -> {
log.error("[Magneto@%s::getAllCardsBySectionSimple] Failed to get section cards", this.getClass().getSimpleName(),
fail.getMessage());
promise.fail(fail.getMessage());
})
.onSuccess(promise::complete);

return promise.future();
}

public Future<List<Card>> getAllCardsByCreationDate(StatisticsPayload statisticsPayload) {
Promise<List<Card>> promise = Promise.promise();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,12 @@
package fr.cgi.magneto.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.entcore.common.user.UserInfos;

import fr.cgi.magneto.core.constants.Field;
import fr.cgi.magneto.core.constants.Slideshow;
import fr.cgi.magneto.core.enums.SlideResourceType;
import fr.cgi.magneto.factory.SlideFactory;
import fr.cgi.magneto.helper.I18nHelper;
import fr.cgi.magneto.helper.SlideHelper;
import fr.cgi.magneto.model.Section;
import fr.cgi.magneto.model.boards.Board;
import fr.cgi.magneto.model.cards.Card;
import fr.cgi.magneto.model.properties.SlideProperties;
Expand All @@ -31,8 +20,13 @@
import io.vertx.core.json.JsonObject;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.sl.usermodel.TextParagraph;
import org.apache.poi.xslf.usermodel.*;
import org.entcore.common.user.UserInfos;

import java.util.*;
import java.util.stream.Collectors;

public class DefaultExportService implements ExportService {

Expand Down Expand Up @@ -65,8 +59,10 @@ public Future<XMLSlideShow> exportBoardToPPTX(String boardId, UserInfos user, I1
documentIds.add(imageId);
return getBoardDocuments(documentIds);
})
.compose(documents -> createFreeLayoutSlideObjects(board, user, slideShow, documents,
i18nHelper))
.compose(documents -> board.isLayoutFree()
? createFreeLayoutSlideObjects(board, user, slideShow, documents,
i18nHelper)
: createSectionLayoutSlideObjects(board, user, slideShow, documents, i18nHelper))
.onFailure(err -> {
String message = String.format(
"[Magneto@%s::exportBoardToPptx] Failed to get documents: %s",
Expand Down Expand Up @@ -149,6 +145,9 @@ private Future<XMLSlideShow> createFreeLayoutSlideObjects(Board board, UserInfos
XMLSlideShow ppt = new XMLSlideShow();
ppt.setPageSize(new java.awt.Dimension(1280, 720));

// TITRE
XSLFSlide newTitleSlide = ppt.createSlide();
createTitleSlide(newTitleSlide, board, documents, i18nHelper);
return serviceFactory.cardService().getAllCardsByBoard(board, user)
.map(fetchedCards -> {
// Créer une map des cartes récupérées pour un accès rapide
Expand All @@ -157,10 +156,6 @@ private Future<XMLSlideShow> createFreeLayoutSlideObjects(Board board, UserInfos

SlideFactory slideFactory = new SlideFactory();

// TITRE
XSLFSlide newTitleSlide = ppt.createSlide();
createTitleSlide(newTitleSlide, board, documents, i18nHelper);

// Utiliser l'ordre des cartes du Board
for (Card boardCard : board.cards()) {
String cardId = boardCard.getId();
Expand Down Expand Up @@ -195,6 +190,52 @@ private Future<XMLSlideShow> createFreeLayoutSlideObjects(Board board, UserInfos
});
}


private Future<XMLSlideShow> createSectionLayoutSlideObjects(Board board, UserInfos user,
JsonObject slideShowData, List<Map<String, Object>> documents, I18nHelper i18nHelper) {
XMLSlideShow ppt = new XMLSlideShow();
ppt.setPageSize(new java.awt.Dimension(1280, 720));

// TITRE
XSLFSlide newTitleSlide = ppt.createSlide();
createTitleSlide(newTitleSlide, board, documents, i18nHelper);

SlideFactory slideFactory = new SlideFactory();

return this.serviceFactory.sectionService().createSectionWithCards(board, user)
.map(sections -> {
for (Section section : sections) {
// TITRE SECTION
XSLFSlide sectionApacheSlide = ppt.createSlide();
SlideHelper.createTitle(sectionApacheSlide, section.getTitle(), Slideshow.MAIN_TITLE_HEIGHT, Slideshow.MAIN_TITLE_FONT_SIZE, TextParagraph.TextAlign.CENTER);

for (Card card : section.getCards()) {
if (card != null) {
try {
Slide slide = createSlideFromCard(card, slideFactory, slideShowData, documents);
XSLFSlide newSlide = ppt.createSlide();
slide.createApacheSlide(newSlide);
} catch (Exception e) {
String message = String.format(
"[Magneto@%s::createSectionLayoutSlideObjects] Failed to create slide for card %s: %s",
this.getClass().getSimpleName(), card.getId(), e.getMessage());
log.error(message);
}
} else {
log.warn(String.format("Card %s from board not found in fetched cards", card.getId()));
}
}
}
return ppt;
})
.onFailure(err -> {
String message = String.format(
"[Magneto@%s::createSectionLayoutSlideObjects] Failed to create slides: %s",
this.getClass().getSimpleName(), err.getMessage());
log.error(message);
});
}

private XSLFSlide createTitleSlide(XSLFSlide newTitleSlide, Board board, List<Map<String, Object>> documents,
I18nHelper i18nHelper) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,31 @@ public Future<List<Section>> getSectionsByBoardId(String boardId) {
return promise.future();
}

@Override
public Future<List<Section>> createSectionWithCards(Board board, UserInfos user) {
Promise<List<Section>> promise = Promise.promise();

List<Section> sections = new ArrayList<>();
this.serviceFactory.sectionService().getSectionsByBoardId(board.getId())
.compose(sectionsResult -> {
sections.addAll(sectionsResult);
List<Future> futures = new ArrayList<>();
for (Section section : sections) {
Future<List<Card>> cardsFuture = this.serviceFactory.cardService().getAllCardsBySectionSimple(section, 0, user);
futures.add(cardsFuture.map(cards -> {
section.setCards(cards);
return section;
}));
}
return CompositeFuture.all(futures);
})
.compose(compositeFuture -> Future.succeededFuture(sections))
.onSuccess(promise::complete)
.onFailure(promise::fail);

return promise.future();
}

@Override
public Future<List<Section>> getSectionsByBoard(Board board, boolean isReadOnly) {
Promise<List<Section>> promise = Promise.promise();
Expand Down

0 comments on commit 6a15457

Please sign in to comment.