diff --git a/api-editor/gui/src/features/actionBar/ActionBar.tsx b/api-editor/gui/src/features/actionBar/ActionBar.tsx index 7c9c60652..5f4b0082e 100644 --- a/api-editor/gui/src/features/actionBar/ActionBar.tsx +++ b/api-editor/gui/src/features/actionBar/ActionBar.tsx @@ -149,64 +149,73 @@ export const ActionBar: React.FC = function ({ declaration }) { ); }; -const getNextElementPath = function ( +const getPreviousElementPath = function ( declarations: PythonDeclaration[], start: PythonDeclaration, filter: AbstractPythonFilter, annotations: AnnotationStore, usages: UsageCountStore, ): string { - let current = getNextElementInTree(declarations, start); - while (current !== start) { + let currentIndex = getPreviousIndex(declarations, getIndex(declarations, start)); + let current = getElementAtIndex(declarations, currentIndex); + while (current !== null && current !== start) { if (filter.shouldKeepDeclaration(current, annotations, usages)) { return current.id; } - current = getNextElementInTree(declarations, current); + currentIndex = getPreviousIndex(declarations, currentIndex); + current = getElementAtIndex(declarations, currentIndex); } return start.id; }; -const getNextElementInTree = function ( - declarations: PythonDeclaration[], - current: PythonDeclaration, -): PythonDeclaration { - if (declarations.length === 0) { - return current; - } - - const index = declarations.findIndex((it) => it.id === current.id); - const nextIndex = (index + 1) % declarations.length; - return declarations[nextIndex]; -}; - -const getPreviousElementPath = function ( +const getNextElementPath = function ( declarations: PythonDeclaration[], start: PythonDeclaration, filter: AbstractPythonFilter, annotations: AnnotationStore, usages: UsageCountStore, -): string | null { - let current = getPreviousElementInTree(declarations, start); - while (current !== start && current !== null) { +): string { + let currentIndex = getNextIndex(declarations, getIndex(declarations, start)); + let current = getElementAtIndex(declarations, currentIndex); + while (current !== null && current !== start) { if (filter.shouldKeepDeclaration(current, annotations, usages)) { return current.id; } - current = getPreviousElementInTree(declarations, current); + currentIndex = getNextIndex(declarations, currentIndex); + current = getElementAtIndex(declarations, currentIndex); } - return null; + return start.id; }; -const getPreviousElementInTree = function ( - declarations: PythonDeclaration[], - current: PythonDeclaration, -): PythonDeclaration { - if (declarations.length === 0) { - return current; +const getPreviousIndex = function (declarations: PythonDeclaration[], currentIndex: number | null): number | null { + if (currentIndex === null || currentIndex < 0 || currentIndex >= declarations.length) { + return null; + } + + return (currentIndex - 1 + declarations.length) % declarations.length; +}; + +const getNextIndex = function (declarations: PythonDeclaration[], currentIndex: number | null): number | null { + if (currentIndex === null || currentIndex < 0 || currentIndex >= declarations.length) { + return null; } + return (currentIndex + 1) % declarations.length; +}; + +const getIndex = function (declarations: PythonDeclaration[], current: PythonDeclaration): number | null { const index = declarations.findIndex((it) => it.id === current.id); - const previousIndex = (index - 1 + declarations.length) % declarations.length; - return declarations[previousIndex]; + if (index === -1) { + return null; + } + return index; +}; + +const getElementAtIndex = function (declarations: PythonDeclaration[], index: number | null): PythonDeclaration | null { + if (index === null) { + return null; + } + return declarations[index]; }; const getAncestors = function (navStr: string, filteredPythonPackage: PythonPackage): string[] { diff --git a/api-editor/gui/src/features/packageData/apiSlice.ts b/api-editor/gui/src/features/packageData/apiSlice.ts index 51a40d727..bae6c034e 100644 --- a/api-editor/gui/src/features/packageData/apiSlice.ts +++ b/api-editor/gui/src/features/packageData/apiSlice.ts @@ -64,6 +64,17 @@ export const apiReducer = reducer; const selectAPI = (state: RootState) => state.api; export const selectRawPythonPackage = (state: RootState) => selectAPI(state).pythonPackage; +export const selectFlatSortedDeclarationList = createSelector( + [selectRawPythonPackage, selectSortingMode, selectUsages], + (pythonPackage, sortingMode, usages) => { + switch (sortingMode) { + case SortingMode.Alphabetical: + return walkChildrenInPreorder(pythonPackage, sortAlphabetically); + case SortingMode.Usages: // Descending + return walkChildrenInPreorder(pythonPackage, sortByUsages(usages)); + } + }, +); export const selectFilteredPythonPackage = createSelector( [selectRawPythonPackage, selectAnnotationStore, selectUsages, selectFilter], (pythonPackage, annotations, usages, filter) => { @@ -88,7 +99,7 @@ export const selectMatchedNodes = createSelector( export const selectNumberOfMatchedNodes = createSelector([selectMatchedNodes], (matchedNodes) => { return matchedNodes.length; }); -export const selectFlatSortedDeclarationList = createSelector( +export const selectFlatFilteredAndSortedDeclarationList = createSelector( [selectFilteredPythonPackage, selectSortingMode, selectUsages], (pythonPackage, sortingMode, usages) => { switch (sortingMode) { diff --git a/api-editor/gui/src/features/packageData/treeView/TreeView.tsx b/api-editor/gui/src/features/packageData/treeView/TreeView.tsx index e241e0473..ec23c31d0 100644 --- a/api-editor/gui/src/features/packageData/treeView/TreeView.tsx +++ b/api-editor/gui/src/features/packageData/treeView/TreeView.tsx @@ -19,7 +19,7 @@ import { FunctionNode } from './FunctionNode'; import { ModuleNode } from './ModuleNode'; import { ParameterNode } from './ParameterNode'; import { AutoSizer } from '../../../common/AutoSizer'; -import { selectFlatSortedDeclarationList } from '../apiSlice'; +import { selectFlatFilteredAndSortedDeclarationList } from '../apiSlice'; import { selectUsages } from '../../usages/usageSlice'; interface ScrollOffset { @@ -36,7 +36,7 @@ export const TreeView: React.FC = memo(() => { const filter = useAppSelector(selectFilter); const usages = useAppSelector(selectUsages); const allExpanded = useAppSelector(selectAllExpandedInTreeView); - const flatSortedList = useAppSelector(selectFlatSortedDeclarationList); + const flatSortedList = useAppSelector(selectFlatFilteredAndSortedDeclarationList); const children = getNodes(allExpanded, flatSortedList); const previousScrollOffset = useAppSelector(selectTreeViewScrollOffset);