Playground: Fix "Report issue" 414 bug (#6409)
parent
2523a017aa
commit
223443c057
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import { Button, ClipboardButton, LinkButton } from "./buttons";
|
import { Button, ClipboardButton } from "./buttons";
|
||||||
import EditorState from "./EditorState";
|
import EditorState from "./EditorState";
|
||||||
import { DebugPanel, InputPanel, OutputPanel } from "./panels";
|
import { DebugPanel, InputPanel, OutputPanel } from "./panels";
|
||||||
import PrettierFormat from "./PrettierFormat";
|
import PrettierFormat from "./PrettierFormat";
|
||||||
|
@ -42,6 +42,10 @@ const ENABLED_OPTIONS = [
|
||||||
"requirePragma",
|
"requirePragma",
|
||||||
"vueIndentScriptAndStyle"
|
"vueIndentScriptAndStyle"
|
||||||
];
|
];
|
||||||
|
const ISSUES_URL = "https://github.com/prettier/prettier/issues/new?body=";
|
||||||
|
const MAX_LENGTH = 8000 - ISSUES_URL.length; // it seems that GitHub limit is 8195
|
||||||
|
const COPY_MESSAGE =
|
||||||
|
"<!-- The issue body has been saved to the clipboard. Please paste it after this line! 👇 -->\n";
|
||||||
|
|
||||||
class Playground extends React.Component {
|
class Playground extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -135,131 +139,144 @@ class Playground extends React.Component {
|
||||||
debugDoc={editorState.showDoc}
|
debugDoc={editorState.showDoc}
|
||||||
reformat={editorState.showSecondFormat}
|
reformat={editorState.showSecondFormat}
|
||||||
>
|
>
|
||||||
{({ formatted, debug }) => (
|
{({ formatted, debug }) => {
|
||||||
<React.Fragment>
|
const fullReport = this.getMarkdown(
|
||||||
<div className="editors-container">
|
formatted,
|
||||||
<Sidebar visible={editorState.showSidebar}>
|
debug.reformatted,
|
||||||
<SidebarOptions
|
true
|
||||||
categories={CATEGORIES_ORDER}
|
);
|
||||||
availableOptions={this.enabledOptions}
|
const showFullReport =
|
||||||
optionValues={options}
|
encodeURIComponent(fullReport).length < MAX_LENGTH;
|
||||||
onOptionValueChange={this.handleOptionValueChange}
|
return (
|
||||||
/>
|
<React.Fragment>
|
||||||
<SidebarCategory title="Range">
|
<div className="editors-container">
|
||||||
<label>
|
<Sidebar visible={editorState.showSidebar}>
|
||||||
The selected range will be highlighted in yellow in the
|
<SidebarOptions
|
||||||
input editor
|
categories={CATEGORIES_ORDER}
|
||||||
</label>
|
availableOptions={this.enabledOptions}
|
||||||
<Option
|
optionValues={options}
|
||||||
option={this.rangeStartOption}
|
onOptionValueChange={this.handleOptionValueChange}
|
||||||
value={options.rangeStart}
|
|
||||||
onChange={this.handleOptionValueChange}
|
|
||||||
/>
|
/>
|
||||||
<Option
|
<SidebarCategory title="Range">
|
||||||
option={this.rangeEndOption}
|
<label>
|
||||||
value={options.rangeEnd}
|
The selected range will be highlighted in yellow in
|
||||||
overrideMax={content.length}
|
the input editor
|
||||||
onChange={this.handleOptionValueChange}
|
</label>
|
||||||
|
<Option
|
||||||
|
option={this.rangeStartOption}
|
||||||
|
value={options.rangeStart}
|
||||||
|
onChange={this.handleOptionValueChange}
|
||||||
|
/>
|
||||||
|
<Option
|
||||||
|
option={this.rangeEndOption}
|
||||||
|
value={options.rangeEnd}
|
||||||
|
overrideMax={content.length}
|
||||||
|
onChange={this.handleOptionValueChange}
|
||||||
|
/>
|
||||||
|
</SidebarCategory>
|
||||||
|
<SidebarCategory title="Debug">
|
||||||
|
<Checkbox
|
||||||
|
label="show AST"
|
||||||
|
checked={editorState.showAst}
|
||||||
|
onChange={editorState.toggleAst}
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
label="show doc"
|
||||||
|
checked={editorState.showDoc}
|
||||||
|
onChange={editorState.toggleDoc}
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
label="show second format"
|
||||||
|
checked={editorState.showSecondFormat}
|
||||||
|
onChange={editorState.toggleSecondFormat}
|
||||||
|
/>
|
||||||
|
</SidebarCategory>
|
||||||
|
<div className="sub-options">
|
||||||
|
<Button onClick={this.resetOptions}>
|
||||||
|
Reset to defaults
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</Sidebar>
|
||||||
|
<div className="editors">
|
||||||
|
<InputPanel
|
||||||
|
mode={util.getCodemirrorMode(options.parser)}
|
||||||
|
ruler={options.printWidth}
|
||||||
|
value={content}
|
||||||
|
codeSample={getCodeSample(options.parser)}
|
||||||
|
overlayStart={options.rangeStart}
|
||||||
|
overlayEnd={options.rangeEnd}
|
||||||
|
onChange={this.setContent}
|
||||||
/>
|
/>
|
||||||
</SidebarCategory>
|
{editorState.showAst ? (
|
||||||
<SidebarCategory title="Debug">
|
<DebugPanel value={debug.ast || ""} />
|
||||||
<Checkbox
|
) : null}
|
||||||
label="show AST"
|
{editorState.showDoc ? (
|
||||||
checked={editorState.showAst}
|
<DebugPanel value={debug.doc || ""} />
|
||||||
onChange={editorState.toggleAst}
|
) : null}
|
||||||
/>
|
|
||||||
<Checkbox
|
|
||||||
label="show doc"
|
|
||||||
checked={editorState.showDoc}
|
|
||||||
onChange={editorState.toggleDoc}
|
|
||||||
/>
|
|
||||||
<Checkbox
|
|
||||||
label="show second format"
|
|
||||||
checked={editorState.showSecondFormat}
|
|
||||||
onChange={editorState.toggleSecondFormat}
|
|
||||||
/>
|
|
||||||
</SidebarCategory>
|
|
||||||
<div className="sub-options">
|
|
||||||
<Button onClick={this.resetOptions}>
|
|
||||||
Reset to defaults
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</Sidebar>
|
|
||||||
<div className="editors">
|
|
||||||
<InputPanel
|
|
||||||
mode={util.getCodemirrorMode(options.parser)}
|
|
||||||
ruler={options.printWidth}
|
|
||||||
value={content}
|
|
||||||
codeSample={getCodeSample(options.parser)}
|
|
||||||
overlayStart={options.rangeStart}
|
|
||||||
overlayEnd={options.rangeEnd}
|
|
||||||
onChange={this.setContent}
|
|
||||||
/>
|
|
||||||
{editorState.showAst ? (
|
|
||||||
<DebugPanel value={debug.ast || ""} />
|
|
||||||
) : null}
|
|
||||||
{editorState.showDoc ? (
|
|
||||||
<DebugPanel value={debug.doc || ""} />
|
|
||||||
) : null}
|
|
||||||
<OutputPanel
|
|
||||||
mode={util.getCodemirrorMode(options.parser)}
|
|
||||||
value={formatted}
|
|
||||||
ruler={options.printWidth}
|
|
||||||
/>
|
|
||||||
{editorState.showSecondFormat ? (
|
|
||||||
<OutputPanel
|
<OutputPanel
|
||||||
mode={util.getCodemirrorMode(options.parser)}
|
mode={util.getCodemirrorMode(options.parser)}
|
||||||
value={getSecondFormat(formatted, debug.reformatted)}
|
value={formatted}
|
||||||
ruler={options.printWidth}
|
ruler={options.printWidth}
|
||||||
/>
|
/>
|
||||||
) : null}
|
{editorState.showSecondFormat ? (
|
||||||
|
<OutputPanel
|
||||||
|
mode={util.getCodemirrorMode(options.parser)}
|
||||||
|
value={getSecondFormat(formatted, debug.reformatted)}
|
||||||
|
ruler={options.printWidth}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="bottom-bar">
|
||||||
<div className="bottom-bar">
|
<div className="bottom-bar-buttons">
|
||||||
<div className="bottom-bar-buttons">
|
<Button onClick={editorState.toggleSidebar}>
|
||||||
<Button onClick={editorState.toggleSidebar}>
|
{editorState.showSidebar ? "Hide" : "Show"} options
|
||||||
{editorState.showSidebar ? "Hide" : "Show"} options
|
</Button>
|
||||||
</Button>
|
<Button onClick={this.clearContent}>Clear</Button>
|
||||||
<Button onClick={this.clearContent}>Clear</Button>
|
<ClipboardButton
|
||||||
<ClipboardButton
|
copy={JSON.stringify(
|
||||||
copy={JSON.stringify(
|
// Remove `parser` since people usually paste this
|
||||||
// Remove `parser` since people usually paste this
|
// into their .prettierrc and specifying a toplevel
|
||||||
// into their .prettierrc and specifying a toplevel
|
// parser there is an anti-pattern. Note:
|
||||||
// parser there is an anti-pattern. Note:
|
// `JSON.stringify` omits keys whose values are
|
||||||
// `JSON.stringify` omits keys whose values are
|
// `undefined`.
|
||||||
// `undefined`.
|
Object.assign({}, options, { parser: undefined }),
|
||||||
Object.assign({}, options, { parser: undefined }),
|
null,
|
||||||
null,
|
2
|
||||||
2
|
)}
|
||||||
)}
|
>
|
||||||
>
|
Copy config JSON
|
||||||
Copy config JSON
|
</ClipboardButton>
|
||||||
</ClipboardButton>
|
</div>
|
||||||
|
<div className="bottom-bar-buttons bottom-bar-buttons-right">
|
||||||
|
<ClipboardButton copy={window.location.href}>
|
||||||
|
Copy link
|
||||||
|
</ClipboardButton>
|
||||||
|
<ClipboardButton
|
||||||
|
copy={() =>
|
||||||
|
this.getMarkdown(formatted, debug.reformatted)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Copy markdown
|
||||||
|
</ClipboardButton>
|
||||||
|
<a
|
||||||
|
href={getReportLink(
|
||||||
|
showFullReport ? fullReport : COPY_MESSAGE
|
||||||
|
)}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<ClipboardButton
|
||||||
|
copy={() => (showFullReport ? "" : fullReport)}
|
||||||
|
>
|
||||||
|
Report issue
|
||||||
|
</ClipboardButton>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="bottom-bar-buttons bottom-bar-buttons-right">
|
</React.Fragment>
|
||||||
<ClipboardButton copy={window.location.href}>
|
);
|
||||||
Copy link
|
}}
|
||||||
</ClipboardButton>
|
|
||||||
<ClipboardButton
|
|
||||||
copy={() =>
|
|
||||||
this.getMarkdown(formatted, debug.reformatted)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Copy markdown
|
|
||||||
</ClipboardButton>
|
|
||||||
<LinkButton
|
|
||||||
href={getReportLink(
|
|
||||||
this.getMarkdown(formatted, debug.reformatted, true)
|
|
||||||
)}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>
|
|
||||||
Report issue
|
|
||||||
</LinkButton>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</React.Fragment>
|
|
||||||
)}
|
|
||||||
</PrettierFormat>
|
</PrettierFormat>
|
||||||
)}
|
)}
|
||||||
</EditorState>
|
</EditorState>
|
||||||
|
@ -277,9 +294,7 @@ function orderOptions(availableOptions, order) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getReportLink(reportBody) {
|
function getReportLink(reportBody) {
|
||||||
return `https://github.com/prettier/prettier/issues/new?body=${encodeURIComponent(
|
return `${ISSUES_URL}${encodeURIComponent(reportBody)}`;
|
||||||
reportBody
|
|
||||||
)}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSecondFormat(formatted, reformatted) {
|
function getSecondFormat(formatted, reformatted) {
|
||||||
|
|
|
@ -5,10 +5,6 @@ export const Button = React.forwardRef((props, ref) => (
|
||||||
<button type="button" className="btn" ref={ref} {...props} />
|
<button type="button" className="btn" ref={ref} {...props} />
|
||||||
));
|
));
|
||||||
|
|
||||||
export function LinkButton(props) {
|
|
||||||
return <a className="btn" {...props} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ClipboardButton extends React.Component {
|
export class ClipboardButton extends React.Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
@ -41,16 +37,16 @@ export class ClipboardButton extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { children } = this.props;
|
||||||
|
const { showTooltip, tooltipText } = this.state;
|
||||||
const rest = Object.assign({}, this.props);
|
const rest = Object.assign({}, this.props);
|
||||||
delete rest.children;
|
delete rest.children;
|
||||||
delete rest.copy;
|
delete rest.copy;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button ref={this.ref} {...rest}>
|
<Button ref={this.ref} {...rest}>
|
||||||
{this.state.showTooltip ? (
|
{showTooltip ? <span className="tooltip">{tooltipText}</span> : null}
|
||||||
<span className="tooltip">{this.state.tooltipText}</span>
|
{children}
|
||||||
) : null}
|
|
||||||
{this.props.children}
|
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue