The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/features/search/components/ManageDashboards.tsx

169 lines
4.8 KiB

import React, { FC, memo, useState } from 'react';
import { css } from '@emotion/css';
import { stylesFactory, useTheme, Spinner, FilterInput } from '@grafana/ui';
import { GrafanaTheme } from '@grafana/data';
import { contextSrv } from 'app/core/services/context_srv';
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
import { FolderDTO } from 'app/types';
import { useManageDashboards } from '../hooks/useManageDashboards';
import { SearchLayout } from '../types';
import { ConfirmDeleteModal } from './ConfirmDeleteModal';
import { MoveToFolderModal } from './MoveToFolderModal';
import { useSearchQuery } from '../hooks/useSearchQuery';
import { SearchResultsFilter } from './SearchResultsFilter';
import { SearchResults } from './SearchResults';
import { DashboardActions } from './DashboardActions';
export interface Props {
folder?: FolderDTO;
}
const { isEditor } = contextSrv;
export const ManageDashboards: FC<Props> = memo(({ folder }) => {
const folderId = folder?.id;
const folderUid = folder?.uid;
const theme = useTheme();
const styles = getStyles(theme);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [isMoveModalOpen, setIsMoveModalOpen] = useState(false);
const defaultLayout = folderId ? SearchLayout.List : SearchLayout.Folders;
const queryParamsDefaults = {
skipRecent: true,
skipStarred: true,
folderIds: folderId ? [folderId] : [],
layout: defaultLayout,
};
const {
query,
hasFilters,
onQueryChange,
onTagFilterChange,
onStarredFilterChange,
onTagAdd,
onSortChange,
onLayoutChange,
} = useSearchQuery(queryParamsDefaults);
const {
results,
loading,
initialLoading,
canSave,
allChecked,
hasEditPermissionInFolders,
canMove,
canDelete,
onToggleSection,
onToggleChecked,
onToggleAllChecked,
onDeleteItems,
onMoveItems,
noFolders,
} = useManageDashboards(query, {}, folder);
const onMoveTo = () => {
setIsMoveModalOpen(true);
};
const onItemDelete = () => {
setIsDeleteModalOpen(true);
};
if (initialLoading) {
return <Spinner className={styles.spinner} />;
}
if (noFolders && !hasFilters) {
return (
<EmptyListCTA
title="This folder doesn't have any dashboards yet"
buttonIcon="plus"
buttonTitle="Create Dashboard"
buttonLink={`dashboard/new?folderId=${folderId}`}
proTip="Add/move dashboards to your folder at ->"
proTipLink="dashboards"
proTipLinkTitle="Manage dashboards"
proTipTarget=""
/>
);
}
return (
<div className={styles.container}>
<div className="page-action-bar">
<div className="gf-form gf-form--grow m-r-2">
<FilterInput value={query.query} onChange={onQueryChange} placeholder={'Search dashboards by name'} />
</div>
<DashboardActions isEditor={isEditor} canEdit={hasEditPermissionInFolders || canSave} folderId={folderId} />
</div>
<div className={styles.results}>
<SearchResultsFilter
allChecked={allChecked}
canDelete={hasEditPermissionInFolders && canDelete}
canMove={hasEditPermissionInFolders && canMove}
deleteItem={onItemDelete}
moveTo={onMoveTo}
onToggleAllChecked={onToggleAllChecked}
onStarredFilterChange={onStarredFilterChange}
onSortChange={onSortChange}
onTagFilterChange={onTagFilterChange}
query={query}
hideLayout={!!folderUid}
onLayoutChange={onLayoutChange}
editable={hasEditPermissionInFolders}
/>
<SearchResults
loading={loading}
results={results}
editable={hasEditPermissionInFolders}
onTagSelected={onTagAdd}
onToggleSection={onToggleSection}
onToggleChecked={onToggleChecked}
layout={query.layout}
/>
</div>
<ConfirmDeleteModal
onDeleteItems={onDeleteItems}
results={results}
isOpen={isDeleteModalOpen}
onDismiss={() => setIsDeleteModalOpen(false)}
/>
<MoveToFolderModal
onMoveItems={onMoveItems}
results={results}
isOpen={isMoveModalOpen}
onDismiss={() => setIsMoveModalOpen(false)}
/>
</div>
);
});
ManageDashboards.displayName = 'ManageDashboards';
export default ManageDashboards;
const getStyles = stylesFactory((theme: GrafanaTheme) => {
return {
container: css`
height: 100%;
display: flex;
flex-direction: column;
`,
results: css`
display: flex;
flex-direction: column;
flex: 1 1 0;
height: 100%;
padding-top: ${theme.spacing.lg};
`,
spinner: css`
display: flex;
justify-content: center;
align-items: center;
min-height: 200px;
`,
};
});