diff --git a/portal-ui/package.json b/portal-ui/package.json
index d217fc7ec..3f7829ef5 100644
--- a/portal-ui/package.json
+++ b/portal-ui/package.json
@@ -61,7 +61,7 @@
"websocket": "^1.0.31"
},
"scripts": {
- "start": "PORT=5000 react-app-rewired start",
+ "start": "PORT=5005 react-app-rewired start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
diff --git a/portal-ui/src/screens/Console/Common/FormComponents/DateRangeSelector/DateRangeSelector.tsx b/portal-ui/src/screens/Console/Common/FormComponents/DateRangeSelector/DateRangeSelector.tsx
index d58f97bf4..8bbff9fcf 100644
--- a/portal-ui/src/screens/Console/Common/FormComponents/DateRangeSelector/DateRangeSelector.tsx
+++ b/portal-ui/src/screens/Console/Common/FormComponents/DateRangeSelector/DateRangeSelector.tsx
@@ -31,7 +31,7 @@ interface IDateRangeSelector {
setTimeStart: (date: any) => void;
timeEnd: any;
setTimeEnd: (date: any) => void;
- triggerSync: () => void;
+ triggerSync?: () => void;
}
const styles = (theme: Theme) =>
@@ -97,16 +97,18 @@ const DateRangeSelector = ({
noInputIcon
/>
- }
- className={classes.syncButton}
- >
- Sync
-
+ {triggerSync && (
+ }
+ className={classes.syncButton}
+ >
+ Sync
+
+ )}
);
diff --git a/portal-ui/src/screens/Console/Common/TableWrapper/TableWrapper.tsx b/portal-ui/src/screens/Console/Common/TableWrapper/TableWrapper.tsx
index 4efe40abc..eb1001107 100644
--- a/portal-ui/src/screens/Console/Common/TableWrapper/TableWrapper.tsx
+++ b/portal-ui/src/screens/Console/Common/TableWrapper/TableWrapper.tsx
@@ -208,9 +208,6 @@ const styles = () =>
right: 0,
top: 0,
},
- popoverContainer: {
- position: "relative",
- },
popoverContent: {
maxHeight: 250,
overflowY: "auto",
@@ -573,7 +570,6 @@ const TableWrapper = ({
horizontal: "left",
}}
onClose={closeColumnSelector}
- className={classes.popoverContainer}
>
Shown Columns
diff --git a/portal-ui/src/screens/Console/Logs/LogSearch/LogSearchFullModal.tsx b/portal-ui/src/screens/Console/Logs/LogSearch/LogSearchFullModal.tsx
new file mode 100644
index 000000000..7ae207b28
--- /dev/null
+++ b/portal-ui/src/screens/Console/Logs/LogSearch/LogSearchFullModal.tsx
@@ -0,0 +1,100 @@
+// This file is part of MinIO Console Server
+// Copyright (c) 2021 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
.
+
+import React, { Fragment } from "react";
+import get from "lodash/get";
+import { Button, Grid } from "@mui/material";
+import { Theme } from "@mui/material/styles";
+import createStyles from "@mui/styles/createStyles";
+import withStyles from "@mui/styles/withStyles";
+import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
+import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
+import { IReqInfoSearchResults } from "./types";
+import { LogSearchColumnLabels } from "./utils";
+
+interface ILogSearchFullModal {
+ modalOpen: boolean;
+ logSearchElement: IReqInfoSearchResults;
+ onClose: () => void;
+ classes: any;
+}
+
+const styles = (theme: Theme) =>
+ createStyles({
+ buttonContainer: {
+ textAlign: "right",
+ },
+ pathLabel: {
+ marginTop: 0,
+ marginBottom: 32,
+ },
+ objectKeyCol: {
+ fontWeight: 700,
+ paddingRight: "10px",
+ textAlign: "left",
+ },
+ ...modalBasic,
+ });
+
+const LogSearchFullModal = ({
+ modalOpen,
+ logSearchElement,
+ onClose,
+ classes,
+}: ILogSearchFullModal) => {
+ const jsonItems = Object.keys(logSearchElement);
+
+ return (
+
+ {
+ onClose();
+ }}
+ >
+
+
+
+
+ {jsonItems.map((objectKey: string, index: number) => (
+
+
+ {get(LogSearchColumnLabels, objectKey, `${objectKey}`)}
+
+ {get(logSearchElement, objectKey, "")}
+
+ ))}
+
+
+
+
+
+ Close
+
+
+
+
+
+ );
+};
+
+export default withStyles(styles)(LogSearchFullModal);
diff --git a/portal-ui/src/screens/Console/Logs/LogSearch/LogsSearchMain.tsx b/portal-ui/src/screens/Console/Logs/LogSearch/LogsSearchMain.tsx
index 841d613b6..193248c0e 100644
--- a/portal-ui/src/screens/Console/Logs/LogSearch/LogsSearchMain.tsx
+++ b/portal-ui/src/screens/Console/Logs/LogSearch/LogsSearchMain.tsx
@@ -38,6 +38,9 @@ import api from "../../../../common/api";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import FilterInputWrapper from "../../Common/FormComponents/FilterInputWrapper/FilterInputWrapper";
import DateTimePickerWrapper from "../../Common/FormComponents/DateTimePickerWrapper/DateTimePickerWrapper";
+import LogSearchFullModal from "./LogSearchFullModal";
+import { LogSearchColumnLabels } from "./utils";
+import DateRangeSelector from "../../Common/FormComponents/DateRangeSelector/DateRangeSelector";
interface ILogSearchProps {
classes: any;
@@ -154,6 +157,10 @@ const LogsSearchMain = ({
]);
const [nextPage, setNextPage] = useState
(0);
const [alreadyFetching, setAlreadyFetching] = useState(false);
+ const [logSearchExtrasOpen, setLogSearchExtrasOpen] =
+ useState(false);
+ const [selectedItem, setSelectedItem] =
+ useState(null);
let recordsResp: any = null;
const logSearchEnabled = features && features.includes("log-search");
@@ -188,11 +195,10 @@ const LogsSearchMain = ({
)
.then((res: ISearchResponse) => {
const fetchedResults = res.results || [];
- const newResultSet = [...records, ...fetchedResults];
setLoading(false);
setAlreadyFetching(false);
- setRecords(newResultSet);
+ setRecords(fetchedResults);
setNextPage(nextPage + 1);
if (recordsResp !== null) {
@@ -218,7 +224,6 @@ const LogsSearchMain = ({
sortOrder,
timeStart,
timeEnd,
- records,
recordsResp,
setErrorSnackMessage,
]);
@@ -262,27 +267,36 @@ const LogsSearchMain = ({
});
};
+ const openExtraInformation = (item: IReqInfoSearchResults) => {
+ setSelectedItem(item);
+ setLogSearchExtrasOpen(true);
+ };
+
+ const closeViewExtraInformation = () => {
+ setSelectedItem(null);
+ setLogSearchExtrasOpen(false);
+ };
+
return (
+ {logSearchExtrasOpen && selectedItem !== null && (
+
+ )}
- Start Time
-
- End Time
-
@@ -376,15 +390,28 @@ const LogsSearchMain = ({
(
@@ -396,17 +423,17 @@ const LogsSearchMain = ({
renderFullObject: true,
},
{
- label: "Request Content Length",
+ label: LogSearchColumnLabels.request_content_length,
elementKey: "request_content_length",
renderFunction: niceBytes,
},
{
- label: "Response Content Length",
+ label: LogSearchColumnLabels.response_content_length,
elementKey: "response_content_length",
renderFunction: niceBytes,
},
{
- label: "Time to Response NS",
+ label: LogSearchColumnLabels.time_to_response_ns,
elementKey: "time_to_response_ns",
renderFunction: nsToSeconds,
contentTextAlign: "right",
@@ -432,6 +459,12 @@ const LogsSearchMain = ({
recordsCount: 1000000,
loadMoreRecords: loadMoreRecords,
}}
+ itemActions={[
+ {
+ type: "view",
+ onClick: openExtraInformation,
+ },
+ ]}
textSelectable
/>
diff --git a/portal-ui/src/screens/Console/Logs/LogSearch/utils.ts b/portal-ui/src/screens/Console/Logs/LogSearch/utils.ts
new file mode 100644
index 000000000..8ed988743
--- /dev/null
+++ b/portal-ui/src/screens/Console/Logs/LogSearch/utils.ts
@@ -0,0 +1,30 @@
+// This file is part of MinIO Console Server
+// Copyright (c) 2021 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 .
+
+export const LogSearchColumnLabels = {
+ time: "Timestamp",
+ api_name: "API Name",
+ bucket: "Bucket",
+ object: "Object",
+ remote_host: "Remote Host",
+ request_id: "Request ID",
+ user_agent: "User Agent",
+ response_status: "Response Status",
+ response_status_code: "Response Status Code",
+ request_content_length: "Request Content Length",
+ response_content_length: "Response Content Length",
+ time_to_response_ns: "Time to Response NS",
+};