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

Page size preference #23

Closed

Conversation

milleymilli
Copy link

@milleymilli milleymilli commented Nov 12, 2023

This is a:

  • ✨ New feature - new behaviour has been implemented
  • πŸ› Bug fix - existing behaviour has been made to behave
  • ♻️ Refactor - the behaviour has not changed, just the implementation
  • βœ… Test backfill - tests for existing behaviour were added but the behaviour itself hasn't changed
  • βš™οΈ Chore - maintenance task, behaviour and implementation haven't changed

Description

  • Purpose -
    • Page Size Preference:
      Users will have the ability to select their preferred page size using a drop down UI component.
      This selected page size preference will be stored in the local storage of the user's browser for future visits to the application.
    • Local Storage Management:
      The application will utilize the browser's local storage to save and retrieve the user's chosen page size preference.
      This enables persistent storage of the selected preference, maintaining it even if the user refreshes the page or returns to the application later.
    • Enhanced User Experience:
      Overall, merging this new code will enhance the user experience by providing an interactive feature that allows users to customize their browsing experience by selecting their preferred page size for resource display.
  • How to check -
    • Inspect Local Storage Changes:
      Use browser developer tools to inspect the local storage for the application.
      Look for the presence of stored data related to the page size preference and confirm that it persists across sessions or page reloads.

Links

Author checklist

  • I have written a title that reflects the relevant ticket
  • I have written a description that says what the PR does and how to validate it
  • I have linked to the project board ticket (and any related PRs/issues) in the Links section
  • I have added a link to this PR to the ticket
  • I have made the PR to main from a branch named <category>/<name>, e.g. feature/edit-spaceships or bugfix/restore-oxygen
  • I have manually tested that the app still works correctly
  • I have requested reviewers here and in my team chat channel
  • I have spoken with my PM or TL about any parts of this task that may have become out-of-scope, or any additional improvements that I now realise may benefit my project
  • I have added tests, or new tests were not required
  • I have updated any documentation (e.g. diagrams, schemas), or documentation updates were not required

Copy link
Author

@milleymilli milleymilli left a comment

Choose a reason for hiding this comment

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

This PR introduces a mechanism to manage the user's preferred page size for better customization of the application experience. Here's a breakdown of the changes:

  1. Fetching Initial Page Size:

    • Reads the user's preferred page size from local storage.
    • If available, attempts to parse the stored value as JSON.
    • In case of parsing error, defaults to "default" and throws an error for debugging purposes.
  2. useState and useEffect Integration:

    • Utilizes the useState hook to manage the current page size, initializing it with the parsed or default value.
    • useEffect to synchronize the selected page size with API requests.
  3. LocalStorage Interaction:

    • Implements a savePageSizePreference function to store the selected page size in local storage.

These changes enhance the user experience by allowing them to customize their preferred page size. The error handling in the parsing process aims to provide better debugging insights if issues arise.

Please review and provide feedback. Thank you!

Copy link
Member

@textbook textbook left a comment

Choose a reason for hiding this comment

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

Please complete the template in the PR description to enable review.

@milleymilli
Copy link
Author

Please complete the template in the PR description to enable review.

I have completed it.

Copy link
Member

@textbook textbook left a comment

Choose a reason for hiding this comment

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

PR:

❌ Still doesn't link to the issue: #17
❌ Checklist is incomplete/incorrect (e.g. tests are checked, but there aren't any)

I was also confused by the "How to check", as it didn't seem to refer to any actual functionality, but...


Functionality:

❌ Doesn't actually do anything. Yes it updates local storage, and sets the select accordingly across sessions and page re-loads. But what use is that? It doesn't actually change how many items are in the page.
❓ What about other lists in the UI? Admins can see a list of drafts, should that follow this preference too?
❓ How would you approach this if the requirement was to remember a user's preference across browsers/computers?


UI:

Screenshot 2023-11-14 at 16 34 39

❌ Select isn't consistently styled, doesn't match the other one (10, 20, 50) on the same page
❌ Label isn't consistent either ("Title Case" instead of "Sentence case", includes a colon, no whitespace before control)
❓ Is this the right place for it? It's a long way from the other page-related controls, especially if there are any resources in the list.


More detailed comments on the implementation details below. In general:

  • It's not well factored, look for opportunities to split out separate parts rather than add eveything into one file; and
  • It's completely untested.

Key:

  • ❌ Problem, needs fixing before approval
  • ❓ Question, needs answering before approval
  • πŸ’‘ Suggestion, can be taken or left

client/src/pages/Home/index.js Show resolved Hide resolved
client/src/pages/Home/index.js Show resolved Hide resolved
client/src/pages/Home/index.js Show resolved Hide resolved
.then(setEnvelope)
.catch((error) => {
// Handle the error from the API request as needed
throw new Error("Error fetching published resources:", error);
Copy link
Member

Choose a reason for hiding this comment

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

❌ Throwing an error in this way is generally not helpful - if you want to created a new error "caused by" the previous one it should be:

Suggested change
throw new Error("Error fetching published resources:", error);
throw new Error("Error fetching published resources:", { cause: error });

MDN

But if you can't really deal with the error or add any useful information, it's best to let it keep going to wherever it ends up.

}, [resourceService, searchParams]);
// Using the selected page size in my API request
resourceService
.getPublished({ ...searchParams, pageSize })
Copy link
Member

Choose a reason for hiding this comment

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

❌ What does adding pageSize to the arguments here achieve? If you look at the service implementation:

async getPublished({ page, perPage } = {}) {

It destructures page and perPage out, but anything else is ignored. You could also see by looking at the Network tab in your developer tools that the request had no additional parameters. Even if that wasn't true, and it passed pageSize along to the request, the GET /resources endpoint doesn't document a pageSize query parameter and would at best ignore it (search/query parameters tend to be optional, although some API implementations will validate and reject 4xx on unexpected parameters/values).

Comment on lines +54 to +56
<option value="default">Default</option>
<option value="small">Small</option>
<option value="large">Large</option>
Copy link
Member

Choose a reason for hiding this comment

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

❓ What are these values supposed to represent? Assuming they follow what's already on the page, i.e.:

  • Default: 20
  • Small: 10
  • Large: 50

it would be helpful to include those values, and this is an odd order to put them in.

<ResourceList resources={resources ?? []} />
<Pagination lastPage={lastPage ?? 1} />
{/* Create the UI for page size selection */}
<label htmlFor="pageSize">Page Size: </label>
Copy link
Member

Choose a reason for hiding this comment

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

πŸ’‘ It's good to associated labels with controls, it makes the site more accessible, but if you look at the other form controls in the app you can see they generally use nesting to do that:

<label>
Items per page
<select

(This is also accepted by our linting.)

Also note other labels are "Sentence cased" not "Title Cased".

client/src/pages/Home/index.js Show resolved Hide resolved
Comment on lines +12 to +28
const storedPageSize = localStorage.getItem("pageSizePreference");
let initialPageSize;

try {
initialPageSize = storedPageSize ? JSON.parse(storedPageSize) : "default";
} catch (error) {
// Handle the error as needed
initialPageSize = "default";
throw new Error("Error parsing page size preference:", error);
}

const [pageSize, setPageSize] = useState(initialPageSize);

// This function is to save the selected page-size into local storage
const savePageSizePreference = (pageSize) => {
localStorage.setItem("pageSizePreference", JSON.stringify(pageSize));
};
Copy link
Member

Choose a reason for hiding this comment

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

πŸ’‘ This is a lot of code in the middle of the home page to handle something relatively minor (and that might also be needed elsewhere). Don't just jam everything into one file, think about how you can separate out unrelated concerns to make your code easier to read (and test). For example, what if you extracted a service to handle local storage, or maybe a hook:

Suggested change
const storedPageSize = localStorage.getItem("pageSizePreference");
let initialPageSize;
try {
initialPageSize = storedPageSize ? JSON.parse(storedPageSize) : "default";
} catch (error) {
// Handle the error as needed
initialPageSize = "default";
throw new Error("Error parsing page size preference:", error);
}
const [pageSize, setPageSize] = useState(initialPageSize);
// This function is to save the selected page-size into local storage
const savePageSizePreference = (pageSize) => {
localStorage.setItem("pageSizePreference", JSON.stringify(pageSize));
};
const [pageSize, setPageSize] = useLocalStorage("pageSizePreference", "default");

Also note some of my other suggestions (error handling, comments*) apply here too.

* if you're going to put comments on functions, use JSDoc so they're structured and useful

@milleymilli milleymilli changed the title Page size preference Page size preference #17 Nov 28, 2023
@milleymilli milleymilli changed the title Page size preference #17 Page size preference Nov 28, 2023
@textbook
Copy link
Member

textbook commented Jan 4, 2024

🍞 Closing as stale (more than one month without updates)

@textbook textbook closed this Jan 4, 2024
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