-
Notifications
You must be signed in to change notification settings - Fork 992
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
Fixes #24475 - Add EmptyState to React components #5850
Conversation
@@ -0,0 +1,67 @@ | |||
import React from 'react'; | |||
import DefaultEmptyState, { EmptyStatePattern } from './index'; | |||
import { testComponentSnapshotsWithFixtures } from '../../../common/testHelpers'; |
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.
'toJson' is defined but never used no-unused-vars
@@ -0,0 +1,67 @@ | |||
import React from 'react'; | |||
import DefaultEmptyState, { EmptyStatePattern } from './index'; |
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.
'shallow' is defined but never used no-unused-vars
</Button> | ||
); | ||
|
||
const documentationBlock = ({ |
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.
see https://github.com/theforeman/foreman/blob/develop/webpack/assets/javascripts/react_app/components/common/DocumentationLink/index.js, maybe worth refactoring / extracting
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.
it is used today in the bookmarks dropdown, so I assume that needs to be extracted from the component and wrapped above it in bookmarks...?
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 if I move it from the <MenuItem>
it will look good. Let me check it out
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.
import PropTypes from 'prop-types'; | ||
import { EmptyState as PfEmptyState, Button } from 'patternfly-react'; | ||
|
||
const secondaryActionButtons = (actions = []) => |
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.
does it make sense to create a component for each one of those? it can in theory make the snapshots smaller?
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.
Do you mean something like:
const ActionButton = ({action: {title, url}, ...props}) =>
<Button href={url}>{title}</Button>;
const PrimaryActionButton = (action) =>
<ActionButton action={action} bsSize="large" bsStyle="primary" />
const SecondaryActionButtons = (actions = []) =>
actions.map(action => <ActionButton action={action} />)
@ohadlevy I updated the code and the storybook:
|
@ohadlevy I have no idea why but when I am using the ReferenceError: Can't find variable: __
ReferenceError: Can't find variable: __
at http://127.0.0.1:36453/webpack/bundle-bbfc6206aec26c54f74a.js:1 in ./webpack/assets/javascripts/react_app/components/common/DocumentationLink/index.js
at http://127.0.0.1:36453/webpack/vendor-255a8802f7a0349e7379.js:1 in a
at http://127.0.0.1:36453/webpack/bundle-bbfc6206aec26c54f74a.js:1 in ./webpack/assets/javascripts/react_app/components/bookmarks/index.js
at http://127.0.0.1:36453/webpack/vendor-255a8802f7a0349e7379.js:1 in a
at http://127.0.0.1:36453/webpack/bundle-bbfc6206aec26c54f74a.js:1 in ./webpack/assets/javascripts/react_app/components/componentRegistry.js
at http://127.0.0.1:36453/webpack/vendor-255a8802f7a0349e7379.js:1 in a
at http://127.0.0.1:36453/webpack/bundle-bbfc6206aec26c54f74a.js:1 in ./webpack/assets/javascripts/react_app/common/MountingService.js
at http://127.0.0.1:36453/webpack/vendor-255a8802f7a0349e7379.js:1 in a
at http://127.0.0.1:36453/webpack/bundle-bbfc6206aec26c54f74a.js:1 in ./webpack/assets/javascripts/bundle.js
at http://127.0.0.1:36453/webpack/vendor-255a8802f7a0349e7379.js:1 in a
at http://127.0.0.1:36453/webpack/vendor-255a8802f7a0349e7379.js:1 in webpackJsonp
ReferenceError: Can't find variable: tfm
ReferenceError: Can't find variable: tfm
at http://127.0.0.1:36453/assets/application-6496916c7a22421384ad3711aebc5b3026d4e153555adc51af5d7700547476d9.js:21485 in global code
ReferenceError: Can't find variable: tfm
ReferenceError: Can't find variable: tfm
at http://127.0.0.1:36453/about:104 in global code
ReferenceError: Can't find variable: tfm
ReferenceError: Can't find variable: tfm
at http://127.0.0.1:36453/about:307 in global code
ReferenceError: Can't find variable: tfm
ReferenceError: Can't find variable: tfm
at http://127.0.0.1:36453/about:318 in global code
test/integration/about_test.rb:31:in `block in <class:AboutIntegrationTest>' |
@ripcurld does window.__ makes any difference? is it during tests (I guess not as i see webpack in your output) also, error about tfm indicate it failed to compile it? |
@amirfefer can you review please? I remember you did something similar in the past? |
@ohadlevy nope |
I found Thanks @ohadlevy & @amirfefer |
Update: @amirfefer's PR |
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.
Looks good @ripcurld !
few minor questions
}; | ||
|
||
DocumentationLink.defaultProps = { | ||
id: 'documentationLink', |
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.
shouldn't it be hard coded? for instance if we have some css rules on this id, the consumer might break that.
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.
Oops you're right. 😱
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.
@amirfefer actually to my surprise BookmarkContainer
is passing id
to DocumentationLink
.
I only noticed it when I ran tests on my computer.
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.
and should the consumer be able to change the id?
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.
Decided not to expose the "id" props as it's used for CSS/jQuery any where in the code base.
import { DocumentLinkContent } from '../DocumentationLink'; | ||
|
||
const ActionButton = ({ url, children, ...props }) => ( | ||
<Button href={url} {...props}> |
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.
Looks like it only wraps a button component with no extra logic or extension, why not just use Button
directly in secondaryActionButtons
and primaryActionButton
} | ||
description="Printers print a file from the computer" | ||
documentation={ | ||
<Unknown> |
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.
Unknown?
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.
It's because I am using React.Fragment. Let me what I can do about it.
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.
I tried to update to 23.0.0
and all tests were failing:
SecurityError: localStorage is not available for opaque origins
at Window.get localStorage [as localStorage] (node_modules/jest-environment-
jsdom/node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
at Array.forEach (<anonymous>)
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.
n/m need to add "testURL"
to jest
section in package.json
in order to fix that
update and yet didn't help. I got many tests failing (some on snapshot and others because turbolink's visit is not called)... I will figure a different way. 😪
/ping @ohadlevy @amirfefer - ready for next iteration of reviews. Thanks 😀 |
}; | ||
|
||
DocumentationLink.defaultProps = { | ||
id: 'documentationLink', |
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.
and should the consumer be able to change the id?
describe('Default Empty State', () => { | ||
// React.Fragment is rendered as <Unknown>: | ||
// https://github.com/facebook/jest/pull/5816 | ||
// To fix this, I am using TestRenderer.create. |
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.
BTW, I tried to mock React.Fragment
using jest
(mock and setMock) none was working for me.
In addition, I found TestRenderer
much easier to follow and to test.
If someone is capable to mock React.Fragment
please let me know. 🍡
</a> | ||
</SafeAnchor> | ||
</li> | ||
</MenuItem> | ||
</Component> | ||
</DocumentationLink> | ||
<MenuItem | ||
bsClass="dropdown" | ||
disabled={false} |
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.
nitpick: this is too large snapshot, is there a way to reduce its size? (divide it ?)
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.
Will have a solution for that hopefully in 2 hours 👍
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 work @ripcurld, I just got one small comment.
@@ -0,0 +1,116 @@ | |||
import React from 'react'; |
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.
Could you change this file so it will contain single component per file?
e.g.
common/EmptyState/EmptyState.js
common/EmptyState/EmptyStatePattern.js
common/EmptyState/EmptyStatePropTypes.js
common/EmptyState/EmptyStateSecondaryActionButtons.js
common/EmptyState/EmptyStatePrimaryActionButton.js
And you can namely expose the relevant component from the common/EmptyState/index.js
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.
No problem - you got it!
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 👍
[test foreman] |
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! Thanks @ripcurld 👍
@ohadlevy @sharvit @amirfefer I rebased (there was a conflict with #5872) |
Rebased (due to #5921) ☘️ |
label = __('For more information please see'), | ||
buttonLabel = __('Documentation'), | ||
}) => | ||
(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.
nitpick: why not url && <...> instead ? e.g.
url && (<React.Fragment>
 {label}{' '}
 <a href={url} target="_blank">
 <DocumentLinkContent>{buttonLabel}</DocumentLinkContent>
 </a>
 </React.Fragment>)
looks good, one nitpick :) |
Signed-off-by: Boaz Shuster <boaz.shuster.github@gmail.com>
[test upgrade] |
@sharvit & @amirfefer mind giving final ack? thanks |
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 👍
Thanks @ripcurld
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! Thanks @ripcurld
This is part of #5755 - Adding Table React components to Hardware Models.
EmptyState is used in the Table component and since it didn't have tests or storybook in
Katello
I decided to push it as its own PR.This PR introduces two
EmptyState
components -DefaultEmptyState
which is what we are using in Foreman andEmptyStatePattern
which allows to customize the empty state component (actuallyDefaultEmptyState
is based on top of it).If you would like to play with this a little bit the storybook can be found here
PRs that are related: #5755 and #5024.
PatternFly React
I saw that @sharvit asked to push
EmptyStatePattern
to pf-react, which is similar to this PR (read more here). Between those two PRs there are nuances but the major difference is that in this PR the primary action and the secondary actions can be rendered in any way you would like (it doesn't have to be a button). This is to allow other people to set their own action-buttons/actions part.Katello
Katello is using a very similar EmptyState component. The only big difference that I see is that the action buttons are wrapped inside
LinkContainer
in order to interact withreact-router
.Therefore, in order to use this component in Katello use
EmptyStatePattern
and pass a function that renders the buttons from title and url. Something like this://cc @ohadlevy @sharvit @amirfefer @tstrachota @waldenraines