-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #113 from mahmednabil109/add_logs_table
Add logs table ui
- Loading branch information
Showing
13 changed files
with
4,749 additions
and
881 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import superagent from 'superagent'; | ||
|
||
// TODO: remove the hardcoded levels | ||
// logLevels is the possible levels for logs | ||
export const Levels = ['panic', 'fatal', 'error', 'warning', 'info', 'debug']; | ||
|
||
// Log defines the expected log entry returned from the api | ||
export interface Log { | ||
job_id: number; | ||
log_data: string; | ||
log_level: string; | ||
date: string; | ||
} | ||
|
||
// Query defines all the possible filters to form a query | ||
export interface Query { | ||
job_id?: number; | ||
text?: string; | ||
log_level?: string; | ||
start_date?: string; | ||
end_date?: string; | ||
page: number; | ||
page_size: number; | ||
} | ||
|
||
// Result defines the structure of the api response to a query | ||
export interface Result { | ||
logs: Log[] | null; | ||
count: number; | ||
page: number; | ||
page_size: number; | ||
} | ||
|
||
// getLogs returns Result that contains logs fetched according to the Query | ||
export async function getLogs(query: Query): Promise<Result> { | ||
let result: superagent.Response = await superagent.get('/log').query(query); | ||
|
||
return result.body; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
* { | ||
margin: 0; | ||
padding: 0; | ||
box-sizing: border-box; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,7 @@ | ||
import React from 'react'; | ||
import '../styles/app.scss'; | ||
import './app.scss'; | ||
import SearchLogs from './search_logs/search_logs'; | ||
|
||
function App() { | ||
return <h1>Context is not Contest</h1>; | ||
export default function App() { | ||
return <SearchLogs />; | ||
} | ||
|
||
export default App; |
10 changes: 10 additions & 0 deletions
10
cmds/admin_server/ui/src/search_logs/log_table/date_cell/date_cell.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import React from 'react'; | ||
import { Cell, CellProps } from 'rsuite-table'; | ||
|
||
export default function DateCell({ rowData, dataKey, ...props }: CellProps) { | ||
return ( | ||
<Cell {...props}> | ||
<p>{dataKey && new Date(rowData[dataKey]).toLocaleString()}</p> | ||
</Cell> | ||
); | ||
} |
14 changes: 14 additions & 0 deletions
14
cmds/admin_server/ui/src/search_logs/log_table/log_table.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
.log-table { | ||
.log-table__search-btn { | ||
display: block !important; | ||
margin: auto; | ||
} | ||
|
||
.log-table__cell { | ||
padding: 2px; | ||
} | ||
|
||
.log-table__pagination { | ||
padding: 2px; | ||
} | ||
} |
125 changes: 125 additions & 0 deletions
125
cmds/admin_server/ui/src/search_logs/log_table/log_table.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import React, { useState } from 'react'; | ||
import { Table, Pagination, Button, useToaster, Message } from 'rsuite'; | ||
import { Column, Cell, HeaderCell } from 'rsuite-table'; | ||
import { StandardProps } from 'rsuite-table/lib/@types/common'; | ||
import { getLogs, Log, Result } from '../../api/logs'; | ||
import { TypeAttributes } from 'rsuite/esm/@types/common'; | ||
import DateCell from './date_cell/date_cell'; | ||
import 'rsuite/dist/rsuite.min.css'; | ||
import './log_table.scss'; | ||
|
||
export interface LogTableProps extends StandardProps { | ||
logLevels?: string; | ||
queryText?: string; | ||
jobID?: number; | ||
startDate?: Date; | ||
endDate?: Date; | ||
} | ||
|
||
export default function LogTable({ | ||
logLevels, | ||
queryText, | ||
jobID, | ||
startDate, | ||
endDate, | ||
}: LogTableProps) { | ||
const [loading, setLoading] = useState<boolean>(false); | ||
const [logs, setLogs] = useState<Log[] | null>([]); | ||
const [count, setCount] = useState<number>(0); | ||
const [page, setPage] = useState<number>(0); | ||
const [limit, setLimit] = useState<number>(20); | ||
|
||
const toaster = useToaster(); | ||
const pageSizes = [20, 50, 100]; | ||
|
||
const showMsg = (type: TypeAttributes.Status, message: string) => { | ||
toaster.push( | ||
<Message showIcon type={type}> | ||
{message} | ||
</Message>, | ||
{ placement: 'topEnd' } | ||
); | ||
}; | ||
const updateLogsTable = async (page: number, limit: number) => { | ||
setLoading(true); | ||
try { | ||
let result: Result = await getLogs({ | ||
job_id: jobID ?? undefined, | ||
text: queryText, | ||
page: page, | ||
page_size: limit, | ||
log_level: logLevels, | ||
start_date: startDate?.toJSON(), | ||
end_date: endDate?.toJSON(), | ||
}); | ||
|
||
setLogs(result.logs); | ||
setCount(result.count); | ||
setPage(result.page); | ||
setLimit(result.page_size); | ||
} catch (err) { | ||
console.log(err); | ||
showMsg('error', err?.message); | ||
} | ||
setLoading(false); | ||
}; | ||
|
||
return ( | ||
<div className="log-table"> | ||
<div> | ||
<Button | ||
className="log-table__search-btn" | ||
color="green" | ||
appearance="primary" | ||
onClick={() => updateLogsTable(0, limit)} | ||
> | ||
Search | ||
</Button> | ||
</div> | ||
<Table | ||
loading={loading} | ||
height={700} | ||
data={logs ?? []} | ||
wordWrap="break-word" | ||
rowHeight={30} | ||
> | ||
<Column width={80} align="center" fixed> | ||
<HeaderCell>JobID</HeaderCell> | ||
<Cell className="log-table__cell" dataKey="job_id" /> | ||
</Column> | ||
<Column width={250} align="center" fixed> | ||
<HeaderCell>Date</HeaderCell> | ||
<DateCell className="log-table__cell" dataKey="date" /> | ||
</Column> | ||
<Column width={80} align="center" fixed> | ||
<HeaderCell>Level</HeaderCell> | ||
<Cell className="log-table__cell" dataKey="log_level" /> | ||
</Column> | ||
<Column width={600} align="left" flexGrow={1}> | ||
<HeaderCell>Data</HeaderCell> | ||
<Cell className="log-table__cell" dataKey="log_data" /> | ||
</Column> | ||
</Table> | ||
<div> | ||
<Pagination | ||
prev | ||
next | ||
first | ||
last | ||
ellipsis | ||
boundaryLinks | ||
className="log-table__pagination" | ||
maxButtons={5} | ||
size="xs" | ||
layout={['total', '-', 'limit', '|', 'pager', 'skip']} | ||
total={count} | ||
limitOptions={pageSizes} | ||
limit={limit} | ||
activePage={page + 1} | ||
onChangePage={(page) => updateLogsTable(page - 1, limit)} | ||
onChangeLimit={(limit) => updateLogsTable(0, limit)} | ||
/> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
.logs-search { | ||
padding: 1.3em; | ||
|
||
.logs-search__input-group { | ||
display: flex; | ||
align-items: center; | ||
padding: 0.3em; | ||
|
||
p { | ||
width: 9em; | ||
} | ||
|
||
.filter-input { | ||
width: 30em; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import React, { useState, useEffect, useMemo, useRef } from 'react'; | ||
import { Input, DateRangePicker, TagPicker, InputNumber } from 'rsuite'; | ||
import LogTable from './log_table/log_table'; | ||
import { Levels } from '../api/logs'; | ||
import './search_logs.scss'; | ||
|
||
export default function SearchLogs() { | ||
const [queryText, setQueryText] = useState<string>(''); | ||
const [jobID, setJobID] = useState<number | null>(null); | ||
const [logLevels, setLogLevels] = useState<string[]>([]); | ||
const [dateRange, setDateRange] = useState<[Date, Date] | null>(null); | ||
|
||
const levelTags = useMemo( | ||
() => Levels.map((l) => ({ key: l, label: l })), | ||
Levels | ||
); | ||
|
||
return ( | ||
<div className="logs-search"> | ||
<div className="logs-search__input-group"> | ||
<p> Search: </p> | ||
<Input | ||
className="filter-input" | ||
placeholder="log data" | ||
value={queryText} | ||
onChange={setQueryText} | ||
/> | ||
</div> | ||
<div className="logs-search__input-group"> | ||
<p> Job ID: </p> | ||
<InputNumber | ||
className="filter-input" | ||
placeholder="Job ID" | ||
min={0} | ||
value={jobID ?? ''} | ||
onChange={(id) => | ||
setJobID(id === '' ? null : parseInt(String(id))) | ||
} | ||
/> | ||
</div> | ||
<div className="logs-search__input-group"> | ||
<p>Date Range:</p> | ||
<DateRangePicker | ||
className="filter-input" | ||
format="yyyy-MM-dd HH:mm:ss" | ||
value={dateRange} | ||
onChange={setDateRange} | ||
/> | ||
</div> | ||
<div className="logs-search__input-group"> | ||
<p>Levels:</p> | ||
<TagPicker | ||
className="filter-input" | ||
data={levelTags} | ||
labelKey="label" | ||
valueKey="key" | ||
value={logLevels} | ||
onChange={setLogLevels} | ||
cleanable={false} | ||
/> | ||
</div> | ||
<LogTable | ||
queryText={queryText} | ||
jobID={jobID ?? undefined} | ||
logLevels={ | ||
logLevels.length > 0 ? logLevels.join(',') : undefined | ||
} | ||
startDate={dateRange ? dateRange[0] : undefined} | ||
endDate={dateRange ? dateRange[1] : undefined} | ||
/> | ||
</div> | ||
); | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters