draft: actions dropdown, need to clean up
This commit is contained in:
@@ -24,6 +24,7 @@ export interface QueryOperationRowProps {
|
||||
collapsable?: boolean;
|
||||
disabled?: boolean;
|
||||
expanderMessages?: ExpanderMessages;
|
||||
isFocused?: boolean;
|
||||
}
|
||||
|
||||
export type QueryOperationRowRenderProp = ((props: QueryOperationRowRenderProps) => React.ReactNode) | React.ReactNode;
|
||||
@@ -48,6 +49,7 @@ export function QueryOperationRow({
|
||||
index,
|
||||
id,
|
||||
expanderMessages,
|
||||
isFocused = false,
|
||||
}: QueryOperationRowProps) {
|
||||
const [isContentVisible, setIsContentVisible] = useState(isOpen !== undefined ? isOpen : true);
|
||||
const styles = useStyles2(getQueryOperationRowStyles);
|
||||
@@ -127,6 +129,7 @@ export function QueryOperationRow({
|
||||
reportDragMousePosition={reportDragMousePosition}
|
||||
title={title}
|
||||
expanderMessages={expanderMessages}
|
||||
isFocused={isFocused}
|
||||
/>
|
||||
</div>
|
||||
{isContentVisible && <div className={styles.content}>{children}</div>}
|
||||
@@ -152,6 +155,7 @@ export function QueryOperationRow({
|
||||
reportDragMousePosition={reportDragMousePosition}
|
||||
title={title}
|
||||
expanderMessages={expanderMessages}
|
||||
isFocused={isFocused}
|
||||
/>
|
||||
{isContentVisible && <div className={styles.content}>{children}</div>}
|
||||
</div>
|
||||
|
||||
@@ -20,6 +20,7 @@ export interface QueryOperationRowHeaderProps {
|
||||
title?: string;
|
||||
id: string;
|
||||
expanderMessages?: ExpanderMessages;
|
||||
isFocused?: boolean;
|
||||
}
|
||||
|
||||
export interface ExpanderMessages {
|
||||
@@ -40,6 +41,7 @@ export const QueryOperationRowHeader = ({
|
||||
title,
|
||||
id,
|
||||
expanderMessages,
|
||||
isFocused = false,
|
||||
}: QueryOperationRowHeaderProps) => {
|
||||
const styles = useStyles2(getStyles);
|
||||
|
||||
@@ -55,7 +57,7 @@ export const QueryOperationRowHeader = ({
|
||||
const dragAndDropLabel = t('query-operation.header.drag-and-drop', 'Drag and drop to reorder');
|
||||
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
<div className={cx(styles.header, isFocused && styles.focused)}>
|
||||
<div className={styles.column}>
|
||||
{collapsable && (
|
||||
<IconButton
|
||||
@@ -107,6 +109,9 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
||||
outline: 'none',
|
||||
},
|
||||
}),
|
||||
focused: css({
|
||||
border: `2px solid ${theme.colors.primary.border}`,
|
||||
}),
|
||||
column: css({
|
||||
label: 'Column',
|
||||
display: 'flex',
|
||||
|
||||
@@ -23,7 +23,7 @@ import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Trans, t } from '@grafana/i18n';
|
||||
import { getDataSourceSrv, renderLimitedComponents, reportInteraction, usePluginComponents } from '@grafana/runtime';
|
||||
import { DataQuery } from '@grafana/schema';
|
||||
import { Badge, ErrorBoundaryAlert, List, Text } from '@grafana/ui';
|
||||
import { Badge, Button, Dropdown, ErrorBoundaryAlert, Icon, List, Menu, Stack, Text, TextLink } from '@grafana/ui';
|
||||
import { OperationRowHelp } from 'app/core/components/QueryOperationRow/OperationRowHelp';
|
||||
import {
|
||||
QueryOperationAction,
|
||||
@@ -410,38 +410,92 @@ export class QueryEditorRow<TQuery extends DataQuery> extends PureComponent<Prop
|
||||
const isUnifiedAlerting = app === CoreApp.UnifiedAlerting;
|
||||
const isExpressionQuery = query.datasource?.uid === ExpressionDatasourceUID;
|
||||
|
||||
// Build menu items for the actions dropdown
|
||||
const menuItems: ReactNode[] = [];
|
||||
|
||||
// Saved query buttons (if applicable) - keep separate as it returns complex ReactNode
|
||||
const savedQueryButtons =
|
||||
!isEditingQueryLibrary && !isUnifiedAlerting && !isExpressionQuery ? (
|
||||
<SavedQueryButtons
|
||||
query={{
|
||||
...query,
|
||||
datasource: datasource ? { uid: datasource.uid, type: datasource.type } : query.datasource,
|
||||
}}
|
||||
app={app}
|
||||
onUpdateSuccess={this.onExitQueryLibraryEditingMode}
|
||||
onSelectQuery={this.onSelectQueryFromLibrary}
|
||||
datasourceFilters={datasource?.name ? [datasource.name] : []}
|
||||
/>
|
||||
) : null;
|
||||
|
||||
// Data source help (toggle action)
|
||||
if (hasEditorHelp) {
|
||||
menuItems.push(
|
||||
<Menu.Item
|
||||
key="datasource-help"
|
||||
label={
|
||||
showingHelp
|
||||
? t('query-operation.header.hide-datasource-help', 'Hide data source help')
|
||||
: t('query-operation.header.datasource-help', 'Show data source help')
|
||||
}
|
||||
icon="question-circle"
|
||||
onClick={this.onToggleHelp}
|
||||
active={showingHelp}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Duplicate query
|
||||
if (!isEditingQueryLibrary) {
|
||||
menuItems.push(
|
||||
<Menu.Item
|
||||
key="duplicate-query"
|
||||
label={t('query-operation.header.duplicate-query', 'Duplicate query')}
|
||||
icon="copy"
|
||||
onClick={this.onCopyQuery}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Focus query
|
||||
if (onFocusQuery) {
|
||||
menuItems.push(
|
||||
<Menu.Item
|
||||
key="focus-query"
|
||||
label={
|
||||
isFocused
|
||||
? t('query-operation.header.collapse', 'Show all queries')
|
||||
: t('query-operation.header.focus', 'Focus query')
|
||||
}
|
||||
icon={isFocused ? 'compress-screen' : 'expand-screen'}
|
||||
onClick={onFocusQuery}
|
||||
active={Boolean(isFocused)}
|
||||
testId={selectors.components.QueryEditorRow.actionButton('Focus query')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Extra actions (warnings, badges, etc.) - keep separate as they return complex ReactNodes
|
||||
const extraActions = this.renderExtraActions();
|
||||
|
||||
// Only render dropdown if there are menu items
|
||||
const actionsDropdown =
|
||||
menuItems.length > 0 ? (
|
||||
<Dropdown overlay={<Menu>{menuItems}</Menu>} placement="bottom-end">
|
||||
<Button
|
||||
icon="ellipsis-v"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
aria-label={t('query-operation.header.actions-menu', 'Query actions menu')}
|
||||
data-testid={selectors.components.QueryEditorRow.actionButton('Actions menu')}
|
||||
/>
|
||||
</Dropdown>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<>
|
||||
{!isEditingQueryLibrary && !isUnifiedAlerting && !isExpressionQuery && (
|
||||
<SavedQueryButtons
|
||||
query={{
|
||||
...query,
|
||||
datasource: datasource ? { uid: datasource.uid, type: datasource.type } : query.datasource,
|
||||
}}
|
||||
app={app}
|
||||
onUpdateSuccess={this.onExitQueryLibraryEditingMode}
|
||||
onSelectQuery={this.onSelectQueryFromLibrary}
|
||||
datasourceFilters={datasource?.name ? [datasource.name] : []}
|
||||
/>
|
||||
)}
|
||||
|
||||
{hasEditorHelp && (
|
||||
<QueryOperationToggleAction
|
||||
title={t('query-operation.header.datasource-help', 'Show data source help')}
|
||||
icon="question-circle"
|
||||
onClick={this.onToggleHelp}
|
||||
active={showingHelp}
|
||||
/>
|
||||
)}
|
||||
{this.renderExtraActions()}
|
||||
{!isEditingQueryLibrary && (
|
||||
<QueryOperationAction
|
||||
title={t('query-operation.header.duplicate-query', 'Duplicate query')}
|
||||
icon="copy"
|
||||
onClick={this.onCopyQuery}
|
||||
/>
|
||||
)}
|
||||
|
||||
{savedQueryButtons}
|
||||
{extraActions}
|
||||
{!hideHideQueryButton ? (
|
||||
<QueryOperationToggleAction
|
||||
dataTestId={selectors.components.QueryEditorRow.actionButton('Hide response')}
|
||||
@@ -462,19 +516,7 @@ export class QueryEditorRow<TQuery extends DataQuery> extends PureComponent<Prop
|
||||
onClick={this.onRemoveQuery}
|
||||
/>
|
||||
)}
|
||||
{onFocusQuery && (
|
||||
<QueryOperationToggleAction
|
||||
dataTestId={selectors.components.QueryEditorRow.actionButton('Focus query')}
|
||||
title={
|
||||
isFocused
|
||||
? t('query-operation.header.collapse', 'Show all queries')
|
||||
: t('query-operation.header.focus', 'Focus query')
|
||||
}
|
||||
icon={isFocused ? 'compress-screen' : 'expand-screen'}
|
||||
active={Boolean(isFocused)}
|
||||
onClick={onFocusQuery}
|
||||
/>
|
||||
)}
|
||||
{actionsDropdown}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -501,6 +543,7 @@ export class QueryEditorRow<TQuery extends DataQuery> extends PureComponent<Prop
|
||||
render() {
|
||||
const {
|
||||
query,
|
||||
queries,
|
||||
index,
|
||||
visualization,
|
||||
collapsable,
|
||||
@@ -511,6 +554,7 @@ export class QueryEditorRow<TQuery extends DataQuery> extends PureComponent<Prop
|
||||
queryLibraryRef,
|
||||
onCancelQueryLibraryEdit,
|
||||
isFocused,
|
||||
onFocusQuery,
|
||||
} = this.props;
|
||||
const { datasource, showingHelp, data } = this.state;
|
||||
const isHidden = query.hide;
|
||||
@@ -542,6 +586,7 @@ export class QueryEditorRow<TQuery extends DataQuery> extends PureComponent<Prop
|
||||
actions={hideActionButtons ? undefined : this.renderActions}
|
||||
isOpen={isOpen}
|
||||
onOpen={onQueryOpenChanged}
|
||||
isFocused={isFocused}
|
||||
>
|
||||
<div className={rowClasses} id={this.id}>
|
||||
<ErrorBoundaryAlert boundaryName="query-editor-operation-row">
|
||||
@@ -562,8 +607,7 @@ export class QueryEditorRow<TQuery extends DataQuery> extends PureComponent<Prop
|
||||
</QueryOperationRow>
|
||||
);
|
||||
|
||||
const { queries } = this.props;
|
||||
const hiddenQueriesCount = queries.length - 1; // Total queries minus the focused one
|
||||
const hiddenQueriesCount = Math.max(0, queries.length - 1); // Total queries minus the focused one
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -571,22 +615,22 @@ export class QueryEditorRow<TQuery extends DataQuery> extends PureComponent<Prop
|
||||
aria-label={selectors.components.QueryEditorRows.rows}
|
||||
className={focusedWrapperStyle}
|
||||
>
|
||||
{isFocused && (
|
||||
{isFocused && hiddenQueriesCount > 0 && (
|
||||
<div className={getFocusedBannerStyle()}>
|
||||
<Text color="primary" variant="bodySmall" italic>
|
||||
<Trans
|
||||
i18nKey="query.query-editor-row.focused-message"
|
||||
values={{ queryName: query.refId, count: hiddenQueriesCount }}
|
||||
>
|
||||
Query {query.refId} is focused, {hiddenQueriesCount}{' '}
|
||||
{hiddenQueriesCount === 1 ? (
|
||||
<Trans i18nKey="query.query-editor-row.focused-singular">query is</Trans>
|
||||
) : (
|
||||
<Trans i18nKey="query.query-editor-row.focused-plural">all other queries are</Trans>
|
||||
)}{' '}
|
||||
hidden from view.
|
||||
</Trans>
|
||||
</Text>
|
||||
<Stack direction="row" alignItems="center" gap={1}>
|
||||
<Icon name="expand-screen" />
|
||||
<Text color="primary" variant="bodySmall" italic>
|
||||
<Trans
|
||||
i18nKey="query.query-editor-row.focused-message"
|
||||
values={{ queryName: query.refId, count: hiddenQueriesCount }}
|
||||
>
|
||||
Query {query.refId} is focused, {'{{count}}'} queries are hidden from view.
|
||||
</Trans>
|
||||
</Text>
|
||||
<Button fill="text" size="sm" onClick={onFocusQuery}>
|
||||
<Trans i18nKey="query-operation.header.collapse">Show all queries</Trans>
|
||||
</Button>
|
||||
</Stack>
|
||||
</div>
|
||||
)}
|
||||
{queryLibraryRef && (
|
||||
|
||||
Reference in New Issue
Block a user