{"version":3,"file":"6263.a73b1b322df478919fca.js","mappings":"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","sources":["webpack://grafana/./public/app/core/components/Form/Form.tsx","webpack://grafana/./public/app/features/dashboard/components/DashboardLoading/DashboardFailed.tsx","webpack://grafana/./public/app/features/dashboard/components/DashboardLoading/DashboardLoading.tsx","webpack://grafana/./public/app/features/dashboard/components/AddLibraryPanelWidget/AddLibraryPanelWidget.tsx","webpack://grafana/./public/app/features/dashboard/components/RowOptions/RowOptionsForm.tsx","webpack://grafana/./public/app/features/dashboard/components/RowOptions/RowOptionsModal.tsx","webpack://grafana/./public/app/features/dashboard/components/RowOptions/RowOptionsButton.tsx","webpack://grafana/./public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx","webpack://grafana/./public/app/features/dashboard/dashgrid/DashboardGrid.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport { HTMLProps, useEffect } from 'react';\nimport * as React from 'react';\nimport {\n  useForm,\n  Mode,\n  DefaultValues,\n  SubmitHandler,\n  FieldValues,\n  UseFormReturn,\n  FieldErrors,\n  FieldPath,\n} from 'react-hook-form';\n\nexport type FormAPI<T extends FieldValues> = Omit<UseFormReturn<T>, 'handleSubmit'> & {\n  errors: FieldErrors<T>;\n};\n\ninterface FormProps<T extends FieldValues> extends Omit<HTMLProps<HTMLFormElement>, 'onSubmit' | 'children'> {\n  validateOn?: Mode;\n  validateOnMount?: boolean;\n  validateFieldsOnMount?: FieldPath<T> | Array<FieldPath<T>>;\n  defaultValues?: DefaultValues<T>;\n  onSubmit: SubmitHandler<T>;\n  children: (api: FormAPI<T>) => React.ReactNode;\n  /** Sets max-width for container. Use it instead of setting individual widths on inputs.*/\n  maxWidth?: number | 'none';\n}\n\nexport function Form<T extends FieldValues>({\n  defaultValues,\n  onSubmit,\n  validateOnMount = false,\n  validateFieldsOnMount,\n  children,\n  validateOn = 'onSubmit',\n  maxWidth = 600,\n  ...htmlProps\n}: FormProps<T>) {\n  const { handleSubmit, trigger, formState, ...rest } = useForm<T>({\n    mode: validateOn,\n    defaultValues,\n  });\n\n  useEffect(() => {\n    if (validateOnMount) {\n      trigger(validateFieldsOnMount);\n    }\n  }, [trigger, validateFieldsOnMount, validateOnMount]);\n\n  return (\n    <form\n      className={css({\n        maxWidth: maxWidth !== 'none' ? maxWidth + 'px' : maxWidth,\n        width: '100%',\n      })}\n      onSubmit={handleSubmit(onSubmit)}\n      {...htmlProps}\n    >\n      {children({ errors: formState.errors, formState, trigger, ...rest })}\n    </form>\n  );\n}\n","import { css } from '@emotion/css';\n\nimport { Alert } from '@grafana/ui';\nimport { getMessageFromError } from 'app/core/utils/errors';\nimport { DashboardInitError, AppNotificationSeverity } from 'app/types';\n\nexport interface Props {\n  initError?: DashboardInitError;\n}\n\nexport const DashboardFailed = ({ initError }: Props) => {\n  if (!initError) {\n    return null;\n  }\n\n  return (\n    <div className={styles.dashboardLoading}>\n      <Alert severity={AppNotificationSeverity.Error} title={initError.message}>\n        {getMessageFromError(initError.error)}\n      </Alert>\n    </div>\n  );\n};\n\nexport const styles = {\n  dashboardLoading: css({\n    height: '60vh',\n    display: 'flex',\n    alignItems: 'center',\n    justifyContent: 'center',\n  }),\n};\n","import { css, keyframes } from '@emotion/css';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { locationService } from '@grafana/runtime';\nimport { Button, HorizontalGroup, Spinner, useStyles2, VerticalGroup } from '@grafana/ui';\nimport { DashboardInitPhase } from 'app/types';\n\nexport interface Props {\n  initPhase: DashboardInitPhase;\n}\n\nexport const DashboardLoading = ({ initPhase }: Props) => {\n  const styles = useStyles2(getStyles);\n  const cancelVariables = () => {\n    locationService.push('/');\n  };\n\n  return (\n    <div className={styles.dashboardLoading}>\n      <div className={styles.dashboardLoadingText}>\n        <VerticalGroup spacing=\"md\">\n          <HorizontalGroup align=\"center\" justify=\"center\" spacing=\"xs\">\n            <Spinner inline={true} /> {initPhase}\n          </HorizontalGroup>{' '}\n          <HorizontalGroup align=\"center\" justify=\"center\">\n            <Button variant=\"secondary\" size=\"md\" icon=\"repeat\" onClick={cancelVariables}>\n              Cancel loading dashboard\n            </Button>\n          </HorizontalGroup>\n        </VerticalGroup>\n      </div>\n    </div>\n  );\n};\n\nexport const getStyles = (theme: GrafanaTheme2) => {\n  // Amount of time we want to pass before we start showing loading spinner\n  const slowStartThreshold = '0.5s';\n\n  const invisibleToVisible = keyframes`\n    0% { opacity: 0%; }\n    100% { opacity: 100%; }\n  `;\n\n  return {\n    dashboardLoading: css({\n      height: '60vh',\n      display: 'flex',\n      opacity: '0%',\n      alignItems: 'center',\n      justifyContent: 'center',\n      [theme.transitions.handleMotion('no-preference', 'reduce')]: {\n        animation: `${invisibleToVisible} 0s step-end ${slowStartThreshold} 1 normal forwards`,\n      },\n    }),\n    dashboardLoadingText: css({\n      fontSize: theme.typography.h4.fontSize,\n    }),\n  };\n};\n","import { css, cx, keyframes } from '@emotion/css';\nimport * as React from 'react';\nimport tinycolor from 'tinycolor2';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { LibraryPanel } from '@grafana/schema';\nimport { IconButton, useStyles2 } from '@grafana/ui';\nimport { Trans } from 'app/core/internationalization';\n\nimport {\n  LibraryPanelsSearch,\n  LibraryPanelsSearchVariant,\n} from '../../../library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch';\nimport { DashboardModel, PanelModel } from '../../state';\n\ninterface Props {\n  panel: PanelModel;\n  dashboard: DashboardModel;\n}\n\nexport const AddLibraryPanelWidget = ({ panel, dashboard }: Props) => {\n  const onCancelAddPanel = (evt: React.MouseEvent<HTMLButtonElement>) => {\n    evt.preventDefault();\n    dashboard.removePanel(panel);\n  };\n\n  const onAddLibraryPanel = (panelInfo: LibraryPanel) => {\n    const { gridPos } = panel;\n\n    const newPanel = {\n      ...panelInfo.model,\n      gridPos,\n      libraryPanel: panelInfo,\n    };\n\n    dashboard.addPanel(newPanel);\n    dashboard.removePanel(panel);\n  };\n\n  const styles = useStyles2(getStyles);\n\n  return (\n    <div className={styles.wrapper}>\n      <div className={styles.callToAction}>\n        <div className={cx(styles.headerRow, 'grid-drag-handle')}>\n          <span>\n            <Trans i18nKey=\"library-panel.add-widget.title\">Add panel from panel library</Trans>\n          </span>\n          <div className=\"flex-grow-1\" />\n          <IconButton\n            aria-label=\"Close 'Add Panel' widget\"\n            name=\"times\"\n            onClick={onCancelAddPanel}\n            tooltip=\"Close widget\"\n          />\n        </div>\n        <LibraryPanelsSearch onClick={onAddLibraryPanel} variant={LibraryPanelsSearchVariant.Tight} showPanelFilter />\n      </div>\n    </div>\n  );\n};\n\nconst getStyles = (theme: GrafanaTheme2) => {\n  const pulsate = keyframes({\n    '0%': {\n      boxShadow: `0 0 0 2px ${theme.colors.background.canvas}, 0 0 0px 4px ${theme.colors.primary.main}`,\n    },\n    '50%': {\n      boxShadow: `0 0 0 2px ${theme.components.dashboard.background}, 0 0 0px 4px ${tinycolor(theme.colors.primary.main)\n        .darken(20)\n        .toHexString()}`,\n    },\n    '100%': {\n      boxShadow: `0 0 0 2px ${theme.components.dashboard.background}, 0 0 0px 4px  ${theme.colors.primary.main}`,\n    },\n  });\n\n  return {\n    // wrapper is used to make sure box-shadow animation isn't cut off in dashboard page\n    wrapper: css({\n      height: '100%',\n      paddingTop: `${theme.spacing(0.5)}`,\n    }),\n    headerRow: css({\n      display: 'flex',\n      alignItems: 'center',\n      height: '38px',\n      flexShrink: 0,\n      width: '100%',\n      fontSize: theme.typography.fontSize,\n      fontWeight: theme.typography.fontWeightMedium,\n      paddingLeft: `${theme.spacing(1)}`,\n      [theme.transitions.handleMotion('no-preference', 'reduce')]: {\n        transition: 'background-color 0.1s ease-in-out',\n      },\n      cursor: 'move',\n\n      '&:hover': {\n        background: `${theme.colors.background.secondary}`,\n      },\n    }),\n    callToAction: css({\n      backgroundColor: theme.components.panel.background,\n      border: `1px solid ${theme.components.panel.borderColor}`,\n      borderRadius: theme.shape.radius.default,\n      display: 'flex',\n      flex: '1 1 0',\n      flexDirection: 'column',\n      height: '100%',\n      position: 'relative',\n      width: '100%',\n      outline: '2px dotted transparent',\n      outlineOffset: '2px',\n      overflow: 'hidden',\n\n      [theme.transitions.handleMotion('no-preference', 'reduce')]: {\n        animation: `${pulsate} 2s ease infinite`,\n      },\n    }),\n  };\n};\n","import { useCallback, useState } from 'react';\nimport * as React from 'react';\n\nimport { selectors } from '@grafana/e2e-selectors';\nimport { Button, Field, Modal, Input, Alert } from '@grafana/ui';\nimport { Form } from 'app/core/components/Form/Form';\n\nimport { RepeatRowSelect } from '../RepeatRowSelect/RepeatRowSelect';\n\nexport type OnRowOptionsUpdate = (title: string, repeat?: string | null) => void;\n\nexport interface Props {\n  title: string;\n  repeat?: string;\n  onUpdate: OnRowOptionsUpdate;\n  onCancel: () => void;\n  warning?: React.ReactNode;\n}\n\nexport const RowOptionsForm = ({ repeat, title, warning, onUpdate, onCancel }: Props) => {\n  const [newRepeat, setNewRepeat] = useState<string | undefined>(repeat);\n  const onChangeRepeat = useCallback((name?: string) => setNewRepeat(name), [setNewRepeat]);\n\n  return (\n    <Form\n      defaultValues={{ title }}\n      onSubmit={(formData: { title: string }) => {\n        onUpdate(formData.title, newRepeat);\n      }}\n    >\n      {({ register }) => (\n        <>\n          <Field label=\"Title\">\n            <Input {...register('title')} type=\"text\" />\n          </Field>\n          <Field label=\"Repeat for\">\n            <RepeatRowSelect repeat={newRepeat} onChange={onChangeRepeat} />\n          </Field>\n          {warning && (\n            <Alert\n              data-testid={selectors.pages.Dashboard.Rows.Repeated.ConfigSection.warningMessage}\n              severity=\"warning\"\n              title=\"\"\n              topSpacing={3}\n              bottomSpacing={0}\n            >\n              {warning}\n            </Alert>\n          )}\n          <Modal.ButtonRow>\n            <Button type=\"button\" variant=\"secondary\" onClick={onCancel} fill=\"outline\">\n              Cancel\n            </Button>\n            <Button type=\"submit\">Update</Button>\n          </Modal.ButtonRow>\n        </>\n      )}\n    </Form>\n  );\n};\n","import { css } from '@emotion/css';\nimport * as React from 'react';\n\nimport { Modal, useStyles2 } from '@grafana/ui';\n\nimport { OnRowOptionsUpdate, RowOptionsForm } from './RowOptionsForm';\n\nexport interface RowOptionsModalProps {\n  title: string;\n  repeat?: string;\n  warning?: React.ReactNode;\n  onDismiss: () => void;\n  onUpdate: OnRowOptionsUpdate;\n}\n\nexport const RowOptionsModal = ({ repeat, title, onDismiss, onUpdate, warning }: RowOptionsModalProps) => {\n  const styles = useStyles2(getStyles);\n\n  return (\n    <Modal isOpen={true} title=\"Row options\" icon=\"copy\" onDismiss={onDismiss} className={styles.modal}>\n      <RowOptionsForm repeat={repeat} title={title} onCancel={onDismiss} onUpdate={onUpdate} warning={warning} />\n    </Modal>\n  );\n};\n\nconst getStyles = () => ({\n  modal: css({\n    label: 'RowOptionsModal',\n    width: '500px',\n  }),\n});\n","import * as React from 'react';\n\nimport { Icon, ModalsController } from '@grafana/ui';\n\nimport { OnRowOptionsUpdate } from './RowOptionsForm';\nimport { RowOptionsModal } from './RowOptionsModal';\n\nexport interface RowOptionsButtonProps {\n  title: string;\n  repeat?: string;\n  onUpdate: OnRowOptionsUpdate;\n  warning?: React.ReactNode;\n}\n\nexport const RowOptionsButton = ({ repeat, title, onUpdate, warning }: RowOptionsButtonProps) => {\n  const onUpdateChange = (hideModal: () => void) => (title: string, repeat?: string | null) => {\n    onUpdate(title, repeat);\n    hideModal();\n  };\n\n  return (\n    <ModalsController>\n      {({ showModal, hideModal }) => {\n        return (\n          <button\n            type=\"button\"\n            className=\"pointer\"\n            aria-label=\"Row options\"\n            onClick={() => {\n              showModal(RowOptionsModal, {\n                title,\n                repeat,\n                onDismiss: hideModal,\n                onUpdate: onUpdateChange(hideModal),\n                warning,\n              });\n            }}\n          >\n            <Icon name=\"cog\" />\n          </button>\n        );\n      }}\n    </ModalsController>\n  );\n};\n\nRowOptionsButton.displayName = 'RowOptionsButton';\n","import { css, cx } from '@emotion/css';\nimport { indexOf } from 'lodash';\nimport { Component } from 'react';\nimport { Unsubscribable } from 'rxjs';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { getTemplateSrv, RefreshEvent } from '@grafana/runtime';\nimport { Icon, TextLink, Themeable2, withTheme2 } from '@grafana/ui';\nimport appEvents from 'app/core/app_events';\nimport { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard/types';\n\nimport { ShowConfirmModalEvent } from '../../../../types/events';\nimport { DashboardModel } from '../../state/DashboardModel';\nimport { PanelModel } from '../../state/PanelModel';\nimport { RowOptionsButton } from '../RowOptions/RowOptionsButton';\n\nexport interface DashboardRowProps extends Themeable2 {\n  panel: PanelModel;\n  dashboard: DashboardModel;\n}\n\nexport class UnthemedDashboardRow extends Component<DashboardRowProps> {\n  sub?: Unsubscribable;\n\n  componentDidMount() {\n    this.sub = this.props.dashboard.events.subscribe(RefreshEvent, this.onVariableUpdated);\n  }\n\n  componentWillUnmount() {\n    if (this.sub) {\n      this.sub.unsubscribe();\n    }\n  }\n\n  onVariableUpdated = () => {\n    this.forceUpdate();\n  };\n\n  onToggle = () => {\n    this.props.dashboard.toggleRow(this.props.panel);\n  };\n\n  getWarning = () => {\n    const panels = !!this.props.panel.panels?.length\n      ? this.props.panel.panels\n      : this.props.dashboard.getRowPanels(indexOf(this.props.dashboard.panels, this.props.panel));\n    const isAnyPanelUsingDashboardDS = panels.some((p) => p.datasource?.uid === SHARED_DASHBOARD_QUERY);\n    if (isAnyPanelUsingDashboardDS) {\n      return (\n        <div>\n          <p>\n            Panels in this row use the {SHARED_DASHBOARD_QUERY} data source. These panels will reference the panel in\n            the original row, not the ones in the repeated rows.\n          </p>\n          <TextLink\n            external\n            href={\n              'https://grafana.com/docs/grafana/latest/dashboards/build-dashboards/create-dashboard/#configure-repeating-rows'\n            }\n          >\n            Learn more\n          </TextLink>\n        </div>\n      );\n    }\n\n    return undefined;\n  };\n\n  onUpdate = (title: string, repeat?: string | null) => {\n    this.props.panel.setProperty('title', title);\n    this.props.panel.setProperty('repeat', repeat ?? undefined);\n    this.props.panel.render();\n    this.props.dashboard.processRepeats();\n    this.forceUpdate();\n  };\n\n  onDelete = () => {\n    appEvents.publish(\n      new ShowConfirmModalEvent({\n        title: 'Delete row',\n        text: 'Are you sure you want to remove this row and all its panels?',\n        altActionText: 'Delete row only',\n        icon: 'trash-alt',\n        onConfirm: () => {\n          this.props.dashboard.removeRow(this.props.panel, true);\n        },\n        onAltAction: () => {\n          this.props.dashboard.removeRow(this.props.panel, false);\n        },\n      })\n    );\n  };\n\n  render() {\n    const title = getTemplateSrv().replace(this.props.panel.title, this.props.panel.scopedVars, 'text');\n    const count = this.props.panel.panels ? this.props.panel.panels.length : 0;\n    const panels = count === 1 ? 'panel' : 'panels';\n    const canEdit = this.props.dashboard.meta.canEdit === true;\n    const collapsed = this.props.panel.collapsed;\n    const styles = getStyles(this.props.theme);\n\n    return (\n      <div\n        className={cx(styles.dashboardRow, {\n          [styles.dashboardRowCollapsed]: collapsed,\n        })}\n        data-testid=\"dashboard-row-container\"\n      >\n        <button\n          aria-expanded={!collapsed}\n          className={cx(styles.title, 'pointer')}\n          type=\"button\"\n          data-testid={selectors.components.DashboardRow.title(title)}\n          onClick={this.onToggle}\n        >\n          <Icon name={collapsed ? 'angle-right' : 'angle-down'} />\n          {title}\n          <span\n            className={cx(styles.count, {\n              [styles.countCollapsed]: collapsed,\n            })}\n          >\n            ({count} {panels})\n          </span>\n        </button>\n        {canEdit && (\n          <div className={styles.actions}>\n            <RowOptionsButton\n              title={this.props.panel.title}\n              repeat={this.props.panel.repeat}\n              onUpdate={this.onUpdate}\n              warning={this.getWarning()}\n            />\n            <button type=\"button\" className=\"pointer\" onClick={this.onDelete} aria-label=\"Delete row\">\n              <Icon name=\"trash-alt\" />\n            </button>\n          </div>\n        )}\n        {collapsed === true && (\n          /* disabling the a11y rules here as the button handles keyboard interactions */\n          /* this is just to provide a better experience for mouse users */\n          /* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */\n          <div\n            className={cx({\n              [styles.toggleTargetCollapsed]: collapsed,\n            })}\n            onClick={this.onToggle}\n          >\n            &nbsp;\n          </div>\n        )}\n        {canEdit && (\n          <div\n            data-testid=\"dashboard-row-drag\"\n            className={cx(styles.dragHandle, 'grid-drag-handle', {\n              [styles.dragHandleCollapsed]: collapsed,\n            })}\n          />\n        )}\n      </div>\n    );\n  }\n}\n\nexport const DashboardRow = withTheme2(UnthemedDashboardRow);\n\nconst getStyles = (theme: GrafanaTheme2) => {\n  const actions = css({\n    color: theme.colors.text.secondary,\n    opacity: 0,\n    [theme.transitions.handleMotion('no-preference', 'reduce')]: {\n      transition: '200ms opacity ease-in 200ms',\n    },\n\n    button: {\n      color: theme.colors.text.secondary,\n      paddingLeft: theme.spacing(2),\n      background: 'transparent',\n      border: 'none',\n\n      '&:hover': {\n        color: theme.colors.text.maxContrast,\n      },\n    },\n  });\n\n  return {\n    dashboardRow: css({\n      display: 'flex',\n      alignItems: 'center',\n      height: '100%',\n\n      '&:hover, &:focus-within': {\n        [`.${actions}`]: {\n          opacity: 1,\n        },\n      },\n    }),\n    dashboardRowCollapsed: css({\n      background: theme.components.panel.background,\n    }),\n    toggleTargetCollapsed: css({\n      flex: 1,\n      cursor: 'pointer',\n      marginRight: '15px',\n    }),\n    title: css({\n      flexGrow: 0,\n      fontSize: theme.typography.h5.fontSize,\n      fontWeight: theme.typography.fontWeightMedium,\n      color: theme.colors.text.primary,\n      background: 'transparent',\n      border: 'none',\n\n      '.fa': {\n        color: theme.colors.text.secondary,\n        fontSize: theme.typography.size.xs,\n        padding: theme.spacing(0, 1),\n      },\n    }),\n    actions,\n    count: css({\n      paddingLeft: theme.spacing(2),\n      color: theme.colors.text.secondary,\n      fontStyle: 'italic',\n      fontSize: theme.typography.size.sm,\n      fontWeight: 'normal',\n      display: 'none',\n    }),\n    countCollapsed: css({\n      display: 'inline-block',\n    }),\n    dragHandle: css({\n      cursor: 'move',\n      width: '16px',\n      height: '100%',\n      background: 'url(\"public/img/grab_dark.svg\") no-repeat 50% 50%',\n      backgroundSize: '8px',\n      visibility: 'hidden',\n      position: 'absolute',\n      top: 0,\n      right: 0,\n    }),\n    dragHandleCollapsed: css({\n      visibility: 'visible',\n      opacity: 1,\n    }),\n  };\n};\n","import classNames from 'classnames';\nimport { PureComponent, CSSProperties } from 'react';\nimport * as React from 'react';\nimport ReactGridLayout, { ItemCallback } from 'react-grid-layout';\nimport { Subscription } from 'rxjs';\n\nimport { config } from '@grafana/runtime';\nimport appEvents from 'app/core/app_events';\nimport { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT } from 'app/core/constants';\nimport { contextSrv } from 'app/core/services/context_srv';\nimport { VariablesChanged } from 'app/features/variables/types';\nimport { DashboardPanelsChangedEvent } from 'app/types/events';\n\nimport { AddLibraryPanelWidget } from '../components/AddLibraryPanelWidget';\nimport { DashboardRow } from '../components/DashboardRow';\nimport { DashboardModel, PanelModel } from '../state';\nimport { GridPos } from '../state/PanelModel';\n\nimport DashboardEmpty from './DashboardEmpty';\nimport { DashboardPanel } from './DashboardPanel';\n\nexport const PANEL_FILTER_VARIABLE = 'systemPanelFilterVar';\n\nexport interface Props {\n  dashboard: DashboardModel;\n  isEditable: boolean;\n  editPanel: PanelModel | null;\n  viewPanel: PanelModel | null;\n  hidePanelMenus?: boolean;\n}\n\ninterface State {\n  panelFilter?: RegExp;\n  width: number;\n}\n\nexport class DashboardGrid extends PureComponent<Props, State> {\n  private panelMap: { [key: string]: PanelModel } = {};\n  private eventSubs = new Subscription();\n  private windowHeight = 1200;\n  private windowWidth = 1920;\n  private gridWidth = 0;\n  /** Used to keep track of mobile panel layout position */\n  private lastPanelBottom = 0;\n  private isLayoutInitialized = false;\n\n  constructor(props: Props) {\n    super(props);\n    this.state = {\n      panelFilter: undefined,\n      width: document.body.clientWidth, // initial very rough estimate\n    };\n  }\n\n  componentDidMount() {\n    const { dashboard } = this.props;\n\n    if (config.featureToggles.panelFilterVariable) {\n      // If panel filter variable is set on load then\n      // update state to filter panels\n      for (const variable of dashboard.getVariables()) {\n        if (variable.id === PANEL_FILTER_VARIABLE) {\n          if ('query' in variable) {\n            this.setPanelFilter(variable.query);\n          }\n          break;\n        }\n      }\n\n      this.eventSubs.add(\n        appEvents.subscribe(VariablesChanged, (e) => {\n          if (e.payload.variable?.id === PANEL_FILTER_VARIABLE) {\n            if ('current' in e.payload.variable) {\n              let variable = e.payload.variable.current;\n              if ('value' in variable && typeof variable.value === 'string') {\n                this.setPanelFilter(variable.value);\n              }\n            }\n          }\n        })\n      );\n    }\n\n    this.eventSubs.add(dashboard.events.subscribe(DashboardPanelsChangedEvent, this.triggerForceUpdate));\n  }\n\n  componentWillUnmount() {\n    this.eventSubs.unsubscribe();\n  }\n\n  setPanelFilter(regex: string) {\n    // Only set the panels filter if the systemPanelFilterVar variable\n    // is a non-empty string\n    let panelFilter = undefined;\n    if (regex.length > 0) {\n      panelFilter = new RegExp(regex, 'i');\n    }\n\n    this.setState({\n      panelFilter: panelFilter,\n    });\n  }\n\n  buildLayout() {\n    const layout: ReactGridLayout.Layout[] = [];\n    this.panelMap = {};\n    const { panelFilter } = this.state;\n\n    let count = 0;\n    for (const panel of this.props.dashboard.panels) {\n      if (!panel.key) {\n        panel.key = `panel-${panel.id}-${Date.now()}`;\n      }\n      this.panelMap[panel.key] = panel;\n\n      if (!panel.gridPos) {\n        console.log('panel without gridpos');\n        continue;\n      }\n\n      const panelPos: ReactGridLayout.Layout = {\n        i: panel.key,\n        x: panel.gridPos.x,\n        y: panel.gridPos.y,\n        w: panel.gridPos.w,\n        h: panel.gridPos.h,\n      };\n\n      if (panel.type === 'row') {\n        panelPos.w = GRID_COLUMN_COUNT;\n        panelPos.h = 1;\n        panelPos.isResizable = false;\n        panelPos.isDraggable = panel.collapsed;\n      }\n\n      if (!panelFilter) {\n        layout.push(panelPos);\n      } else {\n        if (panelFilter.test(panel.title)) {\n          panelPos.isResizable = false;\n          panelPos.isDraggable = false;\n          panelPos.x = (count % 2) * GRID_COLUMN_COUNT;\n          panelPos.y = Math.floor(count / 2);\n          layout.push(panelPos);\n          count++;\n        }\n      }\n    }\n\n    return layout;\n  }\n\n  onLayoutChange = (newLayout: ReactGridLayout.Layout[]) => {\n    if (this.state.panelFilter) {\n      return;\n    }\n    for (const newPos of newLayout) {\n      this.panelMap[newPos.i!].updateGridPos(newPos, this.isLayoutInitialized);\n    }\n\n    if (this.isLayoutInitialized) {\n      this.isLayoutInitialized = true;\n    }\n\n    this.props.dashboard.sortPanelsByGridPos();\n    this.forceUpdate();\n  };\n\n  triggerForceUpdate = () => {\n    this.forceUpdate();\n  };\n\n  updateGridPos = (item: ReactGridLayout.Layout, layout: ReactGridLayout.Layout[]) => {\n    this.panelMap[item.i!].updateGridPos(item);\n  };\n\n  onResize: ItemCallback = (layout, oldItem, newItem) => {\n    const panel = this.panelMap[newItem.i!];\n    panel.updateGridPos(newItem);\n  };\n\n  onResizeStop: ItemCallback = (layout, oldItem, newItem) => {\n    this.updateGridPos(newItem, layout);\n  };\n\n  onDragStop: ItemCallback = (layout, oldItem, newItem) => {\n    this.updateGridPos(newItem, layout);\n  };\n\n  getPanelScreenPos(panel: PanelModel, gridWidth: number): { top: number; bottom: number } {\n    let top = 0;\n\n    // mobile layout\n    if (gridWidth < config.theme2.breakpoints.values.md) {\n      // In mobile layout panels are stacked so we just add the panel vertical margin to the last panel bottom position\n      top = this.lastPanelBottom + GRID_CELL_VMARGIN;\n    } else {\n      // For top position we need to add back the vertical margin removed by translateGridHeightToScreenHeight\n      top = translateGridHeightToScreenHeight(panel.gridPos.y) + GRID_CELL_VMARGIN;\n    }\n\n    this.lastPanelBottom = top + translateGridHeightToScreenHeight(panel.gridPos.h);\n\n    return { top, bottom: this.lastPanelBottom };\n  }\n\n  renderPanels(gridWidth: number, isDashboardDraggable: boolean) {\n    const { panelFilter } = this.state;\n    const panelElements = [];\n\n    // Reset last panel bottom\n    this.lastPanelBottom = 0;\n\n    // This is to avoid layout re-flows, accessing window.innerHeight can trigger re-flow\n    // We assume here that if width change height might have changed as well\n    if (this.gridWidth !== gridWidth) {\n      this.windowHeight = window.innerHeight ?? 1000;\n      this.windowWidth = window.innerWidth;\n      this.gridWidth = gridWidth;\n    }\n\n    for (const panel of this.props.dashboard.panels) {\n      const panelClasses = classNames({ 'react-grid-item--fullscreen': panel.isViewing });\n\n      const p = (\n        <GrafanaGridItem\n          key={panel.key}\n          className={panelClasses}\n          data-panelid={panel.id}\n          gridPos={panel.gridPos}\n          gridWidth={gridWidth}\n          windowHeight={this.windowHeight}\n          windowWidth={this.windowWidth}\n          isViewing={panel.isViewing}\n        >\n          {(width: number, height: number) => {\n            return this.renderPanel(panel, width, height, isDashboardDraggable);\n          }}\n        </GrafanaGridItem>\n      );\n\n      if (!panelFilter) {\n        panelElements.push(p);\n      } else {\n        if (panelFilter.test(panel.title)) {\n          panelElements.push(p);\n        }\n      }\n    }\n\n    return panelElements;\n  }\n\n  renderPanel(panel: PanelModel, width: number, height: number, isDraggable: boolean) {\n    if (panel.type === 'row') {\n      return <DashboardRow key={panel.key} panel={panel} dashboard={this.props.dashboard} />;\n    }\n\n    if (panel.type === 'add-library-panel') {\n      return <AddLibraryPanelWidget key={panel.key} panel={panel} dashboard={this.props.dashboard} />;\n    }\n\n    return (\n      <DashboardPanel\n        key={panel.key}\n        stateKey={panel.key}\n        panel={panel}\n        dashboard={this.props.dashboard}\n        isEditing={panel.isEditing}\n        isViewing={panel.isViewing}\n        isDraggable={isDraggable}\n        width={width}\n        height={height}\n        hideMenu={this.props.hidePanelMenus}\n      />\n    );\n  }\n\n  /**\n   * Without this hack the move animations are triggered on initial load and all panels fly into position.\n   * This can be quite distracting and make the dashboard appear to less snappy.\n   */\n  onGetWrapperDivRef = (ref: HTMLDivElement | null) => {\n    if (ref && contextSrv.user.authenticatedBy !== 'render') {\n      setTimeout(() => {\n        ref.classList.add('react-grid-layout--enable-move-animations');\n      }, 50);\n    }\n  };\n\n  private resizeObserver?: ResizeObserver;\n  private rootEl: HTMLDivElement | null = null;\n  onMeasureRef = (rootEl: HTMLDivElement | null) => {\n    if (!rootEl) {\n      if (this.rootEl && this.resizeObserver) {\n        this.resizeObserver.unobserve(this.rootEl);\n      }\n      return;\n    }\n\n    this.rootEl = rootEl;\n    this.resizeObserver = new ResizeObserver((entries) => {\n      entries.forEach((entry) => {\n        this.setState({ width: entry.contentRect.width });\n      });\n    });\n\n    this.resizeObserver.observe(rootEl);\n  };\n\n  render() {\n    const { isEditable, dashboard } = this.props;\n    const { width } = this.state;\n\n    if (dashboard.panels.length === 0) {\n      return <DashboardEmpty dashboard={dashboard} canCreate={isEditable} />;\n    }\n\n    const draggable = width <= config.theme2.breakpoints.values.md ? false : isEditable;\n\n    // pos: rel + z-index is required to create a new stacking context to contain\n    // the escalating z-indexes of the panels\n    return (\n      <div\n        ref={this.onMeasureRef}\n        style={{\n          flex: '1 1 auto',\n          position: 'relative',\n          zIndex: 1,\n          display: this.props.editPanel ? 'none' : undefined,\n        }}\n      >\n        <div style={{ width: width, height: '100%' }} ref={this.onGetWrapperDivRef}>\n          <ReactGridLayout\n            width={width}\n            isDraggable={draggable}\n            isResizable={isEditable}\n            containerPadding={[0, 0]}\n            useCSSTransforms={true}\n            margin={[GRID_CELL_VMARGIN, GRID_CELL_VMARGIN]}\n            cols={GRID_COLUMN_COUNT}\n            rowHeight={GRID_CELL_HEIGHT}\n            draggableHandle=\".grid-drag-handle\"\n            draggableCancel=\".grid-drag-cancel\"\n            layout={this.buildLayout()}\n            onDragStop={this.onDragStop}\n            onResize={this.onResize}\n            onResizeStop={this.onResizeStop}\n            onLayoutChange={this.onLayoutChange}\n          >\n            {this.renderPanels(width, draggable)}\n          </ReactGridLayout>\n        </div>\n      </div>\n    );\n  }\n}\n\ninterface GrafanaGridItemProps extends React.HTMLAttributes<HTMLDivElement> {\n  gridWidth?: number;\n  gridPos?: GridPos;\n  isViewing: boolean;\n  windowHeight: number;\n  windowWidth: number;\n  children: any; // eslint-disable-line @typescript-eslint/no-explicit-any\n}\n\n/**\n * A hacky way to intercept the react-layout-grid item dimensions and pass them to DashboardPanel\n */\nconst GrafanaGridItem = React.forwardRef<HTMLDivElement, GrafanaGridItemProps>((props, ref) => {\n  const theme = config.theme2;\n  let width = 100;\n  let height = 100;\n\n  const { gridWidth, gridPos, isViewing, windowHeight, windowWidth, ...divProps } = props;\n  const style: CSSProperties = props.style ?? {};\n\n  if (isViewing) {\n    // In fullscreen view mode a single panel take up full width & 85% height\n    width = gridWidth!;\n    height = windowHeight * 0.85;\n    style.height = height;\n    style.width = '100%';\n  } else if (windowWidth < theme.breakpoints.values.md) {\n    // Mobile layout is a bit different, every panel take up full width\n    width = props.gridWidth!;\n    height = translateGridHeightToScreenHeight(gridPos!.h);\n    style.height = height;\n    style.width = '100%';\n  } else {\n    // Normal grid layout. The grid framework passes width and height directly to children as style props.\n    if (props.style) {\n      const { width: styleWidth, height: styleHeight } = props.style;\n      if (styleWidth != null) {\n        width = typeof styleWidth === 'number' ? styleWidth : parseFloat(styleWidth);\n      }\n      if (styleHeight != null) {\n        height = typeof styleHeight === 'number' ? styleHeight : parseFloat(styleHeight);\n      }\n    }\n  }\n\n  // props.children[0] is our main children. RGL adds the drag handle at props.children[1]\n  return (\n    <div {...divProps} style={{ ...divProps.style }} ref={ref}>\n      {/* Pass width and height to children as render props */}\n      {[props.children[0](width, height), props.children.slice(1)]}\n    </div>\n  );\n});\n\n/**\n * This translates grid height dimensions to real pixels\n */\nfunction translateGridHeightToScreenHeight(gridHeight: number): number {\n  return gridHeight * (GRID_CELL_HEIGHT + GRID_CELL_VMARGIN) - GRID_CELL_VMARGIN;\n}\n\nGrafanaGridItem.displayName = 'GridItemWithDimensions';\n"],"names":["Form","defaultValues","onSubmit","validateOnMount","validateFieldsOnMount","children","validateOn","maxWidth","htmlProps","handleSubmit","trigger","formState","rest","DashboardFailed","initError","styles","DashboardLoading","initPhase","getStyles","cancelVariables","theme","slowStartThreshold","invisibleToVisible","AddLibraryPanelWidget","panel","dashboard","onCancelAddPanel","evt","onAddLibraryPanel","panelInfo","gridPos","newPanel","IconButton","LibraryPanelsSearch","pulsate","tinycolor","RowOptionsForm","repeat","title","warning","onUpdate","onCancel","newRepeat","setNewRepeat","onChangeRepeat","name","formData","register","Field","Input","RepeatRowSelect","Alert","selectors","Modal","Button","RowOptionsModal","onDismiss","RowOptionsButton","onUpdateChange","hideModal","showModal","Icon","UnthemedDashboardRow","p","TextLink","count","panels","canEdit","collapsed","DashboardRow","actions","PANEL_FILTER_VARIABLE","DashboardGrid","props","Subscription","newLayout","newPos","item","layout","oldItem","newItem","ref","rootEl","entries","entry","config","variable","e","regex","panelFilter","panelPos","gridWidth","top","translateGridHeightToScreenHeight","isDashboardDraggable","panelElements","panelClasses","GrafanaGridItem","width","height","isDraggable","DashboardPanel","isEditable","DashboardEmpty","draggable","isViewing","windowHeight","windowWidth","divProps","style","styleWidth","styleHeight","gridHeight"],"sourceRoot":""}