Added URL support to object view (#1831)
- Added URL support to object view - Refactored & simplified requests Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -29,7 +29,7 @@ import { connect } from "react-redux";
|
||||
import history from "../../../../../../history";
|
||||
import { decodeFileName, encodeFileName } from "../../../../../../common/utils";
|
||||
import { setModalErrorSnackMessage } from "../../../../../../actions";
|
||||
import { BucketObject } from "./types";
|
||||
import { BucketObjectItem } from "./types";
|
||||
import { CreateNewPathIcon } from "../../../../../../icons";
|
||||
|
||||
interface ICreateFolder {
|
||||
@@ -37,9 +37,9 @@ interface ICreateFolder {
|
||||
modalOpen: boolean;
|
||||
bucketName: string;
|
||||
folderName: string;
|
||||
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
|
||||
onClose: () => any;
|
||||
existingFiles: BucketObject[];
|
||||
existingFiles: BucketObjectItem[];
|
||||
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
@@ -74,8 +74,9 @@ const CreateFolderModal = ({
|
||||
? decodedFolderName
|
||||
: `${decodedFolderName}/`;
|
||||
}
|
||||
const sharesName = (record: BucketObject) =>
|
||||
const sharesName = (record: BucketObjectItem) =>
|
||||
record.name === folderPath + pathUrl;
|
||||
|
||||
if (existingFiles.findIndex(sharesName) !== -1) {
|
||||
setModalErrorSnackMessage({
|
||||
errorMessage: "Folder cannot have the same name as an existing file",
|
||||
@@ -84,8 +85,8 @@ const CreateFolderModal = ({
|
||||
return;
|
||||
}
|
||||
const newPath = `/buckets/${bucketName}/browse/${encodeFileName(
|
||||
`${folderPath}${pathUrl}`
|
||||
)}/`;
|
||||
`${folderPath}${pathUrl}/`
|
||||
)}`;
|
||||
history.push(newPath);
|
||||
onClose();
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
// Copyright (c) 2022 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
@@ -30,12 +30,7 @@ import withStyles from "@mui/styles/withStyles";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import get from "lodash/get";
|
||||
import {
|
||||
BucketObject,
|
||||
BucketObjectsList,
|
||||
RewindObject,
|
||||
RewindObjectList,
|
||||
} from "./types";
|
||||
import { BucketObjectItem, BucketObjectItemsList } from "./types";
|
||||
import api from "../../../../../../common/api";
|
||||
import TableWrapper, {
|
||||
ItemActions,
|
||||
@@ -60,14 +55,18 @@ import {
|
||||
completeObject,
|
||||
openList,
|
||||
resetRewind,
|
||||
setLoadingObjectInfo,
|
||||
setLoadingObjectsList,
|
||||
setLoadingVersions,
|
||||
setNewObject,
|
||||
setObjectDetailsView,
|
||||
setSearchObjects,
|
||||
setSelectedObjectView,
|
||||
setShowDeletedObjects,
|
||||
setVersionsModeEnabled,
|
||||
updateProgress,
|
||||
} from "../../../../ObjectBrowser/actions";
|
||||
import { Route } from "../../../../ObjectBrowser/reducers";
|
||||
import { Route } from "../../../../ObjectBrowser/types";
|
||||
|
||||
import { download, extensionPreview, sortListObjects } from "../utils";
|
||||
import {
|
||||
@@ -219,6 +218,7 @@ interface IListObjectsProps {
|
||||
bucketToRewind: string;
|
||||
searchObjects: string;
|
||||
showDeleted: boolean;
|
||||
loading: boolean;
|
||||
setSnackBarMessage: typeof setSnackBarMessage;
|
||||
setErrorSnackMessage: typeof setErrorSnackMessage;
|
||||
resetRewind: typeof resetRewind;
|
||||
@@ -226,15 +226,21 @@ interface IListObjectsProps {
|
||||
setBucketInfo: typeof setBucketInfo;
|
||||
bucketInfo: BucketInfo | null;
|
||||
versionsMode: boolean;
|
||||
detailsOpen: boolean;
|
||||
setBucketDetailsLoad: typeof setBucketDetailsLoad;
|
||||
setNewObject: typeof setNewObject;
|
||||
updateProgress: typeof updateProgress;
|
||||
completeObject: typeof completeObject;
|
||||
openList: typeof openList;
|
||||
setSearchObjects: typeof setSearchObjects;
|
||||
selectedInternalPaths: string | null;
|
||||
setVersionsModeEnabled: typeof setVersionsModeEnabled;
|
||||
setShowDeletedObjects: typeof setShowDeletedObjects;
|
||||
setLoadingVersions: typeof setLoadingVersions;
|
||||
setObjectDetailsView: typeof setObjectDetailsView;
|
||||
setSelectedObjectView: typeof setSelectedObjectView;
|
||||
setLoadingObjectInfo: typeof setLoadingObjectInfo;
|
||||
setLoadingObjectsList: typeof setLoadingObjectsList;
|
||||
}
|
||||
|
||||
function useInterval(callback: any, delay: number) {
|
||||
@@ -268,6 +274,7 @@ const ListObjects = ({
|
||||
history,
|
||||
rewindEnabled,
|
||||
rewindDate,
|
||||
loading,
|
||||
bucketToRewind,
|
||||
setSnackBarMessage,
|
||||
setErrorSnackMessage,
|
||||
@@ -285,13 +292,16 @@ const ListObjects = ({
|
||||
openList,
|
||||
setVersionsModeEnabled,
|
||||
showDeleted,
|
||||
detailsOpen,
|
||||
setShowDeletedObjects,
|
||||
setLoadingVersions,
|
||||
setObjectDetailsView,
|
||||
selectedInternalPaths,
|
||||
setSelectedObjectView,
|
||||
setLoadingObjectInfo,
|
||||
setLoadingObjectsList,
|
||||
}: IListObjectsProps) => {
|
||||
const [records, setRecords] = useState<BucketObject[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const [rewind, setRewind] = useState<RewindObject[]>([]);
|
||||
const [loadingRewind, setLoadingRewind] = useState<boolean>(false);
|
||||
const [records, setRecords] = useState<BucketObjectItem[]>([]);
|
||||
const [deleteMultipleOpen, setDeleteMultipleOpen] = useState<boolean>(false);
|
||||
const [loadingStartTime, setLoadingStartTime] = useState<number>(0);
|
||||
const [loadingMessage, setLoadingMessage] =
|
||||
@@ -303,9 +313,8 @@ const ListObjects = ({
|
||||
const [rewindSelect, setRewindSelect] = useState<boolean>(false);
|
||||
const [selectedObjects, setSelectedObjects] = useState<string[]>([]);
|
||||
const [previewOpen, setPreviewOpen] = useState<boolean>(false);
|
||||
const [selectedPreview, setSelectedPreview] = useState<BucketObject | null>(
|
||||
null
|
||||
);
|
||||
const [selectedPreview, setSelectedPreview] =
|
||||
useState<BucketObjectItem | null>(null);
|
||||
const [shareFileModalOpen, setShareFileModalOpen] = useState<boolean>(false);
|
||||
const [sortDirection, setSortDirection] = useState<
|
||||
"ASC" | "DESC" | undefined
|
||||
@@ -314,10 +323,6 @@ const ListObjects = ({
|
||||
const [iniLoad, setIniLoad] = useState<boolean>(false);
|
||||
const [canShareFile, setCanShareFile] = useState<boolean>(false);
|
||||
const [canPreviewFile, setCanPreviewFile] = useState<boolean>(false);
|
||||
const [detailsOpen, setDetailsOpen] = useState<boolean>(false);
|
||||
const [selectedInternalPaths, setSelectedInternalPaths] = useState<
|
||||
string | null
|
||||
>(null);
|
||||
const [quota, setQuota] = useState<BucketQuota | null>(null);
|
||||
|
||||
const internalPaths = get(match.params, "subpaths", "");
|
||||
@@ -375,14 +380,14 @@ const ListObjects = ({
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedObjects.length > 0) {
|
||||
setDetailsOpen(true);
|
||||
setObjectDetailsView(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedObjects.length === 0 && selectedInternalPaths === null) {
|
||||
setDetailsOpen(false);
|
||||
setObjectDetailsView(false);
|
||||
}
|
||||
}, [selectedObjects, selectedInternalPaths]);
|
||||
}, [selectedObjects, selectedInternalPaths, setObjectDetailsView]);
|
||||
|
||||
const displayDeleteObject = hasPermission(bucketName, [
|
||||
IAM_SCOPES.S3_DELETE_OBJECT,
|
||||
@@ -442,6 +447,7 @@ const ListObjects = ({
|
||||
});
|
||||
} else {
|
||||
setLoadingVersioning(false);
|
||||
setRecords([]);
|
||||
}
|
||||
}
|
||||
}, [bucketName, loadingVersioning, setErrorSnackMessage, displayListObjects]);
|
||||
@@ -460,74 +466,44 @@ const ListObjects = ({
|
||||
setLoadingLocking(false);
|
||||
});
|
||||
} else {
|
||||
setRecords([]);
|
||||
setLoadingLocking(false);
|
||||
}
|
||||
}
|
||||
}, [bucketName, loadingLocking, setErrorSnackMessage, displayListObjects]);
|
||||
|
||||
// Rewind
|
||||
useEffect(() => {
|
||||
if (rewindEnabled) {
|
||||
if (bucketToRewind !== bucketName) {
|
||||
resetRewind();
|
||||
return;
|
||||
}
|
||||
const decodedIPaths = decodeFileName(internalPaths);
|
||||
|
||||
if (rewindDate) {
|
||||
setLoadingRewind(true);
|
||||
const rewindParsed = rewindDate.toISOString();
|
||||
let pathPrefix = "";
|
||||
if (internalPaths) {
|
||||
const decodedPath = decodeFileName(internalPaths);
|
||||
pathPrefix = decodedPath.endsWith("/")
|
||||
? decodedPath
|
||||
: decodedPath + "/";
|
||||
}
|
||||
api
|
||||
.invoke(
|
||||
"GET",
|
||||
`/api/v1/buckets/${bucketName}/rewind/${rewindParsed}${
|
||||
pathPrefix ? `?prefix=${encodeFileName(pathPrefix)}` : ``
|
||||
}`
|
||||
)
|
||||
.then((res: RewindObjectList) => {
|
||||
setLoadingRewind(false);
|
||||
if (res.objects) {
|
||||
// We omit files from the same path
|
||||
const filteredObjects = res.objects.filter((object) => {
|
||||
return object.name !== decodeFileName(internalPaths);
|
||||
});
|
||||
|
||||
setRewind(filteredObjects);
|
||||
} else {
|
||||
setRewind([]);
|
||||
}
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
setLoadingRewind(false);
|
||||
setErrorSnackMessage(err);
|
||||
});
|
||||
}
|
||||
if (decodedIPaths.endsWith("/") || decodedIPaths === "") {
|
||||
setLoadingObjectsList(true);
|
||||
setObjectDetailsView(false);
|
||||
setSearchObjects("");
|
||||
} else {
|
||||
console.log("AQUI", decodedIPaths);
|
||||
setLoadingObjectInfo(true);
|
||||
setObjectDetailsView(true);
|
||||
setLoadingVersions(true);
|
||||
setSelectedObjectView(
|
||||
`${decodedIPaths ? `${encodeFileName(decodedIPaths)}` : ``}`
|
||||
);
|
||||
}
|
||||
}, [
|
||||
rewindEnabled,
|
||||
rewindDate,
|
||||
bucketToRewind,
|
||||
bucketName,
|
||||
match,
|
||||
setErrorSnackMessage,
|
||||
resetRewind,
|
||||
internalPaths,
|
||||
setSearchObjects,
|
||||
rewindDate,
|
||||
rewindEnabled,
|
||||
setLoadingObjectInfo,
|
||||
setLoadingVersions,
|
||||
setObjectDetailsView,
|
||||
setSelectedObjectView,
|
||||
setLoadingObjectsList,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
setDetailsOpen(false);
|
||||
setSearchObjects("");
|
||||
}, [internalPaths, setSearchObjects]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log("SET PATH");
|
||||
if (loading) {
|
||||
console.log("STE");
|
||||
if (displayListObjects) {
|
||||
let pathPrefix = "";
|
||||
if (internalPaths) {
|
||||
@@ -541,9 +517,23 @@ const ListObjects = ({
|
||||
setLoadingStartTime(currentTimestamp);
|
||||
setLoadingMessage(defLoading);
|
||||
|
||||
// We get URL to look into
|
||||
let urlTake = `/api/v1/buckets/${bucketName}/objects`;
|
||||
|
||||
if (showDeleted) {
|
||||
// Is rewind enabled?, we use Rewind API
|
||||
if (rewindEnabled) {
|
||||
if (bucketToRewind !== bucketName) {
|
||||
resetRewind();
|
||||
return;
|
||||
}
|
||||
|
||||
if (rewindDate) {
|
||||
const rewindParsed = rewindDate.toISOString();
|
||||
|
||||
urlTake = `/api/v1/buckets/${bucketName}/rewind/${rewindParsed}`;
|
||||
}
|
||||
} else if (showDeleted) {
|
||||
// Do we want to display deleted items too?, we use rewind to current time to show everything
|
||||
const currDate = new Date();
|
||||
const currDateISO = currDate.toISOString();
|
||||
|
||||
@@ -557,11 +547,12 @@ const ListObjects = ({
|
||||
pathPrefix ? `?prefix=${encodeFileName(pathPrefix)}` : ``
|
||||
}`
|
||||
)
|
||||
.then((res: BucketObjectsList) => {
|
||||
const records: BucketObject[] = res.objects || [];
|
||||
const folders: BucketObject[] = [];
|
||||
const files: BucketObject[] = [];
|
||||
.then((res: BucketObjectItemsList) => {
|
||||
const records: BucketObjectItem[] = res.objects || [];
|
||||
const folders: BucketObjectItem[] = [];
|
||||
const files: BucketObjectItem[] = [];
|
||||
|
||||
// We separate items between folders or files to display folders at the beginning always.
|
||||
records.forEach((record) => {
|
||||
// We omit files from the same path
|
||||
if (record.name !== decodeFileName(internalPaths)) {
|
||||
@@ -574,10 +565,14 @@ const ListObjects = ({
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const recordsInElement = [...folders, ...files];
|
||||
setRecords(recordsInElement);
|
||||
// In case no objects were retrieved, We check if item is a file
|
||||
if (!res.objects && pathPrefix !== "") {
|
||||
|
||||
if (recordsInElement.length === 0 && pathPrefix !== "") {
|
||||
let pathTest = `/api/v1/buckets/${bucketName}/objects${
|
||||
internalPaths ? `?prefix=${internalPaths}` : ""
|
||||
}`;
|
||||
|
||||
if (rewindEnabled) {
|
||||
const rewindParsed = rewindDate.toISOString();
|
||||
|
||||
@@ -588,89 +583,96 @@ const ListObjects = ({
|
||||
? decodedPath
|
||||
: decodedPath + "/";
|
||||
}
|
||||
api
|
||||
.invoke(
|
||||
"GET",
|
||||
`/api/v1/buckets/${bucketName}/rewind/${rewindParsed}${
|
||||
pathPrefix ? `?prefix=${encodeFileName(pathPrefix)}` : ``
|
||||
}`
|
||||
)
|
||||
.then((res: RewindObjectList) => {
|
||||
//It is a file since it has elements in the object, setting file flag and waiting for component mount
|
||||
if (res.objects === null) {
|
||||
//setFileModeEnabled(true);
|
||||
setLoadingRewind(false);
|
||||
setLoading(false);
|
||||
} else {
|
||||
// It is a folder, we remove loader
|
||||
setLoadingRewind(false);
|
||||
setLoading(false);
|
||||
//setFileModeEnabled(false);
|
||||
}
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
setLoadingRewind(false);
|
||||
setLoading(false);
|
||||
setErrorSnackMessage(err);
|
||||
});
|
||||
} else {
|
||||
api
|
||||
.invoke(
|
||||
"GET",
|
||||
`/api/v1/buckets/${bucketName}/objects${
|
||||
internalPaths ? `?prefix=${internalPaths}` : ``
|
||||
}`
|
||||
)
|
||||
.then((res: BucketObjectsList) => {
|
||||
//It is a file since it has elements in the object, setting file flag and waiting for component mount
|
||||
if (!res.objects) {
|
||||
// It is a folder, we remove loader
|
||||
//setFileModeEnabled(false);
|
||||
setLoading(false);
|
||||
} else {
|
||||
// This code prevents the program from opening a file when a substring of that file is entered as a new folder.
|
||||
// Previously, if there was a file test1.txt and the folder test was created with the same prefix, the program
|
||||
// would open test1.txt instead
|
||||
let found = false;
|
||||
let pathPrefixChopped = pathPrefix.slice(
|
||||
0,
|
||||
pathPrefix.length - 1
|
||||
);
|
||||
for (let i = 0; i < res.objects.length; i++) {
|
||||
if (res.objects[i].name === pathPrefixChopped) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (
|
||||
(res.objects.length === 1 &&
|
||||
res.objects[0].name.endsWith("/")) ||
|
||||
!found
|
||||
) {
|
||||
//setFileModeEnabled(false);
|
||||
} else {
|
||||
//setFileModeEnabled(true);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
}
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
setLoading(false);
|
||||
setErrorSnackMessage(err);
|
||||
});
|
||||
pathTest = `/api/v1/buckets/${bucketName}/rewind/${rewindParsed}${
|
||||
pathPrefix ? `?prefix=${encodeFileName(pathPrefix)}` : ``
|
||||
}`;
|
||||
}
|
||||
|
||||
api
|
||||
.invoke("GET", pathTest)
|
||||
.then((res: BucketObjectItemsList) => {
|
||||
//It is a file since it has elements in the object, setting file flag and waiting for component mount
|
||||
if (!res.objects) {
|
||||
// It is a folder, we remove loader & set original results list
|
||||
setLoadingObjectsList(false);
|
||||
setRecords(recordsInElement);
|
||||
console.log("1");
|
||||
} else {
|
||||
// This code prevents the program from opening a file when a substring of that file is entered as a new folder.
|
||||
// Previously, if there was a file test1.txt and the folder test was created with the same prefix, the program
|
||||
// would open test1.txt instead
|
||||
let found = false;
|
||||
let pathPrefixChopped = pathPrefix.slice(
|
||||
0,
|
||||
pathPrefix.length - 1
|
||||
);
|
||||
for (let i = 0; i < res.objects.length; i++) {
|
||||
if (res.objects[i].name === pathPrefixChopped) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (
|
||||
(res.objects.length === 1 &&
|
||||
res.objects[0].name.endsWith("/")) ||
|
||||
!found
|
||||
) {
|
||||
// This is a folder, we set the original results list
|
||||
console.log("2");
|
||||
setRecords(recordsInElement);
|
||||
} else {
|
||||
console.log("3");
|
||||
// This is a file. We change URL & Open file details view.
|
||||
setObjectDetailsView(true);
|
||||
setSelectedObjectView(internalPaths);
|
||||
|
||||
// We split the selected object URL & remove the last item to fetch the files list for the parent folder
|
||||
const parentPath = `${decodeFileName(internalPaths)
|
||||
.split("/")
|
||||
.slice(0, -1)
|
||||
.join("/")}/`;
|
||||
|
||||
api
|
||||
.invoke(
|
||||
"GET",
|
||||
`${urlTake}${
|
||||
pathPrefix
|
||||
? `?prefix=${encodeFileName(parentPath)}`
|
||||
: ``
|
||||
}`
|
||||
)
|
||||
.then((res: BucketObjectItemsList) => {
|
||||
console.log("4");
|
||||
const records: BucketObjectItem[] = res.objects || [];
|
||||
|
||||
setRecords(records);
|
||||
})
|
||||
.catch(() => {
|
||||
console.log("5");
|
||||
});
|
||||
}
|
||||
|
||||
setLoadingObjectsList(false);
|
||||
}
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
console.log("6");
|
||||
setLoadingObjectsList(false);
|
||||
setErrorSnackMessage(err);
|
||||
});
|
||||
} else {
|
||||
//setFileModeEnabled(false);
|
||||
setLoading(false);
|
||||
console.log("7", recordsInElement);
|
||||
setRecords(recordsInElement);
|
||||
setLoadingObjectsList(false);
|
||||
}
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
setLoading(false);
|
||||
setLoadingObjectsList(false);
|
||||
setErrorSnackMessage(err);
|
||||
});
|
||||
} else {
|
||||
setLoadingRewind(false);
|
||||
setLoading(false);
|
||||
console.log("8");
|
||||
setLoadingObjectsList(false);
|
||||
}
|
||||
}
|
||||
}, [
|
||||
@@ -684,6 +686,11 @@ const ListObjects = ({
|
||||
bucketInfo,
|
||||
showDeleted,
|
||||
displayListObjects,
|
||||
bucketToRewind,
|
||||
resetRewind,
|
||||
setObjectDetailsView,
|
||||
setSelectedObjectView,
|
||||
setLoadingObjectsList,
|
||||
]);
|
||||
|
||||
// bucket info
|
||||
@@ -714,7 +721,7 @@ const ListObjects = ({
|
||||
if (refresh) {
|
||||
setSnackBarMessage(`Objects deleted successfully.`);
|
||||
setSelectedObjects([]);
|
||||
setLoading(true);
|
||||
setLoadingObjectsList(true);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -738,7 +745,7 @@ const ListObjects = ({
|
||||
e.target.value = "";
|
||||
};
|
||||
|
||||
const downloadObject = (object: BucketObject | RewindObject) => {
|
||||
const downloadObject = (object: BucketObjectItem) => {
|
||||
const identityDownload = encodeFileName(
|
||||
`${bucketName}-${object.name}-${new Date().getTime()}-${Math.random()}`
|
||||
);
|
||||
@@ -769,19 +776,15 @@ const ListObjects = ({
|
||||
|
||||
const openPath = (idElement: string) => {
|
||||
setSelectedObjects([]);
|
||||
if (idElement.endsWith("/")) {
|
||||
const newPath = `/buckets/${bucketName}/browse${
|
||||
idElement ? `/${encodeFileName(idElement)}` : ``
|
||||
}`;
|
||||
history.push(newPath);
|
||||
return;
|
||||
}
|
||||
|
||||
setDetailsOpen(true);
|
||||
const newPath = `/buckets/${bucketName}/browse${
|
||||
idElement ? `/${encodeFileName(idElement)}` : ``
|
||||
}`;
|
||||
history.push(newPath);
|
||||
|
||||
setObjectDetailsView(true);
|
||||
setLoadingVersions(true);
|
||||
setSelectedInternalPaths(
|
||||
`${idElement ? `${encodeFileName(idElement)}` : ``}`
|
||||
);
|
||||
setSelectedObjectView(`${idElement ? `${encodeFileName(idElement)}` : ``}`);
|
||||
};
|
||||
|
||||
const uploadObject = useCallback(
|
||||
@@ -894,7 +897,7 @@ const ListObjects = ({
|
||||
};
|
||||
xhr.onloadend = () => {
|
||||
if (files.length === 0) {
|
||||
setLoading(true);
|
||||
setLoadingObjectsList(true);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -925,7 +928,6 @@ const ListObjects = ({
|
||||
errorMessage: "There were some errors during file upload",
|
||||
detailedError: `Uploaded files ${successUploadedFiles}/${totalFiles}`,
|
||||
};
|
||||
console.log("upload results", results);
|
||||
setErrorSnackMessage(err);
|
||||
}
|
||||
});
|
||||
@@ -941,6 +943,7 @@ const ListObjects = ({
|
||||
setNewObject,
|
||||
setErrorSnackMessage,
|
||||
updateProgress,
|
||||
setLoadingObjectsList,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -971,9 +974,9 @@ const ListObjects = ({
|
||||
|
||||
const openPreview = () => {
|
||||
if (selectedObjects.length === 1) {
|
||||
let fileObject: BucketObject | undefined;
|
||||
let fileObject: BucketObjectItem | undefined;
|
||||
|
||||
const findFunction = (currValue: BucketObject | RewindObject) =>
|
||||
const findFunction = (currValue: BucketObjectItem) =>
|
||||
selectedObjects.includes(currValue.name);
|
||||
|
||||
fileObject = filteredRecords.find(findFunction);
|
||||
@@ -987,9 +990,9 @@ const ListObjects = ({
|
||||
|
||||
const openShare = () => {
|
||||
if (selectedObjects.length === 1) {
|
||||
let fileObject: BucketObject | undefined;
|
||||
let fileObject: BucketObjectItem | undefined;
|
||||
|
||||
const findFunction = (currValue: BucketObject | RewindObject) =>
|
||||
const findFunction = (currValue: BucketObjectItem) =>
|
||||
selectedObjects.includes(currValue.name);
|
||||
|
||||
fileObject = filteredRecords.find(findFunction);
|
||||
@@ -1006,7 +1009,7 @@ const ListObjects = ({
|
||||
setSelectedPreview(null);
|
||||
};
|
||||
|
||||
const filteredRecords = records.filter((b: BucketObject) => {
|
||||
const filteredRecords = records.filter((b: BucketObjectItem) => {
|
||||
if (searchObjects === "") {
|
||||
return true;
|
||||
} else {
|
||||
@@ -1019,7 +1022,7 @@ const ListObjects = ({
|
||||
}
|
||||
});
|
||||
|
||||
const rewindCloseModal = (refresh: boolean) => {
|
||||
const rewindCloseModal = () => {
|
||||
setRewindSelect(false);
|
||||
};
|
||||
|
||||
@@ -1043,7 +1046,7 @@ const ListObjects = ({
|
||||
elements = elements.filter((element) => element !== value);
|
||||
}
|
||||
setSelectedObjects(elements);
|
||||
setSelectedInternalPaths(null);
|
||||
setSelectedObjectView(null);
|
||||
|
||||
return elements;
|
||||
};
|
||||
@@ -1052,16 +1055,16 @@ const ListObjects = ({
|
||||
const newSortDirection = get(sortData, "sortDirection", "DESC");
|
||||
setCurrentSortField(sortData.sortBy);
|
||||
setSortDirection(newSortDirection);
|
||||
setLoading(true);
|
||||
setLoadingObjectsList(true);
|
||||
};
|
||||
|
||||
const pageTitle = decodeFileName(internalPaths);
|
||||
const currentPath = pageTitle.split("/").filter((i: string) => i !== "");
|
||||
|
||||
const plSelect = rewindEnabled ? rewind : filteredRecords;
|
||||
const plSelect = filteredRecords;
|
||||
const sortASC = plSelect.sort(sortListObjects(currentSortField));
|
||||
|
||||
let payload: BucketObject[] | RewindObject[] = [];
|
||||
let payload: BucketObjectItem[] = [];
|
||||
|
||||
if (sortDirection === "ASC") {
|
||||
payload = sortASC;
|
||||
@@ -1070,7 +1073,7 @@ const ListObjects = ({
|
||||
}
|
||||
|
||||
const selectAllItems = () => {
|
||||
setSelectedInternalPaths(null);
|
||||
setSelectedObjectView(null);
|
||||
|
||||
if (selectedObjects.length === payload.length) {
|
||||
setSelectedObjects([]);
|
||||
@@ -1083,16 +1086,12 @@ const ListObjects = ({
|
||||
|
||||
const downloadSelected = () => {
|
||||
if (selectedObjects.length !== 0) {
|
||||
let itemsToDownload: BucketObject[] | RewindObject[] = [];
|
||||
let itemsToDownload: BucketObjectItem[] = [];
|
||||
|
||||
const filterFunction = (currValue: BucketObject | RewindObject) =>
|
||||
const filterFunction = (currValue: BucketObjectItem) =>
|
||||
selectedObjects.includes(currValue.name);
|
||||
|
||||
if (rewindEnabled) {
|
||||
itemsToDownload = rewind.filter(filterFunction);
|
||||
} else {
|
||||
itemsToDownload = filteredRecords.filter(filterFunction);
|
||||
}
|
||||
itemsToDownload = filteredRecords.filter(filterFunction);
|
||||
|
||||
itemsToDownload.forEach((filteredItem) => {
|
||||
downloadObject(filteredItem);
|
||||
@@ -1105,13 +1104,13 @@ const ListObjects = ({
|
||||
}
|
||||
|
||||
const onClosePanel = (forceRefresh: boolean) => {
|
||||
setDetailsOpen(false);
|
||||
setSelectedInternalPaths(null);
|
||||
setObjectDetailsView(false);
|
||||
setSelectedObjectView(null);
|
||||
setSelectedObjects([]);
|
||||
setVersionsModeEnabled(false);
|
||||
|
||||
if (forceRefresh) {
|
||||
setLoading(true);
|
||||
setLoadingObjectsList(true);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1287,7 +1286,7 @@ const ListObjects = ({
|
||||
if (versionsMode) {
|
||||
setLoadingVersions(true);
|
||||
} else {
|
||||
setLoading(true);
|
||||
setLoadingObjectsList(true);
|
||||
}
|
||||
}}
|
||||
disabled={
|
||||
@@ -1385,7 +1384,7 @@ const ListObjects = ({
|
||||
columns={
|
||||
rewindEnabled ? rewindModeColumns : listModeColumns
|
||||
}
|
||||
isLoading={rewindEnabled ? loadingRewind : loading}
|
||||
isLoading={loading}
|
||||
loadingMessage={loadingMessage}
|
||||
entityName="Objects"
|
||||
idField="name"
|
||||
@@ -1461,6 +1460,9 @@ const mapStateToProps = ({ objectBrowser, buckets }: AppState) => ({
|
||||
bucketInfo: buckets.bucketDetails.bucketInfo,
|
||||
searchObjects: objectBrowser.searchObjects,
|
||||
showDeleted: objectBrowser.showDeleted,
|
||||
detailsOpen: objectBrowser.objectDetailsOpen,
|
||||
selectedInternalPaths: objectBrowser.selectedInternalPaths,
|
||||
loading: objectBrowser.loadingObjects,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
@@ -1477,6 +1479,10 @@ const mapDispatchToProps = {
|
||||
setVersionsModeEnabled,
|
||||
setShowDeletedObjects,
|
||||
setLoadingVersions,
|
||||
setObjectDetailsView,
|
||||
setSelectedObjectView,
|
||||
setLoadingObjectInfo,
|
||||
setLoadingObjectsList,
|
||||
};
|
||||
|
||||
const connector = connect(mapStateToProps, mapDispatchToProps);
|
||||
|
||||
@@ -16,20 +16,20 @@
|
||||
|
||||
import React from "react";
|
||||
import * as reactMoment from "react-moment";
|
||||
import { BucketObject } from "./types";
|
||||
import { BucketObjectItem } from "./types";
|
||||
import { niceBytes } from "../../../../../../common/utils";
|
||||
import { displayFileIconName } from "./utils";
|
||||
|
||||
// Functions
|
||||
|
||||
export const displayParsedDate = (object: BucketObject) => {
|
||||
export const displayParsedDate = (object: BucketObjectItem) => {
|
||||
if (object.name.endsWith("/")) {
|
||||
return "";
|
||||
}
|
||||
return <reactMoment.default>{object.last_modified}</reactMoment.default>;
|
||||
};
|
||||
|
||||
export const displayNiceBytes = (object: BucketObject) => {
|
||||
export const displayNiceBytes = (object: BucketObjectItem) => {
|
||||
if (object.name.endsWith("/") || !object.size) {
|
||||
return "-";
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ const ObjectDetailPanel = ({
|
||||
}, [internalPaths, bucketName, setLoadingObjectInfo]);
|
||||
|
||||
useEffect(() => {
|
||||
if (distributedSetup && allInfoElements.length >= 1) {
|
||||
if (distributedSetup && allInfoElements && allInfoElements.length >= 1) {
|
||||
let infoElement =
|
||||
allInfoElements.find((el: IFileInfo) => el.is_latest) || emptyFile;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Button, LinearProgress } from "@mui/material";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import { ObjectBrowserReducer } from "../../../../ObjectBrowser/reducers";
|
||||
import { ObjectBrowserReducer } from "../../../../ObjectBrowser/types";
|
||||
import { modalBasic } from "../../../../Common/FormComponents/common/styleLibrary";
|
||||
import {
|
||||
resetRewind,
|
||||
@@ -32,7 +32,7 @@ import DateTimePickerWrapper from "../../../../Common/FormComponents/DateTimePic
|
||||
import FormSwitchWrapper from "../../../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
|
||||
interface IRewindEnable {
|
||||
closeModalAndRefresh: (reload: boolean) => void;
|
||||
closeModalAndRefresh: () => void;
|
||||
classes: any;
|
||||
open: boolean;
|
||||
bucketName: string;
|
||||
@@ -80,14 +80,14 @@ const RewindEnable = ({
|
||||
setRewindEnabling(true);
|
||||
setRewindEnable(true, bucketName, dateSelected);
|
||||
}
|
||||
closeModalAndRefresh(true);
|
||||
closeModalAndRefresh();
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
modalOpen={open}
|
||||
onClose={() => {
|
||||
closeModalAndRefresh(false);
|
||||
closeModalAndRefresh();
|
||||
}}
|
||||
title={`Rewind - ${bucketName}`}
|
||||
>
|
||||
|
||||
@@ -14,29 +14,17 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export interface BucketObject {
|
||||
export interface BucketObjectItem {
|
||||
name: string;
|
||||
size: number;
|
||||
etag?: string;
|
||||
last_modified: Date;
|
||||
content_type: string;
|
||||
content_type?: string;
|
||||
version_id: string;
|
||||
delete_flag?: boolean;
|
||||
}
|
||||
|
||||
export interface BucketObjectsList {
|
||||
objects: BucketObject[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface RewindObject {
|
||||
last_modified: string;
|
||||
delete_flag: boolean;
|
||||
name: string;
|
||||
version_id: string;
|
||||
size: number;
|
||||
}
|
||||
|
||||
export interface RewindObjectList {
|
||||
objects: RewindObject[];
|
||||
export interface BucketObjectItemsList {
|
||||
objects: BucketObjectItem[];
|
||||
total?: number;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import React, { Fragment, useState } from "react";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Grid, LinearProgress } from "@mui/material";
|
||||
import { BucketObject } from "../ListObjects/types";
|
||||
import { BucketObjectItem } from "../ListObjects/types";
|
||||
import { extensionPreview } from "../utils";
|
||||
import { encodeFileName } from "../../../../../../common/utils";
|
||||
import clsx from "clsx";
|
||||
@@ -59,7 +59,7 @@ const styles = () =>
|
||||
|
||||
interface IPreviewFileProps {
|
||||
bucketName: string;
|
||||
object: BucketObject | null;
|
||||
object: BucketObjectItem | null;
|
||||
isFullscreen?: boolean;
|
||||
classes: any;
|
||||
}
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
import React, { Fragment } from "react";
|
||||
import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper";
|
||||
import PreviewFileContent from "./PreviewFileContent";
|
||||
import { BucketObject } from "../ListObjects/types";
|
||||
import { BucketObjectItem } from "../ListObjects/types";
|
||||
import { ObjectPreviewIcon } from "../../../../../../icons";
|
||||
|
||||
interface IPreviewFileProps {
|
||||
open: boolean;
|
||||
bucketName: string;
|
||||
object: BucketObject | null;
|
||||
object: BucketObjectItem | null;
|
||||
onClosePreview: () => void;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { BucketObject, RewindObject } from "./ListObjects/types";
|
||||
import { BucketObjectItem } from "./ListObjects/types";
|
||||
|
||||
export const download = (
|
||||
bucketName: string,
|
||||
@@ -136,14 +136,14 @@ export const extensionPreview = (
|
||||
export const sortListObjects = (fieldSort: string) => {
|
||||
switch (fieldSort) {
|
||||
case "name":
|
||||
return (a: BucketObject | RewindObject, b: BucketObject | RewindObject) =>
|
||||
return (a: BucketObjectItem, b: BucketObjectItem) =>
|
||||
a.name.localeCompare(b.name);
|
||||
case "last_modified":
|
||||
return (a: BucketObject | RewindObject, b: BucketObject | RewindObject) =>
|
||||
return (a: BucketObjectItem, b: BucketObjectItem) =>
|
||||
new Date(a.last_modified).getTime() -
|
||||
new Date(b.last_modified).getTime();
|
||||
case "size":
|
||||
return (a: BucketObject | RewindObject, b: BucketObject | RewindObject) =>
|
||||
return (a: BucketObjectItem, b: BucketObjectItem) =>
|
||||
(a.size || -1) - (b.size || -1);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -53,6 +53,7 @@ const styles = (theme: Theme) =>
|
||||
margin: "15px 0",
|
||||
marginBottom: 0,
|
||||
flexBasis: "initial",
|
||||
flexWrap: "nowrap",
|
||||
},
|
||||
noTopMargin: {
|
||||
marginTop: 0,
|
||||
|
||||
@@ -19,7 +19,7 @@ import { Theme } from "@mui/material/styles";
|
||||
import { Tooltip } from "@mui/material";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { IFileItem } from "../../ObjectBrowser/reducers";
|
||||
import { IFileItem } from "../../ObjectBrowser/types";
|
||||
import ProgressBarWrapper from "../ProgressBarWrapper/ProgressBarWrapper";
|
||||
import { DownloadStatIcon, UploadStatIcon } from "../../../../icons";
|
||||
import clsx from "clsx";
|
||||
|
||||
@@ -21,7 +21,7 @@ import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Tooltip, IconButton } from "@mui/material";
|
||||
import { AppState } from "../../../../store";
|
||||
import { IFileItem } from "../../ObjectBrowser/reducers";
|
||||
import { IFileItem } from "../../ObjectBrowser/types";
|
||||
import { deleteFromList, cleanList } from "../../ObjectBrowser/actions";
|
||||
import { TrashIcon } from "../../../../icons";
|
||||
import ObjectHandled from "./ObjectHandled";
|
||||
|
||||
@@ -25,7 +25,7 @@ import IconButton from "@mui/material/IconButton";
|
||||
import { AppState } from "../../../../store";
|
||||
import OperatorLogo from "../../../../icons/OperatorLogo";
|
||||
import ConsoleLogo from "../../../../icons/ConsoleLogo";
|
||||
import { IFileItem } from "../../ObjectBrowser/reducers";
|
||||
import { IFileItem } from "../../ObjectBrowser/types";
|
||||
import { toggleList } from "../../ObjectBrowser/actions";
|
||||
import { ObjectManagerIcon } from "../../../../icons";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
// Copyright (c) 2022 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
@@ -15,24 +15,24 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment, useState } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import get from "lodash/get";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import { connect } from "react-redux";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import { ObjectBrowserState } from "./reducers";
|
||||
import { objectBrowserCommon } from "../Common/FormComponents/common/styleLibrary";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Button, IconButton, Tooltip } from "@mui/material";
|
||||
import { ObjectBrowserState } from "./types";
|
||||
import { objectBrowserCommon } from "../Common/FormComponents/common/styleLibrary";
|
||||
import { encodeFileName } from "../../../common/utils";
|
||||
import { BackCaretIcon, NewPathIcon } from "../../../icons";
|
||||
import { Button, IconButton, Tooltip } from "@mui/material";
|
||||
import history from "../../../history";
|
||||
import { hasPermission } from "../../../common/SecureComponent";
|
||||
import { IAM_SCOPES } from "../../../common/SecureComponent/permissions";
|
||||
import withSuspense from "../Common/Components/withSuspense";
|
||||
import { BucketObject } from "../Buckets/ListBuckets/Objects/ListObjects/types";
|
||||
import { BucketObjectItem } from "../Buckets/ListBuckets/Objects/ListObjects/types";
|
||||
import { setVersionsModeEnabled } from "./actions";
|
||||
import history from "../../../history";
|
||||
import withSuspense from "../Common/Components/withSuspense";
|
||||
|
||||
const CreateFolderModal = withSuspense(
|
||||
React.lazy(
|
||||
@@ -52,7 +52,7 @@ interface IObjectBrowser {
|
||||
versionsMode: boolean;
|
||||
versionedFile: string;
|
||||
hidePathButton?: boolean;
|
||||
existingFiles: BucketObject[];
|
||||
existingFiles: BucketObjectItem[];
|
||||
additionalOptions?: React.ReactNode;
|
||||
setVersionsModeEnabled: typeof setVersionsModeEnabled;
|
||||
}
|
||||
@@ -86,7 +86,7 @@ const BrowserBreadcrumbs = ({
|
||||
const lastBreadcrumbsIndex = splitPaths.length - 1;
|
||||
|
||||
let breadcrumbsMap = splitPaths.map((objectItem: string, index: number) => {
|
||||
const subSplit = splitPaths.slice(0, index + 1).join("/");
|
||||
const subSplit = `${splitPaths.slice(0, index + 1).join("/")}/`;
|
||||
const route = `/buckets/${bucketName}/browse/${
|
||||
subSplit ? `${encodeFileName(subSplit)}` : ``
|
||||
}`;
|
||||
@@ -98,14 +98,18 @@ const BrowserBreadcrumbs = ({
|
||||
return (
|
||||
<Fragment key={`breadcrumbs-${index.toString()}`}>
|
||||
<span> / </span>
|
||||
<Link
|
||||
to={route}
|
||||
onClick={() => {
|
||||
setVersionsModeEnabled(false);
|
||||
}}
|
||||
>
|
||||
{objectItem}
|
||||
</Link>
|
||||
{index === lastBreadcrumbsIndex ? (
|
||||
<span style={{cursor: "default"}}>{objectItem}</span>
|
||||
) : (
|
||||
<Link
|
||||
to={route}
|
||||
onClick={() => {
|
||||
setVersionsModeEnabled(false);
|
||||
}}
|
||||
>
|
||||
{objectItem}
|
||||
</Link>
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
// Copyright (c) 2022 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
@@ -14,137 +14,28 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { IFileItem } from "./reducers";
|
||||
|
||||
export const REWIND_SET_ENABLE = "REWIND/SET_ENABLE";
|
||||
export const REWIND_RESET_REWIND = "REWIND/RESET_REWIND";
|
||||
|
||||
export const OBJECT_MANAGER_NEW_OBJECT = "OBJECT_MANAGER/NEW_OBJECT";
|
||||
export const OBJECT_MANAGER_UPDATE_PROGRESS_OBJECT =
|
||||
"OBJECT_MANAGER/UPDATE_PROGRESS_OBJECT";
|
||||
export const OBJECT_MANAGER_COMPLETE_OBJECT = "OBJECT_MANAGER/COMPLETE_OBJECT";
|
||||
export const OBJECT_MANAGER_DELETE_FROM_OBJECT_LIST =
|
||||
"OBJECT_MANAGER/DELETE_FROM_OBJECT_LIST";
|
||||
export const OBJECT_MANAGER_CLEAN_LIST = "OBJECT_MANAGER/CLEAN_LIST";
|
||||
export const OBJECT_MANAGER_TOGGLE_LIST = "OBJECT_MANAGER/TOGGLE_LIST";
|
||||
export const OBJECT_MANAGER_OPEN_LIST = "OBJECT_MANAGER/OPEN_LIST";
|
||||
export const OBJECT_MANAGER_CLOSE_LIST = "OBJECT_MANAGER/CLOSE_LIST";
|
||||
export const OBJECT_MANAGER_SET_SEARCH_OBJECT =
|
||||
"OBJECT_MANAGER/SET_SEARCH_OBJECT";
|
||||
|
||||
export const BUCKET_BROWSER_VERSIONS_MODE_ENABLED =
|
||||
"BUCKET_BROWSER/VERSIONS_MODE_ENABLED";
|
||||
export const BUCKET_BROWSER_VERSIONS_SET_SEARCH =
|
||||
"BUCKET_BROWSER/VERSIONS_SET_SEARCH";
|
||||
export const BUCKET_BROWSER_SET_SELECTED_VERSION =
|
||||
"BUCKET_BROWSER/SET_SELECTED_VERSION";
|
||||
export const BUCKET_BROWSER_SHOW_DELETED = "BUCKET_BROWSER/SHOW_DELETED";
|
||||
export const BUCKET_BROWSER_LOAD_VERSIONS = "BUCKET_BROWSER/LOAD_VERSIONS";
|
||||
export const BUCKET_BROWSER_LOAD_OBJECT_DETAILS =
|
||||
"BUCKET_BROWSER/LOAD_OBJECT_DETAILS";
|
||||
|
||||
interface RewindSetEnabled {
|
||||
type: typeof REWIND_SET_ENABLE;
|
||||
bucket: string;
|
||||
state: boolean;
|
||||
dateRewind: any;
|
||||
}
|
||||
|
||||
interface RewindReset {
|
||||
type: typeof REWIND_RESET_REWIND;
|
||||
}
|
||||
|
||||
interface VersionsModeEnabled {
|
||||
type: typeof BUCKET_BROWSER_VERSIONS_MODE_ENABLED;
|
||||
status: boolean;
|
||||
objectName: string;
|
||||
}
|
||||
|
||||
interface OMNewObject {
|
||||
type: typeof OBJECT_MANAGER_NEW_OBJECT;
|
||||
newObject: IFileItem;
|
||||
}
|
||||
|
||||
interface OMUpdateProgress {
|
||||
type: typeof OBJECT_MANAGER_UPDATE_PROGRESS_OBJECT;
|
||||
instanceID: string;
|
||||
progress: number;
|
||||
}
|
||||
|
||||
interface OMCompleteObject {
|
||||
type: typeof OBJECT_MANAGER_COMPLETE_OBJECT;
|
||||
instanceID: string;
|
||||
}
|
||||
|
||||
interface OMDeleteFromList {
|
||||
type: typeof OBJECT_MANAGER_DELETE_FROM_OBJECT_LIST;
|
||||
instanceID: string;
|
||||
}
|
||||
|
||||
interface OMCleanList {
|
||||
type: typeof OBJECT_MANAGER_CLEAN_LIST;
|
||||
}
|
||||
|
||||
interface OMToggleList {
|
||||
type: typeof OBJECT_MANAGER_TOGGLE_LIST;
|
||||
}
|
||||
|
||||
interface OMOpenList {
|
||||
type: typeof OBJECT_MANAGER_OPEN_LIST;
|
||||
}
|
||||
|
||||
interface OMCloseList {
|
||||
type: typeof OBJECT_MANAGER_CLOSE_LIST;
|
||||
}
|
||||
|
||||
interface SetSearchObjects {
|
||||
type: typeof OBJECT_MANAGER_SET_SEARCH_OBJECT;
|
||||
searchString: string;
|
||||
}
|
||||
|
||||
interface SetSearchVersions {
|
||||
type: typeof BUCKET_BROWSER_VERSIONS_SET_SEARCH;
|
||||
searchString: string;
|
||||
}
|
||||
|
||||
interface SetSelectedversion {
|
||||
type: typeof BUCKET_BROWSER_SET_SELECTED_VERSION;
|
||||
selectedVersion: string;
|
||||
}
|
||||
|
||||
interface SetShowDeletedObjects {
|
||||
type: typeof BUCKET_BROWSER_SHOW_DELETED;
|
||||
status: boolean;
|
||||
}
|
||||
|
||||
interface SetLoadingVersions {
|
||||
type: typeof BUCKET_BROWSER_LOAD_VERSIONS;
|
||||
status: boolean;
|
||||
}
|
||||
|
||||
interface SetLoadingObjectInfo {
|
||||
type: typeof BUCKET_BROWSER_LOAD_OBJECT_DETAILS;
|
||||
status: boolean;
|
||||
}
|
||||
|
||||
export type ObjectBrowserActionTypes =
|
||||
| RewindSetEnabled
|
||||
| RewindReset
|
||||
| VersionsModeEnabled
|
||||
| OMNewObject
|
||||
| OMUpdateProgress
|
||||
| OMCompleteObject
|
||||
| OMDeleteFromList
|
||||
| OMCleanList
|
||||
| OMToggleList
|
||||
| OMOpenList
|
||||
| OMCloseList
|
||||
| SetSearchObjects
|
||||
| SetSearchVersions
|
||||
| SetSelectedversion
|
||||
| SetShowDeletedObjects
|
||||
| SetLoadingVersions
|
||||
| SetLoadingObjectInfo;
|
||||
import {
|
||||
BUCKET_BROWSER_LOAD_OBJECT_DETAILS,
|
||||
BUCKET_BROWSER_LOAD_VERSIONS,
|
||||
BUCKET_BROWSER_OBJECT_DETAILS_STATE,
|
||||
BUCKET_BROWSER_SET_SELECTED_VERSION,
|
||||
BUCKET_BROWSER_SHOW_DELETED,
|
||||
BUCKET_BROWSER_VERSIONS_MODE_ENABLED,
|
||||
BUCKET_BROWSER_VERSIONS_SET_SEARCH,
|
||||
OBJECT_MANAGER_CLEAN_LIST,
|
||||
OBJECT_MANAGER_CLOSE_LIST,
|
||||
OBJECT_MANAGER_COMPLETE_OBJECT,
|
||||
OBJECT_MANAGER_DELETE_FROM_OBJECT_LIST,
|
||||
OBJECT_MANAGER_NEW_OBJECT,
|
||||
OBJECT_MANAGER_OPEN_LIST,
|
||||
OBJECT_MANAGER_SET_SEARCH_OBJECT,
|
||||
OBJECT_MANAGER_TOGGLE_LIST,
|
||||
OBJECT_MANAGER_UPDATE_PROGRESS_OBJECT,
|
||||
REWIND_RESET_REWIND,
|
||||
REWIND_SET_ENABLE,
|
||||
IFileItem,
|
||||
BUCKET_BROWSER_SET_SELECTED_OBJECT, OBJECT_MANAGER_SET_LOADING,
|
||||
} from "./types";
|
||||
|
||||
export const setRewindEnable = (
|
||||
state: boolean,
|
||||
@@ -270,3 +161,24 @@ export const setLoadingObjectInfo = (status: boolean) => {
|
||||
status,
|
||||
};
|
||||
};
|
||||
|
||||
export const setObjectDetailsView = (status: boolean) => {
|
||||
return {
|
||||
type: BUCKET_BROWSER_OBJECT_DETAILS_STATE,
|
||||
status,
|
||||
};
|
||||
};
|
||||
|
||||
export const setSelectedObjectView = (object: string | null) => {
|
||||
return {
|
||||
type: BUCKET_BROWSER_SET_SELECTED_OBJECT,
|
||||
object,
|
||||
};
|
||||
};
|
||||
|
||||
export const setLoadingObjectsList = (status: boolean) => {
|
||||
return {
|
||||
type: OBJECT_MANAGER_SET_LOADING,
|
||||
status,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
// Copyright (c) 2022 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
@@ -13,11 +13,11 @@
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import {
|
||||
REWIND_SET_ENABLE,
|
||||
REWIND_RESET_REWIND,
|
||||
BUCKET_BROWSER_VERSIONS_MODE_ENABLED,
|
||||
ObjectBrowserActionTypes,
|
||||
OBJECT_MANAGER_NEW_OBJECT,
|
||||
OBJECT_MANAGER_UPDATE_PROGRESS_OBJECT,
|
||||
OBJECT_MANAGER_COMPLETE_OBJECT,
|
||||
@@ -32,51 +32,12 @@ import {
|
||||
BUCKET_BROWSER_SHOW_DELETED,
|
||||
BUCKET_BROWSER_LOAD_VERSIONS,
|
||||
BUCKET_BROWSER_LOAD_OBJECT_DETAILS,
|
||||
} from "./actions";
|
||||
|
||||
export interface Route {
|
||||
route: string;
|
||||
label: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface RewindItem {
|
||||
rewindEnabled: boolean;
|
||||
bucketToRewind: string;
|
||||
dateToRewind: any;
|
||||
}
|
||||
|
||||
export interface ObjectBrowserState {
|
||||
rewind: RewindItem;
|
||||
objectManager: ObjectManager;
|
||||
searchObjects: string;
|
||||
loadingVersions: boolean;
|
||||
loadingObjectInfo: boolean;
|
||||
versionsMode: boolean;
|
||||
versionedFile: string;
|
||||
searchVersions: string;
|
||||
selectedVersion: string;
|
||||
showDeleted: boolean;
|
||||
}
|
||||
|
||||
export interface ObjectBrowserReducer {
|
||||
objectBrowser: ObjectBrowserState;
|
||||
}
|
||||
|
||||
export interface ObjectManager {
|
||||
objectsToManage: IFileItem[];
|
||||
managerOpen: boolean;
|
||||
}
|
||||
|
||||
export interface IFileItem {
|
||||
type: "download" | "upload";
|
||||
instanceID: string;
|
||||
bucketName: string;
|
||||
prefix: string;
|
||||
percentage: number;
|
||||
done: boolean;
|
||||
waitingForFile: boolean;
|
||||
}
|
||||
BUCKET_BROWSER_OBJECT_DETAILS_STATE,
|
||||
ObjectBrowserState,
|
||||
ObjectBrowserActionTypes,
|
||||
BUCKET_BROWSER_SET_SELECTED_OBJECT,
|
||||
OBJECT_MANAGER_SET_LOADING,
|
||||
} from "./types";
|
||||
|
||||
const defaultRewind = {
|
||||
rewindEnabled: false,
|
||||
@@ -86,6 +47,8 @@ const defaultRewind = {
|
||||
|
||||
const initialState: ObjectBrowserState = {
|
||||
versionsMode: false,
|
||||
loadingObjects: true,
|
||||
objectDetailsOpen: false,
|
||||
loadingVersions: true,
|
||||
loadingObjectInfo: true,
|
||||
rewind: {
|
||||
@@ -100,6 +63,7 @@ const initialState: ObjectBrowserState = {
|
||||
searchVersions: "",
|
||||
selectedVersion: "",
|
||||
showDeleted: false,
|
||||
selectedInternalPaths: null,
|
||||
};
|
||||
|
||||
export function objectBrowserReducer(
|
||||
@@ -244,6 +208,11 @@ export function objectBrowserReducer(
|
||||
...state,
|
||||
searchObjects: action.searchString,
|
||||
};
|
||||
case OBJECT_MANAGER_SET_LOADING:
|
||||
return {
|
||||
...state,
|
||||
loadingObjects: action.status,
|
||||
};
|
||||
case BUCKET_BROWSER_VERSIONS_SET_SEARCH:
|
||||
return {
|
||||
...state,
|
||||
@@ -269,6 +238,16 @@ export function objectBrowserReducer(
|
||||
...state,
|
||||
loadingObjectInfo: action.status,
|
||||
};
|
||||
case BUCKET_BROWSER_OBJECT_DETAILS_STATE:
|
||||
return {
|
||||
...state,
|
||||
objectDetailsOpen: action.status,
|
||||
};
|
||||
case BUCKET_BROWSER_SET_SELECTED_OBJECT:
|
||||
return {
|
||||
...state,
|
||||
selectedInternalPaths: action.object,
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
215
portal-ui/src/screens/Console/ObjectBrowser/types.ts
Normal file
215
portal-ui/src/screens/Console/ObjectBrowser/types.ts
Normal file
@@ -0,0 +1,215 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export const REWIND_SET_ENABLE = "REWIND/SET_ENABLE";
|
||||
export const REWIND_RESET_REWIND = "REWIND/RESET_REWIND";
|
||||
|
||||
export const OBJECT_MANAGER_SET_LOADING = "OBJECT_MANAGER/SET_LOADING";
|
||||
export const OBJECT_MANAGER_NEW_OBJECT = "OBJECT_MANAGER/NEW_OBJECT";
|
||||
export const OBJECT_MANAGER_UPDATE_PROGRESS_OBJECT =
|
||||
"OBJECT_MANAGER/UPDATE_PROGRESS_OBJECT";
|
||||
export const OBJECT_MANAGER_COMPLETE_OBJECT = "OBJECT_MANAGER/COMPLETE_OBJECT";
|
||||
export const OBJECT_MANAGER_DELETE_FROM_OBJECT_LIST =
|
||||
"OBJECT_MANAGER/DELETE_FROM_OBJECT_LIST";
|
||||
export const OBJECT_MANAGER_CLEAN_LIST = "OBJECT_MANAGER/CLEAN_LIST";
|
||||
export const OBJECT_MANAGER_TOGGLE_LIST = "OBJECT_MANAGER/TOGGLE_LIST";
|
||||
export const OBJECT_MANAGER_OPEN_LIST = "OBJECT_MANAGER/OPEN_LIST";
|
||||
export const OBJECT_MANAGER_CLOSE_LIST = "OBJECT_MANAGER/CLOSE_LIST";
|
||||
export const OBJECT_MANAGER_SET_SEARCH_OBJECT =
|
||||
"OBJECT_MANAGER/SET_SEARCH_OBJECT";
|
||||
|
||||
export const BUCKET_BROWSER_VERSIONS_MODE_ENABLED =
|
||||
"BUCKET_BROWSER/VERSIONS_MODE_ENABLED";
|
||||
export const BUCKET_BROWSER_VERSIONS_SET_SEARCH =
|
||||
"BUCKET_BROWSER/VERSIONS_SET_SEARCH";
|
||||
export const BUCKET_BROWSER_SET_SELECTED_VERSION =
|
||||
"BUCKET_BROWSER/SET_SELECTED_VERSION";
|
||||
export const BUCKET_BROWSER_SHOW_DELETED = "BUCKET_BROWSER/SHOW_DELETED";
|
||||
export const BUCKET_BROWSER_LOAD_VERSIONS = "BUCKET_BROWSER/LOAD_VERSIONS";
|
||||
export const BUCKET_BROWSER_LOAD_OBJECT_DETAILS =
|
||||
"BUCKET_BROWSER/LOAD_OBJECT_DETAILS";
|
||||
export const BUCKET_BROWSER_OBJECT_DETAILS_STATE =
|
||||
"BUCKET_BROWSER/OBJECT_DETAILS_STATE";
|
||||
export const BUCKET_BROWSER_SET_SELECTED_OBJECT =
|
||||
"BUCKET_BROWSER/SET_SELECTED_OBJECT";
|
||||
|
||||
export interface Route {
|
||||
route: string;
|
||||
label: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface RewindItem {
|
||||
rewindEnabled: boolean;
|
||||
bucketToRewind: string;
|
||||
dateToRewind: any;
|
||||
}
|
||||
|
||||
export interface ObjectBrowserState {
|
||||
rewind: RewindItem;
|
||||
objectManager: ObjectManager;
|
||||
searchObjects: string;
|
||||
loadingVersions: boolean;
|
||||
loadingObjects: boolean;
|
||||
loadingObjectInfo: boolean;
|
||||
versionsMode: boolean;
|
||||
versionedFile: string;
|
||||
searchVersions: string;
|
||||
selectedVersion: string;
|
||||
showDeleted: boolean;
|
||||
objectDetailsOpen: boolean;
|
||||
selectedInternalPaths: string | null;
|
||||
}
|
||||
|
||||
export interface ObjectBrowserReducer {
|
||||
objectBrowser: ObjectBrowserState;
|
||||
}
|
||||
|
||||
export interface ObjectManager {
|
||||
objectsToManage: IFileItem[];
|
||||
managerOpen: boolean;
|
||||
}
|
||||
|
||||
export interface IFileItem {
|
||||
type: "download" | "upload";
|
||||
instanceID: string;
|
||||
bucketName: string;
|
||||
prefix: string;
|
||||
percentage: number;
|
||||
done: boolean;
|
||||
waitingForFile: boolean;
|
||||
}
|
||||
|
||||
interface RewindSetEnabled {
|
||||
type: typeof REWIND_SET_ENABLE;
|
||||
bucket: string;
|
||||
state: boolean;
|
||||
dateRewind: any;
|
||||
}
|
||||
|
||||
interface RewindReset {
|
||||
type: typeof REWIND_RESET_REWIND;
|
||||
}
|
||||
|
||||
interface VersionsModeEnabled {
|
||||
type: typeof BUCKET_BROWSER_VERSIONS_MODE_ENABLED;
|
||||
status: boolean;
|
||||
objectName: string;
|
||||
}
|
||||
|
||||
interface OMNewObject {
|
||||
type: typeof OBJECT_MANAGER_NEW_OBJECT;
|
||||
newObject: IFileItem;
|
||||
}
|
||||
|
||||
interface OMUpdateProgress {
|
||||
type: typeof OBJECT_MANAGER_UPDATE_PROGRESS_OBJECT;
|
||||
instanceID: string;
|
||||
progress: number;
|
||||
}
|
||||
|
||||
interface OMCompleteObject {
|
||||
type: typeof OBJECT_MANAGER_COMPLETE_OBJECT;
|
||||
instanceID: string;
|
||||
}
|
||||
|
||||
interface OMDeleteFromList {
|
||||
type: typeof OBJECT_MANAGER_DELETE_FROM_OBJECT_LIST;
|
||||
instanceID: string;
|
||||
}
|
||||
|
||||
interface OMCleanList {
|
||||
type: typeof OBJECT_MANAGER_CLEAN_LIST;
|
||||
}
|
||||
|
||||
interface OMToggleList {
|
||||
type: typeof OBJECT_MANAGER_TOGGLE_LIST;
|
||||
}
|
||||
|
||||
interface OMOpenList {
|
||||
type: typeof OBJECT_MANAGER_OPEN_LIST;
|
||||
}
|
||||
|
||||
interface OMCloseList {
|
||||
type: typeof OBJECT_MANAGER_CLOSE_LIST;
|
||||
}
|
||||
|
||||
interface SetSearchObjects {
|
||||
type: typeof OBJECT_MANAGER_SET_SEARCH_OBJECT;
|
||||
searchString: string;
|
||||
}
|
||||
|
||||
interface SetSearchVersions {
|
||||
type: typeof BUCKET_BROWSER_VERSIONS_SET_SEARCH;
|
||||
searchString: string;
|
||||
}
|
||||
|
||||
interface SetSelectedversion {
|
||||
type: typeof BUCKET_BROWSER_SET_SELECTED_VERSION;
|
||||
selectedVersion: string;
|
||||
}
|
||||
|
||||
interface SetShowDeletedObjects {
|
||||
type: typeof BUCKET_BROWSER_SHOW_DELETED;
|
||||
status: boolean;
|
||||
}
|
||||
|
||||
interface SetLoadingVersions {
|
||||
type: typeof BUCKET_BROWSER_LOAD_VERSIONS;
|
||||
status: boolean;
|
||||
}
|
||||
|
||||
interface SetLoadingObjectInfo {
|
||||
type: typeof BUCKET_BROWSER_LOAD_OBJECT_DETAILS;
|
||||
status: boolean;
|
||||
}
|
||||
|
||||
interface SetObjectDetailsState {
|
||||
type: typeof BUCKET_BROWSER_OBJECT_DETAILS_STATE;
|
||||
status: boolean;
|
||||
}
|
||||
|
||||
interface SetSelectedObject {
|
||||
type: typeof BUCKET_BROWSER_SET_SELECTED_OBJECT;
|
||||
object: string | null;
|
||||
}
|
||||
|
||||
interface SetObjectManagerLoading {
|
||||
type: typeof OBJECT_MANAGER_SET_LOADING;
|
||||
status: boolean;
|
||||
}
|
||||
|
||||
export type ObjectBrowserActionTypes =
|
||||
| RewindSetEnabled
|
||||
| RewindReset
|
||||
| VersionsModeEnabled
|
||||
| OMNewObject
|
||||
| OMUpdateProgress
|
||||
| OMCompleteObject
|
||||
| OMDeleteFromList
|
||||
| OMCleanList
|
||||
| OMToggleList
|
||||
| OMOpenList
|
||||
| OMCloseList
|
||||
| SetSearchObjects
|
||||
| SetSearchVersions
|
||||
| SetSelectedversion
|
||||
| SetShowDeletedObjects
|
||||
| SetLoadingVersions
|
||||
| SetLoadingObjectInfo
|
||||
| SetObjectDetailsState
|
||||
| SetSelectedObject
|
||||
| SetObjectManagerLoading;
|
||||
Reference in New Issue
Block a user