mirror of
https://github.com/grafana/grafana.git
synced 2025-02-13 09:05:45 -06:00
* Initial commit * Progress * Update * Progress * updates * Minor fix * fixed ts issue * fixed e2e tests * More explorations * Making progress * Panel options and field options unified * With nested categories * Starting to find something * fix paddings * Progress * Breakthrough ux layout * Progress * Updates * New way of composing options with search * added regex search * Refactoring to react note tree * Show overrides * Adding overrides radio button support * Added popular view * Separate stat/gauge/bargauge options into value options and display options * Initial work on getting library panels into viz picker flow * Fixed issues switching to panel library panel * Move search input put of LibraryPanelsView * Changing design again to have content inside boxes * Style updates * Refactoring to fix scroll issue * Option category naming * Fixed FilterInput issue * Updated snapshots * Fix padding * Updated viz picker design * Unify library panel an viz picker card * Updated card with delete action * Major refactoring back to an object model instead of searching and filtering react node tree * More refactoring * Show option category in label when searching * Nice logic for categories rendering when searching or when only child * Make getSuggestions more lazy for DataLinksEditor * Add missing repeat options and handle conditional options * Prepping options category to be more flexibly and control state from outside * Added option count to search result * Minor style tweak * Added button to close viz picker * Rewrote overrides to enable searching overrides * New search engine and tests * Searching overrides works * Hide radio buttons while searching * Added angular options back * Added memoize for all options so they are not rebuilt for every search key stroke * Added back support for category counters * Started unit test work * Refactoring and base popular options list * Initial update to e2e test, more coming to add e2e test for search features * Minor fix * Review updates * Fixing category open states * Unit test progress * Do not show visualization list mode radio button if library panels is not enabled * Use boolean * More unit tests * Increase library panels per page count and give search focus when switching list mode * field config change test and search test * Feedback updates * Minor tweaks * Minor refactorings * More minimal override collapse state
167 lines
4.7 KiB
TypeScript
167 lines
4.7 KiB
TypeScript
import React, { FC, memo, useState } from 'react';
|
|
import { css } from 'emotion';
|
|
import { HorizontalGroup, stylesFactory, useTheme, Spinner } 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 { FilterInput } from 'app/core/components/FilterInput/FilterInput';
|
|
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>
|
|
<HorizontalGroup justify="space-between">
|
|
<FilterInput value={query.query} onChange={onQueryChange} placeholder={'Search dashboards by name'} />
|
|
<DashboardActions isEditor={isEditor} canEdit={hasEditPermissionInFolders || canSave} folderId={folderId} />
|
|
</HorizontalGroup>
|
|
</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>
|
|
);
|
|
});
|
|
|
|
export default ManageDashboards;
|
|
|
|
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
|
return {
|
|
container: css`
|
|
height: 100%;
|
|
`,
|
|
results: css`
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
height: 100%;
|
|
margin-top: ${theme.spacing.xl};
|
|
`,
|
|
spinner: css`
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
min-height: 200px;
|
|
`,
|
|
};
|
|
});
|