Stack: Use the component from grafana/ui (#77543)

* grafana/ui: Move Stack out of unstable

* grafana/ui: Replace imports

* Replace the import from experimental

* Cleanup

* Remove invalid prop

* Add flexGrow

* Remove Stack used in Field

* Remove import
This commit is contained in:
Alex Khomenko 2023-11-06 17:15:52 +01:00 committed by GitHub
parent c0d8a7132e
commit 25779bb6e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
93 changed files with 317 additions and 335 deletions

View File

@ -1,5 +1,5 @@
import { css } from '@emotion/css';
import React from 'react';
import React, { CSSProperties } from 'react';
import { GrafanaTheme2, ThemeSpacingTokens } from '@grafana/data';
@ -40,11 +40,12 @@ interface StackProps extends Omit<React.HTMLAttributes<HTMLElement>, 'className'
direction?: ResponsiveProp<Direction>;
wrap?: ResponsiveProp<Wrap>;
children?: React.ReactNode;
flexGrow?: ResponsiveProp<CSSProperties['flexGrow']>;
}
export const Stack = React.forwardRef<HTMLDivElement, StackProps>(
({ gap = 1, alignItems, justifyContent, direction, wrap, children, ...rest }, ref) => {
const styles = useStyles2(getStyles, gap, alignItems, justifyContent, direction, wrap);
({ gap = 1, alignItems, justifyContent, direction, wrap, children, flexGrow, ...rest }, ref) => {
const styles = useStyles2(getStyles, gap, alignItems, justifyContent, direction, wrap, flexGrow);
return (
<div ref={ref} className={styles.flex} {...rest}>
@ -62,28 +63,32 @@ const getStyles = (
alignItems: StackProps['alignItems'],
justifyContent: StackProps['justifyContent'],
direction: StackProps['direction'],
wrap: StackProps['wrap']
wrap: StackProps['wrap'],
flexGrow: StackProps['flexGrow']
) => {
return {
flex: css([
{
display: 'flex',
},
getResponsiveStyle<Direction>(theme, direction, (val) => ({
getResponsiveStyle(theme, direction, (val) => ({
flexDirection: val,
})),
getResponsiveStyle<Wrap>(theme, wrap, (val) => ({
getResponsiveStyle(theme, wrap, (val) => ({
flexWrap: val,
})),
getResponsiveStyle<AlignItems>(theme, alignItems, (val) => ({
getResponsiveStyle(theme, alignItems, (val) => ({
alignItems: val,
})),
getResponsiveStyle<JustifyContent>(theme, justifyContent, (val) => ({
getResponsiveStyle(theme, justifyContent, (val) => ({
justifyContent: val,
})),
getResponsiveStyle<ThemeSpacingTokens>(theme, gap, (val) => ({
getResponsiveStyle(theme, gap, (val) => ({
gap: theme.spacing(val),
})),
getResponsiveStyle(theme, flexGrow, (val) => ({
flexGrow: val,
})),
]),
};
};

View File

@ -1,7 +1,6 @@
import React, { useEffect, useMemo, useState } from 'react';
import { Stack } from '@grafana/experimental';
import { Button, Form, Select } from '@grafana/ui';
import { Button, Form, Select, Stack } from '@grafana/ui';
import { CloseButton } from 'app/core/components/CloseButton/CloseButton';
import { ServiceAccountPicker } from 'app/core/components/Select/ServiceAccountPicker';
import { TeamPicker } from 'app/core/components/Select/TeamPicker';

View File

@ -3,8 +3,7 @@ import React, { MouseEventHandler } from 'react';
import { DraggableProvided } from 'react-beautiful-dnd';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Icon, IconButton, useStyles2 } from '@grafana/ui';
import { Icon, IconButton, useStyles2, Stack } from '@grafana/ui';
export interface QueryOperationRowHeaderProps {
actionsElement?: React.ReactNode;
@ -73,7 +72,7 @@ export const QueryOperationRowHeader = ({
{headerElement}
</div>
<Stack gap={1} alignItems="center" wrap={false}>
<Stack gap={1} alignItems="center">
{actionsElement}
{draggable && (
<div onMouseMove={reportDragMousePosition} {...dragHandleProps}>

View File

@ -4,8 +4,7 @@ import React, { useEffect, useState } from 'react';
import { useDebounce } from 'react-use';
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Card, FilterInput, Icon, Pagination, Select, TagList, useStyles2 } from '@grafana/ui';
import { Card, FilterInput, Icon, Pagination, Select, TagList, useStyles2, Stack } from '@grafana/ui';
import { DEFAULT_PER_PAGE_PAGINATION } from 'app/core/constants';
import { getQueryParamValue } from 'app/core/utils/query';
import { FolderState, useDispatch } from 'app/types';

View File

@ -4,9 +4,8 @@ import { keyBy, startCase } from 'lodash';
import React from 'react';
import { DataSourceInstanceSettings, GrafanaTheme2, PanelData, RelativeTimeRange } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { config } from '@grafana/runtime';
import { Badge, useStyles2 } from '@grafana/ui';
import { Badge, useStyles2, Stack } from '@grafana/ui';
import { mapRelativeTimeRangeToOption } from '@grafana/ui/src/components/DateTimePickers/RelativeTimeRangePicker/utils';
import { AlertQuery } from '../../../types/unified-alerting-dto';

View File

@ -4,8 +4,7 @@ import React, { useEffect, useMemo, useState } from 'react';
import { useAsyncFn } from 'react-use';
import { GrafanaTheme2, UrlQueryMap } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Alert, LoadingPlaceholder, Tab, TabContent, TabsBar, useStyles2, withErrorBoundary } from '@grafana/ui';
import { Alert, LoadingPlaceholder, Tab, TabContent, TabsBar, useStyles2, withErrorBoundary, Stack } from '@grafana/ui';
import { useQueryParams } from 'app/core/hooks/useQueryParams';
import { ObjectMatcher, Route, RouteWithID } from 'app/plugins/datasource/alertmanager/types';
import { useDispatch } from 'app/types';

View File

@ -3,8 +3,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useAsyncFn, useInterval } from 'react-use';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Button, useStyles2, withErrorBoundary } from '@grafana/ui';
import { Button, useStyles2, withErrorBoundary, Stack } from '@grafana/ui';
import { useQueryParams } from 'app/core/hooks/useQueryParams';
import { useDispatch } from 'app/types';

View File

@ -4,8 +4,7 @@ import classnames from 'classnames';
import React, { ReactElement, ReactNode, useRef } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Popover as GrafanaPopover, PopoverController, useStyles2 } from '@grafana/ui';
import { Popover as GrafanaPopover, PopoverController, useStyles2, Stack } from '@grafana/ui';
export interface HoverCardProps {
children: ReactElement;

View File

@ -3,8 +3,7 @@ import React, { ReactNode } from 'react';
import tinycolor2 from 'tinycolor2';
import { GrafanaTheme2, IconName } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Icon, useStyles2 } from '@grafana/ui';
import { Icon, useStyles2, Stack } from '@grafana/ui';
export type LabelSize = 'md' | 'sm';
@ -22,7 +21,7 @@ const Label = ({ label, value, icon, color, size = 'md' }: Props) => {
return (
<div className={styles.wrapper} role="listitem">
<Stack direction="row" gap={0} alignItems="stretch" wrap={false}>
<Stack direction="row" gap={0} alignItems="stretch">
<div className={styles.label}>
<Stack direction="row" gap={0.5} alignItems="center">
{icon && <Icon name={icon} />} {label ?? ''}

View File

@ -1,8 +1,7 @@
import { css, cx } from '@emotion/css';
import React, { ComponentProps, HTMLAttributes } from 'react';
import { Stack } from '@grafana/experimental';
import { Icon, IconName, useStyles2, Text } from '@grafana/ui';
import { Icon, IconName, useStyles2, Text, Stack } from '@grafana/ui';
interface Props extends HTMLAttributes<HTMLDivElement> {
icon?: IconName;
@ -22,7 +21,7 @@ const MetaText = ({ children, icon, color = 'secondary', ...rest }: Props) => {
{...rest}
>
<Text variant="bodySmall" color={color}>
<Stack direction="row" alignItems="center" gap={0.5}>
<Stack direction="row" alignItems="center" gap={0.5} wrap={'wrap'}>
{icon && <Icon size="sm" name={icon} />}
{children}
</Stack>

View File

@ -1,7 +1,6 @@
import React, { forwardRef, Ref } from 'react';
import { Stack } from '@grafana/experimental';
import { Button, ButtonProps, Icon } from '@grafana/ui';
import { Button, ButtonProps, Icon, Stack } from '@grafana/ui';
const MoreButton = forwardRef(function MoreButton(props: ButtonProps, ref: Ref<HTMLButtonElement>) {
return (

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React, { useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { useStyles2 } from '@grafana/ui';
import { useStyles2, Stack } from '@grafana/ui';
import { AlertmanagerGroup, AlertState } from 'app/plugins/datasource/alertmanager/types';
import { AlertLabels } from '../AlertLabels';

View File

@ -3,8 +3,7 @@ import { debounce } from 'lodash';
import React, { FormEvent, useEffect, useMemo } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Label, Tooltip, Input, Icon, useStyles2 } from '@grafana/ui';
import { Label, Tooltip, Input, Icon, useStyles2, Stack } from '@grafana/ui';
import { logInfo, LogMessages } from '../../Analytics';

View File

@ -7,7 +7,6 @@ import { Link } from 'react-router-dom';
import { useToggle } from 'react-use';
import { dateTime, GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import {
Alert,
Dropdown,
@ -23,6 +22,7 @@ import {
Tab,
Pagination,
Button,
Stack,
} from '@grafana/ui';
import ConditionalWrap from 'app/features/alerting/components/ConditionalWrap';
import { receiverTypeNames } from 'app/plugins/datasource/alertmanager/consts';

View File

@ -3,8 +3,7 @@ import { uniqueId } from 'lodash';
import React, { FC, useCallback, useState } from 'react';
import { DataFrame, dateTimeFormat, GrafanaTheme2, isTimeSeriesFrames, LoadingState, PanelData } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { AutoSizeInput, Button, clearButtonStyles, IconButton, useStyles2 } from '@grafana/ui';
import { AutoSizeInput, Button, clearButtonStyles, IconButton, useStyles2, Stack } from '@grafana/ui';
import { ClassicConditions } from 'app/features/expressions/components/ClassicConditions';
import { Math } from 'app/features/expressions/components/Math';
import { Reduce } from 'app/features/expressions/components/Reduce';
@ -288,7 +287,7 @@ const Header: FC<HeaderProps> = ({
return (
<header className={styles.header.wrapper}>
<Stack direction="row" gap={0.5} alignItems="center">
<Stack direction="row" gap={1} alignItems="center" wrap={false}>
<Stack direction="row" gap={1} alignItems="center">
{!editingRefId && (
<button type="button" className={cx(clearButton, styles.editable)} onClick={() => setEditMode('refId')}>
<div className={styles.expression.refId}>{refId}</div>

View File

@ -4,8 +4,7 @@ import React, { useEffect, useState } from 'react';
import { useFieldArray, useFormContext } from 'react-hook-form';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Button, Field, FieldSet, Icon, Input, useStyles2 } from '@grafana/ui';
import { Button, Field, FieldSet, Icon, Input, useStyles2, Stack } from '@grafana/ui';
import { MuteTimingFields } from '../../types/mute-timing-form';
import { DAYS_OF_THE_WEEK, defaultTimeInterval, MONTHS, validateArrayField } from '../../utils/mute-timings';

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React, { useMemo, useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { IconButton, LinkButton, Link, useStyles2, ConfirmModal } from '@grafana/ui';
import { IconButton, LinkButton, Link, useStyles2, ConfirmModal, Stack } from '@grafana/ui';
import { MuteTimeInterval } from 'app/plugins/datasource/alertmanager/types';
import { useDispatch } from 'app/types/store';

View File

@ -1,8 +1,7 @@
import pluralize from 'pluralize';
import React, { Fragment } from 'react';
import { Stack } from '@grafana/experimental';
import { Badge } from '@grafana/ui';
import { Badge, Stack } from '@grafana/ui';
interface Props {
active?: number;

View File

@ -1,8 +1,7 @@
import React from 'react';
import { SelectableValue } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Select, SelectCommonProps, Text } from '@grafana/ui';
import { Select, SelectCommonProps, Text, Stack } from '@grafana/ui';
import {
RECEIVER_META_KEY,
@ -36,7 +35,7 @@ interface ReceiversProps {
const ReceiversSummary = ({ receivers }: ReceiversProps) => {
return (
<Stack direction="row" wrap={false}>
<Stack direction="row">
{receivers.map((receiver, index) => (
<Stack key={receiver.uid ?? index} direction="row" gap={0.5}>
{receiver[RECEIVER_PLUGIN_META_KEY]?.icon && (

View File

@ -2,7 +2,6 @@ import { css } from '@emotion/css';
import React, { ReactNode, useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import {
Button,
Field,
@ -17,6 +16,7 @@ import {
useStyles2,
Badge,
FieldValidationMessage,
Stack,
} from '@grafana/ui';
import { MatcherOperator, RouteWithID } from 'app/plugins/datasource/alertmanager/types';

View File

@ -3,8 +3,7 @@ import { debounce } from 'lodash';
import React, { useCallback, useEffect, useRef } from 'react';
import { SelectableValue } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Button, Field, Icon, Input, Label as LabelElement, Select, Tooltip, useStyles2 } from '@grafana/ui';
import { Button, Field, Icon, Input, Label as LabelElement, Select, Tooltip, useStyles2, Stack } from '@grafana/ui';
import { ObjectMatcher, Receiver, RouteWithID } from 'app/plugins/datasource/alertmanager/types';
import { useURLSearchParams } from '../../hooks/useURLSearchParams';

View File

@ -3,8 +3,7 @@ import { take, takeRight, uniqueId } from 'lodash';
import React, { FC } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { getTagColorsFromName, useStyles2 } from '@grafana/ui';
import { getTagColorsFromName, useStyles2, Stack } from '@grafana/ui';
import { ObjectMatcher } from 'app/plugins/datasource/alertmanager/types';
import { HoverCard } from '../HoverCard';
@ -23,7 +22,7 @@ const Matchers: FC<MatchersProps> = ({ matchers }) => {
return (
<span data-testid="label-matchers">
<Stack direction="row" gap={1} alignItems="center">
<Stack direction="row" gap={1} alignItems="center" wrap={'wrap'}>
{firstFew.map((matcher) => (
<MatcherBadge key={uniqueId()} matcher={matcher} />
))}

View File

@ -1,8 +1,7 @@
import { groupBy } from 'lodash';
import React, { FC, useCallback, useMemo, useState } from 'react';
import { Stack } from '@grafana/experimental';
import { Button, Icon, Modal, ModalProps, Spinner } from '@grafana/ui';
import { Button, Icon, Modal, ModalProps, Spinner, Stack } from '@grafana/ui';
import {
AlertmanagerGroup,
AlertState,
@ -239,7 +238,7 @@ const useAlertGroupsModal = (): [
closeOnBackdropClick={true}
closeOnEscape={true}
title={
<Stack direction="row" alignItems="center" gap={1} flexGrow={1}>
<Stack direction="row" alignItems="center" gap={1} wrap={'wrap'}>
<Stack direction="row" alignItems="center" gap={0.5}>
<Icon name="x" /> Matchers
</Stack>

View File

@ -6,8 +6,18 @@ import { Link } from 'react-router-dom';
import { useToggle } from 'react-use';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Badge, Button, Dropdown, getTagColorsFromName, Icon, Menu, Text, Tooltip, useStyles2 } from '@grafana/ui';
import {
Badge,
Button,
Dropdown,
Icon,
Menu,
Stack,
Text,
Tooltip,
getTagColorsFromName,
useStyles2,
} from '@grafana/ui';
import ConditionalWrap from 'app/features/alerting/components/ConditionalWrap';
import { AlertmanagerGroup, ObjectMatcher, Receiver, RouteWithID } from 'app/plugins/datasource/alertmanager/types';
import { ReceiversState } from 'app/types';

View File

@ -1,7 +1,6 @@
import React from 'react';
import { Stack } from '@grafana/experimental';
import { Alert, LinkButton } from '@grafana/ui';
import { Alert, LinkButton, Stack } from '@grafana/ui';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
import { AlertmanagerAction, useAlertmanagerAbility } from '../../hooks/useAbilities';

View File

@ -4,8 +4,7 @@ import { Link } from 'react-router-dom';
import { useToggle } from 'react-use';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Button, Dropdown, Icon, Menu, MenuItem, useStyles2 } from '@grafana/ui';
import { Button, Dropdown, Icon, Menu, MenuItem, useStyles2, Stack } from '@grafana/ui';
import { GrafanaReceiversExporter } from '../export/GrafanaReceiversExporter';

View File

@ -3,8 +3,7 @@ import React, { useMemo, useState } from 'react';
import { useToggle } from 'react-use';
import { dateTime, dateTimeFormat } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Badge, Button, ConfirmModal, Icon, Modal, useStyles2 } from '@grafana/ui';
import { Badge, Button, ConfirmModal, Icon, Modal, useStyles2, Stack } from '@grafana/ui';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
import { ContactPointsState, NotifiersState, ReceiversState, useDispatch } from 'app/types';

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { useStyles2 } from '@grafana/ui';
import { useStyles2, Stack } from '@grafana/ui';
import { HoverCard } from '../HoverCard';
@ -30,7 +29,7 @@ export function TemplateDataDocs() {
);
return (
<Stack gap={2} flexGrow={1}>
<Stack gap={2}>
<TemplateDataTable
caption={<h4 className={styles.header}>Template Data</h4>}
dataItems={GlobalTemplateData}

View File

@ -7,7 +7,6 @@ import { useLocation } from 'react-router-dom';
import AutoSizer from 'react-virtualized-auto-sizer';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { isFetchError } from '@grafana/runtime';
import {
Alert,
@ -21,6 +20,7 @@ import {
Tab,
TabsBar,
useStyles2,
Stack,
} from '@grafana/ui';
import { useCleanup } from 'app/core/hooks/useCleanup';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';

View File

@ -4,8 +4,7 @@ import React, { useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Button, Card, Modal, RadioButtonGroup, useStyles2 } from '@grafana/ui';
import { Button, Card, Modal, RadioButtonGroup, useStyles2, Stack } from '@grafana/ui';
import { TestTemplateAlert } from 'app/plugins/datasource/alertmanager/types';
import { KeyValueField } from '../../../api/templateApi';

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Icon, LinkButton, Tooltip, useStyles2 } from '@grafana/ui';
import { Icon, LinkButton, Tooltip, useStyles2, Stack } from '@grafana/ui';
import { ReceiverPluginMetadata } from './useReceiversMetadata';

View File

@ -1,8 +1,7 @@
import React from 'react';
import { FieldArrayWithId, useFormContext } from 'react-hook-form';
import { Stack } from '@grafana/experimental';
import { InputControl, Text } from '@grafana/ui';
import { InputControl, Text, Stack } from '@grafana/ui';
import { RuleFormValues } from '../../types/rule-form';
import { Annotation, annotationDescriptions, annotationLabels } from '../../utils/constants';

View File

@ -5,8 +5,7 @@ import { useFieldArray, useFormContext } from 'react-hook-form';
import { useToggle } from 'react-use';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Button, Field, Input, Text, TextArea, useStyles2 } from '@grafana/ui';
import { Button, Field, Input, Text, TextArea, useStyles2, Stack } from '@grafana/ui';
import { DashboardModel } from '../../../../dashboard/state';
import { RuleFormValues } from '../../types/rule-form';

View File

@ -4,8 +4,19 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { FormProvider, useForm, useFormContext } from 'react-hook-form';
import { AppEvents, GrafanaTheme2, SelectableValue } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { AsyncSelect, Button, Field, Input, InputControl, Label, Modal, Text, useStyles2 } from '@grafana/ui';
import {
AsyncSelect,
Box,
Button,
Field,
Input,
InputControl,
Label,
Modal,
Stack,
Text,
useStyles2,
} from '@grafana/ui';
import appEvents from 'app/core/app_events';
import { contextSrv } from 'app/core/services/context_srv';
import { createFolder } from 'app/features/manage-dashboards/state/actions';
@ -134,108 +145,103 @@ export function FolderAndGroup({
return (
<div className={styles.container}>
<div>
{
<Field
label={
<Label htmlFor="folder" description={'Select a folder to store your rule.'}>
Folder
</Label>
}
className={styles.formInput}
error={errors.folder?.message}
invalid={!!errors.folder?.message}
data-testid="folder-picker"
>
<Stack direction="row" alignItems="center">
{(!isCreatingFolder && (
<>
<InputControl
render={({ field: { ref, ...field } }) => (
<div style={{ width: 420 }}>
<RuleFolderPicker
inputId="folder"
{...field}
enableReset={true}
onChange={({ title, uid }) => {
field.onChange({ title, uid });
resetGroup();
}}
/>
</div>
)}
name="folder"
rules={{
required: { value: true, message: 'Select a folder' },
validate: {
pathSeparator: (folder: Folder) => checkForPathSeparator(folder.title),
},
}}
/>
<Text color="secondary">or</Text>
<Button
onClick={onOpenFolderCreationModal}
type="button"
icon="plus"
fill="outline"
variant="secondary"
disabled={!contextSrv.hasPermission(AccessControlAction.FoldersCreate)}
>
New folder
</Button>
</>
)) || <div>Creating new folder...</div>}
</Stack>
</Field>
}
{isCreatingFolder && (
<FolderCreationModal onCreate={handleFolderCreation} onClose={() => setIsCreatingFolder(false)} />
)}
</div>
<div>
<Stack alignItems="center">
<Field
label="Evaluation group"
data-testid="group-picker"
description="Rules within the same group are evaluated sequentially over the same time interval."
label={
<Label htmlFor="folder" description={'Select a folder to store your rule.'}>
Folder
</Label>
}
className={styles.formInput}
error={errors.group?.message}
invalid={!!errors.group?.message}
error={errors.folder?.message}
invalid={!!errors.folder?.message}
data-testid="folder-picker"
>
<Stack direction="row" alignItems="center">
{(!isCreatingFolder && (
<InputControl
render={({ field: { ref, ...field }, fieldState }) => (
render={({ field: { ref, ...field } }) => (
<div style={{ width: 420 }}>
<AsyncSelect
disabled={!folder || loading}
inputId="group"
key={uniqueId()}
<RuleFolderPicker
inputId="folder"
{...field}
onChange={(group) => {
field.onChange(group.label ?? '');
enableReset={true}
onChange={({ title, uid }) => {
field.onChange({ title, uid });
resetGroup();
}}
isLoading={loading}
invalid={Boolean(folder) && !group && Boolean(fieldState.error)}
loadOptions={debouncedSearch}
cacheOptions
loadingMessage={'Loading groups...'}
defaultValue={defaultGroupValue}
defaultOptions={groupOptions}
getOptionLabel={(option: SelectableValue<string>) => (
<div>
<span>{option.label}</span>
{option['isProvisioned'] && (
<>
{' '}
<ProvisioningBadge />
</>
)}
</div>
)}
placeholder={'Select an evaluation group...'}
/>
</div>
)}
name="folder"
rules={{
required: { value: true, message: 'Select a folder' },
validate: {
pathSeparator: (folder: Folder) => checkForPathSeparator(folder.title),
},
}}
/>
)) || <div>Creating new folder...</div>}
</Field>
<Box marginTop={2.5} gap={1} display={'flex'} alignItems={'center'}>
<Text color="secondary">or</Text>
<Button
onClick={onOpenFolderCreationModal}
type="button"
icon="plus"
fill="outline"
variant="secondary"
disabled={!contextSrv.hasPermission(AccessControlAction.FoldersCreate)}
>
New folder
</Button>
</Box>
</Stack>
{isCreatingFolder && (
<FolderCreationModal onCreate={handleFolderCreation} onClose={() => setIsCreatingFolder(false)} />
)}
<Stack alignItems="center">
<div style={{ width: 420 }}>
<Field
label="Evaluation group"
data-testid="group-picker"
description="Rules within the same group are evaluated sequentially over the same time interval."
className={styles.formInput}
error={errors.group?.message}
invalid={!!errors.group?.message}
>
<InputControl
render={({ field: { ref, ...field }, fieldState }) => (
<AsyncSelect
disabled={!folder || loading}
inputId="group"
key={uniqueId()}
{...field}
onChange={(group) => {
field.onChange(group.label ?? '');
}}
isLoading={loading}
invalid={Boolean(folder) && !group && Boolean(fieldState.error)}
loadOptions={debouncedSearch}
cacheOptions
loadingMessage={'Loading groups...'}
defaultValue={defaultGroupValue}
defaultOptions={groupOptions}
getOptionLabel={(option: SelectableValue<string>) => (
<div>
<span>{option.label}</span>
{option['isProvisioned'] && (
<>
{' '}
<ProvisioningBadge />
</>
)}
</div>
)}
placeholder={'Select an evaluation group...'}
/>
)}
name="group"
control={control}
rules={{
@ -245,19 +251,21 @@ export function FolderAndGroup({
},
}}
/>
<Text color="secondary">or</Text>
<Button
onClick={onOpenEvaluationGroupCreationModal}
type="button"
icon="plus"
fill="outline"
variant="secondary"
disabled={!folder}
>
New evaluation group
</Button>
</Stack>
</Field>
</Field>
</div>
<Box marginTop={4} gap={1} display={'flex'} alignItems={'center'}>
<Text color="secondary">or</Text>
<Button
onClick={onOpenEvaluationGroupCreationModal}
type="button"
icon="plus"
fill="outline"
variant="secondary"
disabled={!folder}
>
New evaluation group
</Button>
</Box>
{isCreatingEvaluationGroup && (
<EvaluationGroupCreationModal
onCreate={handleEvalGroupCreation}
@ -265,7 +273,7 @@ export function FolderAndGroup({
groupfoldersForGrafana={groupfoldersForGrafana}
/>
)}
</div>
</Stack>
</div>
);
}

View File

@ -3,8 +3,19 @@ import React, { useCallback, useEffect, useState } from 'react';
import { RegisterOptions, useFormContext } from 'react-hook-form';
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Field, Icon, IconButton, Input, InputControl, Label, Switch, Text, Tooltip, useStyles2 } from '@grafana/ui';
import {
Field,
Icon,
IconButton,
Input,
InputControl,
Label,
Stack,
Switch,
Text,
Tooltip,
useStyles2,
} from '@grafana/ui';
import { CombinedRuleGroup, CombinedRuleNamespace } from '../../../../../types/unified-alerting';
import { logInfo, LogMessages } from '../../Analytics';

View File

@ -3,7 +3,6 @@ import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { FieldArrayMethodProps, useFieldArray, useFormContext } from 'react-hook-form';
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import {
Button,
Field,
@ -15,6 +14,7 @@ import {
Icon,
Input,
LoadingPlaceholder,
Stack,
} from '@grafana/ui';
import { useDispatch } from 'app/types';

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Icon, Text, Toggletip, useStyles2 } from '@grafana/ui';
import { Icon, Text, Toggletip, useStyles2, Stack } from '@grafana/ui';
interface NeedHelpInfoProps {
contentText: string | JSX.Element;

View File

@ -1,8 +1,7 @@
import React from 'react';
import { useFormContext } from 'react-hook-form';
import { Stack } from '@grafana/experimental';
import { Icon, Text } from '@grafana/ui';
import { Icon, Text, Stack } from '@grafana/ui';
import { RuleFormType, RuleFormValues } from '../../types/rule-form';
import { GRAFANA_RULES_SOURCE_NAME } from '../../utils/datasource';

View File

@ -10,9 +10,8 @@ import {
rangeUtil,
RelativeTimeRange,
} from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { getDataSourceSrv } from '@grafana/runtime';
import { Button, Card, Icon } from '@grafana/ui';
import { Button, Card, Icon, Stack } from '@grafana/ui';
import { QueryOperationRow } from 'app/core/components/QueryOperationRow/QueryOperationRow';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
import { AlertDataQuery, AlertQuery } from 'app/types/unified-alerting-dto';

View File

@ -12,9 +12,8 @@ import {
RelativeTimeRange,
ThresholdsConfig,
} from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { DataQuery } from '@grafana/schema';
import { GraphTresholdsStyleMode, Icon, InlineField, Input, Tooltip, useStyles2 } from '@grafana/ui';
import { GraphTresholdsStyleMode, Icon, InlineField, Input, Tooltip, useStyles2, Stack } from '@grafana/ui';
import { QueryEditorRow } from 'app/features/query/components/QueryEditorRow';
import { AlertQuery } from 'app/types/unified-alerting-dto';

View File

@ -2,8 +2,7 @@ import { css, cx } from '@emotion/css';
import React, { ReactElement } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { FieldSet, Text, useStyles2 } from '@grafana/ui';
import { FieldSet, Text, useStyles2, Stack } from '@grafana/ui';
export interface RuleEditorSectionProps {
title: string;

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Icon, Tooltip, useStyles2 } from '@grafana/ui';
import { Icon, Tooltip, useStyles2, Stack } from '@grafana/ui';
import { OldFolderPicker, Props as FolderPickerProps } from 'app/core/components/Select/OldFolderPicker';
import { PermissionLevelString, SearchQueryType } from 'app/types';

View File

@ -4,9 +4,8 @@ import { DeepMap, FieldError, FormProvider, useForm, UseFormWatch } from 'react-
import { Link, useParams } from 'react-router-dom';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { config } from '@grafana/runtime';
import { Button, ConfirmModal, CustomScrollbar, HorizontalGroup, Spinner, useStyles2 } from '@grafana/ui';
import { Button, ConfirmModal, CustomScrollbar, HorizontalGroup, Spinner, useStyles2, Stack } from '@grafana/ui';
import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate';
import { useAppNotification } from 'app/core/copy/appNotification';
import { contextSrv } from 'app/core/core';

View File

@ -2,8 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useAsync } from 'react-use';
import { Stack } from '@grafana/experimental';
import { Button, CustomScrollbar, LinkButton, LoadingPlaceholder } from '@grafana/ui';
import { Button, CustomScrollbar, LinkButton, LoadingPlaceholder, Stack } from '@grafana/ui';
import { useAppNotification } from 'app/core/copy/appNotification';
import { useQueryParams } from 'app/core/hooks/useQueryParams';

View File

@ -5,9 +5,20 @@ import { useFormContext } from 'react-hook-form';
import { getDefaultRelativeTimeRange, GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { Stack } from '@grafana/experimental';
import { config, getDataSourceSrv } from '@grafana/runtime';
import { Alert, Button, Dropdown, Field, Icon, InputControl, Menu, MenuItem, Tooltip, useStyles2 } from '@grafana/ui';
import {
Alert,
Button,
Dropdown,
Field,
Icon,
InputControl,
Menu,
MenuItem,
Stack,
Tooltip,
useStyles2,
} from '@grafana/ui';
import { Text } from '@grafana/ui/src/components/Text/Text';
import { isExpressionQuery } from 'app/features/expressions/guards';
import { ExpressionDatasourceUID, ExpressionQueryType, expressionTypes } from 'app/features/expressions/types';

View File

@ -2,9 +2,8 @@ import React from 'react';
import { useFormContext } from 'react-hook-form';
import { DataSourceInstanceSettings } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { DataSourceJsonData } from '@grafana/schema';
import { RadioButtonGroup, Text } from '@grafana/ui';
import { RadioButtonGroup, Text, Stack } from '@grafana/ui';
import { contextSrv } from 'app/core/core';
import { ExpressionDatasourceUID } from 'app/features/expressions/types';
import { AccessControlAction } from 'app/types';

View File

@ -3,8 +3,7 @@ import { isEmpty } from 'lodash';
import React, { useEffect } from 'react';
import { GrafanaTheme2 } from '@grafana/data/src';
import { Stack } from '@grafana/experimental';
import { useStyles2 } from '@grafana/ui';
import { useStyles2, Stack } from '@grafana/ui';
import { dispatch } from 'app/store/store';
import { useRulesSourcesWithRuler } from '../../../hooks/useRuleSourcesWithRuler';

View File

@ -4,9 +4,18 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useObservable, useToggle } from 'react-use';
import { GrafanaTheme2, LoadingState, PanelData, RelativeTimeRange } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { config, isFetchError } from '@grafana/runtime';
import { Alert, Button, Collapse, Icon, IconButton, LoadingPlaceholder, useStyles2, VerticalGroup } from '@grafana/ui';
import {
Alert,
Button,
Collapse,
Icon,
IconButton,
LoadingPlaceholder,
Stack,
VerticalGroup,
useStyles2,
} from '@grafana/ui';
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
import { DEFAULT_PER_PAGE_PAGINATION } from '../../../../../core/constants';
@ -164,7 +173,7 @@ export function RuleViewer({ match }: RuleViewerProps) {
{isProvisioned && <ProvisioningAlert resource={ProvisionedResource.AlertRule} />}
<RuleViewerLayoutContent>
<div>
<Stack direction="row" alignItems="center" wrap={false} gap={1}>
<Stack direction="row" alignItems="center" gap={1}>
<Icon name="bell" size="lg" /> <span className={styles.title}>{rule.name}</span>
</Stack>
<RuleState rule={rule} isCreating={false} isDeleting={false} />

View File

@ -1,7 +1,6 @@
import React, { useMemo, useState } from 'react';
import { Stack } from '@grafana/experimental';
import { Alert, Button, Icon, LoadingPlaceholder, Tab, TabContent, TabsBar, Text } from '@grafana/ui';
import { Alert, Button, Icon, LoadingPlaceholder, Tab, TabContent, TabsBar, Text, Stack } from '@grafana/ui';
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
import { GrafanaAlertState } from 'app/types/unified-alerting-dto';

View File

@ -4,8 +4,7 @@ import React, { useEffect, useMemo } from 'react';
import { FormProvider, RegisterOptions, useForm, useFormContext } from 'react-hook-form';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Badge, Button, Field, Input, Label, LinkButton, Modal, useStyles2 } from '@grafana/ui';
import { Badge, Button, Field, Input, Label, LinkButton, Modal, useStyles2, Stack } from '@grafana/ui';
import { useAppNotification } from 'app/core/copy/appNotification';
import { useCleanup } from 'app/core/hooks/useCleanup';
import { useDispatch } from 'app/types';
@ -235,41 +234,41 @@ export function EditCloudGroupModal(props: ModalProps): React.ReactElement {
<form onSubmit={(e) => e.preventDefault()} key={JSON.stringify(defaultValues)}>
<>
{!props.hideFolder && (
<Field
label={
<Label
htmlFor="namespaceName"
description={
!isGrafanaManagedGroup &&
'Change the current namespace name. Moving groups between namespaces is not supported'
}
>
{nameSpaceLabel}
</Label>
}
invalid={!!errors.namespaceName}
error={errors.namespaceName?.message}
>
<Stack gap={1} direction="row">
<Stack gap={1} alignItems={'center'}>
<Field
className={styles.formInput}
label={
<Label
htmlFor="namespaceName"
description={
!isGrafanaManagedGroup &&
'Change the current namespace name. Moving groups between namespaces is not supported'
}
>
{nameSpaceLabel}
</Label>
}
invalid={!!errors.namespaceName}
error={errors.namespaceName?.message}
>
<Input
id="namespaceName"
readOnly={intervalEditOnly || isGrafanaManagedGroup}
{...register('namespaceName', {
required: 'Namespace name is required.',
})}
className={styles.formInput}
/>
{isGrafanaManagedGroup && props.folderUrl && (
<LinkButton
href={props.folderUrl}
title="Go to folder"
variant="secondary"
icon="folder-open"
target="_blank"
/>
)}
</Stack>
</Field>
</Field>
{isGrafanaManagedGroup && props.folderUrl && (
<LinkButton
href={props.folderUrl}
title="Go to folder"
variant="secondary"
icon="folder-open"
target="_blank"
/>
)}
</Stack>
)}
<Field
label={<Label htmlFor="groupName">Evaluation group name</Label>}

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data/src/themes';
import { Stack } from '@grafana/experimental';
import { CallToActionCard, useStyles2 } from '@grafana/ui';
import { CallToActionCard, useStyles2, Stack } from '@grafana/ui';
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
import { logInfo, LogMessages } from '../../Analytics';
@ -16,7 +15,7 @@ export const NoRulesSplash = () => {
return (
<div>
<p>{"You haven't created any alert rules yet"}</p>
<Stack direction="row" gap={1} alignItems="stretch" flexGrow={1}>
<Stack gap={1}>
<div className={styles.newRuleCard}>
<EmptyListCTA
title=""

View File

@ -4,7 +4,6 @@ import React, { useState } from 'react';
import { useLocation } from 'react-router-dom';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import {
Button,
ClipboardButton,
@ -15,6 +14,7 @@ import {
Menu,
Tooltip,
useStyles2,
Stack,
} from '@grafana/ui';
import { useAppNotification } from 'app/core/copy/appNotification';
import { useDispatch } from 'app/types';

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React, { useMemo } from 'react';
import { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Spinner, useStyles2 } from '@grafana/ui';
import { Spinner, useStyles2, Stack } from '@grafana/ui';
import { CombinedRule } from 'app/types/unified-alerting';
import { PromAlertingRuleState } from 'app/types/unified-alerting-dto';

View File

@ -2,8 +2,7 @@ import { isUndefined, omitBy, sum } from 'lodash';
import pluralize from 'pluralize';
import React, { Fragment } from 'react';
import { Stack } from '@grafana/experimental';
import { Badge } from '@grafana/ui';
import { Badge, Stack } from '@grafana/ui';
import {
AlertGroupTotals,
AlertInstanceTotalState,

View File

@ -3,8 +3,7 @@ import React, { useEffect, useRef, useState } from 'react';
import { useForm } from 'react-hook-form';
import { DataSourceInstanceSettings, GrafanaTheme2, SelectableValue } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Button, Field, Icon, Input, Label, RadioButtonGroup, Tooltip, useStyles2 } from '@grafana/ui';
import { Button, Field, Icon, Input, Label, RadioButtonGroup, Tooltip, useStyles2, Stack } from '@grafana/ui';
import { useQueryParams } from 'app/core/hooks/useQueryParams';
import { PromAlertingRuleState, PromRuleType } from 'app/types/unified-alerting-dto';

View File

@ -3,8 +3,7 @@ import pluralize from 'pluralize';
import React, { useEffect, useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Badge, ConfirmModal, HorizontalGroup, Icon, Spinner, Tooltip, useStyles2 } from '@grafana/ui';
import { Badge, ConfirmModal, HorizontalGroup, Icon, Spinner, Tooltip, useStyles2, Stack } from '@grafana/ui';
import { useDispatch } from 'app/types';
import { CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting';

View File

@ -4,8 +4,7 @@ import { groupBy, uniqueId } from 'lodash';
import React, { useEffect } from 'react';
import { dateTimeFormat, GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Icon, TagList, useStyles2 } from '@grafana/ui';
import { Icon, TagList, useStyles2, Stack } from '@grafana/ui';
import { Label } from '../../Label';
import { AlertStateTag } from '../AlertStateTag';
@ -64,7 +63,7 @@ export const LogRecordViewerByTimestamp = React.memo(
<AlertStateTag state={line.previous} size="sm" muted />
<Icon name="arrow-right" size="sm" />
<AlertStateTag state={line.current} />
<Stack direction="row">{line.values && <AlertInstanceValues record={line.values} />}</Stack>
<Stack>{line.values && <AlertInstanceValues record={line.values} />}</Stack>
<div>
{line.labels && (
<TagList
@ -112,7 +111,7 @@ export function LogRecordViewerByInstance({ records, commonLabels }: LogRecordVi
<AlertStateTag state={line.previous} size="sm" muted />
<Icon name="arrow-right" size="sm" />
<AlertStateTag state={line.current} />
<Stack direction="row">{line.values && <AlertInstanceValues record={line.values} />}</Stack>
<Stack>{line.values && <AlertInstanceValues record={line.values} />}</Stack>
<div>{dateTimeFormat(timestamp)}</div>
</div>
))}
@ -134,7 +133,7 @@ const Timestamp = ({ time }: TimestampProps) => {
return (
<div className={styles.timestampWrapper}>
<Stack direction="row" alignItems="center" gap={1}>
<Stack alignItems="center" gap={1}>
<Icon name="clock-nine" size="sm" />
<span className={styles.timestampText}>{dateTimeFormat(dateTime)}</span>
<small>({formatDistanceToNowStrict(dateTime)} ago)</small>

View File

@ -4,8 +4,7 @@ import React, { useCallback, useMemo, useRef, useState } from 'react';
import { useForm } from 'react-hook-form';
import { DataFrame, dateTime, GrafanaTheme2, TimeRange } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Alert, Button, Field, Icon, Input, Label, TagList, Tooltip, useStyles2 } from '@grafana/ui';
import { Alert, Button, Field, Icon, Input, Label, TagList, Tooltip, useStyles2, Stack } from '@grafana/ui';
import { stateHistoryApi } from '../../../api/stateHistoryApi';
import { combineMatcherStrings } from '../../../utils/alertmanager';

View File

@ -3,8 +3,7 @@ import { groupBy } from 'lodash';
import React, { FormEvent, useCallback, useState } from 'react';
import { AlertState, dateTimeFormat, GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Alert, Field, Icon, Input, Label, LoadingPlaceholder, Tooltip, useStyles2 } from '@grafana/ui';
import { Alert, Field, Icon, Input, Label, LoadingPlaceholder, Tooltip, useStyles2, Stack } from '@grafana/ui';
import { StateHistoryItem, StateHistoryItemData } from 'app/types/unified-alerting';
import { GrafanaAlertStateWithReason, PromAlertingRuleState } from 'app/types/unified-alerting-dto';

View File

@ -3,8 +3,7 @@ import { debounce, uniqueId } from 'lodash';
import React, { FormEvent, useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Button, Field, Icon, Input, Label, Tooltip, useStyles2 } from '@grafana/ui';
import { Button, Field, Icon, Input, Label, Tooltip, useStyles2, Stack } from '@grafana/ui';
import { useQueryParams } from 'app/core/hooks/useQueryParams';
import { parseMatchers } from '../../utils/alertmanager';

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React, { useMemo } from 'react';
import { dateMath, GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { CollapsableSection, Icon, Link, LinkButton, useStyles2 } from '@grafana/ui';
import { CollapsableSection, Icon, Link, LinkButton, useStyles2, Stack } from '@grafana/ui';
import { useQueryParams } from 'app/core/hooks/useQueryParams';
import { AlertmanagerAlert, Silence, SilenceState } from 'app/plugins/datasource/alertmanager/types';
import { useDispatch } from 'app/types';

View File

@ -3,9 +3,8 @@ import React from 'react';
import SVG from 'react-inlinesvg';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { EmbeddedScene, SceneFlexLayout, SceneFlexItem, SceneReactObject } from '@grafana/scenes';
import { Icon, useStyles2, useTheme2 } from '@grafana/ui';
import { Icon, useStyles2, useTheme2, Stack } from '@grafana/ui';
export const getOverviewScene = () => {
return new EmbeddedScene({
@ -48,7 +47,7 @@ export default function GettingStarted({ showWelcomeHeader }: { showWelcomeHeade
</ContentBox>
<ContentBox className={styles.gettingStartedBlock}>
<h3>Get started</h3>
<Stack direction="column" alignItems="space-between">
<Stack direction="column">
<ul className={styles.list}>
<li>
<strong>Create an alert rule</strong> by adding queries and expressions from multiple data sources.

View File

@ -4,7 +4,6 @@ import React, { useState } from 'react';
import { useFormContext } from 'react-hook-form';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import {
Button,
Field,
@ -17,6 +16,7 @@ import {
Select,
Tooltip,
useStyles2,
Stack,
} from '@grafana/ui';
import { getSupportedTransTypeDetails, getTransformOptions } from './types';
@ -56,7 +56,7 @@ export const TransformationsEditor = (props: Props) => {
<div>
{fields.map((fieldVal, index) => {
return (
<Stack direction="row" key={fieldVal.id} alignItems="top">
<Stack direction="row" key={fieldVal.id} alignItems="flex-start">
<Field
label={
<Stack gap={0.5}>

View File

@ -10,7 +10,6 @@ import {
SelectableValue,
} from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { Stack } from '@grafana/experimental';
import { getDataSourceSrv, locationService } from '@grafana/runtime';
import { AnnotationPanelFilter } from '@grafana/schema/src/raw/dashboard/x/dashboard_types.gen';
import {
@ -23,6 +22,7 @@ import {
MultiSelect,
Select,
useStyles2,
Stack,
} from '@grafana/ui';
import { ColorValueEditor } from 'app/core/components/OptionsUI/color';
import config from 'app/core/config';

View File

@ -3,7 +3,6 @@ import React, { useMemo, useEffect } from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
import { PanelPlugin, GrafanaTheme2, FeatureState } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { config } from '@grafana/runtime';
import {
Drawer,
@ -21,6 +20,7 @@ import {
Select,
ClipboardButton,
Icon,
Stack,
} from '@grafana/ui';
import { contextSrv } from 'app/core/services/context_srv';
import { PanelModel } from 'app/features/dashboard/state';

View File

@ -6,7 +6,6 @@ import { Subscription } from 'rxjs';
import { FieldConfigSource, GrafanaTheme2, NavModel, NavModelItem, PageLayoutType } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { Stack } from '@grafana/experimental';
import { locationService } from '@grafana/runtime';
import {
Button,
@ -19,6 +18,7 @@ import {
ToolbarButton,
ToolbarButtonRow,
withTheme2,
Stack,
} from '@grafana/ui';
import { AppChromeUpdate } from 'app/core/components/AppChrome/AppChromeUpdate';
import { Page } from 'app/core/components/Page/Page';

View File

@ -3,10 +3,9 @@ import React, { useMemo, useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { Stack } from '@grafana/experimental';
import { config } from '@grafana/runtime';
import { Dashboard } from '@grafana/schema';
import { Button, Checkbox, Form, TextArea, useStyles2 } from '@grafana/ui';
import { Button, Checkbox, Form, TextArea, useStyles2, Stack } from '@grafana/ui';
import { DashboardModel } from 'app/features/dashboard/state';
import { GenAIDashboardChangesButton } from '../../GenAI/GenAIDashboardChangesButton';

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import { saveAs } from 'file-saver';
import React, { useCallback, useState } from 'react';
import { Stack } from '@grafana/experimental';
import { Button, ClipboardButton, HorizontalGroup, TextArea } from '@grafana/ui';
import { Button, ClipboardButton, HorizontalGroup, TextArea, Stack } from '@grafana/ui';
import { SaveDashboardFormProps } from '../types';

View File

@ -1,7 +1,6 @@
import React from 'react';
import { Stack } from '@grafana/experimental';
import { Tooltip, Button } from '@grafana/ui';
import { Tooltip, Button, Stack } from '@grafana/ui';
type VersionsButtonsType = {
hasMore: boolean;

View File

@ -2,8 +2,7 @@ import { css, cx } from '@emotion/css';
import React, { FormEvent } from 'react';
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Button, ButtonSelect, Icon, InlineFieldRow, Input, Select, useStyles2 } from '@grafana/ui';
import { Button, ButtonSelect, Icon, InlineFieldRow, Input, Select, useStyles2, Stack } from '@grafana/ui';
import alertDef, { EvalFunction } from '../../alerting/state/alertDef';
import { ClassicCondition, ReducerType } from '../types';
@ -73,7 +72,7 @@ export const Condition = ({ condition, index, onChange, onRemoveCondition, refId
condition.evaluator.type === EvalFunction.IsWithinRange || condition.evaluator.type === EvalFunction.IsOutsideRange;
return (
<Stack direction="row">
<Stack>
<div style={{ flex: 1 }}>
<InlineFieldRow>
{index === 0 ? (

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React, { ChangeEvent } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Icon, InlineField, InlineLabel, TextArea, Toggletip, useStyles2 } from '@grafana/ui';
import { Icon, InlineField, InlineLabel, TextArea, Toggletip, useStyles2, Stack } from '@grafana/ui';
import { ExpressionQuery } from '../types';
@ -32,7 +31,7 @@ export const Math = ({ labelWidth, onChange, query, onRunQuery }: Props) => {
};
return (
<Stack direction="row">
<Stack>
<InlineField
label={
<InlineLabel width="auto">

View File

@ -4,9 +4,8 @@ import { Subscription } from 'rxjs';
import { LoadingState, PanelData } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { Stack } from '@grafana/experimental';
import { config } from '@grafana/runtime';
import { Button, ClipboardButton, JSONFormatter, LoadingPlaceholder } from '@grafana/ui';
import { Button, ClipboardButton, JSONFormatter, LoadingPlaceholder, Stack } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { backendSrv } from 'app/core/services/backend_srv';

View File

@ -1,7 +1,6 @@
import React from 'react';
import { locationUtil, SelectableValue } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { locationService } from '@grafana/runtime';
import {
Button,
@ -17,6 +16,7 @@ import {
TextLink,
Tooltip,
Label,
Stack,
} from '@grafana/ui';
import { getConfig } from 'app/core/config';
import { OrgRole, useDispatch } from 'app/types';

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { useStyles2, Icon } from '@grafana/ui';
import { useStyles2, Icon, Stack } from '@grafana/ui';
import { Version, CatalogPlugin, PluginIconName } from '../types';

View File

@ -7,8 +7,7 @@ import {
onUpdateDatasourceSecureJsonDataOption,
updateDatasourcePluginResetOption,
} from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Field, Icon, Label, SecretTextArea, Tooltip } from '@grafana/ui';
import { Field, Icon, Label, SecretTextArea, Tooltip, Stack } from '@grafana/ui';
export interface Props<T extends DataSourceJsonData, S> {
editorProps: DataSourcePluginOptionsEditorProps<T, S>;

View File

@ -2,8 +2,7 @@
import React from 'react';
import { useAsync } from 'react-use';
import { Stack } from '@grafana/experimental';
import { Card } from '@grafana/ui';
import { Card, Stack } from '@grafana/ui';
import { Page } from 'app/core/components/Page/Page';
// Types

View File

@ -16,8 +16,7 @@ import {
GroupByOperationID,
GroupByTransformerOptions,
} from '@grafana/data/src/transformations/transformers/groupBy';
import { Stack } from '@grafana/experimental';
import { useTheme2, Select, StatsPicker, InlineField } from '@grafana/ui';
import { useTheme2, Select, StatsPicker, InlineField, Stack } from '@grafana/ui';
import { useAllFieldNamesFromDataFrames } from '../utils';
@ -84,7 +83,7 @@ export const GroupByFieldConfiguration = ({ fieldName, config, onConfigChange }:
return (
<InlineField className={styles.label} label={fieldName} grow shrink>
<Stack gap={0.5} direction="row" wrap={false}>
<Stack gap={0.5} direction="row">
<div className={styles.operation}>
<Select options={options} value={config?.operation} placeholder="Ignored" onChange={onChange} isClearable />
</div>

View File

@ -12,8 +12,7 @@ import {
LabelsToFieldsMode,
LabelsToFieldsOptions,
} from '@grafana/data/src/transformations/transformers/labelsToFields';
import { Stack } from '@grafana/experimental';
import { InlineField, InlineFieldRow, RadioButtonGroup, Select, FilterPill } from '@grafana/ui';
import { InlineField, InlineFieldRow, RadioButtonGroup, Select, FilterPill, Stack } from '@grafana/ui';
const modes: Array<SelectableValue<LabelsToFieldsMode>> = [
{ value: LabelsToFieldsMode.Columns, label: 'Columns' },
@ -81,7 +80,7 @@ export const LabelsAsFieldsTransformerEditor = ({
</InlineFieldRow>
<InlineFieldRow>
<InlineField label={'Labels'} labelWidth={labelWidth}>
<Stack gap={1} wrap>
<Stack gap={1} wrap={'wrap'}>
{labelNames.map((o, i) => {
const label = o.label!;
return (

View File

@ -3,9 +3,8 @@ import React, { ReactElement } from 'react';
import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd';
import { selectors } from '@grafana/e2e-selectors';
import { Stack } from '@grafana/experimental';
import { reportInteraction } from '@grafana/runtime';
import { Button, useStyles2 } from '@grafana/ui';
import { Button, useStyles2, Stack } from '@grafana/ui';
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
import { VariablesDependenciesButton } from '../inspect/VariablesDependenciesButton';

View File

@ -1,7 +1,7 @@
import React from 'react';
import { MetadataInspectorProps } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Stack } from '@grafana/ui';
import { TestData } from './dataquery.gen';
import { TestDataDataSource } from './datasource';

View File

@ -1,6 +1,6 @@
import React from 'react';
import { Stack } from '@grafana/experimental';
import { Stack } from '@grafana/ui';
import { OperationExplainedBox } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationExplainedBox';
import { OperationListExplained } from 'app/plugins/datasource/prometheus/querybuilder/shared/OperationListExplained';
import { RawQuery } from 'app/plugins/datasource/prometheus/querybuilder/shared/RawQuery';

View File

@ -1,6 +1,6 @@
import React from 'react';
import { Stack } from '@grafana/experimental';
import { Stack } from '@grafana/ui';
import { LokiDatasource } from '../../datasource';
import { LokiVisualQuery, LokiVisualQueryBinary } from '../types';

View File

@ -1,6 +1,6 @@
import React from 'react';
import { Stack } from '@grafana/experimental';
import { Stack } from '@grafana/ui';
import { PrometheusDatasource } from '../../datasource';
import { PromVisualQuery, PromVisualQueryBinary } from '../types';

View File

@ -1,6 +1,6 @@
import React from 'react';
import { Stack } from '@grafana/experimental';
import { Stack } from '@grafana/ui';
import promqlGrammar from '../../promql';
import { promQueryModeller } from '../PromQueryModeller';

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Icon, useStyles2 } from '@grafana/ui';
import { Icon, useStyles2, Stack } from '@grafana/ui';
export interface Props {
feedbackUrl?: string;

View File

@ -3,8 +3,7 @@ import React, { useEffect, useId, useState } from 'react';
import { Draggable } from 'react-beautiful-dnd';
import { DataSourceApi, GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Button, Icon, InlineField, Tooltip, useTheme2 } from '@grafana/ui';
import { Button, Icon, InlineField, Tooltip, useTheme2, Stack } from '@grafana/ui';
import { isConflictingFilter } from 'app/plugins/datasource/loki/querybuilder/operationUtils';
import { LokiOperationId } from 'app/plugins/datasource/loki/querybuilder/types';
@ -96,7 +95,7 @@ export function OperationEditor({
</div>
)}
<div className={styles.paramValue}>
<Stack gap={0.5} direction="row" alignItems="center" wrap={false}>
<Stack gap={0.5} direction="row" alignItems="center">
<Editor
index={paramIndex}
paramDef={paramDef}

View File

@ -4,8 +4,7 @@ import { DragDropContext, Droppable, DropResult } from 'react-beautiful-dnd';
import { useMountedState, usePrevious } from 'react-use';
import { DataSourceApi, GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Button, Cascader, CascaderOption, useStyles2 } from '@grafana/ui';
import { Button, Cascader, CascaderOption, useStyles2, Stack } from '@grafana/ui';
import { OperationEditor } from './OperationEditor';
import { QueryBuilderOperation, QueryWithOperations, VisualQueryModeller } from './types';

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React, { ComponentType } from 'react';
import { GrafanaTheme2, SelectableValue, toOption } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { AutoSizeInput, Button, Checkbox, Select, useStyles2 } from '@grafana/ui';
import { AutoSizeInput, Button, Checkbox, Select, useStyles2, Stack } from '@grafana/ui';
import { QueryBuilderOperationParamDef, QueryBuilderOperationParamEditorProps } from '../shared/types';
@ -97,7 +96,7 @@ function SelectInputParamEditor({
}
return (
<Stack gap={0.5} direction="row" alignItems="center" wrap={false}>
<Stack gap={0.5} direction="row" alignItems="center">
<Select
id={getOperationParamId(operationId, index)}
value={valueOption}

View File

@ -2,8 +2,7 @@ import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { useStyles2 } from '@grafana/ui';
import { useStyles2, Stack } from '@grafana/ui';
interface Props {
children: React.ReactNode;

View File

@ -3,8 +3,7 @@ import { uniqueId } from 'lodash';
import React, { HTMLProps, useRef } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Switch, useStyles2 } from '@grafana/ui';
import { Switch, useStyles2, Stack } from '@grafana/ui';
export interface Props extends Omit<HTMLProps<HTMLInputElement>, 'value' | 'ref'> {
value?: boolean;

View File

@ -3,9 +3,8 @@ import React from 'react';
import { useToggle } from 'react-use';
import { getValueFormat, GrafanaTheme2 } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { config } from '@grafana/runtime';
import { Collapse, Icon, Tooltip, useStyles2 } from '@grafana/ui';
import { Collapse, Icon, Tooltip, useStyles2, Stack } from '@grafana/ui';
import { QueryStats } from 'app/plugins/datasource/loki/types';
export interface Props {
@ -27,7 +26,7 @@ export function QueryOptionGroup({ title, children, collapsedInfo, queryStats }:
isOpen={isOpen}
onToggle={toggleOpen}
label={
<Stack gap={0} wrap={false}>
<Stack gap={0}>
<h6 className={styles.title}>{title}</h6>
{!isOpen && (
<div className={styles.description}>

View File

@ -3,8 +3,7 @@ import React from 'react';
import { useLocation } from 'react-use';
import { GrafanaTheme2, intervalToAbbreviatedDurationString } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { Icon, useStyles2 } from '@grafana/ui';
import { Icon, useStyles2, Stack } from '@grafana/ui';
import alertDef from 'app/features/alerting/state/alertDef';
import { Spacer } from 'app/features/alerting/unified/components/Spacer';
import { fromCombinedRule, stringifyIdentifier } from 'app/features/alerting/unified/utils/rule-id';
@ -84,7 +83,7 @@ const UngroupedModeView = ({ rules, options, handleInstancesLimit, limitInstance
</div>
<div className={styles.alertNameWrapper}>
<div className={styles.instanceDetails}>
<Stack direction="row" gap={1} wrap={false}>
<Stack direction="row" gap={1}>
<div className={styles.alertName} title={ruleWithLocation.name}>
{ruleWithLocation.name}
</div>

View File

@ -1,9 +1,8 @@
import React from 'react';
import { SelectableValue } from '@grafana/data';
import { Stack } from '@grafana/experimental';
import { BarGaugeDisplayMode, BarGaugeValueMode, TableBarGaugeCellOptions } from '@grafana/schema';
import { Field, RadioButtonGroup } from '@grafana/ui';
import { Field, RadioButtonGroup, Stack } from '@grafana/ui';
import { TableCellEditorProps } from '../TableCellOptionEditor';