annotate publishable/resources/js/ServerTable.js @ 5:f282c6ef1671

better support for server side tables
author luka
date Tue, 19 Aug 2025 22:15:16 -0400
parents 84c75d9d90be
children 6ded573b0a61
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
1 class ServerTable {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
2 /**
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
3 * @param {HTMLElement} rootEl - The container element for the table
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
4 * @param {Object} options - Configuration options
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
5 * @param {string} options.endpoint - API endpoint for data
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
6 * @param {Array} options.columns - Array of column configs: [{name, label, ...}]
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
7 * @param {number} [options.pageSize=10] - Default rows per page
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
8 * @param {Array} [options.initialSort=[]] - Default sort: [{col, dir}]
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
9 * @param {Object} [options.headers={}] - Additional headers for requests
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
10 * @param {string} [options.groupBy={}] - Which column to group by
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
11 * @param {Function} [options.groupRender={}] - Function to render the grouping
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
12 */
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
13 constructor(rootEl, options) {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
14 this.rootEl = rootEl;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
15 this.endpoint = options.endpoint;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
16 this.columns = options.columns || [];
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
17 this.pageSize = options.pageSize || 10;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
18 this.sort = options.initialSort || [];
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
19 this.filters = options.filters || {};
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
20 this.currentPage = 1;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
21 this.headers = options.headers || {};
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
22 this.groupBy = options.groupBy;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
23 this.groupRender =
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
24 options.groupRender ||
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
25 ((g, rows) =>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
26 `<tr class="st-group-row"><td colspan="${this.columns.length}">Group: ${g}</td></tr>`);
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
27
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
28 this.skeleton = options.skeleton || `
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
29 <div class="st-table-container">
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
30 <table>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
31 <thead>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
32 </thead>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
33 <tbody>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
34 <!-- Data rows will go here -->
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
35 </tbody>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
36 </table>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
37 <div class="st-controls">
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
38 <span class="st-pagination"></span>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
39 <span class="st-status"></span>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
40 </div>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
41 </div>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
42 `;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
43
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
44 this.state = {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
45 loading: false,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
46 error: null,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
47 totalRecords: 0,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
48 records: [],
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
49 };
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
50
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
51 // Render initial skeleton and fetch initial data
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
52 this.renderSkeleton();
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
53 this.fetchData();
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
54 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
55
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
56 renderSkeleton() {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
57 // Build base structure: table shell, controls area
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
58 this.rootEl.innerHTML = this.skeleton;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
59 // Store references
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
60 this.head = this.rootEl.querySelector("thead");
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
61 this.tbody = this.rootEl.querySelector("tbody");
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
62 this.statusEl = this.rootEl.querySelector(".st-status");
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
63 this.paginationEl = this.rootEl.querySelector(".st-pagination");
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
64
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
65 // Draw the header
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
66 this.head.innerHTML = `
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
67 <tr>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
68 ${this.columns.map((col) => `<th scope="col">${col.label || col.name}</th>`).join("")}
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
69 </tr>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
70 `;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
71 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
72
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
73 async fetchData() {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
74 this.setLoading(true);
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
75 const payload = {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
76 page: this.currentPage,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
77 page_size: this.pageSize,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
78 sort: this.sort,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
79 filters: this.filters,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
80 };
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
81
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
82 try {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
83 const res = await fetch(this.endpoint, {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
84 method: "POST",
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
85 headers: {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
86 ...this.headers,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
87 "Content-Type": "application/json",
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
88 },
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
89 body: JSON.stringify(payload),
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
90 });
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
91
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
92 if (!res.ok) {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
93 throw new Error(`Server responded with ${res.status}`);
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
94 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
95
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
96 const data = await res.json();
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
97 // Minimal shape validation
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
98 if (
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
99 !Array.isArray(data.records) ||
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
100 typeof data.total_records !== "number"
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
101 ) {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
102 throw new Error("Malformed server response");
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
103 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
104
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
105 // Save data in state
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
106 this.state.records = data.records;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
107 this.state.totalRecords = data.total_records;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
108 this.state.error = null;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
109
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
110 this.renderRows();
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
111 this.updateControls();
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
112 } catch (err) {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
113 this.state.error = err.message;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
114 this.renderError();
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
115 } finally {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
116 this.setLoading(false);
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
117 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
118 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
119
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
120 setLoading(loading) {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
121 this.state.loading = loading;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
122 this.statusEl.textContent = loading ? "Loading..." : "";
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
123 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
124
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
125 renderRows() {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
126 const { records } = this.state;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
127 const cols = this.columns;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
128 const groupBy = this.groupBy;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
129 const groupRender =
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
130 typeof this.groupRender === "function"
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
131 ? this.groupRender
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
132 : (g, rows) =>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
133 `<tr class="st-group-row"><td colspan="${cols.length}">Project: ${g}</td></tr>`;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
134
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
135 if (!records || records.length === 0) {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
136 this.tbody.innerHTML = `<tr><td colspan="${cols.length}">No data</td></tr>`;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
137 return;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
138 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
139
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
140 // Group if needed
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
141 if (groupBy) {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
142 // Find grouping field or function
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
143 const getGroupValue =
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
144 typeof groupBy === "function" ? groupBy : (row) => row[groupBy];
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
145 let lastGroup = undefined;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
146 let out = "";
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
147 let groupRows = [];
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
148
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
149 for (let i = 0; i < records.length; i++) {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
150 const row = records[i];
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
151 const groupVal = getGroupValue(row);
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
152
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
153 // On group transition, flush previous group
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
154 if (i === 0 || groupVal !== lastGroup) {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
155 if (i > 0) {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
156 // Optionally do something with groupRows if groupRender wants it
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
157 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
158 // Insert group header row
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
159 out += groupRender(groupVal, []);
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
160 lastGroup = groupVal;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
161 groupRows = [];
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
162 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
163
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
164 groupRows.push(row);
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
165
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
166 out += `<tr>${cols
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
167 .map((col, ci) => {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
168 // If grouping by this column, suppress repeated values (leave blank except for first row in group)
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
169 if (
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
170 typeof groupBy === "string" &&
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
171 col.name === groupBy &&
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
172 groupVal === lastGroup &&
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
173 groupRows.length > 1
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
174 ) {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
175 return `<td></td>`;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
176 }
5
f282c6ef1671 better support for server side tables
luka
parents: 4
diff changeset
177 return `<td class='${ typeof col.class === "string" ? col.class : '' }' >${
4
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
178 typeof col.render === "function"
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
179 ? col.render(row, col, i)
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
180 : row[col.name]
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
181 }</td>`;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
182 })
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
183 .join("")}</tr>`;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
184 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
185 this.tbody.innerHTML = out;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
186 } else {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
187 // No grouping
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
188 this.tbody.innerHTML = records
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
189 .map(
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
190 (row, i) =>
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
191 `<tr>${cols
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
192 .map(
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
193 (col) =>
5
f282c6ef1671 better support for server side tables
luka
parents: 4
diff changeset
194 `<td class='${ typeof col.class === "string" ? col.class : '' }' >${
4
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
195 typeof col.render === "function"
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
196 ? col.render(row, col, i)
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
197 : row[col.name]
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
198 }</td>`,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
199 )
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
200 .join("")}</tr>`,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
201 )
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
202 .join("");
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
203 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
204 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
205 renderError() {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
206 this.tbody.innerHTML = `<tr><td colspan="${this.columns.length}" style="color:red">${this.state.error}</td></tr>`;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
207 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
208
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
209 updateControls() {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
210 // Basic pagination info (full controls to come later)
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
211 const from = 1 + (this.currentPage - 1) * this.pageSize;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
212 const to = Math.min(
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
213 this.currentPage * this.pageSize,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
214 this.state.totalRecords,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
215 );
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
216 this.paginationEl.textContent = `Showing ${from}-${to} of ${this.state.totalRecords}`;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
217 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
218
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
219 // PUBLIC: force reload
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
220 reload() {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
221 this.fetchData();
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
222 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
223
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
224 // PUBLIC: update filters, resets to page 1
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
225 setFilters(newFilters) {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
226 this.filters = newFilters;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
227 this.currentPage = 1;
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
228 this.fetchData();
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
229 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
230 }
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
231
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
232 // Example usage (not part of module export):
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
233 /*
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
234 const table = new ServerTable(document.getElementById('my-table'), {
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
235 endpoint: '/tickets/get_data',
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
236 columns: [
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
237 {name: 'id', label: 'ID'},
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
238 {name: 'subject', label: 'Subject'},
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
239 {name: 'project', label: 'Project'},
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
240 {name: 'created_at', label: 'Created At'},
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
241 ],
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
242 pageSize: 10,
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
243 initialSort: [{col: 'created_at', dir: 'desc'}]
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
244 });
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
245 */
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
246
84c75d9d90be Changing usage to be bootstrap 5, not everything is reviewed but it's been started
luka
parents:
diff changeset
247 window.ServerTable = ServerTable;