diff --git a/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.module.css b/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.module.css
index 367ca7c..d9ed884 100644
--- a/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.module.css
+++ b/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.module.css
@@ -24,6 +24,8 @@
align-items: center;
gap: 10px;
flex-shrink: 0;
+ flex-wrap: wrap;
+ flex: 1;
}
.activeFiltersCount {
@@ -72,7 +74,7 @@
.floatingLabelInput {
position: relative;
- width: 250px;
+ width: 400px;
}
.label {
@@ -280,3 +282,167 @@
}
}
+/* Pagination Controls */
+.paginationControls {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-shrink: 0;
+ margin-left: auto;
+ flex-wrap: wrap;
+}
+
+.pageSizeSelector {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-size: 14px;
+ color: var(--color-text);
+}
+
+.pageSizeSelector label {
+ white-space: nowrap;
+ font-family: var(--font-family);
+}
+
+.pageSizeSelect {
+ height: 32px;
+ padding: 4px 8px;
+ border: 1px solid var(--color-primary);
+ border-radius: 4px;
+ font-size: 14px;
+ font-family: var(--font-family);
+ background: var(--color-bg);
+ color: var(--color-text);
+ cursor: pointer;
+ min-width: 60px;
+}
+
+.pageSizeSelect:focus {
+ outline: none;
+ border-color: var(--color-secondary);
+}
+
+.paginationButton {
+ width: 36px;
+ height: 36px;
+ padding: 0;
+ border: none;
+ background: var(--color-secondary);
+ color: white;
+ border-radius: 50%;
+ cursor: pointer;
+ font-family: var(--font-family);
+ transition: all 0.2s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 18px;
+ font-weight: 500;
+ flex-shrink: 0;
+}
+
+.paginationButton:hover:not(:disabled) {
+ background: var(--color-secondary-hover);
+}
+
+.paginationButton:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.paginationInfo {
+ font-size: 14px;
+ color: var(--color-text);
+ white-space: nowrap;
+ flex-shrink: 0;
+}
+
+/* Page numbers container */
+.pageNumbers {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 2px;
+ align-items: center;
+ justify-content: flex-start;
+ max-width: 40vw;
+ max-height: 120px;
+ overflow-y: auto;
+ padding: 4px;
+}
+
+/* Individual page number button */
+.pageNumber {
+ min-width: 28px;
+ height: 28px;
+ padding: 0 6px;
+ border: 1px solid var(--color-border, #ddd);
+ background: var(--color-bg, #fff);
+ color: var(--color-text);
+ border-radius: 4px;
+ cursor: pointer;
+ font-family: var(--font-family);
+ font-size: 12px;
+ transition: all 0.15s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.pageNumber:hover:not(:disabled) {
+ background: var(--color-secondary);
+ color: white;
+ border-color: var(--color-secondary);
+}
+
+.pageNumber:disabled {
+ cursor: default;
+}
+
+/* Active/current page number */
+.pageNumberActive {
+ background: var(--color-secondary);
+ color: white;
+ border-color: var(--color-secondary);
+ font-weight: 600;
+}
+
+/* Ellipsis indicator */
+.pageEllipsis {
+ padding: 0 8px;
+ color: var(--color-text-secondary, #666);
+ font-size: 14px;
+}
+
+/* Responsive Design for Pagination */
+@media (max-width: 768px) {
+ .paginationControls {
+ flex-direction: column;
+ align-items: stretch;
+ gap: 10px;
+ margin-left: 0;
+ width: 100%;
+ }
+
+ .pageSizeSelector {
+ order: -1;
+ justify-content: center;
+ }
+
+ .paginationInfo {
+ text-align: center;
+ font-size: 13px;
+ }
+
+ .pageNumbers {
+ max-width: 100%;
+ justify-content: center;
+ }
+
+ .pageNumber {
+ min-width: 24px;
+ height: 24px;
+ font-size: 11px;
+ }
+}
+
diff --git a/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.tsx b/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.tsx
index 4439c77..7fc4137 100644
--- a/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.tsx
+++ b/src/components/FormGenerator/FormGeneratorControls/FormGeneratorControls.tsx
@@ -1,3 +1,4 @@
+import React from 'react';
import { useLanguage } from '../../../providers/language/LanguageContext';
import styles from './FormGeneratorControls.module.css';
import { Button } from '../../UiComponents/Button';
@@ -49,6 +50,18 @@ export interface FormGeneratorControlsProps {
// Active filters count for display
activeFiltersCount?: number;
+
+ // Pagination props
+ pagination?: boolean;
+ currentPage?: number;
+ totalPages?: number;
+ currentPageSize?: number;
+ pageSizeOptions?: number[];
+ showPageSizeSelector?: boolean;
+ onPageChange?: (page: number) => void;
+ onPageSizeChange?: (pageSize: number) => void;
+ supportsBackendPagination?: boolean;
+ hookData?: any;
}
export function FormGeneratorControls({
@@ -64,7 +77,17 @@ export function FormGeneratorControls({
searchable = true,
selectable = true,
loading = false,
- activeFiltersCount = 0
+ activeFiltersCount = 0,
+ pagination = false,
+ currentPage = 1,
+ totalPages = 1,
+ currentPageSize = 10,
+ pageSizeOptions = [10, 25, 50, 100, 500],
+ showPageSizeSelector = true,
+ onPageChange,
+ onPageSizeChange,
+ supportsBackendPagination = false,
+ hookData
}: FormGeneratorControlsProps) {
const { t } = useLanguage();
@@ -101,7 +124,7 @@ export function FormGeneratorControls({
)}
- {/* Search Controls - Hide when items are selected */}
+ {/* Search Controls with Pagination - Hide when items are selected */}
{searchable && selectedCount === 0 && (
@@ -133,6 +156,109 @@ export function FormGeneratorControls({
)}
+
+ {/* Pagination Controls */}
+ {pagination && supportsBackendPagination && onPageChange && (
+
+ {showPageSizeSelector && onPageSizeChange && (
+
+
+
+
+ )}
+
+
+
+
+ {/* Page number buttons - show up to 100 pages before and after current */}
+
+ {(() => {
+ const maxPagesVisible = 100; // Max pages to show on each side
+ const startPage = Math.max(1, currentPage - maxPagesVisible);
+ const endPage = Math.min(totalPages, currentPage + maxPagesVisible);
+ const pages: React.ReactNode[] = [];
+
+ // Show ellipsis at start if we're not showing page 1
+ if (startPage > 1) {
+ pages.push(
+ ...
+ );
+ }
+
+ // Generate page buttons
+ for (let i = startPage; i <= endPage; i++) {
+ pages.push(
+
+ );
+ }
+
+ // Show ellipsis at end if we're not showing last page
+ if (endPage < totalPages) {
+ pages.push(
+ ...
+ );
+ }
+
+ return pages;
+ })()}
+
+
+
+
+
+ {/* Total items count */}
+
+ ({hookData?.pagination?.totalItems != null
+ ? hookData.pagination.totalItems.toString()
+ : (loading ? '...' : displayData.length.toString())} {t('formgen.pagination.items', 'items')})
+
+
+ )}
)}
diff --git a/src/components/FormGenerator/FormGeneratorTable/FormGeneratorTable.module.css b/src/components/FormGenerator/FormGeneratorTable/FormGeneratorTable.module.css
index 95433d3..9ff925f 100644
--- a/src/components/FormGenerator/FormGeneratorTable/FormGeneratorTable.module.css
+++ b/src/components/FormGenerator/FormGeneratorTable/FormGeneratorTable.module.css
@@ -74,6 +74,7 @@
font-size: 14px;
background: var(--color-bg);
table-layout: fixed;
+ word-wrap: break-word;
}
/* Disabled user row styling */
@@ -104,9 +105,13 @@
text-align: left;
font-weight: 400;
color: var(--color-text);
- white-space: nowrap;
+ white-space: normal;
+ word-wrap: break-word;
+ overflow-wrap: break-word;
+ word-break: break-word;
user-select: none;
z-index: 10;
+ overflow: visible;
}
.th.actionsColumn {
@@ -286,6 +291,11 @@
border-top: 1px solid var(--color-primary);
color: var(--color-text);
vertical-align: middle;
+ word-wrap: break-word;
+ overflow-wrap: break-word;
+ word-break: break-word;
+ white-space: normal;
+ overflow: visible;
}
diff --git a/src/components/FormGenerator/FormGeneratorTable/FormGeneratorTable.tsx b/src/components/FormGenerator/FormGeneratorTable/FormGeneratorTable.tsx
index 2fbabc1..8aafec5 100644
--- a/src/components/FormGenerator/FormGeneratorTable/FormGeneratorTable.tsx
+++ b/src/components/FormGenerator/FormGeneratorTable/FormGeneratorTable.tsx
@@ -1150,116 +1150,19 @@ export function FormGeneratorTable>({
selectable={selectable}
loading={loading}
activeFiltersCount={activeFiltersCount}
+ pagination={pagination}
+ currentPage={currentPage}
+ totalPages={totalPages}
+ currentPageSize={currentPageSize}
+ pageSizeOptions={pageSizeOptions}
+ showPageSizeSelector={showPageSizeSelector}
+ onPageChange={setCurrentPage}
+ onPageSizeChange={handlePageSizeChange}
+ supportsBackendPagination={supportsBackendPagination}
+ hookData={hookData}
/>
)}
- {/* Pagination - Above Table */}
- {pagination && (
-
- {showPageSizeSelector && (
-
-
-
-
- )}
-
- {pagination && supportsBackendPagination && (
- <>
-
-
-
- {/* Page number buttons - show up to 100 pages before and after current */}
-
- {(() => {
- const maxPagesVisible = 100; // Max pages to show on each side
- const startPage = Math.max(1, currentPage - maxPagesVisible);
- const endPage = Math.min(totalPages, currentPage + maxPagesVisible);
- const pages: React.ReactNode[] = [];
-
- // Show ellipsis at start if we're not showing page 1
- if (startPage > 1) {
- pages.push(
- ...
- );
- }
-
- // Generate page buttons
- for (let i = startPage; i <= endPage; i++) {
- pages.push(
-
- );
- }
-
- // Show ellipsis at end if we're not showing last page
- if (endPage < totalPages) {
- pages.push(
- ...
- );
- }
-
- return pages;
- })()}
-
-
-
-
-
- {/* Total items count */}
-
- ({hookData?.pagination?.totalItems != null
- ? hookData.pagination.totalItems.toString()
- : (loading ? '...' : displayData.length.toString())} {t('formgen.pagination.items', 'items')})
-
- >
- )}
-
- )}
-
{/* Table */}
{/* Loading overlay - shown while loading */}