import React, { useEffect, useMemo, useState } from 'react'; import take from 'lodash/take'; import { PanelProps } from '@grafana/data'; import { CustomScrollbar, Icon, useStyles } from '@grafana/ui'; import { getBackendSrv } from 'app/core/services/backend_srv'; import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv'; import impressionSrv from 'app/core/services/impression_srv'; import { DashboardSearchHit } from 'app/features/search/types'; import { DashListOptions } from './types'; import { getStyles } from './styles'; type Dashboard = DashboardSearchHit & { isSearchResult?: boolean; isRecent?: boolean }; interface DashboardGroup { show: boolean; header: string; dashboards: Dashboard[]; } async function fetchDashboards(options: DashListOptions) { let starredDashboards: Promise = Promise.resolve([]); if (options.showStarred) { const params = { limit: options.maxItems, starred: 'true' }; starredDashboards = getBackendSrv().search(params); } let recentDashboards: Promise = Promise.resolve([]); if (options.showRecentlyViewed) { const dashIds = take(impressionSrv.getDashboardOpened(), options.maxItems); recentDashboards = getBackendSrv().search({ dashboardIds: dashIds, limit: options.maxItems }); } let searchedDashboards: Promise = Promise.resolve([]); if (options.showSearch) { const params = { limit: options.maxItems, query: options.query, folderIds: options.folderId, tag: options.tags, type: 'dash-db', }; searchedDashboards = getBackendSrv().search(params); } const [starred, searched, recent] = await Promise.all([starredDashboards, searchedDashboards, recentDashboards]); const dashMap = starred.reduce( (acc, dash) => Object.assign(acc, { [dash.id]: dash }), {} as Record ); searched.forEach(dash => { if (dashMap.hasOwnProperty(dash.id)) { dashMap[dash.id].isSearchResult = true; } else { dashMap[dash.id] = { ...dash, isSearchResult: true }; } }); recent.forEach(dash => { if (dashMap.hasOwnProperty(dash.id)) { dashMap[dash.id].isRecent = true; } else { dashMap[dash.id] = { ...dash, isRecent: true }; } }); return dashMap; } export function DashList(props: PanelProps) { const [dashboards, setDashboards] = useState>({}); useEffect(() => { fetchDashboards(props.options).then(dashes => { setDashboards(dashes); }); }, [ props.options.showSearch, props.options.showStarred, props.options.showRecentlyViewed, props.options.maxItems, props.options.query, props.options.tags, props.options.folderId, ]); const toggleDashboardStar = async (e: React.SyntheticEvent, dash: Dashboard) => { e.preventDefault(); e.stopPropagation(); const isStarred = await getDashboardSrv().starDashboard(dash.id.toString(), dash.isStarred); setDashboards(Object.assign({}, dashboards, { [dash.id]: { ...dash, isStarred } })); }; const [starredDashboards, recentDashboards, searchedDashboards] = useMemo(() => { const dashboardList = Object.values(dashboards); return [ dashboardList.filter(dash => dash.isStarred), dashboardList.filter(dash => dash.isRecent), dashboardList.filter(dash => dash.isSearchResult), ]; }, [dashboards]); const { showStarred, showRecentlyViewed, showHeadings, showSearch } = props.options; const dashboardGroups: DashboardGroup[] = [ { header: 'Starred dashboards', dashboards: starredDashboards, show: showStarred, }, { header: 'Recently viewed dashboards', dashboards: recentDashboards, show: showRecentlyViewed, }, { header: 'Search', dashboards: searchedDashboards, show: showSearch, }, ]; const css = useStyles(getStyles); return ( {dashboardGroups.map( ({ show, header, dashboards }, i) => show && (
{showHeadings &&
{header}
}
    {dashboards.map(dash => (
  • {dash.title} {dash.folderTitle &&
    {dash.folderTitle}
    }
    toggleDashboardStar(e, dash)}>
  • ))}
) )}
); }