Skip to content

Commit f06f0c5

Browse files
committed
WIP
1 parent 54cc330 commit f06f0c5

File tree

2 files changed

+171
-1
lines changed

2 files changed

+171
-1
lines changed

documentation/docs/pagination.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
---
2+
id: Pagination
3+
title: Pagination
4+
sidebar_label: Pagination
5+
---
6+
7+
## Function
8+
9+
The `paginate` function facilitates paginated data retrieval from a database based on specified criteria.
10+
11+
| Parameter | Description | Type | Example |
12+
| ---------------------- | ---------------------------------------------------------- | ----------------------------- | --------------------------------------------------------------------------------------------------- |
13+
| `basePath` | The base path used for pagination links. | String | `'/personalInformation'` |
14+
| `baseTable` | The primary table from which data is retrieved. | String | `'personal_information'` |
15+
| `selectFields` | Fields selected from the involved tables. | Array of Strings | `['personal_information.first_name', 'personal_information.last_name']` |
16+
| `joinStatements` | SQL join statements connecting related tables. | Array of SQL Template Strings | sql `LEFT JOIN organization ON personal_information.organization_id = organization.organization_id` |
17+
| `sortableAttributes` | Attributes allowing data sorting. | Array of Strings | `['personal_information.personal_information_id', 'personal_information.created_at']` |
18+
| `filterableAttributes` | Attributes that can be filtered with supported operations. | Array of Objects | [See below](#filterable-attributes) |
19+
| `mandatoryFilter` | A condition that must be met for all retrieved records. | SQL Template String | sql `AND personal_information.organization_id=1` |
20+
| `sortBy` | Field by which data is sorted. | String | req.query.sort_by |
21+
| `limit` | Number of records per page. | Number | req.query.page_size |
22+
| `page` | Current page number. | String | req.query.page |
23+
| `direction` | Direction of pagination (next or previous). | String | req.query.direction |
24+
| `filters` | Filters applied to the data. | String | req.query.filters |
25+
| `cursorValues` | Cursor values used for pagination. | String | req.query.cursor |
26+
27+
### Example Usage:
28+
29+
#### Table 1 - ORGANIZATION
30+
31+
| Field Name | Data Type | Constraints |
32+
| -------------------- | ----------- | --------------------------- |
33+
| organization_id (PK) | int | AUTO_INCREMENT, PRIMARY KEY |
34+
| organization_name | VARCHAR(50) | NOT NULL, UNIQUE |
35+
| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP |
36+
37+
#### Table 2 - PERSONAL INFORMATION
38+
39+
| Field Name | Data Type | Constraints |
40+
| ----------------------- | ----------- | --------------------------- |
41+
| personal_information_id | int | AUTO_INCREMENT, PRIMARY KEY |
42+
| first_name | VARCHAR(50) | NOT NULL |
43+
| last_name | VARCHAR(50) | NOT NULL |
44+
| email | VARCHAR(50) | NOT NULL, UNIQUE |
45+
| education_level | VARCHAR(50) | NOT NULL |
46+
| organization_id (FK) | int | NOT NULL |
47+
| created_at | DATETIME | DEFAULT CURRENT_TIMESTAMP |
48+
49+
**Foreign Key:** `organization_id` references `organization(organization_id)`
50+
51+
```javascript
52+
const getPersonalInformation = async (req, res) => {
53+
const resultset = await paginate({
54+
basePath: req.path,
55+
baseTable: "personal_information",
56+
selectFields: [
57+
"personal_information.personal_information_id",
58+
"personal_information.first_name",
59+
"personal_information.last_name",
60+
"personal_information.email",
61+
"personal_information.education_level",
62+
"personal_information.organization_id",
63+
"personal_information.created_at",
64+
],
65+
joinStatements: [
66+
sql`LEFT JOIN organization ON personal_information.organization_id = organization.organization_id`,
67+
// Add other necessary join statements
68+
],
69+
sortableAttributes: [
70+
"personal_information.personal_information_id",
71+
"personal_information.created_at",
72+
],
73+
filterableAttributes: [
74+
{
75+
column: "personal_information.first_name",
76+
operations: [FILTERS.containsIgnoreCase],
77+
},
78+
{
79+
column: "personal_information.personal_information_id",
80+
operations: [
81+
FILTERS.equals,
82+
FILTERS.notEquals,
83+
FILTERS.greaterThan,
84+
FILTERS.greaterThanOrEqual,
85+
FILTERS.lessThan,
86+
FILTERS.lessThanOrEqual,
87+
FILTERS.in,
88+
FILTERS.notIn,
89+
FILTERS.between,
90+
],
91+
},
92+
// Include other filterable attributes
93+
],
94+
groupBy: ["personal_information.personal_information_id"],
95+
mandatoryFilter: sql`AND personal_information.organization_id=${req.params.orgId}`,
96+
sortBy: req.query.sort_by,
97+
limit: req.query.page_size,
98+
page: req.query.page, // "first" | "last" | null
99+
direction: req.query.direction, // next | previous
100+
filters: req.query.filters,
101+
cursorValues: req.query.cursor,
102+
});
103+
return res.send(resultset);
104+
};
105+
106+
module.exports = getPersonalInformation;
107+
```
108+
109+
### Filterable Attributes
110+
111+
The `filterableAttributes` section in the code allows for defining both pre-defined and custom filters for the `personal_information` table.
112+
113+
#### Pre-defined Filters
114+
115+
- `personal_information.first_name`:
116+
117+
- Operation: `FILTERS.containsIgnoreCase`
118+
- Description: Filters based on a case-insensitive partial match of the first name.
119+
120+
- `personal_information.personal_information_id`:
121+
122+
- Operations:
123+
- `FILTERS.equals`
124+
- `FILTERS.notEquals`
125+
- `FILTERS.greaterThan`
126+
- `FILTERS.greaterThanOrEqual`
127+
- `FILTERS.lessThan`
128+
- `FILTERS.lessThanOrEqual`
129+
- `FILTERS.in`
130+
- `FILTERS.notIn`
131+
- `FILTERS.between`
132+
- Description: Offers various operations for filtering based on the `personal_information_id`.
133+
134+
#### Custom Filters
135+
136+
- `personal_information.personal_information_id`:
137+
- Operations:
138+
- `FILTERS.containsIgnoreCase`
139+
- Custom Operator: `searchPersonByFullName`
140+
- Description: Searches personal information based on a full name match.
141+
- Custom Filter Function:
142+
```javascript
143+
{
144+
column: "personal_information.personal_information_id",
145+
operations: [
146+
FILTERS.containsIgnoreCase,
147+
{
148+
operator: "searchPersonByFullName",
149+
description: "search personal information by using full name",
150+
minimumNumberOfOperands: 1,
151+
maximumNumberOfOperands: 1,
152+
filterFn: operands => {
153+
const filterString = operands[0];
154+
if (filterString) {
155+
return sql`(LOWER(personal_information.first_name) LIKE ${`%${filterString}%`} OR LOWER(personal_information.last_name) LIKE ${`%${filterString}%`}) `;
156+
}
157+
return sql``;
158+
}
159+
}
160+
]
161+
},
162+
```
163+
This function checks for a partial match of the provided full name in `first_name` or `last_name`.

documentation/sidebars.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,14 @@ module.exports = {
1111
type: "category",
1212
label: "Overview",
1313
collapsed: false,
14-
items: ["intro", "what-is-xest-why", "installation", "routing", "CRUD"],
14+
items: [
15+
"intro",
16+
"what-is-xest-why",
17+
"installation",
18+
"routing",
19+
"CRUD",
20+
"Pagination",
21+
],
1522
},
1623
{
1724
type: "category",

0 commit comments

Comments
 (0)