Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add pagination to results table #96

Merged
merged 18 commits into from
Apr 20, 2020
Merged

add pagination to results table #96

merged 18 commits into from
Apr 20, 2020

Conversation

KWMORALE
Copy link
Member

@KWMORALE KWMORALE commented Apr 15, 2020

Close issue #39 #37

@KWMORALE KWMORALE requested a review from msm-code April 15, 2020 14:16
@ITAYC0HEN
Copy link
Collaborator

For some reason, I can't make it work with docker-compose.dev.yml:

dev-frontend_1  | Starting the development server...
dev-frontend_1  | 
dev-frontend_1  | Failed to compile.
dev-frontend_1  | 
dev-frontend_1  | ./src/QueryResultsStatus.js
dev-frontend_1  | Module not found: Can't resolve 'react-js-pagination' in '/app/src'

but it does work with the regular one :) The solution looks good in terms of UI, and anything else :D
I want to test it when running a query but all my 3 instances are broken now :(

Good work!

@msm-code
Copy link
Contributor

@ITAYC0HEN had the same problem, you need to do a rebuild first (docker-compose -f docker-compose.dev.yml build). That's because this PR adds a new npm dependency (react-js-pagination).

@msm-code
Copy link
Contributor

Looks good!

But there are a few things that don't make sense after this change:

  • query page will still try to load every result in memory (I've opened the page, and it downloaded all 10k results even though I just stayed on the first page) - it should be downloaded lazily on-demand

  • query page should display the number of results instead of displaying numbre of downloaded results. This is already a part of a different issue ( Mquery is counting results when displaying previous jobs #37 ), so if you don't feel like it feel free to fix it in a different PR.

@ITAYC0HEN
Copy link
Collaborator

@ITAYC0HEN had the same problem, you need to do a rebuild first (docker-compose -f docker-compose.dev.yml build). That's because this PR adds a new npm dependency (react-js-pagination).

Thanks, fixed this :)

Copy link
Contributor

@msm-code msm-code left a comment

Choose a reason for hiding this comment

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

Please try to use lazy loading in the table

@ITAYC0HEN
Copy link
Collaborator

If you're up for lazy load then you can reconsider pagination in favor of. lazy load scrolling (like Facebook, Twitter feeds, VT results)

@msm-code
Copy link
Contributor

You forgot mwdb!

Yeah, that's a viable solution too. Anything that will make it possible to reduce a number of queries to the backend for a finished large query.

I prefer paging, but I can see lazy load working here too.

@KWMORALE KWMORALE marked this pull request as draft April 16, 2020 12:34
@KWMORALE KWMORALE requested a review from msm-code April 17, 2020 14:00
@KWMORALE KWMORALE marked this pull request as ready for review April 17, 2020 14:04
});

if (newShouldRequest) {
let nextTimeout =
Copy link
Contributor

Choose a reason for hiding this comment

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

Querying every 50ms may be too extreme. Maybe just hardcode this to 1000ms?

})
.catch(() => {
this.setState({
shouldRequest: false,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this variable used anywhere? If not, we can remove this safely.


if (
["done", "cancelled", "failed", "expired"].indexOf(
response.data.job.status
Copy link
Contributor

Choose a reason for hiding this comment

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

response.data.job probably can be made a local variable

.then((response) => {
let newShouldRequest = true;

if (
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe move setState above this, and return in if, instead of using a temprary vraiable here?

Comment on lines 113 to 115
let newShouldRequest = true;

if (
["done", "cancelled", "failed", "expired"].indexOf(
response.data.job.status
) !== -1
) {
if (response.data.job.files_processed >= response.data.job.total_files) {
newShouldRequest = false;
}
}

this.setState({
job: response.data.job,
});

if (newShouldRequest) {
let nextTimeout =
response.data.matches.length >= LIMIT ? 50 : 1000;
this.timeout = setTimeout(
() => this.loadJob(),
nextTimeout
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

All my suggestions in one comment:

Suggested change
let newShouldRequest = true;
if (
["done", "cancelled", "failed", "expired"].indexOf(
response.data.job.status
) !== -1
) {
if (response.data.job.files_processed >= response.data.job.total_files) {
newShouldRequest = false;
}
}
this.setState({
job: response.data.job,
});
if (newShouldRequest) {
let nextTimeout =
response.data.matches.length >= LIMIT ? 50 : 1000;
this.timeout = setTimeout(
() => this.loadJob(),
nextTimeout
);
}
let job = response.data.job;
this.setState({
job: job,
matches: response.data.matches,
});
let doneStatuses = ["done", "cancelled", "failed", "expired"];
let isDone = doneStatuses.indexOf(job.status) !== -1;
let processedAll = job.files_processed >= job.total_files;
if (isDone && processedAll) {
return;
}
this.timeout = setTimeout(() => this.loadJob(), 1000);

Copy link
Contributor

Choose a reason for hiding this comment

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

After this rewrite it also shows a bug (that I think was there even before your changes) - if the job is cancelled/failed but it didn't process all files, mquery will keep querying the backend. Maybe it should be || instead of &&?

@@ -63,13 +64,29 @@ class QueryResultsStatus extends Component {
constructor(props) {
super(props);

this.state = {
activePage: 1,
itemPerPage: 20,
Copy link
Contributor

Choose a reason for hiding this comment

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

Plural:

Suggested change
itemPerPage: 20,
itemsPerPage: 20,


if (this.props.job.status === "expired") {
return ReturnExpiredJob(this.props.job.error);
}

// var indexOfLastMatch = this.state.activePage * this.state.itemPerPage;
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove unnecessary comments

<div>
<Pagination
activePage={this.state.activePage}
itemsCountPerPage={this.state.itemPerPage}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
itemsCountPerPage={this.state.itemPerPage}
itemsCountPerPage={this.state.itemsPerPage}

handlePageChange(pageNumber) {
this.setState({ activePage: pageNumber });
this.sendResultsActivePage(pageNumber);

Copy link
Contributor

Choose a reason for hiding this comment

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

unnecessary empty line


loadMatches() {
const LIMIT = 20;
let OFFSET = (this.state.activePage - 1) * 20 + 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why +1?

@msm-code
Copy link
Contributor

Nitpick: doing a new query should reset active page number (if i go to the 8th page, run a new query, pagination will automatically start at the 8th page)

@msm-code
Copy link
Contributor

And also: please rebase your changes on the master, since there are merge conflicts

src/app.py Outdated
Comment on lines 141 to 142
files_processed=job.get("files_processed", 0),
files_matched=job.get("files_matched", 0),
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
files_processed=job.get("files_processed", 0),
files_matched=job.get("files_matched", 0),
files_processed=int(job.get("files_processed", 0)),
files_matched=int(job.get("files_matched", 0)),

@KWMORALE KWMORALE requested a review from msm-code April 17, 2020 18:24
@@ -164,6 +184,19 @@ class QueryResultsStatus extends Component {
</thead>
<tbody>{matches}</tbody>
</table>
{lenMatches > 20 && (
<div>
Copy link
Contributor

Choose a reason for hiding this comment

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

I think div is unnecessary here?

@KWMORALE KWMORALE requested a review from msm-code April 20, 2020 09:01
let doneStatuses = ["done", "cancelled", "failed", "expired"];
let isDone = doneStatuses.indexOf(job.status) !== -1;
let processedAll = job.files_processed >= job.total_files;
if (isDone && processedAll) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Still &&? If nothing else changed, this will cause infinite loop of requests.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've also confirmed it locally. Test plan:

  • start a big query
  • stop it in a middle such that files_processed < total_files (remember that they're strings)
  • observe that requests are repeated in the loop every 1s

Copy link
Contributor

@msm-code msm-code left a comment

Choose a reason for hiding this comment

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

good to go as soon as tests pass

@msm-code msm-code merged commit fe49b19 into master Apr 20, 2020
@msm-code msm-code deleted the feature/pagination branch April 20, 2020 15:16
KWMORALE added a commit to KWMORALE/mquery that referenced this pull request Jul 29, 2020
* Add pagination to results table
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants