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
Conversation
There was a problem hiding this 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.
public/app/plugins/datasource/loki/querybuilder/components/LabelBrowserModal.tsx
Outdated
Show resolved
Hide resolved
}} | ||
</LocalStorageValueProvider> | ||
{!labelsLoaded && <LoadingPlaceholder text="Loading labels..." />} | ||
{!hasLogLabels && <p>No labels found.</p>} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{!hasLogLabels && <p>No labels found.</p>} | |
{labelsLoaded && !hasLogLabels && <p>No labels found.</p>} |
Should this be this?
There was a problem hiding this comment.
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:
{!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> | |
); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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>
);
There was a problem hiding this comment.
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}>
.
There was a problem hiding this comment.
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>
);```
public/app/plugins/datasource/loki/querybuilder/components/LabelBrowserModal.tsx
Outdated
Show resolved
Hide resolved
const hasLogLabels = datasource.languageProvider.getLabelKeys().length > 0; | ||
|
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
What is this feature?
this PR improves how the new loki label browser modal works.
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:
...