{"version":3,"file":"seniorsistemas-angular-components-paginator.mjs","sources":["../../projects/angular-components/paginator/src/lib/paginator/paginator.component.ts","../../projects/angular-components/paginator/src/lib/paginator/paginator.component.html","../../projects/angular-components/paginator/src/seniorsistemas-angular-components-paginator.ts"],"sourcesContent":["import { Component, computed, effect, input, model, OnDestroy, output, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { InteractiveContentDirective } from '@seniorsistemas/angular-components/interactive-content';\nimport { SelectComponent } from '@seniorsistemas/angular-components/select';\nimport { TranslateModule } from '@ngx-translate/core';\n\nimport { PageChange, PaginatorInternalButton } from '../models/paginator.models';\n/**\n * @description Componente de paginação standalone que exibe botões de páginas,\n * seletor de itens por página e navegação para primeira/última página.\n * Emite `pageChange` a cada mudança de página ou tamanho de página.\n *\n * @example\n * ```html\n * <s-paginator\n *   [totalRecords]=\"total\"\n *   [(rows)]=\"tamanhoPagina\"\n *   (pageChange)=\"onPaginaMudou($event)\" />\n * ```\n *\n * @category Structure\n */\n@Component({\n    selector: 's-paginator',\n    standalone: true,\n    imports: [InteractiveContentDirective, SelectComponent, FormsModule, TranslateModule],\n    templateUrl: './paginator.component.html',\n})\nexport class PaginatorComponent implements OnDestroy {\n    /** @description Número total de registros. Campo obrigatório. */\n    totalRecords = input.required<number>();\n    /** @description Número de itens por página. Suporta two-way binding. @default 10 */\n    rows = model(10);\n    /** @description Opções do seletor de itens por página. @default [10, 20, 50, 100, 200] */\n    rowsPerPageOptions = input<number[]>([10, 20, 50, 100, 200]);\n    /** @description Emitido sempre que a página ou o número de itens por página muda. */\n    pageChange = output<PageChange>();\n\n    private readonly currentPageEffect = effect(() => {\n        const page = this.currentPage() - 1;\n        this.pageChange.emit({\n            page,\n            pageCount: this.totalPages(),\n            rows: this.rows(),\n            first: this.rows() * page,\n        });\n    });\n    private readonly MAX_PAGE_BUTTONS = 5;\n    private readonly hasPreviousPage = computed(() => {\n        const previousPage = this.currentPage() - 1;\n        return previousPage >= 1;\n    });\n\n    private readonly hasNextPage = computed(() => {\n        const nextPage = this.currentPage() + 1;\n        return nextPage <= this.totalPages();\n    });\n\n    protected readonly currentPage = signal(1);\n\n    protected buttons = computed(() => {\n        const navigationPageButtons: PaginatorInternalButton[] = [];\n        const maxPageButtons = this.MAX_PAGE_BUTTONS;\n        const currentPage = this.currentPage();\n        const middle = Math.floor(maxPageButtons / 2);\n        const _startPage = currentPage - middle;\n        let startPage = _startPage < 1 ? 1 : _startPage;\n        const _endPage = startPage + maxPageButtons - 1;\n        const endPageIsMoreThanTotalPages = _endPage > this.totalPages();\n\n        if (endPageIsMoreThanTotalPages) {\n            const diff = _endPage - this.totalPages();\n            const canModifyStartPage = startPage - diff >= 1;\n            if (canModifyStartPage) {\n                startPage = startPage - diff;\n            }\n        }\n        const endPage = endPageIsMoreThanTotalPages ? this.totalPages() : _endPage;\n\n        for (let i = startPage; i <= endPage; i++) {\n            navigationPageButtons.push({\n                clicked: (page) => this.goToPage(page.pageIndex as number),\n                pageIndex: i,\n            });\n        }\n\n        return [\n            this.FIRST_PAGE_BUTTON,\n            this.PREVIOUS_PAGE_BUTTON,\n            ...navigationPageButtons,\n            this.NEXT_PAGE_BUTTON,\n            this.LAST_PAGE_BUTTON,\n        ];\n    });\n\n    private readonly FIRST_PAGE_BUTTON: PaginatorInternalButton = {\n        clicked: this.goFirstPage.bind(this),\n        icon: 'fas fa-step-backward',\n        validate: computed(() => {\n            return !this.hasPreviousPage();\n        }),\n    };\n\n    private readonly PREVIOUS_PAGE_BUTTON: PaginatorInternalButton = {\n        clicked: this.goPreviousPage.bind(this),\n        icon: 'fas fa-caret-left',\n        validate: computed(() => {\n            return !this.hasPreviousPage();\n        }),\n    };\n\n    private readonly LAST_PAGE_BUTTON: PaginatorInternalButton = {\n        clicked: this.goLastPage.bind(this),\n        icon: 'fas fa-step-forward',\n        validate: computed(() => {\n            return !this.hasNextPage();\n        }),\n    };\n\n    private readonly NEXT_PAGE_BUTTON: PaginatorInternalButton = {\n        clicked: this.goNextPage.bind(this),\n        icon: 'fas fa-caret-right',\n        validate: computed(() => {\n            return !this.hasNextPage();\n        }),\n    };\n\n    private totalPages = computed(() => {\n        const totalRecords = this.totalRecords();\n        const _pages = totalRecords / this.rows();\n        const pages = Math.ceil(_pages);\n        const isExactPages = _pages === pages;\n        return isExactPages ? pages : pages + 1;\n    });\n\n    public ngOnDestroy(): void {\n        this.currentPageEffect.destroy();\n    }\n\n    protected rowsPerPageChange(): void {\n        if (this.currentPage() !== 1) {\n            this.goToPage(1);\n        }\n    }\n\n    protected activatedButton(button: PaginatorInternalButton): void {\n        button.clicked(button);\n    }\n\n    private goFirstPage(): void {\n        this.goToPage(1);\n    }\n\n    private goNextPage(): void {\n        if (!this.hasNextPage()) {\n            return;\n        }\n        this.currentPage.update((value) => value + 1);\n    }\n\n    private goPreviousPage(): void {\n        if (!this.hasPreviousPage()) {\n            return;\n        }\n        this.currentPage.update((value) => value - 1);\n    }\n\n    private goLastPage(): void {\n        this.goToPage(this.totalPages());\n    }\n\n    private goToPage(pageIndex: number): void {\n        this.currentPage.set(pageIndex);\n    }\n}\n\n","<div class=\"flex justify-between\">\n    <section class=\"flex items-center gap-2\">\n        <div\n            class=\"inline-block h-8 divide-x divide-grayscale-30 overflow-hidden rounded-md border border-grayscale-30\"\n        >\n            @for (btn of buttons(); track $index) {\n                @let active = btn.pageIndex === currentPage();\n                <button\n                    [class.bg-criticality-blue]=\"active\"\n                    [class.text-grayscale-0]=\"active\"\n                    [class.text-criticality-blue]=\"!active\"\n                    (sInteractiveContent)=\"activatedButton(btn)\"\n                    [disabled]=\"btn.disabled || (btn.validate && btn.validate()) || false\"\n                    class=\"group h-8 w-8 hover:bg-grayscale-20 hover:text-grayscale-100 disabled:hover:bg-[transparent] disabled:hover:text-criticality-blue\"\n                >\n                    <div class=\"group-disabled:opacity-50\">\n                        @let page = btn.pageIndex;\n                        @let icon = btn.icon;\n                        @if (page !== undefined) {\n                            {{ page }}\n                        }\n                        @if (icon) {\n                            <i [class]=\"icon\"></i>\n                        }\n                    </div>\n                </button>\n            }\n        </div>\n        <s-select\n            [options]=\"rowsPerPageOptions()\"\n            [(ngModel)]=\"rows\"\n            (ngModelChange)=\"rowsPerPageChange()\"\n        ></s-select>\n    </section>\n    <section class=\"flex items-center gap-2\">\n        @let text =\n            totalRecords() === 0\n                ? 'platform.angular_components.total_record'\n                : 'platform.angular_components.total_records';\n        <p class=\"text-[14px] text-[#212533]\">\n            {{ text | translate: { count: totalRecords() } }}\n        </p>\n        <ng-content></ng-content>\n    </section>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}