Disable "Next" button in Paginator when the next page is empty (#2114)

* Store communityLimit as a constant in the config

* Block Next button on communities list if the next page is empty

* Use this.props instead of undefined props, compare number to the length of the array, not the array itself

* Set nextDisabled prop for Paginator in registration-applications component

* Set nextDisabled prop in Paginator required

* Ignore nextDisabled prop in Paginator component used in person/inbox.tsx and modlog.tsx

* Set nextDisabled to true if community is not yet loaded or no more pages are expected

* Set nextDisabled to false for Paginator in emojis-form.tsx

* Fix swapped bool logic in community.tsx

* Set nextDisabled for Paginator in home.tsx

* Set nextDisabled for Comments and Posts in person-details.tsx

* Set nextDisabled for reports.tsx

* Set nextDisabled for search.tsx

---------

Co-authored-by: SleeplessOne1917 <abias1122@gmail.com>
This commit is contained in:
Jarosław 2023-09-07 16:33:43 +03:00 committed by GitHub
parent 8e2609a96d
commit d98009c7d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 71 additions and 8 deletions

View file

@ -4,6 +4,7 @@ import { I18NextService } from "../../services";
interface PaginatorProps { interface PaginatorProps {
page: number; page: number;
onChange(val: number): any; onChange(val: number): any;
nextDisabled: boolean;
} }
export class Paginator extends Component<PaginatorProps, any> { export class Paginator extends Component<PaginatorProps, any> {
@ -23,6 +24,7 @@ export class Paginator extends Component<PaginatorProps, any> {
<button <button
className="btn btn-secondary" className="btn btn-secondary"
onClick={linkEvent(this, this.handleNext)} onClick={linkEvent(this, this.handleNext)}
disabled={this.props.nextDisabled || false}
> >
{I18NextService.i18n.t("next")} {I18NextService.i18n.t("next")}
</button> </button>

View file

@ -32,7 +32,7 @@ import { Paginator } from "../common/paginator";
import { SortSelect } from "../common/sort-select"; import { SortSelect } from "../common/sort-select";
import { CommunityLink } from "./community-link"; import { CommunityLink } from "./community-link";
const communityLimit = 50; import { communityLimit } from "../../config";
type CommunitiesData = RouteDataResponse<{ type CommunitiesData = RouteDataResponse<{
listCommunitiesResponse: ListCommunitiesResponse; listCommunitiesResponse: ListCommunitiesResponse;
@ -221,7 +221,14 @@ export class Communities extends Component<any, CommunitiesState> {
</tbody> </tbody>
</table> </table>
</div> </div>
<Paginator page={page} onChange={this.handlePageChange} /> <Paginator
page={page}
onChange={this.handlePageChange}
nextDisabled={
communityLimit >
this.state.listCommunitiesResponse.data.communities.length
}
/>
</div> </div>
); );
} }

View file

@ -344,7 +344,14 @@ export class Community extends Component<
</div> </div>
{this.selects(res)} {this.selects(res)}
{this.listings(res)} {this.listings(res)}
<Paginator page={page} onChange={this.handlePageChange} /> <Paginator
page={page}
onChange={this.handlePageChange}
nextDisabled={
this.state.postsRes.state !== "success" ||
fetchLimit > this.state.postsRes.data.posts.length
}
/>
</main> </main>
<aside className="d-none d-md-block col-md-4 col-lg-3"> <aside className="d-none d-md-block col-md-4 col-lg-3">
{this.sidebar(res)} {this.sidebar(res)}

View file

@ -267,7 +267,11 @@ export class EmojiForm extends Component<EmojiFormProps, EmojiFormState> {
{I18NextService.i18n.t("add_custom_emoji")} {I18NextService.i18n.t("add_custom_emoji")}
</button> </button>
<Paginator page={this.state.page} onChange={this.handlePageChange} /> <Paginator
page={this.state.page}
onChange={this.handlePageChange}
nextDisabled={false}
/>
</div> </div>
</div> </div>
); );

View file

@ -653,7 +653,14 @@ export class Home extends Component<any, HomeState> {
<div> <div>
{this.selects} {this.selects}
{this.listings} {this.listings}
<Paginator page={page} onChange={this.handlePageChange} /> <Paginator
page={page}
onChange={this.handlePageChange}
nextDisabled={
this.state.postsRes?.state !== "success" ||
fetchLimit > this.state.postsRes.data.posts.length
}
/>
</div> </div>
</div> </div>
); );

View file

@ -860,7 +860,11 @@ export class Modlog extends Component<
</thead> </thead>
{this.combined} {this.combined}
</table> </table>
<Paginator page={page} onChange={this.handlePageChange} /> <Paginator
page={page}
onChange={this.handlePageChange}
nextDisabled={false}
/>
</div> </div>
); );
} }

View file

@ -256,6 +256,7 @@ export class Inbox extends Component<any, InboxState> {
<Paginator <Paginator
page={this.state.page} page={this.state.page}
onChange={this.handlePageChange} onChange={this.handlePageChange}
nextDisabled={false}
/> />
</div> </div>
</div> </div>

View file

@ -115,7 +115,16 @@ export class PersonDetails extends Component<PersonDetailsProps, any> {
<div className="person-details"> <div className="person-details">
{this.viewSelector(this.props.view)} {this.viewSelector(this.props.view)}
<Paginator page={this.props.page} onChange={this.handlePageChange} /> <Paginator
page={this.props.page}
onChange={this.handlePageChange}
nextDisabled={
(this.props.view === PersonDetailsView.Comments &&
this.props.limit > this.props.personRes.comments.length) ||
(this.props.view === PersonDetailsView.Posts &&
this.props.limit > this.props.personRes.posts.length)
}
/>
</div> </div>
); );
} }

View file

@ -110,6 +110,7 @@ export class RegistrationApplications extends Component<
<Paginator <Paginator
page={this.state.page} page={this.state.page}
onChange={this.handlePageChange} onChange={this.handlePageChange}
nextDisabled={fetchLimit > apps.length}
/> />
</div> </div>
</div> </div>

View file

@ -160,6 +160,16 @@ export class Reports extends Component<any, ReportsState> {
<Paginator <Paginator
page={this.state.page} page={this.state.page}
onChange={this.handlePageChange} onChange={this.handlePageChange}
nextDisabled={
(this.state.messageType === MessageType.All &&
fetchLimit > this.buildCombined.length) ||
(this.state.messageType === MessageType.CommentReport &&
fetchLimit > this.commentReports.length) ||
(this.state.messageType === MessageType.PostReport &&
fetchLimit > this.postReports.length) ||
(this.state.messageType === MessageType.PrivateMessageReport &&
fetchLimit > this.privateMessageReports.length)
}
/> />
</div> </div>
</div> </div>

View file

@ -479,7 +479,14 @@ export class Search extends Component<any, SearchState> {
this.state.searchRes.state === "success" && ( this.state.searchRes.state === "success" && (
<span>{I18NextService.i18n.t("no_results")}</span> <span>{I18NextService.i18n.t("no_results")}</span>
)} )}
<Paginator page={page} onChange={this.handlePageChange} /> <Paginator
page={page}
onChange={this.handlePageChange}
nextDisabled={
this.state.searchRes.state !== "success" ||
fetchLimit > this.resultsCount
}
/>
</div> </div>
); );
} }

View file

@ -28,6 +28,10 @@ export const relTags = "noopener nofollow";
export const emDash = "\u2014"; export const emDash = "\u2014";
export const authCookieName = "jwt"; export const authCookieName = "jwt";
// No. of max displayed communities per
// page on route "/communities"
export const communityLimit = 50;
/** /**
* Accepted formats: * Accepted formats:
* !community@server.com * !community@server.com