{"version":3,"file":"DashboardListPage.d27b4433a05dc7d252e6.js","mappings":"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","sources":["webpack://grafana/./public/app/core/components/Select/SortPicker.tsx","webpack://grafana/./public/app/features/search/state/SearchStateManager.ts","webpack://grafana/./public/app/features/browse-dashboards/components/BrowseActions/BrowseActions.tsx","webpack://grafana/./public/app/features/search/page/components/ActionRow.tsx","webpack://grafana/./public/app/features/browse-dashboards/components/BrowseFilters.tsx","webpack://grafana/./public/app/features/browse-dashboards/types.ts","webpack://grafana/./public/app/features/browse-dashboards/components/CheckboxCell.tsx","webpack://grafana/./public/app/features/browse-dashboards/components/CheckboxHeaderCell.tsx","webpack://grafana/./public/app/features/browse-dashboards/components/NameCell.tsx","webpack://grafana/./public/app/features/browse-dashboards/components/TagsCell.tsx","webpack://grafana/./public/app/features/browse-dashboards/components/DashboardsTree.tsx","webpack://grafana/./public/app/features/browse-dashboards/components/BrowseView.tsx","webpack://grafana/./public/app/features/browse-dashboards/components/NewFolderForm.tsx","webpack://grafana/./public/app/features/browse-dashboards/components/CreateNewButton.tsx","webpack://grafana/./public/app/features/browse-dashboards/components/SearchView.tsx","webpack://grafana/./public/app/features/browse-dashboards/BrowseDashboardsPage.tsx","webpack://grafana/./public/app/features/browse-dashboards/components/BrowseActions/DeleteModal.tsx","webpack://grafana/./public/app/features/browse-dashboards/components/BrowseActions/MoveModal.tsx","webpack://grafana/./public/app/features/browse-dashboards/components/FolderActionsButton.tsx","webpack://grafana/./public/app/features/browse-dashboards/permissions.ts","webpack://grafana/./public/app/features/search/tempI18nPhrases.ts"],"sourcesContent":["import React from 'react';\nimport { useAsync } from 'react-use';\n\nimport { SelectableValue } from '@grafana/data';\nimport { Icon, Select } from '@grafana/ui';\nimport { DEFAULT_SORT } from 'app/features/search/constants';\nimport { getGrafanaSearcher } from 'app/features/search/service';\n\nexport interface Props {\n onChange: (sortValue: SelectableValue) => void;\n value?: string;\n placeholder?: string;\n getSortOptions?: () => Promise;\n filter?: string[];\n isClearable?: boolean;\n}\n\nconst defaultSortOptionsGetter = (): Promise => {\n return getGrafanaSearcher().getSortOptions();\n};\n\nexport function SortPicker({ onChange, value, placeholder, filter, getSortOptions, isClearable }: Props) {\n // Using sync Select and manual options fetching here since we need to find the selected option by value\n const options = useAsync<() => Promise>(async () => {\n const vals = await (getSortOptions ?? defaultSortOptionsGetter)();\n if (filter) {\n return vals.filter((v) => filter.includes(v.value));\n }\n return vals;\n }, [getSortOptions, filter]);\n\n if (options.loading) {\n return null;\n }\n\n const isDesc = Boolean(value?.includes('desc') || value?.startsWith('-')); // bluge syntax starts with \"-\"\n return (\n opt.value === value) ?? null}\n options={options.value}\n aria-label=\"Sort\"\n placeholder={placeholder ?? `Sort (Default ${DEFAULT_SORT.label})`}\n prefix={}\n isClearable={isClearable}\n />\n );\n}\n","import { debounce } from 'lodash';\nimport { FormEvent } from 'react';\n\nimport { locationService } from '@grafana/runtime';\nimport { TermCount } from 'app/core/components/TagFilter/TagFilter';\nimport { StateManagerBase } from 'app/core/services/StateManagerBase';\nimport store from 'app/core/store';\n\nimport { SEARCH_PANELS_LOCAL_STORAGE_KEY, SEARCH_SELECTED_LAYOUT, SEARCH_SELECTED_SORT } from '../constants';\nimport {\n reportDashboardListViewed,\n reportSearchFailedQueryInteraction,\n reportSearchQueryInteraction,\n reportSearchResultInteraction,\n} from '../page/reporting';\nimport { getGrafanaSearcher, SearchQuery } from '../service';\nimport { SearchLayout, SearchQueryParams, SearchState } from '../types';\nimport { parseRouteParams } from '../utils';\n\nexport const initialState: SearchState = {\n query: '',\n tag: [],\n starred: false,\n layout: SearchLayout.Folders,\n sort: undefined,\n prevSort: undefined,\n eventTrackingNamespace: 'dashboard_search',\n};\n\nexport const defaultQueryParams: SearchQueryParams = {\n sort: null,\n starred: null,\n query: null,\n tag: null,\n layout: null,\n};\n\nconst getLocalStorageLayout = () => {\n const selectedLayout = localStorage.getItem(SEARCH_SELECTED_LAYOUT);\n if (selectedLayout === SearchLayout.List) {\n return SearchLayout.List;\n } else {\n return SearchLayout.Folders;\n }\n};\nexport class SearchStateManager extends StateManagerBase {\n updateLocation = debounce((query) => locationService.partial(query, true), 300);\n doSearchWithDebounce = debounce(() => this.doSearch(), 300);\n lastQuery?: SearchQuery;\n\n lastSearchTimestamp = 0;\n\n initStateFromUrl(folderUid?: string, doInitialSearch = true) {\n const stateFromUrl = parseRouteParams(locationService.getSearchObject());\n\n // Force list view when conditions are specified from the URL\n if (stateFromUrl.query || stateFromUrl.datasource || stateFromUrl.panel_type) {\n stateFromUrl.layout = SearchLayout.List;\n }\n\n const layout = getLocalStorageLayout();\n const prevSort = localStorage.getItem(SEARCH_SELECTED_SORT) ?? undefined;\n const sort = layout === SearchLayout.List ? stateFromUrl.sort || prevSort : null;\n\n stateManager.setState({\n ...initialState,\n ...stateFromUrl,\n layout,\n sort: sort ?? initialState.sort,\n prevSort,\n folderUid: folderUid,\n eventTrackingNamespace: folderUid ? 'manage_dashboards' : 'dashboard_search',\n });\n\n if (doInitialSearch && this.hasSearchFilters()) {\n this.doSearch();\n }\n }\n\n /**\n * Updates internal and url state, then triggers a new search\n */\n setStateAndDoSearch(state: Partial) {\n const sort = state.sort || this.state.sort || localStorage.getItem(SEARCH_SELECTED_SORT) || undefined;\n\n // Set internal state\n this.setState({ sort, ...state });\n\n // Update url state\n this.updateLocation({\n query: this.state.query.length === 0 ? null : this.state.query,\n tag: this.state.tag,\n datasource: this.state.datasource,\n panel_type: this.state.panel_type,\n starred: this.state.starred ? this.state.starred : null,\n sort: this.state.sort,\n });\n\n // Prevent searching when user is only clearing the input.\n // We don't show these results anyway\n if (this.hasSearchFilters()) {\n this.doSearchWithDebounce();\n }\n }\n\n onCloseSearch = () => {\n this.updateLocation({\n search: null,\n folder: null,\n ...defaultQueryParams,\n });\n };\n\n onClearSearchAndFilters = () => {\n this.setStateAndDoSearch({\n query: '',\n datasource: undefined,\n tag: [],\n panel_type: undefined,\n starred: undefined,\n sort: undefined,\n });\n };\n\n onQueryChange = (query: string) => {\n this.setStateAndDoSearch({ query });\n };\n\n onRemoveTag = (tagToRemove: string) => {\n this.setStateAndDoSearch({ tag: this.state.tag.filter((tag) => tag !== tagToRemove) });\n };\n\n onTagFilterChange = (tags: string[]) => {\n this.setStateAndDoSearch({ tag: tags });\n };\n\n onAddTag = (newTag: string) => {\n if (this.state.tag && this.state.tag.includes(newTag)) {\n return;\n }\n\n this.setStateAndDoSearch({ tag: [...this.state.tag, newTag] });\n };\n\n onDatasourceChange = (datasource: string | undefined) => {\n this.setStateAndDoSearch({ datasource });\n };\n\n onPanelTypeChange = (panel_type?: string) => {\n this.setStateAndDoSearch({ panel_type });\n };\n\n onStarredFilterChange = (e: FormEvent) => {\n const starred = e.currentTarget.checked;\n this.setStateAndDoSearch({ starred });\n };\n\n onClearStarred = () => {\n this.setStateAndDoSearch({ starred: false });\n };\n\n onSortChange = (sort: string | undefined) => {\n if (sort) {\n localStorage.setItem(SEARCH_SELECTED_SORT, sort);\n } else {\n localStorage.removeItem(SEARCH_SELECTED_SORT);\n }\n\n if (this.state.layout === SearchLayout.Folders) {\n this.setStateAndDoSearch({ sort, layout: SearchLayout.List });\n } else {\n this.setStateAndDoSearch({ sort });\n }\n };\n\n onLayoutChange = (layout: SearchLayout) => {\n localStorage.setItem(SEARCH_SELECTED_LAYOUT, layout);\n\n if (this.state.sort && layout === SearchLayout.Folders) {\n this.setStateAndDoSearch({ layout, prevSort: this.state.sort, sort: undefined });\n } else {\n this.setStateAndDoSearch({ layout, sort: this.state.prevSort });\n }\n };\n\n onSetIncludePanels = (includePanels: boolean) => {\n this.setStateAndDoSearch({ includePanels });\n store.set(SEARCH_PANELS_LOCAL_STORAGE_KEY, includePanels);\n };\n\n hasSearchFilters() {\n return (\n this.state.query ||\n this.state.tag.length ||\n this.state.starred ||\n this.state.panel_type ||\n this.state.sort ||\n this.state.layout === SearchLayout.List\n );\n }\n\n getSearchQuery() {\n const q: SearchQuery = {\n query: this.state.query,\n tags: this.state.tag,\n ds_uid: this.state.datasource,\n panel_type: this.state.panel_type,\n location: this.state.folderUid, // This will scope all results to the prefix\n sort: this.state.sort,\n explain: this.state.explain,\n withAllowedActions: this.state.explain, // allowedActions are currently not used for anything on the UI and added only in `explain` mode\n starred: this.state.starred,\n };\n\n // Only dashboards have additional properties\n if (q.sort?.length && !q.sort.includes('name')) {\n q.kind = ['dashboard', 'folder']; // skip panels\n }\n\n if (!q.query?.length) {\n q.query = '*';\n if (!q.location) {\n q.kind = ['dashboard', 'folder']; // skip panels\n }\n }\n\n if (!this.state.includePanels && !q.kind) {\n q.kind = ['dashboard', 'folder']; // skip panels\n }\n\n if (q.panel_type?.length) {\n q.kind = ['panel'];\n }\n\n return q;\n }\n\n private doSearch() {\n const trackingInfo = {\n layout: this.state.layout,\n starred: this.state.starred,\n sortValue: this.state.sort,\n query: this.state.query,\n tagCount: this.state.tag?.length,\n includePanels: this.state.includePanels,\n };\n\n reportSearchQueryInteraction(this.state.eventTrackingNamespace, trackingInfo);\n\n this.lastQuery = this.getSearchQuery();\n\n this.setState({ loading: true });\n\n const searcher = getGrafanaSearcher();\n\n const searchTimestamp = Date.now();\n const searchPromise = this.state.starred ? searcher.starred(this.lastQuery) : searcher.search(this.lastQuery);\n\n searchPromise\n .then((result) => {\n // Only keep the results if it's was issued after the most recently resolved search.\n // This prevents results showing out of order if first request is slower than later ones\n if (searchTimestamp > this.lastSearchTimestamp) {\n this.setState({ result, loading: false });\n this.lastSearchTimestamp = searchTimestamp;\n }\n })\n .catch((error) => {\n reportSearchFailedQueryInteraction(this.state.eventTrackingNamespace, {\n ...trackingInfo,\n error: error?.message,\n });\n this.setState({ loading: false });\n });\n }\n\n // This gets the possible tags from within the query results\n getTagOptions = (): Promise => {\n const query = this.lastQuery ?? {\n kind: ['dashboard', 'folder'],\n query: '*',\n };\n return getGrafanaSearcher().tags(query);\n };\n\n /**\n * When item is selected clear some filters and report interaction\n */\n onSearchItemClicked = (e: React.MouseEvent) => {\n reportSearchResultInteraction(this.state.eventTrackingNamespace, {\n layout: this.state.layout,\n starred: this.state.starred,\n sortValue: this.state.sort,\n query: this.state.query,\n tagCount: this.state.tag?.length,\n includePanels: this.state.includePanels,\n });\n };\n\n /**\n * Caller should handle debounce\n */\n onReportSearchUsage = () => {\n reportDashboardListViewed(this.state.eventTrackingNamespace, {\n layout: this.state.layout,\n starred: this.state.starred,\n sortValue: this.state.sort,\n query: this.state.query,\n tagCount: this.state.tag?.length,\n includePanels: this.state.includePanels,\n });\n };\n}\n\nlet stateManager: SearchStateManager;\n\nexport function getSearchStateManager() {\n if (!stateManager) {\n const selectedLayout = localStorage.getItem(SEARCH_SELECTED_LAYOUT) as SearchLayout;\n const layout = selectedLayout ?? initialState.layout;\n\n let includePanels = store.getBool(SEARCH_PANELS_LOCAL_STORAGE_KEY, true);\n if (includePanels) {\n includePanels = false;\n }\n\n stateManager = new SearchStateManager({ ...initialState, layout, includePanels });\n }\n\n return stateManager;\n}\n\nexport function useSearchStateManager() {\n const stateManager = getSearchStateManager();\n const state = stateManager.useState();\n\n return [state, stateManager] as const;\n}\n","import { css } from '@emotion/css';\nimport React, { useMemo } from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { config, reportInteraction } from '@grafana/runtime';\nimport { Button, Tooltip, useStyles2 } from '@grafana/ui';\nimport appEvents from 'app/core/app_events';\nimport { t, Trans } from 'app/core/internationalization';\nimport { useSearchStateManager } from 'app/features/search/state/SearchStateManager';\nimport { useDispatch } from 'app/types';\nimport { ShowModalReactEvent } from 'app/types/events';\n\nimport { useDeleteItemsMutation, useMoveItemsMutation } from '../../api/browseDashboardsAPI';\nimport { setAllSelection, useActionSelectionState } from '../../state';\nimport { DashboardTreeSelection } from '../../types';\n\nimport { DeleteModal } from './DeleteModal';\nimport { MoveModal } from './MoveModal';\n\nexport interface Props {}\n\nexport function BrowseActions() {\n const styles = useStyles2(getStyles);\n const dispatch = useDispatch();\n const selectedItems = useActionSelectionState();\n const [deleteItems] = useDeleteItemsMutation();\n const [moveItems] = useMoveItemsMutation();\n const [, stateManager] = useSearchStateManager();\n\n // Folders can only be moved if nested folders is enabled\n const moveIsInvalid = useMemo(\n () => !config.featureToggles.nestedFolders && Object.values(selectedItems.folder).some((v) => v),\n [selectedItems]\n );\n\n const isSearching = stateManager.hasSearchFilters();\n\n const onActionComplete = () => {\n dispatch(setAllSelection({ isSelected: false, folderUID: undefined }));\n\n if (isSearching) {\n // Redo search query\n stateManager.doSearchWithDebounce();\n }\n };\n\n const onDelete = async () => {\n await deleteItems({ selectedItems });\n trackAction('delete', selectedItems);\n onActionComplete();\n };\n\n const onMove = async (destinationUID: string) => {\n await moveItems({ selectedItems, destinationUID });\n trackAction('move', selectedItems);\n onActionComplete();\n };\n\n const showMoveModal = () => {\n appEvents.publish(\n new ShowModalReactEvent({\n component: MoveModal,\n props: {\n selectedItems,\n onConfirm: onMove,\n },\n })\n );\n };\n\n const showDeleteModal = () => {\n appEvents.publish(\n new ShowModalReactEvent({\n component: DeleteModal,\n props: {\n selectedItems,\n onConfirm: onDelete,\n },\n })\n );\n };\n\n const moveButton = (\n \n );\n\n return (\n
\n {moveIsInvalid ? (\n \n {moveButton}\n \n ) : (\n moveButton\n )}\n\n \n
\n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n row: css({\n display: 'flex',\n flexDirection: 'row',\n gap: theme.spacing(1),\n marginBottom: theme.spacing(2),\n }),\n});\n\nconst actionMap = {\n move: 'grafana_manage_dashboards_item_moved',\n delete: 'grafana_manage_dashboards_item_deleted',\n} as const;\n\nfunction trackAction(action: keyof typeof actionMap, selectedItems: Omit) {\n const selectedDashboards = Object.keys(selectedItems.dashboard).filter((uid) => selectedItems.dashboard[uid]);\n const selectedFolders = Object.keys(selectedItems.folder).filter((uid) => selectedItems.folder[uid]);\n\n reportInteraction(actionMap[action], {\n item_counts: {\n folder: selectedFolders.length,\n dashboard: selectedDashboards.length,\n },\n source: 'tree_actions',\n });\n}\n","import { css } from '@emotion/css';\nimport React, { FormEvent } from 'react';\n\nimport { GrafanaTheme2, SelectableValue } from '@grafana/data';\nimport { config } from '@grafana/runtime';\nimport { Button, Checkbox, HorizontalGroup, RadioButtonGroup, useStyles2 } from '@grafana/ui';\nimport { SortPicker } from 'app/core/components/Select/SortPicker';\nimport { TagFilter, TermCount } from 'app/core/components/TagFilter/TagFilter';\nimport { t, Trans } from 'app/core/internationalization';\n\nimport { SearchLayout, SearchState } from '../../types';\n\nfunction getLayoutOptions() {\n return [\n {\n value: SearchLayout.Folders,\n icon: 'folder',\n description: t('search.actions.view-as-folders', 'View by folders'),\n },\n { value: SearchLayout.List, icon: 'list-ul', description: t('search.actions.view-as-list', 'View as list') },\n ];\n}\n\ninterface Props {\n onLayoutChange: (layout: SearchLayout) => void;\n onSortChange: (value?: string) => void;\n onStarredFilterChange?: (event: FormEvent) => void;\n onTagFilterChange: (tags: string[]) => void;\n getTagOptions: () => Promise;\n getSortOptions: () => Promise;\n sortPlaceholder?: string;\n onDatasourceChange: (ds?: string) => void;\n onPanelTypeChange: (pt?: string) => void;\n includePanels: boolean;\n onSetIncludePanels: (v: boolean) => void;\n state: SearchState;\n showStarredFilter?: boolean;\n hideLayout?: boolean;\n}\n\nexport function getValidQueryLayout(q: SearchState): SearchLayout {\n const layout = q.layout ?? SearchLayout.Folders;\n\n // Folders is not valid when a query exists\n if (layout === SearchLayout.Folders) {\n if (q.query || q.sort || q.starred || q.tag.length > 0) {\n return SearchLayout.List;\n }\n }\n\n return layout;\n}\n\nexport const ActionRow = ({\n onLayoutChange,\n onSortChange,\n onStarredFilterChange = () => {},\n onTagFilterChange,\n getTagOptions,\n getSortOptions,\n sortPlaceholder,\n onDatasourceChange,\n onPanelTypeChange,\n onSetIncludePanels,\n state,\n showStarredFilter,\n hideLayout,\n}: Props) => {\n const styles = useStyles2(getStyles);\n const layout = getValidQueryLayout(state);\n\n // Disabled folder layout option when query is present\n const disabledOptions =\n state.tag.length || state.starred || state.query || state.datasource || state.panel_type\n ? [SearchLayout.Folders]\n : [];\n\n return (\n
\n \n \n {config.featureToggles.panelTitleSearch && (\n onSetIncludePanels(!state.includePanels)}\n label={t('search.actions.include-panels', 'Include panels')}\n />\n )}\n\n {showStarredFilter && (\n
\n \n
\n )}\n {state.datasource && (\n \n )}\n {state.panel_type && (\n \n )}\n
\n\n \n {!hideLayout && (\n \n )}\n onSortChange(change?.value)}\n value={state.sort}\n getSortOptions={getSortOptions}\n placeholder={sortPlaceholder || t('search.actions.sort-placeholder', 'Sort')}\n isClearable\n />\n \n
\n );\n};\n\nActionRow.displayName = 'ActionRow';\n\nexport const getStyles = (theme: GrafanaTheme2) => {\n return {\n actionRow: css`\n display: none;\n\n ${theme.breakpoints.up('md')} {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: ${theme.spacing(2)};\n width: 100%;\n }\n `,\n checkboxWrapper: css`\n label {\n line-height: 1.2;\n }\n `,\n };\n};\n","import React from 'react';\n\nimport { ActionRow } from 'app/features/search/page/components/ActionRow';\nimport { getGrafanaSearcher } from 'app/features/search/service';\nimport { useSearchStateManager } from 'app/features/search/state/SearchStateManager';\n\nexport function BrowseFilters() {\n const [searchState, stateManager] = useSearchStateManager();\n\n return (\n
\n \n
\n );\n}\n","import { CellProps, Column, HeaderProps } from 'react-table';\n\nimport { DashboardViewItem, DashboardViewItemKind } from 'app/features/search/types';\n\nexport type DashboardTreeSelection = Record> & {\n $all: boolean;\n};\n\n/**\n * Stores children at a particular location in the tree, and information\n * required for pagination.\n */\nexport type DashboardViewItemCollection = {\n items: DashboardViewItem[];\n lastFetchedKind: 'folder' | 'dashboard';\n lastFetchedPage: number;\n lastKindHasMoreItems: boolean;\n isFullyLoaded: boolean;\n};\n\nexport interface BrowseDashboardsState {\n rootItems: DashboardViewItemCollection | undefined;\n childrenByParentUID: Record;\n selectedItems: DashboardTreeSelection;\n\n // Only folders can ever be open or closed, so no need to seperate this by kind\n openFolders: Record;\n}\n\nexport interface UIDashboardViewItem {\n kind: 'ui';\n uiKind: 'empty-folder' | 'pagination-placeholder' | 'divider';\n uid: string;\n}\n\nexport type DashboardViewItemWithUIItems = DashboardViewItem | UIDashboardViewItem;\n\nexport interface DashboardsTreeItem {\n item: T;\n level: number;\n isOpen: boolean;\n parentUID?: string;\n}\n\ninterface RendererUserProps {\n // Note: userProps for cell renderers (e.g. second argument in `cell.render('Cell', foo)` )\n // aren't typed, so we must be careful when accessing this\n isSelected?: (kind: DashboardViewItem | '$all') => SelectionState;\n onAllSelectionChange?: (newState: boolean) => void;\n onItemSelectionChange?: (item: DashboardViewItem, newState: boolean) => void;\n treeID?: string;\n}\n\nexport type DashboardsTreeColumn = Column;\nexport type DashboardsTreeCellProps = CellProps & RendererUserProps;\nexport type DashboardTreeHeaderProps = HeaderProps & RendererUserProps;\n\nexport enum SelectionState {\n Unselected,\n Selected,\n Mixed,\n}\n","import { css } from '@emotion/css';\nimport React from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { Checkbox, useStyles2 } from '@grafana/ui';\nimport { t } from 'app/core/internationalization';\n\nimport { DashboardsTreeCellProps, SelectionState } from '../types';\n\nimport { isSharedWithMe } from './utils';\n\nexport default function CheckboxCell({\n row: { original: row },\n isSelected,\n onItemSelectionChange,\n}: DashboardsTreeCellProps) {\n const item = row.item;\n\n if (!isSelected) {\n return ;\n }\n\n if (item.kind === 'ui') {\n if (item.uiKind === 'pagination-placeholder') {\n return ;\n } else {\n return ;\n }\n }\n\n if (isSharedWithMe(item.uid)) {\n return ;\n }\n\n const state = isSelected(item);\n\n return (\n onItemSelectionChange?.(item, ev.currentTarget.checked)}\n />\n );\n}\n\nfunction CheckboxSpacer() {\n const styles = useStyles2(getStyles);\n return ;\n}\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n // Should be the same size as the so Dashboard name is aligned to Folder name siblings\n checkboxSpacer: css({\n paddingLeft: theme.spacing(2),\n }),\n});\n","import React from 'react';\n\nimport { Checkbox } from '@grafana/ui';\nimport { t } from 'app/core/internationalization';\n\nimport { DashboardTreeHeaderProps, SelectionState } from '../types';\n\nexport default function CheckboxHeaderCell({ isSelected, onAllSelectionChange }: DashboardTreeHeaderProps) {\n const state = isSelected?.('$all') ?? SelectionState.Unselected;\n\n return (\n {\n if (state === SelectionState.Mixed) {\n // Ensure clicking an indeterminate checkbox always clears the selection\n onAllSelectionChange?.(false);\n } else {\n onAllSelectionChange?.(ev.currentTarget.checked);\n }\n }}\n />\n );\n}\n","import { css } from '@emotion/css';\nimport React from 'react';\nimport Skeleton from 'react-loading-skeleton';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { reportInteraction } from '@grafana/runtime';\nimport { Icon, IconButton, Link, Spinner, useStyles2, Text } from '@grafana/ui';\nimport { getSvgSize } from '@grafana/ui/src/components/Icon/utils';\nimport { t } from 'app/core/internationalization';\nimport { getIconForItem } from 'app/features/search/service/utils';\n\nimport { Indent } from '../../../core/components/Indent/Indent';\nimport { useChildrenByParentUIDState } from '../state';\nimport { DashboardsTreeCellProps } from '../types';\n\nimport { makeRowID } from './utils';\n\nconst CHEVRON_SIZE = 'md';\nconst ICON_SIZE = 'sm';\n\ntype NameCellProps = DashboardsTreeCellProps & {\n onFolderClick: (uid: string, newOpenState: boolean) => void;\n};\n\nexport function NameCell({ row: { original: data }, onFolderClick, treeID }: NameCellProps) {\n const styles = useStyles2(getStyles);\n const { item, level, isOpen } = data;\n const childrenByParentUID = useChildrenByParentUIDState();\n const isLoading = isOpen && !childrenByParentUID[item.uid];\n const iconName = getIconForItem(data.item, isOpen);\n\n if (item.kind === 'ui') {\n return (\n <>\n \n \n {item.uiKind === 'empty-folder' ? (\n \n \n No items\n \n \n ) : (\n \n )}\n \n );\n }\n\n return (\n <>\n \n\n {item.kind === 'folder' ? (\n {\n onFolderClick(item.uid, !isOpen);\n }}\n name={isOpen ? 'angle-down' : 'angle-right'}\n aria-label={\n isOpen\n ? t('browse-dashboards.dashboards-tree.collapse-folder-button', 'Collapse folder {{title}}', {\n title: item.title,\n })\n : t('browse-dashboards.dashboards-tree.expand-folder-button', 'Expand folder {{title}}', {\n title: item.title,\n })\n }\n />\n ) : (\n \n )}\n\n
\n {isLoading ? : }\n\n \n {item.url ? (\n {\n reportInteraction('manage_dashboards_result_clicked');\n }}\n href={item.url}\n className={styles.link}\n >\n {item.title}\n \n ) : (\n item.title\n )}\n \n
\n \n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => {\n return {\n chevron: css({\n marginRight: theme.spacing(1),\n width: getSvgSize(CHEVRON_SIZE),\n }),\n emptyText: css({\n // needed for text to truncate correctly\n overflow: 'hidden',\n }),\n // Should be the same size as the so Dashboard name is aligned to Folder name siblings\n folderButtonSpacer: css({\n paddingLeft: `calc(${getSvgSize(CHEVRON_SIZE)}px + ${theme.spacing(1)})`,\n }),\n iconNameContainer: css({\n alignItems: 'center',\n display: 'flex',\n gap: theme.spacing(1),\n overflow: 'hidden',\n }),\n link: css({\n '&:hover': {\n textDecoration: 'underline',\n },\n }),\n };\n};\n","import { css } from '@emotion/css';\nimport React from 'react';\nimport { CellProps } from 'react-table';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { TagList, useStyles2 } from '@grafana/ui';\n\nimport { DashboardsTreeItem } from '../types';\n\nexport function TagsCell({ row: { original: data } }: CellProps) {\n const styles = useStyles2(getStyles);\n const item = data.item;\n\n if (item.kind === 'ui') {\n if (item.uiKind === 'pagination-placeholder') {\n return ;\n } else {\n return null;\n }\n }\n\n if (!item.tags) {\n return null;\n }\n\n return ;\n}\n\nfunction getStyles(theme: GrafanaTheme2) {\n return {\n // TagList is annoying and has weird default alignment\n tagList: css({\n justifyContent: 'flex-start',\n flexWrap: 'nowrap',\n }),\n };\n}\n","import { css, cx } from '@emotion/css';\nimport React, { useCallback, useEffect, useId, useMemo, useRef } from 'react';\nimport { TableInstance, useTable } from 'react-table';\nimport { VariableSizeList as List } from 'react-window';\nimport InfiniteLoader from 'react-window-infinite-loader';\n\nimport { GrafanaTheme2, isTruthy } from '@grafana/data';\nimport { selectors } from '@grafana/e2e-selectors';\nimport { useStyles2 } from '@grafana/ui';\nimport { t, Trans } from 'app/core/internationalization';\nimport { DashboardViewItem } from 'app/features/search/types';\n\nimport { DashboardsTreeCellProps, DashboardsTreeColumn, DashboardsTreeItem, SelectionState } from '../types';\n\nimport CheckboxCell from './CheckboxCell';\nimport CheckboxHeaderCell from './CheckboxHeaderCell';\nimport { NameCell } from './NameCell';\nimport { TagsCell } from './TagsCell';\nimport { useCustomFlexLayout } from './customFlexTableLayout';\nimport { makeRowID } from './utils';\n\ninterface DashboardsTreeProps {\n items: DashboardsTreeItem[];\n width: number;\n height: number;\n canSelect: boolean;\n isSelected: (kind: DashboardViewItem | '$all') => SelectionState;\n onFolderClick: (uid: string, newOpenState: boolean) => void;\n onAllSelectionChange: (newState: boolean) => void;\n onItemSelectionChange: (item: DashboardViewItem, newState: boolean) => void;\n\n isItemLoaded: (itemIndex: number) => boolean;\n requestLoadMore: (folderUid: string | undefined) => void;\n}\n\nconst HEADER_HEIGHT = 36;\nconst ROW_HEIGHT = 36;\nconst DIVIDER_HEIGHT = 0; // Yes - make it appear as a border on the row rather than a row itself\n\nexport function DashboardsTree({\n items,\n width,\n height,\n isSelected,\n onFolderClick,\n onAllSelectionChange,\n onItemSelectionChange,\n isItemLoaded,\n requestLoadMore,\n canSelect = false,\n}: DashboardsTreeProps) {\n const treeID = useId();\n\n const infiniteLoaderRef = useRef(null);\n const listRef = useRef(null);\n const styles = useStyles2(getStyles);\n\n useEffect(() => {\n // If the tree changed identity, then some indexes that were previously loaded may now be unloaded,\n // especially after a refetch after a move/delete.\n // Clear that cache, and check if we need to trigger another load\n if (infiniteLoaderRef.current) {\n infiniteLoaderRef.current.resetloadMoreItemsCache(true);\n }\n\n if (listRef.current) {\n listRef.current.resetAfterIndex(0);\n }\n }, [items]);\n\n const tableColumns = useMemo(() => {\n const checkboxColumn: DashboardsTreeColumn = {\n id: 'checkbox',\n width: 0,\n Header: CheckboxHeaderCell,\n Cell: CheckboxCell,\n };\n\n const nameColumn: DashboardsTreeColumn = {\n id: 'name',\n width: 3,\n Header: (\n \n Name\n \n ),\n Cell: (props: DashboardsTreeCellProps) => ,\n };\n\n const tagsColumns: DashboardsTreeColumn = {\n id: 'tags',\n width: 2,\n Header: t('browse-dashboards.dashboards-tree.tags-column', 'Tags'),\n Cell: TagsCell,\n };\n const columns = [canSelect && checkboxColumn, nameColumn, tagsColumns].filter(isTruthy);\n\n return columns;\n }, [onFolderClick, canSelect]);\n\n const table = useTable({ columns: tableColumns, data: items }, useCustomFlexLayout);\n const { getTableProps, getTableBodyProps, headerGroups } = table;\n\n const virtualData = useMemo(\n () => ({\n table,\n isSelected,\n onAllSelectionChange,\n onItemSelectionChange,\n treeID,\n }),\n // we need this to rerender if items changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [table, isSelected, onAllSelectionChange, onItemSelectionChange, items, treeID]\n );\n\n const handleIsItemLoaded = useCallback(\n (itemIndex: number) => {\n return isItemLoaded(itemIndex);\n },\n [isItemLoaded]\n );\n\n const handleLoadMore = useCallback(\n (startIndex: number, endIndex: number) => {\n const { parentUID } = items[startIndex];\n requestLoadMore(parentUID);\n },\n [requestLoadMore, items]\n );\n\n const getRowHeight = useCallback(\n (rowIndex: number) => {\n const row = items[rowIndex];\n if (row.item.kind === 'ui' && row.item.uiKind === 'divider') {\n return DIVIDER_HEIGHT;\n }\n\n return ROW_HEIGHT;\n },\n [items]\n );\n\n return (\n
\n {headerGroups.map((headerGroup) => {\n const { key, ...headerGroupProps } = headerGroup.getHeaderGroupProps({\n style: { width },\n });\n\n return (\n
\n {headerGroup.headers.map((column) => {\n const { key, ...headerProps } = column.getHeaderProps();\n\n return (\n
\n {column.render('Header', { isSelected, onAllSelectionChange })}\n
\n );\n })}\n
\n );\n })}\n\n
\n \n {({ onItemsRendered, ref }) => (\n {\n ref(elem);\n listRef.current = elem;\n }}\n height={height - HEADER_HEIGHT}\n width={width}\n itemCount={items.length}\n itemData={virtualData}\n estimatedItemSize={ROW_HEIGHT}\n itemSize={getRowHeight}\n onItemsRendered={onItemsRendered}\n >\n {VirtualListRow}\n \n )}\n \n
\n
\n );\n}\n\ninterface VirtualListRowProps {\n index: number;\n style: React.CSSProperties;\n data: {\n table: TableInstance;\n isSelected: DashboardsTreeCellProps['isSelected'];\n onAllSelectionChange: DashboardsTreeCellProps['onAllSelectionChange'];\n onItemSelectionChange: DashboardsTreeCellProps['onItemSelectionChange'];\n treeID: string;\n };\n}\n\nfunction VirtualListRow({ index, style, data }: VirtualListRowProps) {\n const styles = useStyles2(getStyles);\n const { table, isSelected, onItemSelectionChange, treeID } = data;\n const { rows, prepareRow } = table;\n\n const row = rows[index];\n prepareRow(row);\n\n const dashboardItem = row.original.item;\n\n if (dashboardItem.kind === 'ui' && dashboardItem.uiKind === 'divider') {\n return (\n
\n
\n
\n );\n }\n\n return (\n \n {row.cells.map((cell) => {\n const { key, ...cellProps } = cell.getCellProps();\n\n return (\n
\n {cell.render('Cell', { isSelected, onItemSelectionChange, treeID })}\n
\n );\n })}\n \n );\n}\n\nconst getStyles = (theme: GrafanaTheme2) => {\n return {\n // Column flex properties (cell sizing) are set by customFlexTableLayout.ts\n\n row: css({\n gap: theme.spacing(1),\n }),\n\n divider: css({\n borderTop: `1px solid ${theme.colors.border.weak}`,\n width: '100%',\n margin: 0,\n }),\n\n headerRow: css({\n backgroundColor: theme.colors.background.secondary,\n height: HEADER_HEIGHT,\n }),\n\n bodyRow: css({\n height: ROW_HEIGHT,\n\n '&:hover': {\n backgroundColor: theme.colors.emphasize(theme.colors.background.primary, 0.03),\n },\n }),\n\n cell: css({\n padding: theme.spacing(1),\n overflow: 'hidden', // Required so flex children can do text-overflow: ellipsis\n display: 'flex',\n alignItems: 'center',\n }),\n\n link: css({\n '&:hover': {\n textDecoration: 'underline',\n },\n }),\n };\n};\n","import React, { useCallback } from 'react';\n\nimport { CallToActionCard } from '@grafana/ui';\nimport EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';\nimport { DashboardViewItem } from 'app/features/search/types';\nimport { useDispatch } from 'app/types';\n\nimport { PAGE_SIZE } from '../api/services';\nimport {\n useFlatTreeState,\n useCheckboxSelectionState,\n setFolderOpenState,\n setItemSelectionState,\n useChildrenByParentUIDState,\n setAllSelection,\n useBrowseLoadingStatus,\n useLoadNextChildrenPage,\n fetchNextChildrenPage,\n} from '../state';\nimport { BrowseDashboardsState, DashboardTreeSelection, SelectionState } from '../types';\n\nimport { DashboardsTree } from './DashboardsTree';\n\ninterface BrowseViewProps {\n height: number;\n width: number;\n folderUID: string | undefined;\n canSelect: boolean;\n}\n\nexport function BrowseView({ folderUID, width, height, canSelect }: BrowseViewProps) {\n const status = useBrowseLoadingStatus(folderUID);\n const dispatch = useDispatch();\n const flatTree = useFlatTreeState(folderUID);\n const selectedItems = useCheckboxSelectionState();\n const childrenByParentUID = useChildrenByParentUIDState();\n\n const handleFolderClick = useCallback(\n (clickedFolderUID: string, isOpen: boolean) => {\n dispatch(setFolderOpenState({ folderUID: clickedFolderUID, isOpen }));\n\n if (isOpen) {\n dispatch(fetchNextChildrenPage({ parentUID: clickedFolderUID, pageSize: PAGE_SIZE }));\n }\n },\n [dispatch]\n );\n\n const handleItemSelectionChange = useCallback(\n (item: DashboardViewItem, isSelected: boolean) => {\n dispatch(setItemSelectionState({ item, isSelected }));\n },\n [dispatch]\n );\n\n const isSelected = useCallback(\n (item: DashboardViewItem | '$all'): SelectionState => {\n if (item === '$all') {\n // We keep the boolean $all state up to date in redux, so we can short-circut\n // the logic if we know this has been selected\n if (selectedItems.$all) {\n return SelectionState.Selected;\n }\n\n // Otherwise, if we have any selected items, then it should be in 'mixed' state\n for (const selection of Object.values(selectedItems)) {\n if (typeof selection === 'boolean') {\n continue;\n }\n\n for (const uid in selection) {\n const isSelected = selection[uid];\n if (isSelected) {\n return SelectionState.Mixed;\n }\n }\n }\n\n // Otherwise otherwise, nothing is selected and header should be unselected\n return SelectionState.Unselected;\n }\n\n const isSelected = selectedItems[item.kind][item.uid];\n if (isSelected) {\n return SelectionState.Selected;\n }\n\n // Because if _all_ children, then the parent is selected (and bailed in the previous check),\n // this .some check will only return true if the children are partially selected\n const isMixed = hasSelectedDescendants(item, childrenByParentUID, selectedItems);\n if (isMixed) {\n return SelectionState.Mixed;\n }\n\n return SelectionState.Unselected;\n },\n [selectedItems, childrenByParentUID]\n );\n\n const isItemLoaded = useCallback(\n (itemIndex: number) => {\n const treeItem = flatTree[itemIndex];\n if (!treeItem) {\n return false;\n }\n const item = treeItem.item;\n const result = !(item.kind === 'ui' && item.uiKind === 'pagination-placeholder');\n\n return result;\n },\n [flatTree]\n );\n\n const handleLoadMore = useLoadNextChildrenPage();\n\n if (status === 'fulfilled' && flatTree.length === 0) {\n return (\n
\n {canSelect ? (\n '}\n proTipLink={folderUID && 'dashboards'}\n proTipLinkTitle={folderUID && 'Browse dashboards'}\n proTipTarget=\"\"\n />\n ) : (\n This folder is empty} />\n )}\n
\n );\n }\n\n return (\n dispatch(setAllSelection({ isSelected: newState, folderUID }))}\n onItemSelectionChange={handleItemSelectionChange}\n isItemLoaded={isItemLoaded}\n requestLoadMore={handleLoadMore}\n />\n );\n}\n\nfunction hasSelectedDescendants(\n item: DashboardViewItem,\n childrenByParentUID: BrowseDashboardsState['childrenByParentUID'],\n selectedItems: DashboardTreeSelection\n): boolean {\n const collection = childrenByParentUID[item.uid];\n if (!collection) {\n return false;\n }\n\n return collection.items.some((v) => {\n const thisIsSelected = selectedItems[v.kind][v.uid];\n if (thisIsSelected) {\n return thisIsSelected;\n }\n\n return hasSelectedDescendants(v, childrenByParentUID, selectedItems);\n });\n}\n","import React from 'react';\n\nimport { selectors } from '@grafana/e2e-selectors';\nimport { Button, Input, Form, Field, HorizontalGroup } from '@grafana/ui';\nimport { Trans, t } from 'app/core/internationalization';\n\nimport { validationSrv } from '../../manage-dashboards/services/ValidationSrv';\n\ninterface Props {\n onConfirm: (folderName: string) => void;\n onCancel: () => void;\n}\n\ninterface FormModel {\n folderName: string;\n}\n\nconst initialFormModel: FormModel = { folderName: '' };\n\nexport function NewFolderForm({ onCancel, onConfirm }: Props) {\n const translatedFolderNameRequiredPhrase = t(\n 'browse-dashboards.action.new-folder-name-required-phrase',\n 'Folder name is required.'\n );\n const validateFolderName = async (folderName: string) => {\n try {\n await validationSrv.validateNewFolderName(folderName);\n return true;\n } catch (e) {\n if (e instanceof Error) {\n return e.message;\n } else {\n throw e;\n }\n }\n };\n\n const fieldNameLabel = t('browse-dashboards.new-folder-form.name-label', 'Folder name');\n\n return (\n onConfirm(form.folderName)}\n data-testid={selectors.pages.BrowseDashboards.NewFolderForm.form}\n >\n {({ register, errors }) => (\n <>\n \n await validateFolderName(v),\n })}\n />\n \n \n \n \n \n \n )}\n \n );\n}\n","import React, { useState } from 'react';\nimport { useLocation } from 'react-router-dom';\n\nimport { reportInteraction } from '@grafana/runtime';\nimport { Button, Drawer, Dropdown, Icon, Menu, MenuItem } from '@grafana/ui';\nimport {\n getNewDashboardPhrase,\n getNewFolderPhrase,\n getImportPhrase,\n getNewPhrase,\n} from 'app/features/search/tempI18nPhrases';\nimport { FolderDTO } from 'app/types';\n\nimport { useNewFolderMutation } from '../api/browseDashboardsAPI';\n\nimport { NewFolderForm } from './NewFolderForm';\n\ninterface Props {\n parentFolder?: FolderDTO;\n canCreateFolder: boolean;\n canCreateDashboard: boolean;\n}\n\nexport default function CreateNewButton({ parentFolder, canCreateDashboard, canCreateFolder }: Props) {\n const [isOpen, setIsOpen] = useState(false);\n const location = useLocation();\n const [newFolder] = useNewFolderMutation();\n const [showNewFolderDrawer, setShowNewFolderDrawer] = useState(false);\n\n const onCreateFolder = async (folderName: string) => {\n try {\n await newFolder({\n title: folderName,\n parentUid: parentFolder?.uid,\n });\n const depth = parentFolder?.parents ? parentFolder.parents.length + 1 : 0;\n reportInteraction('grafana_manage_dashboards_folder_created', {\n is_subfolder: Boolean(parentFolder?.uid),\n folder_depth: depth,\n });\n } finally {\n setShowNewFolderDrawer(false);\n }\n };\n\n const newMenu = (\n \n {canCreateDashboard && (\n \n reportInteraction('grafana_menu_item_clicked', {\n url: addFolderUidToUrl('/dashboard/new', parentFolder?.uid),\n from: location.pathname,\n })\n }\n url={addFolderUidToUrl('/dashboard/new', parentFolder?.uid)}\n />\n )}\n {canCreateFolder && setShowNewFolderDrawer(true)} label={getNewFolderPhrase()} />}\n {canCreateDashboard && (\n \n reportInteraction('grafana_menu_item_clicked', {\n url: addFolderUidToUrl('/dashboard/import', parentFolder?.uid),\n from: location.pathname,\n })\n }\n url={addFolderUidToUrl('/dashboard/import', parentFolder?.uid)}\n />\n )}\n \n );\n\n return (\n <>\n \n \n \n {showNewFolderDrawer && (\n setShowNewFolderDrawer(false)}\n size=\"sm\"\n >\n setShowNewFolderDrawer(false)} />\n \n )}\n \n );\n}\n\n/**\n *\n * @param url without any parameters\n * @param folderUid folder id\n * @returns url with paramter if folder is present\n */\nfunction addFolderUidToUrl(url: string, folderUid: string | undefined) {\n return folderUid ? url + '?folderUid=' + folderUid : url;\n}\n","import React, { useCallback } from 'react';\n\nimport { DataFrameView, toDataFrame } from '@grafana/data';\nimport { Button, Card } from '@grafana/ui';\nimport { Trans } from 'app/core/internationalization';\nimport { useKeyNavigationListener } from 'app/features/search/hooks/useSearchKeyboardSelection';\nimport { SearchResultsProps, SearchResultsTable } from 'app/features/search/page/components/SearchResultsTable';\nimport { useSearchStateManager } from 'app/features/search/state/SearchStateManager';\nimport { DashboardViewItemKind } from 'app/features/search/types';\nimport { useDispatch, useSelector } from 'app/types';\n\nimport { setAllSelection, setItemSelectionState, useHasSelection } from '../state';\n\ninterface SearchViewProps {\n height: number;\n width: number;\n canSelect: boolean;\n}\n\nconst NUM_PLACEHOLDER_ROWS = 50;\nconst initialLoadingView = {\n view: new DataFrameView(\n toDataFrame({\n fields: [\n { name: 'uid', display: true, values: Array(NUM_PLACEHOLDER_ROWS).fill(null) },\n { name: 'kind', display: true, values: Array(NUM_PLACEHOLDER_ROWS).fill('dashboard') },\n { name: 'name', display: true, values: Array(NUM_PLACEHOLDER_ROWS).fill('') },\n { name: 'location', display: true, values: Array(NUM_PLACEHOLDER_ROWS).fill('') },\n { name: 'tags', display: true, values: Array(NUM_PLACEHOLDER_ROWS).fill([]) },\n ],\n meta: {\n custom: {\n locationInfo: [],\n },\n },\n })\n ),\n loadMoreItems: () => Promise.resolve(),\n // this is key and controls whether to show the skeleton in generateColumns\n isItemLoaded: () => false,\n totalRows: NUM_PLACEHOLDER_ROWS,\n};\n\nexport function SearchView({ width, height, canSelect }: SearchViewProps) {\n const dispatch = useDispatch();\n const selectedItems = useSelector((wholeState) => wholeState.browseDashboards.selectedItems);\n const hasSelection = useHasSelection();\n\n const { keyboardEvents } = useKeyNavigationListener();\n const [searchState, stateManager] = useSearchStateManager();\n\n const value = searchState.result ?? initialLoadingView;\n\n const selectionChecker = useCallback(\n (kind: string | undefined, uid: string): boolean => {\n if (!kind) {\n return false;\n }\n\n // Currently, this indicates _some_ items are selected, not nessicarily all are\n // selected.\n if (kind === '*' && uid === '*') {\n return hasSelection;\n } else if (kind === '*') {\n // Unsure how this case can happen\n return false;\n }\n\n return selectedItems[assertDashboardViewItemKind(kind)][uid] ?? false;\n },\n [selectedItems, hasSelection]\n );\n\n const clearSelection = useCallback(() => {\n dispatch(setAllSelection({ isSelected: false, folderUID: undefined }));\n }, [dispatch]);\n\n const handleItemSelectionChange = useCallback(\n (kind: string, uid: string) => {\n const newIsSelected = !selectionChecker(kind, uid);\n\n dispatch(\n setItemSelectionState({ item: { kind: assertDashboardViewItemKind(kind), uid }, isSelected: newIsSelected })\n );\n },\n [selectionChecker, dispatch]\n );\n\n if (value.totalRows === 0) {\n return (\n
\n \n \n No results found for your query.\n \n \n \n \n \n
\n );\n }\n\n const props: SearchResultsProps = {\n response: value,\n selection: canSelect ? selectionChecker : undefined,\n selectionToggle: canSelect ? handleItemSelectionChange : undefined,\n clearSelection,\n width: width,\n height: height,\n onTagSelected: stateManager.onAddTag,\n keyboardEvents,\n onDatasourceChange: searchState.datasource ? stateManager.onDatasourceChange : undefined,\n onClickItem: stateManager.onSearchItemClicked,\n };\n\n return ;\n}\n\nfunction assertDashboardViewItemKind(kind: string): DashboardViewItemKind {\n switch (kind) {\n case 'folder':\n return 'folder';\n case 'dashboard':\n return 'dashboard';\n case 'panel':\n return 'panel';\n }\n\n throw new Error('Unsupported kind' + kind);\n}\n","import { css } from '@emotion/css';\nimport React, { memo, useEffect, useMemo } from 'react';\nimport AutoSizer from 'react-virtualized-auto-sizer';\n\nimport { GrafanaTheme2 } from '@grafana/data';\nimport { reportInteraction } from '@grafana/runtime';\nimport { FilterInput, useStyles2 } from '@grafana/ui';\nimport { Page } from 'app/core/components/Page/Page';\nimport { GrafanaRouteComponentProps } from 'app/core/navigation/types';\nimport { useDispatch } from 'app/types';\n\nimport { buildNavModel, getDashboardsTabID } from '../folders/state/navModel';\nimport { useSearchStateManager } from '../search/state/SearchStateManager';\nimport { getSearchPlaceholder } from '../search/tempI18nPhrases';\n\nimport { skipToken, useGetFolderQuery, useSaveFolderMutation } from './api/browseDashboardsAPI';\nimport { BrowseActions } from './components/BrowseActions/BrowseActions';\nimport { BrowseFilters } from './components/BrowseFilters';\nimport { BrowseView } from './components/BrowseView';\nimport CreateNewButton from './components/CreateNewButton';\nimport { FolderActionsButton } from './components/FolderActionsButton';\nimport { SearchView } from './components/SearchView';\nimport { getFolderPermissions } from './permissions';\nimport { setAllSelection, useHasSelection } from './state';\n\nexport interface BrowseDashboardsPageRouteParams {\n uid?: string;\n slug?: string;\n}\n\nexport interface Props extends GrafanaRouteComponentProps {}\n\n// New Browse/Manage/Search Dashboards views for nested folders\n\nconst BrowseDashboardsPage = memo(({ match }: Props) => {\n const { uid: folderUID } = match.params;\n const dispatch = useDispatch();\n\n const styles = useStyles2(getStyles);\n const [searchState, stateManager] = useSearchStateManager();\n const isSearching = stateManager.hasSearchFilters();\n\n useEffect(() => {\n stateManager.initStateFromUrl(folderUID);\n\n // Clear selected state when folderUID changes\n dispatch(\n setAllSelection({\n isSelected: false,\n folderUID: undefined,\n })\n );\n }, [dispatch, folderUID, stateManager]);\n\n useEffect(() => {\n // Clear the search results when we leave SearchView to prevent old results flashing\n // when starting a new search\n if (!isSearching && searchState.result) {\n stateManager.setState({ result: undefined, includePanels: undefined });\n }\n }, [isSearching, searchState.result, stateManager]);\n\n const { data: folderDTO } = useGetFolderQuery(folderUID ?? skipToken);\n const [saveFolder] = useSaveFolderMutation();\n const navModel = useMemo(() => {\n if (!folderDTO) {\n return undefined;\n }\n const model = buildNavModel(folderDTO);\n\n // Set the \"Dashboards\" tab to active\n const dashboardsTabID = getDashboardsTabID(folderDTO.uid);\n const dashboardsTab = model.children?.find((child) => child.id === dashboardsTabID);\n if (dashboardsTab) {\n dashboardsTab.active = true;\n }\n return model;\n }, [folderDTO]);\n\n const hasSelection = useHasSelection();\n\n const { canEditFolders, canEditDashboards, canCreateDashboards, canCreateFolders } = getFolderPermissions(folderDTO);\n\n const showEditTitle = canEditFolders && folderUID;\n const canSelect = canEditFolders || canEditDashboards;\n const onEditTitle = async (newValue: string) => {\n if (folderDTO) {\n const result = await saveFolder({\n ...folderDTO,\n title: newValue,\n });\n if ('error' in result) {\n reportInteraction('grafana_browse_dashboards_page_edit_folder_name', {\n status: 'failed_with_error',\n error: result.error,\n });\n throw result.error;\n } else {\n reportInteraction('grafana_browse_dashboards_page_edit_folder_name', { status: 'success' });\n }\n } else {\n reportInteraction('grafana_browse_dashboards_page_edit_folder_name', { status: 'failed_no_folderDTO' });\n }\n };\n\n return (\n \n {folderDTO && }\n {(canCreateDashboards || canCreateFolders) && (\n \n )}\n \n }\n >\n \n stateManager.onQueryChange(e)}\n />\n\n {hasSelection ? : }\n\n
\n \n {({ width, height }) =>\n isSearching ? (\n \n ) : (\n \n )\n }\n \n
\n
\n \n );\n});\n\nconst getStyles = (theme: GrafanaTheme2) => ({\n pageContents: css({\n display: 'grid',\n gridTemplateRows: 'auto auto 1fr',\n height: '100%',\n rowGap: theme.spacing(1),\n }),\n\n // AutoSizer needs an element to measure the full height available\n subView: css({\n height: '100%',\n }),\n});\n\nBrowseDashboardsPage.displayName = 'BrowseDashboardsPage';\nexport default BrowseDashboardsPage;\n","import React, { useState } from 'react';\n\nimport { config } from '@grafana/runtime';\nimport { Alert, ConfirmModal, Text, Space } from '@grafana/ui';\nimport { Trans, t } from 'app/core/internationalization';\n\nimport { useGetAffectedItemsQuery } from '../../api/browseDashboardsAPI';\nimport { DashboardTreeSelection } from '../../types';\n\nimport { DescendantCount } from './DescendantCount';\n\nexport interface Props {\n isOpen: boolean;\n onConfirm: () => Promise;\n onDismiss: () => void;\n selectedItems: DashboardTreeSelection;\n}\n\nexport const DeleteModal = ({ onConfirm, onDismiss, selectedItems, ...props }: Props) => {\n const { data } = useGetAffectedItemsQuery(selectedItems);\n const deleteIsInvalid = !config.featureToggles.nestedFolders && data && (data.alertRule || data.libraryPanel);\n const [isDeleting, setIsDeleting] = useState(false);\n const onDelete = async () => {\n setIsDeleting(true);\n try {\n await onConfirm();\n setIsDeleting(false);\n onDismiss();\n } catch {\n setIsDeleting(false);\n }\n };\n\n return (\n \n \n \n This action will delete the following content:\n \n \n \n \n \n }\n description={\n <>\n {deleteIsInvalid ? (\n \n \n One or more folders contain library panels or alert rules. Delete these first in order to proceed.\n \n \n ) : null}\n \n }\n confirmationText=\"Delete\"\n confirmText={\n isDeleting\n ? t('browse-dashboards.action.deleting', 'Deleting...')\n : t('browse-dashboards.action.delete-button', 'Delete')\n }\n onDismiss={onDismiss}\n onConfirm={onDelete}\n title={t('browse-dashboards.action.delete-modal-title', 'Delete')}\n {...props}\n />\n );\n};\n","import React, { useState } from 'react';\n\nimport { Alert, Button, Field, Modal, Text, Space } from '@grafana/ui';\nimport { FolderPicker } from 'app/core/components/Select/FolderPicker';\nimport { t, Trans } from 'app/core/internationalization';\n\nimport { DashboardTreeSelection } from '../../types';\n\nimport { DescendantCount } from './DescendantCount';\n\nexport interface Props {\n isOpen: boolean;\n onConfirm: (targetFolderUid: string) => Promise;\n onDismiss: () => void;\n selectedItems: DashboardTreeSelection;\n}\n\nexport const MoveModal = ({ onConfirm, onDismiss, selectedItems, ...props }: Props) => {\n const [moveTarget, setMoveTarget] = useState();\n const [isMoving, setIsMoving] = useState(false);\n const selectedFolders = Object.keys(selectedItems.folder).filter((uid) => selectedItems.folder[uid]);\n\n const onMove = async () => {\n if (moveTarget !== undefined) {\n setIsMoving(true);\n try {\n await onConfirm(moveTarget);\n setIsMoving(false);\n onDismiss();\n } catch {\n setIsMoving(false);\n }\n }\n };\n\n return (\n \n {selectedFolders.length > 0 && (\n \n )}\n\n \n This action will move the following content:\n \n\n \n\n \n\n \n \n \n\n \n \n \n \n \n );\n};\n","import React, { useState } from 'react';\n\nimport { config, locationService, reportInteraction } from '@grafana/runtime';\nimport { Button, Drawer, Dropdown, Icon, Menu, MenuItem } from '@grafana/ui';\nimport { Permissions } from 'app/core/components/AccessControl';\nimport { appEvents } from 'app/core/core';\nimport { t, Trans } from 'app/core/internationalization';\nimport { FolderDTO } from 'app/types';\nimport { ShowModalReactEvent } from 'app/types/events';\n\nimport { useDeleteFolderMutation, useMoveFolderMutation } from '../api/browseDashboardsAPI';\nimport { getFolderPermissions } from '../permissions';\n\nimport { DeleteModal } from './BrowseActions/DeleteModal';\nimport { MoveModal } from './BrowseActions/MoveModal';\n\ninterface Props {\n folder: FolderDTO;\n}\n\nexport function FolderActionsButton({ folder }: Props) {\n const [isOpen, setIsOpen] = useState(false);\n const [showPermissionsDrawer, setShowPermissionsDrawer] = useState(false);\n const [moveFolder] = useMoveFolderMutation();\n const [deleteFolder] = useDeleteFolderMutation();\n const { canEditFolders, canDeleteFolders, canViewPermissions, canSetPermissions } = getFolderPermissions(folder);\n // Can only move folders when nestedFolders is enabled\n const canMoveFolder = config.featureToggles.nestedFolders && canEditFolders;\n\n const onMove = async (destinationUID: string) => {\n await moveFolder({ folder, destinationUID });\n reportInteraction('grafana_manage_dashboards_item_moved', {\n item_counts: {\n folder: 1,\n dashboard: 0,\n },\n source: 'folder_actions',\n });\n };\n\n const onDelete = async () => {\n await deleteFolder(folder);\n reportInteraction('grafana_manage_dashboards_item_deleted', {\n item_counts: {\n folder: 1,\n dashboard: 0,\n },\n source: 'folder_actions',\n });\n const { parents } = folder;\n const parentUrl = parents && parents.length ? parents[parents.length - 1].url : '/dashboards';\n locationService.push(parentUrl);\n };\n\n const showMoveModal = () => {\n appEvents.publish(\n new ShowModalReactEvent({\n component: MoveModal,\n props: {\n selectedItems: {\n folder: { [folder.uid]: true },\n dashboard: {},\n panel: {},\n $all: false,\n },\n onConfirm: onMove,\n },\n })\n );\n };\n\n const showDeleteModal = () => {\n appEvents.publish(\n new ShowModalReactEvent({\n component: DeleteModal,\n props: {\n selectedItems: {\n folder: { [folder.uid]: true },\n dashboard: {},\n panel: {},\n $all: false,\n },\n onConfirm: onDelete,\n },\n })\n );\n };\n\n const managePermissionsLabel = t('browse-dashboards.folder-actions-button.manage-permissions', 'Manage permissions');\n const moveLabel = t('browse-dashboards.folder-actions-button.move', 'Move');\n const deleteLabel = t('browse-dashboards.folder-actions-button.delete', 'Delete');\n\n const menu = (\n \n {canViewPermissions && setShowPermissionsDrawer(true)} label={managePermissionsLabel} />}\n {canMoveFolder && }\n {canDeleteFolders && }\n \n );\n\n if (!canViewPermissions && !canMoveFolder && !canDeleteFolders) {\n return null;\n }\n\n return (\n <>\n \n \n \n {showPermissionsDrawer && (\n setShowPermissionsDrawer(false)}\n size=\"md\"\n >\n \n \n )}\n \n );\n}\n","import { config } from '@grafana/runtime';\nimport { contextSrv } from 'app/core/core';\nimport { AccessControlAction, FolderDTO } from 'app/types';\n\nfunction checkFolderPermission(action: AccessControlAction, folderDTO?: FolderDTO) {\n return folderDTO ? contextSrv.hasPermissionInMetadata(action, folderDTO) : contextSrv.hasPermission(action);\n}\n\nexport function getFolderPermissions(folderDTO?: FolderDTO) {\n // Can only create a folder if we have permissions and either we're at root or nestedFolders is enabled\n const canCreateDashboards = checkFolderPermission(AccessControlAction.DashboardsCreate, folderDTO);\n const canCreateFolders = Boolean(\n (!folderDTO || config.featureToggles.nestedFolders) && checkFolderPermission(AccessControlAction.FoldersCreate)\n );\n const canDeleteFolders = checkFolderPermission(AccessControlAction.FoldersDelete, folderDTO);\n const canEditDashboards = checkFolderPermission(AccessControlAction.DashboardsWrite, folderDTO);\n const canEditFolders = checkFolderPermission(AccessControlAction.FoldersWrite, folderDTO);\n const canSetPermissions = checkFolderPermission(AccessControlAction.FoldersPermissionsWrite, folderDTO);\n const canViewPermissions = checkFolderPermission(AccessControlAction.FoldersPermissionsRead, folderDTO);\n\n return {\n canCreateDashboards,\n canCreateFolders,\n canDeleteFolders,\n canEditDashboards,\n canEditFolders,\n canSetPermissions,\n canViewPermissions,\n };\n}\n","// Temporary place to collect phrases we reuse between new and old browse/search\n// TODO: remove this when new Browse Dashboards UI is no longer feature flagged\n\nimport { t } from 'app/core/internationalization';\n\nexport function getSearchPlaceholder(includePanels = false) {\n return includePanels\n ? t('search.search-input.include-panels-placeholder', 'Search for dashboards, folders, and panels')\n : t('search.search-input.placeholder', 'Search for dashboards and folders');\n}\n\nexport function getNewDashboardPhrase() {\n return t('search.dashboard-actions.new-dashboard', 'New dashboard');\n}\n\nexport function getNewFolderPhrase() {\n return t('search.dashboard-actions.new-folder', 'New folder');\n}\n\nexport function getImportPhrase() {\n return t('search.dashboard-actions.import', 'Import');\n}\n\nexport function getNewPhrase() {\n return t('search.dashboard-actions.new', 'New');\n}\n"],"names":["defaultSortOptionsGetter","SortPicker","onChange","value","placeholder","filter","getSortOptions","isClearable","options","vals","v","isDesc","opt","initialState","defaultQueryParams","getLocalStorageLayout","SearchStateManager","StateManagerBase","query","tagToRemove","tag","tags","newTag","datasource","panel_type","e","starred","sort","layout","includePanels","store","folderUid","doInitialSearch","stateFromUrl","prevSort","stateManager","state","q","trackingInfo","searcher","searchTimestamp","result","error","getSearchStateManager","useSearchStateManager","BrowseActions","styles","getStyles","dispatch","selectedItems","deleteItems","moveItems","moveIsInvalid","config","isSearching","onActionComplete","onDelete","trackAction","onMove","destinationUID","showMoveModal","MoveModal","showDeleteModal","DeleteModal","moveButton","Button","Tooltip","theme","actionMap","action","selectedDashboards","uid","selectedFolders","getLayoutOptions","getValidQueryLayout","ActionRow","onLayoutChange","onSortChange","onStarredFilterChange","onTagFilterChange","getTagOptions","sortPlaceholder","onDatasourceChange","onPanelTypeChange","onSetIncludePanels","showStarredFilter","hideLayout","disabledOptions","TagFilter","Checkbox","RadioButtonGroup","change","BrowseFilters","searchState","SelectionState","CheckboxCell","row","isSelected","onItemSelectionChange","item","CheckboxSpacer","selectors","ev","CheckboxHeaderCell","onAllSelectionChange","CHEVRON_SIZE","ICON_SIZE","NameCell","data","onFolderClick","treeID","level","isOpen","childrenByParentUID","isLoading","iconName","Indent","Text","IconButton","Spinner","Icon","Link","TagsCell","TagList","HEADER_HEIGHT","ROW_HEIGHT","DIVIDER_HEIGHT","DashboardsTree","items","width","height","isItemLoaded","requestLoadMore","canSelect","infiniteLoaderRef","listRef","tableColumns","checkboxColumn","nameColumn","props","tagsColumns","table","getTableProps","getTableBodyProps","headerGroups","virtualData","handleIsItemLoaded","itemIndex","handleLoadMore","startIndex","endIndex","parentUID","getRowHeight","rowIndex","headerGroup","key","headerGroupProps","column","headerProps","onItemsRendered","ref","elem","VirtualListRow","index","style","rows","prepareRow","dashboardItem","cell","cellProps","BrowseView","folderUID","status","flatTree","handleFolderClick","clickedFolderUID","handleItemSelectionChange","selection","hasSelectedDescendants","treeItem","EmptyListCTA","CallToActionCard","newState","collection","thisIsSelected","initialFormModel","NewFolderForm","onCancel","onConfirm","translatedFolderNameRequiredPhrase","validateFolderName","folderName","fieldNameLabel","Form","form","register","errors","Field","Input","CreateNewButton","parentFolder","canCreateDashboard","canCreateFolder","setIsOpen","location","newFolder","showNewFolderDrawer","setShowNewFolderDrawer","onCreateFolder","depth","newMenu","Menu","MenuItem","addFolderUidToUrl","Dropdown","Drawer","url","NUM_PLACEHOLDER_ROWS","initialLoadingView","DataFrameView","SearchView","wholeState","hasSelection","keyboardEvents","selectionChecker","kind","assertDashboardViewItemKind","clearSelection","newIsSelected","Card","SearchResultsTable","BrowseDashboardsPage","match","folderDTO","saveFolder","navModel","model","dashboardsTabID","dashboardsTab","child","canEditFolders","canEditDashboards","canCreateDashboards","canCreateFolders","showEditTitle","onEditTitle","newValue","Page","FolderActionsButton","FilterInput","onDismiss","deleteIsInvalid","isDeleting","setIsDeleting","moveTarget","setMoveTarget","isMoving","setIsMoving","folder","showPermissionsDrawer","setShowPermissionsDrawer","moveFolder","deleteFolder","canDeleteFolders","canViewPermissions","canSetPermissions","canMoveFolder","parents","parentUrl","managePermissionsLabel","moveLabel","deleteLabel","menu","checkFolderPermission","getFolderPermissions","getSearchPlaceholder","getNewDashboardPhrase","getNewFolderPhrase","getImportPhrase","getNewPhrase"],"sourceRoot":""}