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

Commit fc2c9ca

Browse files
authored
feat(gui): improve display of usages in selection view (#957)
* feat(gui): make paragraph headings bold * refactor(gui): extract code that counts how often the default value of a parameter is used implicitly * refactor(gui): rename variable to be more consistent with remaining code * feat(gui): add functions that returns whether parameter is optional/required * fix(gui): refine cases where the default value is shown * feat(gui): differentiate usages of parameters * style: apply automatic fixes of linters * feat(gui): show usage counts for other declarations in selection view * style: apply automatic fixes of linters * feat(gui): for function show parameter usages above parameters Co-authored-by: lars-reimann <[email protected]>
1 parent 4d02e27 commit fc2c9ca

File tree

7 files changed

+122
-38
lines changed

7 files changed

+122
-38
lines changed

api-editor/gui/src/features/packageData/model/PythonParameter.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ export class PythonParameter extends PythonDeclaration {
7171
);
7272
}
7373

74+
isOptional(): boolean {
75+
return this.defaultValue !== null && this.defaultValue !== undefined && this.isExplicitParameter();
76+
}
77+
78+
isRequired(): boolean {
79+
return (this.defaultValue === null || this.defaultValue === undefined) && this.isExplicitParameter();
80+
}
81+
7482
toString(): string {
7583
return `Parameter "${this.name}"`;
7684
}

api-editor/gui/src/features/packageData/selectionView/ClassView.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { SectionListViewItem } from './SectionListViewItem';
88
import { CompleteButton } from '../../annotations/CompleteButton';
99
import { MissingAnnotationButton } from '../../annotations/MissingAnnotationButton';
1010
import { DataCopyButtons } from '../../annotations/DataCopyButtons';
11+
import { NonParameterUsageCounts } from './UsageCounts';
1112

1213
interface ClassViewProps {
1314
pythonClass: PythonClass;
@@ -45,6 +46,7 @@ export const ClassView: React.FC<ClassViewProps> = function ({ pythonClass }) {
4546
</Stack>
4647
<SectionListViewItem title="Superclasses" inputElements={pythonClass.superclasses} />
4748
<SectionListViewItem title="Decorators" inputElements={pythonClass.decorators} />
49+
<NonParameterUsageCounts declaration={pythonClass} />
4850
</Stack>
4951
);
5052
};

api-editor/gui/src/features/packageData/selectionView/FunctionView.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { selectFilter, selectSorter } from '../../ui/uiSlice';
1515
import { selectUsages } from '../../usages/usageSlice';
1616
import { MissingAnnotationButton } from '../../annotations/MissingAnnotationButton';
1717
import { DataCopyButtons } from '../../annotations/DataCopyButtons';
18+
import { NonParameterUsageCounts } from './UsageCounts';
1819

1920
interface FunctionViewProps {
2021
pythonFunction: PythonFunction;
@@ -68,6 +69,8 @@ export const FunctionView: React.FC<FunctionViewProps> = function ({ pythonFunct
6869
</Box>
6970
</Stack>
7071

72+
<NonParameterUsageCounts declaration={pythonFunction} />
73+
7174
<Stack spacing={4}>
7275
<Heading as="h4" size="md">
7376
Sorted & Filtered Parameters

api-editor/gui/src/features/packageData/selectionView/ModuleView.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { PythonModule } from '../model/PythonModule';
1010
import { CodeComponent } from 'react-markdown/lib/ast-to-react';
1111
import { CompleteButton } from '../../annotations/CompleteButton';
1212
import { DataCopyButtons } from '../../annotations/DataCopyButtons';
13+
import { NonParameterUsageCounts } from './UsageCounts';
1314

1415
// See https://github.com/remarkjs/react-markdown#use-custom-components-syntax-highlight
1516
const CustomCode: CodeComponent = function ({
@@ -101,6 +102,8 @@ export const ModuleView: React.FC<ModuleViewProps> = function ({ pythonModule })
101102
</Text>
102103
)}
103104
</Stack>
105+
106+
<NonParameterUsageCounts declaration={pythonModule} />
104107
</Stack>
105108
);
106109
};

api-editor/gui/src/features/packageData/selectionView/ParameterView.tsx

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
import { Bar } from 'react-chartjs-2';
1616
import { useAppSelector } from '../../../app/hooks';
1717
import { selectUsages } from '../../usages/usageSlice';
18+
import { ParameterUsageCounts } from './UsageCounts';
1819

1920
ChartJS.register(CategoryScale, PointElement, LineElement, LinearScale, BarElement, Title, Tooltip);
2021

@@ -24,7 +25,7 @@ interface ParameterViewProps {
2425

2526
export const ParameterView: React.FC<ParameterViewProps> = function ({ pythonParameter }) {
2627
const usages = useAppSelector(selectUsages);
27-
const parameterUsages = usages.valueUsages.get(pythonParameter.id);
28+
const nValueUsages = usages.getValueCountsOrNull(pythonParameter);
2829

2930
return (
3031
<Stack spacing={8}>
@@ -39,24 +40,34 @@ export const ParameterView: React.FC<ParameterViewProps> = function ({ pythonPar
3940
</Stack>
4041
)}
4142

42-
{pythonParameter && (
43+
{pythonParameter && pythonParameter.isExplicitParameter() && (
4344
<Stack spacing={4}>
4445
<Heading as="h4" size="md">
4546
Default Value
4647
</Heading>
4748

48-
{pythonParameter.defaultValue ? (
49+
{pythonParameter.isOptional() ? (
4950
<Stack>
50-
<ChakraText paddingLeft={4}>Code: {pythonParameter.defaultValue}</ChakraText>
51+
<ChakraText paddingLeft={4}>
52+
<Box as="span" fontWeight="bold">
53+
Code:
54+
</Box>{' '}
55+
{pythonParameter.defaultValue}
56+
</ChakraText>
5157

5258
{pythonParameter.defaultValueInDocs ? (
5359
<ChakraText paddingLeft={4}>
54-
Documentation: {pythonParameter.defaultValueInDocs}
60+
<Box as="span" fontWeight="bold">
61+
Documentation:
62+
</Box>{' '}
63+
{pythonParameter.defaultValueInDocs}
5564
</ChakraText>
5665
) : (
5766
<HStack>
5867
<ChakraText paddingLeft={4}>
59-
Documentation:{' '}
68+
<Box as="span" fontWeight="bold">
69+
Documentation:
70+
</Box>{' '}
6071
<Box as="span" color="gray.500">
6172
The documentation does not specify a default value.
6273
</Box>
@@ -72,22 +83,15 @@ export const ParameterView: React.FC<ParameterViewProps> = function ({ pythonPar
7283
</Stack>
7384
)}
7485

75-
{parameterUsages && (
76-
<Stack spacing={4}>
77-
<Heading as="h4" size="md">
78-
Usages
79-
</Heading>
80-
<UsageSum parameterUsages={parameterUsages} />
81-
</Stack>
82-
)}
86+
{nValueUsages && <ParameterUsageCounts parameter={pythonParameter} />}
8387

84-
{parameterUsages && (
88+
{nValueUsages && (
8589
<Stack spacing={4}>
8690
<Heading as="h4" size="md">
8791
Most Common Values
8892
</Heading>
8993
<Box w="30vw" maxWidth="640px">
90-
<CustomBarChart parameterUsages={parameterUsages} />
94+
<CustomBarChart parameterUsages={nValueUsages} />
9195
</Box>
9296
</Stack>
9397
)}
@@ -178,13 +182,3 @@ const isStringifiedLiteral = function (value: string): boolean {
178182
}
179183
return !Number.isNaN(Number.parseFloat(value));
180184
};
181-
182-
const UsageSum: React.FC<CustomBarChartProps> = function ({ parameterUsages }) {
183-
let usage = 0;
184-
185-
parameterUsages.forEach((value) => {
186-
usage += value;
187-
});
188-
189-
return <ChakraText paddingLeft={4}>{usage}</ChakraText>;
190-
};
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { Box, Heading, Stack, Text as ChakraText } from '@chakra-ui/react';
2+
import React from 'react';
3+
import { PythonParameter } from '../model/PythonParameter';
4+
import { useAppSelector } from '../../../app/hooks';
5+
import { selectUsages } from '../../usages/usageSlice';
6+
import { PythonModule } from '../model/PythonModule';
7+
import { PythonClass } from '../model/PythonClass';
8+
import { PythonFunction } from '../model/PythonFunction';
9+
10+
interface NonParameterUsageCountsProps {
11+
declaration: PythonModule | PythonClass | PythonFunction;
12+
}
13+
14+
export const NonParameterUsageCounts: React.FC<NonParameterUsageCountsProps> = function ({ declaration }) {
15+
const usageStore = useAppSelector(selectUsages);
16+
const nUsages = usageStore.getUsageCount(declaration);
17+
18+
return (
19+
<Stack spacing={4}>
20+
<Heading as="h4" size="md">
21+
Usages
22+
</Heading>
23+
24+
<Stack>
25+
<ChakraText paddingLeft={4}>{nUsages}</ChakraText>
26+
</Stack>
27+
</Stack>
28+
);
29+
};
30+
31+
interface ParameterUsageCountsProps {
32+
parameter: PythonParameter;
33+
}
34+
35+
export const ParameterUsageCounts: React.FC<ParameterUsageCountsProps> = function ({ parameter }) {
36+
const usageStore = useAppSelector(selectUsages);
37+
38+
const nExplicitUsages = usageStore.getUsageCount(parameter);
39+
const nImplicitUsages = usageStore.getNumberOfImplicitUsagesOfDefaultValue(parameter);
40+
41+
return (
42+
<Stack spacing={4}>
43+
<Heading as="h4" size="md">
44+
Usages
45+
</Heading>
46+
47+
<Stack>
48+
<ChakraText paddingLeft={4}>
49+
<Box as="span" fontWeight="bold">
50+
Total:
51+
</Box>{' '}
52+
{nExplicitUsages + nImplicitUsages}
53+
</ChakraText>
54+
{parameter.isOptional() && (
55+
<ChakraText paddingLeft={4}>
56+
<Box as="span" fontWeight="bold">
57+
Explicit:
58+
</Box>{' '}
59+
{nExplicitUsages}
60+
</ChakraText>
61+
)}
62+
{parameter.isOptional() && (
63+
<ChakraText paddingLeft={4}>
64+
<Box as="span" fontWeight="bold">
65+
Implicit usages of default value:
66+
</Box>{' '}
67+
{nImplicitUsages}
68+
</ChakraText>
69+
)}
70+
</Stack>
71+
</Stack>
72+
);
73+
};

api-editor/gui/src/features/usages/model/UsageCountStore.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,18 @@ export class UsageCountStore {
109109
return this.valueUsages.get(parameter.id) ?? null;
110110
}
111111

112+
getNumberOfImplicitUsagesOfDefaultValue(parameter: PythonParameter): number {
113+
const containingFunction = parameter.containingFunction;
114+
if (!containingFunction) {
115+
return 0;
116+
}
117+
118+
const parameterUsageCount = this.getUsageCount(parameter);
119+
const functionUsageCount = this.getUsageCount(containingFunction);
120+
121+
return functionUsageCount - parameterUsageCount;
122+
}
123+
112124
toJson(): UsageCountJson {
113125
return {
114126
schemaVersion: EXPECTED_USAGES_SCHEMA_VERSION,
@@ -136,18 +148,7 @@ export class UsageCountStore {
136148
continue;
137149
}
138150

139-
const containingFunction = parameter.containingFunction;
140-
if (!containingFunction) {
141-
continue;
142-
}
143-
144-
const parameterUsageCount = this.getUsageCount(parameter);
145-
const functionUsageCount = this.getUsageCount(containingFunction);
146-
const nImplicitUsages = functionUsageCount - parameterUsageCount;
147-
if (nImplicitUsages === 0) {
148-
continue;
149-
}
150-
151+
const nImplicitUsages = this.getNumberOfImplicitUsagesOfDefaultValue(parameter);
151152
const nExplicitUsages = this.valueUsages.get(parameter.id)?.get(defaultValue) ?? 0;
152153

153154
if (!this.valueUsages.has(parameter.id)) {

0 commit comments

Comments
 (0)