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.
@@ -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": chunked, button-triggered loading that merges into groups.
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
- ? tableData.length < totalRecords
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
- return (0, table_1.searchAndSortData)((0, table_1.SortMultiColumnData)(tableData, columnsSort), columnsSearch);
174
- }, [isGrouped, tableData, columnsSort, columnsSearch]);
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
- var nextPage = Math.floor(tableData.length / (chunk || 1)) + 1;
214
- var lastRecord = tableData.length > 0 ? tableData[tableData.length - 1] : undefined;
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(tableData.length, " of ").concat(totalRecords) : undefined;
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;
@@ -23,7 +23,12 @@ export type TableGroup = {
23
23
  label: string;
24
24
  rows: DataObject[];
25
25
  };
26
- /** Partition rows by a column key, preserving first-seen group order. */
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
  /**
@@ -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
- /** Partition rows by a column key, preserving first-seen group order. */
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 raw = row[groupBy];
147
- var key = raw === undefined || raw === null || raw === "" ? "—" : raw;
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 (typeof value === "string" || typeof value === "number") {
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 && typeof value === "object") {
181
- var o = value;
182
- if (typeof o.label === "string" || typeof o.label === "number") {
183
- return String(o.label);
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
- if (typeof value === "object") {
207
- var o = value;
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelize-design-library",
3
- "version": "2.3.1-beta.4",
3
+ "version": "2.3.1-beta.6",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",