This repository has been archived by the owner on Feb 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 219
Storybook and TS migration of ErrorPlaceholder
component
#5294
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
assets/js/editor-components/error-placeholder/stories/error-message.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { Story, Meta } from '@storybook/react'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import ErrorMessage, { ErrorMessageProps } from '../error-message'; | ||
|
||
export default { | ||
title: 'WooCommerce Blocks/editor-components/Errors/Base Error Atom', | ||
component: ErrorMessage, | ||
} as Meta< ErrorMessageProps >; | ||
|
||
const Template: Story< ErrorMessageProps > = ( args ) => ( | ||
<ErrorMessage { ...args } /> | ||
); | ||
|
||
export const BaseErrorAtom = Template.bind( {} ); | ||
BaseErrorAtom.args = { | ||
error: { | ||
message: | ||
'A very generic and unhelpful error. Please try again later. Or contact support. Or not.', | ||
type: 'general', | ||
}, | ||
}; |
70 changes: 70 additions & 0 deletions
70
assets/js/editor-components/error-placeholder/stories/error-placeholder.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { Story, Meta } from '@storybook/react'; | ||
import { useArgs } from '@storybook/client-api'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import ErrorPlaceholder, { ErrorPlaceholderProps } from '..'; | ||
|
||
export default { | ||
title: 'WooCommerce Blocks/editor-components/Errors', | ||
component: ErrorPlaceholder, | ||
} as Meta< ErrorPlaceholderProps >; | ||
|
||
const Template: Story< ErrorPlaceholderProps > = ( args ) => { | ||
const [ { isLoading }, setArgs ] = useArgs(); | ||
|
||
const onRetry = args.onRetry | ||
? () => { | ||
setArgs( { isLoading: true } ); | ||
|
||
setTimeout( () => setArgs( { isLoading: false } ), 3500 ); | ||
} | ||
: undefined; | ||
|
||
return ( | ||
<ErrorPlaceholder | ||
{ ...args } | ||
onRetry={ onRetry } | ||
isLoading={ isLoading } | ||
/> | ||
); | ||
}; | ||
|
||
export const Default = Template.bind( {} ); | ||
Default.args = { | ||
error: { | ||
message: | ||
'A very generic and unhelpful error. Please try again later. Or contact support. Or not.', | ||
type: 'general', | ||
}, | ||
}; | ||
|
||
export const APIError = Template.bind( {} ); | ||
APIError.args = { | ||
error: { | ||
message: 'Server refuses to comply. It is a teapot.', | ||
type: 'api', | ||
}, | ||
}; | ||
|
||
export const UnknownError = Template.bind( {} ); | ||
UnknownError.args = { | ||
error: { | ||
message: '', | ||
type: 'general', | ||
}, | ||
}; | ||
|
||
export const NoRetry: Story< ErrorPlaceholderProps > = ( args ) => { | ||
return <ErrorPlaceholder { ...args } onRetry={ undefined } />; | ||
}; | ||
NoRetry.args = { | ||
error: { | ||
message: '', | ||
type: 'general', | ||
}, | ||
}; |
19 changes: 0 additions & 19 deletions
19
assets/js/editor-components/error-placeholder/stories/index.js
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
In these cases, I prefer to use an enum. This will allow for easy refactor in the future if there should be a need
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.
While I am also a fan of enums, I feel there are different use-cases which fits best each type, and one shouldn't default to enums, in general. Here is a quick rundown: https://blog.bam.tech/developer-news/should-you-use-enums-or-union-types-in-typescript and here also a nice SO opinion: https://stackoverflow.com/a/60041791/313115
In general, for example, enums are great for readability when their key is not equivalent to their value. Imagine something like:
This doesn't give the reader much information on what's going on. Rather:
The above is much more terse. In our case, the enum would be something like:
I wouldn't say that's very helpful on the readability. I understand what you are saying regarding refactoring, but the SO answer above mentions iterating through a
const
, which I think it fits our case better. Something like:Anyways, in this case, as we have only two types, I think this is slight premature optimization, so my opinion here is YAGNI.
But that's just my 2c, curious to hear what do you think. 🙏
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.
Thanks for sending me these resources!
About readability you can define an enum like this:
For me, the advantage of enums (and the killer feature too) is that we can easily rename for the entire project, instead of the string literal.
I agree, but potentially this component it's a "global" component, so it is better to think about it now that refactor later
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.
Mm, I see what you mean! However you could do the same renaming globally by just extracting the union type. There is no advantage in terms of refactoring between doing:
and
As long as you export both of those things and import them, refactoring is going to involve the exact amount of work. So I'm not sure if that's a significant advantage.
With that said, obviously, in this specific case it is actually a “hard-coded” string union type, so for refactoring reasons, definitely it might be better to extract it into its own type.
As a matter of fact, if you see the code changes, that's an approach I took elsewhere. Previously the code had:
The above was already repeated twice, so I refactored it in its own type. Some go by the Rule of Three when refactoring, though I am a bit more extreme and I usually refactor earlier (some say to a fault). But I definitely agree with you there about long term thinking and also, again, I am a fan of using Enums! 🤓