{"version":3,"file":"PluginListPage.c7454f0a41bdabf7d9d4.js","mappings":"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","sources":["webpack://grafana/./public/app/features/plugins/admin/components/Badges/PluginDisabledBadge.tsx","webpack://grafana/./public/app/features/plugins/admin/components/Badges/sharedStyles.ts","webpack://grafana/./public/app/features/plugins/admin/components/Badges/PluginInstallBadge.tsx","webpack://grafana/./public/app/features/plugins/admin/components/Badges/PluginEnterpriseBadge.tsx","webpack://grafana/./public/app/features/plugins/admin/components/Badges/PluginUpdateAvailableBadge.tsx","webpack://grafana/./public/app/features/plugins/admin/components/PluginLogo.tsx","webpack://grafana/./public/app/features/plugins/admin/components/HorizontalGroup.tsx","webpack://grafana/./public/app/features/plugins/admin/components/PluginListItemBadges.tsx","webpack://grafana/./public/app/features/plugins/admin/components/PluginListItem.tsx","webpack://grafana/./public/app/features/plugins/admin/components/PluginList.tsx","webpack://grafana/./public/app/features/plugins/admin/components/SearchField.tsx","webpack://grafana/./public/app/features/plugins/admin/pages/Browse.tsx","webpack://grafana/./public/app/features/plugins/admin/hooks/useHistory.tsx","webpack://grafana/./public/app/features/plugins/admin/state/selectors.ts","webpack://grafana/./public/app/features/plugins/admin/state/hooks.ts"],"sourcesContent":["import React from 'react';\n\nimport { PluginErrorCode } from '@grafana/data';\nimport { Badge } from '@grafana/ui';\n\ntype Props = { error?: PluginErrorCode };\n\nexport function PluginDisabledBadge({ error }: Props): React.ReactElement {\n const tooltip = errorCodeToTooltip(error);\n return ;\n}\n\nfunction errorCodeToTooltip(error?: PluginErrorCode): string | undefined {\n switch (error) {\n case PluginErrorCode.modifiedSignature:\n return 'Plugin disabled due to modified content';\n case PluginErrorCode.invalidSignature:\n return 'Plugin disabled due to invalid plugin signature';\n case PluginErrorCode.missingSignature:\n return 'Plugin disabled due to missing plugin signature';\n default:\n return `Plugin disabled due to unkown error: ${error}`;\n }\n}\n","import { css } from '@emotion/css';\n\nimport { GrafanaTheme2 } from '@grafana/data';\n\nexport const getBadgeColor = (theme: GrafanaTheme2) => css`\n background: ${theme.colors.background.primary};\n border-color: ${theme.colors.border.strong};\n color: ${theme.colors.text.secondary};\n`;\n","import React from 'react';\n\nimport { Badge, useStyles2 } from '@grafana/ui';\n\nimport { getBadgeColor } from './sharedStyles';\n\nexport function PluginInstalledBadge(): React.ReactElement {\n const customBadgeStyles = useStyles2(getBadgeColor);\n return ;\n}\n","import React from 'react';\n\nimport { featureEnabled } from '@grafana/runtime';\nimport { Badge, Button, HorizontalGroup, PluginSignatureBadge, useStyles2 } from '@grafana/ui';\n\nimport { CatalogPlugin } from '../../types';\n\nimport { getBadgeColor } from './sharedStyles';\n\ntype Props = { plugin: CatalogPlugin };\n\nexport function PluginEnterpriseBadge({ plugin }: Props): React.ReactElement {\n const customBadgeStyles = useStyles2(getBadgeColor);\n const onClick = (ev: React.MouseEvent) => {\n ev.preventDefault();\n window.open(\n `https://grafana.com/grafana/plugins/${plugin.id}?utm_source=grafana_catalog_learn_more`,\n '_blank',\n 'noopener,noreferrer'\n );\n };\n\n if (featureEnabled('enterprise.plugins')) {\n return ;\n }\n\n return (\n \n \n \n \n \n );\n}\n","import { css } from '@emotion/css';\nimport React from 'react';\n\nimport { GrafanaTheme2, PluginType } from '@grafana/data';\nimport { useStyles2 } from '@grafana/ui';\n\nimport { CatalogPlugin } from '../../types';\n\ntype Props = {\n plugin: CatalogPlugin;\n};\n\nexport function PluginUpdateAvailableBadge({ plugin }: Props): React.ReactElement | null {\n const styles = useStyles2(getStyles);\n\n // Currently renderer plugins are not supported by the catalog due to complications related to installation / update / uninstall.\n if (plugin.hasUpdate && !plugin.isCore && plugin.type !== PluginType.renderer) {\n return

Update available!

;\n }\n\n return null;\n}\n\nexport const getStyles = (theme: GrafanaTheme2) => {\n return {\n hasUpdate: css`\n color: ${theme.colors.text.secondary};\n font-size: ${theme.typography.bodySmall.fontSize};\n margin-bottom: 0;\n `,\n };\n};\n","import React from 'react';\n\ntype PluginLogoProps = {\n alt: string;\n className?: string;\n src: string;\n height?: string | number;\n};\n\nexport function PluginLogo({ alt, className, src, height }: PluginLogoProps): React.ReactElement {\n // @ts-ignore - react doesn't know about loading attr.\n return {alt};\n}\n","import { css, cx } from '@emotion/css';\nimport React from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { useTheme2 } from '@grafana/ui';\n\ninterface HorizontalGroupProps {\n children: React.ReactNode;\n wrap?: boolean;\n className?: string;\n}\n\nexport const HorizontalGroup = ({ children, wrap, className }: HorizontalGroupProps) => {\n const theme = useTheme2();\n const styles = getStyles(theme, wrap);\n\n return
{children}
;\n};\n\nconst getStyles = (theme: GrafanaTheme2, wrap?: boolean) => ({\n container: css`\n display: flex;\n flex-direction: row;\n flex-wrap: ${wrap ? 'wrap' : 'no-wrap'};\n & > * {\n margin-bottom: ${theme.spacing()};\n margin-right: ${theme.spacing()};\n }\n & > *:last-child {\n margin-right: 0;\n }\n `,\n});\n","import React from 'react';\n\nimport { HorizontalGroup, PluginSignatureBadge } from '@grafana/ui';\n\nimport { CatalogPlugin } from '../types';\n\nimport { PluginEnterpriseBadge, PluginDisabledBadge, PluginInstalledBadge, PluginUpdateAvailableBadge } from './Badges';\n\ntype PluginBadgeType = {\n plugin: CatalogPlugin;\n};\n\nexport function PluginListItemBadges({ plugin }: PluginBadgeType) {\n if (plugin.isEnterprise) {\n return (\n \n \n {plugin.isDisabled && }\n \n \n );\n }\n\n return (\n \n \n {plugin.isDisabled && }\n {plugin.isInstalled && }\n \n \n );\n}\n","import { css, cx } from '@emotion/css';\nimport React from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Icon, useStyles2 } from '@grafana/ui';\n\nimport { CatalogPlugin, PluginIconName, PluginListDisplayMode } from '../types';\n\nimport { PluginListItemBadges } from './PluginListItemBadges';\nimport { PluginLogo } from './PluginLogo';\n\nexport const LOGO_SIZE = '48px';\n\ntype Props = {\n plugin: CatalogPlugin;\n pathName: string;\n displayMode?: PluginListDisplayMode;\n};\n\nexport function PluginListItem({ plugin, pathName, displayMode = PluginListDisplayMode.Grid }: Props) {\n const styles = useStyles2(getStyles);\n const isList = displayMode === PluginListDisplayMode.List;\n\n return (\n \n \n

{plugin.name}

\n
\n

By {plugin.orgName}

\n \n
\n
\n {plugin.type && }\n
\n
\n );\n}\n\n// Styles shared between the different type of list items\nexport const getStyles = (theme: GrafanaTheme2) => {\n return {\n container: css`\n display: grid;\n grid-template-columns: ${LOGO_SIZE} 1fr ${theme.spacing(3)};\n grid-template-rows: auto;\n gap: ${theme.spacing(2)};\n grid-auto-flow: row;\n background: ${theme.colors.background.secondary};\n border-radius: ${theme.shape.borderRadius()};\n padding: ${theme.spacing(3)};\n transition: ${theme.transitions.create(['background-color', 'box-shadow', 'border-color', 'color'], {\n duration: theme.transitions.duration.short,\n })};\n\n &:hover {\n background: ${theme.colors.emphasize(theme.colors.background.secondary, 0.03)};\n }\n `,\n list: css`\n row-gap: 0px;\n\n > img {\n align-self: start;\n }\n\n > .plugin-content {\n min-height: 0px;\n grid-area: 2 / 2 / 4 / 3;\n\n > p {\n margin: ${theme.spacing(0, 0, 0.5, 0)};\n }\n }\n\n > .plugin-name {\n align-self: center;\n grid-area: 1 / 2 / 2 / 3;\n }\n `,\n pluginType: css`\n grid-area: 1 / 3 / 2 / 4;\n color: ${theme.colors.text.secondary};\n `,\n pluginLogo: css`\n grid-area: 1 / 1 / 3 / 2;\n max-width: 100%;\n align-self: center;\n object-fit: contain;\n `,\n content: css`\n grid-area: 3 / 1 / 4 / 3;\n color: ${theme.colors.text.secondary};\n `,\n name: css`\n grid-area: 1 / 2 / 3 / 3;\n align-self: center;\n font-size: ${theme.typography.h4.fontSize};\n color: ${theme.colors.text.primary};\n margin: 0;\n `,\n };\n};\n","import { css, cx } from '@emotion/css';\nimport React from 'react';\nimport { useLocation } from 'react-router-dom';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { useStyles2 } from '@grafana/ui';\n\nimport { CatalogPlugin, PluginListDisplayMode } from '../types';\n\nimport { PluginListItem } from './PluginListItem';\n\ninterface Props {\n plugins: CatalogPlugin[];\n displayMode: PluginListDisplayMode;\n}\n\nexport const PluginList = ({ plugins, displayMode }: Props) => {\n const isList = displayMode === PluginListDisplayMode.List;\n const styles = useStyles2(getStyles);\n const location = useLocation();\n\n return (\n
\n {plugins.map((plugin) => (\n \n ))}\n
\n );\n};\n\nconst getStyles = (theme: GrafanaTheme2) => {\n return {\n container: css`\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(288px, 1fr));\n gap: ${theme.spacing(3)};\n `,\n list: css`\n grid-template-columns: 1fr;\n `,\n };\n};\n","import React, { useState, useRef } from 'react';\nimport { useDebounce } from 'react-use';\n\nimport { FilterInput } from '@grafana/ui';\n\ninterface Props {\n value?: string;\n onSearch: (value: string) => void;\n}\n\n// useDebounce has a bug which causes it to fire on first render. This wrapper prevents that.\n// https://github.com/streamich/react-use/issues/759\nconst useDebounceWithoutFirstRender = (callBack: () => any, delay = 0, deps: React.DependencyList = []) => {\n const isFirstRender = useRef(true);\n const debounceDeps = [...deps, isFirstRender];\n\n return useDebounce(\n () => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n return;\n }\n return callBack();\n },\n delay,\n debounceDeps\n );\n};\n\nexport const SearchField = ({ value, onSearch }: Props) => {\n const [query, setQuery] = useState(value);\n\n useDebounceWithoutFirstRender(() => onSearch(query ?? ''), 500, [query]);\n\n return (\n {\n if (e.key === 'Enter' || e.keyCode === 13) {\n onSearch(e.currentTarget.value);\n }\n }}\n placeholder=\"Search Grafana plugins\"\n onChange={(value) => {\n setQuery(value);\n }}\n width={46}\n />\n );\n};\n","import { css } from '@emotion/css';\nimport React, { ReactElement } from 'react';\nimport { useSelector } from 'react-redux';\nimport { useLocation } from 'react-router-dom';\n\nimport { SelectableValue, GrafanaTheme2 } from '@grafana/data';\nimport { locationSearchToObject } from '@grafana/runtime';\nimport { LoadingPlaceholder, Select, RadioButtonGroup, useStyles2, Tooltip } from '@grafana/ui';\nimport { Page } from 'app/core/components/Page/Page';\nimport { GrafanaRouteComponentProps } from 'app/core/navigation/types';\nimport { getNavModel } from 'app/core/selectors/navModel';\nimport { StoreState } from 'app/types/store';\n\nimport { HorizontalGroup } from '../components/HorizontalGroup';\nimport { PluginList } from '../components/PluginList';\nimport { SearchField } from '../components/SearchField';\nimport { Sorters } from '../helpers';\nimport { useHistory } from '../hooks/useHistory';\nimport { useGetAllWithFilters, useIsRemotePluginsAvailable, useDisplayMode } from '../state/hooks';\nimport { PluginAdminRoutes, PluginListDisplayMode } from '../types';\n\nexport default function Browse({ route }: GrafanaRouteComponentProps): ReactElement | null {\n const location = useLocation();\n const locationSearch = locationSearchToObject(location.search);\n const navModelId = getNavModelId(route.routeName);\n const navModel = useSelector((state: StoreState) => getNavModel(state.navIndex, navModelId));\n const { displayMode, setDisplayMode } = useDisplayMode();\n const styles = useStyles2(getStyles);\n const history = useHistory();\n const remotePluginsAvailable = useIsRemotePluginsAvailable();\n const query = (locationSearch.q as string) || '';\n const filterBy = (locationSearch.filterBy as string) || 'installed';\n const filterByType = (locationSearch.filterByType as string) || 'all';\n const sortBy = (locationSearch.sortBy as Sorters) || Sorters.nameAsc;\n const { isLoading, error, plugins } = useGetAllWithFilters({\n query,\n filterBy,\n filterByType,\n sortBy,\n });\n const filterByOptions = [\n { value: 'all', label: 'All' },\n { value: 'installed', label: 'Installed' },\n ];\n\n const onSortByChange = (value: SelectableValue) => {\n history.push({ query: { sortBy: value.value } });\n };\n\n const onFilterByChange = (value: string) => {\n history.push({ query: { filterBy: value } });\n };\n\n const onFilterByTypeChange = (value: string) => {\n history.push({ query: { filterByType: value } });\n };\n\n const onSearch = (q: any) => {\n history.push({ query: { filterBy: 'all', filterByType: 'all', q } });\n };\n\n // How should we handle errors?\n if (error) {\n console.error(error.message);\n return null;\n }\n\n return (\n \n \n \n \n \n {/* Filter by type */}\n
\n \n
\n\n {/* Filter by installed / all */}\n {remotePluginsAvailable ? (\n
\n \n
\n ) : (\n \n
\n \n
\n \n )}\n\n {/* Sorting */}\n
\n \n
\n\n {/* Display mode */}\n
\n \n className={styles.displayAs}\n value={displayMode}\n onChange={setDisplayMode}\n options={[\n {\n value: PluginListDisplayMode.Grid,\n icon: 'table',\n description: 'Display plugins in a grid layout',\n },\n { value: PluginListDisplayMode.List, icon: 'list-ul', description: 'Display plugins in list' },\n ]}\n />\n
\n
\n
\n
\n {isLoading ? (\n \n ) : (\n \n )}\n
\n
\n
\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n actionBar: css`\n ${theme.breakpoints.up('xl')} {\n margin-left: auto;\n }\n `,\n listWrap: css`\n margin-top: ${theme.spacing(2)};\n `,\n displayAs: css`\n svg {\n margin-right: 0;\n }\n `,\n});\n\n// Because the component is used under multiple paths (/plugins and /admin/plugins) we need to get\n// the correct navModel from the store\nconst getNavModelId = (routeName?: string) => {\n if (routeName === PluginAdminRoutes.HomeAdmin || routeName === PluginAdminRoutes.BrowseAdmin) {\n return 'admin-plugins';\n }\n\n return 'plugins';\n};\n","import { locationService } from '@grafana/runtime';\n\nexport const useHistory = () => {\n return {\n push: ({ query }: any) => {\n locationService.partial(query);\n },\n };\n};\n","import { createSelector } from '@reduxjs/toolkit';\n\nimport { PluginError, PluginErrorCode } from '@grafana/data';\n\nimport { RequestStatus, PluginCatalogStoreState } from '../types';\n\nimport { pluginsAdapter } from './reducer';\n\nexport const selectRoot = (state: PluginCatalogStoreState) => state.plugins;\n\nexport const selectItems = createSelector(selectRoot, ({ items }) => items);\n\nexport const selectDisplayMode = createSelector(selectRoot, ({ settings }) => settings.displayMode);\n\nexport const { selectAll, selectById } = pluginsAdapter.getSelectors(selectItems);\n\nconst selectInstalled = (filterBy: string) =>\n createSelector(selectAll, (plugins) =>\n plugins.filter((plugin) => (filterBy === 'installed' ? plugin.isInstalled : !plugin.isCore))\n );\n\nconst findByInstallAndType = (filterBy: string, filterByType: string) =>\n createSelector(selectInstalled(filterBy), (plugins) =>\n plugins.filter((plugin) => filterByType === 'all' || plugin.type === filterByType)\n );\n\nconst findByKeyword = (searchBy: string) =>\n createSelector(selectAll, (plugins) => {\n if (searchBy === '') {\n return [];\n }\n\n return plugins.filter((plugin) => {\n const fields: String[] = [];\n if (plugin.name) {\n fields.push(plugin.name.toLowerCase());\n }\n\n if (plugin.orgName) {\n fields.push(plugin.orgName.toLowerCase());\n }\n\n return fields.some((f) => f.includes(searchBy.toLowerCase()));\n });\n });\n\nexport const find = (searchBy: string, filterBy: string, filterByType: string) =>\n createSelector(\n findByInstallAndType(filterBy, filterByType),\n findByKeyword(searchBy),\n (filteredPlugins, searchedPlugins) => {\n return searchBy === '' ? filteredPlugins : searchedPlugins;\n }\n );\n\nexport const selectPluginErrors = createSelector(selectAll, (plugins) =>\n plugins\n ? plugins\n .filter((p) => Boolean(p.error))\n .map(\n (p): PluginError => ({\n pluginId: p.id,\n errorCode: p!.error as PluginErrorCode,\n })\n )\n : []\n);\n\n// The following selectors are used to get information about the outstanding or completed plugins-related network requests.\nexport const selectRequest = (actionType: string) =>\n createSelector(selectRoot, ({ requests = {} }) => requests[actionType]);\n\nexport const selectIsRequestPending = (actionType: string) =>\n createSelector(selectRequest(actionType), (request) => request?.status === RequestStatus.Pending);\n\nexport const selectRequestError = (actionType: string) =>\n createSelector(selectRequest(actionType), (request) =>\n request?.status === RequestStatus.Rejected ? request?.error : null\n );\n\nexport const selectIsRequestNotFetched = (actionType: string) =>\n createSelector(selectRequest(actionType), (request) => request === undefined);\n","import { useEffect } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\n\nimport { PluginError } from '@grafana/data';\n\nimport { sortPlugins, Sorters } from '../helpers';\nimport { CatalogPlugin, PluginCatalogStoreState, PluginListDisplayMode } from '../types';\n\nimport { fetchAll, fetchDetails, fetchRemotePlugins, install, uninstall } from './actions';\nimport { setDisplayMode } from './reducer';\nimport {\n find,\n selectAll,\n selectById,\n selectIsRequestPending,\n selectRequestError,\n selectIsRequestNotFetched,\n selectDisplayMode,\n selectPluginErrors,\n} from './selectors';\n\ntype Filters = {\n query?: string;\n filterBy?: string;\n filterByType?: string;\n sortBy?: Sorters;\n};\n\nexport const useGetAllWithFilters = ({\n query = '',\n filterBy = 'installed',\n filterByType = 'all',\n sortBy = Sorters.nameAsc,\n}: Filters) => {\n useFetchAll();\n\n const filtered = useSelector(find(query, filterBy, filterByType));\n const { isLoading, error } = useFetchStatus();\n const sortedAndFiltered = sortPlugins(filtered, sortBy);\n\n return {\n isLoading,\n error,\n plugins: sortedAndFiltered,\n };\n};\n\nexport const useGetAll = (): CatalogPlugin[] => {\n useFetchAll();\n\n return useSelector(selectAll);\n};\n\nexport const useGetSingle = (id: string): CatalogPlugin | undefined => {\n useFetchAll();\n useFetchDetails(id);\n\n return useSelector((state: PluginCatalogStoreState) => selectById(state, id));\n};\n\nexport const useGetErrors = (): PluginError[] => {\n useFetchAll();\n\n return useSelector(selectPluginErrors);\n};\n\nexport const useInstall = () => {\n const dispatch = useDispatch();\n return (id: string, version?: string, isUpdating?: boolean) => dispatch(install({ id, version, isUpdating }));\n};\n\nexport const useUninstall = () => {\n const dispatch = useDispatch();\n\n return (id: string) => dispatch(uninstall(id));\n};\n\nexport const useIsRemotePluginsAvailable = () => {\n const error = useSelector(selectRequestError(fetchRemotePlugins.typePrefix));\n return error === null;\n};\n\nexport const useFetchStatus = () => {\n const isLoading = useSelector(selectIsRequestPending(fetchAll.typePrefix));\n const error = useSelector(selectRequestError(fetchAll.typePrefix));\n\n return { isLoading, error };\n};\n\nexport const useFetchDetailsStatus = () => {\n const isLoading = useSelector(selectIsRequestPending(fetchDetails.typePrefix));\n const error = useSelector(selectRequestError(fetchDetails.typePrefix));\n\n return { isLoading, error };\n};\n\nexport const useInstallStatus = () => {\n const isInstalling = useSelector(selectIsRequestPending(install.typePrefix));\n const error = useSelector(selectRequestError(install.typePrefix));\n\n return { isInstalling, error };\n};\n\nexport const useUninstallStatus = () => {\n const isUninstalling = useSelector(selectIsRequestPending(uninstall.typePrefix));\n const error = useSelector(selectRequestError(uninstall.typePrefix));\n\n return { isUninstalling, error };\n};\n\n// Only fetches in case they were not fetched yet\nexport const useFetchAll = () => {\n const dispatch = useDispatch();\n const isNotFetched = useSelector(selectIsRequestNotFetched(fetchAll.typePrefix));\n\n useEffect(() => {\n isNotFetched && dispatch(fetchAll());\n }, []); // eslint-disable-line\n};\n\nexport const useFetchDetails = (id: string) => {\n const dispatch = useDispatch();\n const plugin = useSelector((state: PluginCatalogStoreState) => selectById(state, id));\n const isNotFetching = !useSelector(selectIsRequestPending(fetchDetails.typePrefix));\n const shouldFetch = isNotFetching && plugin && !plugin.details;\n\n useEffect(() => {\n shouldFetch && dispatch(fetchDetails(id));\n }, [plugin]); // eslint-disable-line\n};\n\nexport const useDisplayMode = () => {\n const dispatch = useDispatch();\n const displayMode = useSelector(selectDisplayMode);\n\n return {\n displayMode,\n setDisplayMode: (v: PluginListDisplayMode) => dispatch(setDisplayMode(v)),\n };\n};\n"],"names":["PluginDisabledBadge","error","tooltip","PluginErrorCode","errorCodeToTooltip","Badge","icon","text","color","getBadgeColor","theme","css","colors","background","primary","border","strong","secondary","PluginInstalledBadge","customBadgeStyles","useStyles2","className","PluginEnterpriseBadge","plugin","featureEnabled","HorizontalGroup","PluginSignatureBadge","status","signature","Button","size","fill","onClick","ev","preventDefault","window","open","id","PluginUpdateAvailableBadge","styles","getStyles","hasUpdate","isCore","type","PluginType","typography","bodySmall","fontSize","PluginLogo","alt","src","height","loading","children","wrap","useTheme2","cx","container","spacing","PluginListItemBadges","isEnterprise","isDisabled","isInstalled","LOGO_SIZE","PluginListItem","pathName","displayMode","PluginListDisplayMode","isList","href","list","info","logos","small","pluginLogo","name","content","orgName","pluginType","Icon","PluginIconName","title","shape","borderRadius","transitions","create","duration","short","emphasize","h4","PluginList","plugins","location","useLocation","map","pathname","SearchField","value","onSearch","query","setQuery","useState","callBack","delay","deps","isFirstRender","useRef","debounceDeps","useDebounce","current","useDebounceWithoutFirstRender","FilterInput","onKeyDown","e","key","keyCode","currentTarget","placeholder","onChange","width","Browse","route","locationSearch","locationSearchToObject","search","navModelId","getNavModelId","routeName","navModel","useSelector","state","getNavModel","navIndex","setDisplayMode","useDisplayMode","history","push","locationService","remotePluginsAvailable","useIsRemotePluginsAvailable","q","filterBy","filterByType","sortBy","Sorters","isLoading","useGetAllWithFilters","filterByOptions","label","onFilterByChange","console","message","Page","actionBar","RadioButtonGroup","options","Tooltip","placement","disabled","Select","displayAs","description","listWrap","LoadingPlaceholder","breakpoints","up","PluginAdminRoutes","selectRoot","selectItems","createSelector","items","selectDisplayMode","settings","selectAll","selectById","pluginsAdapter","findByInstallAndType","filter","selectInstalled","find","searchBy","fields","toLowerCase","some","f","includes","findByKeyword","filteredPlugins","searchedPlugins","selectPluginErrors","p","Boolean","pluginId","errorCode","selectRequest","actionType","requests","selectIsRequestPending","request","RequestStatus","selectRequestError","useFetchAll","filtered","useFetchStatus","sortPlugins","useGetSingle","useFetchDetails","useGetErrors","useInstall","dispatch","useDispatch","version","isUpdating","install","useUninstall","uninstall","fetchRemotePlugins","fetchAll","useFetchDetailsStatus","fetchDetails","useInstallStatus","isInstalling","useUninstallStatus","isUninstalling","isNotFetched","undefined","useEffect","shouldFetch","details","v"],"sourceRoot":""}