1 |
- {"version":3,"file":"NewDataSourcePage.76cdc49b40e73b8a8e27.js","mappings":"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","sources":["webpack://grafana/./public/app/features/plugins/components/PluginsErrorsInfo.tsx","webpack://grafana/./public/app/features/datasources/NewDataSourcePage.tsx","webpack://grafana/./public/app/features/plugins/admin/state/selectors.ts","webpack://grafana/./public/app/features/plugins/admin/state/hooks.ts"],"sourcesContent":["import { css } from '@emotion/css';\nimport React from 'react';\n\nimport { PluginErrorCode, PluginSignatureStatus } from '@grafana/data';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { HorizontalGroup, InfoBox, List, PluginSignatureBadge, useTheme } from '@grafana/ui';\n\nimport { useGetErrors, useFetchStatus } from '../admin/state/hooks';\n\nexport function PluginsErrorsInfo(): React.ReactElement | null {\n const errors = useGetErrors();\n const { isLoading } = useFetchStatus();\n const theme = useTheme();\n\n if (isLoading || errors.length === 0) {\n return null;\n }\n\n return (\n <InfoBox\n aria-label={selectors.pages.PluginsList.signatureErrorNotice}\n severity=\"warning\"\n urlTitle=\"Read more about plugin signing\"\n url=\"https://grafana.com/docs/grafana/latest/plugins/plugin-signatures/\"\n >\n <div>\n <p>\n Unsigned plugins were found during plugin initialization. Grafana Labs cannot guarantee the integrity of these\n plugins. We recommend only using signed plugins.\n </p>\n The following plugins are disabled and not shown in the list below:\n <List\n items={errors}\n className={css`\n list-style-type: circle;\n `}\n renderItem={(error) => (\n <div\n className={css`\n margin-top: ${theme.spacing.sm};\n `}\n >\n <HorizontalGroup spacing=\"sm\" justify=\"flex-start\" align=\"center\">\n <strong>{error.pluginId}</strong>\n <PluginSignatureBadge\n status={mapPluginErrorCodeToSignatureStatus(error.errorCode)}\n className={css`\n margin-top: 0;\n `}\n />\n </HorizontalGroup>\n </div>\n )}\n />\n </div>\n </InfoBox>\n );\n}\n\nfunction mapPluginErrorCodeToSignatureStatus(code: PluginErrorCode) {\n switch (code) {\n case PluginErrorCode.invalidSignature:\n return PluginSignatureStatus.invalid;\n case PluginErrorCode.missingSignature:\n return PluginSignatureStatus.missing;\n case PluginErrorCode.modifiedSignature:\n return PluginSignatureStatus.modified;\n default:\n return PluginSignatureStatus.missing;\n }\n}\n","import { css, cx } from '@emotion/css';\nimport React, { FC, PureComponent } from 'react';\nimport { connect, ConnectedProps } from 'react-redux';\n\nimport { DataSourcePluginMeta, GrafanaTheme2, NavModel } from '@grafana/data';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { Card, LinkButton, List, PluginSignatureBadge, FilterInput, useStyles2 } from '@grafana/ui';\nimport Page from 'app/core/components/Page/Page';\nimport { StoreState } from 'app/types';\n\nimport { PluginsErrorsInfo } from '../plugins/components/PluginsErrorsInfo';\n\nimport { addDataSource, loadDataSourcePlugins } from './state/actions';\nimport { setDataSourceTypeSearchQuery } from './state/reducers';\nimport { getDataSourcePlugins } from './state/selectors';\n\nfunction mapStateToProps(state: StoreState) {\n return {\n navModel: getNavModel(),\n plugins: getDataSourcePlugins(state.dataSources),\n searchQuery: state.dataSources.dataSourceTypeSearchQuery,\n categories: state.dataSources.categories,\n isLoading: state.dataSources.isLoadingDataSources,\n };\n}\n\nconst mapDispatchToProps = {\n addDataSource,\n loadDataSourcePlugins,\n setDataSourceTypeSearchQuery,\n};\n\nconst connector = connect(mapStateToProps, mapDispatchToProps);\n\ntype Props = ConnectedProps<typeof connector>;\n\nclass NewDataSourcePage extends PureComponent<Props> {\n componentDidMount() {\n this.props.loadDataSourcePlugins();\n }\n\n onDataSourceTypeClicked = (plugin: DataSourcePluginMeta) => {\n this.props.addDataSource(plugin);\n };\n\n onSearchQueryChange = (value: string) => {\n this.props.setDataSourceTypeSearchQuery(value);\n };\n\n renderPlugins(plugins: DataSourcePluginMeta[], id?: string) {\n if (!plugins || !plugins.length) {\n return null;\n }\n\n return (\n <List\n items={plugins}\n className={css`\n > li {\n margin-bottom: 2px;\n }\n `}\n getItemKey={(item) => item.id.toString()}\n renderItem={(item) => (\n <DataSourceTypeCard\n plugin={item}\n onClick={() => this.onDataSourceTypeClicked(item)}\n onLearnMoreClick={this.onLearnMoreClick}\n />\n )}\n aria-labelledby={id}\n />\n );\n }\n\n onLearnMoreClick = (evt: React.SyntheticEvent<HTMLElement>) => {\n evt.stopPropagation();\n };\n\n renderCategories() {\n const { categories } = this.props;\n\n return (\n <>\n {categories.map((category) => (\n <div className=\"add-data-source-category\" key={category.id}>\n <div className=\"add-data-source-category__header\" id={category.id}>\n {category.title}\n </div>\n {this.renderPlugins(category.plugins, category.id)}\n </div>\n ))}\n <div className=\"add-data-source-more\">\n <LinkButton\n variant=\"secondary\"\n href=\"https://grafana.com/plugins?type=datasource&utm_source=grafana_add_ds\"\n target=\"_blank\"\n rel=\"noopener\"\n >\n Find more data source plugins on grafana.com\n </LinkButton>\n </div>\n </>\n );\n }\n\n render() {\n const { navModel, isLoading, searchQuery, plugins } = this.props;\n\n return (\n <Page navModel={navModel}>\n <Page.Contents isLoading={isLoading}>\n <div className=\"page-action-bar\">\n <FilterInput value={searchQuery} onChange={this.onSearchQueryChange} placeholder=\"Filter by name or type\" />\n <div className=\"page-action-bar__spacer\" />\n <LinkButton href=\"datasources\" fill=\"outline\" variant=\"secondary\" icon=\"arrow-left\">\n Cancel\n </LinkButton>\n </div>\n {!searchQuery && <PluginsErrorsInfo />}\n <div>\n {searchQuery && this.renderPlugins(plugins)}\n {!searchQuery && this.renderCategories()}\n </div>\n </Page.Contents>\n </Page>\n );\n }\n}\n\ninterface DataSourceTypeCardProps {\n plugin: DataSourcePluginMeta;\n onClick: () => void;\n onLearnMoreClick: (evt: React.SyntheticEvent<HTMLElement>) => void;\n}\n\nconst DataSourceTypeCard: FC<DataSourceTypeCardProps> = (props) => {\n const { plugin, onLearnMoreClick } = props;\n const isPhantom = plugin.module === 'phantom';\n const onClick = !isPhantom && !plugin.unlicensed ? props.onClick : () => {};\n // find first plugin info link\n const learnMoreLink = plugin.info?.links?.length > 0 ? plugin.info.links[0] : null;\n\n const styles = useStyles2(getStyles);\n\n return (\n <Card className={cx(styles.card, 'card-parent')} onClick={onClick}>\n <Card.Heading\n className={styles.heading}\n aria-label={selectors.pages.AddDataSource.dataSourcePluginsV2(plugin.name)}\n >\n {plugin.name}\n </Card.Heading>\n <Card.Figure align=\"center\" className={styles.figure}>\n <img className={styles.logo} src={plugin.info.logos.small} alt=\"\" />\n </Card.Figure>\n <Card.Description className={styles.description}>{plugin.info.description}</Card.Description>\n {!isPhantom && (\n <Card.Meta className={styles.meta}>\n <PluginSignatureBadge status={plugin.signature} />\n </Card.Meta>\n )}\n <Card.Actions className={styles.actions}>\n {learnMoreLink && (\n <LinkButton\n variant=\"secondary\"\n href={`${learnMoreLink.url}?utm_source=grafana_add_ds`}\n target=\"_blank\"\n rel=\"noopener\"\n onClick={onLearnMoreClick}\n icon=\"external-link-alt\"\n aria-label={`${plugin.name}, learn more.`}\n >\n {learnMoreLink.name}\n </LinkButton>\n )}\n </Card.Actions>\n </Card>\n );\n};\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n heading: css({\n fontSize: theme.v1.typography.heading.h5,\n fontWeight: 'inherit',\n }),\n figure: css({\n width: 'inherit',\n marginRight: '0px',\n '> img': {\n width: theme.spacing(7),\n },\n }),\n meta: css({\n marginTop: '6px',\n position: 'relative',\n }),\n description: css({\n margin: '0px',\n fontSize: theme.typography.size.sm,\n }),\n actions: css({\n position: 'relative',\n alignSelf: 'center',\n marginTop: '0px',\n opacity: 0,\n\n '.card-parent:hover &, .card-parent:focus-within &': {\n opacity: 1,\n },\n }),\n card: css({\n gridTemplateAreas: `\n \"Figure Heading Actions\"\n \"Figure Description Actions\"\n \"Figure Meta Actions\"\n \"Figure - Actions\"`,\n }),\n logo: css({\n marginRight: theme.v1.spacing.lg,\n marginLeft: theme.v1.spacing.sm,\n width: theme.spacing(7),\n maxHeight: theme.spacing(7),\n }),\n };\n}\n\nexport function getNavModel(): NavModel {\n const main = {\n icon: 'database',\n id: 'datasource-new',\n text: 'Add data source',\n href: 'datasources/new',\n subTitle: 'Choose a data source type',\n };\n\n return {\n main: main,\n node: main,\n };\n}\n\nexport default connector(NewDataSourcePage);\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":["PluginsErrorsInfo","errors","useGetErrors","isLoading","useFetchStatus","theme","useTheme","length","InfoBox","selectors","severity","urlTitle","url","List","items","className","css","renderItem","error","spacing","sm","HorizontalGroup","justify","align","pluginId","PluginSignatureBadge","status","mapPluginErrorCodeToSignatureStatus","errorCode","code","PluginErrorCode","PluginSignatureStatus","mapDispatchToProps","addDataSource","loadDataSourcePlugins","setDataSourceTypeSearchQuery","connector","connect","state","navModel","getNavModel","plugins","getDataSourcePlugins","dataSources","searchQuery","dataSourceTypeSearchQuery","categories","isLoadingDataSources","NewDataSourcePage","PureComponent","plugin","this","props","value","evt","stopPropagation","componentDidMount","renderPlugins","id","getItemKey","item","toString","DataSourceTypeCard","onClick","onDataSourceTypeClicked","onLearnMoreClick","renderCategories","map","category","title","LinkButton","variant","href","target","rel","render","Page","FilterInput","onChange","onSearchQueryChange","placeholder","fill","icon","isPhantom","module","unlicensed","learnMoreLink","info","links","styles","useStyles2","getStyles","Card","cx","card","heading","name","figure","logo","src","logos","small","alt","description","meta","signature","actions","fontSize","v1","typography","h5","fontWeight","width","marginRight","marginTop","position","margin","size","alignSelf","opacity","gridTemplateAreas","lg","marginLeft","maxHeight","main","text","subTitle","node","selectRoot","selectItems","createSelector","selectDisplayMode","settings","displayMode","selectAll","selectById","pluginsAdapter","findByInstallAndType","filterBy","filterByType","filter","isInstalled","isCore","selectInstalled","type","find","searchBy","fields","push","toLowerCase","orgName","some","f","includes","findByKeyword","filteredPlugins","searchedPlugins","selectPluginErrors","p","Boolean","selectRequest","actionType","requests","selectIsRequestPending","request","RequestStatus","selectRequestError","useGetAllWithFilters","query","sortBy","Sorters","useFetchAll","filtered","useSelector","sortPlugins","useGetSingle","useFetchDetails","useInstall","dispatch","useDispatch","version","isUpdating","install","useUninstall","uninstall","useIsRemotePluginsAvailable","fetchRemotePlugins","fetchAll","useFetchDetailsStatus","fetchDetails","useInstallStatus","isInstalling","useUninstallStatus","isUninstalling","isNotFetched","undefined","useEffect","shouldFetch","details","useDisplayMode","setDisplayMode","v"],"sourceRoot":""}
|