import { css } from '@emotion/css'; import { useDialog } from '@react-aria/dialog'; import { FocusScope } from '@react-aria/focus'; import { useOverlay } from '@react-aria/overlays'; import { useRef, useState } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; import { getBackendSrv } from '@grafana/runtime'; import { Button, useStyles2 } from '@grafana/ui'; import { config } from 'app/core/config'; import { MediaType, PickerTabType, ResourceFolderName } from '../types'; import { FileUploader } from './FileUploader'; import { FolderPickerTab } from './FolderPickerTab'; import { URLPickerTab } from './URLPickerTab'; interface Props { value?: string; //img/icons/unicons/0-plus.svg onChange: (value?: string) => void; mediaType: MediaType; folderName: ResourceFolderName; maxFiles?: number; hidePopper?: () => void; } interface ErrorResponse { message: string; } export const ResourcePickerPopover = (props: Props) => { const { value, onChange, mediaType, folderName, maxFiles, hidePopper } = props; const styles = useStyles2(getStyles); const onClose = () => { onChange(value); hidePopper?.(); }; const ref = useRef(null); const { dialogProps } = useDialog({}, ref); const { overlayProps } = useOverlay({ onClose, isDismissable: true, isOpen: true }, ref); const isURL = value && value.includes('://'); const [newValue, setNewValue] = useState(value ?? ''); const [activePicker, setActivePicker] = useState(isURL ? PickerTabType.URL : PickerTabType.Folder); const [formData, setFormData] = useState(new FormData()); const [upload, setUpload] = useState(false); const [error, setError] = useState({ message: '' }); const getTabClassName = (tabName: PickerTabType) => { return `${styles.resourcePickerPopoverTab} ${activePicker === tabName && styles.resourcePickerPopoverActiveTab}`; }; const renderFolderPicker = () => ( ); const renderURLPicker = () => ; const renderUploader = () => ( ); const renderPicker = () => { switch (activePicker) { case PickerTabType.Folder: return renderFolderPicker(); case PickerTabType.URL: return renderURLPicker(); case PickerTabType.Upload: return renderUploader(); default: return renderFolderPicker(); } }; return (
{renderPicker()}
); }; const getStyles = (theme: GrafanaTheme2) => ({ resourcePickerPopover: css({ borderRadius: theme.shape.radius.default, boxShadow: theme.shadows.z3, background: theme.colors.background.primary, border: `1px solid ${theme.colors.border.weak}`, }), resourcePickerPopoverTab: css({ width: '50%', textAlign: 'center', padding: theme.spacing(1, 0), background: theme.colors.background.secondary, color: theme.colors.text.secondary, fontSize: theme.typography.bodySmall.fontSize, cursor: 'pointer', border: 'none', '&:focus:not(:focus-visible)': { outline: 'none', boxShadow: 'none', }, ':focus-visible': { position: 'relative', }, }), resourcePickerPopoverActiveTab: css({ color: theme.colors.text.primary, fontWeight: theme.typography.fontWeightMedium, background: theme.colors.background.primary, }), resourcePickerPopoverContent: css({ width: '315px', fontSize: theme.typography.bodySmall.fontSize, minHeight: '184px', padding: theme.spacing(1), display: 'flex', flexDirection: 'column', }), resourcePickerPopoverTabs: css({ display: 'flex', width: '100%', borderRadius: `${theme.shape.radius.default} ${theme.shape.radius.default} 0 0`, }), buttonRow: css({ display: 'flex', justifyContent: 'center', gap: theme.spacing(2), padding: theme.spacing(1), }), });