-
Notifications
You must be signed in to change notification settings - Fork 23
SCENARIO: Delete a picture from a document (see#187). #283
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?
Conversation
|
Thank you @Sidqui-Youssef and @Amine-jabote for your scenario. Please note that your scenario should be in the |
2d4fa8b to
593d936
Compare
7a9c4be to
52a5fcb
Compare
Co-authored-by: Amine-jabote <[email protected]>
… (see #199). Co-authored-by: lucas-rubagotti <[email protected]>
|
Thank you for your contribution @lucas-rubagotti @IlanPin @nasschml. |
34cc072 to
274098c
Compare
|
On remercie @lunatiique et @floporsch911 qui nous ont aidé pour la gestion de l'historique des commits . |
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.
Thank you for your contribution @IlanPin and @nasschml (and the others for scenarios and tests).
However the implementation cannot be integrated for now as it still does not comply with the quality expectations of the project.
The related skill to be acquired in this course is named "Développer une fonctionnalité en minimisant l'impact des changements sur le code existant".
For now the last commit impacts 319 lines. This is HUGE for a single feature. If you look at others you will see it ranges from 20 to 80 lines. Please amend the code to comply with my first review and I will start a seconde one.
Regards.
| @@ -1,103 +1,309 @@ | |||
| import { useState, useEffect, useCallback, useMemo, useRef } from 'react'; | |||
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.
Please don't move the line from line 3 to line 1. This will make the diff more understandable (and hence easier to rebase and to understand blame view)
| import DiscreeteDropdown from './DiscreeteDropdown'; | ||
| import PictureUploadAction from '../menu-items/PictureUploadAction'; | ||
| import {v4 as uuid} from 'uuid'; | ||
| import { v4 as uuid } from 'uuid'; |
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.
Please don't include changes unrelated with your contribution. This "pollutes" blame view and more lines means more conflicts when integrating your work.
| setSelectedText, | ||
| backend, | ||
| setLastUpdate | ||
| }) { |
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.
Please don't include changes unrelated with your contribution. This "pollutes" blame view and more lines means more conflicts when integrating your work.
Moreover, in this case, it makes it very difficult to locate if you added a parameter or not.
| const [editedDocument, setEditedDocument] = useState(); | ||
| const [editedText, setEditedText] = useState(); | ||
| const PASSAGE = new RegExp(`\\{${rubric}} ?([^{]*)`); | ||
| const [editedDocument, setEditedDocument] = useState(null); |
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.
Please don't include changes unrelated with your contribution. This "pollutes" blame view and more lines means more conflicts when integrating your work.
In this cas, this means exactly the same (no parameter means a null parameter).
| const [editedText, setEditedText] = useState(); | ||
| const PASSAGE = new RegExp(`\\{${rubric}} ?([^{]*)`); | ||
| const [editedDocument, setEditedDocument] = useState(null); | ||
| const [editedText, setEditedText] = useState(''); |
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.
Please don't include changes unrelated with your contribution. This "pollutes" blame view and more lines means more conflicts when integrating your work.
Moreover null is different from "". This could have unexpected effects.
frontend/src/hyperglosae.js
Outdated
| }); | ||
|
|
||
| this.deleteDocument = ({_id, _rev}) => | ||
| this.deleteDocument = ({ _id, _rev }) => |
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.
Unrelated with the contribution.
frontend/src/hyperglosae.js
Outdated
| .then(x => x.userCtx?.name); | ||
|
|
||
| this.postSession = ({name, password}) => | ||
| this.postSession = ({ name, password }) => |
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.
Unrelated with the contribution.
frontend/src/hyperglosae.js
Outdated
|
|
||
| this.refreshMetadata = (id, callback) => { | ||
| this.getView({view: 'metadata', id, options: ['include_docs']}) | ||
| this.getView({ view: 'metadata', id, options: ['include_docs'] }) |
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.
Unrelated with the contribution.
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.
Why haven't you fixed this?
frontend/src/hyperglosae.js
Outdated
|
|
||
| this.refreshContent = (id, callback) => { | ||
| this.getView({view: 'content', id, options: ['include_docs']}) | ||
| this.getView({ view: 'content', id, options: ['include_docs'] }) |
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.
Unrelated with the contribution.
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.
Why haven't you fixed this?
frontend/src/hyperglosae.js
Outdated
|
|
||
| this.getAllDocuments = (user) => | ||
| this.getView({view: 'all_documents', id: user || 'PUBLIC', options: ['include_docs']}) | ||
| this.getView({ view: 'all_documents', id: user || 'PUBLIC', options: ['include_docs'] }) |
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.
Unrelated with the contribution.
bc0fdaf to
ba21230
Compare
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.
| ? rawText.match(PASSAGE)[1] | ||
| : rawText; | ||
| // Memoized regex to extract our passage | ||
| const PASSAGE = useMemo(() => new RegExp(`\\{${rubric}} ?([^\\{]*)`), [rubric]); |
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.
In other words, you added useMemo although it had nothing to do with your contribution.
| <svg viewBox="0 0 16 16"> | ||
| <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0z"/> | ||
| <path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1z"/> | ||
| </svg>`; |
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.
Why haven't you fixed this?
| fig.appendChild(trash); | ||
| fig.addEventListener('mouseenter', () => (trash.style.opacity = '1')); | ||
| fig.addEventListener('mouseleave', () => (trash.style.opacity = '0')); | ||
| trash.addEventListener('click', () => { |
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.
Why haven't you fixed this?
| }); | ||
| }; | ||
|
|
||
| const obs = new MutationObserver(attachTrash); |
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.
Why haven't you fixed this?
frontend/src/hyperglosae.js
Outdated
|
|
||
| this.refreshMetadata = (id, callback) => { | ||
| this.getView({view: 'metadata', id, options: ['include_docs']}) | ||
| this.getView({ view: 'metadata', id, options: ['include_docs'] }) |
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.
Why haven't you fixed this?
frontend/src/hyperglosae.js
Outdated
|
|
||
| this.refreshContent = (id, callback) => { | ||
| this.getView({view: 'content', id, options: ['include_docs']}) | ||
| this.getView({ view: 'content', id, options: ['include_docs'] }) |
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.
Why haven't you fixed this?
|
We have decided to keep the use of MutationObserver in the EditableText component. After further review, we realized that removing it would have required major refactoring of related logic. We have now made sure that everything not related to our contribution remains untouched. To integrate the React Bootstrap Icons trash component cleanly into the DOM, we imported both react-dom (for createRoot) and react-bootstrap-icons. We refactored the relevant useEffect to use the component instead of injecting raw SVG code. The associated CSS was updated to style the new button as required (bottom-right, with a dark background). In addition, we updated the event test (event.js). The workaround with manual click propagation is no longer needed, since our click handling is now fully compatible with Cypress. All changes are now limited strictly to our contribution, and the commit history is clean. |
|
@IlanPin @nasschml Here is a prompt you can type into ChatGPT:
It will both explain you why these are bad practices and give you the rules you can apply to correct your code. |
Co-authored-by: lucas-rubagotti <[email protected]>
5688511 to
2c55c78
Compare
|
Thank you for your feedback regarding the use of DOM methods like querySelectorAll, querySelector, document.createElement, etc. We now fully understand the importance of maintainability and React best practices: With the latest commit, all logic for displaying and deleting images is now handled 100% in a React-friendly way: Everything works as expected on my local setup (display, image deletion, etc.), but some tests still fail in the CI pipeline. I will continue investigating this on my side. In the meantime, I am open to any feedback or suggestions you may have to further improve the React implementation. |
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.
| import {v4 as uuid} from 'uuid'; | ||
|
|
||
| function EditableText({id, text, rubric, isPartOf, links, fragment, setFragment, setHighlightedText, setSelectedText, backend, setLastUpdate}) { | ||
| function EditableText({ id, text, rubric, isPartOf, links, fragment, setFragment, setHighlightedText, setSelectedText, backend, setLastUpdate }) { |
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.
This edited line is not related with your contribution.
| </div> | ||
| <DiscreeteDropdown> | ||
| <PictureUploadAction {... {id, backend, handleImageUrl}}/> | ||
| <PictureUploadAction {...{id, backend, handleImageUrl}} /> |
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.
This edited line is not related with your contribution.
| )} | ||
| </div> | ||
| ); | ||
|
|
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.
This edited line is not related with your contribution.
|
|
||
| const imageRegex = /!\[([^\]]*)\]\(([^)]+)\)/g; | ||
| let images = []; | ||
| let Text = text || ''; |
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.
Upper case names are usually used for classes and not for variables.
| while ((match = imageRegex.exec(Text)) !== null) { | ||
| images.push({ alt: match[1], src: match[2] }); | ||
| } | ||
| Text = Text.replace(imageRegex, ''); |
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.
Upper case names are usually used for classes and not for variables.
| const clean = t => (t || '').replace(mdRx, '').replace(/\n{2,}/g, '\n\n').trim(); | ||
| if (internal) { | ||
| backend.deleteAttachment(id, name, res => { | ||
| if (!res.ok) return alert('Error deleting attachment.'); |
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.
Don't show notifications to users if you don't provide solutions for them to fix the problem.
| <div className="formatted-text" onClick={handleClick}> | ||
| <FormattedText {...{setHighlightedText, setSelectedText}}> | ||
| {text || ' '} | ||
| <FormattedText {...{ setHighlightedText, setSelectedText }}> |
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.
This line is not related with your contribution.
caddc1a to
201e3d2
Compare
Co-authored-by: Nasschml <[email protected]>
We, @Sidqui-Youssef @lucas-rubagotti @Amine-jabote @FredWantou @IlanPin @nasschml , hereby grant to Hyperglosae maintainers the right to publish our contribution under the terms of any licenses the Free Software Foundation classifies as Free Software Licenses.