Skip to content

Commit

Permalink
front: add help module for lmr usage
Browse files Browse the repository at this point in the history
  • Loading branch information
Math-R committed Dec 8, 2024
1 parent 9c34c10 commit bedd0af
Show file tree
Hide file tree
Showing 11 changed files with 718 additions and 24 deletions.
335 changes: 335 additions & 0 deletions front/public/locales/fr/stdcm-help-section.json

Large diffs are not rendered by default.

21 changes: 18 additions & 3 deletions front/src/applications/stdcm/components/StdcmHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@ import { getIsSuperUser } from 'reducers/user/userSelectors';
type StdcmHeaderProps = {
isDebugMode: boolean;
onDebugModeToggle: React.Dispatch<React.SetStateAction<boolean>>;
toggleHelpModule: () => void;
showHelpModule: boolean;
};

const StdcmHeader = ({ isDebugMode, onDebugModeToggle }: StdcmHeaderProps) => {
const StdcmHeader = ({
isDebugMode,
onDebugModeToggle,
toggleHelpModule,
showHelpModule,
}: StdcmHeaderProps) => {
const { t } = useTranslation('stdcm');
const isSuperUser = useSelector(getIsSuperUser);

Expand All @@ -23,16 +30,24 @@ const StdcmHeader = ({ isDebugMode, onDebugModeToggle }: StdcmHeaderProps) => {
</span>
</div>
{isSuperUser && (
<div className="stdcm-header_debug">
<div className="stdcm-header__debug">
<button
data-testid="stdcm-debug-button"
type="button"
aria-label="stdcm-debug"
className={cx({ 'debug-on': isDebugMode, 'debug-off': !isDebugMode })}
className={cx('debug', { selected: isDebugMode })}
onClick={() => onDebugModeToggle(!isDebugMode)}
>
<Bug />
</button>
<button
type="button"
aria-label="stdcm-help"
className={cx('ml-4 px-3', { selected: showHelpModule })}
onClick={() => toggleHelpModule()}
>
Aide
</button>
</div>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { ArrowLeft } from '@osrd-project/ui-icons';
import cx from 'classnames';
import { useTranslation } from 'react-i18next';

import type { Section } from './types';
import SectionContentManager from './SectionContentManager';

type HelpSectionProps = {
section: string;
isActive: boolean;
closeHelpSection: () => void;
};

const HelpSection = ({ section, isActive, closeHelpSection }: HelpSectionProps) => {
const { t } = useTranslation('stdcm-help-section');
const currentSection = t(`sections.${section}`, { returnObjects: true }) as Section;

return (
<div className={cx('stdcm__help-section', { active: isActive })}>
<div className="stdcm__help-section__header">
<button
type="button"
onClick={closeHelpSection}
className="flex align-items-center stdcm__help-section__back-button"
>
<span className="mr-2">
<ArrowLeft size="lg" iconColor="#1844ef" />
</span>
{t('backToIndex')}
</button>
</div>
<div className="stdcm__help-section__content">
<h1 className={cx('stdcm__help-section__title', { active: isActive })}>
{currentSection.title}
</h1>
{Array.isArray(currentSection.content) &&
currentSection.content.map((content, index) => (
<SectionContentManager key={index} content={content} />
))}
{currentSection.subSections?.map((subSection, index) => (
<>
<h2 className="stdcm__help-section__subtitle">{subSection.title}</h2>
{subSection.content?.map((content, idx) => (
<SectionContentManager key={idx} content={content} />
))}
</>
))}
</div>
</div>
);
};

export default HelpSection;
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import type { Content } from './types';

type SectionContentManagerProps = {
content: Content;
};

const SectionContentManager = ({ content }: SectionContentManagerProps) => (
<div className="section__content">
{(() => {
switch (content.type) {
case 'list':
return (
<ul>
{content.items &&
content.items.map((item, index) => <li key={index}>{item.value}</li>)}
</ul>
);

case 'text':
// eslint-disable-next-line react/no-danger
return <p dangerouslySetInnerHTML={{ __html: content.value }} />;
case 'faq':
return (
<ol>
{content.questions &&
content.questions.map((question, index) => (
<li key={index}>
<h3>{`${index + 1}. ${question.question}`}</h3>
<p> {question.answer}</p>
</li>
))}
</ol>
);
case 'definitions':
return (
<table>
<tbody>
{content.definitions.map((item) => (
<tr key={`${item.term}`}>
<th scope="row">{item.term}</th>
<td>{item.definition}</td>
</tr>
))}
</tbody>
</table>
);
default:
return null;
}
})()}
</div>
);

export default SectionContentManager;
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useState } from 'react';

import { X } from '@osrd-project/ui-icons';
import cx from 'classnames';
import { useTranslation } from 'react-i18next';

import HelpSection from './HelpSection';

type StdcmHelpSectionProps = {
toggleHelpModule: () => void;
showHelpModule: boolean;
};

const StdcmHelpModule = ({ toggleHelpModule, showHelpModule }: StdcmHelpSectionProps) => {
const { t } = useTranslation('stdcm-help-section');

const [activeSection, setActiveSection] = useState<string | null>(null);

const closeHelpModule = () => {
setActiveSection(null);
toggleHelpModule();
};
const closeHelpSection = () => setActiveSection(null);
const sections = Object.keys(t('sections', { returnObjects: true }));
return (
<div className={cx('stdcm__help-module', { active: showHelpModule })}>
<div className="stdcm__help-module__header">
<button type="button" className="stdcm__help-module__close" onClick={closeHelpModule}>
<X size="lg" iconColor="#B6B2AF" />
</button>
</div>
<div className="stdcm__help-module__content">
<h1 className="stdcm__help-module__title">Aide</h1>
<div className="stdcm__help-module__chapters">
{sections &&
sections.map((section, index) => (
<>
<button
type="button"
key={index}
className="stdcm__help-module__title-button"
onClick={() => setActiveSection(section)}
>
{t(`sections.${section}.title`)}
</button>
{index !== sections.length - 1 && <hr />}
</>
))}
</div>
</div>
{sections.map((section, index) => (
<HelpSection
section={section}
closeHelpSection={closeHelpSection}
isActive={section === activeSection}
key={index}
/>
))}
</div>
);
};

export default StdcmHelpModule;
42 changes: 42 additions & 0 deletions front/src/applications/stdcm/components/StdcmHelpModule/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
export type Section = {
id: string; // Identifiant unique de la section
title: string; // Titre de la section
content?: Content[]; // Tableau des contenus de la section,
subSections?: Omit<Section, 'subSection'>[]; // Tableau des sous-sections
};

// Définition des différents types de contenu qu'une section peut avoir
export type Content = ListContent | TextContent | FAQContent | GlossaryContent;

// Contenu sous forme de liste
export type ListContent = {
type: 'list'; // Indique qu'il s'agit d'une liste
items: Record<string, string>[]; // Tableau des éléments de la liste
};

// Contenu sous forme de texte
export type TextContent = {
type: 'text'; // Indique qu'il s'agit d'un texte
value: string; // Texte contenant éventuellement du HTML
};

export type FAQItem = {
question: string; // La question
answer: string; // La réponse
};

export type FAQContent = {
type: 'faq'; // Indique qu'il s'agit d'une FAQ
questions: FAQItem[]; // La question
};

// Contenu sous forme de glossaire (clé/valeur)
export type GlossaryContent = {
type: 'definitions'; // Indique qu'il s'agit d'un glossaire
definitions: GlossaryItem[]; // Dictionnaire terme -> définition
};

export type GlossaryItem = {
term: string; // Terme du glossaire
definition: string; // Définition du terme
};
12 changes: 11 additions & 1 deletion front/src/applications/stdcm/views/StdcmView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { replaceElementAtIndex } from 'utils/array';
import StdcmEmptyConfigError from '../components/StdcmEmptyConfigError';
import StdcmConfig from '../components/StdcmForm/StdcmConfig';
import StdcmHeader from '../components/StdcmHeader';
import StdcmHelpModule from '../components/StdcmHelpModule/StdcmHelpModule';
import StdcmResults from '../components/StdcmResults';
import StdcmStatusBanner from '../components/StdcmStatusBanner';
import useStdcmEnvironment, { NO_CONFIG_FOUND_MSG } from '../hooks/useStdcmEnv';
Expand All @@ -27,6 +28,7 @@ const StdcmView = () => {
const [retainedSimulationIndex, setRetainedSimulationIndex] = useState(-1);
const [showBtnToLaunchSimulation, setShowBtnToLaunchSimulation] = useState(false);
const [isDebugMode, setIsDebugMode] = useState(false);
const [showHelpModule, setShowHelpModule] = useState(false);

const {
launchStdcmRequest,
Expand Down Expand Up @@ -65,6 +67,8 @@ const StdcmView = () => {
dispatch(resetStdcmConfig());
};

const toggleHelpModule = () => setShowHelpModule(!showHelpModule);

// reset config data with the selected simulation data
useEffect(() => {
if (selectedSimulation) {
Expand Down Expand Up @@ -171,7 +175,12 @@ const StdcmView = () => {

return (
<div role="button" tabIndex={0} className="stdcm" onClick={() => setShowStatusBanner(false)}>
<StdcmHeader isDebugMode={isDebugMode} onDebugModeToggle={setIsDebugMode} />
<StdcmHeader
isDebugMode={isDebugMode}
onDebugModeToggle={setIsDebugMode}
toggleHelpModule={toggleHelpModule}
showHelpModule={showHelpModule}
/>

{!isNil(error) ? (
<StdcmEmptyConfigError />
Expand Down Expand Up @@ -206,6 +215,7 @@ const StdcmView = () => {
)}
</div>
)}
<StdcmHelpModule showHelpModule={showHelpModule} toggleHelpModule={toggleHelpModule} />
</div>
)}
{loading && <LoaderFill />}
Expand Down
1 change: 1 addition & 0 deletions front/src/styles/scss/applications/_stdcm.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
@import 'stdcm/linkedPath';
@import 'stdcm/loader';
@import 'stdcm/results';
@import 'stdcm/helpModule';
Loading

0 comments on commit bedd0af

Please sign in to comment.