Repository: mui/material-ui (TypeScript)
Date: 2020-10-28 17:55:45+00:00
Task type: Bug Fix

Issue:
[Table] All option demo display wrong text
<!-- Provide a general summary of the issue in the Title above -->
When select All option in table pagination(with -1 value) the display text shown `1--1 of x` instead of `1-x of x`
<!--
  Thank you very much for contributing to Material-UI by creating an issue! ❤️
  To avoid duplicate issues we ask you to check off the following list.
-->

<!-- Checked checkbox should look like this: [x] -->

- [x] The issue is present in the latest release.
- [x] I have searched the [issues](https://github.com/mui-org/material-ui/issues) of this repository and believe that this is not a duplicate.

## Current Behavior 😯

<!-- Describe what happens instead of the expected behavior. -->

Display wrong number( `-1` ) when select ALL option.

## Expected Behavior 🤔

<!-- Describe what should happen. -->
Should display `1-x of x` when x is the number of rows

## Steps to Reproduce 🕹

<!--
  Provide a link to a live example (you can use codesandbox.io) and an unambiguous set of steps to reproduce this bug.
  Include code to reproduce, if relevant (which it most likely is).

  You should use the official codesandbox template as a starting point: https://material-ui.com/r/issue-template

  If you have an issue concerning TypeScript please start from this TypeScript playground: https://material-ui.com/r/ts-issue-template

  Issues without some form of live example have a longer response time.
-->

Steps:

1. go to example in https://material-ui.com/components/tables/#custom-pagination-options
2. select All option in pagination
3. the text become `1--1 of 13`

## Context 🔦

<!--
  What are you trying to accomplish? How has this issue affected you?
  Providing context helps us come up with a solution that is most useful in the real world.
-->
Trying to get correct data
## Your Environment 🌎
<!--
  Include as many relevant details about the environment with which you experienced the bug.
  If you encounter issues with TypeScript please include version and tsconfig.
-->
https://material-ui.com/components/tables


Issue discussion:
@hswimmer Thanks for the report. It looks like we can fix the demo:

```diff
diff --git a/docs/src/pages/components/tables/CustomPaginationActionsTable.tsx b/docs/src/pages/components/tables/CustomPaginationActionsTable.tsx
index 974475210d..7bd0e7a2c7 100644
--- a/docs/src/pages/components/tables/CustomPaginationActionsTable.tsx
+++ b/docs/src/pages/components/tables/CustomPaginationActionsTable.tsx
@@ -186,7 +186,7 @@ export default function CustomPaginationActionsTable() {
         <TableFooter>
           <TableRow>
             <TablePagination
-              rowsPerPageOptions={[5, 10, 25, { label: 'All', value: -1 }]}
+              rowsPerPageOptions={[5, 10, 25, { label: 'All', value: rows.length }]}
               colSpan={3}
               count={rows.length}
               rowsPerPage={rowsPerPage}
```

Do you want to work on a pull request? :)
@oliviertassinari 
I have an issue with the suggested solution:
I want to keep the selected `rowsPerPage` for displaying this numbers of rows in next use.
When I keep the `-1` option and use this number in next view - I always see all rows. 
but if I use `rows.length` and the number of rows was changed from last view - everything is get messy:  the first option is marked as selected, only "prev `rows.length` " rows are shown.

To avoid this wrong behavior we can add a workaround in our code, 
but maybe you can add the next change -:
![image](https://user-images.githubusercontent.com/59191743/97426329-f75fe380-191b-11eb-9175-85c13497dc6f.png)

@hswimmer Thanks for looking into, we have started to explore a solution in #23280
> but if I use rows.length and the number of rows was changed from last view - everything is get messy: the first option is marked as selected, only "prev rows.length " rows are shown.

Ok, this sounds fair. We could restore the support of `-1`, with a test case and description of its support in the prop this time. @JoaoJesus94. What do you think? We could do the same for the prop `count`, where `-1` means "unknown". For `rowsPerPage` it could mean "all".
> Ok, this sounds fair. We could restore the support of `-1`, with a test case and description of its support in the prop this time. @JoaoJesus94. What do you think? We could do the same for the prop `count`, where `-1` means "unknown". For `rowsPerPage` it could mean "all".

@oliviertassinari It seems that the changes that @hswimmer suggested will fix it.
Regarding prop `count` I think we don't need to touch it. `-1` already means "unknown"
@JoaoJesus94 Sounds great, we would only need to add a test case to avoid a regression in the future (like we already had) :)

Solution patch:
diff --git a/docs/pages/api-docs/table-pagination.md b/docs/pages/api-docs/table-pagination.md
--- a/docs/pages/api-docs/table-pagination.md
+++ b/docs/pages/api-docs/table-pagination.md
@@ -40,7 +40,7 @@ The `MuiTablePagination` name can be used for providing [default props](/customi
 | <span class="prop-name required">onPageChange<abbr title="required">*</abbr></span> | <span class="prop-type">func</span> |  | Callback fired when the page is changed.<br><br>**Signature:**<br>`function(event: object, page: number) => void`<br>*event:* The event source of the callback.<br>*page:* The page selected. |
 | <span class="prop-name">onRowsPerPageChange</span> | <span class="prop-type">func</span> |  | Callback fired when the number of rows per page is changed.<br><br>**Signature:**<br>`function(event: object) => void`<br>*event:* The event source of the callback. |
 | <span class="prop-name required">page<abbr title="required">*</abbr></span> | <span class="prop-type">number</span> |  | The zero-based index of the current page. |
-| <span class="prop-name required">rowsPerPage<abbr title="required">*</abbr></span> | <span class="prop-type">number</span> |  | The number of rows per page. |
+| <span class="prop-name required">rowsPerPage<abbr title="required">*</abbr></span> | <span class="prop-type">number</span> |  | The number of rows per page.<br>Set -1 to display all the rows. |
 | <span class="prop-name">rowsPerPageOptions</span> | <span class="prop-type">Array&lt;number<br>&#124;&nbsp;{ label: string, value: number }&gt;</span> | <span class="prop-default">[10, 25, 50, 100]</span> | Customizes the options of the rows per page select field. If less than two options are available, no select field will be displayed. |
 | <span class="prop-name">SelectProps</span> | <span class="prop-type">object</span> | <span class="prop-default">{}</span> | Props applied to the rows per page [`Select`](/api/select/) element. |
 | <span class="prop-name">showFirstButton</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, show the first-page button. |
diff --git a/packages/material-ui/src/TablePagination/TablePagination.d.ts b/packages/material-ui/src/TablePagination/TablePagination.d.ts
--- a/packages/material-ui/src/TablePagination/TablePagination.d.ts
+++ b/packages/material-ui/src/TablePagination/TablePagination.d.ts
@@ -109,6 +109,8 @@ export interface TablePaginationTypeMap<P, D extends React.ElementType> {
       page: number;
       /**
        * The number of rows per page.
+       *
+       * Set -1 to display all the rows.
        */
       rowsPerPage: number;
       /**
diff --git a/packages/material-ui/src/TablePagination/TablePagination.js b/packages/material-ui/src/TablePagination/TablePagination.js
--- a/packages/material-ui/src/TablePagination/TablePagination.js
+++ b/packages/material-ui/src/TablePagination/TablePagination.js
@@ -111,6 +111,11 @@ const TablePagination = React.forwardRef(function TablePagination(props, ref) {
   const labelId = useId(SelectProps.labelId);
   const MenuItemComponent = SelectProps.native ? 'option' : MenuItem;
 
+  const getLabelDisplayedRowsTo = () => {
+    if (count === -1) return (page + 1) * rowsPerPage;
+    return rowsPerPage === -1 ? count : Math.min(count, (page + 1) * rowsPerPage);
+  };
+
   return (
     <Component className={clsx(classes.root, className)} colSpan={colSpan} ref={ref} {...other}>
       <Toolbar className={classes.toolbar}>
@@ -149,7 +154,7 @@ const TablePagination = React.forwardRef(function TablePagination(props, ref) {
         <Typography color="inherit" variant="body2" className={classes.caption}>
           {labelDisplayedRows({
             from: count === 0 ? 0 : page * rowsPerPage + 1,
-            to: count !== -1 ? Math.min(count, (page + 1) * rowsPerPage) : (page + 1) * rowsPerPage,
+            to: getLabelDisplayedRowsTo(),
             count: count === -1 ? -1 : count,
             page,
           })}
@@ -276,6 +281,8 @@ TablePagination.propTypes = {
   }),
   /**
    * The number of rows per page.
+   *
+   * Set -1 to display all the rows.
    */
   rowsPerPage: PropTypes.number.isRequired,
   /**


Test patch:
diff --git a/packages/material-ui/src/TablePagination/TablePagination.test.js b/packages/material-ui/src/TablePagination/TablePagination.test.js
--- a/packages/material-ui/src/TablePagination/TablePagination.test.js
+++ b/packages/material-ui/src/TablePagination/TablePagination.test.js
@@ -402,4 +402,27 @@ describe('<TablePagination />', () => {
       expect(combobox).toHaveAccessibleName('Rows per page: 10');
     });
   });
+
+  describe('prop: rowsPerPage', () => {
+    it('should display max number of rows text when prop is -1', () => {
+      const { container } = render(
+        <table>
+          <TableFooter>
+            <TableRow>
+              <TablePagination
+                rowsPerPageOptions={[5, 10, 25, { label: 'All', value: -1 }]}
+                count={25}
+                page={0}
+                rowsPerPage={-1}
+                onPageChange={noop}
+              />
+            </TableRow>
+          </TableFooter>
+        </table>,
+      );
+
+      expect(container).to.include.text('All');
+      expect(container).to.include.text('1-25 of 25');
+    });
+  });
 });