@ticatec/uniface-element 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accordion/README.md +169 -0
- package/dist/accordion/README_CN.md +176 -0
- package/dist/action-bar/README.md +275 -0
- package/dist/action-bar/README_CN.md +285 -0
- package/dist/app-layout/README.md +374 -0
- package/dist/app-layout/README_CN.md +381 -0
- package/dist/app-top-bar/README.md +357 -0
- package/dist/app-top-bar/README_CN.md +365 -0
- package/dist/attachment-files/AttachmentFilesField.svelte +67 -1
- package/dist/attachment-files/AttachmentFilesField.svelte.d.ts +8 -1
- package/dist/base-calendar/CalendarBase.svelte +0 -3
- package/dist/box/README.md +385 -0
- package/dist/box/README_CN.md +393 -0
- package/dist/breadcrumbs/README.md +442 -0
- package/dist/breadcrumbs/README_CN.md +442 -0
- package/dist/button/Button.svelte +27 -7
- package/dist/button/Button.svelte.d.ts +3 -1
- package/dist/button/IconButton.svelte +26 -6
- package/dist/button/IconButton.svelte.d.ts +3 -1
- package/dist/button/IconButton_README.md +513 -0
- package/dist/button/IconButton_README_CN.md +513 -0
- package/dist/button/README.md +428 -0
- package/dist/button/README_CN.md +428 -0
- package/dist/button/TextButton.svelte +26 -6
- package/dist/button/TextButton.svelte.d.ts +3 -1
- package/dist/button/TextButton_README.md +571 -0
- package/dist/button/TextButton_README_CN.md +571 -0
- package/dist/card/README.md +666 -0
- package/dist/card/README_CN.md +666 -0
- package/dist/cascade-options-select/CascadeOptionSelect.svelte +43 -7
- package/dist/cascade-options-select/CascadeOptionSelect.svelte.d.ts +3 -4
- package/dist/cascade-options-select/README.md +663 -2
- package/dist/cascade-options-select/README_CN.md +664 -0
- package/dist/checkbox/CheckBox.svelte +20 -6
- package/dist/checkbox/CheckBox.svelte.d.ts +4 -2
- package/dist/checkbox/README.md +562 -0
- package/dist/checkbox/README_CN.md +727 -0
- package/dist/common-editor/NumberInput.svelte +39 -26
- package/dist/common-editor/NumberInput.svelte.d.ts +5 -1
- package/dist/concise-data-table/ConciseListTable.svelte +133 -36
- package/dist/concise-data-table/ConciseListTable.svelte.d.ts +8 -1
- package/dist/concise-data-table/DataCell.svelte +5 -6
- package/dist/concise-data-table/DataRow.svelte +22 -2
- package/dist/concise-data-table/DataRow.svelte.d.ts +1 -0
- package/dist/concise-data-table/README.md +606 -0
- package/dist/concise-data-table/README_CN.md +611 -0
- package/dist/context-menu/ContextMenu.svelte +138 -21
- package/dist/context-menu/ContextMenu.svelte.d.ts +5 -0
- package/dist/context-menu/ContextMenuItem.d.ts +20 -4
- package/dist/context-menu/README.md +551 -0
- package/dist/context-menu/README_CN.md +551 -0
- package/dist/criteria-field/CriteriaField.svelte +3 -5
- package/dist/criteria-field/README.md +532 -0
- package/dist/criteria-field/README_CN.md +532 -0
- package/dist/data-table/README.md +712 -0
- package/dist/data-table/README_CN.md +712 -0
- package/dist/date-picker/DatePicker.svelte +44 -7
- package/dist/date-picker/DatePicker.svelte.d.ts +3 -4
- package/dist/date-picker/DateTimePicker.svelte +32 -8
- package/dist/date-picker/DateTimePicker.svelte.d.ts +3 -4
- package/dist/date-picker/README.md +326 -0
- package/dist/date-picker/README_CN.md +316 -0
- package/dist/date-picker/ScrollBar.svelte +18 -8
- package/dist/date-picker/ScrollBar.svelte.d.ts +1 -1
- package/dist/date-picker/TimePanel.svelte +5 -5
- package/dist/date-picker/TimePanel.svelte.d.ts +1 -1
- package/dist/date-range/README.md +374 -0
- package/dist/date-range/README_CN.md +374 -0
- package/dist/dialog/DialogBoard.svelte +1 -1
- package/dist/dialog/README.md +596 -0
- package/dist/dialog/README_CN.md +596 -0
- package/dist/drawer/README.md +679 -1
- package/dist/drawer/README_CN.md +679 -0
- package/dist/group-box/group-check-box/GroupCheckBox.svelte +62 -5
- package/dist/group-box/group-check-box/GroupCheckBox.svelte.d.ts +7 -2
- package/dist/group-box/group-check-box/README.md +749 -0
- package/dist/group-box/group-check-box/README_CN.md +750 -0
- package/dist/group-box/group-radio-box/GroupRadioBox.svelte +69 -4
- package/dist/group-box/group-radio-box/GroupRadioBox.svelte.d.ts +8 -2
- package/dist/group-box/group-radio-box/README.md +920 -0
- package/dist/group-box/group-radio-box/README_CN.md +920 -0
- package/dist/image-files/README.md +1346 -0
- package/dist/image-files/README_CN.md +1346 -0
- package/dist/input-options-select/InputOptionsSelect.svelte +161 -65
- package/dist/input-options-select/InputOptionsSelect.svelte.d.ts +4 -1
- package/dist/lib/forwardAllEvents.d.ts +3 -0
- package/dist/lib/forwardAllEvents.js +24 -0
- package/dist/list-box/README.md +579 -0
- package/dist/list-box/README_CN.md +682 -0
- package/dist/lookup-editor/LookupEditor.svelte +15 -3
- package/dist/lookup-editor/LookupEditor.svelte.d.ts +3 -4
- package/dist/lookup-editor/README.md +684 -0
- package/dist/lookup-editor/README_CN.md +684 -0
- package/dist/memo-editor/MemoEditor.svelte +77 -27
- package/dist/memo-editor/MemoEditor.svelte.d.ts +6 -3
- package/dist/memo-editor/README.md +819 -0
- package/dist/memo-editor/README_CN.md +819 -0
- package/dist/message-box/README.md +398 -0
- package/dist/message-box/README_CN.md +398 -0
- package/dist/number-editor/NumberEditor.svelte +2 -2
- package/dist/number-editor/NumberEditor.svelte.d.ts +1 -1
- package/dist/number-editor/README.md +353 -22
- package/dist/number-editor/README_CN.md +357 -0
- package/dist/number-range/README.md +443 -0
- package/dist/number-range/README_CN.md +443 -0
- package/dist/options-multi-select/OptionsMultiSelect.svelte +87 -12
- package/dist/options-multi-select/OptionsMultiSelect.svelte.d.ts +3 -1
- package/dist/options-multi-select/README.md +480 -0
- package/dist/options-multi-select/README_CN.md +480 -0
- package/dist/options-select/OptionsSelect.svelte +36 -5
- package/dist/options-select/OptionsSelect.svelte.d.ts +3 -4
- package/dist/options-select/README.md +632 -0
- package/dist/options-select/README_CN.md +632 -0
- package/dist/page/README.md +605 -0
- package/dist/page/README_CN.md +605 -0
- package/dist/pagination/README.md +946 -0
- package/dist/pagination/README_CN.md +946 -0
- package/dist/pagination-panel/README.md +1075 -0
- package/dist/pagination-panel/README_CN.md +1075 -0
- package/dist/popup-hint/README.md +841 -0
- package/dist/popup-hint/README_CN.md +840 -0
- package/dist/progress-bar/README.md +242 -0
- package/dist/progress-bar/README_CN.md +242 -0
- package/dist/progress-step-bar/README.md +316 -0
- package/dist/progress-step-bar/README_CN.md +316 -0
- package/dist/prompts-text-editor/PromptsTextEditor.svelte +6 -3
- package/dist/prompts-text-editor/PromptsTextEditor.svelte.d.ts +3 -1
- package/dist/prompts-text-editor/README.md +329 -0
- package/dist/prompts-text-editor/README_CN.md +329 -0
- package/dist/property-editor/README.md +969 -0
- package/dist/property-editor/README_CN.md +969 -0
- package/dist/radio-button/README.md +372 -0
- package/dist/radio-button/README_CN.md +372 -0
- package/dist/radio-button/RadioButton.svelte +32 -3
- package/dist/radio-button/RadioButton.svelte.d.ts +12 -1
- package/dist/search-box/README.md +425 -0
- package/dist/search-box/README_CN.md +424 -0
- package/dist/search-box/SearchBox.svelte +22 -6
- package/dist/search-box/SearchBox.svelte.d.ts +4 -1
- package/dist/tabs/README.md +919 -0
- package/dist/tabs/README_CN.md +920 -0
- package/dist/tag/README.md +922 -0
- package/dist/tag/README_CN.md +922 -0
- package/dist/text-editor/PasswordEditor.svelte +17 -2
- package/dist/text-editor/PasswordEditor.svelte.d.ts +3 -3
- package/dist/text-editor/PasswordEditor_README.md +551 -0
- package/dist/text-editor/PasswordEditor_README_CN.md +551 -0
- package/dist/text-editor/README.md +466 -0
- package/dist/text-editor/README_CN.md +466 -0
- package/dist/text-editor/TextEditor.svelte +51 -19
- package/dist/text-editor/TextEditor.svelte.d.ts +0 -1
- package/dist/ticatec-uniface-web.css +1 -0
- package/dist/time-editor/README.md +498 -24
- package/dist/time-editor/README_CN.md +498 -0
- package/dist/time-editor/TimeEditor.svelte +7 -3
- package/dist/time-editor/TimeEditor.svelte.d.ts +3 -1
- package/dist/toast/README.md +667 -0
- package/dist/toast/README_CN.md +667 -0
- package/dist/transfer/README.md +795 -0
- package/dist/transfer/Transfer.svelte +6 -4
- package/dist/transfer/Transfer.svelte.d.ts +3 -1
- package/dist/tree-view/README.md +761 -0
- package/dist/tree-view/README_CN.md +761 -0
- package/dist/tree-view/TreeView.svelte +5 -3
- package/dist/tree-view/TreeView.svelte.d.ts +3 -1
- package/dist/unit-number-editor/README.md +546 -20
- package/dist/unit-number-editor/README_CN.md +525 -0
- package/dist/unit-number-editor/UnitNumberEditor.svelte +62 -8
- package/dist/unit-number-editor/UnitNumberEditor.svelte.d.ts +5 -1
- package/docs/form-field/cn/README_CN.md +364 -0
- package/docs/form-field/en/README.md +364 -0
- package/docs/form-panel/flex-form/cn/README_CN.md +586 -0
- package/docs/form-panel/flex-form/en/README.md +586 -0
- package/docs/form-panel/flex-row-form/cn/README_CN.md +787 -0
- package/docs/form-panel/flex-row-form/en/README.md +787 -0
- package/docs/form-panel/grid-form/en/README.md +744 -0
- package/package.json +1 -1
- package/dist/drawer/README-CN.md +0 -1
|
@@ -0,0 +1,1075 @@
|
|
|
1
|
+
# PaginationPanel
|
|
2
|
+
|
|
3
|
+
A comprehensive pagination control panel that combines page navigation, rows per page selection, and total records display in a unified interface.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Complete Pagination**: Includes page navigation, row count selector, and summary info
|
|
8
|
+
- **Customizable Row Options**: Configure available rows per page options
|
|
9
|
+
- **Total Information Display**: Show total records with customizable formatting
|
|
10
|
+
- **Multiple Alignments**: Support for left, right, and center alignment
|
|
11
|
+
- **Size Variants**: Normal and big size options
|
|
12
|
+
- **Style Integration**: Inherits styling from base Pagination component
|
|
13
|
+
- **Custom Info Generator**: Flexible total information display with custom formatting
|
|
14
|
+
- **Event Handling**: Separate handlers for page changes and row count changes
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @ticatec/uniface-element
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Basic Usage
|
|
23
|
+
|
|
24
|
+
```svelte
|
|
25
|
+
<script>
|
|
26
|
+
import PaginationPanel from '@ticatec/uniface-element/PaginationPanel';
|
|
27
|
+
|
|
28
|
+
let currentPage = 1;
|
|
29
|
+
let totalPages = 10;
|
|
30
|
+
let totalRecords = 250;
|
|
31
|
+
let rowsPerPage = 25;
|
|
32
|
+
|
|
33
|
+
function handlePageChange(page) {
|
|
34
|
+
currentPage = page;
|
|
35
|
+
console.log('Page changed to:', page);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function handleRowCountChange(rows) {
|
|
39
|
+
rowsPerPage = rows;
|
|
40
|
+
// Recalculate total pages based on new row count
|
|
41
|
+
totalPages = Math.ceil(totalRecords / rows);
|
|
42
|
+
currentPage = 1; // Reset to first page
|
|
43
|
+
console.log('Rows per page changed to:', rows);
|
|
44
|
+
}
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<PaginationPanel
|
|
48
|
+
pageNo={currentPage}
|
|
49
|
+
pageCount={totalPages}
|
|
50
|
+
total={totalRecords}
|
|
51
|
+
rowCount={rowsPerPage}
|
|
52
|
+
onPageChange={handlePageChange}
|
|
53
|
+
onRowCountChanged={handleRowCountChange}
|
|
54
|
+
/>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## API Reference
|
|
58
|
+
|
|
59
|
+
### Props
|
|
60
|
+
|
|
61
|
+
| Prop | Type | Default | Description |
|
|
62
|
+
|------|------|---------|-------------|
|
|
63
|
+
| `pageNo` | `number` | `1` | Current active page number |
|
|
64
|
+
| `pageCount` | `number` | `0` | Total number of pages |
|
|
65
|
+
| `total` | `number` | `null` | Total number of records |
|
|
66
|
+
| `rowCount` | `number` | `25` | Current rows per page setting |
|
|
67
|
+
| `rowsSet` | `Array<number>` | `[25, 50, 100]` | Available rows per page options |
|
|
68
|
+
| `type` | `'plain' \| 'round' \| 'circle'` | `'round'` | Visual style variant |
|
|
69
|
+
| `page$style` | `string` | `''` | Custom CSS styles for pagination component |
|
|
70
|
+
| `big` | `boolean` | `false` | Enable larger size variant |
|
|
71
|
+
| `rowCountLabel` | `string` | `'Rows/Page'` | Label for rows per page selector |
|
|
72
|
+
| `align` | `'left' \| 'right' \| ''` | `''` | Panel alignment |
|
|
73
|
+
| `generateInfo` | `GenerateTotalInfo \| null` | `null` | Custom function to generate total info text |
|
|
74
|
+
| `onPageChange` | `OnPageChange` | `undefined` | Page change event handler |
|
|
75
|
+
| `onRowCountChanged` | `OnRowCountChanged` | `undefined` | Row count change event handler |
|
|
76
|
+
|
|
77
|
+
### Types
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
export type OnPageChange = (page: number) => void;
|
|
81
|
+
export type OnRowCountChanged = (rows: number) => void;
|
|
82
|
+
export type GenerateTotalInfo = (total: number, pageCount: number, pageNo: number, rows: number) => string;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Examples
|
|
86
|
+
|
|
87
|
+
### Data Table with Full Pagination
|
|
88
|
+
|
|
89
|
+
```svelte
|
|
90
|
+
<script>
|
|
91
|
+
import PaginationPanel from '@ticatec/uniface-element/PaginationPanel';
|
|
92
|
+
|
|
93
|
+
let users = [];
|
|
94
|
+
let currentPage = 1;
|
|
95
|
+
let totalPages = 1;
|
|
96
|
+
let totalUsers = 0;
|
|
97
|
+
let rowsPerPage = 25;
|
|
98
|
+
let loading = false;
|
|
99
|
+
|
|
100
|
+
async function loadUsers(page = 1, rows = 25) {
|
|
101
|
+
loading = true;
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
// Simulate API call
|
|
105
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
106
|
+
|
|
107
|
+
// Mock data
|
|
108
|
+
totalUsers = 237; // Total records from API
|
|
109
|
+
totalPages = Math.ceil(totalUsers / rows);
|
|
110
|
+
currentPage = page;
|
|
111
|
+
|
|
112
|
+
const startIndex = (page - 1) * rows;
|
|
113
|
+
users = Array.from({ length: Math.min(rows, totalUsers - startIndex) }, (_, i) => ({
|
|
114
|
+
id: startIndex + i + 1,
|
|
115
|
+
name: `User ${startIndex + i + 1}`,
|
|
116
|
+
email: `user${startIndex + i + 1}@example.com`,
|
|
117
|
+
role: ['Admin', 'User', 'Moderator'][Math.floor(Math.random() * 3)],
|
|
118
|
+
status: Math.random() > 0.2 ? 'Active' : 'Inactive'
|
|
119
|
+
}));
|
|
120
|
+
} finally {
|
|
121
|
+
loading = false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function handlePageChange(page) {
|
|
126
|
+
loadUsers(page, rowsPerPage);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function handleRowCountChange(rows) {
|
|
130
|
+
rowsPerPage = rows;
|
|
131
|
+
loadUsers(1, rows); // Reset to page 1 with new row count
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Custom info generator
|
|
135
|
+
function generateUserInfo(total, pageCount, pageNo, rows) {
|
|
136
|
+
const start = (pageNo - 1) * rows + 1;
|
|
137
|
+
const end = Math.min(pageNo * rows, total);
|
|
138
|
+
return `Showing <b>${start}-${end}</b> of <b>${total}</b> users`;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Load initial data
|
|
142
|
+
loadUsers(currentPage, rowsPerPage);
|
|
143
|
+
</script>
|
|
144
|
+
|
|
145
|
+
<div class="user-management">
|
|
146
|
+
<h2>User Management</h2>
|
|
147
|
+
|
|
148
|
+
{#if loading}
|
|
149
|
+
<div class="loading">Loading users...</div>
|
|
150
|
+
{:else}
|
|
151
|
+
<table class="users-table">
|
|
152
|
+
<thead>
|
|
153
|
+
<tr>
|
|
154
|
+
<th>ID</th>
|
|
155
|
+
<th>Name</th>
|
|
156
|
+
<th>Email</th>
|
|
157
|
+
<th>Role</th>
|
|
158
|
+
<th>Status</th>
|
|
159
|
+
</tr>
|
|
160
|
+
</thead>
|
|
161
|
+
<tbody>
|
|
162
|
+
{#each users as user}
|
|
163
|
+
<tr>
|
|
164
|
+
<td>{user.id}</td>
|
|
165
|
+
<td>{user.name}</td>
|
|
166
|
+
<td>{user.email}</td>
|
|
167
|
+
<td>{user.role}</td>
|
|
168
|
+
<td class="status {user.status.toLowerCase()}">{user.status}</td>
|
|
169
|
+
</tr>
|
|
170
|
+
{/each}
|
|
171
|
+
</tbody>
|
|
172
|
+
</table>
|
|
173
|
+
{/if}
|
|
174
|
+
|
|
175
|
+
<PaginationPanel
|
|
176
|
+
pageNo={currentPage}
|
|
177
|
+
pageCount={totalPages}
|
|
178
|
+
total={totalUsers}
|
|
179
|
+
rowCount={rowsPerPage}
|
|
180
|
+
rowsSet={[10, 25, 50, 100]}
|
|
181
|
+
rowCountLabel="Users per page"
|
|
182
|
+
generateInfo={generateUserInfo}
|
|
183
|
+
onPageChange={handlePageChange}
|
|
184
|
+
onRowCountChanged={handleRowCountChange}
|
|
185
|
+
align="right"
|
|
186
|
+
/>
|
|
187
|
+
</div>
|
|
188
|
+
|
|
189
|
+
<style>
|
|
190
|
+
.user-management {
|
|
191
|
+
max-width: 1200px;
|
|
192
|
+
margin: 0 auto;
|
|
193
|
+
padding: 20px;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.loading {
|
|
197
|
+
text-align: center;
|
|
198
|
+
padding: 40px;
|
|
199
|
+
color: #666;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.users-table {
|
|
203
|
+
width: 100%;
|
|
204
|
+
border-collapse: collapse;
|
|
205
|
+
margin-bottom: 20px;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.users-table th,
|
|
209
|
+
.users-table td {
|
|
210
|
+
padding: 12px;
|
|
211
|
+
text-align: left;
|
|
212
|
+
border-bottom: 1px solid #ddd;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.users-table th {
|
|
216
|
+
background-color: #f8f9fa;
|
|
217
|
+
font-weight: 600;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.status.active {
|
|
221
|
+
color: #28a745;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.status.inactive {
|
|
225
|
+
color: #dc3545;
|
|
226
|
+
}
|
|
227
|
+
</style>
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Product Catalog with Custom Styling
|
|
231
|
+
|
|
232
|
+
```svelte
|
|
233
|
+
<script>
|
|
234
|
+
import PaginationPanel from '@ticatec/uniface-element/PaginationPanel';
|
|
235
|
+
|
|
236
|
+
let products = [];
|
|
237
|
+
let currentPage = 1;
|
|
238
|
+
let totalPages = 1;
|
|
239
|
+
let totalProducts = 0;
|
|
240
|
+
let rowsPerPage = 12;
|
|
241
|
+
let category = 'all';
|
|
242
|
+
|
|
243
|
+
const categories = {
|
|
244
|
+
all: 'All Products',
|
|
245
|
+
electronics: 'Electronics',
|
|
246
|
+
clothing: 'Clothing',
|
|
247
|
+
books: 'Books'
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
async function loadProducts(page = 1, rows = 12, cat = 'all') {
|
|
251
|
+
// Simulate API call with category filter
|
|
252
|
+
const categoryTotals = {
|
|
253
|
+
all: 180,
|
|
254
|
+
electronics: 45,
|
|
255
|
+
clothing: 67,
|
|
256
|
+
books: 68
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
totalProducts = categoryTotals[cat];
|
|
260
|
+
totalPages = Math.ceil(totalProducts / rows);
|
|
261
|
+
currentPage = page;
|
|
262
|
+
|
|
263
|
+
const startIndex = (page - 1) * rows;
|
|
264
|
+
products = Array.from({ length: Math.min(rows, totalProducts - startIndex) }, (_, i) => ({
|
|
265
|
+
id: startIndex + i + 1,
|
|
266
|
+
name: `${categories[cat]} Product ${startIndex + i + 1}`,
|
|
267
|
+
price: (Math.random() * 200 + 20).toFixed(2),
|
|
268
|
+
image: `https://picsum.photos/200/200?random=${startIndex + i + 1}`,
|
|
269
|
+
rating: (Math.random() * 2 + 3).toFixed(1)
|
|
270
|
+
}));
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function handlePageChange(page) {
|
|
274
|
+
loadProducts(page, rowsPerPage, category);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function handleRowCountChange(rows) {
|
|
278
|
+
rowsPerPage = rows;
|
|
279
|
+
loadProducts(1, rows, category);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function handleCategoryChange() {
|
|
283
|
+
loadProducts(1, rowsPerPage, category);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Custom product info generator
|
|
287
|
+
function generateProductInfo(total, pageCount, pageNo, rows) {
|
|
288
|
+
return `
|
|
289
|
+
<span style="color: #007bff;">Page ${pageNo}</span> of
|
|
290
|
+
<span style="color: #007bff;">${pageCount}</span> •
|
|
291
|
+
<span style="color: #28a745;">${total}</span> products total
|
|
292
|
+
`;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Load initial products
|
|
296
|
+
loadProducts(currentPage, rowsPerPage, category);
|
|
297
|
+
</script>
|
|
298
|
+
|
|
299
|
+
<div class="product-catalog">
|
|
300
|
+
<div class="catalog-header">
|
|
301
|
+
<h2>Product Catalog</h2>
|
|
302
|
+
<div class="category-filter">
|
|
303
|
+
<label>Category:</label>
|
|
304
|
+
<select bind:value={category} on:change={handleCategoryChange}>
|
|
305
|
+
{#each Object.entries(categories) as [key, value]}
|
|
306
|
+
<option value={key}>{value}</option>
|
|
307
|
+
{/each}
|
|
308
|
+
</select>
|
|
309
|
+
</div>
|
|
310
|
+
</div>
|
|
311
|
+
|
|
312
|
+
<div class="products-grid">
|
|
313
|
+
{#each products as product}
|
|
314
|
+
<div class="product-card">
|
|
315
|
+
<img src={product.image} alt={product.name} />
|
|
316
|
+
<h3>{product.name}</h3>
|
|
317
|
+
<div class="product-info">
|
|
318
|
+
<span class="price">${product.price}</span>
|
|
319
|
+
<span class="rating">⭐ {product.rating}</span>
|
|
320
|
+
</div>
|
|
321
|
+
</div>
|
|
322
|
+
{/each}
|
|
323
|
+
</div>
|
|
324
|
+
|
|
325
|
+
<PaginationPanel
|
|
326
|
+
pageNo={currentPage}
|
|
327
|
+
pageCount={totalPages}
|
|
328
|
+
total={totalProducts}
|
|
329
|
+
rowCount={rowsPerPage}
|
|
330
|
+
rowsSet={[6, 12, 24, 48]}
|
|
331
|
+
rowCountLabel="Products per page"
|
|
332
|
+
generateInfo={generateProductInfo}
|
|
333
|
+
onPageChange={handlePageChange}
|
|
334
|
+
onRowCountChanged={handleRowCountChange}
|
|
335
|
+
type="round"
|
|
336
|
+
big
|
|
337
|
+
/>
|
|
338
|
+
</div>
|
|
339
|
+
|
|
340
|
+
<style>
|
|
341
|
+
.product-catalog {
|
|
342
|
+
max-width: 1200px;
|
|
343
|
+
margin: 0 auto;
|
|
344
|
+
padding: 20px;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.catalog-header {
|
|
348
|
+
display: flex;
|
|
349
|
+
justify-content: space-between;
|
|
350
|
+
align-items: center;
|
|
351
|
+
margin-bottom: 30px;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
.category-filter {
|
|
355
|
+
display: flex;
|
|
356
|
+
align-items: center;
|
|
357
|
+
gap: 10px;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.category-filter select {
|
|
361
|
+
padding: 8px 12px;
|
|
362
|
+
border: 1px solid #ddd;
|
|
363
|
+
border-radius: 4px;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.products-grid {
|
|
367
|
+
display: grid;
|
|
368
|
+
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
369
|
+
gap: 24px;
|
|
370
|
+
margin-bottom: 40px;
|
|
371
|
+
min-height: 400px;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.product-card {
|
|
375
|
+
border: 1px solid #ddd;
|
|
376
|
+
border-radius: 8px;
|
|
377
|
+
padding: 16px;
|
|
378
|
+
text-align: center;
|
|
379
|
+
transition: transform 0.2s;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.product-card:hover {
|
|
383
|
+
transform: translateY(-2px);
|
|
384
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.product-card img {
|
|
388
|
+
width: 100%;
|
|
389
|
+
height: 200px;
|
|
390
|
+
object-fit: cover;
|
|
391
|
+
border-radius: 4px;
|
|
392
|
+
margin-bottom: 12px;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.product-card h3 {
|
|
396
|
+
margin: 0 0 12px 0;
|
|
397
|
+
font-size: 16px;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
.product-info {
|
|
401
|
+
display: flex;
|
|
402
|
+
justify-content: space-between;
|
|
403
|
+
align-items: center;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.price {
|
|
407
|
+
font-size: 18px;
|
|
408
|
+
font-weight: bold;
|
|
409
|
+
color: #007bff;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.rating {
|
|
413
|
+
color: #ff9500;
|
|
414
|
+
}
|
|
415
|
+
</style>
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Reports Dashboard
|
|
419
|
+
|
|
420
|
+
```svelte
|
|
421
|
+
<script>
|
|
422
|
+
import PaginationPanel from '@ticatec/uniface-element/PaginationPanel';
|
|
423
|
+
|
|
424
|
+
let reports = [];
|
|
425
|
+
let currentPage = 1;
|
|
426
|
+
let totalPages = 1;
|
|
427
|
+
let totalReports = 0;
|
|
428
|
+
let rowsPerPage = 15;
|
|
429
|
+
let dateRange = 'week';
|
|
430
|
+
|
|
431
|
+
async function loadReports(page = 1, rows = 15, range = 'week') {
|
|
432
|
+
// Simulate loading reports based on date range
|
|
433
|
+
const rangeTotals = {
|
|
434
|
+
today: 23,
|
|
435
|
+
week: 156,
|
|
436
|
+
month: 642,
|
|
437
|
+
year: 7834
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
totalReports = rangeTotals[range];
|
|
441
|
+
totalPages = Math.ceil(totalReports / rows);
|
|
442
|
+
currentPage = page;
|
|
443
|
+
|
|
444
|
+
const startIndex = (page - 1) * rows;
|
|
445
|
+
reports = Array.from({ length: Math.min(rows, totalReports - startIndex) }, (_, i) => ({
|
|
446
|
+
id: `RPT-${String(startIndex + i + 1).padStart(4, '0')}`,
|
|
447
|
+
title: `Report ${startIndex + i + 1}`,
|
|
448
|
+
type: ['Sales', 'Analytics', 'Performance', 'User Activity'][Math.floor(Math.random() * 4)],
|
|
449
|
+
createdAt: new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000).toLocaleDateString(),
|
|
450
|
+
status: ['Completed', 'Processing', 'Failed'][Math.floor(Math.random() * 3)],
|
|
451
|
+
size: `${(Math.random() * 10 + 0.5).toFixed(1)} MB`
|
|
452
|
+
}));
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
function handlePageChange(page) {
|
|
456
|
+
loadReports(page, rowsPerPage, dateRange);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function handleRowCountChange(rows) {
|
|
460
|
+
rowsPerPage = rows;
|
|
461
|
+
loadReports(1, rows, dateRange);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function handleDateRangeChange() {
|
|
465
|
+
loadReports(1, rowsPerPage, dateRange);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Custom report info generator
|
|
469
|
+
function generateReportInfo(total, pageCount, pageNo, rows) {
|
|
470
|
+
const start = (pageNo - 1) * rows + 1;
|
|
471
|
+
const end = Math.min(pageNo * rows, total);
|
|
472
|
+
return `
|
|
473
|
+
<div style="display: flex; align-items: center; gap: 16px;">
|
|
474
|
+
<span>Reports <b>${start}-${end}</b> of <b>${total}</b></span>
|
|
475
|
+
<span style="color: #666;">•</span>
|
|
476
|
+
<span style="color: #007bff;">Page ${pageNo}/${pageCount}</span>
|
|
477
|
+
</div>
|
|
478
|
+
`;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Load initial reports
|
|
482
|
+
loadReports(currentPage, rowsPerPage, dateRange);
|
|
483
|
+
</script>
|
|
484
|
+
|
|
485
|
+
<div class="reports-dashboard">
|
|
486
|
+
<div class="dashboard-header">
|
|
487
|
+
<h2>Reports Dashboard</h2>
|
|
488
|
+
<div class="date-filter">
|
|
489
|
+
<label>Time Range:</label>
|
|
490
|
+
<select bind:value={dateRange} on:change={handleDateRangeChange}>
|
|
491
|
+
<option value="today">Today</option>
|
|
492
|
+
<option value="week">This Week</option>
|
|
493
|
+
<option value="month">This Month</option>
|
|
494
|
+
<option value="year">This Year</option>
|
|
495
|
+
</select>
|
|
496
|
+
</div>
|
|
497
|
+
</div>
|
|
498
|
+
|
|
499
|
+
<div class="reports-table-container">
|
|
500
|
+
<table class="reports-table">
|
|
501
|
+
<thead>
|
|
502
|
+
<tr>
|
|
503
|
+
<th>Report ID</th>
|
|
504
|
+
<th>Title</th>
|
|
505
|
+
<th>Type</th>
|
|
506
|
+
<th>Created</th>
|
|
507
|
+
<th>Status</th>
|
|
508
|
+
<th>Size</th>
|
|
509
|
+
<th>Actions</th>
|
|
510
|
+
</tr>
|
|
511
|
+
</thead>
|
|
512
|
+
<tbody>
|
|
513
|
+
{#each reports as report}
|
|
514
|
+
<tr>
|
|
515
|
+
<td><code>{report.id}</code></td>
|
|
516
|
+
<td>{report.title}</td>
|
|
517
|
+
<td><span class="badge type-{report.type.toLowerCase().replace(' ', '-')}">{report.type}</span></td>
|
|
518
|
+
<td>{report.createdAt}</td>
|
|
519
|
+
<td><span class="status status-{report.status.toLowerCase()}">{report.status}</span></td>
|
|
520
|
+
<td>{report.size}</td>
|
|
521
|
+
<td>
|
|
522
|
+
<button class="action-btn download">Download</button>
|
|
523
|
+
<button class="action-btn delete">Delete</button>
|
|
524
|
+
</td>
|
|
525
|
+
</tr>
|
|
526
|
+
{/each}
|
|
527
|
+
</tbody>
|
|
528
|
+
</table>
|
|
529
|
+
</div>
|
|
530
|
+
|
|
531
|
+
<PaginationPanel
|
|
532
|
+
pageNo={currentPage}
|
|
533
|
+
pageCount={totalPages}
|
|
534
|
+
total={totalReports}
|
|
535
|
+
rowCount={rowsPerPage}
|
|
536
|
+
rowsSet={[10, 15, 25, 50]}
|
|
537
|
+
rowCountLabel="Reports per page"
|
|
538
|
+
generateInfo={generateReportInfo}
|
|
539
|
+
onPageChange={handlePageChange}
|
|
540
|
+
onRowCountChanged={handleRowCountChange}
|
|
541
|
+
type="plain"
|
|
542
|
+
align="left"
|
|
543
|
+
/>
|
|
544
|
+
</div>
|
|
545
|
+
|
|
546
|
+
<style>
|
|
547
|
+
.reports-dashboard {
|
|
548
|
+
max-width: 1400px;
|
|
549
|
+
margin: 0 auto;
|
|
550
|
+
padding: 20px;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
.dashboard-header {
|
|
554
|
+
display: flex;
|
|
555
|
+
justify-content: space-between;
|
|
556
|
+
align-items: center;
|
|
557
|
+
margin-bottom: 30px;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
.date-filter {
|
|
561
|
+
display: flex;
|
|
562
|
+
align-items: center;
|
|
563
|
+
gap: 10px;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
.date-filter select {
|
|
567
|
+
padding: 8px 12px;
|
|
568
|
+
border: 1px solid #ddd;
|
|
569
|
+
border-radius: 4px;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
.reports-table-container {
|
|
573
|
+
overflow-x: auto;
|
|
574
|
+
margin-bottom: 20px;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
.reports-table {
|
|
578
|
+
width: 100%;
|
|
579
|
+
border-collapse: collapse;
|
|
580
|
+
min-width: 800px;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
.reports-table th,
|
|
584
|
+
.reports-table td {
|
|
585
|
+
padding: 12px;
|
|
586
|
+
text-align: left;
|
|
587
|
+
border-bottom: 1px solid #ddd;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.reports-table th {
|
|
591
|
+
background-color: #f8f9fa;
|
|
592
|
+
font-weight: 600;
|
|
593
|
+
position: sticky;
|
|
594
|
+
top: 0;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.badge {
|
|
598
|
+
padding: 4px 8px;
|
|
599
|
+
border-radius: 12px;
|
|
600
|
+
font-size: 12px;
|
|
601
|
+
font-weight: 600;
|
|
602
|
+
text-transform: uppercase;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
.badge.type-sales { background: #e3f2fd; color: #1976d2; }
|
|
606
|
+
.badge.type-analytics { background: #f3e5f5; color: #7b1fa2; }
|
|
607
|
+
.badge.type-performance { background: #e8f5e8; color: #388e3c; }
|
|
608
|
+
.badge.type-user-activity { background: #fff3e0; color: #f57c00; }
|
|
609
|
+
|
|
610
|
+
.status {
|
|
611
|
+
font-weight: 600;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
.status.status-completed { color: #28a745; }
|
|
615
|
+
.status.status-processing { color: #ffc107; }
|
|
616
|
+
.status.status-failed { color: #dc3545; }
|
|
617
|
+
|
|
618
|
+
.action-btn {
|
|
619
|
+
padding: 4px 8px;
|
|
620
|
+
margin: 0 2px;
|
|
621
|
+
border: none;
|
|
622
|
+
border-radius: 4px;
|
|
623
|
+
cursor: pointer;
|
|
624
|
+
font-size: 12px;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
.action-btn.download {
|
|
628
|
+
background: #007bff;
|
|
629
|
+
color: white;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
.action-btn.delete {
|
|
633
|
+
background: #dc3545;
|
|
634
|
+
color: white;
|
|
635
|
+
}
|
|
636
|
+
</style>
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
### Log Viewer with Large Dataset
|
|
640
|
+
|
|
641
|
+
```svelte
|
|
642
|
+
<script>
|
|
643
|
+
import PaginationPanel from '@ticatec/uniface-element/PaginationPanel';
|
|
644
|
+
|
|
645
|
+
let logs = [];
|
|
646
|
+
let currentPage = 1;
|
|
647
|
+
let totalPages = 1;
|
|
648
|
+
let totalLogs = 0;
|
|
649
|
+
let rowsPerPage = 50;
|
|
650
|
+
let logLevel = 'all';
|
|
651
|
+
let searchTerm = '';
|
|
652
|
+
|
|
653
|
+
const logLevels = ['all', 'error', 'warning', 'info', 'debug'];
|
|
654
|
+
|
|
655
|
+
async function loadLogs(page = 1, rows = 50, level = 'all', search = '') {
|
|
656
|
+
// Simulate large log dataset
|
|
657
|
+
const levelMultipliers = {
|
|
658
|
+
all: 1,
|
|
659
|
+
error: 0.1,
|
|
660
|
+
warning: 0.15,
|
|
661
|
+
info: 0.6,
|
|
662
|
+
debug: 0.15
|
|
663
|
+
};
|
|
664
|
+
|
|
665
|
+
const baseLogs = 15000;
|
|
666
|
+
totalLogs = Math.floor(baseLogs * (level === 'all' ? 1 : levelMultipliers[level]));
|
|
667
|
+
|
|
668
|
+
if (search) {
|
|
669
|
+
totalLogs = Math.floor(totalLogs * 0.2); // Simulate search filtering
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
totalPages = Math.ceil(totalLogs / rows);
|
|
673
|
+
currentPage = page;
|
|
674
|
+
|
|
675
|
+
const startIndex = (page - 1) * rows;
|
|
676
|
+
logs = Array.from({ length: Math.min(rows, totalLogs - startIndex) }, (_, i) => {
|
|
677
|
+
const logIndex = startIndex + i + 1;
|
|
678
|
+
const levels = level === 'all' ? ['error', 'warning', 'info', 'debug'] : [level];
|
|
679
|
+
const randomLevel = levels[Math.floor(Math.random() * levels.length)];
|
|
680
|
+
|
|
681
|
+
return {
|
|
682
|
+
id: logIndex,
|
|
683
|
+
timestamp: new Date(Date.now() - Math.random() * 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
684
|
+
level: randomLevel,
|
|
685
|
+
message: search
|
|
686
|
+
? `Log message ${logIndex} containing "${search}" with additional details`
|
|
687
|
+
: `Log message ${logIndex} - ${randomLevel} level event occurred`,
|
|
688
|
+
source: ['auth', 'api', 'database', 'cache', 'queue'][Math.floor(Math.random() * 5)]
|
|
689
|
+
};
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
function handlePageChange(page) {
|
|
694
|
+
loadLogs(page, rowsPerPage, logLevel, searchTerm);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
function handleRowCountChange(rows) {
|
|
698
|
+
rowsPerPage = rows;
|
|
699
|
+
loadLogs(1, rows, logLevel, searchTerm);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
function handleLevelChange() {
|
|
703
|
+
loadLogs(1, rowsPerPage, logLevel, searchTerm);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
function handleSearch() {
|
|
707
|
+
loadLogs(1, rowsPerPage, logLevel, searchTerm);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// Custom log info generator
|
|
711
|
+
function generateLogInfo(total, pageCount, pageNo, rows) {
|
|
712
|
+
const start = (pageNo - 1) * rows + 1;
|
|
713
|
+
const end = Math.min(pageNo * rows, total);
|
|
714
|
+
return `
|
|
715
|
+
<div style="font-family: monospace; font-size: 12px;">
|
|
716
|
+
Logs ${start.toLocaleString()}-${end.toLocaleString()} of ${total.toLocaleString()} • Page ${pageNo}/${pageCount}
|
|
717
|
+
</div>
|
|
718
|
+
`;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
// Load initial logs
|
|
722
|
+
loadLogs(currentPage, rowsPerPage, logLevel, searchTerm);
|
|
723
|
+
</script>
|
|
724
|
+
|
|
725
|
+
<div class="log-viewer">
|
|
726
|
+
<div class="log-controls">
|
|
727
|
+
<h2>System Logs</h2>
|
|
728
|
+
<div class="filters">
|
|
729
|
+
<div class="filter-group">
|
|
730
|
+
<label>Level:</label>
|
|
731
|
+
<select bind:value={logLevel} on:change={handleLevelChange}>
|
|
732
|
+
{#each logLevels as level}
|
|
733
|
+
<option value={level}>{level.toUpperCase()}</option>
|
|
734
|
+
{/each}
|
|
735
|
+
</select>
|
|
736
|
+
</div>
|
|
737
|
+
<div class="filter-group">
|
|
738
|
+
<label>Search:</label>
|
|
739
|
+
<input
|
|
740
|
+
type="text"
|
|
741
|
+
bind:value={searchTerm}
|
|
742
|
+
placeholder="Search logs..."
|
|
743
|
+
on:keydown={(e) => e.key === 'Enter' && handleSearch()}
|
|
744
|
+
/>
|
|
745
|
+
<button on:click={handleSearch}>Search</button>
|
|
746
|
+
</div>
|
|
747
|
+
</div>
|
|
748
|
+
</div>
|
|
749
|
+
|
|
750
|
+
<div class="logs-container">
|
|
751
|
+
{#each logs as log}
|
|
752
|
+
<div class="log-entry level-{log.level}">
|
|
753
|
+
<div class="log-header">
|
|
754
|
+
<span class="timestamp">{new Date(log.timestamp).toLocaleString()}</span>
|
|
755
|
+
<span class="level level-{log.level}">{log.level.toUpperCase()}</span>
|
|
756
|
+
<span class="source">[{log.source}]</span>
|
|
757
|
+
</div>
|
|
758
|
+
<div class="log-message">{log.message}</div>
|
|
759
|
+
</div>
|
|
760
|
+
{/each}
|
|
761
|
+
</div>
|
|
762
|
+
|
|
763
|
+
<PaginationPanel
|
|
764
|
+
pageNo={currentPage}
|
|
765
|
+
pageCount={totalPages}
|
|
766
|
+
total={totalLogs}
|
|
767
|
+
rowCount={rowsPerPage}
|
|
768
|
+
rowsSet={[25, 50, 100, 200]}
|
|
769
|
+
rowCountLabel="Logs per page"
|
|
770
|
+
generateInfo={generateLogInfo}
|
|
771
|
+
onPageChange={handlePageChange}
|
|
772
|
+
onRowCountChanged={handleRowCountChange}
|
|
773
|
+
type="circle"
|
|
774
|
+
/>
|
|
775
|
+
</div>
|
|
776
|
+
|
|
777
|
+
<style>
|
|
778
|
+
.log-viewer {
|
|
779
|
+
max-width: 1200px;
|
|
780
|
+
margin: 0 auto;
|
|
781
|
+
padding: 20px;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
.log-controls {
|
|
785
|
+
margin-bottom: 20px;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
.log-controls h2 {
|
|
789
|
+
margin: 0 0 16px 0;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
.filters {
|
|
793
|
+
display: flex;
|
|
794
|
+
gap: 20px;
|
|
795
|
+
align-items: center;
|
|
796
|
+
flex-wrap: wrap;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
.filter-group {
|
|
800
|
+
display: flex;
|
|
801
|
+
align-items: center;
|
|
802
|
+
gap: 8px;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
.filter-group select,
|
|
806
|
+
.filter-group input {
|
|
807
|
+
padding: 6px 10px;
|
|
808
|
+
border: 1px solid #ddd;
|
|
809
|
+
border-radius: 4px;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
.filter-group button {
|
|
813
|
+
padding: 6px 12px;
|
|
814
|
+
background: #007bff;
|
|
815
|
+
color: white;
|
|
816
|
+
border: none;
|
|
817
|
+
border-radius: 4px;
|
|
818
|
+
cursor: pointer;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
.logs-container {
|
|
822
|
+
background: #1e1e1e;
|
|
823
|
+
border-radius: 8px;
|
|
824
|
+
padding: 16px;
|
|
825
|
+
margin-bottom: 20px;
|
|
826
|
+
max-height: 600px;
|
|
827
|
+
overflow-y: auto;
|
|
828
|
+
font-family: 'Courier New', monospace;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
.log-entry {
|
|
832
|
+
margin-bottom: 12px;
|
|
833
|
+
padding: 8px;
|
|
834
|
+
border-radius: 4px;
|
|
835
|
+
border-left: 4px solid;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
.log-entry.level-error {
|
|
839
|
+
background: rgba(220, 53, 69, 0.1);
|
|
840
|
+
border-left-color: #dc3545;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
.log-entry.level-warning {
|
|
844
|
+
background: rgba(255, 193, 7, 0.1);
|
|
845
|
+
border-left-color: #ffc107;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
.log-entry.level-info {
|
|
849
|
+
background: rgba(0, 123, 255, 0.1);
|
|
850
|
+
border-left-color: #007bff;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
.log-entry.level-debug {
|
|
854
|
+
background: rgba(108, 117, 125, 0.1);
|
|
855
|
+
border-left-color: #6c757d;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
.log-header {
|
|
859
|
+
display: flex;
|
|
860
|
+
gap: 12px;
|
|
861
|
+
align-items: center;
|
|
862
|
+
margin-bottom: 4px;
|
|
863
|
+
font-size: 12px;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
.timestamp {
|
|
867
|
+
color: #adb5bd;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
.level {
|
|
871
|
+
font-weight: bold;
|
|
872
|
+
padding: 2px 6px;
|
|
873
|
+
border-radius: 3px;
|
|
874
|
+
font-size: 10px;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
.level.level-error { background: #dc3545; color: white; }
|
|
878
|
+
.level.level-warning { background: #ffc107; color: black; }
|
|
879
|
+
.level.level-info { background: #007bff; color: white; }
|
|
880
|
+
.level.level-debug { background: #6c757d; color: white; }
|
|
881
|
+
|
|
882
|
+
.source {
|
|
883
|
+
color: #28a745;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
.log-message {
|
|
887
|
+
color: #f8f9fa;
|
|
888
|
+
font-size: 13px;
|
|
889
|
+
line-height: 1.4;
|
|
890
|
+
}
|
|
891
|
+
</style>
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
### Mobile-Responsive Panel
|
|
895
|
+
|
|
896
|
+
```svelte
|
|
897
|
+
<script>
|
|
898
|
+
import PaginationPanel from '@ticatec/uniface-element/PaginationPanel';
|
|
899
|
+
import { onMount } from 'svelte';
|
|
900
|
+
|
|
901
|
+
let currentPage = 1;
|
|
902
|
+
let totalPages = 15;
|
|
903
|
+
let totalItems = 300;
|
|
904
|
+
let rowsPerPage = 20;
|
|
905
|
+
let isMobile = false;
|
|
906
|
+
|
|
907
|
+
onMount(() => {
|
|
908
|
+
const checkMobile = () => {
|
|
909
|
+
isMobile = window.innerWidth < 768;
|
|
910
|
+
};
|
|
911
|
+
|
|
912
|
+
checkMobile();
|
|
913
|
+
window.addEventListener('resize', checkMobile);
|
|
914
|
+
|
|
915
|
+
return () => window.removeEventListener('resize', checkMobile);
|
|
916
|
+
});
|
|
917
|
+
|
|
918
|
+
function handlePageChange(page) {
|
|
919
|
+
currentPage = page;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
function handleRowCountChange(rows) {
|
|
923
|
+
rowsPerPage = rows;
|
|
924
|
+
totalPages = Math.ceil(totalItems / rows);
|
|
925
|
+
currentPage = 1;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
// Mobile-friendly info generator
|
|
929
|
+
function generateMobileInfo(total, pageCount, pageNo, rows) {
|
|
930
|
+
if (isMobile) {
|
|
931
|
+
return `<div style="font-size: 12px; text-align: center;">${pageNo}/${pageCount} • ${total} items</div>`;
|
|
932
|
+
}
|
|
933
|
+
return `Showing ${(pageNo - 1) * rows + 1}-${Math.min(pageNo * rows, total)} of ${total} items`;
|
|
934
|
+
}
|
|
935
|
+
</script>
|
|
936
|
+
|
|
937
|
+
<div class="mobile-demo">
|
|
938
|
+
<h2>Mobile-Responsive Pagination</h2>
|
|
939
|
+
<p>Resize your browser to see mobile adaptations</p>
|
|
940
|
+
|
|
941
|
+
<div class="content-grid">
|
|
942
|
+
{#each Array(rowsPerPage) as _, i}
|
|
943
|
+
<div class="content-item">
|
|
944
|
+
Item {(currentPage - 1) * rowsPerPage + i + 1}
|
|
945
|
+
</div>
|
|
946
|
+
{/each}
|
|
947
|
+
</div>
|
|
948
|
+
|
|
949
|
+
<PaginationPanel
|
|
950
|
+
pageNo={currentPage}
|
|
951
|
+
pageCount={totalPages}
|
|
952
|
+
total={totalItems}
|
|
953
|
+
rowCount={rowsPerPage}
|
|
954
|
+
rowsSet={isMobile ? [10, 20] : [10, 20, 50]}
|
|
955
|
+
rowCountLabel={isMobile ? "Per page" : "Items per page"}
|
|
956
|
+
generateInfo={generateMobileInfo}
|
|
957
|
+
onPageChange={handlePageChange}
|
|
958
|
+
onRowCountChanged={handleRowCountChange}
|
|
959
|
+
type="round"
|
|
960
|
+
big={!isMobile}
|
|
961
|
+
align={isMobile ? "" : "right"}
|
|
962
|
+
/>
|
|
963
|
+
</div>
|
|
964
|
+
|
|
965
|
+
<style>
|
|
966
|
+
.mobile-demo {
|
|
967
|
+
max-width: 800px;
|
|
968
|
+
margin: 0 auto;
|
|
969
|
+
padding: 20px;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
.content-grid {
|
|
973
|
+
display: grid;
|
|
974
|
+
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
|
975
|
+
gap: 16px;
|
|
976
|
+
margin-bottom: 30px;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
.content-item {
|
|
980
|
+
padding: 20px;
|
|
981
|
+
background: #f8f9fa;
|
|
982
|
+
border: 1px solid #dee2e6;
|
|
983
|
+
border-radius: 8px;
|
|
984
|
+
text-align: center;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
@media (max-width: 767px) {
|
|
988
|
+
.content-grid {
|
|
989
|
+
grid-template-columns: 1fr 1fr;
|
|
990
|
+
gap: 12px;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
.content-item {
|
|
994
|
+
padding: 16px;
|
|
995
|
+
font-size: 14px;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
</style>
|
|
999
|
+
```
|
|
1000
|
+
|
|
1001
|
+
## Best Practices
|
|
1002
|
+
|
|
1003
|
+
1. **Data Loading**: Implement proper loading states during page transitions
|
|
1004
|
+
2. **URL Synchronization**: Keep URL parameters in sync with pagination state
|
|
1005
|
+
3. **Performance**: Use efficient data fetching strategies for large datasets
|
|
1006
|
+
4. **User Experience**: Provide clear feedback about current state and total items
|
|
1007
|
+
5. **Mobile Optimization**: Adapt row options and info display for mobile devices
|
|
1008
|
+
6. **Accessibility**: Ensure all controls are keyboard accessible
|
|
1009
|
+
7. **Error Handling**: Handle API failures gracefully with retry options
|
|
1010
|
+
|
|
1011
|
+
## Styling
|
|
1012
|
+
|
|
1013
|
+
The PaginationPanel component combines styling from multiple sub-components:
|
|
1014
|
+
|
|
1015
|
+
```css
|
|
1016
|
+
.uniface-pagination-panel {
|
|
1017
|
+
display: flex;
|
|
1018
|
+
align-items: center;
|
|
1019
|
+
justify-content: space-between;
|
|
1020
|
+
gap: 16px;
|
|
1021
|
+
padding: 16px 0;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
.uniface-pagination-panel.left {
|
|
1025
|
+
justify-content: flex-start;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
.uniface-pagination-panel.right {
|
|
1029
|
+
justify-content: flex-end;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
.page-options {
|
|
1033
|
+
display: flex;
|
|
1034
|
+
align-items: center;
|
|
1035
|
+
gap: 8px;
|
|
1036
|
+
font-size: 14px;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
.pagination {
|
|
1040
|
+
flex: 0 0 auto;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
.pagination-info {
|
|
1044
|
+
font-size: 14px;
|
|
1045
|
+
color: #666;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
/* Mobile responsive */
|
|
1049
|
+
@media (max-width: 767px) {
|
|
1050
|
+
.uniface-pagination-panel {
|
|
1051
|
+
flex-direction: column;
|
|
1052
|
+
gap: 12px;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
.page-options,
|
|
1056
|
+
.pagination-info {
|
|
1057
|
+
font-size: 12px;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
```
|
|
1061
|
+
|
|
1062
|
+
## Accessibility
|
|
1063
|
+
|
|
1064
|
+
- Full keyboard navigation support
|
|
1065
|
+
- ARIA labels for all interactive elements
|
|
1066
|
+
- Screen reader announcements for page changes
|
|
1067
|
+
- High contrast mode compatibility
|
|
1068
|
+
- Focus management between controls
|
|
1069
|
+
|
|
1070
|
+
## Related Components
|
|
1071
|
+
|
|
1072
|
+
- [Pagination](../pagination/README.md) - Core pagination component
|
|
1073
|
+
- [OptionsSelect](../options-select/README.md) - Row count selector
|
|
1074
|
+
- [DataTable](../data-table/README.md) - Data tables with pagination
|
|
1075
|
+
- [Button](../button/README.md) - For custom pagination actions
|