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:
+
+ {localShards.map((shard) => (
+
+ Id: {shard.shard_id}
+
+ ))}
+
+ >
+ )}
+ <>
+ Remote shards (not included in the snapshot):
+
+ {remoteShards.map((shard) => (
+
+ Id: {shard.shard_id} ({shard.peer_id})
+
+ ))}
+
+ >
+
+ For more information, please visit the{' '}
+
+ documentation
+
+ .
+
+
+ )}
{isLoading &&
Loading...
}
{!isLoading && snapshots?.length > 0 && (