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

Feature/logs paging active #318

Merged
merged 13 commits into from
May 24, 2018
Merged

Feature/logs paging active #318

merged 13 commits into from
May 24, 2018

Conversation

jordibc
Copy link
Contributor

@jordibc jordibc commented Apr 24, 2018

Add a "get more logs" button that loads logs from previous pages.

There are no changes to the dataStore configuration, we just use it appropriately in the main application to show older logs on request.

It introduces two new variables to the status:
  logsFilter: function that selects the relevant logs (we use it
    to show only the logs that include the selected datasets).
  logsPageLast: index of the last page that we have retrieved so far.

The Log dialog now contains a new action, a flat button that allows
it to load logs from previous pages.

There are new semantics for the getLogs() function: if it returns
null, then there are no more log pages (so we do not need to request
more). Also, the pages are a positive number, that is, page 1 is the
page previous to the last one (instead of it being page -1).
Remove the optimization for not retrieving the dataStore multiple
times unnecessarily. It turns out that it is negligible, and thus
it is better to have a simpler code.
So, when concatenated, the position of the last log is predictable
(it is in position 0), and also of the most recent log (it is in
the last position of the array).
When requesting a new log page in the log dialog, it will
now show a button that includes the date of the last log
retrieved so far.
So we show the correct date in the button to get older log pages.
@adrianq adrianq requested a review from tokland May 16, 2018 09:05
@@ -74,6 +74,10 @@ const DataSets = React.createClass({
};
},

tr(text, variables={}) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Very minor: variables={} is idiomatic Python for keyword args, but AFAIK in JS is idiomatic to write the spaces: variables = {}

if (Array.isArray(datasets)) {
const ids = datasets.map(ds => ds.id);
const idsSet = new Set(ids);
this.state.logsFilter = log => log.datasets.some(ds => idsSet.has(ds.id));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Imperatively modifying this.state is forbidden in React (except the initial set in a constructor) -> this.setState({...}).

}

let title = this.tr("logs");
if (Array.isArray(datasets)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This kind of checks is a hint that a refactor is needed. I see openLogs is called on the global button onClick, it gets the mouse event, which is what is being compared here. I'd create a separate openAllLogs method for that action.

addLogs(pages) {
// Add logs from the given log pages (to the already loaded logs if any).
if (!Array.isArray(pages))
pages = [this.state.logsPageLast + 1];
Copy link
Collaborator

Choose a reason for hiding this comment

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

To avoid this check+rebinding of pages, we can make sure the caller sends the correct values. I think the check is needed in onClick={this.addLogs}.

this.setState({logsPageLast: -1});
} else {
const logsOldestDate = logs.length > 0 ? logs[logs.length - 1].date : null;
logs = _(logs).filter(this.state.logsFilter).value();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Avoid rebinding/reuse of variables, create new const values with descriptive names -> const filteredLogs = ...

@@ -303,21 +332,37 @@ const DataSets = React.createClass({

const logActions = [
<FlatButton
label={this.getTranslation('close')}
label={(this.state.logsPageLast < 0 ? this.tr("logs_no_older") : this.tr("logs_older")) +
Copy link
Collaborator

Choose a reason for hiding this comment

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

Too much logic for a prop, we can use a variable.

const store = await getStore();
const logsPageCurrent = await store.get('logs-page-current').catch(() => 0);
const pagesNames = pages.map(n => 'logs-page-' + mod(logsPageCurrent - n, maxLogPages));
const logs = await Promise.all(pagesNames.map(name => store.get(name).catch(() => null)));
Copy link
Collaborator

Choose a reason for hiding this comment

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

I've seen there is a way to avoid 404 on non-existing pages. The store has a method to get the current keys. Thus we could also remove the catch, which might mask real problems (network issues/implementation bugs). Just an idea:

const storeKeys = new Set(await store.getKeys());
const existingPageNames = pagesNames.filter(name => storeKeys.has(name));
const logs = await Promise.all(existingPageNames.map(name => store.get(name)));

@@ -303,21 +332,37 @@ const DataSets = React.createClass({

const logActions = [
<FlatButton
label={this.getTranslation('close')}
label={(this.state.logsPageLast < 0 ? this.tr("logs_no_older") : this.tr("logs_older")) +
Copy link
Collaborator

@tokland tokland May 17, 2018

Choose a reason for hiding this comment

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

Related to the 404 avoidance for non-existing pages, I was thinking we could use the same idea: since we already know the existing pages in the store, we can hide the button if we are sure there is no more data to load.

@@ -303,21 +332,37 @@ const DataSets = React.createClass({

const logActions = [
<FlatButton
Copy link
Collaborator

@tokland tokland May 17, 2018

Choose a reason for hiding this comment

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

A question about the UX, @adrianq : does it make sense to move this action inside the logs box, as a center button? this way the user only sees it when it really makes sense.

@adrianq
Copy link
Member

adrianq commented May 17, 2018

@tokland I talked to @jordibc and it looks like he is not gonna have time before Tuesday for this. Can you please implement the changes yourself in this branch? I will make a final review afterwards and have a look at the UX...

- Apply styling (spaces/indent)
- Create wrapper methods openAllLogs/addNextLog
- Render loadMoreLogs button only if necessary
- Move loadMoreLogs button to logs list
- Abstract logs.getCurrentPage
- Refactor getLogs
- Fix: Clear always next page in the circular buffer
- Format date in logs rendering.
@tokland
Copy link
Collaborator

tokland commented May 18, 2018

I've applied all my proposed changes and some extra refactor.

Also implements the "sharing: save only on changes" feature, which requires EyeSeeTea/d2-ui#20

@tokland
Copy link
Collaborator

tokland commented May 23, 2018

Task "Sharing: Move logging to parent component, so it logs only once when dialog is closed." -> Done. Ready to test again.

@adrianq adrianq merged commit 7333909 into development May 24, 2018
@adrianq adrianq removed the testing label May 24, 2018
@adrianq adrianq deleted the feature/logs-paging-active branch May 10, 2019 08:35
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