1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Introducing log search

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
Alex Andreev 2020-10-20 13:44:54 +03:00
parent edf59c9efd
commit 7234d2eb7f
4 changed files with 64 additions and 3 deletions

View File

@ -8,14 +8,17 @@ import { Icon } from "../icon";
import { _i18n } from "../../i18n";
import { cssNames, downloadFile } from "../../utils";
import { Pod } from "../../api/endpoints";
import { PodLogSearch } from "./pod-log-search";
interface Props {
ready: boolean
tabId: string
tabData: IPodLogsData
logs: string[][]
logs: string[]
save: (data: Partial<IPodLogsData>) => void
reload: () => void
onSearch: (query: string) => void
search: string
}
export const PodLogControls = observer((props: Props) => {
@ -24,6 +27,7 @@ export const PodLogControls = observer((props: Props) => {
const { selectedContainer, showTimestamps, previous } = tabData;
const since = podLogsStore.getTimestamps(podLogsStore.logs.get(tabId)[0]);
const pod = new Pod(tabData.pod);
const toggleTimestamps = () => {
save({ showTimestamps: !showTimestamps });
}
@ -110,6 +114,7 @@ export const PodLogControls = observer((props: Props) => {
onClick={downloadLogs}
tooltip={_i18n._(t`Save`)}
/>
<PodLogSearch onSearch={props.onSearch} search={props.search} />
</div>
</div>
);

View File

@ -0,0 +1,25 @@
import React from "react";
import { observer } from "mobx-react";
import { cssNames } from "../../utils";
import { Input } from "../input";
interface Props {
onSearch: (query: string) => void
search: string
}
export const PodLogSearch = observer((props: Props) => {
const { onSearch, search } = props;
const setSearch = (query: string) => {
onSearch(query);
};
return (
<div className="PodLogsSearch">
<Input
className={cssNames("SearchInput")}
value={search}
onChange={setSearch}
/>
</div>
)
});

View File

@ -29,11 +29,18 @@
font-family: $font-monospace;
font-size: smaller;
white-space: pre;
-webkit-font-smoothing: auto;
-webkit-font-smoothing: auto; // Better readability on non-retina screens
&:hover {
// TODO: Use a theme var to styling
background: #35373a;
}
span {
border-radius: 2px;
background-color: #8cc474b8;
-webkit-font-smoothing: auto;
}
}
}
}

View File

@ -27,6 +27,7 @@ export class PodLogs extends React.Component<Props> {
@observable ready = false;
@observable preloading = false; // Indicator for setting Spinner (loader) at the top of the logs
@observable showJumpToBottom = false;
@observable findQuery = ""; // A text from search field
private logsElement = React.createRef<HTMLDivElement>(); // A reference for outer container in VirtualList
private lastLineIsShown = true; // used for proper auto-scroll content after refresh
@ -101,6 +102,14 @@ export class PodLogs extends React.Component<Props> {
}
}
/**
* Updating findQuery observable
* @param query {string} A text from search field
*/
onSearch(query: string) {
this.findQuery = query;
}
/**
* Computed prop which returns logs with or without timestamps added to each line
* @returns {Array} An array log items
@ -138,9 +147,22 @@ export class PodLogs extends React.Component<Props> {
*/
getLogRow = (index: number) => {
const isSeparator = this.logs[index] === "---newlogs---"; // TODO: Use constant separator
const { findQuery } = this;
const item = this.logs[index];
const contents: React.ReactElement[] = [];
if (findQuery) {
// If search is enabled, replace keyword with backgrounded <span> to "highlight" searchable text
const pieces = item.split(findQuery);
pieces.forEach((piece, index) => {
const overlay = index !== pieces.length - 1 ? <span>{findQuery}</span> : null
contents.push(
<>{piece}{overlay}</>
);
})
}
return (
<div className={cssNames("LogRow", { separator: isSeparator })}>
{this.logs[index]}
{contents.length > 1 ? contents : item}
</div>
);
}
@ -207,6 +229,8 @@ export class PodLogs extends React.Component<Props> {
logs={this.logs}
save={this.save}
reload={this.reload}
search={this.findQuery}
onSearch={this.onSearch}
/>
)
return (