-
Notifications
You must be signed in to change notification settings - Fork 706
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
Refactor current basic form #1212
Conversation
@@ -0,0 +1,85 @@ | |||
import * as React from "react"; |
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.
Sorry, I don't know why this is detected as a new file. The changes here from the DatabaseSection
are:
enablerChildrenParam: string; | ||
enablerCondition: boolean; |
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.
These two parameters are used to know which of the children params is used to enable/disable the section.
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.
Why do you need enablerCondition
? Ah, because some charts might use enablePersistence
while others disablePersistence
?
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.
Exactly. A real example is the externalDatabase
that to be enabled require the property mariadb.enabled
to be false
.
const { label, param, name, enablerChildrenParam, enablerCondition } = this.props; | ||
return ( | ||
<div className="subsection margin-v-normal"> | ||
{param.children && param.children[enablerChildrenParam] && ( |
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.
only show the enabler section if that param exists
}; | ||
}; | ||
|
||
private renderParam(name: string, param: IBasicFormParam, index: number) { |
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.
Generically render sub params as in the BasicDeploymentForm
component.
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.
Can one implementation be shared for both cases then? (Assuming a subsection will generally be able to support all the same fields - though we don't need to support further subsections etc.)
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.
yes, I thought about that but I didn't know where to place the function. Probably just the one in the BasicDeploymentForm
should be enough.
/> | ||
); | ||
default: |
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 removed this case to assume that if the type
is not set, it refers to a string
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 - a bunch of comments, but fine to land.
So we're still enforcing a certain structure on the schema now right? Or did I miss that here? (The reason I worry about enforcing a certain structure is that it might make people less likely to use it. If I have a chart with values where the db values are just at the top level, I'd have to break my chart compatability to use this - I think?)
export interface IDiskSizeParamState { | ||
Gi: number; | ||
export interface ISliderParamState { | ||
amount: number; |
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.
value
is a bit more generic, but amount
fine too.
Gi: toNumber(this.props.param.value) || 10, | ||
class SliderParam extends React.Component<ISliderParamProps, ISliderParamState> { | ||
public state: ISliderParamState = { | ||
amount: toNumber(this.props.param.value) || this.props.min, |
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.
Doesn't this mean it can be set initially outside min/max?
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.
yes, the default value comes from the values.yaml
or the schema. If there is a problem with the configuration, the default value may not be valid
expect(defaultProps.param.children!.useSelfHostedDatabase.value).toBe(true); | ||
expect(wrapper.find(".margin-t-normal").prop("hidden")).toBe(true); | ||
expect(wrapper.find("div").findWhere(d => d.prop("hidden"))).toExist(); |
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.
This change is because there are more than one div ? So it's "expect at least one div with a hidden
prop". Not sure if that should be more specific to match the test label.
Also - why are you creating a div
with a hidden
prop, rather than a className
or similar? Also, does this return true for <div hidden={false}>
as the prop is still passed (which is what the code below does, I think?)
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.
This change is because there are more than one div ? So it's "expect at least one div with a hidden prop". Not sure if that should be more specific to match the test label.
Yes. Taking a look to the functional code, I couldn't find something better to identify the div
I am interested in.
Also - why are you creating a div with a hidden prop, rather than a className or similar?
Well, I am interested in hiding the div
, why are you suggesting using a className instead? Is there something I am missing?
Also, does this return true for
as the prop is still passed (which is what the code below does, I think?)
No, since the property of hidden
is false, the find iteration return false
so it's not returned. It only returns true
for <div hidden={true}>
.
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.
Well, I am interested in hiding the
div
, why are you suggesting using a className instead? Is there something I am missing?
No - I was just unsure whether the hidden
attribute should be used in this case. See the MDN doc, I was thinking that what we're doing here is equivalent to hiding panels in a tabbed dialog (where it should not be used), but the use-case here is different in that the elements are only relevant if the self-hosted option is enabled (across all presentations) so I think you're right to use it.
enablerChildrenParam: string; | ||
enablerCondition: boolean; |
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.
Why do you need enablerCondition
? Ah, because some charts might use enablePersistence
while others disablePersistence
?
}; | ||
}; | ||
|
||
private renderParam(name: string, param: IBasicFormParam, index: number) { |
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.
Can one implementation be shared for both cases then? (Assuming a subsection will generally be able to support all the same fields - though we don't need to support further subsections etc.)
@@ -90,7 +92,8 @@ export function setValue(values: string, path: string, newValue: any) { | |||
export function getValue(values: string, path: string, defaultValue?: any) { | |||
const doc = YAML.parseDocument(values); | |||
const splittedPath = path.split("."); | |||
return (doc as any).getIn(splittedPath) || defaultValue; | |||
const value = (doc as any).getIn(splittedPath); | |||
return value === undefined || value === null ? defaultValue : value; |
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.
Not really important, but should the default also be limited to min/max? Completely ignorable :)
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 default is set by the user (the same way they set the min/max) so that shouldn't be a case (and their tests should catch that)
Yes (that't not changed in this PR), but the logic is a bit different. If you want to have a subsection, you need to follow a certain structure. You still can set the db values at the top level but you won't see them grouped in a section, just as plain arguments. I think it makes sense to have this kind of conversion from structured objects to subsections (that's what automatic parsers do for JSON schemas). Apart from that, we have the hardcoded change in which we are moving |
Merging this to send another PR. If there is something unresolved please let me know! |
Yep, I often +1 with some comments, meaning that you should feel free to land it once you've looked at the comments and made a decision either way. Thanks! |
This PR contains several improvements:
keys
that Kubeapps expects has been reduced to the minimum possible (for the moment) and moved to the fileschema.ts
so any component can read those.DatabaseSection
has been refactored toSubsection
to make it generic. The idea is to reuse this component for the hostname section.DiskSize
has been refactored toSliderParam
to make it generic. The idea is to reuse this component for the resource params.