client/app/components/queries/QueryEditor/QueryEditorControls.jsx (170 lines of code) (raw):
import { isFunction, map, filter, fromPairs, noop } from "lodash";
import React, { useEffect } from "react";
import PropTypes from "prop-types";
import Tooltip from "antd/lib/tooltip";
import Button from "antd/lib/button";
import Select from "antd/lib/select";
import KeyboardShortcuts, { humanReadableShortcut } from "@/services/KeyboardShortcuts";
import AutocompleteToggle from "./AutocompleteToggle";
import "./QueryEditorControls.less";
export function ButtonTooltip({ title, shortcut, ...props }) {
shortcut = humanReadableShortcut(shortcut, 1); // show only primary shortcut
title =
title && shortcut ? (
<React.Fragment>
{title} (<i>{shortcut}</i>)
</React.Fragment>
) : (
title || shortcut
);
return <Tooltip placement="top" title={title} {...props} />;
}
ButtonTooltip.propTypes = {
title: PropTypes.node,
shortcut: PropTypes.string,
};
ButtonTooltip.defaultProps = {
title: null,
shortcut: null,
};
export default function EditorControl({
addParameterButtonProps,
formatButtonProps,
saveButtonProps,
executeButtonProps,
autocompleteToggleProps,
dataSourceSelectorProps,
}) {
useEffect(() => {
const buttons = filter(
[addParameterButtonProps, formatButtonProps, saveButtonProps, executeButtonProps],
b => b.shortcut && isFunction(b.onClick)
);
if (buttons.length > 0) {
const shortcuts = fromPairs(map(buttons, b => [b.shortcut, b.disabled ? noop : b.onClick]));
KeyboardShortcuts.bind(shortcuts);
return () => {
KeyboardShortcuts.unbind(shortcuts);
};
}
}, [addParameterButtonProps, formatButtonProps, saveButtonProps, executeButtonProps]);
return (
<div className="query-editor-controls">
{addParameterButtonProps !== false && (
<ButtonTooltip title={addParameterButtonProps.title} shortcut={addParameterButtonProps.shortcut}>
<Button
className="query-editor-controls-button m-r-5"
disabled={addParameterButtonProps.disabled}
onClick={addParameterButtonProps.onClick}>
{"{{"} {"}}"}
</Button>
</ButtonTooltip>
)}
{formatButtonProps !== false && (
<ButtonTooltip title={formatButtonProps.title} shortcut={formatButtonProps.shortcut}>
<Button
className="query-editor-controls-button m-r-5"
disabled={formatButtonProps.disabled}
onClick={formatButtonProps.onClick}>
<span className="zmdi zmdi-format-indent-increase" />
{formatButtonProps.text}
</Button>
</ButtonTooltip>
)}
{autocompleteToggleProps !== false && (
<AutocompleteToggle
available={autocompleteToggleProps.available}
enabled={autocompleteToggleProps.enabled}
onToggle={autocompleteToggleProps.onToggle}
/>
)}
{dataSourceSelectorProps === false && <span className="query-editor-controls-spacer" />}
{dataSourceSelectorProps !== false && (
<Select
className="w-100 flex-fill datasource-small"
disabled={dataSourceSelectorProps.disabled}
value={dataSourceSelectorProps.value}
onChange={dataSourceSelectorProps.onChange}>
{map(dataSourceSelectorProps.options, option => (
<Select.Option key={`option-${option.value}`} value={option.value}>
{option.label}
</Select.Option>
))}
</Select>
)}
{saveButtonProps !== false && (
<ButtonTooltip title={saveButtonProps.title} shortcut={saveButtonProps.shortcut}>
<Button
className="query-editor-controls-button m-l-5"
disabled={saveButtonProps.disabled}
loading={saveButtonProps.loading}
onClick={saveButtonProps.onClick}
data-test="SaveButton">
{!saveButtonProps.loading && <span className="fa fa-floppy-o" />}
{saveButtonProps.text}
</Button>
</ButtonTooltip>
)}
{executeButtonProps !== false && (
<ButtonTooltip title={executeButtonProps.title} shortcut={executeButtonProps.shortcut}>
<Button
className="query-editor-controls-button m-l-5"
type="primary"
disabled={executeButtonProps.disabled}
onClick={executeButtonProps.onClick}
data-test="ExecuteButton">
<span className="zmdi zmdi-play" />
{executeButtonProps.text}
</Button>
</ButtonTooltip>
)}
</div>
);
}
const ButtonPropsPropType = PropTypes.oneOfType([
PropTypes.bool, // `false` to hide button
PropTypes.shape({
title: PropTypes.node,
disabled: PropTypes.bool,
loading: PropTypes.bool,
onClick: PropTypes.func,
text: PropTypes.node,
shortcut: PropTypes.string,
}),
]);
EditorControl.propTypes = {
addParameterButtonProps: ButtonPropsPropType,
formatButtonProps: ButtonPropsPropType,
saveButtonProps: ButtonPropsPropType,
executeButtonProps: ButtonPropsPropType,
autocompleteToggleProps: PropTypes.oneOfType([
PropTypes.bool, // `false` to hide
PropTypes.shape({
available: PropTypes.bool,
enabled: PropTypes.bool,
onToggle: PropTypes.func,
}),
]),
dataSourceSelectorProps: PropTypes.oneOfType([
PropTypes.bool, // `false` to hide
PropTypes.shape({
disabled: PropTypes.bool,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
options: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
label: PropTypes.node,
})
),
onChange: PropTypes.func,
}),
]),
};
EditorControl.defaultProps = {
addParameterButtonProps: false,
formatButtonProps: false,
saveButtonProps: false,
executeButtonProps: false,
autocompleteToggleProps: false,
dataSourceSelectorProps: false,
};