-
Notifications
You must be signed in to change notification settings - Fork 9
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
feat: 🎸 Add ResolvedQuery, LoadingEmptyState, and Tooltip #80
Conversation
This adds lib-ui candidates from the forklift-ui repo
Codecov Report
@@ Coverage Diff @@
## main #80 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 1 1
Lines 19 19
Branches 5 5
=========================================
Hits 19 19 Continue to review full report at Codecov.
|
🚀 Deployed Storybook Preview: http://konveyor-lib-ui-pr-80-preview.surge.sh ✨ |
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.
@ibolton336 this is great, just a couple of thoughts here (I know I'm nitpicking my own code, but I have meant to revisit these things before moving these to lib-ui anyway).
children: React.ReactElement; | ||
} | ||
|
||
const ConditionalTooltip: React.FunctionComponent<IConditionalTooltipProps> = ({ |
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 still not 100% certain this component is necessary, I've been considering getting rid of it in forklift-ui. You can disable a tooltip by passing trigger="manual"
and isVisible="false"
, but that doesn't feel clean either. I guess we can add this component but I might try to contribute a simpler isDisabled
prop to the PF tooltip.
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.
+1 Will remove for now.
import { KubeClientError } from '../../modules/kube-client/types'; | ||
import LoadingEmptyState from '../LoadingEmptyState'; | ||
|
||
export enum QuerySpinnerMode { |
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 have been meaning to go and replace most of our string enums with simple string unions in forklift. I think it makes for cleaner TypeScript code, and I didn't realize you could do it when I wrote this. Let's change this to:
export type QuerySpinnerMode = 'inline' | 'emptyState' | 'none';
and then everywhere we are using spinnerMode={QuerySpinnerMode.Inline}
we can just use spinnerMode="inline"
etc, and we don't have to import the type.
}: IResolvedQueriesProps) => { | ||
const status = getAggregateQueryStatus(results); | ||
const erroredResults = results.filter((result) => result.isError); | ||
const filteredErrorTitles = errorTitles.filter((_title, index) => results[index].isError); |
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 have honestly been on the fence about whether having results
and errorTitles
as arrays was a good idea. If you're using ResolvedQueries to wait for several queries, especially if some of those are conditional, you have to make sure the errorTitles
array is always the same length as the results
array and they all match up. It's easy to screw up and not something TS can catch for us, and can lead to the wrong error message being displayed.
Maybe it's not worth holding up this PR, but I would love to reconsider these props, we could maybe have results be an array of objects like:
export interface IResolvedQueriesProps {
results: { result: UnknownResult; errorTitle: string }[];
// ...
}
That would enforce with TS that every query result gets an errorTitle, and then we wouldn't have to filter the errorTitles to match, we could just loop over the erroredResults and use the errorTitle from each. This might cause usage to look messier though, as it'll require a couple extra lines of code to pass in an array of objects like this.
I'm open to your thoughts on this @ibolton336 @seanforyou23 @gildub, I would be fine with merging this as-is and messing with a breaking change in forklift, or making this change now and potentially making a breaking revert or some other approach later. Open to other ideas as well.
|
||
export const ResolvedQuery: React.FunctionComponent<IResolvedQueryProps> = ({ | ||
result, | ||
errorTitle, |
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.
The result
and errorTitle
props could remain separate here though, because the above problem doesn't apply when there is just one of each. Then we'd pass them in as one object to ResolvedQueries
below.
forceLoadingState = false, | ||
children = null, | ||
}: IResolvedQueriesProps) => { | ||
const status = getAggregateQueryStatus(resultsMap.map((r) => r.result)); |
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.
@mturley What do you think of this approach? Not sure if resultsMap is the best name for this list of objects.
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.
The implementation looks great. I agree about the name, but I'm not sure I know the best solution.
I think maybe we still call the prop results
, and call the type ResultsWithErrorTitles
? TS will help if anyone tries to pass the wrong thing.
I'm still curious to see what it will look like to actually pass these in. a handful of extra lines in app code is worth avoiding the issue though I think. Thanks for this!
) : status === 'error' ? ( | ||
<AlertGroup aria-live="assertive"> | ||
{erroredResults.map((resultsMap, index) => { | ||
const { result, errorTitle } = resultsMap; |
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.
Broke out the values from the map def here. Please let me know your thoughts.
import { ResolvedQueries, IResolvedQueriesProps } from './ResolvedQueries'; | ||
|
||
export interface IResolvedQueryProps | ||
extends Omit<IResolvedQueriesProps, 'results' | 'errorTitles'> { |
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.
Changed the resultsWithErrorTitles prop to optional as I was seeing some type errors when trying to do:
<ResolvedQuery
result={plansQuery}
errorTitle={"Could not load plans"}
errorsInline={false}
>
Typescript was wanting a resultsWithErrorTitles prop I think because I we are extending the ResolvedQueries prop types here? @mturley
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.
Oh, we just need to change this:
extends Omit<IResolvedQueriesProps, 'results' | 'errorTitles'> {
to this:
extends Omit<IResolvedQueriesProps, 'resultsWithErrorTitles'> {
with that change the error should go away, I don't think we should make that prop optional.
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.
Ahh ok thank you!
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.
@mturley Just updated.
e823b2d
to
bba2ded
Compare
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.
Awesome. Thanks! I opened an issue for one of us to follow up and create docs examples for these when we get a chance. #81
🎉 This PR is included in version 5.2.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This adds lib-ui candidates from the forklift-ui repo.
What: Closes #
Additional issues: