Commit c29911fd authored by Greg Tatum's avatar Greg Tatum
Browse files

Bug 1597376 - Make the summary dropdowns conditional in the profiler settings; r=julienw

This is probably the biggest change to the existing components, as it makes the
summary dropdowns conditional based on the page context. This keeps the old
workflow working, but allows for the new about:profiling page's design. Most
of the diff here is creating the new _renderSection method which consolidates
this logic, and also handles the summary div structure.

Differential Revision: https://phabricator.services.mozilla.com/D55009

--HG--
extra : moz-landing-system : lando
parent 6cba996a
......@@ -12,6 +12,7 @@
* @property {string} threadsString
* @property {string[]} objdirs
* @property {string[] | null} supportedFeatures
* @property {PageContext} pageContext
*/
/**
......@@ -36,6 +37,7 @@
* @typedef {import("../@types/perf").PopupWindow} PopupWindow
* @typedef {import("../@types/perf").State} StoreState
* @typedef {StateProps & DispatchProps} Props
* @typedef {import("../@types/perf").PageContext} PageContext
*/
/**
......@@ -63,6 +65,7 @@ const {
label,
input,
span,
h1,
h2,
h3,
section,
......@@ -78,6 +81,7 @@ const {
makeExponentialScale,
formatFileSize,
calculateOverhead,
UnhandledCaseError,
} = require("devtools/client/performance-new/utils");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const actions = require("devtools/client/performance-new/store/actions");
......@@ -403,6 +407,59 @@ class Settings extends PureComponent {
this.setState({ temporaryThreadText: null });
this.props.changeThreads(_threadTextToList(event.target.value));
}
/**
* about:profiling doesn't need to collapse the children into details/summary,
* but the popup and devtools do (for now).
*
* @param {string} id
* @param {React.ReactNode} title
* @param {React.ReactNode} children
* @returns React.ReactNode
*/
_renderSection(id, title, children) {
const { pageContext } = this.props;
switch (pageContext) {
case "popup":
case "devtools":
// Render the section with a dropdown summary.
return details(
{
className: "perf-settings-details",
// @ts-ignore - The React type definitions don't know about onToggle.
onToggle: _handleToggle,
},
summary(
{
className: "perf-settings-summary",
id,
},
// Concatenating strings like this isn't very localizable, but it should go
// away by the time we localize these components.
title + ":"
),
// Contain the overflow of the slide down animation with the first div.
div(
{ className: "perf-settings-details-contents" },
// Provide a second <div> element for the contents of the slide down
// animation.
div(
{ className: "perf-settings-details-contents-slider" },
children
)
)
);
case "aboutprofiling":
// Render the section without a dropdown summary.
return div(
{ className: "perf-settings-sections" },
div(null, h2(null, title), children)
);
default:
throw new UnhandledCaseError(pageContext, "PageContext");
}
}
/**
* @param {ThreadColumn[]} threadDisplay
* @param {number} index
......@@ -435,56 +492,39 @@ class Settings extends PureComponent {
_renderThreads() {
const { temporaryThreadText } = this.state;
return details(
{
className: "perf-settings-details",
// @ts-ignore - The React type definitions don't know about onToggle.
onToggle: _handleToggle,
},
summary(
{
className: "perf-settings-summary",
id: "perf-settings-threads-summary",
},
"Threads:"
),
// Contain the overflow of the slide down animation with the first div.
return this._renderSection(
"perf-settings-threads-summary",
"Threads",
div(
{ className: "perf-settings-details-contents" },
// Provide a second <div> element for the contents of the slide down
// animation.
null,
div(
{ className: "perf-settings-details-contents-slider" },
div(
{ className: "perf-settings-thread-columns" },
threadColumns.map(this._renderThreadsColumns)
),
div(
{ className: "perf-settings-row" },
label(
{
className: "perf-settings-text-label",
title:
"These thread names are a comma separated list that is used to " +
"enable profiling of the threads in the profiler. The name needs to " +
"be only a partial match of the thread name to be included. It " +
"is whitespace sensitive.",
},
div({}, "Add custom threads by name:"),
input({
className: "perf-settings-text-input",
id: "perf-settings-thread-text",
type: "text",
value:
temporaryThreadText === null
? this.props.threads.join(",")
: temporaryThreadText,
onBlur: this._handleThreadTextCleanup,
onFocus: this._setThreadTextFromInput,
onChange: this._setThreadTextFromInput,
})
)
{ className: "perf-settings-thread-columns" },
threadColumns.map(this._renderThreadsColumns)
),
div(
{ className: "perf-settings-row" },
label(
{
className: "perf-settings-text-label",
title:
"These thread names are a comma separated list that is used to " +
"enable profiling of the threads in the profiler. The name needs to " +
"be only a partial match of the thread name to be included. It " +
"is whitespace sensitive.",
},
div(null, "Add custom threads by name:"),
input({
className: "perf-settings-text-input",
id: "perf-settings-thread-text",
type: "text",
value:
temporaryThreadText === null
? this.props.threads.join(",")
: temporaryThreadText,
onBlur: this._handleThreadTextCleanup,
onFocus: this._setThreadTextFromInput,
onChange: this._setThreadTextFromInput,
})
)
)
)
......@@ -517,16 +557,19 @@ class Settings extends PureComponent {
className: `perf-settings-checkbox-label perf-settings-feature-label ${extraClassName}`,
key: value,
},
input({
className: "perf-settings-checkbox",
id: `perf-settings-feature-checkbox-${value}`,
type: "checkbox",
value,
checked: isSupported && this.props.features.includes(value),
onChange: this._handleFeaturesCheckboxChange,
disabled: !isSupported,
}),
div({ className: "perf-settings-feature-name" }, name),
div(
{ className: "perf-settings-checkbox-and-name" },
input({
className: "perf-settings-checkbox",
id: `perf-settings-feature-checkbox-${value}`,
type: "checkbox",
value,
checked: isSupported && this.props.features.includes(value),
onChange: this._handleFeaturesCheckboxChange,
disabled: !isSupported,
}),
div({ className: "perf-settings-feature-name" }, name)
),
div(
{ className: "perf-settings-feature-title" },
title,
......@@ -547,35 +590,22 @@ class Settings extends PureComponent {
}
_renderFeatures() {
return details(
{
className: "perf-settings-details",
// @ts-ignore - The React type definitions don't know about onToggle.
onToggle: _handleToggle,
},
summary(
{
className: "perf-settings-summary",
id: "perf-settings-features-summary",
},
"Features:"
),
return this._renderSection(
"perf-settings-features-summary",
"Features",
div(
{ className: "perf-settings-details-contents" },
div(
{ className: "perf-settings-details-contents-slider" },
// Render the supported features first.
featureCheckboxes.map(featureCheckbox =>
this._renderFeatureCheckbox(featureCheckbox, false)
),
h3(
{ className: "perf-settings-features-disabled-title" },
"The following features are currently unavailable:"
),
// Render the unsupported features second.
featureCheckboxes.map(featureCheckbox =>
this._renderFeatureCheckbox(featureCheckbox, true)
)
null,
// Render the supported features first.
featureCheckboxes.map(featureCheckbox =>
this._renderFeatureCheckbox(featureCheckbox, false)
),
h3(
{ className: "perf-settings-features-disabled-title" },
"The following features are currently unavailable:"
),
// Render the unsupported features second.
featureCheckboxes.map(featureCheckbox =>
this._renderFeatureCheckbox(featureCheckbox, true)
)
)
);
......@@ -583,51 +613,61 @@ class Settings extends PureComponent {
_renderLocalBuildSection() {
const { objdirs } = this.props;
return details(
{
className: "perf-settings-details",
// @ts-ignore - The React type definitions don't know about onToggle.
onToggle: _handleToggle,
},
summary(
{
className: "perf-settings-summary",
id: "perf-settings-local-build-summary",
},
"Local build:"
),
return this._renderSection(
"perf-settings-local-build-summary",
"Local build",
div(
{ className: "perf-settings-details-contents" },
div(
{ className: "perf-settings-details-contents-slider" },
p(
null,
`If you're profiling a build that you have compiled yourself, on this
machine, please add your build's objdir to the list below so that
it can be used to look up symbol information.`
),
DirectoryPicker({
dirs: objdirs,
onAdd: this._handleAddObjdir,
onRemove: this._handleRemoveObjdir,
})
)
null,
p(
null,
`If you're profiling a build that you have compiled yourself, on this
machine, please add your build's objdir to the list below so that
it can be used to look up symbol information.`
),
DirectoryPicker({
dirs: objdirs,
onAdd: this._handleAddObjdir,
onRemove: this._handleRemoveObjdir,
})
)
);
}
/**
* For now, render different titles depending on the context.
* @return {string}
*/
_renderTitle() {
const { pageContext } = this.props;
switch (pageContext) {
case "aboutprofiling":
return "Buffer Settings";
case "popup":
case "devtools":
return "Recording Settings";
default:
throw new UnhandledCaseError(pageContext, "PageContext");
}
}
render() {
return section(
{ className: "perf-settings" },
h2({ className: "perf-settings-title" }, "Recording Settings"),
div(
{ className: "perf-settings-row" },
label({ className: "perf-settings-label" }, "Overhead:"),
div(
{ className: "perf-settings-value perf-settings-notches" },
this._renderNotches()
)
),
this.props.pageContext === "aboutprofiling"
? h1(null, "Full Settings")
: null,
h2({ className: "perf-settings-title" }, this._renderTitle()),
// The new about:profiling will implement a different overhead mechanism.
this.props.pageContext === "aboutprofiling"
? null
: div(
{ className: "perf-settings-row" },
label({ className: "perf-settings-label" }, "Overhead:"),
div(
{ className: "perf-settings-value perf-settings-notches" },
this._renderNotches()
)
),
Range({
label: "Sampling interval:",
value: this.props.interval,
......@@ -710,6 +750,7 @@ function mapStateToProps(state) {
threadsString: selectors.getThreadsString(state),
objdirs: selectors.getObjdirs(state),
supportedFeatures: selectors.getSupportedFeatures(state),
pageContext: selectors.getPageContext(state),
};
}
......
......@@ -254,6 +254,10 @@
display: flex;
}
.perf-settings-checkbox-and-name {
display: flex;
}
.perf-settings-checkbox {
align-self: flex-start;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment