Skip to content

Commit a5616fa

Browse files
authored
Merge pull request #332 from devtron-labs/feat/improve-log-search
feat: incremental search in logs
2 parents 3409271 + d4e6ac0 commit a5616fa

File tree

30 files changed

+295
-151
lines changed

30 files changed

+295
-151
lines changed

package-lock.json

Lines changed: 7 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@devtron-labs/devtron-fe-common-lib",
3-
"version": "0.3.22",
3+
"version": "4.0.1",
44
"description": "Supporting common component library",
55
"type": "module",
66
"main": "dist/index.js",
@@ -83,18 +83,18 @@
8383
"react-dom": "^17.0.2",
8484
"react-draggable": "^4.4.5",
8585
"react-ga4": "^1.4.1",
86+
"react-keybind": "^0.9.4",
8687
"react-mde": "^11.5.0",
8788
"react-router": "^5.3.0",
8889
"react-router-dom": "^5.3.0",
8990
"react-select": "5.8.0",
90-
"react-keybind": "^0.9.4",
9191
"rxjs": "^7.8.1",
9292
"yaml": "^2.4.1"
9393
},
9494
"dependencies": {
9595
"@types/react-dates": "^21.8.6",
9696
"ansi_up": "^5.2.1",
97-
"dayjs": "^1.11.12",
97+
"dayjs": "^1.11.13",
9898
"fast-json-patch": "^3.1.1",
9999
"jsonpath-plus": "^9.0.0",
100100
"react-dates": "^21.8.0",
Lines changed: 19 additions & 0 deletions
Loading

src/Assets/Icon/ic-close.svg

Lines changed: 2 additions & 2 deletions
Loading

src/Assets/Icon/ic-expand.svg

Lines changed: 1 addition & 1 deletion
Loading

src/Common/CodeEditor/CodeEditor.tsx

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,6 @@ function useCodeEditorContext() {
5454
return context
5555
}
5656

57-
/**
58-
* TODO: can be removed with this new merge into react-monaco-editor :)
59-
* see: https://github.com/react-monaco-editor/react-monaco-editor/pull/955
60-
* */
61-
const _onChange = {
62-
onChange: null,
63-
}
64-
6557
const INITIAL_HEIGHT_WHEN_DYNAMIC_HEIGHT = 100
6658

6759
const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.memo(
@@ -107,6 +99,12 @@ const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.
10799
const [contentHeight, setContentHeight] = useState(
108100
adjustEditorHeightToContent ? INITIAL_HEIGHT_WHEN_DYNAMIC_HEIGHT : height,
109101
)
102+
/**
103+
* TODO: can be removed with this new merge into react-monaco-editor :)
104+
* see: https://github.com/react-monaco-editor/react-monaco-editor/pull/955
105+
* */
106+
const onChangeRef = useRef(onChange)
107+
onChangeRef.current = onChange
110108
monaco.editor.defineTheme(CodeEditorThemesKeys.vsDarkDT, {
111109
base: 'vs-dark',
112110
inherit: true,
@@ -257,14 +255,9 @@ const CodeEditor: React.FC<CodeEditorInterface> & CodeEditorComposition = React.
257255
editorRef.current.layout()
258256
}, [width, windowHeight])
259257

260-
/**
261-
* NOTE: Please see @_onChange variable
262-
*/
263-
_onChange.onChange = onChange
264-
265258
const setCode = (value: string) => {
266259
dispatch({ type: 'setCode', value })
267-
_onChange.onChange?.(value)
260+
onChangeRef.current?.(value)
268261
}
269262

270263
useEffect(() => {

src/Common/Types.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -639,12 +639,6 @@ export interface VulnerabilityType {
639639
url?: string
640640
}
641641

642-
export interface ScanVulnerabilitiesTableProps {
643-
vulnerabilities: VulnerabilityType[]
644-
hidePolicy?: boolean
645-
shouldStick?: boolean
646-
}
647-
648642
export interface MaterialInfo {
649643
revision: string
650644
modifiedTime: string | Date

src/Shared/Components/CICDHistory/LogStageAccordion.tsx

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import DOMPurify from 'dompurify'
22
import { getTimeDifference } from '@Shared/Helpers'
3+
import { RefCallback } from 'react'
34
import { LogStageAccordionProps } from './types'
4-
import { getStageStatusIcon } from './utils'
5+
import { getLogSearchIndex, getStageStatusIcon } from './utils'
56
import { ReactComponent as ICCaretDown } from '../../../Assets/Icon/ic-caret-down.svg'
67

78
const LogsItemContainer = ({ children }: { children: React.ReactNode }) => (
@@ -20,6 +21,7 @@ const LogStageAccordion = ({
2021
stageIndex,
2122
isLoading,
2223
fullScreenView,
24+
searchIndex,
2325
}: LogStageAccordionProps) => {
2426
const handleAccordionToggle = () => {
2527
if (isOpen) {
@@ -37,6 +39,24 @@ const LogStageAccordion = ({
3739
return timeDifference
3840
}
3941

42+
const scrollIntoView: RefCallback<HTMLSpanElement> = (node) => {
43+
if (!node) {
44+
return
45+
}
46+
47+
if (node.dataset.containsMatch === 'true' && node.dataset.triggered !== 'true') {
48+
// eslint-disable-next-line no-param-reassign
49+
node.dataset.triggered = 'true'
50+
// TODO: this will additionally scroll the top most scrollbar. Need to check into that
51+
node.scrollIntoView({ block: 'center', behavior: 'smooth' })
52+
}
53+
54+
if (node.dataset.containsMatch === 'false') {
55+
// eslint-disable-next-line no-param-reassign
56+
node.dataset.triggered = 'false'
57+
}
58+
}
59+
4060
return (
4161
<div className="flexbox-col dc__gap-8">
4262
<button
@@ -64,23 +84,32 @@ const LogStageAccordion = ({
6484

6585
{isOpen && (
6686
<div className="flexbox-col dc__gap-4">
67-
{logs.map((log: string, logsIndex: number) => (
68-
<LogsItemContainer
69-
// eslint-disable-next-line react/no-array-index-key
70-
key={`logs-${stage}-${startTime}-${logsIndex}`}
71-
>
72-
<span className="cn-4 col-2 lh-20 dc__text-align-end dc__word-break mono fs-14">
73-
{logsIndex + 1}
74-
</span>
75-
<p
76-
className="mono fs-14 mb-0-imp cn-0 dc__word-break lh-20"
77-
// eslint-disable-next-line react/no-danger
78-
dangerouslySetInnerHTML={{
79-
__html: DOMPurify.sanitize(log),
80-
}}
81-
/>
82-
</LogsItemContainer>
83-
))}
87+
{logs.map((log: string, logsIndex: number) => {
88+
const doesLineContainSearchMatch =
89+
getLogSearchIndex({ stageIndex, lineNumberInsideStage: logsIndex }) === searchIndex
90+
91+
return (
92+
<LogsItemContainer
93+
// eslint-disable-next-line react/no-array-index-key
94+
key={`logs-${stage}-${startTime}-${logsIndex}`}
95+
>
96+
<span
97+
ref={scrollIntoView}
98+
className="cn-4 col-2 lh-20 dc__text-align-end dc__word-break mono fs-14"
99+
data-contains-match={doesLineContainSearchMatch}
100+
>
101+
{logsIndex + 1}
102+
</span>
103+
<p
104+
className="mono fs-14 mb-0-imp cn-0 dc__word-break lh-20"
105+
// eslint-disable-next-line react/no-danger
106+
dangerouslySetInnerHTML={{
107+
__html: DOMPurify.sanitize(log),
108+
}}
109+
/>
110+
</LogsItemContainer>
111+
)
112+
})}
84113

85114
{isLoading && (
86115
<LogsItemContainer>

0 commit comments

Comments
 (0)