1 |
- {"version":3,"file":"DashboardImport.eb3a3448f35ab8116a37.js","mappings":"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","sources":["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/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/manage-dashboards/utils/validation.ts","webpack://grafana/./public/app/features/manage-dashboards/components/ImportDashboardLibraryPanelsList.tsx","webpack://grafana/./public/app/features/manage-dashboards/components/ImportDashboardForm.tsx","webpack://grafana/./public/app/features/manage-dashboards/components/ImportDashboardOverview.tsx","webpack://grafana/./public/app/features/manage-dashboards/DashboardImportPage.tsx","webpack://grafana/./public/app/features/panel/components/VizTypePicker/PanelTypeCard.tsx","webpack://grafana/./public/app/features/plugins/components/PluginStateInfo.tsx"],"sourcesContent":["import { createAction } from '@reduxjs/toolkit';\nimport { AnyAction } from 'redux';\n\nimport { LoadingState } from '@grafana/data';\nimport { DashboardSearchHit } 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: DashboardSearchHit[] }>(\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, useStyles } 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 = useStyles(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: FC = () => <span>Loading library panel...</span>;\n\nconst Confirm: FC = () => {\n const styles = useStyles(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 = useStyles(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 { 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 folderFilter?: 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 folderFilter: args.folderFilter,\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 { GrafanaTheme } from '@grafana/data';\n\nexport function getModalStyles(theme: GrafanaTheme) {\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.border.radius.sm};\n border: 1px solid ${theme.colors.bg3};\n background: ${theme.colors.bg1};\n color: ${theme.colors.textSemiWeak};\n font-size: ${theme.typography.size.md};\n width: 100%;\n\n thead {\n color: #538ade;\n font-size: ${theme.typography.size.sm};\n }\n\n th,\n td {\n padding: 6px 13px;\n height: ${theme.spacing.xl};\n }\n\n tbody > tr:nth-child(odd) {\n background: ${theme.colors.bg2};\n }\n `,\n noteTextbox: css`\n margin-bottom: ${theme.spacing.xl};\n `,\n textInfo: css`\n color: ${theme.colors.textSemiWeak};\n font-size: ${theme.typography.size.sm};\n `,\n dashboardSearch: css`\n margin-top: ${theme.spacing.md};\n `,\n modal: css`\n width: 500px;\n `,\n modalText: css`\n font-size: ${theme.typography.heading.h4};\n color: ${theme.colors.link};\n margin-bottom: calc(${theme.spacing.d} * 2);\n padding-top: ${theme.spacing.d};\n `,\n };\n}\n","import { getBackendSrv } from '@grafana/runtime';\n\nimport { validationSrv } from '../services/ValidationSrv';\n\nexport const validateDashboardJson = (json: string) => {\n try {\n JSON.parse(json);\n return true;\n } catch (error) {\n return 'Not valid JSON';\n }\n};\n\nexport const validateGcomDashboard = (gcomDashboard: string) => {\n // From DashboardImportCtrl\n const match = /(^\\d+$)|dashboards\\/(\\d+)/.exec(gcomDashboard);\n\n return match && (match[1] || match[2]) ? true : 'Could not find a valid Grafana.com ID';\n};\n\nexport const validateTitle = (newTitle: string, folderId: number) => {\n return validationSrv\n .validateNewDashboardName(folderId, newTitle)\n .then(() => {\n return true;\n })\n .catch((error) => {\n if (error.type === 'EXISTING') {\n return error.message;\n }\n });\n};\n\nexport const validateUid = (value: string) => {\n return getBackendSrv()\n .get(`/api/dashboards/uid/${value}`)\n .then((existingDashboard) => {\n return `Dashboard named '${existingDashboard?.dashboard.title}' in folder '${existingDashboard?.meta.folderTitle}' has the same UID`;\n })\n .catch((error) => {\n error.isHandled = true;\n return true;\n });\n};\n","import { css } from '@emotion/css';\nimport React, { ReactElement } from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { Field, useStyles2 } from '@grafana/ui';\n\nimport { LibraryPanelCard } from '../../library-panels/components/LibraryPanelCard/LibraryPanelCard';\nimport { LibraryPanelInput, LibraryPanelInputState } from '../state/reducers';\n\ninterface ImportDashboardLibraryPanelsListProps {\n inputs: LibraryPanelInput[];\n label: string;\n description: string;\n folderName?: string;\n}\n\nexport function ImportDashboardLibraryPanelsList({\n inputs,\n label,\n description,\n folderName,\n}: ImportDashboardLibraryPanelsListProps): ReactElement | null {\n const styles = useStyles2(getStyles);\n\n if (!Boolean(inputs?.length)) {\n return null;\n }\n\n return (\n <div className={styles.spacer}>\n <Field label={label} description={description}>\n <>\n {inputs.map((input, index) => {\n const libraryPanelIndex = `elements[${index}]`;\n const libraryPanel =\n input.state === LibraryPanelInputState.New\n ? { ...input.model, meta: { ...input.model.meta, folderName: folderName ?? 'General' } }\n : { ...input.model };\n return (\n <div className={styles.item} key={libraryPanelIndex}>\n <LibraryPanelCard libraryPanel={libraryPanel} onClick={() => undefined} />\n </div>\n );\n })}\n </>\n </Field>\n </div>\n );\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n spacer: css`\n margin-bottom: ${theme.spacing(2)};\n `,\n item: css`\n margin-bottom: ${theme.spacing(1)};\n `,\n };\n}\n","import React, { FC, useEffect, useState } from 'react';\n\nimport { selectors } from '@grafana/e2e-selectors';\nimport { DataSourcePicker } from '@grafana/runtime';\nimport { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend';\nimport {\n Button,\n Field,\n FormAPI,\n FormFieldErrors,\n FormsOnSubmit,\n HorizontalGroup,\n Input,\n InputControl,\n Legend,\n} from '@grafana/ui';\nimport { FolderPicker } from 'app/core/components/Select/FolderPicker';\n\nimport {\n DashboardInput,\n DashboardInputs,\n DataSourceInput,\n ImportDashboardDTO,\n LibraryPanelInputState,\n} from '../state/reducers';\nimport { validateTitle, validateUid } from '../utils/validation';\n\nimport { ImportDashboardLibraryPanelsList } from './ImportDashboardLibraryPanelsList';\n\ninterface Props extends Pick<FormAPI<ImportDashboardDTO>, 'register' | 'errors' | 'control' | 'getValues' | 'watch'> {\n uidReset: boolean;\n inputs: DashboardInputs;\n initialFolderId: number;\n\n onCancel: () => void;\n onUidReset: () => void;\n onSubmit: FormsOnSubmit<ImportDashboardDTO>;\n}\n\nexport const ImportDashboardForm: FC<Props> = ({\n register,\n errors,\n control,\n getValues,\n uidReset,\n inputs,\n initialFolderId,\n onUidReset,\n onCancel,\n onSubmit,\n watch,\n}) => {\n const [isSubmitted, setSubmitted] = useState(false);\n const watchDataSources = watch('dataSources');\n const watchFolder = watch('folder');\n\n /*\n This useEffect is needed for overwriting a dashboard. It\n submits the form even if there's validation errors on title or uid.\n */\n useEffect(() => {\n if (isSubmitted && (errors.title || errors.uid)) {\n onSubmit(getValues(), {} as any);\n }\n }, [errors, getValues, isSubmitted, onSubmit]);\n const newLibraryPanels = inputs?.libraryPanels?.filter((i) => i.state === LibraryPanelInputState.New) ?? [];\n const existingLibraryPanels = inputs?.libraryPanels?.filter((i) => i.state === LibraryPanelInputState.Exists) ?? [];\n\n return (\n <>\n <Legend>Options</Legend>\n <Field label=\"Name\" invalid={!!errors.title} error={errors.title && errors.title.message}>\n <Input\n {...register('title', {\n required: 'Name is required',\n validate: async (v: string) => await validateTitle(v, getValues().folder.id),\n })}\n type=\"text\"\n data-testid={selectors.components.ImportDashboardForm.name}\n />\n </Field>\n <Field label=\"Folder\">\n <InputControl\n render={({ field: { ref, ...field } }) => (\n <FolderPicker {...field} enableCreateNew initialFolderId={initialFolderId} />\n )}\n name=\"folder\"\n control={control}\n />\n </Field>\n <Field\n label=\"Unique identifier (UID)\"\n description=\"The unique identifier (UID) of a dashboard can be used for uniquely identify a dashboard between multiple Grafana installs.\n The UID allows having consistent URLs for accessing dashboards so changing the title of a dashboard will not break any\n bookmarked links to that dashboard.\"\n invalid={!!errors.uid}\n error={errors.uid && errors.uid.message}\n >\n <>\n {!uidReset ? (\n <Input\n disabled\n {...register('uid', { validate: async (v: string) => await validateUid(v) })}\n addonAfter={!uidReset && <Button onClick={onUidReset}>Change uid</Button>}\n />\n ) : (\n <Input {...register('uid', { required: true, validate: async (v: string) => await validateUid(v) })} />\n )}\n </>\n </Field>\n {inputs.dataSources &&\n inputs.dataSources.map((input: DataSourceInput, index: number) => {\n if (input.pluginId === ExpressionDatasourceRef.type) {\n return null;\n }\n const dataSourceOption = `dataSources[${index}]`;\n const current = watchDataSources ?? [];\n return (\n <Field\n label={input.label}\n key={dataSourceOption}\n invalid={errors.dataSources && !!errors.dataSources[index]}\n error={errors.dataSources && errors.dataSources[index] && 'A data source is required'}\n >\n <InputControl\n name={dataSourceOption as any}\n render={({ field: { ref, ...field } }) => (\n <DataSourcePicker\n {...field}\n noDefault={true}\n placeholder={input.info}\n pluginId={input.pluginId}\n current={current[index]?.uid}\n />\n )}\n control={control}\n rules={{ required: true }}\n />\n </Field>\n );\n })}\n {inputs.constants &&\n inputs.constants.map((input: DashboardInput, index) => {\n const constantIndex = `constants[${index}]`;\n return (\n <Field\n label={input.label}\n error={errors.constants && errors.constants[index] && `${input.label} needs a value`}\n invalid={errors.constants && !!errors.constants[index]}\n key={constantIndex}\n >\n <Input {...register(constantIndex as any, { required: true })} defaultValue={input.value} />\n </Field>\n );\n })}\n <ImportDashboardLibraryPanelsList\n inputs={newLibraryPanels}\n label=\"New library panels\"\n description=\"List of new library panels that will get imported.\"\n folderName={watchFolder.title}\n />\n <ImportDashboardLibraryPanelsList\n inputs={existingLibraryPanels}\n label=\"Existing library panels\"\n description=\"List of existing library panels. These panels are not affected by the import.\"\n folderName={watchFolder.title}\n />\n <HorizontalGroup>\n <Button\n type=\"submit\"\n data-testid={selectors.components.ImportDashboardForm.submit}\n variant={getButtonVariant(errors)}\n onClick={() => {\n setSubmitted(true);\n }}\n >\n {getButtonText(errors)}\n </Button>\n <Button type=\"reset\" variant=\"secondary\" onClick={onCancel}>\n Cancel\n </Button>\n </HorizontalGroup>\n </>\n );\n};\n\nfunction getButtonVariant(errors: FormFieldErrors<ImportDashboardDTO>) {\n return errors && (errors.title || errors.uid) ? 'destructive' : 'primary';\n}\n\nfunction getButtonText(errors: FormFieldErrors<ImportDashboardDTO>) {\n return errors && (errors.title || errors.uid) ? 'Import (Overwrite)' : 'Import';\n}\n","import React, { PureComponent } from 'react';\nimport { connect, ConnectedProps } from 'react-redux';\n\nimport { dateTimeFormat } from '@grafana/data';\nimport { locationService, reportInteraction } from '@grafana/runtime';\nimport { Form, Legend } from '@grafana/ui';\nimport { StoreState } from 'app/types';\n\nimport { clearLoadedDashboard, importDashboard } from '../state/actions';\nimport { DashboardSource, ImportDashboardDTO } from '../state/reducers';\n\nimport { ImportDashboardForm } from './ImportDashboardForm';\n\nconst IMPORT_FINISHED_EVENT_NAME = 'dashboard_import_imported';\n\nconst mapStateToProps = (state: StoreState) => {\n const searchObj = locationService.getSearchObject();\n\n return {\n dashboard: state.importDashboard.dashboard,\n meta: state.importDashboard.meta,\n source: state.importDashboard.source,\n inputs: state.importDashboard.inputs,\n folder: searchObj.folderId ? { id: Number(searchObj.folderId) } : { id: 0 },\n };\n};\n\nconst mapDispatchToProps = {\n clearLoadedDashboard,\n importDashboard,\n};\n\nconst connector = connect(mapStateToProps, mapDispatchToProps);\n\ntype Props = ConnectedProps<typeof connector>;\n\ninterface State {\n uidReset: boolean;\n}\n\nclass ImportDashboardOverviewUnConnected extends PureComponent<Props, State> {\n state: State = {\n uidReset: false,\n };\n\n onSubmit = (form: ImportDashboardDTO) => {\n reportInteraction(IMPORT_FINISHED_EVENT_NAME);\n\n this.props.importDashboard(form);\n };\n\n onCancel = () => {\n this.props.clearLoadedDashboard();\n };\n\n onUidReset = () => {\n this.setState({ uidReset: true });\n };\n\n render() {\n const { dashboard, inputs, meta, source, folder } = this.props;\n const { uidReset } = this.state;\n\n return (\n <>\n {source === DashboardSource.Gcom && (\n <div style={{ marginBottom: '24px' }}>\n <div>\n <Legend>\n Importing dashboard from{' '}\n <a\n href={`https://grafana.com/dashboards/${dashboard.gnetId}`}\n className=\"external-link\"\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Grafana.com\n </a>\n </Legend>\n </div>\n <table className=\"filter-table form-inline\">\n <tbody>\n <tr>\n <td>Published by</td>\n <td>{meta.orgName}</td>\n </tr>\n <tr>\n <td>Updated on</td>\n <td>{dateTimeFormat(meta.updatedAt)}</td>\n </tr>\n </tbody>\n </table>\n </div>\n )}\n <Form\n onSubmit={this.onSubmit}\n defaultValues={{ ...dashboard, constants: [], dataSources: [], elements: [], folder: folder }}\n validateOnMount\n validateFieldsOnMount={['title', 'uid']}\n validateOn=\"onChange\"\n >\n {({ register, errors, control, watch, getValues }) => (\n <ImportDashboardForm\n register={register}\n errors={errors}\n control={control}\n getValues={getValues}\n uidReset={uidReset}\n inputs={inputs}\n onCancel={this.onCancel}\n onUidReset={this.onUidReset}\n onSubmit={this.onSubmit}\n watch={watch}\n initialFolderId={folder.id}\n />\n )}\n </Form>\n </>\n );\n }\n}\n\nexport const ImportDashboardOverview = connector(ImportDashboardOverviewUnConnected);\nImportDashboardOverview.displayName = 'ImportDashboardOverview';\n","import { css } from '@emotion/css';\nimport React, { FormEvent, PureComponent } from 'react';\nimport { connect, ConnectedProps } from 'react-redux';\n\nimport { AppEvents, GrafanaTheme2, LoadingState } from '@grafana/data';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { reportInteraction } from '@grafana/runtime';\nimport {\n Button,\n Field,\n FileUpload,\n Form,\n HorizontalGroup,\n Input,\n Spinner,\n stylesFactory,\n TextArea,\n Themeable2,\n VerticalGroup,\n withTheme2,\n} from '@grafana/ui';\nimport appEvents from 'app/core/app_events';\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';\n\nimport { cleanUpAction } from '../../core/actions/cleanUp';\n\nimport { ImportDashboardOverview } from './components/ImportDashboardOverview';\nimport { fetchGcomDashboard, importDashboardJson } from './state/actions';\nimport { validateDashboardJson, validateGcomDashboard } from './utils/validation';\n\ntype DashboardImportPageRouteSearchParams = {\n gcomDashboardId?: string;\n};\n\ntype OwnProps = Themeable2 & GrafanaRouteComponentProps<{}, DashboardImportPageRouteSearchParams>;\n\nconst IMPORT_STARTED_EVENT_NAME = 'dashboard_import_loaded';\n\nconst mapStateToProps = (state: StoreState) => ({\n navModel: getNavModel(state.navIndex, 'import', undefined, true),\n loadingState: state.importDashboard.state,\n});\n\nconst mapDispatchToProps = {\n fetchGcomDashboard,\n importDashboardJson,\n cleanUpAction,\n};\n\nconst connector = connect(mapStateToProps, mapDispatchToProps);\n\ntype Props = OwnProps & ConnectedProps<typeof connector>;\n\nclass UnthemedDashboardImport extends PureComponent<Props> {\n constructor(props: Props) {\n super(props);\n const { gcomDashboardId } = this.props.queryParams;\n if (gcomDashboardId) {\n this.getGcomDashboard({ gcomDashboard: gcomDashboardId });\n return;\n }\n }\n\n componentWillUnmount() {\n this.props.cleanUpAction({ stateSelector: (state: StoreState) => state.importDashboard });\n }\n\n onFileUpload = (event: FormEvent<HTMLInputElement>) => {\n reportInteraction(IMPORT_STARTED_EVENT_NAME, {\n import_source: 'json_uploaded',\n });\n\n const { importDashboardJson } = this.props;\n const file = event.currentTarget.files && event.currentTarget.files.length > 0 && event.currentTarget.files[0];\n\n if (file) {\n const reader = new FileReader();\n const readerOnLoad = () => {\n return (e: any) => {\n let dashboard: any;\n try {\n dashboard = JSON.parse(e.target.result);\n } catch (error) {\n appEvents.emit(AppEvents.alertError, [\n 'Import failed',\n 'JSON -> JS Serialization failed: ' + error.message,\n ]);\n return;\n }\n importDashboardJson(dashboard);\n };\n };\n reader.onload = readerOnLoad();\n reader.readAsText(file);\n }\n };\n\n getDashboardFromJson = (formData: { dashboardJson: string }) => {\n reportInteraction(IMPORT_STARTED_EVENT_NAME, {\n import_source: 'json_pasted',\n });\n\n this.props.importDashboardJson(JSON.parse(formData.dashboardJson));\n };\n\n getGcomDashboard = (formData: { gcomDashboard: string }) => {\n reportInteraction(IMPORT_STARTED_EVENT_NAME, {\n import_source: 'gcom',\n });\n\n let dashboardId;\n const match = /(^\\d+$)|dashboards\\/(\\d+)/.exec(formData.gcomDashboard);\n if (match && match[1]) {\n dashboardId = match[1];\n } else if (match && match[2]) {\n dashboardId = match[2];\n }\n\n if (dashboardId) {\n this.props.fetchGcomDashboard(dashboardId);\n }\n };\n\n renderImportForm() {\n const styles = importStyles(this.props.theme);\n\n return (\n <>\n <div className={styles.option}>\n <FileUpload accept=\"application/json\" onFileUpload={this.onFileUpload}>\n Upload JSON file\n </FileUpload>\n </div>\n <div className={styles.option}>\n <Form onSubmit={this.getGcomDashboard} defaultValues={{ gcomDashboard: '' }}>\n {({ register, errors }) => (\n <Field\n label=\"Import via grafana.com\"\n invalid={!!errors.gcomDashboard}\n error={errors.gcomDashboard && errors.gcomDashboard.message}\n >\n <Input\n id=\"url-input\"\n placeholder=\"Grafana.com dashboard URL or ID\"\n type=\"text\"\n {...register('gcomDashboard', {\n required: 'A Grafana dashboard URL or ID is required',\n validate: validateGcomDashboard,\n })}\n addonAfter={<Button type=\"submit\">Load</Button>}\n />\n </Field>\n )}\n </Form>\n </div>\n <div className={styles.option}>\n <Form onSubmit={this.getDashboardFromJson} defaultValues={{ dashboardJson: '' }}>\n {({ register, errors }) => (\n <>\n <Field\n label=\"Import via panel json\"\n invalid={!!errors.dashboardJson}\n error={errors.dashboardJson && errors.dashboardJson.message}\n >\n <TextArea\n {...register('dashboardJson', {\n required: 'Need a dashboard JSON model',\n validate: validateDashboardJson,\n })}\n data-testid={selectors.components.DashboardImportPage.textarea}\n id=\"dashboard-json-textarea\"\n rows={10}\n />\n </Field>\n <Button type=\"submit\" data-testid={selectors.components.DashboardImportPage.submit}>\n Load\n </Button>\n </>\n )}\n </Form>\n </div>\n </>\n );\n }\n\n render() {\n const { loadingState, navModel } = this.props;\n\n return (\n <Page navModel={navModel}>\n <Page.Contents>\n {loadingState === LoadingState.Loading && (\n <VerticalGroup justify=\"center\">\n <HorizontalGroup justify=\"center\">\n <Spinner size={32} />\n </HorizontalGroup>\n </VerticalGroup>\n )}\n {[LoadingState.Error, LoadingState.NotStarted].includes(loadingState) && this.renderImportForm()}\n {loadingState === LoadingState.Done && <ImportDashboardOverview />}\n </Page.Contents>\n </Page>\n );\n }\n}\n\nconst DashboardImportUnConnected = withTheme2(UnthemedDashboardImport);\nconst DashboardImport = connector(DashboardImportUnConnected);\nDashboardImport.displayName = 'DashboardImport';\nexport default DashboardImport;\n\nconst importStyles = stylesFactory((theme: GrafanaTheme2) => {\n return {\n option: css`\n margin-bottom: ${theme.spacing(4)};\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: React.FC<Props> = ({\n isCurrent,\n title,\n plugin,\n onClick,\n onDelete,\n disabled,\n showBadge,\n description,\n children,\n}) => {\n const styles = useStyles2(getStyles);\n const cssClass = cx({\n [styles.item]: true,\n [styles.disabled]: disabled || plugin.state === PluginState.deprecated,\n [styles.current]: isCurrent,\n });\n\n return (\n <div\n className={cssClass}\n aria-label={selectors.components.PluginVisualization.item(plugin.name)}\n onClick={disabled ? undefined : onClick}\n title={isCurrent ? 'Click again to close this section' : plugin.name}\n >\n <img className={styles.img} src={plugin.info.logos.small} alt=\"\" />\n\n <div className={styles.itemContent}>\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, disabled && styles.disabled)}>\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 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: 0.2;\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 margin-left: auto;\n `,\n };\n};\n\ninterface PanelPluginBadgeProps {\n plugin: PanelPluginMeta;\n}\n\nconst PanelPluginBadge: React.FC<PanelPluginBadgeProps> = ({ plugin }) => {\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 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":["initialDeleteLibraryPanelModalState","loadingState","LoadingState","dashboardTitles","searchCompleted","createAction","deleteLibraryPanelModalReducer","state","action","match","payload","dashboards","map","d","title","DeleteLibraryPanelModal","libraryPanel","onDismiss","onConfirm","styles","useStyles","getModalStyles","dispatch","useReducer","asyncDispatch","useMemo","asyncDispatcher","useEffect","async","apiGetConnectedDashboards","uid","getConnectedDashboards","connected","Boolean","length","done","Modal","className","modal","icon","isOpen","LoadingIndicator","HasConnectedDashboards","Confirm","Button","variant","onClick","fill","disabled","modalText","suffix","message","textInfo","myTable","i","LibraryPanelCard","onDelete","showSecondaryActions","showDeletionModal","setShowDeletionModal","useState","panelPlugin","config","model","type","getPanelPluginNotFound","meta","PanelTypeCard","isCurrent","name","description","plugin","undefined","FolderLink","useStyles2","getStyles","folderUid","folderName","metaContainer","Link","href","Icon","size","theme","css","colors","text","secondary","typography","bodySmall","fontSize","spacing","searchForLibraryPanels","args","subscription","Subscription","dataObservable","from","getLibraryPanels","searchString","perPage","page","excludeUid","currentPanelId","sortDirection","typeFilter","panelFilter","folderFilter","pipe","mergeMap","elements","libraryPanels","totalCount","of","catchError","err","console","error","initialLibraryPanelsViewState","finalize","unsubscribe","share","add","merge","timer","mapTo","initSearch","takeUntil","subscribe","deleteLibraryPanel","apiDeleteLibraryPanel","e","Function","numberOfPages","changePage","libraryPanelsViewReducer","Math","ceil","border","radius","sm","bg3","bg1","textSemiWeak","md","xl","bg2","noteTextbox","dashboardSearch","heading","h4","link","validateDashboardJson","json","JSON","parse","validateGcomDashboard","gcomDashboard","exec","validateUid","value","getBackendSrv","get","then","existingDashboard","dashboard","folderTitle","catch","isHandled","ImportDashboardLibraryPanelsList","inputs","label","spacer","Field","input","index","libraryPanelIndex","LibraryPanelInputState","item","ImportDashboardForm","register","errors","control","getValues","uidReset","initialFolderId","onUidReset","onCancel","onSubmit","watch","isSubmitted","setSubmitted","watchDataSources","watchFolder","newLibraryPanels","filter","existingLibraryPanels","Legend","invalid","Input","required","validate","await","newTitle","v","folderId","folder","id","validationSrv","selectors","InputControl","render","field","FolderPicker","enableCreateNew","addonAfter","dataSources","pluginId","ExpressionDatasourceRef","dataSourceOption","current","DataSourcePicker","noDefault","placeholder","info","rules","constants","constantIndex","defaultValue","HorizontalGroup","getButtonVariant","getButtonText","mapDispatchToProps","clearLoadedDashboard","importDashboard","connector","connect","searchObj","locationService","source","Number","ImportDashboardOverviewUnConnected","PureComponent","form","reportInteraction","this","props","setState","DashboardSource","style","marginBottom","gnetId","target","rel","orgName","dateTimeFormat","updatedAt","Form","defaultValues","validateOnMount","validateFieldsOnMount","validateOn","ImportDashboardOverview","displayName","IMPORT_STARTED_EVENT_NAME","fetchGcomDashboard","importDashboardJson","cleanUpAction","navModel","getNavModel","navIndex","UnthemedDashboardImport","constructor","super","event","import_source","file","currentTarget","files","reader","FileReader","readerOnLoad","result","appEvents","AppEvents","onload","readAsText","formData","dashboardJson","dashboardId","gcomDashboardId","queryParams","getGcomDashboard","componentWillUnmount","stateSelector","renderImportForm","importStyles","option","FileUpload","accept","onFileUpload","getDashboardFromJson","TextArea","rows","Page","VerticalGroup","justify","Spinner","includes","DashboardImport","withTheme2","stylesFactory","showBadge","children","cssClass","cx","PluginState","img","src","logos","small","alt","itemContent","badge","PanelPluginBadge","IconButton","stopPropagation","deleteButton","background","shape","borderRadius","shadows","z1","transitions","create","duration","short","emphasize","primary","selected","fontWeightMedium","fontWeightLight","isUnsignedPluginSignature","signature","PluginSignatureBadge","status","PluginStateInfo","display","color","tooltip","getFeatureStateInfo","Badge"],"sourceRoot":""}
|