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:
parent
edf59c9efd
commit
7234d2eb7f
@ -8,14 +8,17 @@ import { Icon } from "../icon";
|
|||||||
import { _i18n } from "../../i18n";
|
import { _i18n } from "../../i18n";
|
||||||
import { cssNames, downloadFile } from "../../utils";
|
import { cssNames, downloadFile } from "../../utils";
|
||||||
import { Pod } from "../../api/endpoints";
|
import { Pod } from "../../api/endpoints";
|
||||||
|
import { PodLogSearch } from "./pod-log-search";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
ready: boolean
|
ready: boolean
|
||||||
tabId: string
|
tabId: string
|
||||||
tabData: IPodLogsData
|
tabData: IPodLogsData
|
||||||
logs: string[][]
|
logs: string[]
|
||||||
save: (data: Partial<IPodLogsData>) => void
|
save: (data: Partial<IPodLogsData>) => void
|
||||||
reload: () => void
|
reload: () => void
|
||||||
|
onSearch: (query: string) => void
|
||||||
|
search: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PodLogControls = observer((props: Props) => {
|
export const PodLogControls = observer((props: Props) => {
|
||||||
@ -24,6 +27,7 @@ export const PodLogControls = observer((props: Props) => {
|
|||||||
const { selectedContainer, showTimestamps, previous } = tabData;
|
const { selectedContainer, showTimestamps, previous } = tabData;
|
||||||
const since = podLogsStore.getTimestamps(podLogsStore.logs.get(tabId)[0]);
|
const since = podLogsStore.getTimestamps(podLogsStore.logs.get(tabId)[0]);
|
||||||
const pod = new Pod(tabData.pod);
|
const pod = new Pod(tabData.pod);
|
||||||
|
|
||||||
const toggleTimestamps = () => {
|
const toggleTimestamps = () => {
|
||||||
save({ showTimestamps: !showTimestamps });
|
save({ showTimestamps: !showTimestamps });
|
||||||
}
|
}
|
||||||
@ -110,6 +114,7 @@ export const PodLogControls = observer((props: Props) => {
|
|||||||
onClick={downloadLogs}
|
onClick={downloadLogs}
|
||||||
tooltip={_i18n._(t`Save`)}
|
tooltip={_i18n._(t`Save`)}
|
||||||
/>
|
/>
|
||||||
|
<PodLogSearch onSearch={props.onSearch} search={props.search} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
25
src/renderer/components/dock/pod-log-search.tsx
Normal file
25
src/renderer/components/dock/pod-log-search.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
});
|
||||||
@ -29,11 +29,18 @@
|
|||||||
font-family: $font-monospace;
|
font-family: $font-monospace;
|
||||||
font-size: smaller;
|
font-size: smaller;
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
-webkit-font-smoothing: auto;
|
-webkit-font-smoothing: auto; // Better readability on non-retina screens
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
// TODO: Use a theme var to styling
|
||||||
background: #35373a;
|
background: #35373a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
border-radius: 2px;
|
||||||
|
background-color: #8cc474b8;
|
||||||
|
-webkit-font-smoothing: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,6 +27,7 @@ export class PodLogs extends React.Component<Props> {
|
|||||||
@observable ready = false;
|
@observable ready = false;
|
||||||
@observable preloading = false; // Indicator for setting Spinner (loader) at the top of the logs
|
@observable preloading = false; // Indicator for setting Spinner (loader) at the top of the logs
|
||||||
@observable showJumpToBottom = false;
|
@observable showJumpToBottom = false;
|
||||||
|
@observable findQuery = ""; // A text from search field
|
||||||
|
|
||||||
private logsElement = React.createRef<HTMLDivElement>(); // A reference for outer container in VirtualList
|
private logsElement = React.createRef<HTMLDivElement>(); // A reference for outer container in VirtualList
|
||||||
private lastLineIsShown = true; // used for proper auto-scroll content after refresh
|
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
|
* Computed prop which returns logs with or without timestamps added to each line
|
||||||
* @returns {Array} An array log items
|
* @returns {Array} An array log items
|
||||||
@ -138,9 +147,22 @@ export class PodLogs extends React.Component<Props> {
|
|||||||
*/
|
*/
|
||||||
getLogRow = (index: number) => {
|
getLogRow = (index: number) => {
|
||||||
const isSeparator = this.logs[index] === "---newlogs---"; // TODO: Use constant separator
|
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 (
|
return (
|
||||||
<div className={cssNames("LogRow", { separator: isSeparator })}>
|
<div className={cssNames("LogRow", { separator: isSeparator })}>
|
||||||
{this.logs[index]}
|
{contents.length > 1 ? contents : item}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -207,6 +229,8 @@ export class PodLogs extends React.Component<Props> {
|
|||||||
logs={this.logs}
|
logs={this.logs}
|
||||||
save={this.save}
|
save={this.save}
|
||||||
reload={this.reload}
|
reload={this.reload}
|
||||||
|
search={this.findQuery}
|
||||||
|
onSearch={this.onSearch}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user