Skip to content
This repository has been archived by the owner on Dec 7, 2019. It is now read-only.

Add search bar and filters for logcat output #147

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

tokou
Copy link

@tokou tokou commented Jun 3, 2018

There are many ways to approach this.
I decided against adding to the window.test object as logcat output can be very large.

I kept the static html generated by the Jar. I just added an id static_logs in order to remove it once we load the logs in js.

I made a LogContainer component that shows the filters, the search bar and the logs once they are loaded from the file (it replaces the static logs).

I extracted the SearchBar component and made it generic and used by LogFilter and SuiteFilter

I tested this with a 10k lines logcat output file. Loading is seamless thanks to the html. Search is kinda laggy but acceptable. Maybe there's a React trick out there to make it faster.

@yunikkk
Copy link
Contributor

yunikkk commented Jun 6, 2018

Hey @navstyachka could you PTAL?)

@navstyachka
Copy link
Contributor

Hi @tokou! Thank you for the contribution, but as soon as this is a massive change, I will need more time to review that.

@tokou
Copy link
Author

tokou commented Jun 7, 2018

I just noticed that it does not work when opening the index file directly in the browser. It works when you serve it from a local web server though.
I will look into it.

@tokou
Copy link
Author

tokou commented Jun 8, 2018

I made an update to get the logs from the DOM tree instead of reading the logcat file.
It works without a web server now.

@tokou
Copy link
Author

tokou commented Jun 11, 2018

The build seems to have failed for reasons unrelated to the code. Any way to retrigger it ?

@yunikkk
Copy link
Contributor

yunikkk commented Jun 12, 2018

@tokou I've triggered it

Copy link
Contributor

@navstyachka navstyachka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for your contribution and the idea itself! But I am sorry to say that for the moment your code does not meet our code standards and this pull needs not just some fixes but a totally different code approach and cannot be merged. We will be happy to have a look at how to improve Composer features and especially the search. I hope my comments will help you to improve your React and JS overall knowledge!

}

loadStaticLogs() {
let logDivs = document.querySelectorAll('#static_logs > div > div')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bad practice to reach elements directly from DOM in react, because it is against the whole concept of virtual DOM, except for rare cases (like reaching out <head> tag and some other corner cases).
Also, just fyi, using operator > is a bad practice, and sticking to simple tag div (without id or data-attribute) is also a bad practise — if HTML changes, the code is broken.

return
}
let logs = []
for (var div of logDivs) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use var for defining variables, as we use es-2015 syntax. Please check it out here: https://old.babeljs.io/learn-es2015/#let-const

Also, you can use method map for array iterating. Please check it out here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

for (var div of logDivs) {
logs.push(Object.assign({level: div.className, line: div.innerText, key: logs.length}))
}
this.setState({logs: logs, results: logs, loading: false})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fyi, in es6, if a key is the same as a value, you can write it like this: {logs, results: logs, loading: false}, please check it out here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer

}

componentDidMount() {
document.addEventListener('DOMContentLoaded', (event) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has no sense adding listener DOMContentLoaded as the method componentDidMount itself says that the DOM is ready. Please read the React documentation to understand React way: https://reactjs.org/docs/state-and-lifecycle.html

}
let logs = []
for (var div of logDivs) {
logs.push(Object.assign({level: div.className, line: div.innerText, key: logs.length}))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no sense in using Object.assign here — what you actually want is just to add a new object to the array. Object.assign is a method used to perform more complicated actions with the objects. Please see the documentation here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

Also, if you want to add a unique key, here comes the map method — it has a unique index for each item in the array.

logs.push(Object.assign({level: div.className, line: div.innerText, key: logs.length}))
}
this.setState({logs: logs, results: logs, loading: false})
window.document.getElementById("static_logs").remove()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing DOM directly with JS in React is a forbidden action and it is against basic React rules. Please read the React manual for more information.


render() {
return this.state.hide
? (<div></div>)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In React, if we don't need a component to render, we return null

<div>
<div className="card">
<div className="title-common">LOGS</div>
<LogFilterButton onClick={ () => this.performFilterSearch("level:verbose") } text="Verbose" disabled={ !!!this.props.data.length } />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using !!! is not a good practice — what you basically do is converting a number to a boolean with the !! and checking the opposite value. In JS you can use just number to check for true or false. If the number is 0 — it's a false value, if > 0 — it's a true value.

<div className="card">
<div className="title-common">LOGS</div>
<LogFilterButton onClick={ () => this.performFilterSearch("level:verbose") } text="Verbose" disabled={ !!!this.props.data.length } />
<LogFilterButton onClick={ () => this.performFilterSearch("level:debug") } text="Debug" disabled={ !!!this.props.data.length } />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use smth more than 1 time — put it into a variable.


componentWillReceiveProps(props) {
let data = props.data;
if (data === this.state.data) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code will always result in false, please read the JS documentation on how arrays works.

@tokou
Copy link
Author

tokou commented Jul 9, 2018

Hi @navstyachka
Thanks for your detailed review.
As you have guessed I am not really a react dev but an Android dev that wanted to contribute.
I will take the time to make corrections based on your review.
I understand that it is not possible to merge the PR even after the corrections.
As I said in previous comments, I tried other approaches but they all resulted in performance problems when logs get large.
I would be interested to explore other approaches if you have any suggestions.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants