Skip to content

Update the snackbar notification design#46126

Merged
bl-nero merged 17 commits intomasterfrom
bl-nero/notifications
Sep 9, 2024
Merged

Update the snackbar notification design#46126
bl-nero merged 17 commits intomasterfrom
bl-nero/notifications

Conversation

@bl-nero
Copy link
Copy Markdown
Contributor

@bl-nero bl-nero commented Sep 2, 2024

Screenshot 2024-09-05 at 14 17 05 Screenshot 2024-09-05 at 14 19 13 Screenshot 2024-09-02 at 16 55 28 Screenshot 2024-09-02 at 16 55 34

Figma

Contributes to #45977
Requires #45973 (because I use the exported Action interface here).
Followed up by https://github.com/gravitational/teleport.e/pull/4972

bl-nero and others added 11 commits August 28, 2024 17:36
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Sep 2, 2024

The PR changelog entry failed validation: Changelog entry not found in the PR body. Please add a "no-changelog" label to the PR, or changelog lines starting with changelog: followed by the changelog entries for the PR.

@bl-nero
Copy link
Copy Markdown
Contributor Author

bl-nero commented Sep 2, 2024

Note: I'm not closing the issue just yet with this PR; there's an opportuinity to (1) improve the desktop viewer that doesn't adhere to our UI patterns here, and (2) make it generally much easier to use the notifications in web UI by moving the notification service from Teleterm to shared components. I'll address this after I deal with more important work from the UX design bucket.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Sep 2, 2024

The PR changelog entry failed validation: Changelog entry not found in the PR body. Please add a "no-changelog" label to the PR, or changelog lines starting with changelog: followed by the changelog entries for the PR.

@bl-nero
Copy link
Copy Markdown
Contributor Author

bl-nero commented Sep 2, 2024

Manual testing: tested the notifications on account settings screen, Teleport Connect app, and desktop session.

@bl-nero bl-nero added the no-changelog Indicates that a PR does not require a changelog entry label Sep 2, 2024
Comment thread web/packages/shared/components/Notification/Notification.tsx
@bl-nero
Copy link
Copy Markdown
Contributor Author

bl-nero commented Sep 4, 2024

Addressed Rafał's feedback and corrected the plain string case (there was a separate design for this case in the Figma deck that I didn't catch).

Copy link
Copy Markdown
Member

@ravicious ravicious left a comment

Choose a reason for hiding this comment

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

Looks good overall, I submitted a couple of minor suggestions, with the one about putting single strings into title rather than description being almost major.

Comment thread web/packages/shared/components/Notification/Notification.tsx Outdated
Comment thread web/packages/shared/components/Notification/Notification.tsx
Comment thread web/packages/shared/components/Notification/Notification.tsx Outdated

export type NotificationItemObjectContent = {
title: string;
title?: string;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We used to enforce that at least title is always present. This type here makes it legal to create a notification with pretty an empty content because every field is optional.

What if we still enforced some minimum required fields?

export type NotificationItemObjectContent = (
  | { title: string; subtitle?: string; description?: string }
  | { description: string; title?: undefined; subtitle?: undefined }
) & {
  list?: string[];
  icon?: React.ComponentType<IconProps>;
  action?: Action;
};

This type forces you to always provide at least title and other fields or just description. I think that's the intention behind toObjectContent. The type also does not allow you to provide description and subtitle but no title, which is what we want to avoid, I think.

If we go with this type, there's one example in the story which actually breaks it, the notification with a list and nothing else.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I agree that we might make it more strict, but think that this level of complexity is a bit of an overkill here. I'm a bit afraid that if we make it this complex, it's gonna bubble up the type hierarchy in unpredictable ways and cause errors with very confusing messages. For now, I'm fine with a risk of someone creating an empty notification. Am I missing something obvious here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's true that the error messages generated by this type might end up being confusing. When I'm considering this tradeoff myself, I usually brush off the problem with error messages by believing that TypeScript will only improve its error messages over time [1], whereas we can enforce more safety through types right now.

When I encounter a confusing type error, I usually try to look up its source, which in this case would guide me towards a fix. The error message gets kind of better when we give names to individual types, but it's still far from perfect.

Types with names
type TitleWithOptionalSubtitleAndDescription = {
  title: string;
  subtitle?: string;
  description?: string;
};

type DescriptionOnly = {
  description: string;
  title?: undefined;
  subtitle?: undefined;
};

export type NotificationItemObjectContent = (
  | TitleWithOptionalSubtitleAndDescription
  | DescriptionOnly
) & {
  list?: string[];
  icon?: React.ComponentType<IconProps>;
  action?: Action;
};
        <Notification
          …
            content: {
              subtitle: 'siemka',
            },
        />


web/packages/shared/components/Notification/Notification.story.tsx:69:13 - error TS2322: Type '{ subtitle: string; }' is not assignable to type 'NotificationItemContent'.
  Type '{ subtitle: string; }' is not assignable to type 'TitleWithOptionalSubtitleAndDescription & { list?: string[]; icon?: ComponentType<IconProps>; action?: Action; }'.
    Property 'title' is missing in type '{ subtitle: string; }' but required in type 'TitleWithOptionalSubtitleAndDescription'.

69             content: {
               ~~~~~~~

  web/packages/shared/components/Notification/types.ts:39:3
    39   title: string;
         ~~~~~
    'title' is declared here.
  web/packages/shared/components/Notification/types.ts:31:3
    31   content: NotificationItemContent;
         ~~~~~~~
    The expected type comes from property 'content' which is declared here on type 'NotificationItem'

It's fine if you want to go for optional types though. If we find that the lack of them poses a real problem, we can always add them in the future, which shouldn't require big changes.

[1]: Because in my mind it's their duty to catch up to where Elm and Rust were years ago. Which might not actually be true, hence "believing". 😶

Comment thread web/packages/shared/components/Notification/Notification.tsx Outdated
Comment thread web/packages/shared/components/Notification/Notification.tsx Outdated
@bl-nero
Copy link
Copy Markdown
Contributor Author

bl-nero commented Sep 5, 2024

@ravicious Changed the string-only default to title-only, got rid of the unnecessary space, but pushing back on the type changes. PTAL.

@bl-nero bl-nero requested a review from ravicious September 5, 2024 12:21

export type NotificationItemObjectContent = {
title: string;
title?: string;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It's true that the error messages generated by this type might end up being confusing. When I'm considering this tradeoff myself, I usually brush off the problem with error messages by believing that TypeScript will only improve its error messages over time [1], whereas we can enforce more safety through types right now.

When I encounter a confusing type error, I usually try to look up its source, which in this case would guide me towards a fix. The error message gets kind of better when we give names to individual types, but it's still far from perfect.

Types with names
type TitleWithOptionalSubtitleAndDescription = {
  title: string;
  subtitle?: string;
  description?: string;
};

type DescriptionOnly = {
  description: string;
  title?: undefined;
  subtitle?: undefined;
};

export type NotificationItemObjectContent = (
  | TitleWithOptionalSubtitleAndDescription
  | DescriptionOnly
) & {
  list?: string[];
  icon?: React.ComponentType<IconProps>;
  action?: Action;
};
        <Notification
          …
            content: {
              subtitle: 'siemka',
            },
        />


web/packages/shared/components/Notification/Notification.story.tsx:69:13 - error TS2322: Type '{ subtitle: string; }' is not assignable to type 'NotificationItemContent'.
  Type '{ subtitle: string; }' is not assignable to type 'TitleWithOptionalSubtitleAndDescription & { list?: string[]; icon?: ComponentType<IconProps>; action?: Action; }'.
    Property 'title' is missing in type '{ subtitle: string; }' but required in type 'TitleWithOptionalSubtitleAndDescription'.

69             content: {
               ~~~~~~~

  web/packages/shared/components/Notification/types.ts:39:3
    39   title: string;
         ~~~~~
    'title' is declared here.
  web/packages/shared/components/Notification/types.ts:31:3
    31   content: NotificationItemContent;
         ~~~~~~~
    The expected type comes from property 'content' which is declared here on type 'NotificationItem'

It's fine if you want to go for optional types though. If we find that the lack of them poses a real problem, we can always add them in the future, which shouldn't require big changes.

[1]: Because in my mind it's their duty to catch up to where Elm and Rust were years ago. Which might not actually be true, hence "believing". 😶

@bl-nero
Copy link
Copy Markdown
Contributor Author

bl-nero commented Sep 5, 2024

@ravicious Thanks for the type naming trick, I'll keep it in mind the next time when I'll need to get creative with the type system. :)

(Oh, yes, if we had a Rust-level error experience, life would be so much easier.)

@public-teleport-github-review-bot
Copy link
Copy Markdown

@bl-nero - this PR will require admin approval to merge due to its size. Consider breaking it up into a series smaller changes.

@bl-nero bl-nero changed the base branch from bl-nero/banners-ui to master September 6, 2024 13:19
@bl-nero
Copy link
Copy Markdown
Contributor Author

bl-nero commented Sep 6, 2024

Sorry for the mess, I accidentally merged master into it before merging the dependency.

@bl-nero bl-nero added this pull request to the merge queue Sep 9, 2024
Merged via the queue into master with commit 4464ef9 Sep 9, 2024
@bl-nero bl-nero deleted the bl-nero/notifications branch September 9, 2024 10:17
@public-teleport-github-review-bot
Copy link
Copy Markdown

@bl-nero See the table below for backport results.

Branch Result
branch/v16 Failed

mvbrock pushed a commit that referenced this pull request Sep 10, 2024
* Add an alert CTA label

This label allows to customize text on a button that contains the alert
link.

* Comment

* Use the new alert CTA label to display a link button

The link button replaces current visual representation of a cluster
alert, where the entire alert message is a link.

* Update api/types/cluster_alert.go

Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>

* Rename CTA to "link text"

* Rename CTA to "link text"

* review

* Remove unnecessary functions

* Update the snackbar notification design

* Review

* Review

* Get rid of min-height

* Revert e/ update

---------

Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog Indicates that a PR does not require a changelog entry size/sm ui

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants