@trackunit/filters-filter-bar 1.7.87 → 1.7.90

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/filters-filter-bar",
3
- "version": "1.7.87",
3
+ "version": "1.7.90",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -9,23 +9,23 @@
9
9
  "dependencies": {
10
10
  "react": "19.0.0",
11
11
  "dequal": "^2.0.3",
12
- "lodash": "4.17.21",
13
12
  "jest-fetch-mock": "^3.0.3",
14
13
  "tailwind-merge": "^2.0.0",
15
14
  "string-ts": "^2.0.0",
16
15
  "zod": "^3.23.8",
17
- "@trackunit/iris-app-api": "1.6.53",
18
- "@trackunit/react-core-hooks": "1.6.57",
19
- "@trackunit/react-filter-components": "1.6.80",
20
- "@trackunit/react-date-and-time-components": "1.9.80",
21
- "@trackunit/shared-utils": "1.8.54",
22
- "@trackunit/react-form-components": "1.7.45",
23
- "@trackunit/react-core-contexts-api": "1.7.55",
24
- "@trackunit/geo-json-utils": "1.6.53",
25
- "@trackunit/i18n-library-translation": "1.6.58",
26
- "@trackunit/css-class-variance-utilities": "1.6.53",
27
- "@trackunit/react-components": "1.8.29",
28
- "@trackunit/react-test-setup": "1.3.53"
16
+ "@trackunit/iris-app-api": "1.6.56",
17
+ "@trackunit/react-core-hooks": "1.6.60",
18
+ "@trackunit/react-filter-components": "1.6.83",
19
+ "@trackunit/react-date-and-time-components": "1.9.83",
20
+ "@trackunit/shared-utils": "1.8.57",
21
+ "@trackunit/react-form-components": "1.7.48",
22
+ "@trackunit/react-core-contexts-api": "1.7.58",
23
+ "@trackunit/geo-json-utils": "1.6.56",
24
+ "@trackunit/i18n-library-translation": "1.6.61",
25
+ "@trackunit/css-class-variance-utilities": "1.6.56",
26
+ "@trackunit/react-components": "1.8.32",
27
+ "@trackunit/react-test-setup": "1.3.56",
28
+ "@tanstack/react-router": "1.114.29"
29
29
  },
30
30
  "module": "./index.esm.js",
31
31
  "main": "./index.cjs.js",
@@ -8,6 +8,10 @@ export type FilterPersistenceConfig<TFilterBarDefinition extends FilterBarDefini
8
8
  * An optional callback function that gets called when filter values change. This overrides the default behavior of saving filter values to local storage.
9
9
  */
10
10
  saveData?: (data: FilterStateValues<TFilterBarDefinition> | null) => void;
11
+ /**
12
+ * An optional callback function that gets called when filter values change. This overrides the default behavior of refreshing filter values.
13
+ */
14
+ refreshData?: () => void;
11
15
  };
12
16
  export interface FilterBarProps<TFilterBarDefinition extends FilterBarDefinition> extends FilterPersistenceConfig<TFilterBarDefinition> {
13
17
  /**
@@ -1,7 +1,6 @@
1
1
  import { ErrorHandlingContextValue } from "@trackunit/react-core-contexts-api";
2
2
  import { ZodTypeAny } from "zod";
3
3
  interface SearchParamAsFilterProps<TZodSchema> {
4
- searchParamName: string;
5
4
  filterName: string;
6
5
  search: Record<PropertyKey, unknown>;
7
6
  zodSchema: TZodSchema;
@@ -12,12 +11,11 @@ interface SearchParamAsFilterProps<TZodSchema> {
12
11
  * The parameter is validated using the provided Zod schema.
13
12
  *
14
13
  * @template T - A Zod schema used for validation.
15
- * @param {string} searchParamName - The name of the search parameter in the URL.
16
14
  * @param {string} filterName - The name of the filter.
17
15
  * @param {object} search - The current search state, provided by `useSearch` from @tanstack/react-router.
18
16
  * @param {T} zodSchema - The Zod schema for validating the filter data.
19
17
  * @param {ErrorHandlingContextValue} errorHandler - Error handling context for capturing and reporting exceptions.
20
18
  * @returns {any} The parsed filter data if validation succeeds, otherwise `null`.
21
19
  */
22
- export declare const useSearchParamAsFilter: <TZodSchema extends ZodTypeAny>({ searchParamName, filterName, search, zodSchema, errorHandler, }: SearchParamAsFilterProps<TZodSchema>) => any;
20
+ export declare const useSearchParamAsFilter: <TZodSchema extends ZodTypeAny>({ filterName, search, zodSchema, errorHandler, }: SearchParamAsFilterProps<TZodSchema>) => any;
23
21
  export {};
@@ -9,7 +9,7 @@ import { FilterBarConfig, FilterBarDefinition, FilterBarInferredValue, FilterMap
9
9
  declare const useFilterBarActions: <TFilterBarDefinition extends FilterBarDefinition>({ name, filterBarConfig, filterBarDefinition, setFilterBarConfig, setValue, initialState, }: {
10
10
  name: string;
11
11
  filterBarConfig: FilterBarConfig<TFilterBarDefinition>;
12
- filterBarDefinition: FilterBarDefinition;
12
+ filterBarDefinition: TFilterBarDefinition;
13
13
  setFilterBarConfig: Dispatch<SetStateAction<FilterBarConfig<TFilterBarDefinition>>>;
14
14
  setValue: (key: string, callback: (prev: FilterBarInferredValue<TFilterBarDefinition, never> | undefined) => FilterBarInferredValue<TFilterBarDefinition, never> | undefined) => void;
15
15
  initialState?: InitialState<TFilterBarDefinition>;
@@ -1,9 +1,14 @@
1
- import { FilterBarConfig, FilterBarDefinition, FilterBarInferredValue } from "../../types/FilterTypes";
1
+ import { FilterBarConfig, FilterBarDefinition, FilterBarInferredValue, FilterDefinition, FilterStateValues, FilterValueType } from "../../types/FilterTypes";
2
2
  import { FilterPersistenceConfig } from "../types";
3
3
  interface FilterBarPersistenceProps<TFilterBarDefinition extends FilterBarDefinition> extends FilterPersistenceConfig<TFilterBarDefinition> {
4
4
  name: string;
5
5
  setValue: (key: string, callback: (prev: FilterBarInferredValue<TFilterBarDefinition, never> | undefined) => FilterBarInferredValue<TFilterBarDefinition, never> | undefined) => void;
6
+ /**
7
+ * An optional callback function that gets called to check if a filter value is the default value.
8
+ */
9
+ isDefaultValue: (key: string, value: FilterValueType) => boolean;
6
10
  }
11
+ export declare const MAX_URL_LENGTH = 5000;
7
12
  /**
8
13
  * Get the persistence key for the filter bar.
9
14
  *
@@ -15,12 +20,51 @@ export declare const getPersistenceKey: (name: string, clientSideUserId?: string
15
20
  /**
16
21
  * Custom hook for managing the persistence of filter bar configurations.
17
22
  *
23
+ * This hook provides a complete state management solution for filter bars with automatic
24
+ * URL synchronization and localStorage persistence. It maintains the following state:
25
+ *
26
+ * ## State Management Flow:
27
+ *
28
+ * 1. **Initial Load**:
29
+ * - Loads from localStorage (if no custom loadData or saveData function is provided)
30
+ * - Updates with state from URL search parameters
31
+ * - Ensures URL is updated with the final state after load
32
+ *
33
+ * 2. **Save Operations**:
34
+ * - Updates localStorage with new filter values
35
+ * - Updates URL search parameters to reflect current state
36
+ * - Maintains synchronization between localStorage and URL
37
+ *
38
+ * 3. **URL Change Detection**:
39
+ * - Listens for changes in URL search parameters
40
+ * - Compares URL state with last known state to detect external changes
41
+ * - Triggers refreshData callback when external URL changes are detected
42
+ * - Only updates URL when no custom loadData or saveData function provided
43
+ *
44
+ * ## Behavior Modes:
45
+ *
46
+ * **Default Mode** (no custom functions):
47
+ * - Uses localStorage for persistence
48
+ * - Automatically syncs with URL search parameters
49
+ * - Handles URL updates and change detection
50
+ *
51
+ * **Custom Mode** (with loadData/saveData functions):
52
+ * - Does NOT sync with URL or use localStorage
53
+ * - Relies entirely on provided functions for persistence
54
+ * - Does not provide URL change detection via refreshData callback
55
+ *
56
+ * The hook prevents infinite loops by:
57
+ * - Tracking what state was last sent to the URL
58
+ * - Only updating URL when state actually changes
59
+ * - Distinguishing between internal state changes and external URL changes
60
+ *
18
61
  * @template TFilterBarDefinition - The type of the filter bar definition.
19
62
  * @param {FilterBarPersistenceProps<TFilterBarDefinition>} props - The props for the filter bar persistence.
20
63
  * @returns { object } An object containing the loadData and saveData functions.
21
64
  */
22
- export declare const useFilterBarPersistence: <TFilterBarDefinition extends FilterBarDefinition>({ name, setValue, loadData: inputLoadData, saveData: inputSaveData, }: FilterBarPersistenceProps<TFilterBarDefinition>) => {
65
+ export declare const useFilterBarPersistence: <TFilterBarDefinition extends FilterBarDefinition>({ name, setValue, refreshData, isDefaultValue, loadData: inputLoadData, saveData: inputSaveData, }: FilterBarPersistenceProps<TFilterBarDefinition>) => {
23
66
  loadData: <TFilterBarDefinitionExtended extends TFilterBarDefinition>(updatedFilterDefinitionsValues: Array<TFilterBarDefinitionExtended[keyof TFilterBarDefinitionExtended]>) => FilterBarConfig<TFilterBarDefinition>;
24
67
  saveData: (filterBarConfig: Partial<FilterBarConfig<TFilterBarDefinition>>, filterBarDefinitions: TFilterBarDefinition) => void;
68
+ getFilterValuesToUrl: (values: FilterStateValues<FilterBarDefinition> | null, definitions: Array<FilterDefinition>, setEmptyAndDefaultValues: boolean, isDefaultValue: (key: string, value: FilterValueType) => boolean) => Record<string, unknown>;
25
69
  };
26
70
  export {};
@@ -0,0 +1,10 @@
1
+ import { FilterBarDefinition, FilterDefinition, FilterStateValues, FilterValueType } from "../../types/FilterTypes";
2
+ /**
3
+ * Hook to sync filter values with URL
4
+ *
5
+ * @returns {object} Object containing loadFromUrl and saveToUrl functions
6
+ */
7
+ export declare const useFilterUrlSync: () => {
8
+ getFilterValuesFromUrl: <TFilterBarDefinition extends FilterBarDefinition>(definitions: Array<FilterDefinition>, search: Record<PropertyKey, unknown>) => FilterStateValues<TFilterBarDefinition>;
9
+ getFilterValuesToUrl: (values: FilterStateValues<FilterBarDefinition> | null, definitions: Array<FilterDefinition>, setEmptyAndDefaultValues: boolean, isDefaultValue: (key: string, value: FilterValueType) => boolean) => Record<string, unknown>;
10
+ };
@@ -0,0 +1,10 @@
1
+ import { FilterBarDefinition, FilterValueType, InitialState } from "../../types/FilterTypes";
2
+ /**
3
+ * Generic hook for setting the value of a filter bar.
4
+ *
5
+ * @template TFilterBarDefinition - The type of the filter bar definition.
6
+ * @returns {object} An object containing the setValue function.
7
+ */
8
+ export declare const useIsDefaultValue: <TFilterBarDefinition extends FilterBarDefinition>() => {
9
+ isDefaultValue: (key: string, filterValue: FilterValueType, filterBarDefinition: TFilterBarDefinition, initialState?: InitialState<TFilterBarDefinition>) => boolean;
10
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * This hook provides functionality to:
3
+ * - Get the length of the search parameters excluding a specific key
4
+ */
5
+ export declare const useSearchUtils: () => {
6
+ getSearchParamsLengthExcluding: (excludeKey: string, searchParams: Record<PropertyKey, unknown>) => number;
7
+ getUrlLengthWithSearchParam: (key: string, value: string, prev: Record<PropertyKey, unknown>) => number;
8
+ };
@@ -1,5 +1,6 @@
1
1
  import { ReactNode } from "react";
2
- import { AreaFilterGeoJsonGeometry } from "./FilterZodTypes";
2
+ import z, { ZodTypeAny } from "zod";
3
+ import { AreaFilterGeoJsonGeometry, areaFilterGeoJsonGeometrySchema, booleanSchema, dateRangeSchema, minMaxFilterSchema, numberSchema, stringArraySchema, stringSchema, valueNameArraySchema, valueNameSchema } from "./FilterZodTypes";
3
4
  export type ValueName = {
4
5
  value: string;
5
6
  name: string;
@@ -14,7 +15,7 @@ export type MinMaxFilterValue = {
14
15
  min?: number;
15
16
  max?: number;
16
17
  };
17
- export type FilterValueType = Array<string> | Array<ValueName> | ValueName | MinMaxFilterValue | AreaFilterGeoJsonGeometry | string | number | BooleanValue | undefined;
18
+ export type FilterValueType = Array<string> | Array<ValueName> | ValueName | DateRangeValue | MinMaxFilterValue | AreaFilterGeoJsonGeometry | string | number | BooleanValue | undefined;
18
19
  export declare type FilterTypes = "boolean" | "string" | "number" | "dateRange" | "area" | "valueNameArray" | "valueName" | "stringArray" | "minMax";
19
20
  export type FilterMapActions = {
20
21
  toggleArrayValue: (key: string, value: string) => void;
@@ -62,48 +63,63 @@ export interface AbstractFilterDefinition {
62
63
  showInFilterBar?: () => boolean;
63
64
  showDirectly?: boolean;
64
65
  isHidden?: boolean;
66
+ zodSchema?: ZodTypeAny;
65
67
  }
66
68
  export interface BooleanFilterDefinition extends AbstractFilterDefinition {
67
69
  type: "boolean";
68
70
  defaultValue?: BooleanValue;
69
71
  valueAsText?: (value: BooleanValue) => string;
70
72
  component: (filterComponentProps: FilterViewProps<BooleanValue>) => ReactNode;
73
+ zodSchema?: typeof booleanSchema;
71
74
  }
72
75
  export interface StringFilterDefinition extends AbstractFilterDefinition {
73
76
  type: "string";
74
77
  defaultValue?: string;
75
78
  valueAsText?: (value: string) => string;
76
79
  component: (filterComponentProps: FilterViewProps<string>) => ReactNode;
80
+ zodSchema?: typeof stringSchema;
77
81
  }
78
82
  export interface NumberFilterDefinition extends AbstractFilterDefinition {
79
83
  type: "number";
80
84
  defaultValue?: number;
81
85
  valueAsText?: (value: number) => string;
82
86
  component: (filterComponentProps: FilterViewProps<number>) => ReactNode;
87
+ zodSchema?: typeof numberSchema;
83
88
  }
84
89
  export interface AreaFilterDefinition extends AbstractFilterDefinition {
85
90
  type: "area";
86
91
  defaultValue?: AreaFilterGeoJsonGeometry;
87
92
  valueAsText?: (value: AreaFilterGeoJsonGeometry) => string;
88
93
  component: (filterComponentProps: FilterViewProps<AreaFilterGeoJsonGeometry>) => ReactNode;
94
+ zodSchema?: typeof areaFilterGeoJsonGeometrySchema;
89
95
  }
90
96
  export interface ValueNameArrayFilterDefinition extends AbstractFilterDefinition {
91
97
  type: "valueNameArray";
92
98
  defaultValue?: Array<ValueName>;
93
99
  valueAsText?: (value: Array<ValueName>) => Array<string>;
94
100
  component: (filterComponentProps: FilterViewProps<Array<ValueName>>) => ReactNode;
101
+ zodSchema?: typeof valueNameArraySchema;
95
102
  }
96
103
  export interface ValueNameFilterDefinition extends AbstractFilterDefinition {
97
104
  type: "valueName";
98
105
  defaultValue?: ValueName;
99
106
  valueAsText?: (value: ValueName) => string;
100
107
  component: (filterComponentProps: FilterViewProps<ValueName>) => ReactNode;
108
+ zodSchema?: typeof valueNameSchema;
101
109
  }
102
110
  export interface StringArrayFilterDefinition extends AbstractFilterDefinition {
103
111
  type: "stringArray";
104
112
  defaultValue?: Array<string>;
105
113
  valueAsText?: (value: Array<string>) => Array<string>;
106
114
  component: (filterComponentProps: FilterViewProps<Array<string>>) => ReactNode;
115
+ zodSchema?: typeof stringArraySchema;
116
+ }
117
+ export interface ArrayFilterDefinition<TZodType extends ZodTypeAny> extends AbstractFilterDefinition {
118
+ type: "stringArray";
119
+ defaultValue?: z.infer<TZodType>;
120
+ valueAsText?: (value: z.infer<TZodType>) => Array<string>;
121
+ component: (filterComponentProps: FilterViewProps<z.infer<TZodType>>) => ReactNode;
122
+ zodSchema: TZodType;
107
123
  }
108
124
  export interface MinMaxFilterDefinition extends AbstractFilterDefinition {
109
125
  type: "minMax";
@@ -118,6 +134,7 @@ export interface MinMaxFilterDefinition extends AbstractFilterDefinition {
118
134
  maximumNumber?: number | undefined;
119
135
  valueAsText?: (value: MinMaxFilterValue) => string;
120
136
  component: (filterComponentProps: FilterViewProps<MinMaxFilterValue>) => ReactNode;
137
+ zodSchema?: typeof minMaxFilterSchema;
121
138
  }
122
139
  export type DateRangeValue = {
123
140
  from: string | undefined;
@@ -136,8 +153,9 @@ export interface DateRangeFilterDefinition extends AbstractFilterDefinition {
136
153
  to?: string | undefined;
137
154
  valueAsText?: (value: DateRangeValue) => string;
138
155
  component: (filterComponentProps: FilterViewProps<DateRangeValue>) => ReactNode;
156
+ zodSchema?: typeof dateRangeSchema;
139
157
  }
140
- export type FilterDefinition = BooleanFilterDefinition | MinMaxFilterDefinition | StringFilterDefinition | NumberFilterDefinition | DateRangeFilterDefinition | AreaFilterDefinition | ValueNameFilterDefinition | ValueNameArrayFilterDefinition | StringArrayFilterDefinition;
158
+ export type FilterDefinition = BooleanFilterDefinition | MinMaxFilterDefinition | StringFilterDefinition | NumberFilterDefinition | DateRangeFilterDefinition | AreaFilterDefinition | ValueNameFilterDefinition | ValueNameArrayFilterDefinition | ArrayFilterDefinition<any> | StringArrayFilterDefinition;
141
159
  export type FilterDefinitionValue = NonNullable<FilterDefinition["defaultValue"]>;
142
160
  export interface FilterViewProps<TReturnType> {
143
161
  filterDefinition: FilterDefinition;
@@ -22,3 +22,47 @@ export declare const areaFilterGeoJsonGeometrySchema: z.ZodUnion<[z.ZodObject<{
22
22
  coordinates: [number, number][][][];
23
23
  }>]>;
24
24
  export type AreaFilterGeoJsonGeometry = z.infer<typeof areaFilterGeoJsonGeometrySchema>;
25
+ export declare const stringSchema: z.ZodString;
26
+ export declare const stringArraySchema: z.ZodArray<z.ZodString, "many">;
27
+ export declare const numberSchema: z.ZodNumber;
28
+ export declare const booleanSchema: z.ZodBoolean;
29
+ export declare const valueNameSchema: z.ZodObject<{
30
+ value: z.ZodString;
31
+ name: z.ZodString;
32
+ }, "strip", z.ZodTypeAny, {
33
+ value: string;
34
+ name: string;
35
+ }, {
36
+ value: string;
37
+ name: string;
38
+ }>;
39
+ export declare const minMaxFilterSchema: z.ZodObject<{
40
+ min: z.ZodOptional<z.ZodNumber>;
41
+ max: z.ZodOptional<z.ZodNumber>;
42
+ }, "strip", z.ZodTypeAny, {
43
+ min?: number | undefined;
44
+ max?: number | undefined;
45
+ }, {
46
+ min?: number | undefined;
47
+ max?: number | undefined;
48
+ }>;
49
+ export declare const dateRangeSchema: z.ZodObject<{
50
+ from: z.ZodOptional<z.ZodString>;
51
+ to: z.ZodOptional<z.ZodString>;
52
+ }, "strip", z.ZodTypeAny, {
53
+ from?: string | undefined;
54
+ to?: string | undefined;
55
+ }, {
56
+ from?: string | undefined;
57
+ to?: string | undefined;
58
+ }>;
59
+ export declare const valueNameArraySchema: z.ZodArray<z.ZodObject<{
60
+ value: z.ZodString;
61
+ name: z.ZodString;
62
+ }, "strip", z.ZodTypeAny, {
63
+ value: string;
64
+ name: string;
65
+ }, {
66
+ value: string;
67
+ name: string;
68
+ }>, "many">;