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

Add pagination to manage automations #26414

Open
wants to merge 31 commits into
base: main
Choose a base branch
from

Conversation

sgress454
Copy link
Contributor

@sgress454 sgress454 commented Feb 18, 2025

Checklist for submitter

  • Changes file added for user-visible changes in changes/, orbit/changes/ or ee/fleetd-chrome/changes.
    See Changes files for more information.
  • Added/updated automated tests
  • A detailed QA plan exists on the associated ticket (if it isn't there, work with the product group's QA engineer to add it)
  • Manual QA for all new/changed functionality

Details

This PR updates the policy Manage Automations modals to support pagination. Previously, these modals received a list of policies from the main Manage Policies page, which is itself paginated, so that a user could only add automations to whatever policies were currently listed on the Manage Automations page. This PR does some refactoring via the creation of a new PaginatedList component which:

  • accepts a fetchPage property it can call to get a page of data,
  • renders the data in a list with checkboxes and optional custom markup (e.g. dropdowns)
  • keeps track of changed ("dirty") items in the list, even across page changes
  • allows parent components to access the list of dirty items via a React ref

For this specific use case, there's also a new PoliciesPaginatedList which implements the fetchPage for getting a page of policies, and adds Save and Cancel buttons. Each of the updated modals uses PoliciesPaginatedList to replace its current code for rendering policies in a list, and delegates much of the logic around change tracking to the new components.

Still TODO

  • tests for new components
  • implementing totalItems for accurate pagination

Comment on lines 328 to 333
{showPreviewCalendarEvent && (
<CalendarEventPreviewModal
onCancel={togglePreviewCalendarEvent}
policy={selectedPolicyToPreview}
/>
)}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved the calendar preview to be a nested modal inside CalendarEventsModal so that the PoliciesPaginatedList can maintain its state (otherwise it loses the page its on whenever the preview is opened).

Copy link
Contributor

Choose a reason for hiding this comment

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

We've generally been avoiding nested modals as a product rule. Would it be feasible to include the
lost state in PaginatedList's useImperativeHandle, and have the parent grab that state to
persist before rendering the preview modal, then pass it back in when it goes back to the paginated
list view?

If not, maybe just cosmetically hide the evidence of the parent modal when rendering the child? It
currently looks like:

Copy link
Contributor

Choose a reason for hiding this comment

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

Screenshot 2025-02-18 at 11 30 04 AM

Comment on lines -45 to -51
interface IFormPolicy {
name: string;
id: number;
installSoftwareEnabled: boolean;
swIdToInstall?: number;
platform: CommaSeparatedPlatformString;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is now exported from PoliciesPaginatedList and shared with all the modals.

@sgress454 sgress454 changed the title Sgress454/23243 add pagination to manage automations Add pagination to manage automations Feb 18, 2025
// The size of the page to fetch and show.
pageSize?: number;
// The total # of items on all pages.
totalItems: number;
Copy link
Contributor

Choose a reason for hiding this comment

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

Where should this be used?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's TODO but I'd really like to update the Pagination control to accept it, because currently it just disables nextPage if the current # of page items is <= the size of a page, which means that if the last page has exactly numItemsOnPage items, we let you click "next" again and get an empty page:
image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I think I'll take this out for now, it's definitely worthwhile to do but this PR has got enough in it.

}

// Wrap with forwardRef to expose the imperative handle:
const PaginatedList = forwardRef(PaginatedListInner) as <TItem>(
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like forwardRef will be deprecated soon,
is there a way to do this with the ref passed in as a prop instead?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah I see...until we're on v19, you need to use forwardRef for the useImperativeHandle above. Can
we just leave a note then to change this whenever we upgrade to v19?

},
}));

// TODO -- better error state?
Copy link
Contributor

Choose a reason for hiding this comment

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

DataError 👍

@jacobshandling
Copy link
Contributor

jacobshandling commented Feb 18, 2025

Great work! A couple more things

Looks like we lost name truncation on the calendar events modal:
Screenshot 2025-02-18 at 11 27 32 AM

We lost a bit of form validation in the RunScript and InstallSoftware modals - in each of them, if any policies are selected but no script/software respectively is chosen for the selected policy, we want to disable the Save button:

Screenshot 2025-02-18 at 11 28 20 AM Screenshot 2025-02-18 at 11 28 28 AM

@sgress454
Copy link
Contributor Author

We lost a bit of form validation in the RunScript and InstallSoftware modals - in each of them, if any policies are selected but no script/software respectively is chosen for the selected policy, we want to disable the Save button:

I have an ongoing discussion on this because I'm not sure it's a good idea when paginating, but I'll implement it as designed in the meantime.

Looks like we lost name truncation on the calendar events modal:

Good catch, meant to wrap the labels in PaginatedList in TooltipTruncatedText, that should take care of all of them.

Copy link

codecov bot commented Feb 19, 2025

Codecov Report

Attention: Patch coverage is 66.66667% with 36 lines in your changes missing coverage. Please review.

Project coverage is 63.85%. Comparing base (b2a8b5c) to head (7fd1cf8).
Report is 87 commits behind head on main.

Files with missing lines Patch % Lines
...onents/CalendarEventsModal/CalendarEventsModal.tsx 43.47% 12 Missing and 1 partial ⚠️
...ts/PoliciesPaginatedList/PoliciesPaginatedList.tsx 64.70% 12 Missing ⚠️
...rontend/components/PaginatedList/PaginatedList.tsx 78.43% 9 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #26414      +/-   ##
==========================================
+ Coverage   63.84%   63.85%   +0.01%     
==========================================
  Files        1632     1638       +6     
  Lines      157954   158155     +201     
  Branches     4125     4173      +48     
==========================================
+ Hits       100845   100993     +148     
- Misses      49204    49254      +50     
- Partials     7905     7908       +3     
Flag Coverage Δ
frontend 53.82% <66.66%> (+0.32%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@sgress454
Copy link
Contributor Author

@jacobshandling updated this to:

  • use TruncatedTooltipText for the list labels:
image image
  • Hide the main calendar events modal when the calendar preview modal is open:

--

  • Disable the save button on install software and run script modals when dropdown values aren't selected:

26414-disable-save-1


26414-disable-save-2


  • Removed the total property for now
  • Added comment re: using forwardRef after React 19

@sgress454 sgress454 marked this pull request as ready for review February 20, 2025 16:26
@sgress454 sgress454 requested a review from a team as a code owner February 20, 2025 16:26
@jacobshandling
Copy link
Contributor

Looks like we need to make the background colors line up for the nested modals:
ezgif-8a7bf8b3d47142

@@ -36,10 +36,30 @@
.form-field__help-text {
margin-top: $pad-large;
}

&__hide-main {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice. I think you'll need to hide the app-wide overlay from the original modal as well, or something
like that.

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

Successfully merging this pull request may close these issues.

2 participants