-
Notifications
You must be signed in to change notification settings - Fork 19
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
Feat: improve delete private probe flow #951
Conversation
- remove redundant variables - clean-up unneeded if-statements
- add `ConfirmModal` that supports async confirm (including errors/catch). - add business logic to avoid error when trying to delete probe that is in use
…s-handling # Conflicts: # src/components/ProbeEditor/ProbeEditor.tsx # src/page/EditProbe/EditProbe.tsx # src/test/fixtures/probes.ts
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.
self-review 👍🏻
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.
Really nice improvement! Love how it looks now 💯 💯 💯
I left a few comments/questions.
@@ -42,6 +37,20 @@ export class SMDataSource extends DataSourceApi<SMQuery, SMOptions> { | |||
super(instanceSettings); | |||
} | |||
|
|||
async fetchAPI<T>(url: BackendSrvRequest['url'], options?: Omit<BackendSrvRequest, 'url'>) { |
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 addition!
src/datasource/DataSource.ts
Outdated
}) | ||
).then((res) => { | ||
return res.data; | ||
return this.fetchAPI(`${this.instanceSettings.url}/sm/probe/add`, { |
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.
Can we type it as we do above? Like this.fetchAPI<AddProbeResult>(`${this.instanceSettings.url}/sm/probe/add`, {
Same question for all other calls where the type is not set when calling fetchAPI
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.
If the type is missing, it's because it was also missing previously.
I will take a look at how the usage trickles down, and update with types.
@@ -50,6 +50,8 @@ export class SMDataSource extends DataSourceApi<SMQuery, SMOptions> { | |||
...options, | |||
}) | |||
).catch((error: unknown) => { | |||
// We could log the error here |
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.
Yeah, I think this is a good idea
While I agree that the error message could look better, I wouldn't focus on this particular error message, as it results from modifying code. Ideally, this error shouldn't be shown to a user of the app (unless someone starts using a probe while another one tries to delete it). We could definitely upper case first letter of the |
@VikaCep how about this?
|
- Add missing type in `DataSource.fetchAPI` usage - Fragment code to make it more readable - Upper case first letter in `ConfirmModal` - Refactor `DeleteProbeButton`
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.
Mostly nitty nits. A few other comments but on a whole this is ace 💪
<Alert className={styles.alert} title={error?.name ?? `${title} error`} severity="error"> | ||
<div>{error?.message ?? GENERIC_ERROR_MESSAGE}</div> |
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.
Nittiest of nits: Don't need the optional chaining for error?.name
or error?.message
here or you need to update the ConfirmError
type to allow them to be optional.
); | ||
|
||
return ( | ||
<Tooltip content={tooltipContent} interactive={canEdit && !canDelete}> |
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.
You can add the tooltip
prop directly to button now and it works better for accessibility as it becomes keyboard accessible and reads out the tooltip despite the button being 'disabled'.
With that said, I don't love the link in the tooltip as Grafana doesn't support accessing interactive content via the keyboard in tooltips but as there is an alternative presentation of the link in the sidebar this is okay 😄
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.
I had to use both the Tooltip
component and the tooltip
prop 😓
With only the prop, the tooltip isn't interactable
With disabled on the Button
there is no focus (unless aria-disabled
is used, which is only possible when tooltip
is truthy).
const { history, user } = render(<ProbeCard probe={probe} />); | ||
await screen.findByText(probe.name); | ||
await user.click(screen.getByText(probe.name)); | ||
expect(history.location.pathname).toBe(`${getRoute(ROUTES.EditProbe)}/${probe.id}`); | ||
}); | ||
|
||
it.each<[ExtendedProbe, string]>([ |
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.
TIL. I always manually looped over when I wanted to do something like this 😅
<Card className={styles.card} href={href}> | ||
<div className={styles.cardContent}> | ||
<Card> | ||
<Card.Heading> |
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.
I am torn on moving back to using @grafana/ui's Card
component. IMO they have painted themselves into a corner with how prescriptive it is and it is doing way more work than what I would expect a Design System's card to provide.
I think you've done a good job with what they provide here but I do hate that the heading is a h2 regardless as I'd flag this as an accessibility issue on this page when doing an audit. We could probably add props to the Card.Heading
upstream in grafana/grafana to fix this at a later date so can leave it but just want to flag why I made a local Card
component in the first place.
Last comment but I don't think this is for this PR but future enhancements for the probes UI. I was experimenting with what happens when I:
Some things for us to do in the future 😃 |
- Remove optional chaining
- Remove optional chaining - Remove commented code - Navigate to probe list on delete success - Make tooltip accessible
- Remove unused styles - Add test id to `dataTestIds.ts`
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 🔥🔥🔥
What this PR does / why we need it:
This PR aims to improve the management of probes, including better error handling (specifically when deleting probes). Probe listing now uses more of the components shipped by
@grafana/ui
, which (hopefully) will allow for the view to be more in line with Grafana.UI has been updated in collaboration with the design dep. It's intended to be good enough, until a potential UI overhaul.
Probe Listing
Updates:
Probe delete button
Updates:
Confirm modal (async)
Updates:
ConfirmModal
async
is not present orfalse
, theConfirmModal
from@grafana/ui
is returnedasync
@grafana/ui
is returned instead.onConfirm
callback is.catch
ed by the modalonError
is passed, the error message can be handled (and passed as prob) from the outsideonError
is not passed, the component tries to use.name
and.message
from the caught error (with generic fallbacks).Additional fixes and refactoring
DataSource.fetchAPI
was added to keep the code bit more DRYWhich issue(s) this PR fixes:
Fixes https://github.com/grafana/synthetic-monitoring/issues/97
Special notes for your reviewer:
To trigger error handling for the
ConfirmDialog
, change line 48 inDeleteProbeButton
fromif (!canDelete) {
toif (!!canDelete) {
(which will allow you to press the delete button for probes that are in use). You can also usetweak
if you want to go all-in on testing different types of errors/responses