diff --git a/src/components/InfoBanner.jsx b/src/components/InfoBanner.jsx new file mode 100644 index 00000000..75559fa4 --- /dev/null +++ b/src/components/InfoBanner.jsx @@ -0,0 +1,40 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import { Alert, Box, Collapse } from '@mui/material'; +import IconButton from '@mui/material/IconButton'; +import CloseIcon from '@mui/icons-material/Close'; + +const InfoBanner = ({ severity, children, onClose }) => { + const [open, setOpen] = useState(true); + + const handleClose = () => { + onClose && onClose(); + setOpen(false); + }; + + return ( + + + + + + } + sx={{ my: 2, lineHeight: 1.7 }} + > + {children} + + + + ); +}; + +InfoBanner.propTypes = { + severity: PropTypes.string.isRequired, + children: PropTypes.node.isRequired, + onClose: PropTypes.func, +}; + +export default InfoBanner; diff --git a/src/components/Snapshots/SnapshotsTab.jsx b/src/components/Snapshots/SnapshotsTab.jsx index d4a75463..6eef126b 100644 --- a/src/components/Snapshots/SnapshotsTab.jsx +++ b/src/components/Snapshots/SnapshotsTab.jsx @@ -3,11 +3,12 @@ import PropTypes from 'prop-types'; import { useClient } from '../../context/client-context'; import { useSnackbar } from 'notistack'; import { getSnackbarOptions } from '../Common/utils/snackbarOptions'; -import { Button, Grid, TableCell, TableContainer, TableRow, Typography } from '@mui/material'; +import { Button, Grid, Link, TableCell, TableContainer, TableRow, Typography } from '@mui/material'; import PhotoCamera from '@mui/icons-material/PhotoCamera'; import { TableWithGaps, TableHeadWithGaps, TableBodyWithGaps } from '../Common/TableWithGaps'; import { SnapshotsTableRow } from './SnapshotsTableRow'; import { pumpFile, updateProgress } from '../../common/utils'; +import InfoBanner from '../InfoBanner'; export const SnapshotsTab = ({ collectionName }) => { const { client: qdrantClient } = useClient(); @@ -15,6 +16,8 @@ export const SnapshotsTab = ({ collectionName }) => { const [isLoading, setIsLoading] = useState(false); const { enqueueSnackbar, closeSnackbar } = useSnackbar(); const errorSnackbarOptions = getSnackbarOptions('error', closeSnackbar); + const [localShards, setLocalShards] = useState([]); + const [remoteShards, setRemoteShards] = useState([]); useEffect(() => { setIsLoading(true); @@ -29,6 +32,21 @@ export const SnapshotsTab = ({ collectionName }) => { .finally(() => { setIsLoading(false); }); + + qdrantClient + .api('cluster') + .collectionClusterInfo({ collection_name: collectionName }) + .then((res) => { + const remoteShards = res.data.result.remote_shards; + const localShards = res.data.result.local_shards; + if (remoteShards.length > 0) { + setRemoteShards(remoteShards); + setLocalShards(localShards); + } + }) + .catch((err) => { + enqueueSnackbar(err.message, errorSnackbarOptions); + }); }, [qdrantClient, collectionName]); const createSnapshot = () => { @@ -122,6 +140,43 @@ export const SnapshotsTab = ({ collectionName }) => { Take snapshot + {remoteShards && remoteShards.length !== 0 && ( + + + Snapshot will not contain the full collection. It will only include shards on the current machine. + + + {localShards.length > 0 && ( + <> + Local shards: + + + )} + <> + Remote shards (not included in the snapshot): + + + + For more information, please visit the{' '} + + documentation + + . + + + )} {isLoading &&
Loading...
} {!isLoading && snapshots?.length > 0 && (