{"version":3,"file":"toolbox-pagination.mjs","sources":["../../../projects/toolbox/pagination/pagination.helpers.ts","../../../projects/toolbox/pagination/pagination.component.ts","../../../projects/toolbox/pagination/pagination.component.html","../../../projects/toolbox/pagination/toolbox-pagination.ts"],"sourcesContent":["/* eslint-disable no-param-reassign */\r\nimport { TbxPagination } from \"./pagination.model\";\r\n\r\n/**\r\n * Gets pagination information based on the specified information.\r\n * @param totalItems The total items.\r\n * @param currentPage The current page.\r\n * @param pageSize The number of items to display in the page.\r\n * @returns A {@link TbxPagination} with the pagination information.\r\n */\r\nexport const calculatePages = (\r\n  totalItems: number, currentPage = 1, pageSize = 15\r\n): TbxPagination => {\r\n\r\n  const totalPages = Math.ceil( totalItems / pageSize );\r\n\r\n  // Ensure current page is not out of range\r\n  if( currentPage < 1 ) {\r\n    currentPage = 1;\r\n  }\r\n  else if( currentPage > totalPages ) {\r\n    currentPage = totalPages;\r\n  }\r\n\r\n  let startPage: number;\r\n  let endPage: number;\r\n\r\n  // Show all when less than total pages\r\n  if( totalPages <= 5 ) {\r\n    startPage = 1;\r\n    endPage = totalPages;\r\n  }\r\n  else {\r\n    // Calculate start and end pages when more than default\r\n    if( currentPage <= 3 ) {\r\n      startPage = 1;\r\n      endPage = 5;\r\n    }\r\n    else if( currentPage + 1 >= totalPages ) {\r\n      startPage = totalPages - 4;\r\n      endPage = totalPages;\r\n    }\r\n    else {\r\n      startPage = currentPage - 2;\r\n      endPage = currentPage + 2;\r\n    }\r\n  }\r\n\r\n  // Calculate start and end item indexes\r\n  const startIndex = (\r\n    currentPage - 1\r\n  ) * pageSize;\r\n  const endIndex = Math.min( startIndex + pageSize - 1, totalItems - 1 );\r\n\r\n  // Create an array of pages to repeat in the pagination control\r\n  const pages =\r\n    Array.from( Array( (\r\n      endPage + 1\r\n    ) - startPage ).keys() ).map( i => startPage + i );\r\n\r\n  // Return object with all pagination properties required by the view\r\n  return {\r\n    totalItems,\r\n    currentPage,\r\n    pageSize,\r\n    totalPages,\r\n    startPage,\r\n    endPage,\r\n    startIndex,\r\n    endIndex,\r\n    pages\r\n  };\r\n};\r\n","import { NgClass } from \"@angular/common\";\r\nimport {\r\n  Component, Input, input, output,\r\n  ViewEncapsulation,\r\n  ChangeDetectionStrategy, model\r\n} from \"@angular/core\";\r\nimport { FormsModule } from \"@angular/forms\";\r\n\r\nimport { TbxPagination } from \"./pagination.model\";\r\nimport { TbxPaginationEvent } from \"./pagination.event\";\r\nimport { calculatePages } from \"./pagination.helpers\";\r\n\r\n/**\r\n * Displays pagination controls using Bootstrap's Pagination class.\r\n */\r\n@Component( {\n    selector: \"tbx-pagination\",\n    templateUrl: \"./pagination.component.html\",\n    styleUrls: [\"./pagination.component.scss\"],\n    encapsulation: ViewEncapsulation.None,\n    changeDetection: ChangeDetectionStrategy.OnPush,\n    imports: [FormsModule, NgClass]\n} )\r\nexport class TbxPaginationComponent {\r\n  /** An array of sizes that can be selected (defaults to 10, 15, 25, 50, and 100). */\r\n  public sizeOptions = input<number[]>( [5, 10, 15, 25, 50, 75, 100] );\r\n\r\n  /** Show/hide the drop-down to allow user to select different page sizes. */\r\n  public showSizeOptions = input<boolean>( true );\r\n\r\n  /** The number of items per page to be displayed (defaults to 25). */\r\n  public selectedSize = model<number>( 25 );\r\n\r\n  /** The event when the user clicks on a page button. */\r\n  public pageChange = output<TbxPaginationEvent>();\r\n\r\n  /** Stores the pagination calculation. */\r\n  public pagination?: TbxPagination;\r\n\r\n  /** Stores a reference to the items to paginate against. */\r\n  private internalItemCount = 0;\r\n\r\n  /** The items to use in calculating the number of pages. */\r\n  @Input()\r\n  public get totalItems(): number { return this.internalItemCount; }\r\n\r\n  public set totalItems( count: number ) {\r\n    this.internalItemCount = count;\r\n\r\n    // https://tinyurl.com/y7drfj5p\r\n    void Promise.resolve( null ).then( () => {\r\n      // Reset to the first page on item total change\r\n      this.calculate( 1 );\r\n      this.pageChange.emit( this.createPaginationEvent() );\r\n    } );\r\n  }\r\n\r\n  /**\r\n   * Called when the user clicks on a page button.\r\n   * @param page The page to display.\r\n   * @param event The event details.\r\n   */\r\n  public onPageChange( page: number, event: MouseEvent ): void {\r\n    event.preventDefault();\r\n\r\n    this.calculate( page );\r\n    this.pageChange.emit( this.createPaginationEvent() );\r\n  }\r\n\r\n  /** Called when the user selects a page size. */\r\n  public selectSizeChange(): void {\r\n    this.calculate( 1 );\r\n    this.pageChange.emit( this.createPaginationEvent() );\r\n  }\r\n\r\n  private calculate( pageNumber: number ): void {\r\n    this.pagination = calculatePages(\r\n      this.internalItemCount, pageNumber, +this.selectedSize() );\r\n  }\r\n\r\n  private createPaginationEvent(): TbxPaginationEvent {\r\n    const startIndex = this.pagination?.startIndex ?? 0;\r\n    const endIndex = startIndex + ( this.pagination?.pageSize ?? 0 ) - 1;\r\n\r\n    return {\r\n      totalItems: this.pagination?.totalItems ?? 0,\r\n      selectedPage: this.pagination?.currentPage ?? 0,\r\n      selectedPageSize: this.pagination?.pageSize ?? 0,\r\n      totalPages: this.pagination?.totalPages ?? 0,\r\n      startPage: this.pagination?.startPage ?? 0,\r\n      endPage: this.pagination?.endPage ?? 0,\r\n      startIndex,\r\n      endIndex,\r\n      pages: this.pagination?.pages ?? []\r\n    };\r\n  }\r\n}\r\n","@if (pagination) {\r\n  <div class=\"pagination-container\">\r\n\r\n    @if (showSizeOptions()) {\r\n      <div class=\"page-items d-none d-md-block\">\r\n        <label for=\"sizeOptions\" class=\"hidden-xs\">Items per page: &nbsp;</label>\r\n        <select id=\"sizeOptions\"\r\n                name=\"selectedSize\"\r\n                (change)=\"selectSizeChange()\"\r\n                [(ngModel)]=\"selectedSize\">\r\n          @for (option of sizeOptions(); track option) {\r\n            <option value=\"{{option}}\">{{ option }}\r\n            </option>\r\n          }\r\n        </select>\r\n      </div>\r\n    }\r\n\r\n    @if (pagination.startIndex > -1) {\r\n      <div class=\"item-count text-muted d-none d-sm-block\">\r\n        {{ pagination.startIndex + 1 }} - {{ pagination.endIndex + 1 }} of\r\n        {{ pagination.totalItems }}\r\n      </div>\r\n    }\r\n\r\n    <ul class=\"pagination\">\r\n      <li class=\"page-item\" [ngClass]=\"{disabled:pagination.currentPage === 1}\">\r\n        <button class=\"page-link\" (click)=\"onPageChange( 1, $event )\">\r\n          &#8676;\r\n        </button>\r\n      </li>\r\n      <li class=\"page-item\" [ngClass]=\"{disabled:pagination.currentPage === 1}\">\r\n        <button class=\"page-link\"\r\n                (click)=\"onPageChange( pagination.currentPage - 1, $event )\">\r\n          &#8592;\r\n        </button>\r\n      </li>\r\n\r\n      @for (page of pagination.pages; track page) {\r\n        <li class=\"page-item\"\r\n            [ngClass]=\"{active:pagination.currentPage === page}\">\r\n          <button class=\"page-link\" (click)=\"onPageChange( page, $event )\">\r\n            {{ page }}\r\n          </button>\r\n        </li>\r\n      }\r\n\r\n      <li class=\"page-item\"\r\n          [ngClass]=\"{disabled:pagination.currentPage === pagination.totalPages}\">\r\n        <button class=\"page-link\"\r\n                (click)=\"onPageChange( pagination.currentPage + 1, $event )\">\r\n          &rarr;\r\n        </button>\r\n      </li>\r\n      <li class=\"page-item\"\r\n          [ngClass]=\"{disabled:pagination.currentPage === pagination.totalPages}\">\r\n        <button class=\"page-link\"\r\n                (click)=\"onPageChange( pagination.totalPages, $event )\">\r\n          &#8677;\r\n        </button>\r\n      </li>\r\n    </ul>\r\n  </div>\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}