import { css } from '@emotion/css'; import React, { Dispatch, SetStateAction, useEffect, useState } from 'react'; import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { Field, FilterInput, Select, useStyles2 } from '@grafana/ui'; import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { FileElement, GrafanaDatasource } from 'app/plugins/datasource/grafana/datasource'; import { MediaType, ResourceFolderName } from '../types'; import { ResourceCards } from './ResourceCards'; const getFolders = (mediaType: MediaType) => { if (mediaType === MediaType.Icon) { return [ResourceFolderName.Icon, ResourceFolderName.IOT, ResourceFolderName.Marker]; } else { return [ResourceFolderName.BG]; } }; const getFolderIfExists = (folders: Array>, path: string) => { return folders.find((folder) => path.startsWith(folder.value!)) ?? folders[0]; }; export interface ResourceItem { label: string; value: string; // includes folder search: string; imgUrl: string; } interface Props { value?: string; mediaType: MediaType; folderName: ResourceFolderName; newValue: string; setNewValue: Dispatch>; } export const FolderPickerTab = (props: Props) => { const { value, mediaType, folderName, newValue, setNewValue } = props; const styles = useStyles2(getStyles); const folders = getFolders(mediaType).map((v) => ({ label: v, value: v, })); const [searchQuery, setSearchQuery] = useState(); const [currentFolder, setCurrentFolder] = useState>( getFolderIfExists(folders, value?.length ? value : folderName) ); const [directoryIndex, setDirectoryIndex] = useState([]); const [filteredIndex, setFilteredIndex] = useState([]); const onChangeSearch = (query: string) => { if (query) { query = query.toLowerCase(); setFilteredIndex(directoryIndex.filter((card) => card.search.includes(query))); } else { setFilteredIndex(directoryIndex); } }; useEffect(() => { // we don't want to load everything before picking a folder const folder = currentFolder?.value; if (folder) { const filter = mediaType === MediaType.Icon ? (item: FileElement) => item.name.endsWith('.svg') : (item: FileElement) => item.name.endsWith('.png') || item.name.endsWith('.gif'); getDatasourceSrv() .get('-- Grafana --') .then((ds) => { (ds as GrafanaDatasource).listFiles(folder).subscribe({ next: (frame) => { const cards: ResourceItem[] = []; frame.forEach((item) => { if (filter(item)) { const idx = item.name.lastIndexOf('.'); cards.push({ value: `${folder}/${item.name}`, label: item.name, search: (idx ? item.name.substring(0, idx) : item.name).toLowerCase(), imgUrl: `public/${folder}/${item.name}`, }); } }); setDirectoryIndex(cards); setFilteredIndex(cards); }, }); }); } }, [mediaType, currentFolder]); return ( <>