diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts
index 766c4dbf36d..24e61fd2841 100644
--- a/packages/grafana-e2e-selectors/src/selectors/components.ts
+++ b/packages/grafana-e2e-selectors/src/selectors/components.ts
@@ -1288,6 +1288,9 @@ export const versionedComponents = {
submit: {
[MIN_GRAFANA_VERSION]: 'data-testid-import-dashboard-submit',
},
+ floatGridItemsWarning: {
+ [MIN_GRAFANA_VERSION]: 'data-testid-import-dashboard-float-grid-items-warning',
+ },
},
PanelAlertTabContent: {
content: {
diff --git a/public/app/features/manage-dashboards/import/components/ImportDashboardFormV2.test.tsx b/public/app/features/manage-dashboards/import/components/ImportDashboardFormV2.test.tsx
new file mode 100644
index 00000000000..c6ac4ce9d96
--- /dev/null
+++ b/public/app/features/manage-dashboards/import/components/ImportDashboardFormV2.test.tsx
@@ -0,0 +1,113 @@
+import { render, screen } from '@testing-library/react';
+
+import { selectors } from '@grafana/e2e-selectors';
+import { defaultSpec, Spec as DashboardV2Spec } from '@grafana/schema/dist/esm/schema/dashboard/v2';
+import { Form } from 'app/core/components/Form/Form';
+
+import { DashboardInputs, InputType, ImportFormDataV2 } from '../../types';
+
+import { ImportDashboardFormV2 } from './ImportDashboardFormV2';
+
+const mockInputs: DashboardInputs = {
+ dataSources: [
+ {
+ name: 'Prometheus',
+ label: 'Prometheus',
+ pluginId: 'prometheus',
+ type: InputType.DataSource,
+ description: 'Select a Prometheus data source',
+ info: 'Select prometheus',
+ value: '',
+ },
+ {
+ name: 'Loki',
+ label: 'Loki',
+ pluginId: 'loki',
+ type: InputType.DataSource,
+ description: 'Select a Loki data source',
+ info: 'Select loki',
+ value: '',
+ },
+ ],
+ constants: [],
+ libraryPanels: [],
+};
+
+jest.mock('../utils/validation', () => ({
+ validateTitle: jest.fn().mockResolvedValue(true),
+}));
+
+jest.mock('app/core/components/Select/FolderPicker', () => ({
+ FolderPicker: ({ value, onChange }: { value: string; onChange: (val: string, title: string) => void }) => (
+ onChange(e.target.value, 'Test Folder')} />
+ ),
+}));
+
+jest.mock('app/features/datasources/components/picker/DataSourcePicker', () => ({
+ DataSourcePicker: ({
+ onChange,
+ pluginId,
+ current,
+ }: {
+ onChange: (ds: { uid: string; type: string; name: string }) => void;
+ pluginId: string;
+ current?: { uid: string; type: string };
+ }) => (
+
+ onChange({
+ uid: e.target.value,
+ type: pluginId,
+ name: `${pluginId} instance`,
+ })
+ }
+ />
+ ),
+}));
+
+describe('ImportDashboardFormV2', () => {
+ const mockOnCancel = jest.fn();
+ const mockOnSubmit = jest.fn();
+
+ function renderForm(hasFloatGridItems = false, inputs: DashboardInputs = mockInputs) {
+ const defaultDashboard: DashboardV2Spec = defaultSpec();
+ return render(
+
+ );
+ }
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it('renders float grid items warning when hasFloatGridItems is true', () => {
+ renderForm(true);
+ expect(screen.queryByTestId(selectors.components.ImportDashboardForm.floatGridItemsWarning)).toBeInTheDocument();
+ });
+
+ it('does not render float grid items warning when hasFloatGridItems is false', () => {
+ renderForm(false);
+ expect(
+ screen.queryByTestId(selectors.components.ImportDashboardForm.floatGridItemsWarning)
+ ).not.toBeInTheDocument();
+ });
+});
diff --git a/public/app/features/manage-dashboards/import/components/ImportDashboardFormV2.tsx b/public/app/features/manage-dashboards/import/components/ImportDashboardFormV2.tsx
index 3d5899dda98..ac604a49f1d 100644
--- a/public/app/features/manage-dashboards/import/components/ImportDashboardFormV2.tsx
+++ b/public/app/features/manage-dashboards/import/components/ImportDashboardFormV2.tsx
@@ -4,7 +4,7 @@ import { Controller, FieldErrors, FieldPath, UseFormReturn } from 'react-hook-fo
import { selectors } from '@grafana/e2e-selectors';
import { Trans, t } from '@grafana/i18n';
import { ExpressionDatasourceRef } from '@grafana/runtime/internal';
-import { Button, Field, FormFieldErrors, FormsOnSubmit, Stack, Input } from '@grafana/ui';
+import { Button, Field, FormFieldErrors, FormsOnSubmit, Stack, Input, Alert } from '@grafana/ui';
import { FolderPicker } from 'app/core/components/Select/FolderPicker';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
@@ -16,9 +16,19 @@ interface Props extends Pick, 'register' | 'cont
errors: FieldErrors;
onCancel: () => void;
onSubmit: FormsOnSubmit;
+ hasFloatGridItems: boolean;
}
-export const ImportDashboardFormV2 = ({ register, errors, control, inputs, getValues, onCancel, onSubmit }: Props) => {
+export const ImportDashboardFormV2 = ({
+ register,
+ errors,
+ control,
+ inputs,
+ getValues,
+ onCancel,
+ onSubmit,
+ hasFloatGridItems,
+}: Props) => {
const [isSubmitted, setSubmitted] = useState(false);
const [selectedDataSources, setSelectedDataSources] = useState>({});
@@ -119,6 +129,19 @@ export const ImportDashboardFormV2 = ({ register, errors, control, inputs, getVa
);
})}
+ {hasFloatGridItems && (
+
+
+ The dashboard contains grid items with floating positions. This is not supported by Grafana and the numbers
+ will be truncated to integers.
+
+
+ )}
+