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/playlist/PlaylistPage.tsx

104 lines
4.1 KiB

import { useMemo, useState } from 'react';
import { useAsync } from 'react-use';
import { ConfirmModal, EmptyState, LinkButton, TextLink } from '@grafana/ui';
import { Page } from 'app/core/components/Page/Page';
import PageActionBar from 'app/core/components/PageActionBar/PageActionBar';
import { Trans, t } from 'app/core/internationalization';
import { contextSrv } from 'app/core/services/context_srv';
import { PlaylistPageList } from './PlaylistPageList';
import { StartModal } from './StartModal';
import { getPlaylistAPI, searchPlaylists } from './api';
import { Playlist } from './types';
export const PlaylistPage = () => {
const api = getPlaylistAPI();
const [forcePlaylistsFetch, setForcePlaylistsFetch] = useState(0);
const [searchQuery, setSearchQuery] = useState('');
const allPlaylists = useAsync(() => api.getAllPlaylist(), [forcePlaylistsFetch]);
const playlists = useMemo(() => searchPlaylists(allPlaylists.value ?? [], searchQuery), [searchQuery, allPlaylists]);
const [startPlaylist, setStartPlaylist] = useState<Playlist | undefined>();
const [playlistToDelete, setPlaylistToDelete] = useState<Playlist | undefined>();
const hasPlaylists = playlists && playlists.length > 0;
const onDismissDelete = () => setPlaylistToDelete(undefined);
const onDeletePlaylist = () => {
if (!playlistToDelete) {
return;
}
api.deletePlaylist(playlistToDelete.uid).finally(() => {
setForcePlaylistsFetch(forcePlaylistsFetch + 1);
setPlaylistToDelete(undefined);
});
};
const showSearch = allPlaylists.loading || playlists.length > 0 || searchQuery.length > 0;
return (
<Page
actions={
contextSrv.isEditor ? (
<LinkButton href="/playlists/new">
<Trans i18nKey="playlist-page.create-button.title">New playlist</Trans>
</LinkButton>
) : undefined
}
navId="dashboards/playlists"
>
<Page.Contents>
{showSearch && <PageActionBar searchQuery={searchQuery} setSearchQuery={setSearchQuery} />}
{allPlaylists.loading ? (
<PlaylistPageList.Skeleton />
) : (
<>
{!hasPlaylists && searchQuery ? (
<EmptyState variant="not-found" message={t('playlists.empty-state.message', 'No playlists found')} />
) : (
<PlaylistPageList
playlists={playlists}
setStartPlaylist={setStartPlaylist}
setPlaylistToDelete={setPlaylistToDelete}
/>
)}
{!showSearch && (
<EmptyState
variant="call-to-action"
button={
<LinkButton disabled={!contextSrv.isEditor} href="playlists/new" icon="plus" size="lg">
<Trans i18nKey="playlist-page.empty.button">Create playlist</Trans>
</LinkButton>
}
message={t('playlist-page.empty.title', 'There are no playlists created yet')}
>
<Trans i18nKey="playlist-page.empty.pro-tip">
You can use playlists to cycle dashboards on TVs without user control.{' '}
<TextLink external href="https://docs.grafana.org/reference/playlist/">
Learn more
</TextLink>
</Trans>
</EmptyState>
)}
{playlistToDelete && (
<ConfirmModal
title={playlistToDelete.name}
confirmText={t('playlist-page.delete-modal.confirm-text', 'Delete')}
body={t('playlist-page.delete-modal.body', 'Are you sure you want to delete {{name}} playlist?', {
name: playlistToDelete.name,
})}
onConfirm={onDeletePlaylist}
isOpen={Boolean(playlistToDelete)}
onDismiss={onDismissDelete}
/>
)}
{startPlaylist && <StartModal playlist={startPlaylist} onDismiss={() => setStartPlaylist(undefined)} />}
</>
)}
</Page.Contents>
</Page>
);
};
export default PlaylistPage;