Skip to content

Commit

Permalink
add and-or search combinations
Browse files Browse the repository at this point in the history
  • Loading branch information
vish9812 committed Nov 2, 2023
1 parent 5457d3a commit ec6ead5
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 12 deletions.
3 changes: 1 addition & 2 deletions src/analyzer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function Analyzer() {
</Grid>
</Grid>
<Grid item xs={12}>
<div style={{ height: "550px" }} class="ag-theme-alpine">
<div style={{ height: "750px" }} class="ag-theme-alpine">
<AgGridSolid
ref={gridRef}
defaultColDef={gridService.defaultColDef}
Expand All @@ -102,7 +102,6 @@ function Analyzer() {
getRowId={(params) => params.data.id}
getRowStyle={getRowStyle}
enableCellTextSelection={true}
// ensureDomOrder={true}
/>
</div>
</Grid>
Expand Down
48 changes: 46 additions & 2 deletions src/analyzer/useViewModel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ describe("useViewModel", () => {
[Processor.logKeys.fullData]: "test one two four",
[Processor.logKeys.msg]: "test one two four",
},
{
[Processor.logKeys.id]: "23",
[Processor.logKeys.timestamp]: "2023-10-20T10:00:00.000Z",
[Processor.logKeys.fullData]: "test one two contains check four",
[Processor.logKeys.msg]: "test one two contains check four",
},
{
[Processor.logKeys.id]: "24",
[Processor.logKeys.timestamp]: "2023-10-20T10:00:00.000Z",
[Processor.logKeys.fullData]: "test one two ands check four",
[Processor.logKeys.msg]: "test one two ands check four",
},
{
[Processor.logKeys.id]: "30",
[Processor.logKeys.timestamp]: "2023-10-20T12:00:00.000Z",
Expand All @@ -100,6 +112,8 @@ describe("useViewModel", () => {
];

vi.spyOn(Processor, "isErrorLog")
.mockReturnValueOnce(true)
.mockReturnValueOnce(true)
.mockReturnValueOnce(true)
.mockReturnValueOnce(true)
.mockReturnValueOnce(false);
Expand All @@ -110,14 +124,39 @@ describe("useViewModel", () => {
startTime: "2023-10-20T01:00:00.000Z",
endTime: "2023-10-20T11:00:00.000Z",
errorsOnly: true,
logs: [comparer.last().logs[0], comparer.last().logs[1]],
logs: [
comparer.last().logs[1],
comparer.last().logs[2],
comparer.last().logs[3],
comparer.last().logs[4],
],
regex: "^tes.*our$",
terms: [
{
and: true,
contains: true,
value: "ands",
},
{
and: true,
contains: false,
value: "msg",
},
{
and: false,
contains: true,
value: "check",
},
],
};

const vm = useViewModel();
vm.handleFiltersChange(filters);

expect(vm.rows(), "rows").toEqual([comparer.last().logs[1]]);
expect(vm.rows(), "rows").toEqual([
comparer.last().logs[2],
comparer.last().logs[3],
]);
expect(vm.timeJumps().prevDisabled, "prevDisabled").toEqual(true);
expect(vm.timeJumps().nextDisabled, "nextDisabled").toEqual(false);

Expand All @@ -133,22 +172,27 @@ describe("useViewModel", () => {
{
[Processor.logKeys.id]: "1",
[Processor.logKeys.timestamp]: "2023-10-20T08:00:00.000Z",
[Processor.logKeys.fullData]: "json string 1",
},
{
[Processor.logKeys.id]: "2",
[Processor.logKeys.timestamp]: "2023-10-20T10:00:00.000Z",
[Processor.logKeys.fullData]: "json string 2",
},
{
[Processor.logKeys.id]: "3",
[Processor.logKeys.timestamp]: "2023-10-20T12:00:00.000Z",
[Processor.logKeys.fullData]: "json string 3",
},
{
[Processor.logKeys.id]: "4",
[Processor.logKeys.timestamp]: "2023-10-20T14:00:00.000Z",
[Processor.logKeys.fullData]: "json string 4",
},
{
[Processor.logKeys.id]: "5",
[Processor.logKeys.timestamp]: "2023-10-20T16:00:00.000Z",
[Processor.logKeys.fullData]: "json string 5",
},
];
vi.spyOn(comparer, "last").mockReturnValue(processor);
Expand Down
41 changes: 36 additions & 5 deletions src/analyzer/useViewModel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import Processor, { JSONLogs } from "../models/processor";
import { createSignal } from "solid-js";
import { FiltersData } from "../components/filters/useViewModel";
import type {
FiltersData,
SearchTerm,
} from "../components/filters/useViewModel";
import comparer from "../models/comparer";
import stringsUtils from "../utils/strings";
import filesUtils from "../utils/files";
Expand Down Expand Up @@ -48,13 +51,41 @@ function useViewModel() {
if (keep && filtersData.errorsOnly) {
keep = Processor.isErrorLog(log);
}

const fullData = log[Processor.logKeys.fullData].toLowerCase();
if (keep && filtersData.regex) {
keep = stringsUtils.regexMatch(
log[Processor.logKeys.fullData],
filtersData.regex
);
keep = stringsUtils.regexMatch(fullData, filtersData.regex);
}
if (keep && filtersData.terms) {
const ands = filtersData.terms.filter((t) => t.and);
let currCondition = true;
const updateCurrCondition = (term: SearchTerm) => {
const val = term.value.trim();
if (val) {
currCondition = term.contains
? fullData.includes(val)
: !fullData.includes(val);
}
};

for (const term of ands) {
if (!currCondition) break;
updateCurrCondition(term);
}

if (!currCondition) {
const ors = filtersData.terms.filter((t) => !t.and);

for (const term of ors) {
if (currCondition) break;
updateCurrCondition(term);
}
}

keep = currCondition;
}

// Update time jumps
if (keep) {
const id = log[Processor.logKeys.id];
const time = new Date(log[Processor.logKeys.timestamp]);
Expand Down
57 changes: 55 additions & 2 deletions src/components/filters/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,26 @@ import {
TextField,
Typography,
} from "@suid/material";
import useViewModel, { type FiltersProps } from "./useViewModel";
import useViewModel, {
type SearchTerm,
type FiltersProps,
} from "./useViewModel";
import AgGridSolid, { type AgGridSolidRef } from "ag-grid-solid";
import type { GridOptions } from "ag-grid-community";
import { GroupedMsg } from "../../models/processor";
import { Show } from "solid-js";
import { type Accessor, For, Show } from "solid-js";
import comparer from "../../models/comparer";
import { Select } from "@thisbeyond/solid-select";
import { IconButton } from "@suid/material";
import AddIcon from "@suid/icons-material/Add";
import RemoveIcon from "@suid/icons-material/Remove";

const texts = {
and: "AND",
or: "OR",
contains: "Contains",
notContains: "Not Contains",
};

function Filters(props: FiltersProps) {
let topMsgsGridRef = {} as AgGridSolidRef;
Expand All @@ -29,6 +43,7 @@ function Filters(props: FiltersProps) {
handleLogsSelectionChanged,
handleErrorsOnlyChange,
handleResetClick,
handleNewSearchTerm,
} = useViewModel(props);

const commonGridOptions: GridOptions<GroupedMsg> = {
Expand Down Expand Up @@ -72,6 +87,7 @@ function Filters(props: FiltersProps) {
{ ...commonGridOptions.columnDefs![1] },
],
rowSelection: undefined,
onSelectionChanged: undefined,
};

function handleEnterKey(e: KeyboardEvent) {
Expand All @@ -80,6 +96,33 @@ function Filters(props: FiltersProps) {
}
}

function getSimpleSearchHTML(term: SearchTerm, i: Accessor<number>) {
return (
<>
<Select
class="app-select"
options={[texts.and, texts.or]}
initialValue={term.and ? texts.and : texts.or}
onChange={(val) => setFilters("terms", i(), "and", val === texts.and)}
/>
<Select
class="app-select"
options={[texts.contains, texts.notContains]}
initialValue={term.contains ? texts.contains : texts.notContains}
onChange={(val) =>
setFilters("terms", i(), "contains", val === texts.contains)
}
/>
<TextField
label="value"
value={term.value}
onChange={(_, val) => setFilters("terms", i(), "value", val)}
onKeyDown={handleEnterKey}
/>
</>
);
}

return (
<Grid container spacing={2}>
<Grid item xs={12}>
Expand All @@ -102,6 +145,16 @@ function Filters(props: FiltersProps) {
onChange={(_, val) => setFilters("regex", val)}
onKeyDown={handleEnterKey}
/>
<For each={filters.terms}>{getSimpleSearchHTML}</For>
<IconButton color="primary" onClick={() => handleNewSearchTerm(true)}>
<AddIcon />
</IconButton>
<IconButton
color="warning"
onClick={() => handleNewSearchTerm(false)}
>
<RemoveIcon />
</IconButton>
</Stack>
</Grid>
<Grid item xs={12}>
Expand Down
29 changes: 29 additions & 0 deletions src/components/filters/useViewModel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ describe("useViewModel", () => {
startTime: "",
endTime: "",
regex: "",
terms: [
{
and: true,
contains: true,
value: "",
},
],
logs: [],
errorsOnly: false,
};
Expand Down Expand Up @@ -188,4 +195,26 @@ describe("useViewModel", () => {
});
});
});

test("handleNewSearchTerm", () => {
createRoot((dispose) => {
const vm = useViewModel(props);
const original = [...vm.filters.terms];

vm.handleNewSearchTerm(true);
expect(vm.filters.terms, "term added").toEqual([
...original,
{
and: true,
contains: true,
value: "",
},
]);

vm.handleNewSearchTerm(false);
expect(vm.filters.terms, "term removed").toEqual(original);

dispose();
});
});
});
30 changes: 29 additions & 1 deletion src/components/filters/useViewModel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@ interface FiltersProps {
onFiltersChange: (filters: FiltersData) => void;
}

interface SearchTerm {
and: boolean;
contains: boolean;
value: string;
}

interface FiltersData {
startTime: string;
endTime: string;
regex: string;
terms: SearchTerm[];
logs: JSONLogs;
errorsOnly: boolean;
}
Expand All @@ -22,6 +29,13 @@ function defaultFilters(): FiltersData {
startTime: "",
endTime: "",
regex: "",
terms: [
{
and: true,
contains: true,
value: "",
},
],
logs: [],
errorsOnly: false,
};
Expand Down Expand Up @@ -75,6 +89,19 @@ function useViewModel(props: FiltersProps) {
handleFiltersChange();
}

function handleNewSearchTerm(isAddition: boolean) {
if (isAddition) {
setFilters("terms", filters.terms.length, {
and: true,
contains: true,
value: "",
});
return;
}

setFilters("terms", filters.terms.slice(0, -1));
}

return {
filters,
topLogs,
Expand All @@ -85,8 +112,9 @@ function useViewModel(props: FiltersProps) {
handleLogsSelectionChanged,
handleErrorsOnlyChange,
handleResetClick,
handleNewSearchTerm,
};
}

export default useViewModel;
export type { FiltersData, FiltersProps };
export type { SearchTerm, FiltersData, FiltersProps };

0 comments on commit ec6ead5

Please sign in to comment.