Skip to content

Many enhancements: node/edge editing, formula columns, selection panel, Github check before save, mobile UX & pre-production CI... - #332

Open
JeanGarf wants to merge 268 commits into
gephi:mainfrom
JeanGarf:main_jg
Open

Many enhancements: node/edge editing, formula columns, selection panel, Github check before save, mobile UX & pre-production CI...#332
JeanGarf wants to merge 268 commits into
gephi:mainfrom
JeanGarf:main_jg

Conversation

@JeanGarf

@JeanGarf JeanGarf commented Aug 4, 2026

Copy link
Copy Markdown

Pull request type

Check the type of change your PR introduces:

  • Bugfix
  • Feature
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • Documentation content changes
  • Other (please describe):

Summary of changes (d906a95627860e)

This range covers the full set of changes accumulated on this fork since the base commit, spanning many feature/fix branches merged into develop and periodically promoted to main_jg.

Save & session

  • Fix GitHub file being overwritten after creating a new workspace (Critical Bug)

  • Add a save icon next to "Workspace", greyed out until there are unsaved changes

  • Persist session settings (layout & metrics parameters) together with the graph

  • Warn before editing a GitHub file that has become stale, checked as soon as the create/edit popup opens

  • Re-arm the freshness check every ~1 minute (down from 5) and re-check before every save

  • Fix a save deadlock and add an "Overwrite" button to the conflict popup

  • Save-conflict popup: all 3 buttons visible on mobile, "Keep" selected by default

  • Fix a reload loop (the internal reference date wasn't refreshed after Reload)

  • Disable the HTTP cache on gist reads (getFile / getFileContent)

  • Fix a freshness false positive: memorize the open date from the same detail endpoint used by the periodic checks, instead of the list endpoint; add a 1s tolerance to absorb transient GitHub timestamp inconsistencies

  • Stop flagging a remote change that isn't one (real content comparison, not date alone)

  • Fix the two remaining root causes of false "modified on GitHub" alerts: fingerprint mismatch between sent and remote-returned bytes, and an un-persisted "keep my changes" acknowledgment causing repeated re-warnings

  • Open from GitHub: the last opened file is now really preselected (not just visually), so "Open" works immediately

Node & Edge editing

  • Avoid Gephi Lite to crash when deleting an Edge [Deleting Edge makes Gephi lite to crash #318] (critical bug)

  • Prevent creation of duplicate nodes/edges

  • Support changing edge extremities (source/target) via updateEdge, add a swap button in the edit form, and an "Invert arrow's direction" menu item [Add button to invert Source and Target of an Edge #321 ]

  • Pre-fill default attribute values on node/edge creation [Default value for attributes #326 ]

  • Auto-focus the first empty field in node/edge modals

  • Numeric attributes: cross-platform +/− stepper

  • Add a validation button in the modal header and duplicate the OK button in the modal footer (espacially for Android)

  • Fix edge weight resetting to 1 on creation [weight field is reseted to 1 #322 ]

  • Move ID field to the end of node/edge create/edit forms and data columns; move x/y position fields to the end of the edit form

  • Fix Escape not closing the node/edge create/edit popups

  • Confirm before losing unsaved input when closing the editor (Back button, Escape, click-outside, and both close crosses all go through the same confirmation)

Formula (scripted) columns & data columns

  • Scripted columns: persisted script, live recompute, editable label, and a "Freeze values" action to materialize computed values into a static attribute

  • Add automatic "Update Date" / "Creation Date" columns, with backfill for graphs already loaded in session

  • GEXF export now materializes formula column values

  • Rename "Delete attribute" → "Delete column"; rename "Identifier" → "ID"

  • Fix the Label caption for scripted attributes: back to a plain fixed "Label" instead of computing it from the current display label (Appearance)

Selection panel & Graph view

  • Add a title and selected-item count to the selection panel;
  • Make selected nodes/edges clickable to locate them
  • Click a node's label to locate it;
  • Add quick-action icons (locate, select neighbors, edit, invert direction, delete);
  • Add icons to create an edge from a node and select a node's edges
  • Sort selected edges by source, target, then label; show only endpoint labels for a selected edge and refocus dimming on it
  • Improve camera framing when locating an edge; unify multi-edge zoom between table and panel (mobile-aware); fix excessive zoom-out on multi-node framing
  • Scroll the selection panel to top after locating an item
  • Visualize the shortest path between two selected nodes
  • Long-press to add a node or edge to the selection (touch equivalent of Ctrl-click)
  • Mobile: fold the selection panel without losing the selection
  • Selection panel: toggle between alphabetical and size sort, persisted per item type

Search

  • Made the main fuzzy search robust to involuntary focus loss on Android
  • Fixed the clear cross not closing the results list on Windows, and made it reappear automatically on Android
  • Touch-friendly fuzzy search, persistent results, browser autocomplete hidden
  • Clear cross: focus returned to the field, and the cross always visible
  • Persistent fuzzy search text and clearable fields in the editor
  • Pre-fill node/edge creation with the text typed in the fuzzy search
  • Close the results dropdown when another panel or popup takes its place (it used to keep floating on top)

Data tables

  • Locate a node/edge by clicking from the data tables
  • Add Source/Target label columns [In data view, edge mode, Create column Source Label and Target Label #320 ] and move ID columns to the end (edge view, then node view)
  • Search edges by source/target labels, not just internal IDs
  • Keyboard navigation between cells, plus a cancel button
  • Align the number field's stepper with the check button, not the cross

Filters

  • Reorder the filters panel and support scripted attributes as filterable
  • Fix the displayed From/To range-filter placeholder values
  • Add a "Based on filtered values" checkbox for size min/max interpolation
  • Left panel: clarify when filters are active
  • Make filtered items readable and consistent everywhere (funnel icon, selection, dimmed rendering)
  • A filtered edge also dims both its endpoints

Color palette

  • Sort the color legend alphabetically and keep existing colors when a new category is added
  • Remove obsolete categories from the palette; sync the palette when data changes, not only when fields change

Mobile & navigation

  • Add mobile header with node/edge creation icons; expand the Workspace toolbar by default on mobile
  • Fix the Layout submenu appearing unexpectedly on mobile
  • Android Back button closes the popup instead of navigating; prevent Back from popping Graph/Data views or exiting the app with unsaved work; warn before leaving the app with unsaved changes
  • Add a "+" button to create a node directly from the bottom bar, between the panel-close button and "Graph"

Default labels

  • Use ID as the default label for nodes/edges; don't show the ID when "No label" is selected

Pre-production banner & CI

  • Add CI deployment of pre-production to GitHub Pages from develop; configure GitHub Pages for this fork; grant contents:write permission to the deploy workflow
  • Move the pre-production banner to the top of the graph; detect preprod via URL

Misc / internal

  • Factor the duplicated data-creation menu into a shared constant; add it to the Graph view above Spatialisation [Data Creation Menu also on Graph View #319 ]
  • Refresh the filtered graph cache on node/edge data changes, not only on fullGraph reference changes
  • Documentation: factoring rule (avoid divergent behavior across call sites) and feature-branch sync rule (merge --no-ff)
  • Show the build commit hash and date below the version number in the About popup, so the running version can be checked at a glance

JeanGarf and others added 30 commits July 13, 2026 23:21
Keeps it consistent with the Node ID/Edge ID column already moved to the end in the data table views.
# Conflicts:
#	packages/gephi-lite/src/views/graphPage/Selection.tsx
Remove the CNAME pointing to the upstream lite.gephi.org domain,
switch redirect URLs to relative paths, trigger deploy-app on
push to main_jg instead of main (kept in sync with upstream),
and disable the automatic Docker Hub publish workflow.
- Nouvelle icône dans le volet de sélection d'un nœud ouvrant le formulaire
  de création d'edge avec ce nœud pré-rempli comme source et le focus placé
  sur le champ cible.
- Support d'un prop autoFocus dans GraphSearch.
- Correction d'un crash latent : le rendu d'un item de sélection était tenté
  avant que le dataset ait rattrapé la sélection (fenêtre transitoire après
  création), provoquant un accès sur des données undefined. Le rendu est
  désormais ignoré pour ce frame et se corrige au rendu suivant. Les deux
  listes partagent le même renderItem factorisé.
- Traductions create_edge_from_node ajoutées (dev, en, fr, hu, ko, uk).
Lors de la sélection d'un ou plusieurs edges, les nœuds source et cible
sont désormais mis en avant (labels forcés) et tous les autres nœuds sont
estompés avec leur label masqué, de la même façon que lors de la sélection
d'un nœud.
Lors de la localisation d'un item (bouton du volet de sélection), l'estompage
est désormais recentré sur les nœuds mis en évidence : localiser un edge parmi
plusieurs edges sélectionnés n'affiche plus que les labels de sa source et de
sa cible, tous les autres nœuds étant estompés le temps de la mise en évidence.
…lisation

- Ajout d'une case à cocher (cochée) en tête de chaque edge sélectionné ;
  la décocher désélectionne l'edge (et éteint donc les labels de ses nœuds).
- Le bouton "localiser" d'un edge ne sélectionne plus que cet edge avant de
  zoomer, pour un focus persistant sur sa source et sa cible.
- Retrait du focus temporaire via highlightedNodes, l'estompage étant piloté
  par la sélection.
Affiche "Selected nodes" ou "Selected edges" en tête du volet de droite
pour rendre explicite que les items listés sont sélectionnés.
Le canvas sigma occupe toute la fenêtre : le header et les volets sont dessinés
par-dessus. Le cadrage vise désormais la zone réellement visible (l'élément
".filler", entre les volets et sous le header, quel que soit leur état), avec
recentrage, et réserve la place des disques des nœuds (unités de graphe) et de
leurs labels (mesurés en pixels) pour qu'ils tiennent intégralement.
- Séparateur sous le titre du volet.
- Icône croix (fermer), grise et homogène, à gauche de l'aperçu d'un item
  sélectionné (nœud ou edge) pour le désélectionner, à la place de l'ancienne
  case à cocher (moins de risque de clic accidentel près de "localiser").
- Tooltips ajoutés sur les icônes caret, menu et croix.
- Volet des nœuds : icône "sélectionner les edges" placée avant "sélectionner
  les voisins" (usage plus fréquent).
…icônes

- Dans le volet Selected Edges, la source et la cible de chaque edge sont
  désormais cliquables : un clic localise ce nœud (remplace la sélection par
  ce seul nœud puis recentre la caméra), équivalent au bouton localiser d'un nœud.
- Dans le volet Selected Nodes, échange des icônes crayon (éditer) et + (créer
  un edge), et ajout d'un espace avant l'icône poubelle.
claude added 26 commits July 26, 2026 13:38
Sur petit écran le volet de sélection et le panneau de menu sont
empilés et ne peuvent pas être ouverts en même temps, et le seul bouton
pour refermer le volet vidait la sélection : le champ de recherche
n'était donc atteignable qu'en perdant ce qui était sélectionné.

Ce bouton devient un chevron qui replie simplement le volet, la
sélection étant conservée. Un second appui ouvre le panneau de menu et
donne accès à la recherche. Toute modification de la sélection redéploie
le volet, ce qui est le chemin de retour.

Vider la sélection se fait désormais depuis une croix ajoutée dans la
barre de titre du volet, à droite du bouton de localisation et séparée
de lui pour éviter les appuis manqués. Sur grand écran rien ne change :
la croix en haut à droite du volet vide toujours la sélection, et la
nouvelle croix n'y est pas affichée.
Un bouton dans la barre de titre bascule l'ordre de la liste entre
alphabétique (par libellé pour un nœud ; par source, cible puis libellé
pour un lien, l'ordre existant) et taille décroissante. La taille est
celle du rendu, calculée par Apparence > Taille, donc l'ordre du volet
correspond à ce que montre le graphe ; à taille égale, le tri
alphabétique départage pour que la liste reste lisible. Les nœuds
n'étaient jusqu'ici pas triés du tout et apparaissaient dans l'ordre
d'insertion.

Le réglage est persisté dans les préférences, séparément pour les nœuds
et pour les liens.

Corrige au passage le désérialiseur du SDK : il prenait pour un graphe
sérialisé tout objet possédant les clés « nodes » et « edges », sans
vérifier qu'il s'agissait bien de tableaux. Un état simplement indexé
par type d'élément faisait donc échouer l'analyse et l'ensemble du
document était silencieusement abandonné - ce qui rendait ici toutes les
préférences non persistantes, thème compris.
…pas un

Après une sauvegarde, la date de référence était mémorisée depuis la
réponse du PATCH, alors que toutes les vérifications ultérieures lisent
la date depuis GET /gists/{id}. Les deux peuvent différer pour la
version qui vient d'être écrite, et le garde-fou croyait alors que le
distant avait bougé - à chaque vérification, jusqu'à la sauvegarde
suivante. La date est désormais relue depuis le même endpoint que les
vérifications, comme le fait déjà l'ouverture d'un fichier.

Deuxième garde-fou, indépendant de la cause : avant d'alerter, le
contenu distant est téléchargé et comparé à l'empreinte de ce qui a été
synchronisé en dernier. La date de mise à jour d'un gist bouge en effet
pour des raisons qui ne touchent pas au fichier (étoile, fork,
commentaire, ou deux lectures de la même version qui ne s'accordent
pas) ; seules des données réellement différentes déclenchent désormais
l'avertissement. Quand elles sont identiques, la nouvelle date est
adoptée comme référence pour ne pas re-télécharger à chaque minute.

L'empreinte est rangée dans l'état fichier, donc persistée : elle
survit à un rechargement de page. Sans empreinte connue, le
comportement précédent s'applique (comparaison de dates seule), et un
échec de téléchargement alerte aussi - le doute doit rester du côté qui
protège le travail distant.
Le bouton Retour d'Android fermait l'éditeur sans condition, effaçant au
passage ce que l'utilisateur avait commencé à saisir. Il demande
désormais confirmation dès que quelque chose a été modifié, et la
réponse par défaut - bouton principal, focalisé, et réponse de la touche
Échap - est de poursuivre la saisie. Sans aucune modification, la
fermeture reste immédiate.

Même traitement pour les deux autres fermetures involontaires que ces
éditeurs autorisent, la touche Échap et le clic à l'extérieur : elles
perdaient la saisie exactement de la même façon. Les boutons de
fermeture et d'annulation restent sans confirmation, un clic dessus
étant une intention explicite.

La demande de fermeture passe maintenant par l'état des modales
(`requestCloseModal`) plutôt que par une fermeture directe, ce qui
permet à la modale ouverte d'intervenir ; les modales sans saisie en
cours se ferment comme avant. L'état « saisie en cours » vient de
`dirtyFields` et non de `formState.isDirty`, ce dernier étant déjà vrai à
l'ouverture parce qu'un champ dont la valeur par défaut est indéfinie
rapporte une chaîne vide dès son enregistrement.
Les deux croix de fermeture - celle de l'en-tête de la modale et celle
du pied de formulaire - passent désormais par la même demande de
fermeture que la touche Retour, Échap et le clic à l'extérieur : sans
saisie en cours elles ferment directement, sinon elles affichent la
confirmation qui, par défaut, poursuit la saisie.

La modale expose sa demande de fermeture par contexte, ce qui permet au
pied de formulaire - construit par le formulaire et non par la modale -
de l'utiliser sans dupliquer la logique. Hors modale (les mêmes
formulaires sont aussi rendus dans un volet latéral), le bouton
d'annulation retombe sur son gestionnaire d'origine.

Ajoute au CLAUDE.md la règle correspondante : une même action
déclenchable de plusieurs façons doit passer par un seul et même code, et
une demande visant un seul de ces déclencheurs s'applique aux autres.
Sous le numéro de version, en gris et en petit pour ne pas attirer
l'œil : le hash de commit git et la date/heure de build, de manière à
pouvoir vérifier qu'on est bien sur la dernière version déployée.

Les deux valeurs sont injectées une fois pour toutes à la compilation
(vite.config.mts, via `define`), donc gravées dans le bundle : rien à
calculer ni à récupérer au chargement de la page. Absentes (nœud null)
dans un environnement sans checkout git pour lire le hash, auquel cas
la ligne ne s'affiche pas du tout plutôt que d'afficher une valeur
trompeuse.
L'empreinte de référence était prise sur les octets envoyés lors d'une
sauvegarde, alors que la vérification compare avec les octets que le
distant renvoie. Toute différence introduite par GitHub sur le trajet
suffisait donc à faire échouer chaque comparaison ultérieure, et la
protection par contenu ajoutée précédemment ne servait plus à rien. La
sauvegarde relit désormais le gist et prend l'empreinte de ce qu'il
contient réellement — même lecture, même côté du fil.

Une seule requête ramène maintenant métadonnées et contenu (readGist),
ce qui évite aussi de mélanger une date issue d'une lecture avec un
contenu issu d'une autre.

Par ailleurs, répondre « Conserver mes modifications » ne changeait rien
à l'état : la vérification suivante retrouvait le même écart de date et
réaffichait l'alerte, toutes les minutes. La version distante ainsi
écartée est désormais mémorisée et n'est plus resignalée ; une version
distante réellement nouvelle alerte toujours, et la vérification avant
sauvegarde reste inchangée pour ne pas écraser sans confirmation.

Enfin, quand aucune empreinte n'est connue (état enregistré par une
version antérieure), celle du distant est mémorisée au passage, pour que
la vérification suivante puisse trancher au lieu de redemander sans fin.
…u une popup la remplace

Sur mobile, la liste de résultats de la recherche fuzzy est affichée dans
un portail pour rester visible malgré un blur involontaire (repli CSS du
panneau). Ce mécanisme la laissait aussi flotter au-dessus de la popup de
création de node/edge (ou de toute autre popup) ouverte depuis le "+", et
au-dessus des autres panneaux du menu latéral.

La fermeture est maintenant explicite dès qu'une popup s'ouvre ou que le
panneau de recherche est remplacé par un autre, et la liste réapparaît
avec les mêmes résultats une fois la popup fermée ou le panneau repris.
…vert

La ligne du dernier fichier ouvert pouvait apparaître en surbrillance sans
que rien ne soit réellement sélectionné, rendant le bouton Open inopérant
tant qu'on ne recliquait pas dessus. Le fichier actuellement ouvert dans
l'espace de travail est maintenant vraiment présélectionné dès le
chargement de la liste, sans persistance au-delà de la session en cours.
Ajout d'un bouton "+" entre le bouton de fermeture du volet et le
bouton Graph, ouvrant directement la popup de création de node (la
même que celle déjà utilisée depuis le "+" à côté de "Nodes" ou le
menu de création de données). Pas de bouton équivalent pour les edges :
on en crée une depuis un node déjà sélectionné.
@JeanGarf JeanGarf changed the title Main jg Many enhencements: node/edge editing, formula columns, selection panel, Github check before save, mobile UX & pre-production CI... Aug 4, 2026
@JeanGarf JeanGarf changed the title Many enhencements: node/edge editing, formula columns, selection panel, Github check before save, mobile UX & pre-production CI... Many enhancements: node/edge editing, formula columns, selection panel, Github check before save, mobile UX & pre-production CI... Aug 4, 2026
@JeanGarf

JeanGarf commented Aug 4, 2026

Copy link
Copy Markdown
Author

Thank you for creating Gephi-Lite and sorry for having made such a major update all at once, but I didn't initially think I would implement so many ergonomic improvements to make data entry and navigation smoother.

From now on, it is much easier to create Nodes and Links from these Nodes, to visualize the Links from a Node, and many other things.

Don't hesitate to contact me if needed to integrate this update.

Best regards,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants