-
Notifications
You must be signed in to change notification settings - Fork 226
Add ability for MethodRow to render multiple modelings of the same method #2910
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
robertbrignull
merged 10 commits into
main
from
robertbrignull/multiple-models-method-row
Oct 9, 2023
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
e75eccb
Change MethodRow to accept ModelEditorViewState object instead of jus…
robertbrignull a704cd7
Convert getModelingStatus to take ModeledMethod[]
robertbrignull 86d7d83
Convert ApiOrMethodCell to ApiOrMethodRow
robertbrignull 252c7a2
Convert MethodRow to display multiple modelings
robertbrignull 8eef4eb
Add story with multiple modelings
robertbrignull f87b1c4
Add some simple tests of rendering multiple models
robertbrignull 5ba64a1
Add test for when there's no modeled method
robertbrignull 8b0825a
Use better name for variable
robertbrignull 0265353
Use index as react key
robertbrignull edd2aa5
Merge branch 'main' into robertbrignull/multiple-models-method-row
robertbrignull File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,8 +21,16 @@ import { MethodName } from "./MethodName"; | |
| import { ModelTypeDropdown } from "./ModelTypeDropdown"; | ||
| import { ModelInputDropdown } from "./ModelInputDropdown"; | ||
| import { ModelOutputDropdown } from "./ModelOutputDropdown"; | ||
| import { ModelEditorViewState } from "../../model-editor/shared/view-state"; | ||
|
|
||
| const ApiOrMethodCell = styled(VSCodeDataGridCell)` | ||
| const MultiModelColumn = styled(VSCodeDataGridCell)` | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: 0.5em; | ||
| `; | ||
|
|
||
| const ApiOrMethodRow = styled.div` | ||
| min-height: calc(var(--input-height) * 1px); | ||
| display: flex; | ||
| flex-direction: row; | ||
| align-items: center; | ||
|
|
@@ -55,10 +63,10 @@ const DataGridRow = styled(VSCodeDataGridRow)<{ focused?: boolean }>` | |
| export type MethodRowProps = { | ||
| method: Method; | ||
| methodCanBeModeled: boolean; | ||
| modeledMethod: ModeledMethod | undefined; | ||
| modeledMethods: ModeledMethod[]; | ||
| methodIsUnsaved: boolean; | ||
| modelingInProgress: boolean; | ||
| mode: Mode; | ||
| viewState: ModelEditorViewState; | ||
| revealedMethodSignature: string | null; | ||
| onChange: (modeledMethod: ModeledMethod) => void; | ||
| }; | ||
|
|
@@ -88,38 +96,44 @@ const ModelableMethodRow = forwardRef<HTMLElement | undefined, MethodRowProps>( | |
| (props, ref) => { | ||
| const { | ||
| method, | ||
| modeledMethod, | ||
| modeledMethods: modeledMethodsProp, | ||
| methodIsUnsaved, | ||
| mode, | ||
| viewState, | ||
| revealedMethodSignature, | ||
| onChange, | ||
| } = props; | ||
|
|
||
| const modeledMethods = viewState.showMultipleModels | ||
| ? modeledMethodsProp | ||
| : modeledMethodsProp.slice(0, 1); | ||
|
|
||
| const jumpToUsage = useCallback( | ||
| () => sendJumpToUsageMessage(method), | ||
| [method], | ||
| ); | ||
|
|
||
| const modelingStatus = getModelingStatus(modeledMethod, methodIsUnsaved); | ||
| const modelingStatus = getModelingStatus(modeledMethods, methodIsUnsaved); | ||
|
|
||
| return ( | ||
| <DataGridRow | ||
| data-testid="modelable-method-row" | ||
| ref={ref} | ||
| focused={revealedMethodSignature === method.signature} | ||
| > | ||
| <ApiOrMethodCell gridColumn={1}> | ||
| <ModelingStatusIndicator status={modelingStatus} /> | ||
| <MethodClassifications method={method} /> | ||
| <MethodName {...props.method} /> | ||
| {mode === Mode.Application && ( | ||
| <UsagesButton onClick={jumpToUsage}> | ||
| {method.usages.length} | ||
| </UsagesButton> | ||
| )} | ||
| <ViewLink onClick={jumpToUsage}>View</ViewLink> | ||
| {props.modelingInProgress && <ProgressRing />} | ||
| </ApiOrMethodCell> | ||
| <VSCodeDataGridCell gridColumn={1}> | ||
| <ApiOrMethodRow> | ||
| <ModelingStatusIndicator status={modelingStatus} /> | ||
| <MethodClassifications method={method} /> | ||
| <MethodName {...props.method} /> | ||
| {viewState.mode === Mode.Application && ( | ||
| <UsagesButton onClick={jumpToUsage}> | ||
| {method.usages.length} | ||
| </UsagesButton> | ||
| )} | ||
| <ViewLink onClick={jumpToUsage}>View</ViewLink> | ||
| {props.modelingInProgress && <ProgressRing />} | ||
| </ApiOrMethodRow> | ||
| </VSCodeDataGridCell> | ||
| {props.modelingInProgress && ( | ||
| <> | ||
| <VSCodeDataGridCell gridColumn={2}> | ||
|
|
@@ -138,34 +152,46 @@ const ModelableMethodRow = forwardRef<HTMLElement | undefined, MethodRowProps>( | |
| )} | ||
| {!props.modelingInProgress && ( | ||
| <> | ||
| <VSCodeDataGridCell gridColumn={2}> | ||
| <ModelTypeDropdown | ||
| method={method} | ||
| modeledMethod={modeledMethod} | ||
| onChange={onChange} | ||
| /> | ||
| </VSCodeDataGridCell> | ||
| <VSCodeDataGridCell gridColumn={3}> | ||
| <ModelInputDropdown | ||
| method={method} | ||
| modeledMethod={modeledMethod} | ||
| onChange={onChange} | ||
| /> | ||
| </VSCodeDataGridCell> | ||
| <VSCodeDataGridCell gridColumn={4}> | ||
| <ModelOutputDropdown | ||
| method={method} | ||
| modeledMethod={modeledMethod} | ||
| onChange={onChange} | ||
| /> | ||
| </VSCodeDataGridCell> | ||
| <VSCodeDataGridCell gridColumn={5}> | ||
| <ModelKindDropdown | ||
| method={method} | ||
| modeledMethod={modeledMethod} | ||
| onChange={onChange} | ||
| /> | ||
| </VSCodeDataGridCell> | ||
| <MultiModelColumn gridColumn={2}> | ||
| {forEachModeledMethod(modeledMethods, (modeledMethod, index) => ( | ||
| <ModelTypeDropdown | ||
| key={index} | ||
| method={method} | ||
| modeledMethod={modeledMethod} | ||
| onChange={onChange} | ||
| /> | ||
| ))} | ||
| </MultiModelColumn> | ||
| <MultiModelColumn gridColumn={3}> | ||
| {forEachModeledMethod(modeledMethods, (modeledMethod, index) => ( | ||
| <ModelInputDropdown | ||
| key={index} | ||
| method={method} | ||
| modeledMethod={modeledMethod} | ||
| onChange={onChange} | ||
| /> | ||
| ))} | ||
| </MultiModelColumn> | ||
| <MultiModelColumn gridColumn={4}> | ||
| {forEachModeledMethod(modeledMethods, (modeledMethod, index) => ( | ||
| <ModelOutputDropdown | ||
| key={index} | ||
| method={method} | ||
| modeledMethod={modeledMethod} | ||
| onChange={onChange} | ||
| /> | ||
| ))} | ||
| </MultiModelColumn> | ||
| <MultiModelColumn gridColumn={5}> | ||
| {forEachModeledMethod(modeledMethods, (modeledMethod, index) => ( | ||
| <ModelKindDropdown | ||
| key={index} | ||
| method={method} | ||
| modeledMethod={modeledMethod} | ||
| onChange={onChange} | ||
| /> | ||
| ))} | ||
| </MultiModelColumn> | ||
| </> | ||
| )} | ||
| </DataGridRow> | ||
|
|
@@ -178,7 +204,7 @@ const UnmodelableMethodRow = forwardRef< | |
| HTMLElement | undefined, | ||
| MethodRowProps | ||
| >((props, ref) => { | ||
| const { method, mode, revealedMethodSignature } = props; | ||
| const { method, viewState, revealedMethodSignature } = props; | ||
|
|
||
| const jumpToUsage = useCallback( | ||
| () => sendJumpToUsageMessage(method), | ||
|
|
@@ -191,17 +217,19 @@ const UnmodelableMethodRow = forwardRef< | |
| ref={ref} | ||
| focused={revealedMethodSignature === method.signature} | ||
| > | ||
| <ApiOrMethodCell gridColumn={1}> | ||
| <ModelingStatusIndicator status="saved" /> | ||
| <MethodName {...props.method} /> | ||
| {mode === Mode.Application && ( | ||
| <UsagesButton onClick={jumpToUsage}> | ||
| {method.usages.length} | ||
| </UsagesButton> | ||
| )} | ||
| <ViewLink onClick={jumpToUsage}>View</ViewLink> | ||
| <MethodClassifications method={method} /> | ||
| </ApiOrMethodCell> | ||
| <VSCodeDataGridCell gridColumn={1}> | ||
| <ApiOrMethodRow> | ||
| <ModelingStatusIndicator status="saved" /> | ||
| <MethodName {...props.method} /> | ||
| {viewState.mode === Mode.Application && ( | ||
| <UsagesButton onClick={jumpToUsage}> | ||
| {method.usages.length} | ||
| </UsagesButton> | ||
| )} | ||
| <ViewLink onClick={jumpToUsage}>View</ViewLink> | ||
| <MethodClassifications method={method} /> | ||
| </ApiOrMethodRow> | ||
| </VSCodeDataGridCell> | ||
| <VSCodeDataGridCell gridColumn="span 4"> | ||
| Method already modeled | ||
| </VSCodeDataGridCell> | ||
|
|
@@ -218,3 +246,17 @@ function sendJumpToUsageMessage(method: Method) { | |
| usage: method.usages[0], | ||
| }); | ||
| } | ||
|
|
||
| function forEachModeledMethod( | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not totally happy with this but it's the cleanest thing I could come up with right now. The idea is that when there are no modeled methods we still need to render one set of boxes, but passing |
||
| modeledMethods: ModeledMethod[], | ||
| renderer: ( | ||
| modeledMethod: ModeledMethod | undefined, | ||
| index: number, | ||
| ) => JSX.Element, | ||
| ): JSX.Element | JSX.Element[] { | ||
| if (modeledMethods.length === 0) { | ||
| return renderer(undefined, 0); | ||
| } else { | ||
| return modeledMethods.map(renderer); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not yet sure what the signature for
onChangeshould be. Perhaps it should not be(modeledMethods: ModeledMethod[]) => voidso we send over all the modelings for this method whenever anything changes.I think it'll have to be that, as otherwise is something changes on one modeling, the receiver of the callback wouldn't know which modeling it was. So we have to send all of them at once so it knows if the number of modelings has changed and the exact state of all of them.
I could do that in this PR or the next one. This PR isn't intending to actually make this component work yet and be able to edit multiple modelings. I just want to get the UI looking right and then we can hook up all the implementation later. So long as it still works correctly when the feature flag is disabled that's ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think sending all of them even if only 1 has changed makes the most sense. My suggestion would be something like
onChange: (signature: string, modeledMethods: ModeledMethod[]). I would suggest adding the signature so we don't need to find the signature of the method that is being modeled from themodeledMethods, but can simply use it as-is.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making the method signature
onChange: (signature: string, modeledMethods: ModeledMethod[])sounds good to me. I was also considering the same thing. I'll save that change for a separate PR though.