{"version":3,"file":"7782.4ba5c16799c29c3b5597.js","mappings":"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","sources":["webpack://grafana/./public/app/core/components/PanelTypeFilter/PanelTypeFilter.tsx","webpack://grafana/./public/app/features/library-panels/components/DeleteLibraryPanelModal/reducer.ts","webpack://grafana/./public/app/features/library-panels/components/DeleteLibraryPanelModal/DeleteLibraryPanelModal.tsx","webpack://grafana/./public/app/features/library-panels/components/DeleteLibraryPanelModal/actions.ts","webpack://grafana/./public/app/features/library-panels/components/LibraryPanelCard/LibraryPanelCard.tsx","webpack://grafana/./public/app/core/components/FolderFilter/FolderFilter.tsx","webpack://grafana/./public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.tsx","webpack://grafana/./public/app/features/library-panels/components/LibraryPanelsView/LibraryPanelsView.tsx","webpack://grafana/./public/app/features/library-panels/components/LibraryPanelsView/actions.ts","webpack://grafana/./public/app/features/library-panels/components/LibraryPanelsView/reducer.ts","webpack://grafana/./public/app/features/library-panels/styles.ts","webpack://grafana/./public/app/features/panel/components/VizTypePicker/PanelTypeCard.tsx","webpack://grafana/./public/app/features/panel/state/util.ts","webpack://grafana/./public/app/features/plugins/components/PluginStateInfo.tsx"],"sourcesContent":["import { css } from '@emotion/css';\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { GrafanaTheme2, PanelPluginMeta, SelectableValue } from '@grafana/data';\nimport { Icon, Button, MultiSelect, useStyles2 } from '@grafana/ui';\nimport { getAllPanelPluginMeta } from 'app/features/panel/state/util';\n\nexport interface Props {\n  onChange: (plugins: PanelPluginMeta[]) => void;\n  maxMenuHeight?: number;\n}\n\nexport const PanelTypeFilter = ({ onChange: propsOnChange, maxMenuHeight }: Props): JSX.Element => {\n  const plugins = useMemo<PanelPluginMeta[]>(() => getAllPanelPluginMeta(), []);\n  const options = useMemo(\n    () =>\n      plugins\n        .map((p) => ({ label: p.name, imgUrl: p.info.logos.small, value: p }))\n        .sort((a, b) => a.label?.localeCompare(b.label)),\n    [plugins]\n  );\n  const [value, setValue] = useState<Array<SelectableValue<PanelPluginMeta>>>([]);\n  const onChange = useCallback(\n    (plugins: Array<SelectableValue<PanelPluginMeta>>) => {\n      const changedPlugins = plugins.filter((p) => p.value).map((p) => p.value!);\n      propsOnChange(changedPlugins);\n      setValue(plugins);\n    },\n    [propsOnChange]\n  );\n  const styles = useStyles2(getStyles);\n\n  const selectOptions = {\n    defaultOptions: true,\n    getOptionLabel: (i: any) => i.label,\n    getOptionValue: (i: any) => i.value,\n    noOptionsMessage: 'No Panel types found',\n    placeholder: 'Filter by type',\n    maxMenuHeight,\n    options,\n    value,\n    onChange,\n  };\n\n  return (\n    <div className={styles.container}>\n      {value.length > 0 && (\n        <Button\n          size=\"xs\"\n          icon=\"trash-alt\"\n          fill=\"text\"\n          className={styles.clear}\n          onClick={() => onChange([])}\n          aria-label=\"Clear types\"\n        >\n          Clear types\n        </Button>\n      )}\n      <MultiSelect {...selectOptions} prefix={<Icon name=\"filter\" />} aria-label=\"Panel Type filter\" />\n    </div>\n  );\n};\n\nfunction getStyles(theme: GrafanaTheme2) {\n  return {\n    container: css`\n      label: container;\n      position: relative;\n      min-width: 180px;\n      flex-grow: 1;\n    `,\n    clear: css`\n      label: clear;\n      font-size: ${theme.spacing(1.5)};\n      position: absolute;\n      top: -${theme.spacing(4.5)};\n      right: 0;\n    `,\n  };\n}\n","import { createAction } from '@reduxjs/toolkit';\nimport { AnyAction } from 'redux';\n\nimport { LoadingState } from '@grafana/data';\nimport { DashboardSearchItem } from 'app/features/search/types';\n\nexport interface DeleteLibraryPanelModalState {\n  loadingState: LoadingState;\n  dashboardTitles: string[];\n}\n\nexport const initialDeleteLibraryPanelModalState: DeleteLibraryPanelModalState = {\n  loadingState: LoadingState.Loading,\n  dashboardTitles: [],\n};\n\nexport const searchCompleted = createAction<{ dashboards: DashboardSearchItem[] }>(\n  'libraryPanels/delete/searchCompleted'\n);\n\nexport const deleteLibraryPanelModalReducer = (\n  state: DeleteLibraryPanelModalState = initialDeleteLibraryPanelModalState,\n  action: AnyAction\n): DeleteLibraryPanelModalState => {\n  if (searchCompleted.match(action)) {\n    return {\n      ...state,\n      dashboardTitles: action.payload.dashboards.map((d) => d.title),\n      loadingState: LoadingState.Done,\n    };\n  }\n\n  return state;\n};\n","import React, { FC, useEffect, useMemo, useReducer } from 'react';\n\nimport { LoadingState } from '@grafana/data';\nimport { Button, Modal, useStyles2 } from '@grafana/ui';\n\nimport { getModalStyles } from '../../styles';\nimport { LibraryElementDTO } from '../../types';\nimport { asyncDispatcher } from '../LibraryPanelsView/actions';\n\nimport { getConnectedDashboards } from './actions';\nimport { deleteLibraryPanelModalReducer, initialDeleteLibraryPanelModalState } from './reducer';\n\ninterface Props {\n  libraryPanel: LibraryElementDTO;\n  onConfirm: () => void;\n  onDismiss: () => void;\n}\n\nexport const DeleteLibraryPanelModal: FC<Props> = ({ libraryPanel, onDismiss, onConfirm }) => {\n  const styles = useStyles2(getModalStyles);\n  const [{ dashboardTitles, loadingState }, dispatch] = useReducer(\n    deleteLibraryPanelModalReducer,\n    initialDeleteLibraryPanelModalState\n  );\n  const asyncDispatch = useMemo(() => asyncDispatcher(dispatch), [dispatch]);\n  useEffect(() => {\n    asyncDispatch(getConnectedDashboards(libraryPanel));\n  }, [asyncDispatch, libraryPanel]);\n  const connected = Boolean(dashboardTitles.length);\n  const done = loadingState === LoadingState.Done;\n\n  return (\n    <Modal className={styles.modal} title=\"Delete library panel\" icon=\"trash-alt\" onDismiss={onDismiss} isOpen={true}>\n      {!done ? <LoadingIndicator /> : null}\n      {done ? (\n        <div>\n          {connected ? <HasConnectedDashboards dashboardTitles={dashboardTitles} /> : null}\n          {!connected ? <Confirm /> : null}\n\n          <Modal.ButtonRow>\n            <Button variant=\"secondary\" onClick={onDismiss} fill=\"outline\">\n              Cancel\n            </Button>\n            <Button variant=\"destructive\" onClick={onConfirm} disabled={connected}>\n              Delete\n            </Button>\n          </Modal.ButtonRow>\n        </div>\n      ) : null}\n    </Modal>\n  );\n};\n\nconst LoadingIndicator = () => <span>Loading library panel...</span>;\n\nconst Confirm = () => {\n  const styles = useStyles2(getModalStyles);\n\n  return <div className={styles.modalText}>Do you want to delete this panel?</div>;\n};\n\nconst HasConnectedDashboards: FC<{ dashboardTitles: string[] }> = ({ dashboardTitles }) => {\n  const styles = useStyles2(getModalStyles);\n  const suffix = dashboardTitles.length === 1 ? 'dashboard.' : 'dashboards.';\n  const message = `${dashboardTitles.length} ${suffix}`;\n  if (dashboardTitles.length === 0) {\n    return null;\n  }\n\n  return (\n    <div>\n      <p className={styles.textInfo}>\n        {'This library panel can not be deleted because it is connected to '}\n        <strong>{message}</strong>\n        {' Remove the library panel from the dashboards listed below and retry.'}\n      </p>\n      <table className={styles.myTable}>\n        <thead>\n          <tr>\n            <th>Dashboard name</th>\n          </tr>\n        </thead>\n        <tbody>\n          {dashboardTitles.map((title, i) => (\n            <tr key={`dash-title-${i}`}>\n              <td>{title}</td>\n            </tr>\n          ))}\n        </tbody>\n      </table>\n    </div>\n  );\n};\n","import { getConnectedDashboards as apiGetConnectedDashboards } from '../../state/api';\nimport { DispatchResult, LibraryElementDTO } from '../../types';\n\nimport { searchCompleted } from './reducer';\n\nexport function getConnectedDashboards(libraryPanel: LibraryElementDTO): DispatchResult {\n  return async function (dispatch) {\n    const dashboards = await apiGetConnectedDashboards(libraryPanel.uid);\n    dispatch(searchCompleted({ dashboards }));\n  };\n}\n","import { css } from '@emotion/css';\nimport React, { ReactElement, useState } from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { Icon, Link, useStyles2 } from '@grafana/ui';\nimport { getPanelPluginNotFound } from 'app/features/panel/components/PanelPluginError';\nimport { PanelTypeCard } from 'app/features/panel/components/VizTypePicker/PanelTypeCard';\n\nimport { LibraryElementDTO } from '../../types';\nimport { DeleteLibraryPanelModal } from '../DeleteLibraryPanelModal/DeleteLibraryPanelModal';\n\nexport interface LibraryPanelCardProps {\n  libraryPanel: LibraryElementDTO;\n  onClick: (panel: LibraryElementDTO) => void;\n  onDelete?: (panel: LibraryElementDTO) => void;\n  showSecondaryActions?: boolean;\n}\n\nexport const LibraryPanelCard: React.FC<LibraryPanelCardProps & { children?: JSX.Element | JSX.Element[] }> = ({\n  libraryPanel,\n  onClick,\n  onDelete,\n  showSecondaryActions,\n}) => {\n  const [showDeletionModal, setShowDeletionModal] = useState(false);\n\n  const onDeletePanel = () => {\n    onDelete?.(libraryPanel);\n    setShowDeletionModal(false);\n  };\n\n  const panelPlugin = config.panels[libraryPanel.model.type] ?? getPanelPluginNotFound(libraryPanel.model.type).meta;\n\n  return (\n    <>\n      <PanelTypeCard\n        isCurrent={false}\n        title={libraryPanel.name}\n        description={libraryPanel.description}\n        plugin={panelPlugin}\n        onClick={() => onClick?.(libraryPanel)}\n        onDelete={showSecondaryActions ? () => setShowDeletionModal(true) : undefined}\n      >\n        <FolderLink libraryPanel={libraryPanel} />\n      </PanelTypeCard>\n      {showDeletionModal && (\n        <DeleteLibraryPanelModal\n          libraryPanel={libraryPanel}\n          onConfirm={onDeletePanel}\n          onDismiss={() => setShowDeletionModal(false)}\n        />\n      )}\n    </>\n  );\n};\n\ninterface FolderLinkProps {\n  libraryPanel: LibraryElementDTO;\n}\n\nfunction FolderLink({ libraryPanel }: FolderLinkProps): ReactElement | null {\n  const styles = useStyles2(getStyles);\n\n  if (!libraryPanel.meta.folderUid && !libraryPanel.meta.folderName) {\n    return null;\n  }\n\n  if (!libraryPanel.meta.folderUid) {\n    return (\n      <span className={styles.metaContainer}>\n        <Icon name={'folder'} size=\"sm\" />\n        <span>{libraryPanel.meta.folderName}</span>\n      </span>\n    );\n  }\n\n  return (\n    <span className={styles.metaContainer}>\n      <Link href={`/dashboards/f/${libraryPanel.meta.folderUid}`}>\n        <Icon name={'folder-upload'} size=\"sm\" />\n        <span>{libraryPanel.meta.folderName}</span>\n      </Link>\n    </span>\n  );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n  return {\n    metaContainer: css`\n      display: flex;\n      align-items: center;\n      color: ${theme.colors.text.secondary};\n      font-size: ${theme.typography.bodySmall.fontSize};\n      padding-top: ${theme.spacing(0.5)};\n\n      svg {\n        margin-right: ${theme.spacing(0.5)};\n        margin-bottom: 3px;\n      }\n    `,\n  };\n}\n","import { css } from '@emotion/css';\nimport debounce from 'debounce-promise';\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { GrafanaTheme2, SelectableValue } from '@grafana/data';\nimport { AsyncMultiSelect, Icon, Button, useStyles2 } from '@grafana/ui';\nimport { getBackendSrv } from 'app/core/services/backend_srv';\nimport { DashboardSearchHit, DashboardSearchItemType } from 'app/features/search/types';\nimport { FolderInfo, PermissionLevelString } from 'app/types';\n\nexport interface FolderFilterProps {\n  onChange: (folder: FolderInfo[]) => void;\n  maxMenuHeight?: number;\n}\n\nexport function FolderFilter({ onChange, maxMenuHeight }: FolderFilterProps): JSX.Element {\n  const styles = useStyles2(getStyles);\n  const [loading, setLoading] = useState(false);\n  const getOptions = useCallback((searchString: string) => getFoldersAsOptions(searchString, setLoading), []);\n  const debouncedLoadOptions = useMemo(() => debounce(getOptions, 300), [getOptions]);\n\n  const [value, setValue] = useState<Array<SelectableValue<FolderInfo>>>([]);\n  const onSelectOptionChange = useCallback(\n    (folders: Array<SelectableValue<FolderInfo>>) => {\n      const changedFolderIds = folders.filter((f) => Boolean(f.value)).map((f) => f.value!);\n      onChange(changedFolderIds);\n      setValue(folders);\n    },\n    [onChange]\n  );\n\n  return (\n    <div className={styles.container}>\n      {value.length > 0 && (\n        <Button\n          size=\"xs\"\n          icon=\"trash-alt\"\n          fill=\"text\"\n          className={styles.clear}\n          onClick={() => onChange([])}\n          aria-label=\"Clear folders\"\n        >\n          Clear folders\n        </Button>\n      )}\n      <AsyncMultiSelect\n        value={value}\n        onChange={onSelectOptionChange}\n        isLoading={loading}\n        loadOptions={debouncedLoadOptions}\n        maxMenuHeight={maxMenuHeight}\n        placeholder=\"Filter by folder\"\n        noOptionsMessage=\"No folders found\"\n        prefix={<Icon name=\"filter\" />}\n        aria-label=\"Folder filter\"\n        defaultOptions\n      />\n    </div>\n  );\n}\n\nasync function getFoldersAsOptions(\n  searchString: string,\n  setLoading: (loading: boolean) => void\n): Promise<Array<SelectableValue<FolderInfo>>> {\n  setLoading(true);\n\n  const params = {\n    query: searchString,\n    type: DashboardSearchItemType.DashFolder,\n    permission: PermissionLevelString.View,\n  };\n\n  // FIXME: stop using id from search and use UID instead\n  const searchHits: DashboardSearchHit[] = await getBackendSrv().search(params);\n  const options = searchHits.map((d) => ({ label: d.title, value: { uid: d.uid, title: d.title } }));\n  if (!searchString || 'general'.includes(searchString.toLowerCase())) {\n    options.unshift({ label: 'General', value: { uid: 'general', title: 'General' } });\n  }\n\n  setLoading(false);\n\n  return options;\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n  return {\n    container: css`\n      label: container;\n      position: relative;\n      min-width: 180px;\n      flex-grow: 1;\n    `,\n    clear: css`\n      label: clear;\n      font-size: ${theme.spacing(1.5)};\n      position: absolute;\n      top: -${theme.spacing(4.5)};\n      right: 0;\n    `,\n  };\n}\n","import { css } from '@emotion/css';\nimport React, { useCallback, useState } from 'react';\nimport { useDebounce } from 'react-use';\n\nimport { GrafanaTheme2, PanelPluginMeta, SelectableValue } from '@grafana/data';\nimport { useStyles2, VerticalGroup, FilterInput } from '@grafana/ui';\nimport { FolderInfo } from 'app/types';\n\nimport { FolderFilter } from '../../../../core/components/FolderFilter/FolderFilter';\nimport { PanelTypeFilter } from '../../../../core/components/PanelTypeFilter/PanelTypeFilter';\nimport { SortPicker } from '../../../../core/components/Select/SortPicker';\nimport { DEFAULT_PER_PAGE_PAGINATION } from '../../../../core/constants';\nimport { LibraryElementDTO } from '../../types';\nimport { LibraryPanelsView } from '../LibraryPanelsView/LibraryPanelsView';\n\nexport enum LibraryPanelsSearchVariant {\n  Tight = 'tight',\n  Spacious = 'spacious',\n}\n\nexport interface LibraryPanelsSearchProps {\n  onClick: (panel: LibraryElementDTO) => void;\n  variant?: LibraryPanelsSearchVariant;\n  showSort?: boolean;\n  showPanelFilter?: boolean;\n  showFolderFilter?: boolean;\n  showSecondaryActions?: boolean;\n  currentPanelId?: string;\n  currentFolderUID?: string;\n  perPage?: number;\n}\n\nexport const LibraryPanelsSearch = ({\n  onClick,\n  variant = LibraryPanelsSearchVariant.Spacious,\n  currentPanelId,\n  currentFolderUID,\n  perPage = DEFAULT_PER_PAGE_PAGINATION,\n  showPanelFilter = false,\n  showFolderFilter = false,\n  showSort = false,\n  showSecondaryActions = false,\n}: LibraryPanelsSearchProps): JSX.Element => {\n  const styles = useStyles2(useCallback((theme) => getStyles(theme, variant), [variant]));\n\n  const [searchQuery, setSearchQuery] = useState('');\n  const [debouncedSearchQuery, setDebouncedSearchQuery] = useState('');\n  useDebounce(() => setDebouncedSearchQuery(searchQuery), 200, [searchQuery]);\n\n  const [sortDirection, setSortDirection] = useState<SelectableValue<string>>({});\n  const [folderFilter, setFolderFilter] = useState<string[]>(currentFolderUID ? [currentFolderUID] : []);\n  const [panelFilter, setPanelFilter] = useState<string[]>([]);\n\n  const sortOrFiltersVisible = showSort || showPanelFilter || showFolderFilter;\n  const verticalGroupSpacing = variant === LibraryPanelsSearchVariant.Tight ? 'lg' : 'xs';\n\n  return (\n    <div className={styles.container}>\n      <VerticalGroup spacing={verticalGroupSpacing}>\n        <div className={styles.gridContainer}>\n          <div className={styles.filterInputWrapper}>\n            <FilterInput\n              value={searchQuery}\n              onChange={setSearchQuery}\n              placeholder=\"Search by name or description\"\n              width={0}\n              escapeRegex={false}\n            />\n          </div>\n          {sortOrFiltersVisible && (\n            <SearchControls\n              showSort={showSort}\n              showPanelFilter={showPanelFilter}\n              showFolderFilter={showFolderFilter}\n              onSortChange={setSortDirection}\n              onFolderFilterChange={setFolderFilter}\n              onPanelFilterChange={setPanelFilter}\n              sortDirection={sortDirection.value}\n              variant={variant}\n            />\n          )}\n        </div>\n\n        <div className={styles.libraryPanelsView}>\n          <LibraryPanelsView\n            onClickCard={onClick}\n            searchString={debouncedSearchQuery}\n            sortDirection={sortDirection.value}\n            panelFilter={panelFilter}\n            folderFilter={folderFilter}\n            currentPanelId={currentPanelId}\n            showSecondaryActions={showSecondaryActions}\n            perPage={perPage}\n          />\n        </div>\n      </VerticalGroup>\n    </div>\n  );\n};\n\nfunction getStyles(theme: GrafanaTheme2, variant: LibraryPanelsSearchVariant) {\n  const tightLayout = css`\n    flex-direction: row;\n    row-gap: ${theme.spacing(1)};\n  `;\n  return {\n    filterInputWrapper: css`\n      flex-grow: ${variant === LibraryPanelsSearchVariant.Tight ? 1 : 'initial'};\n    `,\n    container: css`\n      width: 100%;\n      overflow-y: auto;\n      padding: ${theme.spacing(1)};\n    `,\n    libraryPanelsView: css`\n      width: 100%;\n    `,\n    gridContainer: css`\n      ${variant === LibraryPanelsSearchVariant.Tight ? tightLayout : ''};\n      display: flex;\n      flex-direction: column;\n      width: 100%;\n      column-gap: ${theme.spacing(1)};\n      row-gap: ${theme.spacing(1)};\n      padding-bottom: ${theme.spacing(2)};\n    `,\n  };\n}\n\ninterface SearchControlsProps {\n  showSort: boolean;\n  showPanelFilter: boolean;\n  showFolderFilter: boolean;\n  sortDirection?: string;\n  onSortChange: (sortValue: SelectableValue) => void;\n  onFolderFilterChange: (folder: string[]) => void;\n  onPanelFilterChange: (plugins: string[]) => void;\n  variant?: LibraryPanelsSearchVariant;\n}\n\nconst SearchControls = React.memo(\n  ({\n    variant = LibraryPanelsSearchVariant.Spacious,\n    showSort,\n    showPanelFilter,\n    showFolderFilter,\n    sortDirection,\n    onSortChange,\n    onFolderFilterChange,\n    onPanelFilterChange,\n  }: SearchControlsProps) => {\n    const styles = useStyles2(useCallback((theme) => getRowStyles(theme, variant), [variant]));\n    const panelFilterChanged = useCallback(\n      (plugins: PanelPluginMeta[]) => onPanelFilterChange(plugins.map((p) => p.id)),\n      [onPanelFilterChange]\n    );\n    const folderFilterChanged = useCallback(\n      (folders: FolderInfo[]) => onFolderFilterChange(folders.map((f) => f.uid ?? '')),\n      [onFolderFilterChange]\n    );\n\n    return (\n      <div className={styles.container}>\n        {showSort && <SortPicker value={sortDirection} onChange={onSortChange} filter={['alpha-asc', 'alpha-desc']} />}\n        {(showFolderFilter || showPanelFilter) && (\n          <div className={styles.filterContainer}>\n            {showFolderFilter && <FolderFilter onChange={folderFilterChanged} />}\n            {showPanelFilter && <PanelTypeFilter onChange={panelFilterChanged} />}\n          </div>\n        )}\n      </div>\n    );\n  }\n);\nSearchControls.displayName = 'SearchControls';\n\nfunction getRowStyles(theme: GrafanaTheme2, variant = LibraryPanelsSearchVariant.Spacious) {\n  const searchRowContainer = css`\n    display: flex;\n    gap: ${theme.spacing(1)};\n    flex-grow: 1;\n    flex-direction: row;\n    justify-content: end;\n  `;\n  const searchRowContainerTight = css`\n    ${searchRowContainer};\n    flex-grow: initial;\n    flex-direction: column;\n    justify-content: normal;\n  `;\n  const filterContainer = css`\n    display: flex;\n    flex-direction: row;\n    margin-left: auto;\n    gap: 4px;\n  `;\n  const filterContainerTight = css`\n    ${filterContainer};\n    flex-direction: column;\n    margin-left: initial;\n  `;\n\n  switch (variant) {\n    case LibraryPanelsSearchVariant.Spacious:\n      return {\n        container: searchRowContainer,\n        filterContainer: filterContainer,\n      };\n    case LibraryPanelsSearchVariant.Tight:\n      return {\n        container: searchRowContainerTight,\n        filterContainer: filterContainerTight,\n      };\n  }\n}\n","import { css, cx } from '@emotion/css';\nimport React, { useMemo, useReducer } from 'react';\nimport { useDebounce } from 'react-use';\n\nimport { GrafanaTheme2, LoadingState } from '@grafana/data';\nimport { Pagination, useStyles2 } from '@grafana/ui';\n\nimport { LibraryElementDTO } from '../../types';\nimport { LibraryPanelCard } from '../LibraryPanelCard/LibraryPanelCard';\n\nimport { asyncDispatcher, deleteLibraryPanel, searchForLibraryPanels } from './actions';\nimport { changePage, initialLibraryPanelsViewState, libraryPanelsViewReducer } from './reducer';\n\ninterface LibraryPanelViewProps {\n  className?: string;\n  onClickCard: (panel: LibraryElementDTO) => void;\n  showSecondaryActions?: boolean;\n  currentPanelId?: string;\n  searchString: string;\n  sortDirection?: string;\n  panelFilter?: string[];\n  folderFilter?: string[];\n  perPage?: number;\n}\n\nexport const LibraryPanelsView: React.FC<LibraryPanelViewProps> = ({\n  className,\n  onClickCard,\n  searchString,\n  sortDirection,\n  panelFilter,\n  folderFilter,\n  showSecondaryActions,\n  currentPanelId: currentPanel,\n  perPage: propsPerPage = 40,\n}) => {\n  const styles = useStyles2(getPanelViewStyles);\n  const [{ libraryPanels, page, perPage, numberOfPages, loadingState, currentPanelId }, dispatch] = useReducer(\n    libraryPanelsViewReducer,\n    {\n      ...initialLibraryPanelsViewState,\n      currentPanelId: currentPanel,\n      perPage: propsPerPage,\n    }\n  );\n  const asyncDispatch = useMemo(() => asyncDispatcher(dispatch), [dispatch]);\n  useDebounce(\n    () =>\n      asyncDispatch(\n        searchForLibraryPanels({\n          searchString,\n          sortDirection,\n          panelFilter,\n          folderFilterUIDs: folderFilter,\n          page,\n          perPage,\n          currentPanelId,\n        })\n      ),\n    300,\n    [searchString, sortDirection, panelFilter, folderFilter, page, asyncDispatch]\n  );\n  const onDelete = ({ uid }: LibraryElementDTO) =>\n    asyncDispatch(deleteLibraryPanel(uid, { searchString, page, perPage }));\n  const onPageChange = (page: number) => asyncDispatch(changePage({ page }));\n\n  return (\n    <div className={cx(styles.container, className)}>\n      <div className={styles.libraryPanelList}>\n        {loadingState === LoadingState.Loading ? (\n          <p>Loading library panels...</p>\n        ) : libraryPanels.length < 1 ? (\n          <p className={styles.noPanelsFound}>No library panels found.</p>\n        ) : (\n          libraryPanels?.map((item, i) => (\n            <LibraryPanelCard\n              key={`library-panel=${i}`}\n              libraryPanel={item}\n              onDelete={onDelete}\n              onClick={onClickCard}\n              showSecondaryActions={showSecondaryActions}\n            />\n          ))\n        )}\n      </div>\n      {libraryPanels.length ? (\n        <div className={styles.pagination}>\n          <Pagination\n            currentPage={page}\n            numberOfPages={numberOfPages}\n            onNavigate={onPageChange}\n            hideWhenSinglePage={true}\n          />\n        </div>\n      ) : null}\n    </div>\n  );\n};\n\nconst getPanelViewStyles = (theme: GrafanaTheme2) => {\n  return {\n    container: css`\n      display: flex;\n      flex-direction: column;\n      flex-wrap: nowrap;\n    `,\n    libraryPanelList: css`\n      max-width: 100%;\n      display: grid;\n      grid-gap: ${theme.spacing(1)};\n    `,\n    searchHeader: css`\n      display: flex;\n    `,\n    newPanelButton: css`\n      margin-top: 10px;\n      align-self: flex-start;\n    `,\n    pagination: css`\n      align-self: center;\n      margin-top: ${theme.spacing(1)};\n    `,\n    noPanelsFound: css`\n      label: noPanelsFound;\n      min-height: 200px;\n    `,\n  };\n};\n","import { AnyAction } from '@reduxjs/toolkit';\nimport { Dispatch } from 'react';\nimport { from, merge, of, Subscription, timer } from 'rxjs';\nimport { catchError, finalize, mapTo, mergeMap, share, takeUntil } from 'rxjs/operators';\n\nimport { deleteLibraryPanel as apiDeleteLibraryPanel, getLibraryPanels } from '../../state/api';\n\nimport { initialLibraryPanelsViewState, initSearch, searchCompleted } from './reducer';\n\ntype DispatchResult = (dispatch: Dispatch<AnyAction>) => void;\ninterface SearchArgs {\n  perPage: number;\n  page: number;\n  searchString: string;\n  sortDirection?: string;\n  panelFilter?: string[];\n  folderFilterUIDs?: string[];\n  currentPanelId?: string;\n}\n\nexport function searchForLibraryPanels(args: SearchArgs): DispatchResult {\n  return function (dispatch) {\n    const subscription = new Subscription();\n    const dataObservable = from(\n      getLibraryPanels({\n        searchString: args.searchString,\n        perPage: args.perPage,\n        page: args.page,\n        excludeUid: args.currentPanelId,\n        sortDirection: args.sortDirection,\n        typeFilter: args.panelFilter,\n        folderFilterUIDs: args.folderFilterUIDs,\n      })\n    ).pipe(\n      mergeMap(({ perPage, elements: libraryPanels, page, totalCount }) =>\n        of(searchCompleted({ libraryPanels, page, perPage, totalCount }))\n      ),\n      catchError((err) => {\n        console.error(err);\n        return of(searchCompleted({ ...initialLibraryPanelsViewState, page: args.page, perPage: args.perPage }));\n      }),\n      finalize(() => subscription.unsubscribe()), // make sure we unsubscribe\n      share()\n    );\n\n    subscription.add(\n      // If 50ms without a response dispatch a loading state\n      // mapTo will translate the timer event into a loading state\n      // takeUntil will cancel the timer emit when first response is received on the dataObservable\n      merge(timer(50).pipe(mapTo(initSearch()), takeUntil(dataObservable)), dataObservable).subscribe(dispatch)\n    );\n  };\n}\n\nexport function deleteLibraryPanel(uid: string, args: SearchArgs): DispatchResult {\n  return async function (dispatch) {\n    try {\n      await apiDeleteLibraryPanel(uid);\n      searchForLibraryPanels(args)(dispatch);\n    } catch (e) {\n      console.error(e);\n    }\n  };\n}\n\nexport function asyncDispatcher(dispatch: Dispatch<AnyAction>) {\n  return function (action: any) {\n    if (action instanceof Function) {\n      return action(dispatch);\n    }\n    return dispatch(action);\n  };\n}\n","import { createAction } from '@reduxjs/toolkit';\nimport { AnyAction } from 'redux';\n\nimport { LoadingState } from '@grafana/data';\n\nimport { LibraryElementDTO } from '../../types';\n\nexport interface LibraryPanelsViewState {\n  loadingState: LoadingState;\n  libraryPanels: LibraryElementDTO[];\n  totalCount: number;\n  perPage: number;\n  page: number;\n  numberOfPages: number;\n  currentPanelId?: string;\n}\n\nexport const initialLibraryPanelsViewState: LibraryPanelsViewState = {\n  loadingState: LoadingState.Loading,\n  libraryPanels: [],\n  totalCount: 0,\n  perPage: 40,\n  page: 1,\n  numberOfPages: 0,\n  currentPanelId: undefined,\n};\n\nexport const initSearch = createAction('libraryPanels/view/initSearch');\nexport const searchCompleted = createAction<\n  Omit<LibraryPanelsViewState, 'currentPanelId' | 'searchString' | 'loadingState' | 'numberOfPages'>\n>('libraryPanels/view/searchCompleted');\n\nexport const changePage = createAction<Pick<LibraryPanelsViewState, 'page'>>('libraryPanels/view/changePage');\n\nexport const libraryPanelsViewReducer = (state: LibraryPanelsViewState, action: AnyAction) => {\n  if (initSearch.match(action)) {\n    return { ...state, loadingState: LoadingState.Loading };\n  }\n\n  if (searchCompleted.match(action)) {\n    const { libraryPanels, page, perPage, totalCount } = action.payload;\n    const numberOfPages = Math.ceil(totalCount / perPage);\n    return {\n      ...state,\n      libraryPanels,\n      perPage,\n      totalCount,\n      loadingState: LoadingState.Done,\n      numberOfPages,\n      page: page > numberOfPages ? page - 1 : page,\n    };\n  }\n\n  if (changePage.match(action)) {\n    return { ...state, page: action.payload.page };\n  }\n\n  return state;\n};\n","import { css } from '@emotion/css';\n\nimport { GrafanaTheme2 } from '@grafana/data';\n\nexport function getModalStyles(theme: GrafanaTheme2) {\n  return {\n    myTable: css`\n      max-height: 204px;\n      overflow-y: auto;\n      margin-top: 11px;\n      margin-bottom: 28px;\n      border-radius: ${theme.shape.borderRadius(1)};\n      border: 1px solid ${theme.colors.action.hover};\n      background: ${theme.colors.background.primary};\n      color: ${theme.colors.text.secondary};\n      font-size: ${theme.typography.h6.fontSize};\n      width: 100%;\n\n      thead {\n        color: #538ade;\n        font-size: ${theme.typography.bodySmall.fontSize};\n      }\n\n      th,\n      td {\n        padding: 6px 13px;\n        height: ${theme.spacing(4)};\n      }\n\n      tbody > tr:nth-child(odd) {\n        background: ${theme.colors.background.secondary};\n      }\n    `,\n    noteTextbox: css`\n      margin-bottom: ${theme.spacing(4)};\n    `,\n    textInfo: css`\n      color: ${theme.colors.text.secondary};\n      font-size: ${theme.typography.size.sm};\n    `,\n    dashboardSearch: css`\n      margin-top: ${theme.spacing(2)};\n    `,\n    modal: css`\n      width: 500px;\n    `,\n    modalText: css`\n      font-size: ${theme.typography.h4.fontSize};\n      color: ${theme.colors.text.primary};\n      margin-bottom: ${theme.spacing(4)};\n      padding-top: ${theme.spacing(2)};\n    `,\n  };\n}\n","import { css, cx } from '@emotion/css';\nimport React, { MouseEventHandler } from 'react';\n\nimport { GrafanaTheme2, isUnsignedPluginSignature, PanelPluginMeta, PluginState } from '@grafana/data';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { IconButton, PluginSignatureBadge, useStyles2 } from '@grafana/ui';\nimport { PluginStateInfo } from 'app/features/plugins/components/PluginStateInfo';\n\ninterface Props {\n  isCurrent: boolean;\n  plugin: PanelPluginMeta;\n  title: string;\n  onClick: MouseEventHandler<HTMLDivElement>;\n  onDelete?: () => void;\n  disabled?: boolean;\n  showBadge?: boolean;\n  description?: string;\n}\n\nexport const PanelTypeCard = ({\n  isCurrent,\n  title,\n  plugin,\n  onClick,\n  onDelete,\n  disabled,\n  showBadge,\n  description,\n  children,\n}: React.PropsWithChildren<Props>) => {\n  const styles = useStyles2(getStyles);\n  const isDisabled = disabled || plugin.state === PluginState.deprecated;\n  const cssClass = cx({\n    [styles.item]: true,\n    [styles.itemDisabled]: isDisabled,\n    [styles.current]: isCurrent,\n  });\n\n  return (\n    <div\n      className={cssClass}\n      aria-label={selectors.components.PluginVisualization.item(plugin.name)}\n      onClick={isDisabled ? undefined : onClick}\n      title={isCurrent ? 'Click again to close this section' : plugin.name}\n    >\n      <img className={cx(styles.img, { [styles.disabled]: isDisabled })} src={plugin.info.logos.small} alt=\"\" />\n\n      <div className={cx(styles.itemContent, { [styles.disabled]: isDisabled })}>\n        <div className={styles.name}>{title}</div>\n        {description ? <span className={styles.description}>{description}</span> : null}\n        {children}\n      </div>\n      {showBadge && (\n        <div className={cx(styles.badge, { [styles.disabled]: isDisabled })}>\n          <PanelPluginBadge plugin={plugin} />\n        </div>\n      )}\n      {onDelete && (\n        <IconButton\n          name=\"trash-alt\"\n          onClick={(e) => {\n            e.stopPropagation();\n            onDelete();\n          }}\n          className={styles.deleteButton}\n          aria-label=\"Delete button on panel type card\"\n        />\n      )}\n    </div>\n  );\n};\n\nPanelTypeCard.displayName = 'PanelTypeCard';\n\nconst getStyles = (theme: GrafanaTheme2) => {\n  return {\n    item: css`\n      position: relative;\n      display: flex;\n      flex-shrink: 0;\n      cursor: pointer;\n      background: ${theme.colors.background.secondary};\n      border-radius: ${theme.shape.borderRadius()};\n      box-shadow: ${theme.shadows.z1};\n      border: 1px solid ${theme.colors.background.secondary};\n      align-items: center;\n      padding: 8px;\n      width: 100%;\n      position: relative;\n      overflow: hidden;\n      transition: ${theme.transitions.create(['background'], {\n        duration: theme.transitions.duration.short,\n      })};\n\n      &:hover {\n        background: ${theme.colors.emphasize(theme.colors.background.secondary, 0.03)};\n      }\n    `,\n    itemContent: css`\n      overflow: hidden;\n      position: relative;\n      padding: ${theme.spacing(0, 1)};\n    `,\n    itemDisabled: css`\n      cursor: default;\n\n      &,\n      &:hover {\n        background: ${theme.colors.action.disabledBackground};\n      }\n    `,\n    current: css`\n      label: currentVisualizationItem;\n      border: 1px solid ${theme.colors.primary.border};\n      background: ${theme.colors.action.selected};\n    `,\n    disabled: css`\n      opacity: ${theme.colors.action.disabledOpacity};\n      filter: grayscale(1);\n      cursor: default;\n      pointer-events: none;\n    `,\n    name: css`\n      text-overflow: ellipsis;\n      overflow: hidden;\n      font-size: ${theme.typography.size.sm};\n      font-weight: ${theme.typography.fontWeightMedium};\n      width: 100%;\n    `,\n    description: css`\n      display: block;\n      text-overflow: ellipsis;\n      overflow: hidden;\n      color: ${theme.colors.text.secondary};\n      font-size: ${theme.typography.bodySmall.fontSize};\n      font-weight: ${theme.typography.fontWeightLight};\n      width: 100%;\n      max-height: 4.5em;\n    `,\n    img: css`\n      max-height: 38px;\n      width: 38px;\n      display: flex;\n      align-items: center;\n    `,\n    badge: css`\n      background: ${theme.colors.background.primary};\n    `,\n    deleteButton: css`\n      cursor: pointer;\n      margin-left: auto;\n    `,\n  };\n};\n\ninterface PanelPluginBadgeProps {\n  plugin: PanelPluginMeta;\n}\n\nconst PanelPluginBadge = ({ plugin }: PanelPluginBadgeProps) => {\n  if (isUnsignedPluginSignature(plugin.signature)) {\n    return <PluginSignatureBadge status={plugin.signature} />;\n  }\n\n  return <PluginStateInfo state={plugin.state} />;\n};\n\nPanelPluginBadge.displayName = 'PanelPluginBadge';\n","import { PanelPluginMeta, PluginState, unEscapeStringFromRegex } from '@grafana/data';\nimport { config } from 'app/core/config';\n\nexport function getAllPanelPluginMeta(): PanelPluginMeta[] {\n  const allPanels = config.panels;\n\n  return Object.keys(allPanels)\n    .filter((key) => allPanels[key]['hideFromList'] === false)\n    .map((key) => allPanels[key])\n    .sort((a: PanelPluginMeta, b: PanelPluginMeta) => a.sort - b.sort);\n}\n\nexport function filterPluginList(\n  pluginsList: PanelPluginMeta[],\n  searchQuery: string, // Note: this will be an escaped regex string as it comes from `FilterInput`\n  current: PanelPluginMeta\n): PanelPluginMeta[] {\n  if (!searchQuery.length) {\n    return pluginsList.filter((p) => {\n      if (p.state === PluginState.deprecated) {\n        return current.id === p.id;\n      }\n      return true;\n    });\n  }\n\n  const query = unEscapeStringFromRegex(searchQuery).toLowerCase();\n  const first: PanelPluginMeta[] = [];\n  const match: PanelPluginMeta[] = [];\n  const isGraphQuery = 'graph'.startsWith(query);\n\n  for (const item of pluginsList) {\n    if (item.state === PluginState.deprecated && current.id !== item.id) {\n      continue;\n    }\n\n    const name = item.name.toLowerCase();\n    const idx = name.indexOf(query);\n\n    if (idx === 0) {\n      first.push(item);\n    } else if (idx > 0) {\n      match.push(item);\n    } else if (isGraphQuery && item.id === 'timeseries') {\n      first.push(item);\n    }\n  }\n\n  return first.concat(match);\n}\n","import React, { FC } from 'react';\n\nimport { PluginState } from '@grafana/data';\nimport { Badge, BadgeProps } from '@grafana/ui';\n\ninterface Props {\n  state?: PluginState;\n}\n\nexport const PluginStateInfo: FC<Props> = (props) => {\n  const display = getFeatureStateInfo(props.state);\n\n  if (!display) {\n    return null;\n  }\n\n  return <Badge color={display.color} title={display.tooltip} text={display.text} icon={display.icon} />;\n};\n\nfunction getFeatureStateInfo(state?: PluginState): BadgeProps | null {\n  switch (state) {\n    case PluginState.deprecated:\n      return {\n        text: 'Deprecated',\n        color: 'red',\n        tooltip: `This feature is deprecated and will be removed in a future release`,\n      };\n    case PluginState.alpha:\n      return {\n        text: 'Alpha',\n        color: 'blue',\n        tooltip: `This feature is experimental and future updates might not be backward compatible`,\n      };\n    case PluginState.beta:\n      return {\n        text: 'Beta',\n        color: 'blue',\n        tooltip: `This feature is close to complete but not fully tested`,\n      };\n    default:\n      return null;\n  }\n}\n"],"names":["PanelTypeFilter","onChange","propsOnChange","maxMenuHeight","plugins","useMemo","getAllPanelPluginMeta","options","map","p","label","name","imgUrl","info","logos","small","value","sort","a","b","localeCompare","setValue","useState","useCallback","changedPlugins","filter","styles","useStyles2","getStyles","selectOptions","defaultOptions","getOptionLabel","i","getOptionValue","noOptionsMessage","placeholder","className","container","length","size","icon","fill","clear","onClick","prefix","theme","css","spacing","initialDeleteLibraryPanelModalState","loadingState","LoadingState","dashboardTitles","searchCompleted","createAction","deleteLibraryPanelModalReducer","state","action","match","payload","dashboards","d","title","DeleteLibraryPanelModal","libraryPanel","onDismiss","onConfirm","getModalStyles","dispatch","useReducer","asyncDispatch","asyncDispatcher","useEffect","async","apiGetConnectedDashboards","uid","getConnectedDashboards","connected","Boolean","done","Modal","modal","isOpen","LoadingIndicator","HasConnectedDashboards","Confirm","Button","variant","disabled","modalText","suffix","message","textInfo","myTable","LibraryPanelCard","onDelete","showSecondaryActions","showDeletionModal","setShowDeletionModal","panelPlugin","config","model","type","getPanelPluginNotFound","meta","PanelTypeCard","isCurrent","description","plugin","undefined","FolderLink","folderUid","folderName","metaContainer","Link","href","Icon","colors","text","secondary","typography","bodySmall","fontSize","FolderFilter","loading","setLoading","getOptions","searchString","params","query","DashboardSearchItemType","permission","PermissionLevelString","getBackendSrv","search","includes","toLowerCase","unshift","getFoldersAsOptions","debouncedLoadOptions","debounce","onSelectOptionChange","folders","changedFolderIds","f","isLoading","loadOptions","LibraryPanelsSearchVariant","LibraryPanelsSearch","Spacious","currentPanelId","currentFolderUID","perPage","DEFAULT_PER_PAGE_PAGINATION","showPanelFilter","showFolderFilter","showSort","tightLayout","filterInputWrapper","Tight","libraryPanelsView","gridContainer","searchQuery","setSearchQuery","debouncedSearchQuery","setDebouncedSearchQuery","useDebounce","sortDirection","setSortDirection","folderFilter","setFolderFilter","panelFilter","setPanelFilter","sortOrFiltersVisible","verticalGroupSpacing","FilterInput","width","escapeRegex","SearchControls","onSortChange","onFolderFilterChange","onPanelFilterChange","LibraryPanelsView","onClickCard","React","searchRowContainer","searchRowContainerTight","filterContainer","filterContainerTight","getRowStyles","panelFilterChanged","id","folderFilterChanged","SortPicker","displayName","currentPanel","propsPerPage","getPanelViewStyles","libraryPanels","page","numberOfPages","libraryPanelsViewReducer","initialLibraryPanelsViewState","searchForLibraryPanels","folderFilterUIDs","deleteLibraryPanel","cx","libraryPanelList","noPanelsFound","item","pagination","currentPage","onNavigate","changePage","hideWhenSinglePage","searchHeader","newPanelButton","args","subscription","Subscription","dataObservable","from","getLibraryPanels","excludeUid","typeFilter","pipe","mergeMap","elements","totalCount","of","catchError","err","console","error","finalize","unsubscribe","share","add","merge","timer","mapTo","initSearch","takeUntil","subscribe","apiDeleteLibraryPanel","e","Function","Math","ceil","shape","borderRadius","hover","background","primary","h6","noteTextbox","sm","dashboardSearch","h4","showBadge","children","isDisabled","PluginState","cssClass","itemDisabled","current","selectors","img","src","alt","itemContent","badge","PanelPluginBadge","stopPropagation","deleteButton","shadows","z1","transitions","create","duration","short","emphasize","disabledBackground","border","selected","disabledOpacity","fontWeightMedium","fontWeightLight","isUnsignedPluginSignature","signature","status","allPanels","Object","keys","key","filterPluginList","pluginsList","unEscapeStringFromRegex","first","isGraphQuery","startsWith","idx","indexOf","push","concat","PluginStateInfo","props","display","color","tooltip","getFeatureStateInfo"],"sourceRoot":""}