-
Notifications
You must be signed in to change notification settings - Fork 20
Option in Periods Group that allows users to create their own custom periods template #1335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
6cef39a
92fcfe6
ccbe675
710b111
0dd2022
6064c88
430d89e
0c6066b
a5a23a6
8373127
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| import React, { useState, useEffect } from 'react'; | ||
| import Modal from 'react-modal'; | ||
| import { useTranslation } from 'react-i18next'; | ||
| import InputString from './InputString'; | ||
|
|
||
| interface InputModalProps { | ||
| isOpen: boolean; | ||
| title: string; | ||
| onClose: () => void; | ||
| onConfirm: (value: string) => void; | ||
| confirmButtonColor?: string; | ||
| confirmButtonLabel?: string; | ||
| closeButtonLabel?: string; | ||
| inputPlaceholder?: string; | ||
| defaultValue?: string; | ||
| maxLength?: number; | ||
| type?: 'text' | 'email' | 'number'; | ||
| pattern?: string; | ||
| autocompleteChoices?: ({ label: string; value: string } | string)[]; | ||
| } | ||
|
|
||
| const InputModal: React.FC<InputModalProps> = ({ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pourquoi un nouveau composant InputModal. Que manquait-il aux autres modal? ça prendrait une explication de pourquoi ce type est nécessaire
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lorsqu'on clique sur le bouton Sauvegarder comme modèle, notre idée est de permettre à l’utilisateur de nommer le modèle. Alors, je avais pensé qu’on pourrait créer une fenêtre modale qui combine les fonctionnalités de |
||
| isOpen, | ||
| title, | ||
| onClose, | ||
| onConfirm, | ||
| confirmButtonColor = 'blue', | ||
| confirmButtonLabel, | ||
| closeButtonLabel, | ||
| defaultValue = '', | ||
| maxLength = 255, | ||
| type = 'text', | ||
| pattern, | ||
| autocompleteChoices = [] | ||
| }) => { | ||
| const { t } = useTranslation('main'); | ||
|
|
||
| const [inputValue, setInputValue] = useState(defaultValue); | ||
| const [isValid, setIsValid] = useState(true); | ||
|
|
||
| useEffect(() => { | ||
| setInputValue(defaultValue as string); | ||
| setIsValid(true); | ||
| }, [isOpen, defaultValue]); | ||
|
|
||
| const handleInputChange = (inputData: { value: any; valid: boolean }) => { | ||
| setInputValue(inputData.value); | ||
| setIsValid(inputData.valid); | ||
| }; | ||
|
|
||
| const handleConfirm = () => { | ||
| if (isValid) { | ||
| onConfirm(inputValue); | ||
| onClose(); | ||
| } | ||
| }; | ||
|
|
||
| const handleCancel = () => { | ||
| onClose(); | ||
| }; | ||
|
|
||
| if (!process.env.IS_TESTING) { | ||
| Modal.setAppElement('#app'); | ||
| } | ||
|
|
||
| return ( | ||
| <Modal | ||
| isOpen={isOpen} | ||
| onRequestClose={handleCancel} | ||
| className="react-modal" | ||
| overlayClassName="react-modal-overlay" | ||
| contentLabel={title} | ||
| > | ||
| <div> | ||
| <div className="center">{title}</div> | ||
|
|
||
| <div className="input-modal-content"> | ||
| <InputString | ||
| id="modal-input" | ||
| onValueUpdated={handleInputChange} | ||
| value={inputValue} | ||
| maxLength={maxLength} | ||
| type={type} | ||
| pattern={pattern} | ||
| autocompleteChoices={autocompleteChoices} | ||
| /> | ||
| {!isValid && <div className="apptr__input-error">{t('PleaseEnterValidValue')}</div>} | ||
| </div> | ||
|
|
||
| <div className={'tr__form-buttons-container _center'}> | ||
| <div className="center"> | ||
| <button | ||
| className={`button ${confirmButtonColor || 'blue'}`} | ||
| onClick={handleConfirm} | ||
| disabled={!isValid} | ||
| > | ||
| {confirmButtonLabel || t('Confirm')} | ||
| </button> | ||
| </div> | ||
| <div className="center"> | ||
| <button className="button grey" onClick={handleCancel}> | ||
| {closeButtonLabel || t('Cancel')} | ||
| </button> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </Modal> | ||
| ); | ||
| }; | ||
|
|
||
| export default InputModal; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,7 @@ export type choiceType = { | |
| value: string; | ||
| disabled?: boolean; | ||
| label?: string; | ||
| className?: string; | ||
| choices?: choiceType[]; | ||
| [key: string]: unknown; | ||
| }; | ||
|
|
@@ -67,7 +68,11 @@ const InputSelect: React.FunctionComponent<InputSelectProps> = ({ | |
| if (choice.choices) { | ||
| const childChoices = choice.choices.map((childChoice) => { | ||
| return ( | ||
| <option key={`${childChoice.value}`} value={childChoice.value} disabled={choice.disabled}> | ||
| <option | ||
| key={`choice_${childChoice.value}`} | ||
| value={childChoice.value} | ||
| disabled={childChoice.disabled} | ||
| > | ||
| {childChoice.label || t(`${localePrefix}:${childChoice.value}`)} | ||
| </option> | ||
| ); | ||
|
|
@@ -79,7 +84,12 @@ const InputSelect: React.FunctionComponent<InputSelectProps> = ({ | |
| ); | ||
| } else { | ||
| selectChoices.push( | ||
| <option key={`${choice.value}`} value={choice.value} disabled={choice.disabled}> | ||
| <option | ||
| key={`choice_${choice.value}`} | ||
| value={choice.value} | ||
| disabled={choice.disabled} | ||
| className={choice.className} | ||
| > | ||
| {choice.label || t(`${localePrefix}:${choice.value}`)} | ||
| </option> | ||
| ); | ||
|
|
@@ -97,7 +107,7 @@ const InputSelect: React.FunctionComponent<InputSelectProps> = ({ | |
| textOverflow: 'ellipsis' | ||
| }} | ||
| > | ||
| {!noBlank && <option key={'_blank'} value=""></option>} | ||
| {!noBlank && <option value=""></option>} | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why remove the key here?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oups! Je l'ai enlevé sans faire exprès. Je vais le remettre! |
||
| {selectChoices} | ||
| </select> | ||
| ); | ||
|
|
||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Est-il nécessaire de faire ce changement dans cette classe de base? Plutôt que dans la classe qui l'utilise? On va généralement privilégier d'attendre d'avoir au moins 2 ou 3 utilisations d'un feature avant de l'emmener dans les classes génériques (sinon, ça devient comme un API et il faut tester/supporter, etc)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
En fait, au départ, j'avais écrit ces fonctions dans le fichier
TransitScheduleEdit.tsxpour changer l'état duInputModalqu'on a créé. Mais en fouillant, j'avais trouvé qu'on avait déjà deux fonctions qui se ressemblait beaucoupopenDeleteConfirmModaletopenBackConfirmModal(idem à pour les fonctions de close). Alors, comme j'avais aussi besoin d'ovrir et de fermer la fenêtre InputModal, je me suis dit que je peux réutiliser ces fonctions de open et de close, avec une petite modification pour qu'elles soient plus génériques.Je peux remettre les fonctions initiales dans TransitScheduleEdit sans problème!