pixelize-design-library 2.3.1-beta.4 → 2.3.1-beta.6
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/.claude/settings.local.json +5 -1
- package/dist/Components/Table/Table.js +39 -7
- package/dist/Components/Table/TableProps.d.ts +3 -0
- package/dist/Components/Table/settings/TableSettings.js +1 -1
- package/dist/Utils/table.d.ts +6 -1
- package/dist/Utils/table.js +47 -27
- package/package.json +1 -1
|
@@ -30,7 +30,11 @@
|
|
|
30
30
|
"Bash(node -e \"const p=require.resolve\\('@chakra-ui/react'\\);console.log\\(p\\)\")",
|
|
31
31
|
"Bash(sed -n '31,45p' src/Pages/table.tsx)",
|
|
32
32
|
"Bash(perl -0pi -e 's/\\\\n\\\\s*content: \\\\\\(\\\\\\) => <>Hello<\\\\/>,?//' src/Pages/table.tsx)",
|
|
33
|
-
"Bash(cd /Users/mahesh/Applications/Pixelize/CRM/Micro-Components *)"
|
|
33
|
+
"Bash(cd /Users/mahesh/Applications/Pixelize/CRM/Micro-Components *)",
|
|
34
|
+
"Bash(node -e \"console.log\\(require\\('./node_modules/pixelize-design-library/package.json'\\).version\\)\")",
|
|
35
|
+
"Bash(node -e \"console.log\\(JSON.stringify\\(require\\('./node_modules/pixelize-authenticator/package.json'\\).dependencies\\)\\)\")",
|
|
36
|
+
"Bash(node -e \"console.log\\(require\\('./node_modules/pixelize-authenticator/package.json'\\).version\\)\")",
|
|
37
|
+
"Bash(node -e \"console.log\\(require\\('./node_modules/pixelize-authenticator/node_modules/pixelize-design-library/package.json'\\).version\\)\")"
|
|
34
38
|
],
|
|
35
39
|
"additionalDirectories": [
|
|
36
40
|
"/private/tmp",
|
|
@@ -131,6 +131,32 @@ function Table(_a) {
|
|
|
131
131
|
// Grouping is chosen by the user in Table Settings > Group and persisted to
|
|
132
132
|
// preferences (`json.groupBy`); there is no `groupBy` prop.
|
|
133
133
|
var _35 = (0, react_1.useState)(undefined), groupByState = _35[0], setGroupByState = _35[1];
|
|
134
|
+
// Grouped "Load more" accumulates pages here so loading more ADDS rows to the
|
|
135
|
+
// groups (server pagination replaces `data` each fetch). Reset on fresh loads
|
|
136
|
+
// (search / filter / sort / page-size). Only used in grouped + groupLoadMore mode.
|
|
137
|
+
var _36 = (0, react_1.useState)([]), accumulatedRows = _36[0], setAccumulatedRows = _36[1];
|
|
138
|
+
var pendingLoadMoreRef = (0, react_1.useRef)(false);
|
|
139
|
+
(0, react_1.useEffect)(function () {
|
|
140
|
+
if (!groupLoadMore)
|
|
141
|
+
return;
|
|
142
|
+
if (pendingLoadMoreRef.current) {
|
|
143
|
+
pendingLoadMoreRef.current = false;
|
|
144
|
+
setAccumulatedRows(function (prev) {
|
|
145
|
+
var seen = new Set(prev.map(function (r) { return r.id; }));
|
|
146
|
+
var merged = prev.slice();
|
|
147
|
+
for (var _i = 0, tableData_1 = tableData; _i < tableData_1.length; _i++) {
|
|
148
|
+
var r = tableData_1[_i];
|
|
149
|
+
if (!seen.has(r.id))
|
|
150
|
+
merged.push(r);
|
|
151
|
+
}
|
|
152
|
+
return merged;
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
setAccumulatedRows(tableData);
|
|
157
|
+
}
|
|
158
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
159
|
+
}, [tableData, groupLoadMore]);
|
|
134
160
|
(0, react_1.useEffect)(function () {
|
|
135
161
|
if (tablePreferences === null || tablePreferences === void 0 ? void 0 : tablePreferences.density)
|
|
136
162
|
setDensityState(tablePreferences.density);
|
|
@@ -159,19 +185,22 @@ function Table(_a) {
|
|
|
159
185
|
var isGrouped = !!groupByState;
|
|
160
186
|
// Infinite scroll (server mode, not grouped): load more on scroll-near-bottom.
|
|
161
187
|
var canInfinite = infiniteScroll && !isGrouped;
|
|
162
|
-
// Grouped "Load more":
|
|
188
|
+
// Grouped "Load more": the accumulated pages back the grouped board so loading
|
|
189
|
+
// more grows the groups instead of replacing them.
|
|
190
|
+
var loadMoreBase = isGrouped && groupLoadMore ? accumulatedRows : tableData;
|
|
163
191
|
var hasMoreEffective = typeof hasMore === "boolean"
|
|
164
192
|
? hasMore
|
|
165
193
|
: isServerPagination
|
|
166
|
-
?
|
|
194
|
+
? loadMoreBase.length < totalRecords
|
|
167
195
|
: false;
|
|
168
196
|
var canGroupLoadMore = isGrouped && groupLoadMore && hasMoreEffective;
|
|
169
197
|
var groupPalette = (0, react_1.useMemo)(function () { return (0, table_1.buildTablePalette)(theme); }, [theme]);
|
|
170
198
|
var groupedSource = (0, react_1.useMemo)(function () {
|
|
171
199
|
if (!isGrouped)
|
|
172
200
|
return [];
|
|
173
|
-
|
|
174
|
-
|
|
201
|
+
var src = groupLoadMore ? accumulatedRows : tableData;
|
|
202
|
+
return (0, table_1.searchAndSortData)((0, table_1.SortMultiColumnData)(src, columnsSort), columnsSearch);
|
|
203
|
+
}, [isGrouped, groupLoadMore, accumulatedRows, tableData, columnsSort, columnsSearch]);
|
|
175
204
|
var renderGroups = (0, react_1.useMemo)(function () {
|
|
176
205
|
if (!isGrouped)
|
|
177
206
|
return undefined;
|
|
@@ -210,11 +239,14 @@ function Table(_a) {
|
|
|
210
239
|
if (isLoadingMore || isTableLoading || !hasMoreEffective)
|
|
211
240
|
return;
|
|
212
241
|
var chunk = loadMoreChunkSize !== null && loadMoreChunkSize !== void 0 ? loadMoreChunkSize : rowsPerPage;
|
|
213
|
-
|
|
214
|
-
|
|
242
|
+
// Next page is derived from how many rows we've already accumulated, so each
|
|
243
|
+
// click advances (fixes "always fromIndex 2") and the parent can replace `data`.
|
|
244
|
+
var nextPage = Math.floor(loadMoreBase.length / (chunk || 1)) + 1;
|
|
245
|
+
var lastRecord = loadMoreBase.length > 0 ? loadMoreBase[loadMoreBase.length - 1] : undefined;
|
|
246
|
+
pendingLoadMoreRef.current = true;
|
|
215
247
|
(_a = onPaginationRef.current) === null || _a === void 0 ? void 0 : _a.call(onPaginationRef, nextPage, chunk, lastRecord, "next");
|
|
216
248
|
};
|
|
217
|
-
var groupLoadMoreCaption = totalRecords > 0 ? "Showing ".concat(
|
|
249
|
+
var groupLoadMoreCaption = totalRecords > 0 ? "Showing ".concat(loadMoreBase.length, " of ").concat(totalRecords) : undefined;
|
|
218
250
|
var tablePaginationText = (0, react_1.useMemo)(function () { return isServerPagination
|
|
219
251
|
? "".concat(startRow + 1, " - ").concat(Math.min(startRow + rowsPerPage, totalRecords), " of ").concat(totalRecords)
|
|
220
252
|
: "".concat(startRow + 1, " - ").concat(endRow > tableData.length ? tableData.length : endRow, " of ").concat(tableData.length); }, [startRow, rowsPerPage, totalRecords, endRow, tableData.length]);
|
|
@@ -108,8 +108,11 @@ export type TableHeaderProps = {
|
|
|
108
108
|
isHidden?: boolean;
|
|
109
109
|
type?: "status";
|
|
110
110
|
statusColors?: Record<string, string>;
|
|
111
|
+
columnType?: TableColumnType;
|
|
111
112
|
node?: (data: DataObject) => JSX.Element | string | number | undefined;
|
|
112
113
|
};
|
|
114
|
+
/** Known field data-types (open-ended via the trailing string for forward-compat). */
|
|
115
|
+
export type TableColumnType = "text" | "singleline" | "multiLine" | "description" | "email" | "phone" | "website" | "number" | "integer" | "decimal" | "dropdown" | "multiSelectDropdown" | "user" | "date" | "date_time" | "time" | "not_assigned" | (string & {});
|
|
113
116
|
export type ExportOption = {
|
|
114
117
|
label: string;
|
|
115
118
|
id: string;
|
|
@@ -151,7 +151,7 @@ var TableSettings = function (_a) {
|
|
|
151
151
|
react_2.default.createElement(react_1.TabPanel, { px: 0, py: 1 },
|
|
152
152
|
react_2.default.createElement(react_1.Text, { fontSize: "12px", color: theme.colors.gray[500], mb: 2 }, "Group rows by a column. Click Save to apply."),
|
|
153
153
|
react_2.default.createElement(react_1.Flex, { direction: "column", gap: 2 }, __spreadArray([{ id: undefined, label: "None (no grouping)" }], columns
|
|
154
|
-
.filter(function (c) { return !c.isHidden; })
|
|
154
|
+
.filter(function (c) { return !!c.columnType && !c.isHidden; })
|
|
155
155
|
.map(function (c) { return ({ id: c.id, label: String(c.label) }); }), true).map(function (opt) {
|
|
156
156
|
var _a, _b;
|
|
157
157
|
var selected = selectedGroup === opt.id;
|
package/dist/Utils/table.d.ts
CHANGED
|
@@ -23,7 +23,12 @@ export type TableGroup = {
|
|
|
23
23
|
label: string;
|
|
24
24
|
rows: DataObject[];
|
|
25
25
|
};
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Partition rows by a column, preserving first-seen group order. The group key is
|
|
28
|
+
* a normalized string so object/array values (e.g. a `user` field that is an object
|
|
29
|
+
* or an array of users) group together by their readable text instead of by object
|
|
30
|
+
* identity.
|
|
31
|
+
*/
|
|
27
32
|
export declare function groupRows(data: DataObject[], groupBy: string | number): TableGroup[];
|
|
28
33
|
export declare const calculateLeftOffset: (columns: number[], index: number) => number;
|
|
29
34
|
/**
|
package/dist/Utils/table.js
CHANGED
|
@@ -137,14 +137,19 @@ function pickTableColor(value, palette, override) {
|
|
|
137
137
|
return { solid: "#8B3FC8", soft: "#8B3FC822", text: "#8B3FC8" };
|
|
138
138
|
return palette[hashKey(value) % palette.length];
|
|
139
139
|
}
|
|
140
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Partition rows by a column, preserving first-seen group order. The group key is
|
|
142
|
+
* a normalized string so object/array values (e.g. a `user` field that is an object
|
|
143
|
+
* or an array of users) group together by their readable text instead of by object
|
|
144
|
+
* identity.
|
|
145
|
+
*/
|
|
141
146
|
function groupRows(data, groupBy) {
|
|
142
147
|
var order = [];
|
|
143
148
|
var map = new Map();
|
|
144
149
|
for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
|
|
145
150
|
var row = data_1[_i];
|
|
146
|
-
var
|
|
147
|
-
var key =
|
|
151
|
+
var text = getStringValue(row[groupBy]);
|
|
152
|
+
var key = text === "" ? "—" : text;
|
|
148
153
|
if (!map.has(key)) {
|
|
149
154
|
map.set(key, []);
|
|
150
155
|
order.push(key);
|
|
@@ -170,21 +175,49 @@ var extractTextFromReactNode = function (node) {
|
|
|
170
175
|
}
|
|
171
176
|
return "";
|
|
172
177
|
};
|
|
178
|
+
/** Best-effort readable text for an entity object (user/relation/option/etc.). */
|
|
179
|
+
var objectToText = function (o) {
|
|
180
|
+
var _a, _b;
|
|
181
|
+
if (typeof o.label === "string" || typeof o.label === "number")
|
|
182
|
+
return String(o.label);
|
|
183
|
+
if (typeof o.name === "string" || typeof o.name === "number")
|
|
184
|
+
return String(o.name);
|
|
185
|
+
var first = (_a = o.first_name) !== null && _a !== void 0 ? _a : o.firstName;
|
|
186
|
+
var last = (_b = o.last_name) !== null && _b !== void 0 ? _b : o.lastName;
|
|
187
|
+
if (typeof first === "string" || typeof last === "string") {
|
|
188
|
+
return "".concat(first !== null && first !== void 0 ? first : "", " ").concat(last !== null && last !== void 0 ? last : "").trim();
|
|
189
|
+
}
|
|
190
|
+
if (typeof o.full_name === "string")
|
|
191
|
+
return o.full_name;
|
|
192
|
+
if (typeof o.title === "string")
|
|
193
|
+
return o.title;
|
|
194
|
+
if (typeof o.company_name === "string")
|
|
195
|
+
return o.company_name;
|
|
196
|
+
if (typeof o.email === "string")
|
|
197
|
+
return o.email;
|
|
198
|
+
if (typeof o.value === "string" || typeof o.value === "number")
|
|
199
|
+
return String(o.value);
|
|
200
|
+
return "";
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Readable string for any cell value. Handles primitives, React elements, entity
|
|
204
|
+
* objects (e.g. `user`: `{ name }` / `{ first_name, last_name }`), and arrays of
|
|
205
|
+
* any of those (e.g. a multi-user field) by joining their texts.
|
|
206
|
+
*/
|
|
173
207
|
var getStringValue = function (value) {
|
|
174
|
-
if (
|
|
208
|
+
if (value === null || value === undefined)
|
|
209
|
+
return "";
|
|
210
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
175
211
|
return String(value);
|
|
176
212
|
}
|
|
177
213
|
if (react_1.default.isValidElement(value)) {
|
|
178
214
|
return extractTextFromReactNode(value);
|
|
179
215
|
}
|
|
180
|
-
if (value
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (typeof o.name === "string" || typeof o.name === "number") {
|
|
186
|
-
return String(o.name);
|
|
187
|
-
}
|
|
216
|
+
if (Array.isArray(value)) {
|
|
217
|
+
return value.map(getStringValue).filter(function (s) { return s !== ""; }).join(", ");
|
|
218
|
+
}
|
|
219
|
+
if (typeof value === "object") {
|
|
220
|
+
return objectToText(value);
|
|
188
221
|
}
|
|
189
222
|
return "";
|
|
190
223
|
};
|
|
@@ -203,21 +236,8 @@ function normalizeTableCellValue(value) {
|
|
|
203
236
|
if (react_1.default.isValidElement(value)) {
|
|
204
237
|
return value;
|
|
205
238
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (typeof o.label === "string" || typeof o.label === "number") {
|
|
209
|
-
return String(o.label);
|
|
210
|
-
}
|
|
211
|
-
if (typeof o.name === "string" || typeof o.name === "number") {
|
|
212
|
-
return String(o.name);
|
|
213
|
-
}
|
|
214
|
-
if (typeof o.title === "string")
|
|
215
|
-
return o.title;
|
|
216
|
-
if (typeof o.company_name === "string")
|
|
217
|
-
return o.company_name;
|
|
218
|
-
return "";
|
|
219
|
-
}
|
|
220
|
-
return String(value);
|
|
239
|
+
// Objects (relation/user) and arrays (multi-user / multi-select) → readable text.
|
|
240
|
+
return getStringValue(value);
|
|
221
241
|
}
|
|
222
242
|
var searchAndSortData = function (data, searchValues) {
|
|
223
243
|
var filteredData = data.filter(function (item) {
|