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

Loki: Add improvements to loki label browser #59387

Merged
merged 5 commits into from Nov 29, 2022

Conversation

gwdawson
Copy link
Member

What is this feature?
this PR improves how the new loki label browser modal works.

  • rather than disabling the button, we now display the error inside the modal
  • improve the code quality of this component

Why do we need this feature?
following my first pr (#58525), i received some feedback with these improvements.

Who is this feature for?
...

Which issue(s) does this PR fix?:
...

Special notes for your reviewer:
...

@gwdawson gwdawson added add to changelog no-backport Skip backport of PR labels Nov 28, 2022
@gwdawson gwdawson added this to the 9.3.0 milestone Nov 28, 2022
@gwdawson gwdawson requested a review from a team as a code owner November 28, 2022 12:12
@gwdawson gwdawson self-assigned this Nov 28, 2022
Copy link
Member

@ivanahuckova ivanahuckova left a comment

Choose a reason for hiding this comment

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

Nice! Left some feedback related to implementation logic of loading labels within browser.

@gwdawson gwdawson requested review from ivanahuckova and a team November 29, 2022 09:52
}}
</LocalStorageValueProvider>
{!labelsLoaded && <LoadingPlaceholder text="Loading labels..." />}
{!hasLogLabels && <p>No labels found.</p>}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
{!hasLogLabels && <p>No labels found.</p>}
{labelsLoaded && !hasLogLabels && <p>No labels found.</p>}

Should this be this?

Copy link
Contributor

Choose a reason for hiding this comment

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

That's why sometimes we prefer ternaries over all these booleans:

Suggested change
{!hasLogLabels && <p>No labels found.</p>}
return (
<Modal isOpen={isOpen} title="Label browser" onDismiss={onClose}>
{!labelsLoaded ? (
<LoadingPlaceholder text="Loading labels..." />
) : (
<>
{!hasLogLabels ? (
<p>No labels found.</p>
) : (
<LocalStorageValueProvider<string[]> storageKey={LAST_USED_LABELS_KEY} defaultValue={[]}>
{(lastUsedLabels, onLastUsedLabelsSave, onLastUsedLabelsDelete) => {
return (
<LokiLabelBrowser
languageProvider={datasource.languageProvider}
onChange={onChange}
lastUsedLabels={lastUsedLabels}
storeLastUsedLabels={onLastUsedLabelsSave}
deleteLastUsedLabels={onLastUsedLabelsDelete}
app={app}
/>
);
}}
</LocalStorageValueProvider>
)}
</>
)}
</Modal>
);

Copy link
Member Author

Choose a reason for hiding this comment

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

@matyax something like this was my initial thought but i'm not a huge fan on nested ternaries.

Copy link
Contributor

Choose a reason for hiding this comment

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

When you start seeing these piling up it's usually a better option:

imagen

Copy link
Contributor

@svennergr svennergr Nov 29, 2022

Choose a reason for hiding this comment

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

Imo just using early returns could offer best readability here, even though you may need to repeat <Modal isOpen={isOpen} title="Label browser" onDismiss={onClose}> lines.

e.g.:

if (!labelsLoaded) {
    return (
      <Modal isOpen={isOpen} title="Label browser" onDismiss={onClose}>
        <LoadingPlaceholder text="Loading labels..." />
      </Modal>
    );
  }
  if (!hasLogLabels) {
    return (
      <Modal isOpen={isOpen} title="Label browser" onDismiss={onClose}>
        <p>No labels found.</p>
      </Modal>
    );
  }
  return (
    <Modal isOpen={isOpen} title="Label browser" onDismiss={onClose}>
      <LocalStorageValueProvider<string[]> storageKey={LAST_USED_LABELS_KEY} defaultValue={[]}>
        {(lastUsedLabels, onLastUsedLabelsSave, onLastUsedLabelsDelete) => {
          return (
            <LokiLabelBrowser
              languageProvider={datasource.languageProvider}
              onChange={onChange}
              lastUsedLabels={lastUsedLabels}
              storeLastUsedLabels={onLastUsedLabelsSave}
              deleteLastUsedLabels={onLastUsedLabelsDelete}
              app={app}
            />
          );
        }}
      </LocalStorageValueProvider>
    </Modal>
  );

Copy link
Contributor

Choose a reason for hiding this comment

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

That's also a good option. What I don't like about that is 1) mounting and unmounting a Modal component during a transition (loading -> loaded with or without labels) and 2) having to 3x <Modal isOpen={isOpen} title="Label browser" onDismiss={onClose}>.

Copy link
Member

Choose a reason for hiding this comment

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

Then what about keeping modal, just changing the modal content:

  const LogBrowserContent = () => {
    if (!labelsLoaded) {
      return <LoadingPlaceholder text="Loading labels..." />;
    }

    if (labelsLoaded && !hasLogLabels) {
      return <div>No labels found.</div>;
    }

    return (
      <LocalStorageValueProvider<string[]> storageKey={LAST_USED_LABELS_KEY} defaultValue={[]}>
        {(lastUsedLabels, onLastUsedLabelsSave, onLastUsedLabelsDelete) => {
          return (
            <LokiLabelBrowser
              languageProvider={datasource.languageProvider}
              onChange={onChange}
              lastUsedLabels={lastUsedLabels}
              storeLastUsedLabels={onLastUsedLabelsSave}
              deleteLastUsedLabels={onLastUsedLabelsDelete}
              app={app}
            />
          );
        }}
      </LocalStorageValueProvider>
    );
  };

  return (
    <Modal isOpen={isOpen} title="Label browser" onDismiss={onClose}>
      <LogBrowserContent />
    </Modal>
  );```
  

Comment on lines 48 to 49
const hasLogLabels = datasource.languageProvider.getLabelKeys().length > 0;

Copy link
Contributor

Choose a reason for hiding this comment

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

This is still not in a place where the languageProvider was definitely started, or at least finished starting. Best would be to move this to the useEffect callback.

Copy link
Contributor

@svennergr svennergr left a comment

Choose a reason for hiding this comment

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

LGTM. I am unsure if @matyax has strong opinions about the structure of the components though.

@matyax
Copy link
Contributor

matyax commented Nov 29, 2022

imagen

I think this is not ideal, but it's still valid react, so 👍

@gwdawson gwdawson merged commit 6b5ebf2 into main Nov 29, 2022
@gwdawson gwdawson deleted the gareth/improve-loki-label-browser branch November 29, 2022 14:07
@gwdawson gwdawson modified the milestones: 9.3.0, 9.4.0 Nov 30, 2022
@dsotirakis dsotirakis modified the milestones: 9.4.0, 9.4.0-beta1 Jan 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants