hs-uix 1.6.5 → 1.7.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/README.md +2 -0
- package/common-components.d.ts +152 -0
- package/dist/common-components.js +1385 -77
- package/dist/common-components.mjs +1438 -82
- package/dist/datatable.js +291 -239
- package/dist/datatable.mjs +207 -155
- package/dist/feed.js +939 -0
- package/dist/feed.mjs +927 -0
- package/dist/form.js +115 -93
- package/dist/form.mjs +115 -93
- package/dist/index.js +3529 -1060
- package/dist/index.mjs +3231 -770
- package/dist/kanban.js +286 -225
- package/dist/kanban.mjs +180 -119
- package/dist/utils.js +2906 -2
- package/dist/utils.mjs +2944 -1
- package/feed.d.ts +1 -0
- package/index.d.ts +51 -2
- package/package.json +17 -4
- package/packages/datatable/README.md +1046 -0
- package/packages/datatable/index.d.ts +246 -0
- package/packages/feed/README.md +224 -0
- package/packages/feed/index.d.ts +261 -0
- package/packages/form/README.md +1229 -0
- package/packages/form/index.d.ts +498 -0
- package/packages/kanban/README.md +707 -0
- package/packages/kanban/index.d.ts +367 -0
- package/utils.d.ts +122 -0
package/dist/kanban.mjs
CHANGED
|
@@ -1,6 +1,127 @@
|
|
|
1
1
|
// packages/kanban/src/Kanban.jsx
|
|
2
|
-
import React2, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import React2, { useCallback as useCallback2, useEffect as useEffect2, useMemo, useRef as useRef2, useState } from "react";
|
|
3
|
+
|
|
4
|
+
// src/utils/query.js
|
|
3
5
|
import Fuse from "fuse.js";
|
|
6
|
+
var getEmptyFilterValue = (filter) => {
|
|
7
|
+
const type = filter.type || "select";
|
|
8
|
+
if (type === "multiselect") return [];
|
|
9
|
+
if (type === "dateRange") return { from: null, to: null };
|
|
10
|
+
return "";
|
|
11
|
+
};
|
|
12
|
+
var isFilterActive = (filter, value) => {
|
|
13
|
+
const type = filter.type || "select";
|
|
14
|
+
if (type === "multiselect") return Array.isArray(value) && value.length > 0;
|
|
15
|
+
if (type === "dateRange") return value && (value.from || value.to);
|
|
16
|
+
return !!value;
|
|
17
|
+
};
|
|
18
|
+
var formatDateChip = (dateObj) => {
|
|
19
|
+
if (!dateObj) return "";
|
|
20
|
+
const { year, month, date } = dateObj;
|
|
21
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
22
|
+
month: "short",
|
|
23
|
+
day: "numeric",
|
|
24
|
+
year: "numeric"
|
|
25
|
+
}).format(new Date(year, month, date));
|
|
26
|
+
};
|
|
27
|
+
var dateToTimestamp = (dateObj) => {
|
|
28
|
+
if (!dateObj) return null;
|
|
29
|
+
return new Date(dateObj.year, dateObj.month, dateObj.date).getTime();
|
|
30
|
+
};
|
|
31
|
+
var toStableKey = (value) => {
|
|
32
|
+
try {
|
|
33
|
+
return JSON.stringify(value);
|
|
34
|
+
} catch (_error) {
|
|
35
|
+
return String(value);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var filterRows = (rows, filters, values) => {
|
|
39
|
+
let result = rows;
|
|
40
|
+
for (const filter of filters || []) {
|
|
41
|
+
const value = values[filter.name];
|
|
42
|
+
if (!isFilterActive(filter, value)) continue;
|
|
43
|
+
const type = filter.type || "select";
|
|
44
|
+
if (filter.filterFn) {
|
|
45
|
+
result = result.filter((row) => filter.filterFn(row, value));
|
|
46
|
+
} else if (type === "multiselect") {
|
|
47
|
+
result = result.filter((row) => value.includes(row[filter.name]));
|
|
48
|
+
} else if (type === "dateRange") {
|
|
49
|
+
const fromTs = dateToTimestamp(value.from);
|
|
50
|
+
const toTs = value.to ? dateToTimestamp(value.to) + 864e5 - 1 : null;
|
|
51
|
+
result = result.filter((row) => {
|
|
52
|
+
const rowTs = new Date(row[filter.name]).getTime();
|
|
53
|
+
if (Number.isNaN(rowTs)) return false;
|
|
54
|
+
if (fromTs && rowTs < fromTs) return false;
|
|
55
|
+
if (toTs && rowTs > toTs) return false;
|
|
56
|
+
return true;
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
result = result.filter((row) => row[filter.name] === value);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
};
|
|
64
|
+
var searchRows = (rows, term, fields, opts = {}) => {
|
|
65
|
+
const { fuzzy = false, fuzzyOptions } = opts;
|
|
66
|
+
const t = String(term ?? "").toLowerCase();
|
|
67
|
+
if (!t || !fields || fields.length === 0) return rows;
|
|
68
|
+
if (fuzzy) {
|
|
69
|
+
const fuse = new Fuse(rows, {
|
|
70
|
+
keys: fields,
|
|
71
|
+
threshold: 0.4,
|
|
72
|
+
distance: 100,
|
|
73
|
+
ignoreLocation: true,
|
|
74
|
+
...fuzzyOptions
|
|
75
|
+
});
|
|
76
|
+
return fuse.search(t).map((r) => r.item);
|
|
77
|
+
}
|
|
78
|
+
return rows.filter(
|
|
79
|
+
(row) => fields.some((field) => {
|
|
80
|
+
const val = row[field];
|
|
81
|
+
return val && String(val).toLowerCase().includes(t);
|
|
82
|
+
})
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// src/utils/interactionHooks.js
|
|
87
|
+
import { useRef, useEffect, useCallback } from "react";
|
|
88
|
+
import { useDebounce } from "@hubspot/ui-extensions";
|
|
89
|
+
var useDebouncedDispatch = (value, debounceMs, dispatch) => {
|
|
90
|
+
const debounced = useDebounce(value, debounceMs > 0 ? debounceMs : 300);
|
|
91
|
+
const pendingRef = useRef(null);
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (debounceMs <= 0) return;
|
|
94
|
+
if (pendingRef.current == null) return;
|
|
95
|
+
if (debounced !== pendingRef.current) return;
|
|
96
|
+
const next = pendingRef.current;
|
|
97
|
+
pendingRef.current = null;
|
|
98
|
+
dispatch(next);
|
|
99
|
+
}, [debounceMs, debounced, dispatch]);
|
|
100
|
+
return useCallback(
|
|
101
|
+
(next) => {
|
|
102
|
+
if (debounceMs > 0) {
|
|
103
|
+
pendingRef.current = next;
|
|
104
|
+
} else {
|
|
105
|
+
pendingRef.current = null;
|
|
106
|
+
dispatch(next);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
[debounceMs, dispatch]
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
var useSelectionReset = ({ resetKey, enabled, isControlled, clearSelection }) => {
|
|
113
|
+
const ref = useRef("");
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
if (!enabled || isControlled) {
|
|
116
|
+
ref.current = resetKey;
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (ref.current && ref.current !== resetKey) {
|
|
120
|
+
clearSelection();
|
|
121
|
+
}
|
|
122
|
+
ref.current = resetKey;
|
|
123
|
+
}, [resetKey, enabled, isControlled, clearSelection]);
|
|
124
|
+
};
|
|
4
125
|
|
|
5
126
|
// src/common-components/StyledText.js
|
|
6
127
|
import React from "react";
|
|
@@ -254,6 +375,7 @@ var DEFAULT_LABELS = {
|
|
|
254
375
|
emptyTitle: "No cards",
|
|
255
376
|
emptyMessage: "Nothing matches the current filters.",
|
|
256
377
|
loading: "Loading board...",
|
|
378
|
+
loadingMessage: "This should only take a moment.",
|
|
257
379
|
errorTitle: "Something went wrong.",
|
|
258
380
|
errorMessage: "An error occurred while loading data.",
|
|
259
381
|
cardCount: (n) => String(n),
|
|
@@ -281,38 +403,6 @@ var makeRotatedLabelDataUri = (label) => makeStyledTextDataUri(label, {
|
|
|
281
403
|
format: { fontWeight: "demibold" },
|
|
282
404
|
orientation: "vertical-down"
|
|
283
405
|
});
|
|
284
|
-
var getEmptyFilterValue = (filter) => {
|
|
285
|
-
const type = filter.type || "select";
|
|
286
|
-
if (type === "multiselect") return [];
|
|
287
|
-
if (type === "dateRange") return { from: null, to: null };
|
|
288
|
-
return "";
|
|
289
|
-
};
|
|
290
|
-
var isFilterActive = (filter, value) => {
|
|
291
|
-
const type = filter.type || "select";
|
|
292
|
-
if (type === "multiselect") return Array.isArray(value) && value.length > 0;
|
|
293
|
-
if (type === "dateRange") return value && (value.from || value.to);
|
|
294
|
-
return !!value;
|
|
295
|
-
};
|
|
296
|
-
var formatDateChip = (dateObj) => {
|
|
297
|
-
if (!dateObj) return "";
|
|
298
|
-
const { year, month, date } = dateObj;
|
|
299
|
-
return new Intl.DateTimeFormat("en-US", {
|
|
300
|
-
month: "short",
|
|
301
|
-
day: "numeric",
|
|
302
|
-
year: "numeric"
|
|
303
|
-
}).format(new Date(year, month, date));
|
|
304
|
-
};
|
|
305
|
-
var dateToTimestamp = (dateObj) => {
|
|
306
|
-
if (!dateObj) return null;
|
|
307
|
-
return new Date(dateObj.year, dateObj.month, dateObj.date).getTime();
|
|
308
|
-
};
|
|
309
|
-
var toStableKey = (value) => {
|
|
310
|
-
try {
|
|
311
|
-
return JSON.stringify(value);
|
|
312
|
-
} catch (_error) {
|
|
313
|
-
return String(value);
|
|
314
|
-
}
|
|
315
|
-
};
|
|
316
406
|
var canStageReceiveRow = (stage, row, canMove) => {
|
|
317
407
|
if (!stage) return false;
|
|
318
408
|
if (typeof canMove === "function" && !canMove(row, stage.value)) return false;
|
|
@@ -520,7 +610,7 @@ var KanbanColumn = ({
|
|
|
520
610
|
children
|
|
521
611
|
}) => {
|
|
522
612
|
const countLabel = labels.cardCount(totalCount != null ? totalCount : bucketCount);
|
|
523
|
-
const countNode = countDisplay === "text" ? /* @__PURE__ */ React2.createElement(Text, { format: { fontWeight: "demibold" } }, countLabel) : countDisplay === "none" ? null : /* @__PURE__ */ React2.createElement(Tag2, { variant: "
|
|
613
|
+
const countNode = countDisplay === "text" ? /* @__PURE__ */ React2.createElement(Text, { format: { fontWeight: "demibold" } }, countLabel) : countDisplay === "none" ? null : /* @__PURE__ */ React2.createElement(Tag2, { variant: "default" }, countLabel);
|
|
524
614
|
if (collapsed) {
|
|
525
615
|
const rotated = makeRotatedLabelDataUri(stage.label);
|
|
526
616
|
const rotatedCount = countDisplay === "none" ? null : makeRotatedTagDataUri(countLabel);
|
|
@@ -853,7 +943,7 @@ var Kanban = ({
|
|
|
853
943
|
filters,
|
|
854
944
|
filterInlineLimit = DEFAULT_FILTER_INLINE_LIMIT,
|
|
855
945
|
showFilterBadges = true,
|
|
856
|
-
showClearFiltersButton
|
|
946
|
+
showClearFiltersButton,
|
|
857
947
|
sortOptions,
|
|
858
948
|
defaultSort,
|
|
859
949
|
sort,
|
|
@@ -899,15 +989,15 @@ var Kanban = ({
|
|
|
899
989
|
const [internalSelection, setInternalSelection] = useState([]);
|
|
900
990
|
const [internalShowMetrics, setInternalShowMetrics] = useState(false);
|
|
901
991
|
const [transitionPrompts, setTransitionPrompts] = useState({});
|
|
902
|
-
const selectionResetRef = useRef("");
|
|
903
992
|
const resolvedShowMetrics = controlledShowMetrics != null ? controlledShowMetrics : internalShowMetrics;
|
|
904
|
-
const toggleMetrics =
|
|
993
|
+
const toggleMetrics = useCallback2(() => {
|
|
905
994
|
const next = !resolvedShowMetrics;
|
|
906
995
|
if (onMetricsToggle) onMetricsToggle(next);
|
|
907
996
|
if (controlledShowMetrics == null) setInternalShowMetrics(next);
|
|
908
997
|
}, [resolvedShowMetrics, onMetricsToggle, controlledShowMetrics]);
|
|
909
998
|
const effectiveColumnWidth = Math.max(MIN_COLUMN_WIDTH, columnWidth || DEFAULT_COLUMN_WIDTH);
|
|
910
999
|
const resolvedSearch = searchValue != null ? searchValue : internalSearch;
|
|
1000
|
+
const searchInputValue = searchDebounce > 0 ? internalSearch : resolvedSearch;
|
|
911
1001
|
const resolvedFilters = filterValues != null ? filterValues : internalFilters;
|
|
912
1002
|
const resolvedSort = sort != null ? sort : internalSort;
|
|
913
1003
|
const resolvedCollapsed = collapsedStages != null ? collapsedStages : internalCollapsed;
|
|
@@ -921,7 +1011,7 @@ var Kanban = ({
|
|
|
921
1011
|
}
|
|
922
1012
|
return map;
|
|
923
1013
|
}, [stages]);
|
|
924
|
-
const fireParamsChange =
|
|
1014
|
+
const fireParamsChange = useCallback2((overrides = {}) => {
|
|
925
1015
|
if (!onParamsChange) return;
|
|
926
1016
|
onParamsChange({
|
|
927
1017
|
search: overrides.search != null ? overrides.search : resolvedSearch,
|
|
@@ -930,27 +1020,30 @@ var Kanban = ({
|
|
|
930
1020
|
collapsedStages: overrides.collapsedStages != null ? overrides.collapsedStages : resolvedCollapsed
|
|
931
1021
|
});
|
|
932
1022
|
}, [onParamsChange, resolvedCollapsed, resolvedFilters, resolvedSearch, resolvedSort]);
|
|
933
|
-
const
|
|
934
|
-
|
|
935
|
-
if (
|
|
936
|
-
|
|
937
|
-
|
|
1023
|
+
const lastAppliedSearchRef = useRef2(searchValue != null ? searchValue : "");
|
|
1024
|
+
useEffect2(() => {
|
|
1025
|
+
if (searchValue == null) return;
|
|
1026
|
+
if (searchValue === lastAppliedSearchRef.current) return;
|
|
1027
|
+
lastAppliedSearchRef.current = searchValue;
|
|
1028
|
+
setInternalSearch(searchValue);
|
|
1029
|
+
}, [searchValue]);
|
|
1030
|
+
const dispatchSearch = useCallback2(
|
|
938
1031
|
(val) => {
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
fireParamsChange({ search: val });
|
|
943
|
-
};
|
|
944
|
-
if (searchDebounce > 0) {
|
|
945
|
-
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
946
|
-
debounceRef.current = setTimeout(dispatch, searchDebounce);
|
|
947
|
-
} else {
|
|
948
|
-
dispatch();
|
|
949
|
-
}
|
|
1032
|
+
lastAppliedSearchRef.current = val;
|
|
1033
|
+
if (onSearchChange) onSearchChange(val);
|
|
1034
|
+
fireParamsChange({ search: val });
|
|
950
1035
|
},
|
|
951
|
-
[fireParamsChange, onSearchChange
|
|
1036
|
+
[fireParamsChange, onSearchChange]
|
|
952
1037
|
);
|
|
953
|
-
const
|
|
1038
|
+
const dispatchSearchDebounced = useDebouncedDispatch(internalSearch, searchDebounce, dispatchSearch);
|
|
1039
|
+
const handleSearch = useCallback2(
|
|
1040
|
+
(val) => {
|
|
1041
|
+
setInternalSearch(val);
|
|
1042
|
+
dispatchSearchDebounced(val);
|
|
1043
|
+
},
|
|
1044
|
+
[dispatchSearchDebounced]
|
|
1045
|
+
);
|
|
1046
|
+
const handleFilter = useCallback2(
|
|
954
1047
|
(name, val) => {
|
|
955
1048
|
const next = { ...resolvedFilters, [name]: val };
|
|
956
1049
|
if (filterValues == null) setInternalFilters(next);
|
|
@@ -959,7 +1052,7 @@ var Kanban = ({
|
|
|
959
1052
|
},
|
|
960
1053
|
[fireParamsChange, onFilterChange, filterValues, resolvedFilters]
|
|
961
1054
|
);
|
|
962
|
-
const handleFilterRemove =
|
|
1055
|
+
const handleFilterRemove = useCallback2(
|
|
963
1056
|
(key) => {
|
|
964
1057
|
if (key === "all") {
|
|
965
1058
|
const cleared = {};
|
|
@@ -980,7 +1073,7 @@ var Kanban = ({
|
|
|
980
1073
|
},
|
|
981
1074
|
[filters, filterValues, fireParamsChange, onFilterChange, resolvedFilters]
|
|
982
1075
|
);
|
|
983
|
-
const handleSort =
|
|
1076
|
+
const handleSort = useCallback2(
|
|
984
1077
|
(val) => {
|
|
985
1078
|
if (onSortChange) onSortChange(val);
|
|
986
1079
|
if (sort == null) setInternalSort(val);
|
|
@@ -988,7 +1081,7 @@ var Kanban = ({
|
|
|
988
1081
|
},
|
|
989
1082
|
[fireParamsChange, onSortChange, sort]
|
|
990
1083
|
);
|
|
991
|
-
const handleCollapsed =
|
|
1084
|
+
const handleCollapsed = useCallback2(
|
|
992
1085
|
(stageValue) => {
|
|
993
1086
|
const next = resolvedCollapsed.includes(stageValue) ? resolvedCollapsed.filter((v) => v !== stageValue) : [...resolvedCollapsed, stageValue];
|
|
994
1087
|
if (onCollapsedStagesChange) onCollapsedStagesChange(next);
|
|
@@ -997,7 +1090,7 @@ var Kanban = ({
|
|
|
997
1090
|
},
|
|
998
1091
|
[fireParamsChange, resolvedCollapsed, collapsedStages, onCollapsedStagesChange]
|
|
999
1092
|
);
|
|
1000
|
-
const handleExpanded =
|
|
1093
|
+
const handleExpanded = useCallback2(
|
|
1001
1094
|
(stageValue) => {
|
|
1002
1095
|
const next = resolvedExpanded.includes(stageValue) ? resolvedExpanded.filter((v) => v !== stageValue) : [...resolvedExpanded, stageValue];
|
|
1003
1096
|
if (onExpandedStagesChange) onExpandedStagesChange(next);
|
|
@@ -1005,7 +1098,7 @@ var Kanban = ({
|
|
|
1005
1098
|
},
|
|
1006
1099
|
[resolvedExpanded, expandedStages, onExpandedStagesChange]
|
|
1007
1100
|
);
|
|
1008
|
-
const handleToggleSelect =
|
|
1101
|
+
const handleToggleSelect = useCallback2(
|
|
1009
1102
|
(rowId) => {
|
|
1010
1103
|
const next = resolvedSelection.includes(rowId) ? resolvedSelection.filter((id) => id !== rowId) : [...resolvedSelection, rowId];
|
|
1011
1104
|
if (onSelectionChange) onSelectionChange(next);
|
|
@@ -1013,7 +1106,7 @@ var Kanban = ({
|
|
|
1013
1106
|
},
|
|
1014
1107
|
[resolvedSelection, selectedIds, onSelectionChange]
|
|
1015
1108
|
);
|
|
1016
|
-
const clearTransitionPrompt =
|
|
1109
|
+
const clearTransitionPrompt = useCallback2((rowId) => {
|
|
1017
1110
|
setTransitionPrompts((prev) => {
|
|
1018
1111
|
if (!Object.prototype.hasOwnProperty.call(prev, rowId)) return prev;
|
|
1019
1112
|
const next = { ...prev };
|
|
@@ -1021,7 +1114,7 @@ var Kanban = ({
|
|
|
1021
1114
|
return next;
|
|
1022
1115
|
});
|
|
1023
1116
|
}, []);
|
|
1024
|
-
const commitStageChange =
|
|
1117
|
+
const commitStageChange = useCallback2(
|
|
1025
1118
|
(row, newStage, oldStage, result) => {
|
|
1026
1119
|
clearTransitionPrompt(row[rowIdField]);
|
|
1027
1120
|
if (onStageChange) onStageChange(row, newStage, oldStage, result);
|
|
@@ -1040,17 +1133,14 @@ var Kanban = ({
|
|
|
1040
1133
|
() => `${selectionQueryKey}::${selectionResetKey == null ? "" : toStableKey(selectionResetKey)}`,
|
|
1041
1134
|
[selectionQueryKey, selectionResetKey]
|
|
1042
1135
|
);
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
selectionResetRef.current = combinedSelectionResetKey;
|
|
1052
|
-
}, [combinedSelectionResetKey, selectable, selectedIds]);
|
|
1053
|
-
const getStageFor = useCallback(
|
|
1136
|
+
const clearSelection = useCallback2(() => setInternalSelection([]), []);
|
|
1137
|
+
useSelectionReset({
|
|
1138
|
+
resetKey: combinedSelectionResetKey,
|
|
1139
|
+
enabled: selectable,
|
|
1140
|
+
isControlled: selectedIds != null,
|
|
1141
|
+
clearSelection
|
|
1142
|
+
});
|
|
1143
|
+
const getStageFor = useCallback2(
|
|
1054
1144
|
(row) => {
|
|
1055
1145
|
if (typeof groupBy === "function") return groupBy(row);
|
|
1056
1146
|
return row[groupBy];
|
|
@@ -1058,47 +1148,13 @@ var Kanban = ({
|
|
|
1058
1148
|
[groupBy]
|
|
1059
1149
|
);
|
|
1060
1150
|
const filteredData = useMemo(() => {
|
|
1061
|
-
let result = data;
|
|
1062
|
-
for (const filter of filters || []) {
|
|
1063
|
-
const val = resolvedFilters[filter.name];
|
|
1064
|
-
if (!isFilterActive(filter, val)) continue;
|
|
1065
|
-
const type = filter.type || "select";
|
|
1066
|
-
if (filter.filterFn) {
|
|
1067
|
-
result = result.filter((row) => filter.filterFn(row, val));
|
|
1068
|
-
} else if (type === "multiselect") {
|
|
1069
|
-
result = result.filter((row) => val.includes(row[filter.name]));
|
|
1070
|
-
} else if (type === "dateRange") {
|
|
1071
|
-
const fromTs = dateToTimestamp(val.from);
|
|
1072
|
-
const toTs = val.to ? dateToTimestamp(val.to) + 864e5 - 1 : null;
|
|
1073
|
-
result = result.filter((row) => {
|
|
1074
|
-
const rowTs = new Date(row[filter.name]).getTime();
|
|
1075
|
-
if (Number.isNaN(rowTs)) return false;
|
|
1076
|
-
if (fromTs && rowTs < fromTs) return false;
|
|
1077
|
-
if (toTs && rowTs > toTs) return false;
|
|
1078
|
-
return true;
|
|
1079
|
-
});
|
|
1080
|
-
} else {
|
|
1081
|
-
result = result.filter((row) => row[filter.name] === val);
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1151
|
+
let result = filterRows(data, filters, resolvedFilters);
|
|
1084
1152
|
const searchLower = (resolvedSearch || "").toLowerCase().trim();
|
|
1085
1153
|
if (searchEnabled && searchLower) {
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
distance: 100,
|
|
1091
|
-
ignoreLocation: true,
|
|
1092
|
-
...fuzzyOptions
|
|
1093
|
-
});
|
|
1094
|
-
result = fuse.search(searchLower).map((r) => r.item);
|
|
1095
|
-
} else {
|
|
1096
|
-
result = result.filter(
|
|
1097
|
-
(row) => searchFields.some(
|
|
1098
|
-
(f) => String(row[f] || "").toLowerCase().includes(searchLower)
|
|
1099
|
-
)
|
|
1100
|
-
);
|
|
1101
|
-
}
|
|
1154
|
+
result = searchRows(result, searchLower, searchFields, {
|
|
1155
|
+
fuzzy: fuzzySearch,
|
|
1156
|
+
fuzzyOptions
|
|
1157
|
+
});
|
|
1102
1158
|
}
|
|
1103
1159
|
return result;
|
|
1104
1160
|
}, [data, resolvedSearch, resolvedFilters, filters, searchEnabled, searchFields, fuzzySearch, fuzzyOptions]);
|
|
@@ -1159,7 +1215,7 @@ var Kanban = ({
|
|
|
1159
1215
|
const resolvedMaxBody = maxBodyLines || (cardDensity === "comfortable" ? 5 : 3);
|
|
1160
1216
|
const resolvedStageControl = stageControl || (cardDensity === "comfortable" ? "select" : "menu");
|
|
1161
1217
|
const resolvedStageControlPlacement = stageControlPlacement || (resolvedStageControl === "menu" ? "inline" : "separateRow");
|
|
1162
|
-
const handleStageChangeRequest =
|
|
1218
|
+
const handleStageChangeRequest = useCallback2(
|
|
1163
1219
|
(row, newStage, oldStage) => {
|
|
1164
1220
|
var _a2;
|
|
1165
1221
|
if (!newStage || newStage === oldStage) return;
|
|
@@ -1181,7 +1237,7 @@ var Kanban = ({
|
|
|
1181
1237
|
},
|
|
1182
1238
|
[canMove, commitStageChange, rowIdField, stagesByValue]
|
|
1183
1239
|
);
|
|
1184
|
-
const renderCardNode =
|
|
1240
|
+
const renderCardNode = useCallback2(
|
|
1185
1241
|
(row, stage) => {
|
|
1186
1242
|
var _a2;
|
|
1187
1243
|
const rowId = row[rowIdField];
|
|
@@ -1280,10 +1336,14 @@ var Kanban = ({
|
|
|
1280
1336
|
error,
|
|
1281
1337
|
title: labels.errorTitle,
|
|
1282
1338
|
message: typeof error === "string" ? error : labels.errorMessage
|
|
1283
|
-
}) : /* @__PURE__ */ React2.createElement(Alert, { variant: "danger", title: labels.errorTitle }, typeof error === "string" ? error : labels.errorMessage) : loading && data.length === 0 ? renderLoadingState ? renderLoadingState({ label: labels.loading }) :
|
|
1339
|
+
}) : /* @__PURE__ */ React2.createElement(Alert, { variant: "danger", title: labels.errorTitle }, typeof error === "string" ? error : labels.errorMessage) : loading && data.length === 0 ? renderLoadingState ? renderLoadingState({ label: labels.loading }) : (
|
|
1340
|
+
// Same EmptyState layout as the empty state (just the "building" image +
|
|
1341
|
+
// a loading message) so loading and empty match with no layout shift.
|
|
1342
|
+
/* @__PURE__ */ React2.createElement(Tile, null, /* @__PURE__ */ React2.createElement(Flex, { direction: "column", align: "center", justify: "center" }, /* @__PURE__ */ React2.createElement(EmptyState, { title: labels.loading, imageName: "building", layout: "vertical" }, /* @__PURE__ */ React2.createElement(Text, null, labels.loadingMessage))))
|
|
1343
|
+
) : filteredData.length === 0 ? renderEmptyState ? renderEmptyState({
|
|
1284
1344
|
title: labels.emptyTitle,
|
|
1285
1345
|
message: labels.emptyMessage
|
|
1286
|
-
}) : /* @__PURE__ */ React2.createElement(Tile, null, /* @__PURE__ */ React2.createElement(EmptyState, { title: labels.emptyTitle, layout: "vertical"
|
|
1346
|
+
}) : /* @__PURE__ */ React2.createElement(Tile, null, /* @__PURE__ */ React2.createElement(Flex, { direction: "column", align: "center", justify: "center" }, /* @__PURE__ */ React2.createElement(EmptyState, { title: labels.emptyTitle, layout: "vertical" }, /* @__PURE__ */ React2.createElement(Text, null, labels.emptyMessage)))) : /* @__PURE__ */ React2.createElement(Flex, { direction: "row", gap: "sm", wrap: "nowrap" }, stages.map((stage) => {
|
|
1287
1347
|
const stageRows = sortedBuckets[stage.value] || [];
|
|
1288
1348
|
const meta = stageMeta == null ? void 0 : stageMeta[stage.value];
|
|
1289
1349
|
const isExpanded = resolvedExpanded.includes(stage.value);
|
|
@@ -1312,11 +1372,12 @@ var Kanban = ({
|
|
|
1312
1372
|
visibleRows.map((row) => renderCardNode(row, stage))
|
|
1313
1373
|
));
|
|
1314
1374
|
}));
|
|
1375
|
+
const resolvedShowClearFiltersButton = showClearFiltersButton ?? showFilterBadges;
|
|
1315
1376
|
return /* @__PURE__ */ React2.createElement(Flex, { direction: "column", gap: "sm" }, /* @__PURE__ */ React2.createElement(
|
|
1316
1377
|
KanbanToolbar,
|
|
1317
1378
|
{
|
|
1318
1379
|
showSearch: searchEnabled,
|
|
1319
|
-
searchValue:
|
|
1380
|
+
searchValue: searchInputValue,
|
|
1320
1381
|
searchPlaceholder: resolvedSearchPlaceholder,
|
|
1321
1382
|
onSearchChange: handleSearch,
|
|
1322
1383
|
filters,
|
|
@@ -1324,7 +1385,7 @@ var Kanban = ({
|
|
|
1324
1385
|
onFilterChange: handleFilter,
|
|
1325
1386
|
filterInlineLimit,
|
|
1326
1387
|
showFilterBadges,
|
|
1327
|
-
showClearFiltersButton,
|
|
1388
|
+
showClearFiltersButton: resolvedShowClearFiltersButton,
|
|
1328
1389
|
activeChips,
|
|
1329
1390
|
onFilterRemove: handleFilterRemove,
|
|
1330
1391
|
sortOptions,
|