mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 16:15:42 -06:00
115 lines
4.0 KiB
TypeScript
115 lines
4.0 KiB
TypeScript
import React, { FC, useState } from 'react';
|
|
import { connect, MapStateToProps } from 'react-redux';
|
|
import { NavModel } from '@grafana/data';
|
|
import Page from 'app/core/components/Page/Page';
|
|
import { StoreState } from 'app/types';
|
|
import { GrafanaRouteComponentProps } from '../../core/navigation/types';
|
|
import { getNavModel } from 'app/core/selectors/navModel';
|
|
import { useDebounce } from 'react-use';
|
|
import { PlaylistDTO } from './types';
|
|
import { ConfirmModal } from '@grafana/ui';
|
|
import PageActionBar from 'app/core/components/PageActionBar/PageActionBar';
|
|
import EmptyListCTA from '../../core/components/EmptyListCTA/EmptyListCTA';
|
|
import { deletePlaylist, getAllPlaylist } from './api';
|
|
import { StartModal } from './StartModal';
|
|
import { PlaylistPageList } from './PlaylistPageList';
|
|
import { EmptyQueryListBanner } from './EmptyQueryListBanner';
|
|
|
|
interface ConnectedProps {
|
|
navModel: NavModel;
|
|
}
|
|
export interface PlaylistPageProps extends ConnectedProps, GrafanaRouteComponentProps {}
|
|
|
|
export const PlaylistPage: FC<PlaylistPageProps> = ({ navModel }) => {
|
|
const [searchQuery, setSearchQuery] = useState('');
|
|
const [debouncedSearchQuery, setDebouncedSearchQuery] = useState(searchQuery);
|
|
const [hasFetched, setHasFetched] = useState(false);
|
|
const [startPlaylist, setStartPlaylist] = useState<PlaylistDTO | undefined>();
|
|
const [playlistToDelete, setPlaylistToDelete] = useState<PlaylistDTO | undefined>();
|
|
const [forcePlaylistsFetch, setForcePlaylistsFetch] = useState(0);
|
|
|
|
const [playlists, setPlaylists] = useState<PlaylistDTO[]>([]);
|
|
|
|
useDebounce(
|
|
async () => {
|
|
const playlists = await getAllPlaylist(searchQuery);
|
|
if (!hasFetched) {
|
|
setHasFetched(true);
|
|
}
|
|
setPlaylists(playlists);
|
|
setDebouncedSearchQuery(searchQuery);
|
|
},
|
|
350,
|
|
[forcePlaylistsFetch, searchQuery]
|
|
);
|
|
|
|
const hasPlaylists = playlists && playlists.length > 0;
|
|
const onDismissDelete = () => setPlaylistToDelete(undefined);
|
|
const onDeletePlaylist = () => {
|
|
if (!playlistToDelete) {
|
|
return;
|
|
}
|
|
deletePlaylist(playlistToDelete.id).finally(() => {
|
|
setForcePlaylistsFetch(forcePlaylistsFetch + 1);
|
|
setPlaylistToDelete(undefined);
|
|
});
|
|
};
|
|
|
|
const emptyListBanner = (
|
|
<EmptyListCTA
|
|
title="There are no playlists created yet"
|
|
buttonIcon="plus"
|
|
buttonLink="playlists/new"
|
|
buttonTitle="Create Playlist"
|
|
proTip="You can use playlists to cycle dashboards on TVs without user control"
|
|
proTipLink="http://docs.grafana.org/reference/playlist/"
|
|
proTipLinkTitle="Learn more"
|
|
proTipTarget="_blank"
|
|
/>
|
|
);
|
|
|
|
const showSearch = playlists.length > 0 || searchQuery.length > 0 || debouncedSearchQuery.length > 0;
|
|
|
|
return (
|
|
<Page navModel={navModel}>
|
|
<Page.Contents isLoading={!hasFetched}>
|
|
{showSearch && (
|
|
<PageActionBar
|
|
searchQuery={searchQuery}
|
|
linkButton={{ title: 'New playlist', href: '/playlists/new' }}
|
|
setSearchQuery={setSearchQuery}
|
|
/>
|
|
)}
|
|
|
|
{!hasPlaylists && searchQuery ? (
|
|
<EmptyQueryListBanner />
|
|
) : (
|
|
<PlaylistPageList
|
|
playlists={playlists}
|
|
setStartPlaylist={setStartPlaylist}
|
|
setPlaylistToDelete={setPlaylistToDelete}
|
|
/>
|
|
)}
|
|
{!showSearch && emptyListBanner}
|
|
{playlistToDelete && (
|
|
<ConfirmModal
|
|
title={playlistToDelete.name}
|
|
confirmText="Delete"
|
|
body={`Are you sure you want to delete '${playlistToDelete.name}' playlist?`}
|
|
onConfirm={onDeletePlaylist}
|
|
isOpen={Boolean(playlistToDelete)}
|
|
onDismiss={onDismissDelete}
|
|
/>
|
|
)}
|
|
{startPlaylist && <StartModal playlist={startPlaylist} onDismiss={() => setStartPlaylist(undefined)} />}
|
|
</Page.Contents>
|
|
</Page>
|
|
);
|
|
};
|
|
|
|
const mapStateToProps: MapStateToProps<ConnectedProps, {}, StoreState> = (state: StoreState) => ({
|
|
navModel: getNavModel(state.navIndex, 'playlists'),
|
|
});
|
|
|
|
export default connect(mapStateToProps)(PlaylistPage);
|