Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe Commits: 4fde4c23 by Tony Chemit at 2023-04-01T16:02:43+02:00 Erreur sur déplacement de données d'observation (la marée cible n'est pas bien rafrachît dans l'arbre de navigation) - Closes #2656 - - - - - 5930e9e5 by Tony Chemit at 2023-04-01T16:02:43+02:00 Lorsque l'on réinitialise le programme d'une marée, il faudrait certainement rafraichir l'arbre - Closes #2658 - - - - - 445e730f by Tony Chemit at 2023-04-01T16:02:43+02:00 Navigation UI - improve delete root data - - - - - acb6bc6c by Tony Chemit at 2023-04-01T16:02:44+02:00 Sur le nœud Observations embarqués, il est possible de tout déplacer même si le formulaire n'est pas accéssible - Closes #2665 - - - - - 10 changed files: - client/core/src/main/resources/fr/ird/observe/client/ui/ObserveCommon.jcss - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/delete/DeleteRootTreeAdapter.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/move/MoveExecutor.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/move/MoveTreeAdapter.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/move/layout/MoveLayoutExecutor.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/move/layout/MoveLayoutTreeAdapter.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/ropen/actions/SaveContentRootOpenableUIAdapter.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/NavigationUIHandler.java - client/datasource/editor/ps/src/main/java/fr/ird/observe/client/datasource/editor/ps/data/observation/RouteListUI.jaxx - toolkit/api-services/src/main/java/fr/ird/observe/services/service/data/MoveRequest.java Changes: ===================================== client/core/src/main/resources/fr/ird/observe/client/ui/ObserveCommon.jcss ===================================== @@ -195,3 +195,7 @@ BlockingLayerUI { .editableAndNotModified { enabled:{states.isEditable() && !states.isModified()}; } + +.editableAndShowDataAndNotEmpty { + enabled:{states.isEditable() && states.isShowData() && !states.isEmpty()}; +} ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/delete/DeleteRootTreeAdapter.java ===================================== @@ -23,7 +23,6 @@ package fr.ird.observe.client.datasource.editor.api.content.actions.delete; */ import fr.ird.observe.client.datasource.editor.api.navigation.NavigationUI; -import fr.ird.observe.client.datasource.editor.api.navigation.NavigationUIHandler; import fr.ird.observe.client.datasource.editor.api.navigation.tree.NavigationNode; import fr.ird.observe.client.datasource.editor.api.navigation.tree.root.RootNavigationInitializer; @@ -45,6 +44,8 @@ public abstract class DeleteRootTreeAdapter<OldParent extends NavigationNode> ex @Override public void removeChildren(NavigationUI navigationUI, OldParent parentNode, Set<String> ids) { super.removeChildren(navigationUI, parentNode, ids); + // update navigation result + navigationUI.getTree().getModel().updateNavigationResult(); NavigationNode rootNode = parentNode.getRoot(); RootNavigationInitializer initializer = (RootNavigationInitializer) rootNode.getInitializer(); boolean removeGroupBy = parentNode.getChildCount() == 0 && !initializer.getRequest().isLoadEmptyGroupBy(); @@ -54,6 +55,5 @@ public abstract class DeleteRootTreeAdapter<OldParent extends NavigationNode> ex navigationUI.getTree().selectFirstNode(); } } - NavigationUIHandler.updateStatistics(navigationUI, removeGroupBy ? -1 : 0, -ids.size()); } } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/move/MoveExecutor.java ===================================== @@ -27,6 +27,7 @@ import fr.ird.observe.client.datasource.editor.api.navigation.NavigationTree; import fr.ird.observe.client.util.ObserveSwingTechnicalException; import fr.ird.observe.datasource.security.ConcurrentModificationException; import fr.ird.observe.dto.ToolkitIdDtoBean; +import fr.ird.observe.navigation.tree.navigation.NavigationTreeConfig; import fr.ird.observe.services.service.data.MoveRequest; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -90,7 +91,14 @@ public class MoveExecutor { ToolkitIdDtoBean oldParentId = request.getOldParentId(); Set<String> referenceId = request.getIds(); log.info(String.format("Move adapt tree [start] %s from parent: %s to %s", referenceId, oldParentId, newParentId)); - + String oldGroupByValue; + if (request.isNewParentIsRootType()) { + // if new parent id is a Trip, then we need to keep back his groupBy value + NavigationTreeConfig config = tree.getModel().getConfig(); + oldGroupByValue = tree.getModel().getDataSourcesManager().getMainDataSource().getRootOpenableService().getGroupByValue(config.getGroupByName(), config.getGroupByFlavor(), newParentId.getId()); + } else { + oldGroupByValue = null; + } Set<String> newIds; try { newIds = requestConsumer.apply(request, newParentId, referenceId); @@ -100,7 +108,7 @@ public class MoveExecutor { MoveTreeAdapter<?, ?, ?> moveTreeAdapter = this.treeAdapter.apply(request); try { - SwingUtilities.invokeAndWait(() -> moveTreeAdapter.adaptTree(request, tree, newIds)); + SwingUtilities.invokeAndWait(() -> moveTreeAdapter.adaptTree(request, tree, newIds, oldGroupByValue)); } catch (InterruptedException | InvocationTargetException e) { throw new ObserveSwingTechnicalException(e.getCause()); } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/move/MoveTreeAdapter.java ===================================== @@ -22,8 +22,10 @@ package fr.ird.observe.client.datasource.editor.api.content.actions.move; * #L% */ +import fr.ird.observe.client.datasource.editor.api.content.data.rlist.ContentRootListUINavigationNode; import fr.ird.observe.client.datasource.editor.api.navigation.NavigationTree; import fr.ird.observe.client.datasource.editor.api.navigation.tree.NavigationNode; +import fr.ird.observe.navigation.tree.navigation.NavigationTreeConfig; import fr.ird.observe.services.service.data.MoveRequest; import java.util.Objects; @@ -50,24 +52,44 @@ public abstract class MoveTreeAdapter<OldParent extends NavigationNode, NewParen public abstract NewNode addMissingChildren(NewParent newParentNode, String newId); - public final void adaptTree(MoveRequest request, NavigationTree tree, Set<String> newIds) { + public final void adaptTree(MoveRequest request, NavigationTree tree, Set<String> newIds, String oldGroupByValue) { Set<String> ids = request.getIds(); boolean selectTarget = request.isSelectTarget(); boolean multiple = !request.isSingle(); OldParent oldParentNode = getOldParentNode(getIncomingNode()); - NewParent newParentNode = getNewParentNode(oldParentNode, request.getNewParentId().getId()); - NavigationNode nodeToSelect = adaptNewParentNode(newParentNode, multiple || !selectTarget ? null : newIds.iterator().next()); + String newParentId = request.getNewParentId().getId(); + if (request.isNewParentIsRootType()) { + NavigationTreeConfig config = tree.getModel().getConfig(); + String groupByValue = oldParentNode.getContext().getServicesProvider().getRootOpenableService().getGroupByValue(config.getGroupByName(), config.getGroupByFlavor(), newParentId); + if (!Objects.equals(oldGroupByValue, groupByValue)) { + // the navigation must be updated, new parent groupBy value has changed + String[] previousPaths = oldParentNode.toPaths(); + tree.getModel().updateNavigationResult(); + // update the old parent parent node + ContentRootListUINavigationNode oldParentNodeParent = (ContentRootListUINavigationNode) oldParentNode.upToGroupByValue(); + oldParentNodeParent.updateNode(); + // get the new old parent node + oldParentNode = (OldParent) tree.getModel().getNodeFromPath(previousPaths, false); + // need also to update the new parent old parent node + ContentRootListUINavigationNode newParentOldParentNode = (ContentRootListUINavigationNode) tree.getModel().getNodeFromPath(new String[]{oldGroupByValue}, false); + if (newParentOldParentNode != null) { + // only update it if it still exist (the node may have been removed from navigation tree) + newParentOldParentNode.updateNode(); + if (!config.isLoadEmptyGroupBy() && newParentOldParentNode.getChildCount() == 0) { + // the configuration requires that node to be removed + newParentOldParentNode.removeFromParent(); + } + } + } + } + NewParent newParentNode = getNewParentNode(oldParentNode, newParentId); + + // kep old node paths + String[] oldNodePaths = oldParentNode.toPaths(); + NavigationNode nodeToSelect = adaptNewParentNode(tree, newParentNode, multiple || !selectTarget ? null : newIds.iterator().next()); if (!selectTarget) { // stay on old parent node - nodeToSelect = oldParentNode; - } else { - if (multiple) { - // on multiple move select new parent node - nodeToSelect = newParentNode; - } else if (nodeToSelect == null) { - // this can happen if new parent node was not loaded before the service call - nodeToSelect = newParentNode; - } + nodeToSelect = tree.getModel().getNodeFromPath(oldNodePaths, false); } adaptOldParentNode(oldParentNode, ids); doFinalSelect(selectTarget, tree, nodeToSelect); @@ -82,18 +104,17 @@ public abstract class MoveTreeAdapter<OldParent extends NavigationNode, NewParen oldParentNode.reloadNodeDataToRootAndChildren(); } - public final NewNode adaptNewParentNode(NewParent newParentNode, String newId) { + public final NavigationNode adaptNewParentNode(NavigationTree tree, NewParent newParentNode, String newId) { // reload node - newParentNode.reloadNodeDataToRootAndChildren(); - // add new nodes - // refresh ui FIXME:Tree this should be done by addMissingChildren ? - newParentNode.nodeChanged(); - NewNode newNode = addMissingChildren(newParentNode, newId); -// if (newNode!=null) { -// // and reload his parent -// newNode.getParent().reloadNodeData(); -// } - return newNode; + String[] paths = newParentNode.toPaths(); + ContentRootListUINavigationNode newParentOldParentNode = (ContentRootListUINavigationNode) newParentNode.upToGroupByValue(); + newParentOldParentNode.updateNode(); + newParentNode = (NewParent) tree.getModel().getNodeFromPath(paths, false); + if (newId == null) { + return newParentNode; + } + // get new node + return addMissingChildren(newParentNode, newId); } public final void doFinalSelect(boolean selectTarget, NavigationTree tree, NavigationNode nodeToSelect) { ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/move/layout/MoveLayoutExecutor.java ===================================== @@ -25,6 +25,7 @@ package fr.ird.observe.client.datasource.editor.api.content.actions.move.layout; import fr.ird.observe.client.datasource.editor.api.DataSourceEditor; import fr.ird.observe.client.datasource.editor.api.navigation.NavigationTree; import fr.ird.observe.client.util.ObserveSwingTechnicalException; +import fr.ird.observe.navigation.tree.navigation.NavigationTreeConfig; import fr.ird.observe.services.service.data.MoveLayoutRequest; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -88,11 +89,14 @@ public class MoveLayoutExecutor { String oldParentId = request.getOldParentId(); log.info(String.format("Move adapt tree [start] from parent: %s to %s", oldParentId, newParentId)); + NavigationTreeConfig config = tree.getModel().getConfig(); + String oldGroupByValue = tree.getModel().getDataSourcesManager().getMainDataSource().getRootOpenableService().getGroupByValue(config.getGroupByName(), config.getGroupByFlavor(), newParentId); + requestConsumer.accept(request); MoveLayoutTreeAdapter<?, ?> moveTreeAdapter = treeAdapter.apply(request); try { - SwingUtilities.invokeAndWait(() -> moveTreeAdapter.adaptTree(request, tree)); + SwingUtilities.invokeAndWait(() -> moveTreeAdapter.adaptTree(request, tree, oldGroupByValue)); } catch (InterruptedException | InvocationTargetException e) { throw new ObserveSwingTechnicalException(e.getCause()); } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/move/layout/MoveLayoutTreeAdapter.java ===================================== @@ -22,6 +22,7 @@ package fr.ird.observe.client.datasource.editor.api.content.actions.move.layout; * #L% */ +import fr.ird.observe.client.datasource.editor.api.content.data.rlist.ContentRootListUINavigationNode; import fr.ird.observe.client.datasource.editor.api.content.data.ropen.ContentRootOpenableUINavigationNode; import fr.ird.observe.client.datasource.editor.api.navigation.NavigationTree; import fr.ird.observe.client.datasource.editor.api.navigation.tree.NavigationNode; @@ -48,15 +49,36 @@ public abstract class MoveLayoutTreeAdapter<ParentNode extends ContentRootOpenab public abstract SourceNode getNodeToSelect(ParentNode parentNode); - public final void adaptTree(MoveLayoutRequest request, NavigationTree tree) { + public final void adaptTree(MoveLayoutRequest request, NavigationTree tree, String oldGroupByValue) { boolean selectTarget = request.isSelectTarget(); ParentNode oldParentNode = oldParentSupplier.get(); NavigationTreeConfig config = tree.getModel().getConfig(); String newParentId = request.getNewParentId(); - //FIXME NPE See https://gitlab.com/ultreiaio/ird-observe/-/issues/2656 String groupByValue = oldParentNode.getContext().getServicesProvider().getRootOpenableService().getGroupByValue(config.getGroupByName(), config.getGroupByFlavor(), newParentId); + if (!Objects.equals(oldGroupByValue, groupByValue)) { + // the navigation must be updated, new parent groupBy value has changed + tree.getModel().updateNavigationResult(); + // update the old parent parent node + ContentRootListUINavigationNode oldParentNodeParent = oldParentNode.getParent(); + oldParentNodeParent.updateNode(); + // get the new old parent node + oldParentNode = (ParentNode) oldParentNodeParent.findChildById(request.getOldParentId()); + + // need also to update the new parent old parent node + ContentRootListUINavigationNode newParentOldParentNode = (ContentRootListUINavigationNode) tree.getModel().getNodeFromPath(new String[]{oldGroupByValue}, false); + if (newParentOldParentNode != null) { + // only update it if it still exist (the node may have been removed from navigation tree) + newParentOldParentNode.updateNode(); + if (!config.isLoadEmptyGroupBy() && newParentOldParentNode.getChildCount() == 0) { + // the configuration requires that node to be removed + newParentOldParentNode.removeFromParent(); + } + } + } else { + + oldParentNode.updateNode(); + } @SuppressWarnings("unchecked") ParentNode newParentNode = (ParentNode) tree.getModel().getNodeFromPath(new String[]{groupByValue, newParentId}, true); - oldParentNode.updateNode(); newParentNode.updateNode(); if (selectTarget) { NavigationNode nodeToSelect = getNodeToSelect(newParentNode); ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/ropen/actions/SaveContentRootOpenableUIAdapter.java ===================================== @@ -30,13 +30,12 @@ import fr.ird.observe.client.datasource.editor.api.content.data.ropen.ContentRoo import fr.ird.observe.client.datasource.editor.api.content.data.ropen.ContentRootOpenableUINavigationNode; import fr.ird.observe.client.datasource.editor.api.navigation.NavigationTree; import fr.ird.observe.client.datasource.editor.api.navigation.NavigationUI; -import fr.ird.observe.client.datasource.editor.api.navigation.NavigationUIHandler; -import fr.ird.observe.client.datasource.editor.api.navigation.tree.NavigationNode; import fr.ird.observe.client.datasource.editor.api.navigation.tree.capability.ReferenceContainerCapability; import fr.ird.observe.client.datasource.editor.api.navigation.tree.root.RootNavigationNode; import fr.ird.observe.dto.data.DataGroupByDto; import fr.ird.observe.dto.data.RootOpenableDto; import fr.ird.observe.dto.reference.DataDtoReference; +import fr.ird.observe.navigation.tree.NavigationResult; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -70,16 +69,13 @@ public class SaveContentRootOpenableUIAdapter<D extends RootOpenableDto, U exten boolean groupByChanged = !Objects.equals(oldGroupByDto.getFilterValue(), newGroupByValue); // We need to inject ot node the new reference (it could does not know the id if not persisted) // As I prefer to use a unique code (for persisted or not, keep it like this) - node = updateReference(dataSourceEditor.getNavigationUI(), node, bean.getId(), oldGroupByDto, groupByChanged ? newGroupByValue : null); + node = updateReference(dataSourceEditor.getNavigationUI(), node, bean.getId(), oldGroupByDto, groupByChanged, newGroupByValue); tree.reSelectSafeNodeThen(node, () -> { dataSourceEditor.getModel().resetFromPreviousUi(ui); if (notPersisted) { tree.expandPath(tree.getSelectionPath()); } - if (!groupByChanged) { - NavigationUIHandler.updateStatistics(dataSourceEditor.getNavigationUI(), 0, 1); - } }); } @@ -87,11 +83,13 @@ public class SaveContentRootOpenableUIAdapter<D extends RootOpenableDto, U exten ContentRootOpenableUINavigationNode node, String id, DataGroupByDto<D> oldGroupByDto, + boolean groupByChanged, String newGroupByValue) { boolean notPersisted = node.getInitializer().isNotPersisted(); - NavigationNode parent = node.getParent(); - boolean groupByChanged = newGroupByValue != null; + ContentRootListUINavigationNode parent = node.getParent(); if (groupByChanged) { + // the navigation must be updated, new parent groupBy value has changed + NavigationResult navigationResult = navigationUI.getTree().getModel().updateNavigationResult(); // groupBy has changed (remove node from parent) RootNavigationNode rootNode = (RootNavigationNode) node.getRoot(); node.removeFromParent(); @@ -99,19 +97,19 @@ public class SaveContentRootOpenableUIAdapter<D extends RootOpenableDto, U exten boolean removeGroupBy = parent.getChildCount() == 0 && !rootNode.getInitializer().getRequest().isLoadEmptyGroupBy(); if (removeGroupBy) { parent.removeFromParent(); - NavigationUIHandler.updateStatistics(navigationUI, -1, 0); } else { // update old parent to root parent.reloadNodeDataToRoot(); } // find parent - parent = rootNode.findChildById(newGroupByValue); + parent = (ContentRootListUINavigationNode) rootNode.findChildById(newGroupByValue); if (parent == null) { // must create it (will update navigation result) - parent = rootNode.getCapability().createMissingNode(newGroupByValue); + DataGroupByDto<?> reference = navigationResult.getGroupBy(newGroupByValue); + parent = rootNode.getCapability().insertChildNode(reference); } else { // update parent reference in node - DataGroupByDto<?> parentReference = ((ContentRootListUINavigationNode) parent).getInitializer().getParentReference(); + DataGroupByDto<?> parentReference = parent.getInitializer().getParentReference(); node.getInitializer().setParentReference(() -> parentReference); } } @@ -129,7 +127,7 @@ public class SaveContentRootOpenableUIAdapter<D extends RootOpenableDto, U exten node.populateChildrenIfNotLoaded(); } - ReferenceContainerCapability<?> capability = (ReferenceContainerCapability<?>) parent.getCapability(); + ReferenceContainerCapability<?> capability = parent.getCapability(); if (groupByChanged) { if (parent.isNotLoaded()) { // will load all children even the updated one ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/NavigationUIHandler.java ===================================== @@ -50,18 +50,6 @@ public class NavigationUIHandler implements UIHandler<NavigationUI>, WithClientU private Set<ReloadAction> actionsToReload; private NavigationUIInitializer initializer; - public static void updateStatistics(NavigationUI ui, int groupByCountDiff, int dataCountDiff) { - NavigationResult navigationResult = ui.getTree().getRootNode().getInitializer().getNavigationResult(); - TreeConfigUIHandler.updateStatistics(navigationResult.getRequest(), - ui.getTree().getModel().getGroupByHelper(), - () -> navigationResult.getGroupByCount() + groupByCountDiff, - () -> navigationResult.getGroupByDataCount() + dataCountDiff, - () -> navigationResult.getDataCount() + dataCountDiff, - ui::setStatisticsText, - ui::setStatisticsTip, - ui.getStatisticsLabel()::setIcon); - } - public static void updateStatistics(NavigationUI ui) { NavigationResult navigationResult = ui.getTree().getRootNode().getInitializer().getNavigationResult(); TreeConfigUIHandler.updateStatistics(navigationResult.getRequest(), ===================================== client/datasource/editor/ps/src/main/java/fr/ird/observe/client/datasource/editor/ps/data/observation/RouteListUI.jaxx ===================================== @@ -28,5 +28,5 @@ <RouteListUIModel id='model' constructorParams='@override:getNavigationSource(this)'/> <RouteListUIModelStates id='states'/> <TripDto id='bean'/> - <JMenuItem id='moveAll' styleClass='editableAndNotModified'/> + <JMenuItem id='moveAll' styleClass='editableAndShowDataAndNotEmpty'/> </fr.ird.observe.client.datasource.editor.api.content.data.list.ContentListUI> ===================================== toolkit/api-services/src/main/java/fr/ird/observe/services/service/data/MoveRequest.java ===================================== @@ -24,6 +24,7 @@ package fr.ird.observe.services.service.data; import fr.ird.observe.dto.BusinessDto; import fr.ird.observe.dto.ToolkitIdDtoBean; +import fr.ird.observe.dto.data.RootOpenableDto; import java.util.Set; import java.util.StringJoiner; @@ -92,6 +93,10 @@ public class MoveRequest { return ids.size() == 1; } + public boolean isNewParentIsRootType() { + return RootOpenableDto.class.isAssignableFrom(getParentTargetDtoType()); + } + @Override public String toString() { return new StringJoiner(", ", MoveRequest.class.getSimpleName() + "[", "]") View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/compare/5898d698338b3b12bb4dea34a... -- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/compare/5898d698338b3b12bb4dea34a... You're receiving this email because of your account on gitlab.com.