11import {
2+ VSCodeCheckbox ,
23 VSCodeDataGridCell ,
34 VSCodeDataGridRow ,
4- VSCodeDropdown ,
5- VSCodeOption ,
5+ VSCodeLink ,
66} from "@vscode/webview-ui-toolkit/react" ;
77import * as React from "react" ;
8- import { useCallback , useMemo } from "react" ;
8+ import { ChangeEvent , useCallback , useMemo } from "react" ;
99import styled from "styled-components" ;
1010import { vscode } from "../vscode-api" ;
1111
@@ -18,52 +18,27 @@ import {
1818import { KindInput } from "./KindInput" ;
1919import { extensiblePredicateDefinitions } from "../../data-extensions-editor/predicates" ;
2020import { Mode } from "../../data-extensions-editor/shared/mode" ;
21+ import { Dropdown } from "../common/Dropdown" ;
2122
22- const Dropdown = styled ( VSCodeDropdown ) `
23- width: 100%;
24- ` ;
25-
26- type SupportedUnsupportedSpanProps = {
27- supported : boolean ;
28- modeled : ModeledMethod | undefined ;
29- } ;
30-
31- const SupportSpan = styled . span < SupportedUnsupportedSpanProps > `
32- color: ${ ( props ) => {
33- if ( ! props . supported && props . modeled && props . modeled ?. type !== "none" ) {
34- return "orange" ;
35- } else {
36- return props . supported ? "green" : "red" ;
37- }
38- } } ;
39- ` ;
40-
41- type SupportedUnsupportedLinkProps = {
42- supported : boolean ;
43- modeled : ModeledMethod | undefined ;
44- } ;
45-
46- const SupportLink = styled . button < SupportedUnsupportedLinkProps > `
47- color: ${ ( props ) => {
48- if ( ! props . supported && props . modeled && props . modeled ?. type !== "none" ) {
49- return "orange" ;
50- } else {
51- return props . supported ? "green" : "red" ;
52- }
53- } } ;
54- background-color: transparent;
55- border: none;
56- cursor: pointer;
57- padding: 0;
23+ const ApiOrMethodCell = styled ( VSCodeDataGridCell ) `
24+ display: flex;
25+ flex-direction: row;
26+ align-items: center;
27+ gap: 0.5em;
5828` ;
5929
6030const UsagesButton = styled . button `
6131 color: var(--vscode-editor-foreground);
62- background-color: transparent ;
32+ background-color: var(--vscode-input-background) ;
6333 border: none;
34+ border-radius: 40%;
6435 cursor: pointer;
6536` ;
6637
38+ const ViewLink = styled ( VSCodeLink ) `
39+ white-space: nowrap;
40+ ` ;
41+
6742type Props = {
6843 externalApiUsage : ExternalApiUsage ;
6944 modeledMethod : ModeledMethod | undefined ;
@@ -90,9 +65,7 @@ export const MethodRow = ({
9065 } , [ externalApiUsage . methodParameters ] ) ;
9166
9267 const handleTypeInput = useCallback (
93- ( e : InputEvent ) => {
94- const target = e . target as HTMLSelectElement ;
95-
68+ ( e : ChangeEvent < HTMLSelectElement > ) => {
9669 let newProvenance : Provenance = "manual" ;
9770 if ( modeledMethod ?. provenance === "df-generated" ) {
9871 newProvenance = "df-manual" ;
@@ -106,14 +79,14 @@ export const MethodRow = ({
10679 output : "ReturnType" ,
10780 kind : "value" ,
10881 ...modeledMethod ,
109- type : target . value as ModeledMethodType ,
82+ type : e . target . value as ModeledMethodType ,
11083 provenance : newProvenance ,
11184 } ) ;
11285 } ,
11386 [ onChange , externalApiUsage , modeledMethod , argumentsList ] ,
11487 ) ;
11588 const handleInputInput = useCallback (
116- ( e : InputEvent ) => {
89+ ( e : ChangeEvent < HTMLSelectElement > ) => {
11790 if ( ! modeledMethod ) {
11891 return ;
11992 }
@@ -128,7 +101,7 @@ export const MethodRow = ({
128101 [ onChange , externalApiUsage , modeledMethod ] ,
129102 ) ;
130103 const handleOutputInput = useCallback (
131- ( e : InputEvent ) => {
104+ ( e : ChangeEvent < HTMLSelectElement > ) => {
132105 if ( ! modeledMethod ) {
133106 return ;
134107 }
@@ -169,94 +142,96 @@ export const MethodRow = ({
169142 ? extensiblePredicateDefinitions [ modeledMethod . type ]
170143 : undefined ;
171144
145+ const showModelTypeCell =
146+ ! externalApiUsage . supported ||
147+ ( modeledMethod && modeledMethod ?. type !== "none" ) ;
148+ const modelTypeOptions = useMemo (
149+ ( ) => [
150+ { value : "none" , label : "Unmodeled" } ,
151+ { value : "source" , label : "Source" } ,
152+ { value : "sink" , label : "Sink" } ,
153+ { value : "summary" , label : "Flow summary" } ,
154+ { value : "neutral" , label : "Neutral" } ,
155+ ] ,
156+ [ ] ,
157+ ) ;
158+
159+ const showInputCell =
160+ modeledMethod ?. type && [ "sink" , "summary" ] . includes ( modeledMethod ?. type ) ;
161+ const inputOptions = useMemo (
162+ ( ) => [
163+ { value : "Argument[this]" , label : "Argument[this]" } ,
164+ ...argumentsList . map ( ( argument , index ) => ( {
165+ value : `Argument[${ index } ]` ,
166+ label : `Argument[${ index } ]: ${ argument } ` ,
167+ } ) ) ,
168+ ] ,
169+ [ argumentsList ] ,
170+ ) ;
171+
172+ const showOutputCell =
173+ modeledMethod ?. type && [ "source" , "summary" ] . includes ( modeledMethod ?. type ) ;
174+ const outputOptions = useMemo (
175+ ( ) => [
176+ { value : "ReturnValue" , label : "ReturnValue" } ,
177+ { value : "Argument[this]" , label : "Argument[this]" } ,
178+ ...argumentsList . map ( ( argument , index ) => ( {
179+ value : `Argument[${ index } ]` ,
180+ label : `Argument[${ index } ]: ${ argument } ` ,
181+ } ) ) ,
182+ ] ,
183+ [ argumentsList ] ,
184+ ) ;
185+
186+ const showKindCell = predicate ?. supportedKinds ;
187+
172188 return (
173189 < VSCodeDataGridRow >
174- < VSCodeDataGridCell gridColumn = { 1 } >
175- < SupportSpan
176- supported = { externalApiUsage . supported }
177- modeled = { modeledMethod }
178- >
179- { externalApiUsage . packageName } .{ externalApiUsage . typeName }
180- </ SupportSpan >
181- </ VSCodeDataGridCell >
182- < VSCodeDataGridCell gridColumn = { 2 } >
190+ < ApiOrMethodCell gridColumn = { 1 } >
191+ < VSCodeCheckbox />
192+ < span >
193+ { externalApiUsage . packageName } .{ externalApiUsage . typeName } .
194+ { externalApiUsage . methodName }
195+ { externalApiUsage . methodParameters }
196+ </ span >
183197 { mode === Mode . Application && (
184- < SupportSpan
185- supported = { externalApiUsage . supported }
186- modeled = { modeledMethod }
187- >
188- { externalApiUsage . methodName }
189- { externalApiUsage . methodParameters }
190- </ SupportSpan >
191- ) }
192- { mode === Mode . Framework && (
193- < SupportLink
194- supported = { externalApiUsage . supported }
195- modeled = { modeledMethod }
196- onClick = { jumpToUsage }
197- >
198- { externalApiUsage . methodName }
199- { externalApiUsage . methodParameters }
200- </ SupportLink >
201- ) }
202- </ VSCodeDataGridCell >
203- { mode === Mode . Application && (
204- < VSCodeDataGridCell gridColumn = { 3 } >
205198 < UsagesButton onClick = { jumpToUsage } >
206199 { externalApiUsage . usages . length }
207200 </ UsagesButton >
208- </ VSCodeDataGridCell >
209- ) }
210- < VSCodeDataGridCell gridColumn = { 4 } >
211- { ( ! externalApiUsage . supported ||
212- ( modeledMethod && modeledMethod ?. type !== "none" ) ) && (
213- < Dropdown
214- value = { modeledMethod ?. type ?? "none" }
215- onInput = { handleTypeInput }
216- >
217- < VSCodeOption value = "none" > Unmodeled</ VSCodeOption >
218- < VSCodeOption value = "source" > Source</ VSCodeOption >
219- < VSCodeOption value = "sink" > Sink</ VSCodeOption >
220- < VSCodeOption value = "summary" > Flow summary</ VSCodeOption >
221- < VSCodeOption value = "neutral" > Neutral</ VSCodeOption >
222- </ Dropdown >
223201 ) }
202+ < ViewLink onClick = { jumpToUsage } > View</ ViewLink >
203+ </ ApiOrMethodCell >
204+ < VSCodeDataGridCell gridColumn = { 2 } >
205+ < Dropdown
206+ value = { modeledMethod ?. type ?? "none" }
207+ options = { modelTypeOptions }
208+ disabled = { ! showModelTypeCell }
209+ onChange = { handleTypeInput }
210+ />
224211 </ VSCodeDataGridCell >
225- < VSCodeDataGridCell gridColumn = { 5 } >
226- { modeledMethod ?. type &&
227- [ "sink" , "summary" ] . includes ( modeledMethod ?. type ) && (
228- < Dropdown value = { modeledMethod ?. input } onInput = { handleInputInput } >
229- < VSCodeOption value = "Argument[this]" > Argument[this]</ VSCodeOption >
230- { argumentsList . map ( ( argument , index ) => (
231- < VSCodeOption key = { argument } value = { `Argument[${ index } ]` } >
232- Argument[{ index } ]: { argument }
233- </ VSCodeOption >
234- ) ) }
235- </ Dropdown >
236- ) }
212+ < VSCodeDataGridCell gridColumn = { 3 } >
213+ < Dropdown
214+ value = { modeledMethod ?. input }
215+ options = { inputOptions }
216+ disabled = { ! showInputCell }
217+ onChange = { handleInputInput }
218+ />
237219 </ VSCodeDataGridCell >
238- < VSCodeDataGridCell gridColumn = { 6 } >
239- { modeledMethod ?. type &&
240- [ "source" , "summary" ] . includes ( modeledMethod ?. type ) && (
241- < Dropdown value = { modeledMethod ?. output } onInput = { handleOutputInput } >
242- < VSCodeOption value = "ReturnValue" > ReturnValue</ VSCodeOption >
243- < VSCodeOption value = "Argument[this]" > Argument[this]</ VSCodeOption >
244- { argumentsList . map ( ( argument , index ) => (
245- < VSCodeOption key = { argument } value = { `Argument[${ index } ]` } >
246- Argument[{ index } ]: { argument }
247- </ VSCodeOption >
248- ) ) }
249- </ Dropdown >
250- ) }
220+ < VSCodeDataGridCell gridColumn = { 4 } >
221+ < Dropdown
222+ value = { modeledMethod ?. output }
223+ options = { outputOptions }
224+ disabled = { ! showOutputCell }
225+ onChange = { handleOutputInput }
226+ />
251227 </ VSCodeDataGridCell >
252- < VSCodeDataGridCell gridColumn = { 7 } >
253- { predicate ?. supportedKinds && (
254- < KindInput
255- kinds = { predicate . supportedKinds }
256- value = { modeledMethod ?. kind }
257- onChange = { handleKindChange }
258- />
259- ) }
228+ < VSCodeDataGridCell gridColumn = { 5 } >
229+ < KindInput
230+ kinds = { predicate ?. supportedKinds || [ ] }
231+ value = { modeledMethod ?. kind }
232+ disabled = { ! showKindCell }
233+ onChange = { handleKindChange }
234+ />
260235 </ VSCodeDataGridCell >
261236 </ VSCodeDataGridRow >
262237 ) ;
0 commit comments