Skip to content
This repository was archived by the owner on Jan 19, 2025. It is now read-only.

feat: improved filters in GUI #504

Merged
merged 49 commits into from
May 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
2cfeb01
feat: Removed all previous filters and added new filter "hasName"
Masara May 20, 2022
75f4335
refactor: New names for abstract AbstractPythonFilter.ts functions
Masara May 20, 2022
124f9a0
feat: Added is-filter, not working yet tho
Masara May 20, 2022
973a4ee
feat: Adjustments for filtering
Masara May 20, 2022
cf53023
Merge branch 'main' into 487-api_editor_aditional_filter_commands
lars-reimann May 20, 2022
ef49715
fix: update menu bar again
lars-reimann May 20, 2022
52ba9f6
fix: filter logic (probably not perfect yet)
lars-reimann May 20, 2022
04bffcd
style: apply automatic fixes of linters
lars-reimann May 20, 2022
0c2c967
refactor: move filter logic completely into the filters
lars-reimann May 21, 2022
a7e3ded
style: apply automatic fixes of linters
lars-reimann May 21, 2022
9e009f1
fix: filter logic
lars-reimann May 21, 2022
71af8e0
style: apply automatic fixes of linters
lars-reimann May 21, 2022
acf6eea
fix: remove skip logic (no longer provides better performance)
lars-reimann May 21, 2022
e0fafe5
style: apply automatic fixes of linters
lars-reimann May 21, 2022
7ac3eba
refactor: remove null filter (same as empty ConjunctiveFilter)
lars-reimann May 23, 2022
75751dc
refactor: filter factory
lars-reimann May 23, 2022
f8cf213
fix: popover warning
lars-reimann May 23, 2022
fb86683
feat: negated filters
lars-reimann May 23, 2022
c322fdd
refactor: remove setting "show private declarations"
lars-reimann May 23, 2022
a52be1b
fix: help text for "name" filter
lars-reimann May 23, 2022
6a47fc5
feat: improved help text
lars-reimann May 23, 2022
59f5b97
feat: boldface for filtered elements
lars-reimann May 23, 2022
82e6fe1
Merge branch 'main' into 487-api_editor_aditional_filter_commands
lars-reimann May 23, 2022
af102b9
feat: ignore casing of filters
lars-reimann May 23, 2022
341a6e6
perf: memoization of TreeView
lars-reimann May 23, 2022
3ade1b4
style: apply automatic fixes of linters
lars-reimann May 23, 2022
ec4d07c
feat: filter `annotation:any`
lars-reimann May 23, 2022
155eb6c
fix: incorrect filtering of parameters
lars-reimann May 23, 2022
3b70a66
fix: remove console.log
lars-reimann May 23, 2022
98f0214
style: apply automatic fixes of linters
lars-reimann May 23, 2022
fbbdd5a
feat: update help text
lars-reimann May 23, 2022
e41b286
style: use === instead of ==
lars-reimann May 24, 2022
ae5dbbe
feat: filters for specific annotations
lars-reimann May 24, 2022
ceb53b2
style: apply automatic fixes of linters
lars-reimann May 24, 2022
20289c8
docs: add code documentation for filters
lars-reimann May 24, 2022
82583a3
fix: filter text
lars-reimann May 24, 2022
8abc2ea
style: apply automatic fixes of linters
lars-reimann May 24, 2022
58b4438
Merge branch 'main' into 487-api_editor_aditional_filter_commands
lars-reimann May 24, 2022
2d81267
feat: minor GUI improvements
lars-reimann May 25, 2022
4ee8068
style: apply automatic fixes of linters
lars-reimann May 25, 2022
5481ae9
refactor: remove commented out code
lars-reimann May 25, 2022
82f33b7
feat: compute which modules are public
lars-reimann May 25, 2022
92fe9b3
feat: emphasize important parts in help text
lars-reimann May 25, 2022
a0dc4ee
fix: inability to add annotation to parameters of functions if they w…
lars-reimann May 25, 2022
7581a85
style: apply automatic fixes of linters
lars-reimann May 25, 2022
f58efab
test: applyToPackage
lars-reimann May 25, 2022
1720407
test: createFilterFromString
lars-reimann May 25, 2022
8b28653
style: apply automatic fixes of linters
lars-reimann May 25, 2022
27fc09f
Merge branch 'main' into 487-api_editor_aditional_filter_commands
lars-reimann May 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions api-editor/gui/src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import GroupForm from '../features/annotations/forms/GroupForm';
import MoveForm from '../features/annotations/forms/MoveForm';
import OptionalForm from '../features/annotations/forms/OptionalForm';
import RenameForm from '../features/annotations/forms/RenameForm';
import { PythonFilter } from '../features/packageData/model/PythonFilter';
import PythonPackage from '../features/packageData/model/PythonPackage';
import { parsePythonPackageJson, PythonPackageJson } from '../features/packageData/model/PythonPackageBuilder';
import PackageDataImportDialog from '../features/packageData/PackageDataImportDialog';
Expand All @@ -48,6 +47,7 @@ import AttributeForm from '../features/annotations/forms/AttributeForm';
import { UsageCountJson, UsageCountStore } from '../features/usages/model/UsageCountStore';
import { selectShowUsageImportDialog } from '../features/usages/usageSlice';
import UsageImportDialog from '../features/usages/UsageImportDialog';
import { createFilterFromString } from '../features/packageData/model/filters/filterFactory';

const App: React.FC = function () {
const dispatch = useAppDispatch();
Expand Down Expand Up @@ -92,9 +92,9 @@ const App: React.FC = function () {
// eslint-disable-next-line
}, []);

const [filter, setFilter] = useState('');
const pythonFilter = PythonFilter.fromFilterBoxInput(filter);
const filteredPythonPackage = pythonPackage.filter(pythonFilter);
const [filter, setFilter] = useState('is:public');
const pythonFilter = createFilterFromString(filter);
const filteredPythonPackage = pythonFilter.applyToPackage(pythonPackage, useAppSelector(selectAnnotations));

const userActionTarget = pythonPackage.getByRelativePathAsString(currentUserAction.target);

Expand Down Expand Up @@ -160,7 +160,9 @@ const App: React.FC = function () {
/>
)}
{currentUserAction.type === 'move' && <MoveForm target={userActionTarget || pythonPackage} />}
{currentUserAction.type === 'none' && <TreeView pythonPackage={filteredPythonPackage} />}
{currentUserAction.type === 'none' && (
<TreeView pythonPackage={filteredPythonPackage} filter={pythonFilter} />
)}
{currentUserAction.type === 'optional' && (
<OptionalForm target={userActionTarget || pythonPackage} />
)}
Expand Down
220 changes: 92 additions & 128 deletions api-editor/gui/src/common/MenuBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import {
Icon,
IconButton,
Input,
InputGroup,
InputRightElement,
ListItem,
Menu,
MenuButton,
Expand All @@ -38,17 +36,12 @@ import {
VStack,
} from '@chakra-ui/react';
import React, { useRef, useState } from 'react';
import { FaCheck, FaChevronDown } from 'react-icons/fa';
import { FaChevronDown } from 'react-icons/fa';
import { useAppDispatch, useAppSelector } from '../app/hooks';
import { resetAnnotations, toggleAnnotationImportDialog } from '../features/annotations/annotationSlice';
import AnnotatedPythonPackageBuilder from '../features/annotatedPackageData/model/AnnotatedPythonPackageBuilder';
import { PythonFilter } from '../features/packageData/model/PythonFilter';
import PythonPackage from '../features/packageData/model/PythonPackage';
import {
selectShowPrivateDeclarations,
togglePackageDataImportDialog,
toggleShowPrivateDeclarations,
} from '../features/packageData/packageDataSlice';
import { togglePackageDataImportDialog } from '../features/packageData/packageDataSlice';
import { Setter } from './util/types';
import { toggleUsageImportDialog } from '../features/usages/usageSlice';

Expand All @@ -60,79 +53,78 @@ interface MenuBarProps {
}

const HelpButton = function () {
const dispatch = useAppDispatch();
const [isOpen, setIsOpen] = useState(false);
const cancelRef = useRef(null);

// Event handlers ----------------------------------------------------------

const handleConfirm = () => {
dispatch(resetAnnotations());
setIsOpen(false);
};
const handleCancel = () => setIsOpen(false);

// Render ------------------------------------------------------------------

return (
<Popover>
<PopoverTrigger>
<IconButton
variant="ghost"
icon={<Icon name="help" />}
aria-label="help"
onClick={() => setIsOpen(true)}
/>
</PopoverTrigger>
<PopoverContent minWidth={462} fontSize="sm">
<PopoverArrow />
<PopoverCloseButton />
<PopoverHeader>Filter Options</PopoverHeader>
<PopoverBody>
<UnorderedList spacing={2}>
<ListItem>
<ChakraText>
<strong>is:xy</strong>
</ChakraText>
<ChakraText>
Displays only elements that are of the given type xy. Possible types are: module, class,
function, parameter.
</ChakraText>
</ListItem>
<ListItem>
<ChakraText>
<strong>hasName:xy</strong>
</ChakraText>
<ChakraText>Displays only elements with names that contain the given string xy.</ChakraText>
</ListItem>
<ListItem>
<ChakraText>
<strong>is:annotated</strong>
</ChakraText>
<ChakraText>Displays only elements that have been annotated.</ChakraText>
</ListItem>
<ListItem>
<ChakraText>
<strong>hasAnnotation:xy</strong>
</ChakraText>
<ChakraText>
Displays only elements that are annotated with the given type xy. Possible types:
unused, constant, required, optional, enum and boundary.
</ChakraText>
</ListItem>
<ListItem>
<ChakraText>
<strong>!filter</strong>
</ChakraText>
<ChakraText>
Displays only elements that do not match the given filter. Possible filters are any in
this list.
</ChakraText>
</ListItem>
</UnorderedList>
</PopoverBody>
</PopoverContent>
</Popover>
<Box>
<Popover>
<PopoverTrigger>
<IconButton variant="ghost" icon={<Icon name="help" />} aria-label="help" />
</PopoverTrigger>
<PopoverContent minWidth={462} fontSize="sm" marginRight={2}>
<PopoverArrow />
<PopoverCloseButton />
<PopoverHeader>Filter Options</PopoverHeader>
<PopoverBody>
<UnorderedList spacing={2}>
<ListItem>
<ChakraText>
<strong>is:[type]</strong>
</ChakraText>
<ChakraText>
Displays only elements that are of the given type. Replace [type] with one of{' '}
<em>module, class, function, parameter</em>.
</ChakraText>
</ListItem>
<ListItem>
<ChakraText>
<strong>is:[visibility]</strong>
</ChakraText>
<ChakraText>
Displays only elements that have the given visibility. Replace [visibility] with one
of <em>public, internal</em>.
</ChakraText>
</ListItem>
<ListItem>
<ChakraText>
<strong>name:xy</strong>
</ChakraText>
<ChakraText>
Displays only elements with names that contain the given string xy.
</ChakraText>
</ListItem>
<ListItem>
<ChakraText>
<strong>annotation:any</strong>
</ChakraText>
<ChakraText>Displays only elements that have been annotated.</ChakraText>
</ListItem>
<ListItem>
<ChakraText>
<strong>annotation:[type]</strong>
</ChakraText>
<ChakraText>
Displays only elements that are annotated with the given type xy. Replace [type]
with one of{' '}
<em>
@attribute, @boundary, @calledAfter, @constant, @enum, @group, @move, @optional,
@pure, @renaming, @required, @unused
</em>
.
</ChakraText>
</ListItem>
<ListItem>
<ChakraText>
<strong>!filter</strong>
</ChakraText>
<ChakraText>
Displays only elements that do not match the given filter. Possible filters are any
in this list.
</ChakraText>
</ListItem>
</UnorderedList>
</PopoverBody>
</PopoverContent>
</Popover>
</Box>
);
};

Expand Down Expand Up @@ -189,7 +181,6 @@ const DeleteAllAnnotations = function () {

const MenuBar: React.FC<MenuBarProps> = function ({ pythonPackage, filter, setFilter, displayInferErrors }) {
const { colorMode, toggleColorMode } = useColorMode();
const initialFocusRef = useRef(null);
const dispatch = useAppDispatch();

const annotationStore = useAppSelector((state) => state.annotations);
Expand Down Expand Up @@ -228,10 +219,7 @@ const MenuBar: React.FC<MenuBarProps> = function ({ pythonPackage, filter, setFi
};

const settings: string[] = [];
if (useAppSelector(selectShowPrivateDeclarations)) {
settings.push('showPrivateDeclarations');
}
if (colorMode == 'dark') {
if (colorMode === 'dark') {
settings.push('darkMode');
}

Expand All @@ -246,15 +234,21 @@ const MenuBar: React.FC<MenuBarProps> = function ({ pythonPackage, filter, setFi
</MenuButton>
<MenuList>
<MenuGroup title="Import">
<MenuItem onClick={() => dispatch(togglePackageDataImportDialog())}>API Data</MenuItem>
<MenuItem onClick={() => dispatch(toggleUsageImportDialog())}>Usages</MenuItem>
<MenuItem onClick={() => dispatch(toggleAnnotationImportDialog())}>
<MenuItem paddingLeft={8} onClick={() => dispatch(togglePackageDataImportDialog())}>
API Data
</MenuItem>
<MenuItem paddingLeft={8} onClick={() => dispatch(toggleUsageImportDialog())}>
Usages
</MenuItem>
<MenuItem paddingLeft={8} onClick={() => dispatch(toggleAnnotationImportDialog())}>
Annotations
</MenuItem>
</MenuGroup>
<MenuDivider />
<MenuGroup title="Export">
<MenuItem onClick={exportAnnotations}>Annotations</MenuItem>
<MenuItem paddingLeft={8} onClick={exportAnnotations}>
Annotations
</MenuItem>
</MenuGroup>
</MenuList>
</Menu>
Expand All @@ -270,13 +264,6 @@ const MenuBar: React.FC<MenuBarProps> = function ({ pythonPackage, filter, setFi
</MenuButton>
<MenuList>
<MenuOptionGroup type="checkbox" value={settings}>
<MenuItemOption
value="showPrivateDeclarations"
onClick={() => dispatch(toggleShowPrivateDeclarations())}
>
Show private declarations
</MenuItemOption>

<MenuItemOption value={'darkMode'} onClick={toggleColorMode}>
Dark mode
</MenuItemOption>
Expand All @@ -289,37 +276,14 @@ const MenuBar: React.FC<MenuBarProps> = function ({ pythonPackage, filter, setFi
<Spacer />

<HStack>
<Box>
<Popover isOpen={!PythonFilter.fromFilterBoxInput(filter)} initialFocusRef={initialFocusRef}>
<PopoverTrigger>
<InputGroup ref={initialFocusRef}>
<Input
type="text"
placeholder="Filter..."
value={filter}
onChange={(event) => setFilter(event.target.value)}
isInvalid={!PythonFilter.fromFilterBoxInput(filter)}
borderColor={
PythonFilter.fromFilterBoxInput(filter)?.isFilteringModules()
? 'green'
: 'inherit'
}
spellCheck={false}
minWidth="400px"
/>
{PythonFilter.fromFilterBoxInput(filter)?.isFilteringModules() && (
<InputRightElement>
<Icon as={FaCheck} color="green.500" />
</InputRightElement>
)}
</InputGroup>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverBody>Each scope must only be used once.</PopoverBody>
</PopoverContent>
</Popover>
</Box>
<Input
type="text"
placeholder="Filter..."
value={filter}
onChange={(event) => setFilter(event.target.value)}
spellCheck={false}
minWidth="400px"
/>
<HelpButton />
</HStack>
</Flex>
Expand Down
Loading