@izumisy-tailor/tailor-data-viewer 0.2.9 → 0.2.10

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@izumisy-tailor/tailor-data-viewer",
3
3
  "private": false,
4
- "version": "0.2.9",
4
+ "version": "0.2.10",
5
5
  "type": "module",
6
6
  "description": "Flexible data viewer component for Tailor Platform",
7
7
  "files": [
@@ -73,7 +73,7 @@ describe("useCollection", () => {
73
73
  const { result } = renderHook(() => useCollection({ query: FAKE_QUERY }));
74
74
 
75
75
  act(() => {
76
- result.current.addFilter("status", "ACTIVE", "eq");
76
+ result.current.addFilter("status", "eq", "ACTIVE");
77
77
  });
78
78
 
79
79
  expect(result.current.filters).toHaveLength(1);
@@ -91,10 +91,10 @@ describe("useCollection", () => {
91
91
  const { result } = renderHook(() => useCollection({ query: FAKE_QUERY }));
92
92
 
93
93
  act(() => {
94
- result.current.addFilter("status", "ACTIVE", "eq");
94
+ result.current.addFilter("status", "eq", "ACTIVE");
95
95
  });
96
96
  act(() => {
97
- result.current.addFilter("status", "INACTIVE", "eq");
97
+ result.current.addFilter("status", "eq", "INACTIVE");
98
98
  });
99
99
 
100
100
  expect(result.current.filters).toHaveLength(1);
@@ -130,8 +130,8 @@ describe("useCollection", () => {
130
130
  const { result } = renderHook(() => useCollection({ query: FAKE_QUERY }));
131
131
 
132
132
  act(() => {
133
- result.current.addFilter("status", "ACTIVE", "eq");
134
- result.current.addFilter("amount", 1000, "gte");
133
+ result.current.addFilter("status", "eq", "ACTIVE");
134
+ result.current.addFilter("amount", "gte", 1000);
135
135
  });
136
136
  act(() => {
137
137
  result.current.removeFilter("status");
@@ -145,8 +145,8 @@ describe("useCollection", () => {
145
145
  const { result } = renderHook(() => useCollection({ query: FAKE_QUERY }));
146
146
 
147
147
  act(() => {
148
- result.current.addFilter("status", "ACTIVE", "eq");
149
- result.current.addFilter("amount", 1000, "gte");
148
+ result.current.addFilter("status", "eq", "ACTIVE");
149
+ result.current.addFilter("amount", "gte", 1000);
150
150
  });
151
151
  act(() => {
152
152
  result.current.clearFilters();
@@ -167,7 +167,7 @@ describe("useCollection", () => {
167
167
 
168
168
  // Adding filter should reset pagination
169
169
  act(() => {
170
- result.current.addFilter("status", "ACTIVE", "eq");
170
+ result.current.addFilter("status", "eq", "ACTIVE");
171
171
  });
172
172
  expect(result.current.cursor).toBeNull();
173
173
  expect(result.current.hasPrevPage).toBe(false);
@@ -65,7 +65,8 @@ export function useCollection<
65
65
  {
66
66
  query: TQuery;
67
67
  variables: ResolveVariables<TQuery, FieldName<TMetadata, TTableName>>;
68
- }
68
+ },
69
+ MetadataFilter<TMetadata, TTableName>
69
70
  >;
70
71
 
71
72
  /**
@@ -129,7 +130,7 @@ export function useCollection(
129
130
  // Filter operations
130
131
  // ---------------------------------------------------------------------------
131
132
  const addFilter = useCallback(
132
- (field: string, value: unknown, operator: FilterOperator = "eq") => {
133
+ (field: string, operator: FilterOperator, value: unknown) => {
133
134
  setFiltersState((prev) => {
134
135
  const existing = prev.findIndex((f) => f.field === field);
135
136
  const newFilter: Filter = {
@@ -273,7 +274,9 @@ export function useCollection(
273
274
  return {
274
275
  toQueryArgs,
275
276
  filters,
276
- addFilter,
277
+ // Cast needed: implementation accepts FilterOperator (widest),
278
+ // but overload signatures narrow via OperatorForField<TFilter, F>.
279
+ addFilter: addFilter as UseCollectionReturn["addFilter"],
277
280
  setFilters,
278
281
  removeFilter,
279
282
  clearFilters,
@@ -133,7 +133,7 @@ export function SearchFilterForm<TRow extends Record<string, unknown>>({
133
133
 
134
134
  if (!isBooleanType && !filterValue.trim()) return;
135
135
 
136
- addFilter(selectedField, value, selectedOperator);
136
+ addFilter(selectedField, selectedOperator, value);
137
137
  setSelectedField("");
138
138
  setSelectedOperator("eq");
139
139
  setFilterValue("");
@@ -72,6 +72,21 @@ export type OperatorForFilterType = {
72
72
  */
73
73
  export type FilterOperator = OperatorForFilterType[FilterConfig["type"]];
74
74
 
75
+ /**
76
+ * Resolve the operator union for a specific field within a filter type.
77
+ *
78
+ * When `TFilter` is a metadata-aware discriminated union (e.g. `MetadataFilter`),
79
+ * this narrows operators to only those valid for the given field's type.
80
+ * When the field cannot be resolved (e.g. non-metadata usage), falls back to `FilterOperator`.
81
+ */
82
+ export type OperatorForField<TFilter, F extends string> = [
83
+ Extract<TFilter, { field: F }>,
84
+ ] extends [never]
85
+ ? FilterOperator
86
+ : Extract<TFilter, { field: F }> extends { operator: infer O }
87
+ ? O
88
+ : FilterOperator;
89
+
75
90
  // =============================================================================
76
91
  // Filter Type → FieldType Mapping (type-level)
77
92
  // =============================================================================
@@ -364,6 +379,7 @@ export interface UseCollectionReturn<
364
379
  TFieldName extends string = string,
365
380
  TVariables = QueryVariables<TFieldName>,
366
381
  TQueryArgs = { query: unknown; variables: TVariables },
382
+ TFilter = Filter<TFieldName>,
367
383
  > {
368
384
  /**
369
385
  * Returns query arguments (`{ query, variables }`) that can be spread
@@ -381,7 +397,11 @@ export interface UseCollectionReturn<
381
397
  /** Current active filters */
382
398
  filters: Filter[];
383
399
  /** Add or update a filter for a field */
384
- addFilter(field: TFieldName, value: unknown, operator?: FilterOperator): void;
400
+ addFilter<F extends TFieldName>(
401
+ field: F,
402
+ operator: OperatorForField<TFilter, F>,
403
+ value: unknown,
404
+ ): void;
385
405
  /** Replace all filters at once */
386
406
  setFilters(filters: Filter[]): void;
387
407
  /** Remove filter for a specific field */
@@ -762,7 +782,7 @@ export interface SearchFilterFormProps<TRow extends Record<string, unknown>> {
762
782
  /** Current active filters */
763
783
  filters: Filter[];
764
784
  /** Add or update a filter */
765
- addFilter: (field: string, value: unknown, operator?: FilterOperator) => void;
785
+ addFilter: (field: string, operator: FilterOperator, value: unknown) => void;
766
786
  /** Remove a filter */
767
787
  removeFilter: (field: string) => void;
768
788
  /** Clear all filters */