Skip to content
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 #30432 - Add pf4 table component #7829

Closed
wants to merge 1 commit into from

Conversation

johnpmitsch
Copy link

@johnpmitsch johnpmitsch commented Jul 17, 2020

This is the pattternfly 4 table that we have been using in Katello, I'm moving it here.

The goal of this table is to make a non-opinionated table that provides:

  • Search
  • Pagination
  • Empty state handling
  • Error state handling
  • Allows passing props to the pf4 table for customization

I called it TableWrapper as I don't see this as an opinionated ForemanTable, rather the pf4 table with some batteries included. I think we can build a more opinionated ForemanTable or variations of this on top of this, but doing so now without a lot of use cases would mean a lot of speculation around the features we need.

I'm not married to the name so feel free to suggest something that conveys this better :)

Still a lot to do here, but it is functional and rendering, I was able to swap out for the local component in Katello and it worked well. There is some existing technical debt that has to be figured out here, Katello has been using a different Search component than Foreman for a while, I moved it over as well, this has been converted to pf4.

For now, you can test this out by going to the stories under pf4 > TableWrapper: npm run stories

The big remaining tasks are:

  • Add and update tests for TableWrapper and Search
  • Add more storybook examples - currently I am blocked by not being able to mock the API
  • Update to use foreman's empty state
  • Move downshift and any other introduced dependencies to foreman-js
  • Fix pagination issue where 0 results still show number
  • More testing
  • Should we use Katello's search?

@theforeman-bot
Copy link
Member

Issues: #30432

@johnpmitsch
Copy link
Author

johnpmitsch commented Jul 17, 2020

I just moved this from Katello without any changes for now and am opening as a draft PR to start the discussion.

I'll clean this up, adding tests and stories. It will likely also need some foreman-js changes, same as this PR too.

You can see usage in the new katello CV page https://github.com/Katello/katello/blob/master/webpack/scenes/ContentViews/Table/ContentViewsTable.js

I named it TableWrapper as the usage is similar to the original pf4 table, with pagination and search added. The rows and columns still need to be structured the same way that patternfly4 expects

The goal is to provide a table that has search and pagination that can display content from the API. I would consider this the first iteration of the table, I know there are more features and support for Rails content, but as long as we don't limit ourselves that all can be added later and iterated on.

.foreman-pf4-search-clear {
padding: 8px 5px 4px 5px;
margin-left: 10px;
}

Choose a reason for hiding this comment

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

Unexpected missing end-of-source newline no-missing-end-of-source-newline

// accounting for excess padding on search bar and aligning vertically
.foreman-pf4-search-clear {
padding: 8px 5px 4px 5px;
margin-left: 10px;

Choose a reason for hiding this comment

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

Expected newline before "}" of a multi-line block block-closing-brace-newline-before
Unexpected whitespace at end of line no-eol-whitespace

.foreman-pf4-search-input {
padding-right: 35px;
margin-right: -23px;
}

Choose a reason for hiding this comment

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

Unexpected missing end-of-source newline no-missing-end-of-source-newline

@johnpmitsch
Copy link
Author

johnpmitsch commented Nov 13, 2020

Still a lot to do here, but it is functional and rendering, I was able to swap out for the local component in Katello and it worked well. There is some existing technical debt that has to be figured out here, Katello has been using a different Search component than Foreman for a while, I moved it over as well, this has been converted to pf4. Also, there is a new empty state page in Foreman that could make more sense to use here.

The big remaining tasks are:

  • Add and update tests for TableWrapper and Search
  • Add more storybook examples - currently I am blocked by not being able to mock the API, I tried to set something up similar to
    const initializeMocks = () => {
    mockRequest({
    url: '/api/v2/compute_resources/1/available_storage_domains',
    response: VMWareData.storageDomainResponse,
    });
    mockRequest({
    url: '/api/v2/compute_resources/1/available_storage_pods',
    response: VMWareData.storagePodResponse,
    });
    };
    but didn't have any luck, it doesn't seem to be working for that story as well
  • Update to use foreman's empty state
  • Move downshift and any other introduced dependencies to foreman-js
  • Fix pagination issue where 0 results still show number

@MariaAga
Copy link
Member

@johnpmitsch Your solution was almost there :)
Looks like the mock needs an exact url (without the port) so I got it to work using:

  const path = window.location.protocol + "//" + window.location.hostname
  mockRequest({
    url: `${path}/api/v2/compute_resources/1/available_storage_domains`,
    response: VMWareData.storageDomainResponse,
  });

@johnpmitsch
Copy link
Author

@johnpmitsch Your solution was almost there :)
Looks like the mock needs an exact url (without the port) so I got it to work using:

  const path = window.location.protocol + "//" + window.location.hostname
  mockRequest({
    url: `${path}/api/v2/compute_resources/1/available_storage_domains`,
    response: VMWareData.storageDomainResponse,
  });

Thank you!! 🙏

.foreman-pf4-search-clear {
padding: 8px 5px 4px 5px;
margin-left: 10px;
}

Choose a reason for hiding this comment

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

Unexpected missing end-of-source newline no-missing-end-of-source-newline

@johnpmitsch
Copy link
Author

johnpmitsch commented Jan 15, 2021

Moving to ready for review, it still needs more testing and there are some open questions, but I think it's a good time to get feedback.

@MariaAga
Copy link
Member

@johnpmitsch Can this pr be broken into a few prs? Like one for search, one for pagination, one for the empty states?

Copy link
Contributor

@jeremylenz jeremylenz left a comment

Choose a reason for hiding this comment

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

The storybook story isn't rendering for me. It displays an error:

TypeError: (0 , _ForemanContext.usePaginationOptions) is not a function
    at TableWrapper (http://centos7-katello-devel.redhatlaptop.example.com:6006/main.0fd139abeda772fcc60c.bundle.js:24318:62)
    at renderWithHooks (http://centos7-katello-devel.redhatlaptop.example.com:6006/foreman-vendor.bundle-v7.2.9-development-db270870644d27fe3377.js:510743:18)
    at mountIndeterminateComponent (http://centos7-katello-devel.redhatlaptop.example.com:6006/foreman-vendor.bundle-v7.2.9-development-db270870644d27fe3377.js:513569:13)
    at beginWork (http://centos7-katello-devel.redhatlaptop.example.com:6006/foreman-vendor.bundle-v7.2.9-development-db270870644d27fe3377.js:514807:16)
    at HTMLUnknownElement.callCallback (http://centos7-katello-devel.redhatlaptop.example.com:6006/foreman-vendor.bundle-v7.2.9-development-db270870644d27fe3377.js:499703:14)
    at Object.invokeGuardedCallbackDev (http://centos7-katello-devel.redhatlaptop.example.com:6006/foreman-vendor.bundle-v7.2.9-development-db270870644d27fe3377.js:499752:16)
    at invokeGuardedCallback (http://centos7-katello-devel.redhatlaptop.example.com:6006/foreman-vendor.bundle-v7.2.9-development-db270870644d27fe3377.js:499814:31)
    at beginWork$1 (http://centos7-katello-devel.redhatlaptop.example.com:6006/foreman-vendor.bundle-v7.2.9-development-db270870644d27fe3377.js:519717:7)
    at performUnitOfWork (http://centos7-katello-devel.redhatlaptop.example.com:6006/foreman-vendor.bundle-v7.2.9-development-db270870644d27fe3377.js:518529:12)
    at workLoopSync (http://centos7-katello-devel.redhatlaptop.example.com:6006/foreman-vendor.bundle-v7.2.9-development-db270870644d27fe3377.js:518460:5)

@Ron-Lavi
Copy link
Member

Ron-Lavi commented Mar 8, 2021

@johnpmitsch, what is the status of this PR? :)

This adds a table component to patternfly 4 that wraps the pf4 table with the following features:
- Search
- Pagination
- Empty state handling
- allow passthrough of props to pf4 table
@johnpmitsch
Copy link
Author

@jeremylenz @LaViro I rebased and fixed the pagination hook error, the storybook should be all set to test out, let me know if it gives any more trouble.

I would love to start getting some feedback, there are open questions and to-dos but everything is functional, it would be great to get feedback on the design.

@johnpmitsch
Copy link
Author

@johnpmitsch Can this pr be broken into a few prs? Like one for search, one for pagination, one for the empty states?

I'll look into this!

Copy link
Contributor

@jeremylenz jeremylenz left a comment

Choose a reason for hiding this comment

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

Thanks @johnpmitsch, stories are working now :)

The autocomplete is kinda wonky in the story - It just suggests "bread" all the time but doesn't suggest operators or values. And I never get any search results. Not saying you have to have a fully functional autocomplete for the storybook, but if nonfunctionality is intended it would be nice to make it more graceful somehow, or at least call out that it's not going to work the same as a real one.

Some more initial comments below

const ForemanContext = getForemanContext();

export default {
title: 'Components|PF4/TableWrapper',
Copy link
Contributor

Choose a reason for hiding this comment

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

The old hierarchy separator | should not be used any more. They should all be /

As it is, this renders as a new top-level section called "Components|PF4". If you think there should be a new top-level section for PF4 components, I'd be fine with that, but it's too confusing to use |; I'd use "PF4 Components" or something.

@@ -0,0 +1,85 @@
import React from 'react';
Copy link
Contributor

Choose a reason for hiding this comment

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

Would like to see a story for this component!

Comment on lines +4 to +7
// library. This is helpful when the request is not coming from Katello. For example, axios
// called within Katello can be mocked with axios-mock-adapter or similar, but a http request
// made by axios that is coming from Foreman cannot be mocked by axios-mock-adapter or a
// jest mock within Katello. So to do this, we can mock the request a level deeper within
Copy link
Contributor

Choose a reason for hiding this comment

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

please rephrase so it's not Katello-specific :)

Comment on lines +79 to +80
<FlexItem align={{ default: 'alignRight' }}>
<Pagination
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm thinking that the location of <Pagination> should maybe be more flexible. We've already been requested to put <Pagination> in various places, (on the left, outside the table, etc.) Would it be better to just not include it here, and allow the consumer to insert it as one of the <FlexItem> children?

}) => {
const isFiltering = activeFilters || searchIsActive;
if (status === STATUS.PENDING) return <Loading showText={false} />;
// Can we display the error message?
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment no longer makes sense without the others that used to be there

</FlexItem>
</Flex>
<MainTable
searchIsActive={!!searchQuery}
Copy link
Contributor

Choose a reason for hiding this comment

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

bang bang

// Loading icon shows first
expect(getByLabelText(loadingLabel)).toBeInTheDocument();
// Loading icon disappears
await patientlyWaitFor(() => expect(queryByLabelText(loadingLabel)).not.toBeInTheDocument());
Copy link
Contributor

Choose a reason for hiding this comment

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

TableWrapper.test.js (7.693 s)

Tests that use this helper are still taking forever. I think it's worth filing an issue to see if there's any way we can improve this.

@@ -0,0 +1,115 @@
import React, { Component } from 'react';
import Downshift from 'downshift';
Copy link
Contributor

Choose a reason for hiding this comment

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

would be nice to see a comment here to refresh my memory on what Downshift does for us


import './TypeAhead.scss';

class TypeAhead extends Component {
Copy link
Contributor

Choose a reason for hiding this comment

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

There's no reason this can't be written with hooks 👼

import api from '../../../redux/API/API';
import { stringIncludes } from './helpers';

class Search extends Component {
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, why not write this with hooks 👼

@johnpmitsch
Copy link
Author

@LaViro has kindly offered to take this PR over in my absence, so I am going to close this out. Anyone is free to use any code from this PR.

Thanks @LaViro! 👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants