@open-mercato/ui 0.6.1-develop.3260.1.dc719cac84 → 0.6.1-develop.3278.1.a4d26475e4
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/.turbo/turbo-build.log +1 -1
- package/dist/backend/DataTable.js +149 -53
- package/dist/backend/DataTable.js.map +2 -2
- package/dist/backend/filters/ActiveFilterChips.js +142 -0
- package/dist/backend/filters/ActiveFilterChips.js.map +7 -0
- package/dist/backend/filters/AdvancedFilterBuilder.js +689 -163
- package/dist/backend/filters/AdvancedFilterBuilder.js.map +2 -2
- package/dist/backend/filters/AdvancedFilterPanel.js +354 -0
- package/dist/backend/filters/AdvancedFilterPanel.js.map +7 -0
- package/dist/backend/filters/FilterEmptyState.js +41 -0
- package/dist/backend/filters/FilterEmptyState.js.map +7 -0
- package/dist/backend/filters/FilterFieldPicker.js +148 -0
- package/dist/backend/filters/FilterFieldPicker.js.map +7 -0
- package/dist/backend/filters/FilteredEmptyResults.js +26 -0
- package/dist/backend/filters/FilteredEmptyResults.js.map +7 -0
- package/dist/backend/filters/QuickFilters.js +41 -0
- package/dist/backend/filters/QuickFilters.js.map +7 -0
- package/dist/backend/filters/filterValidation.js +47 -0
- package/dist/backend/filters/filterValidation.js.map +7 -0
- package/dist/backend/filters/treeReducer.js +159 -0
- package/dist/backend/filters/treeReducer.js.map +7 -0
- package/dist/backend/hooks/useAdvancedFilter.js +82 -1
- package/dist/backend/hooks/useAdvancedFilter.js.map +2 -2
- package/dist/backend/utils/api.js +18 -1
- package/dist/backend/utils/api.js.map +2 -2
- package/dist/backend/utils/useAutoDiscoveredFields.js +1 -0
- package/dist/backend/utils/useAutoDiscoveredFields.js.map +2 -2
- package/dist/backend/utils/useCurrentUserId.js +31 -0
- package/dist/backend/utils/useCurrentUserId.js.map +7 -0
- package/dist/primitives/dialog.js +7 -5
- package/dist/primitives/dialog.js.map +2 -2
- package/dist/primitives/tag.js +4 -2
- package/dist/primitives/tag.js.map +2 -2
- package/package.json +3 -3
- package/src/backend/DataTable.tsx +307 -63
- package/src/backend/__tests__/DataTable.extensions.test.tsx +170 -0
- package/src/backend/filters/ActiveFilterChips.tsx +179 -0
- package/src/backend/filters/AdvancedFilterBuilder.tsx +840 -237
- package/src/backend/filters/AdvancedFilterPanel.tsx +456 -0
- package/src/backend/filters/FilterEmptyState.tsx +51 -0
- package/src/backend/filters/FilterFieldPicker.tsx +139 -0
- package/src/backend/filters/FilteredEmptyResults.tsx +40 -0
- package/src/backend/filters/QuickFilters.tsx +62 -0
- package/src/backend/filters/__tests__/ActiveFilterChips.test.tsx +75 -0
- package/src/backend/filters/__tests__/AdvancedFilterBuilder.test.tsx +210 -0
- package/src/backend/filters/__tests__/AdvancedFilterPanel.test.tsx +212 -0
- package/src/backend/filters/__tests__/FilterEmptyState.test.tsx +31 -0
- package/src/backend/filters/__tests__/FilterFieldPicker.test.tsx +61 -0
- package/src/backend/filters/__tests__/FilteredEmptyResults.test.tsx +35 -0
- package/src/backend/filters/__tests__/QuickFilters.test.tsx +34 -0
- package/src/backend/filters/__tests__/filterValidation.test.ts +69 -0
- package/src/backend/filters/__tests__/treeReducer.test.ts +189 -0
- package/src/backend/filters/filterValidation.ts +61 -0
- package/src/backend/filters/treeReducer.ts +201 -0
- package/src/backend/hooks/__tests__/useAdvancedFilter.test.tsx +213 -0
- package/src/backend/hooks/useAdvancedFilter.ts +130 -0
- package/src/backend/utils/api.ts +27 -2
- package/src/backend/utils/useAutoDiscoveredFields.ts +2 -0
- package/src/backend/utils/useCurrentUserId.ts +40 -0
- package/src/primitives/__tests__/zindex-overlay.test.tsx +22 -0
- package/src/primitives/dialog.tsx +18 -7
- package/src/primitives/tag.tsx +3 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -21,6 +21,7 @@ import { EmptyState } from "../primitives/empty-state.js";
|
|
|
21
21
|
import { TooltipProvider } from "../primitives/tooltip.js";
|
|
22
22
|
import { TruncatedCell } from "./TruncatedCell.js";
|
|
23
23
|
import { FilterBar } from "./FilterBar.js";
|
|
24
|
+
import { FilteredEmptyResults } from "./filters/FilteredEmptyResults.js";
|
|
24
25
|
import { useCustomFieldFilterDefs } from "./utils/customFieldFilters.js";
|
|
25
26
|
import { fetchCustomFieldDefinitionsPayload } from "./utils/customFieldDefs.js";
|
|
26
27
|
import { RowActions } from "./RowActions.js";
|
|
@@ -41,7 +42,15 @@ import { useConfirmDialog } from "./confirm-dialog/index.js";
|
|
|
41
42
|
import { ComponentReplacementHandles } from "@open-mercato/shared/modules/widgets/component-registry";
|
|
42
43
|
import { insertByInjectionPlacement } from "@open-mercato/shared/modules/widgets/injection-position";
|
|
43
44
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
44
|
-
import {
|
|
45
|
+
import { getDefaultOperator, isAdvancedFilterState, flatToTree } from "@open-mercato/shared/lib/query/advanced-filter";
|
|
46
|
+
import {
|
|
47
|
+
createEmptyTree,
|
|
48
|
+
serializeTreeForPersist,
|
|
49
|
+
deserializeTreeFromPersist,
|
|
50
|
+
isPersistedFilterTree,
|
|
51
|
+
treeToFlat
|
|
52
|
+
} from "@open-mercato/shared/lib/query/advanced-filter-tree";
|
|
53
|
+
import { treeReducer } from "./filters/treeReducer.js";
|
|
45
54
|
import { AdvancedFilterBuilder } from "./filters/AdvancedFilterBuilder.js";
|
|
46
55
|
import { useAutoDiscoveredFields } from "./utils/useAutoDiscoveredFields.js";
|
|
47
56
|
import { useCustomFieldDefs } from "./utils/customFieldDefs.js";
|
|
@@ -635,8 +644,10 @@ function DataTable({
|
|
|
635
644
|
virtualized = false,
|
|
636
645
|
virtualizedMaxHeight,
|
|
637
646
|
virtualizedOverscan = 10,
|
|
638
|
-
advancedFilter,
|
|
639
|
-
columnChooser
|
|
647
|
+
advancedFilter: advancedFilterInput,
|
|
648
|
+
columnChooser,
|
|
649
|
+
activeFilterChips,
|
|
650
|
+
filterAwareEmptyState
|
|
640
651
|
}) {
|
|
641
652
|
const t = useT();
|
|
642
653
|
const { confirm, ConfirmDialogElement } = useConfirmDialog();
|
|
@@ -645,6 +656,28 @@ function DataTable({
|
|
|
645
656
|
const containerRef = React.useRef(null);
|
|
646
657
|
const lastScopeRef = React.useRef(null);
|
|
647
658
|
const hasInitializedScopeRef = React.useRef(false);
|
|
659
|
+
const legacyAdvancedFilterWarnedRef = React.useRef(false);
|
|
660
|
+
const advancedFilter = React.useMemo(() => {
|
|
661
|
+
if (!advancedFilterInput) return void 0;
|
|
662
|
+
if (!isAdvancedFilterState(advancedFilterInput.value)) {
|
|
663
|
+
return advancedFilterInput;
|
|
664
|
+
}
|
|
665
|
+
if (!legacyAdvancedFilterWarnedRef.current && process.env.NODE_ENV !== "production") {
|
|
666
|
+
legacyAdvancedFilterWarnedRef.current = true;
|
|
667
|
+
console.warn(
|
|
668
|
+
"[DataTable] `advancedFilter.value` was passed as the legacy `AdvancedFilterState` shape. This bridge will be removed in the next minor version \u2014 migrate to the tree shape (`AdvancedFilterTree`, see `@open-mercato/shared/lib/query/advanced-filter-tree`)."
|
|
669
|
+
);
|
|
670
|
+
}
|
|
671
|
+
const legacy = advancedFilterInput;
|
|
672
|
+
return {
|
|
673
|
+
fields: legacy.fields,
|
|
674
|
+
auto: legacy.auto,
|
|
675
|
+
value: flatToTree(legacy.value),
|
|
676
|
+
onChange: (next) => legacy.onChange(treeToFlat(next)),
|
|
677
|
+
onApply: legacy.onApply,
|
|
678
|
+
onClear: legacy.onClear
|
|
679
|
+
};
|
|
680
|
+
}, [advancedFilterInput]);
|
|
648
681
|
React.useEffect(() => {
|
|
649
682
|
return subscribeOrganizationScopeChanged((detail) => {
|
|
650
683
|
const prev = lastScopeRef.current;
|
|
@@ -1091,20 +1124,27 @@ function DataTable({
|
|
|
1091
1124
|
visibility[key] = value;
|
|
1092
1125
|
}
|
|
1093
1126
|
}
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1127
|
+
let filtersPayload;
|
|
1128
|
+
if (advancedFilter) {
|
|
1129
|
+
const persisted = serializeTreeForPersist(advancedFilter.value);
|
|
1130
|
+
filtersPayload = persisted.root.children.length > 0 ? persisted : void 0;
|
|
1131
|
+
} else {
|
|
1132
|
+
const filtersRecord = {};
|
|
1133
|
+
for (const [key, value] of Object.entries(filterValues ?? {})) {
|
|
1134
|
+
if (typeof key === "string") filtersRecord[key] = value;
|
|
1135
|
+
}
|
|
1136
|
+
if (Object.keys(filtersRecord).length) filtersPayload = filtersRecord;
|
|
1097
1137
|
}
|
|
1098
1138
|
const candidate = {
|
|
1099
1139
|
columnOrder,
|
|
1100
1140
|
columnVisibility: visibility,
|
|
1101
1141
|
sorting,
|
|
1102
|
-
filters:
|
|
1142
|
+
filters: filtersPayload,
|
|
1103
1143
|
searchValue
|
|
1104
1144
|
};
|
|
1105
1145
|
return sanitizePerspectiveSettings(candidate) ?? {};
|
|
1106
|
-
}, [columnOrder, columnVisibility, sorting, filterValues, searchValue]);
|
|
1107
|
-
const applyPerspectiveSettings = React.useCallback((settings, nextId) => {
|
|
1146
|
+
}, [columnOrder, columnVisibility, sorting, filterValues, searchValue, advancedFilter]);
|
|
1147
|
+
const applyPerspectiveSettings = React.useCallback((settings, nextId, options) => {
|
|
1108
1148
|
const normalized = sanitizePerspectiveSettings(settings) ?? {};
|
|
1109
1149
|
if (normalized.columnOrder && normalized.columnOrder.length) {
|
|
1110
1150
|
setColumnOrder(normalized.columnOrder);
|
|
@@ -1125,8 +1165,15 @@ function DataTable({
|
|
|
1125
1165
|
setSorting([]);
|
|
1126
1166
|
onSortingChange?.([]);
|
|
1127
1167
|
}
|
|
1128
|
-
if (
|
|
1129
|
-
|
|
1168
|
+
if (!options?.preserveAdvancedFilter) {
|
|
1169
|
+
const restoredTree = isPersistedFilterTree(normalized.filters) ? deserializeTreeFromPersist(normalized.filters) : null;
|
|
1170
|
+
if (advancedFilter?.onApplyTree) {
|
|
1171
|
+
advancedFilter.onApplyTree(restoredTree ?? createEmptyTree());
|
|
1172
|
+
if (onFiltersApply) onFiltersApply({});
|
|
1173
|
+
} else if (onFiltersApply) {
|
|
1174
|
+
const legacy = restoredTree ? {} : normalized.filters ?? {};
|
|
1175
|
+
onFiltersApply(legacy);
|
|
1176
|
+
}
|
|
1130
1177
|
}
|
|
1131
1178
|
if (onSearchChange) {
|
|
1132
1179
|
onSearchChange(normalized.searchValue ?? "");
|
|
@@ -1143,7 +1190,7 @@ function DataTable({
|
|
|
1143
1190
|
initialSnapshotRef.current = null;
|
|
1144
1191
|
}
|
|
1145
1192
|
}
|
|
1146
|
-
}, [onFiltersApply, onSearchChange, onSortingChange, perspectiveTableId, table]);
|
|
1193
|
+
}, [onFiltersApply, onSearchChange, onSortingChange, perspectiveTableId, table, advancedFilter]);
|
|
1147
1194
|
React.useLayoutEffect(() => {
|
|
1148
1195
|
if (!perspectiveTableId) return;
|
|
1149
1196
|
if (snapshotHydratedTableRef.current === perspectiveTableId) return;
|
|
@@ -1151,9 +1198,14 @@ function DataTable({
|
|
|
1151
1198
|
const snapshot = readPerspectiveSnapshot(perspectiveTableId);
|
|
1152
1199
|
if (!snapshot) return;
|
|
1153
1200
|
initialSnapshotRef.current = snapshot;
|
|
1154
|
-
|
|
1201
|
+
const preserveAdvancedFilter = !!advancedFilter?.onApplyTree;
|
|
1202
|
+
applyPerspectiveSettings(
|
|
1203
|
+
snapshot.settings,
|
|
1204
|
+
snapshot.perspectiveId ?? null,
|
|
1205
|
+
{ preserveAdvancedFilter }
|
|
1206
|
+
);
|
|
1155
1207
|
initialPerspectiveAppliedRef.current = true;
|
|
1156
|
-
}, [perspectiveTableId, applyPerspectiveSettings]);
|
|
1208
|
+
}, [perspectiveTableId, applyPerspectiveSettings, advancedFilter]);
|
|
1157
1209
|
const perspectiveQueryKey = ["table-perspectives", perspectiveTableId];
|
|
1158
1210
|
const savePerspectiveMutation = useMutation({
|
|
1159
1211
|
mutationFn: async (input) => {
|
|
@@ -1366,7 +1418,7 @@ function DataTable({
|
|
|
1366
1418
|
if (!canUsePerspectives) return;
|
|
1367
1419
|
if (!perspectiveTableId) return;
|
|
1368
1420
|
if (initialSnapshotRef.current) return;
|
|
1369
|
-
if (initialPerspectiveAppliedRef.current
|
|
1421
|
+
if (initialPerspectiveAppliedRef.current) return;
|
|
1370
1422
|
const source = perspectiveData ?? perspectiveConfig?.initialState?.response;
|
|
1371
1423
|
if (!source) return;
|
|
1372
1424
|
const tryResolve = (id) => {
|
|
@@ -1603,6 +1655,18 @@ function DataTable({
|
|
|
1603
1655
|
customFieldDefs: needsAutoDiscovery ? autoDiscoveryDefs : []
|
|
1604
1656
|
});
|
|
1605
1657
|
const resolvedAdvancedFilterFields = isAutoAdvancedFilter ? autoDiscovered.advancedFilterFields : advancedFilter?.fields ?? [];
|
|
1658
|
+
const advancedFilterRuleCount = React.useMemo(() => {
|
|
1659
|
+
if (!advancedFilter) return 0;
|
|
1660
|
+
function countRules(group) {
|
|
1661
|
+
let n = 0;
|
|
1662
|
+
for (const c of group.children) {
|
|
1663
|
+
if (c.type === "rule") n += 1;
|
|
1664
|
+
else n += countRules(c);
|
|
1665
|
+
}
|
|
1666
|
+
return n;
|
|
1667
|
+
}
|
|
1668
|
+
return countRules(advancedFilter.value.root);
|
|
1669
|
+
}, [advancedFilter]);
|
|
1606
1670
|
const resolvedColumnChooserFields = isAutoColumnChooser ? autoDiscovered.columnChooserFields : columnChooser?.availableColumns ?? [];
|
|
1607
1671
|
const effectiveColumnChooserFields = React.useMemo(() => {
|
|
1608
1672
|
if (resolvedColumnChooserFields.length > 0) return resolvedColumnChooserFields;
|
|
@@ -1722,14 +1786,56 @@ function DataTable({
|
|
|
1722
1786
|
const builtToolbar = React.useMemo(() => {
|
|
1723
1787
|
if (toolbar) return toolbar;
|
|
1724
1788
|
const anySearch = onSearchChange != null;
|
|
1725
|
-
const
|
|
1789
|
+
const suppressFilterBarFilters = !!(advancedFilter && advancedFilter.externalPopover);
|
|
1790
|
+
const effectiveBaseFilters = suppressFilterBarFilters ? [] : baseFilters;
|
|
1791
|
+
const effectiveCfFilters = suppressFilterBarFilters ? [] : cfFilters;
|
|
1792
|
+
const effectiveInjectedFilters = suppressFilterBarFilters ? [] : injectedFilters;
|
|
1793
|
+
const anyFilters = effectiveBaseFilters && effectiveBaseFilters.length > 0 || effectiveCfFilters && effectiveCfFilters.length > 0 || effectiveInjectedFilters.length > 0;
|
|
1726
1794
|
const hasBulkButtons = hasInjectedBulkActions || hasPropBulkActions;
|
|
1727
|
-
|
|
1728
|
-
const
|
|
1795
|
+
const hasAdvancedFilterButton = Boolean(advancedFilter);
|
|
1796
|
+
const hasPerspectiveButton = canUsePerspectives;
|
|
1797
|
+
if (!anySearch && !anyFilters && !hasBulkButtons && !hasAdvancedFilterButton && !hasPerspectiveButton) return null;
|
|
1798
|
+
const baseList = effectiveBaseFilters || [];
|
|
1729
1799
|
const existing = new Set(baseList.map((f) => f.id));
|
|
1730
|
-
const cfOnly = (
|
|
1731
|
-
const injectedOnly =
|
|
1800
|
+
const cfOnly = (effectiveCfFilters || []).filter((f) => !existing.has(f.id));
|
|
1801
|
+
const injectedOnly = effectiveInjectedFilters.filter((f) => !existing.has(f.id) && !cfOnly.some((cf) => cf.id === f.id));
|
|
1732
1802
|
const combined = [...baseList, ...cfOnly, ...injectedOnly];
|
|
1803
|
+
const advancedFilterButton = advancedFilter ? /* @__PURE__ */ jsxs(
|
|
1804
|
+
Button,
|
|
1805
|
+
{
|
|
1806
|
+
ref: advancedFilter.triggerRef,
|
|
1807
|
+
type: "button",
|
|
1808
|
+
variant: advancedFilterRuleCount > 0 ? "default" : "outline",
|
|
1809
|
+
size: "default",
|
|
1810
|
+
className: advancedFilterRuleCount > 0 ? "bg-foreground text-background hover:bg-foreground/90" : "",
|
|
1811
|
+
onClick: () => {
|
|
1812
|
+
if (advancedFilter.externalPopover) {
|
|
1813
|
+
advancedFilter.onTriggerClick?.();
|
|
1814
|
+
return;
|
|
1815
|
+
}
|
|
1816
|
+
const opening = !isAdvancedFilterOpen;
|
|
1817
|
+
if (opening && advancedFilterRuleCount === 0) {
|
|
1818
|
+
const defaultField = resolvedAdvancedFilterFields[0];
|
|
1819
|
+
const seeded = treeReducer(advancedFilter.value, {
|
|
1820
|
+
type: "addRule",
|
|
1821
|
+
groupId: advancedFilter.value.root.id,
|
|
1822
|
+
defaultField: defaultField?.key,
|
|
1823
|
+
defaultOperator: defaultField ? getDefaultOperator(defaultField.type) : void 0
|
|
1824
|
+
});
|
|
1825
|
+
advancedFilter.onChange(seeded);
|
|
1826
|
+
}
|
|
1827
|
+
setAdvancedFilterOpen(opening);
|
|
1828
|
+
},
|
|
1829
|
+
"aria-label": t("ui.advancedFilter.toggle", "Advanced filters"),
|
|
1830
|
+
title: t("ui.advancedFilter.toggle", "Advanced filters"),
|
|
1831
|
+
"data-testid": "advanced-filter-trigger",
|
|
1832
|
+
children: [
|
|
1833
|
+
/* @__PURE__ */ jsx(Filter, { className: "h-4 w-4" }),
|
|
1834
|
+
/* @__PURE__ */ jsx("span", { children: t("ui.dataTable.filters", "Filters") }),
|
|
1835
|
+
advancedFilterRuleCount > 0 ? /* @__PURE__ */ jsx("span", { className: "ml-1 inline-flex h-5 min-w-5 px-1.5 items-center justify-center rounded-full bg-muted-foreground/30 text-background text-xs", children: advancedFilterRuleCount }) : null
|
|
1836
|
+
]
|
|
1837
|
+
}
|
|
1838
|
+
) : null;
|
|
1733
1839
|
const perspectiveButton = canUsePerspectives ? /* @__PURE__ */ jsx(
|
|
1734
1840
|
ViewSwitcherDropdown,
|
|
1735
1841
|
{
|
|
@@ -1756,7 +1862,10 @@ function DataTable({
|
|
|
1756
1862
|
}
|
|
1757
1863
|
)
|
|
1758
1864
|
] }) : null;
|
|
1759
|
-
const leadingItems = perspectiveButton ? /* @__PURE__ */
|
|
1865
|
+
const leadingItems = advancedFilterButton || perspectiveButton ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1866
|
+
advancedFilterButton,
|
|
1867
|
+
perspectiveButton
|
|
1868
|
+
] }) : null;
|
|
1760
1869
|
const trailingItems = hasBulkButtons ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
1761
1870
|
selectedRows.length > 0 ? /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: t("ui.dataTable.bulkAction.selectedCount", "{count} selected", { count: selectedRows.length }) }) : null,
|
|
1762
1871
|
injectedBulkActions.map((action) => {
|
|
@@ -1845,7 +1954,11 @@ function DataTable({
|
|
|
1845
1954
|
runBulkAction,
|
|
1846
1955
|
runPropBulkAction,
|
|
1847
1956
|
searchTrailingInjectionSpotId,
|
|
1848
|
-
resolvedInjectionContext
|
|
1957
|
+
resolvedInjectionContext,
|
|
1958
|
+
advancedFilter,
|
|
1959
|
+
advancedFilterRuleCount,
|
|
1960
|
+
isAdvancedFilterOpen,
|
|
1961
|
+
resolvedAdvancedFilterFields
|
|
1849
1962
|
]);
|
|
1850
1963
|
const hasTitle = title != null;
|
|
1851
1964
|
const hasActions = actions !== void 0 && actions !== null && actions !== false;
|
|
@@ -1857,7 +1970,7 @@ function DataTable({
|
|
|
1857
1970
|
const hasRefreshButton = Boolean(refreshButtonConfig);
|
|
1858
1971
|
const hasToolbar = builtToolbar != null;
|
|
1859
1972
|
const hasToolbarInjection = Boolean(toolbarInjectionSpotId);
|
|
1860
|
-
const shouldRenderActionsWrapper = hasActions || hasRefreshButton || shouldReserveActionsSpace || hasExport || hasToolbarInjection
|
|
1973
|
+
const shouldRenderActionsWrapper = hasActions || hasRefreshButton || shouldReserveActionsSpace || hasExport || hasToolbarInjection;
|
|
1861
1974
|
const renderToolbarInline = embedded && hasToolbar;
|
|
1862
1975
|
const shouldRenderToolbarBelow = hasToolbar && !renderToolbarInline;
|
|
1863
1976
|
const shouldRenderHeader = hasTitle || renderToolbarInline || shouldRenderActionsWrapper || shouldRenderToolbarBelow;
|
|
@@ -1900,32 +2013,6 @@ function DataTable({
|
|
|
1900
2013
|
]
|
|
1901
2014
|
}
|
|
1902
2015
|
) : null,
|
|
1903
|
-
advancedFilter ? /* @__PURE__ */ jsxs(
|
|
1904
|
-
Button,
|
|
1905
|
-
{
|
|
1906
|
-
type: "button",
|
|
1907
|
-
variant: advancedFilter.value.conditions.length > 0 ? "secondary" : "ghost",
|
|
1908
|
-
size: "icon",
|
|
1909
|
-
onClick: () => {
|
|
1910
|
-
const opening = !isAdvancedFilterOpen;
|
|
1911
|
-
if (opening && advancedFilter.value.conditions.length === 0) {
|
|
1912
|
-
const newCondition = createEmptyCondition();
|
|
1913
|
-
if (resolvedAdvancedFilterFields.length > 0) {
|
|
1914
|
-
newCondition.field = resolvedAdvancedFilterFields[0].key;
|
|
1915
|
-
newCondition.operator = getDefaultOperator(resolvedAdvancedFilterFields[0].type);
|
|
1916
|
-
}
|
|
1917
|
-
advancedFilter.onChange({ ...advancedFilter.value, conditions: [newCondition] });
|
|
1918
|
-
}
|
|
1919
|
-
setAdvancedFilterOpen(opening);
|
|
1920
|
-
},
|
|
1921
|
-
"aria-label": t("ui.advancedFilter.toggle", "Advanced filters"),
|
|
1922
|
-
title: t("ui.advancedFilter.toggle", "Advanced filters"),
|
|
1923
|
-
children: [
|
|
1924
|
-
/* @__PURE__ */ jsx(Filter, { className: "h-4 w-4" }),
|
|
1925
|
-
advancedFilter.value.conditions.length > 0 ? /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 flex h-4 w-4 items-center justify-center rounded-full bg-primary text-overline text-primary-foreground", children: advancedFilter.value.conditions.length }) : null
|
|
1926
|
-
]
|
|
1927
|
-
}
|
|
1928
|
-
) : null,
|
|
1929
2016
|
canUsePerspectives ? /* @__PURE__ */ jsxs(
|
|
1930
2017
|
Button,
|
|
1931
2018
|
{
|
|
@@ -1949,7 +2036,7 @@ function DataTable({
|
|
|
1949
2036
|
shouldRenderToolbarBelow ? /* @__PURE__ */ jsx("div", { className: toolbarWrapperClassName, children: builtToolbar }) : null,
|
|
1950
2037
|
headerInjectionSpotId ? /* @__PURE__ */ jsx("div", { className: embedded ? "mt-2" : "mt-3", children: /* @__PURE__ */ jsx(InjectionSpot, { spotId: headerInjectionSpotId, context: resolvedInjectionContext }) }) : null
|
|
1951
2038
|
] }),
|
|
1952
|
-
advancedFilter && isAdvancedFilterOpen ? /* @__PURE__ */ jsx("div", { className: "border-b", children: /* @__PURE__ */ jsx(
|
|
2039
|
+
advancedFilter && !advancedFilter.externalPopover && isAdvancedFilterOpen ? /* @__PURE__ */ jsx("div", { className: "border-b", children: /* @__PURE__ */ jsx(
|
|
1953
2040
|
AdvancedFilterBuilder,
|
|
1954
2041
|
{
|
|
1955
2042
|
fields: resolvedAdvancedFilterFields,
|
|
@@ -1965,11 +2052,12 @@ function DataTable({
|
|
|
1965
2052
|
}
|
|
1966
2053
|
}
|
|
1967
2054
|
) }) : null,
|
|
1968
|
-
advancedFilter && advancedFilter.
|
|
1969
|
-
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: t("ui.advancedFilter.activeCount", "{count} active filters", { count:
|
|
2055
|
+
advancedFilter && !advancedFilter.externalPopover && advancedFilterRuleCount > 0 && !isAdvancedFilterOpen ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap px-4 py-2 border-b text-sm", children: [
|
|
2056
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: t("ui.advancedFilter.activeCount", "{count} active filters", { count: advancedFilterRuleCount }) }),
|
|
1970
2057
|
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "h-auto px-1 py-0.5 text-xs", onClick: () => setAdvancedFilterOpen(true), children: t("ui.advancedFilter.edit", "Edit") }),
|
|
1971
2058
|
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "h-auto px-1 py-0.5 text-xs text-muted-foreground", onClick: advancedFilter.onClear, children: t("ui.advancedFilter.clearAll", "Clear all") })
|
|
1972
2059
|
] }) : null,
|
|
2060
|
+
activeFilterChips,
|
|
1973
2061
|
/* @__PURE__ */ jsx(
|
|
1974
2062
|
HeaderDndWrapper,
|
|
1975
2063
|
{
|
|
@@ -2120,7 +2208,15 @@ function DataTable({
|
|
|
2120
2208
|
const bottomPadding = lastItem ? rowVirtualizer.getTotalSize() - lastItem.end : 0;
|
|
2121
2209
|
return bottomPadding > 0 ? /* @__PURE__ */ jsx("tr", { style: { height: `${bottomPadding}px` } }) : null;
|
|
2122
2210
|
})() : null
|
|
2123
|
-
] }) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: mergedColumns.length + (rowActions || injectedRowActions.length > 0 ? 1 : 0) + (hasInjectedBulkActions ? 1 : 0), className: "py-6", children:
|
|
2211
|
+
] }) : /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan: mergedColumns.length + (rowActions || injectedRowActions.length > 0 ? 1 : 0) + (hasInjectedBulkActions ? 1 : 0), className: "py-6", children: filterAwareEmptyState?.active ? /* @__PURE__ */ jsx(
|
|
2212
|
+
FilteredEmptyResults,
|
|
2213
|
+
{
|
|
2214
|
+
entityNamePlural: filterAwareEmptyState.entityNamePlural,
|
|
2215
|
+
canRemoveLast: filterAwareEmptyState.canRemoveLast,
|
|
2216
|
+
onClearAll: filterAwareEmptyState.onClearAll,
|
|
2217
|
+
onRemoveLast: filterAwareEmptyState.onRemoveLast
|
|
2218
|
+
}
|
|
2219
|
+
) : emptyState && typeof emptyState !== "string" ? emptyState : /* @__PURE__ */ jsx(
|
|
2124
2220
|
EmptyState,
|
|
2125
2221
|
{
|
|
2126
2222
|
size: "sm",
|