@shefing/quickfilter 1.0.9 → 1.0.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/dist/FilterField.js +3 -3
- package/dist/FilterField.js.map +1 -1
- package/dist/QuickFilter.d.ts.map +1 -1
- package/dist/QuickFilter.js +41 -10
- package/dist/QuickFilter.js.map +1 -1
- package/dist/filters/components/checkbox-filter.d.ts.map +1 -1
- package/dist/filters/components/checkbox-filter.js +41 -44
- package/dist/filters/components/checkbox-filter.js.map +1 -1
- package/dist/filters/components/date-filter.d.ts.map +1 -1
- package/dist/filters/components/date-filter.js +23 -11
- package/dist/filters/components/date-filter.js.map +1 -1
- package/dist/filters/components/select-filter.d.ts.map +1 -1
- package/dist/filters/components/select-filter.js +5 -4
- package/dist/filters/components/select-filter.js.map +1 -1
- package/dist/filters/components/small-select-filter.d.ts.map +1 -1
- package/dist/filters/components/small-select-filter.js +1 -1
- package/dist/filters/components/small-select-filter.js.map +1 -1
- package/package.json +1 -1
package/dist/FilterField.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import React, { useCallback } from 'react';
|
|
4
4
|
import { useTranslation } from '@payloadcms/ui';
|
|
5
|
-
import { rtlLanguages } from '@payloadcms/translations';
|
|
5
|
+
import { getTranslation, rtlLanguages } from '@payloadcms/translations';
|
|
6
6
|
import { DateFilter } from './filters/components/date-filter';
|
|
7
7
|
import { SmallSelectFilter } from './filters/components/small-select-filter';
|
|
8
8
|
import { SelectFilter } from './filters/components/select-filter';
|
|
@@ -48,7 +48,7 @@ const FilterField = ({ field, onFilterChange, value: controlledValue })=>{
|
|
|
48
48
|
return /*#__PURE__*/ _jsx(SmallSelectFilter, {
|
|
49
49
|
label: field.label,
|
|
50
50
|
options: (field.options || []).map((option)=>({
|
|
51
|
-
label: option.label,
|
|
51
|
+
label: getTranslation(option.label, i18n),
|
|
52
52
|
value: option.value
|
|
53
53
|
})),
|
|
54
54
|
onChange: handleSelectFilterChange,
|
|
@@ -60,7 +60,7 @@ const FilterField = ({ field, onFilterChange, value: controlledValue })=>{
|
|
|
60
60
|
return /*#__PURE__*/ _jsx(SelectFilter, {
|
|
61
61
|
label: field.label,
|
|
62
62
|
options: (field.options || []).map((option)=>({
|
|
63
|
-
label: option.label,
|
|
63
|
+
label: getTranslation(option.label, i18n),
|
|
64
64
|
value: option.value
|
|
65
65
|
})),
|
|
66
66
|
onChange: handleSelectFilterChange,
|
package/dist/FilterField.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/FilterField.tsx"],"sourcesContent":["'use client';\nimport React, { useCallback } from 'react';\nimport { useTranslation } from '@payloadcms/ui';\nimport { rtlLanguages } from '@payloadcms/translations';\nimport { DateFilter } from './filters/components/date-filter';\nimport { Locale } from './filters/types/filters-type';\nimport { SmallSelectFilter } from './filters/components/small-select-filter';\nimport { SelectFilter } from './filters/components/select-filter';\nimport { CheckboxFilter } from './filters/components/checkbox-filter';\n\nconst FilterField = ({\n field,\n onFilterChange,\n value: controlledValue,\n}: {\n field: any;\n onFilterChange: (fieldName: string, value: any) => void;\n value: any;\n}) => {\n const { i18n } = useTranslation();\n const localeLang = i18n.language;\n const isRTL = (rtlLanguages as readonly string[]).includes(localeLang);\n const direction = isRTL ? 'rtl' : 'ltr';\n const userLocale = { code: localeLang, direction };\n\n const handleDateFilterChange = useCallback(\n (value: any) => {\n onFilterChange(field.name, value);\n },\n [onFilterChange, field.name],\n );\n\n const handleSelectFilterChange = useCallback(\n (value: any) => {\n onFilterChange(field.name, value);\n },\n [onFilterChange, field.name],\n );\n\n const handleCheckboxFilterChange = useCallback(\n (state: any) => {\n onFilterChange(field.name, state);\n },\n [onFilterChange, field.name],\n );\n\n switch (field.type) {\n case 'date':\n return (\n <DateFilter\n label={field.label}\n value={controlledValue}\n key={field.name}\n onChange={handleDateFilterChange}\n locale={userLocale as Locale}\n className={` w-[${field.width || '250px'}]`}\n />\n );\n case 'select':\n if (field.options.length <= 3) {\n return (\n <SmallSelectFilter\n label={field.label}\n key={field.name}\n options={(field.options || []).map((option: any) => ({\n label: option.label,\n value: option.value,\n }))}\n onChange={handleSelectFilterChange}\n value={controlledValue}\n locale={userLocale as Locale}\n className={` w-[${field.width || '250px'}]`}\n />\n );\n }\n return (\n <SelectFilter\n label={field.label}\n key={field.name}\n options={(field.options || []).map((option: any) => ({\n label: option.label,\n value: option.value,\n }))}\n onChange={handleSelectFilterChange}\n value={controlledValue}\n locale={userLocale as Locale}\n className={` w-[${field.width || '250px'}]`}\n />\n );\n case 'checkbox':\n return (\n <CheckboxFilter\n label={field.label}\n key={field.name}\n onChange={handleCheckboxFilterChange}\n value={controlledValue}\n checkboxLabel={''}\n locale={userLocale as Locale}\n className={` w-[${field.width || '250px'}]`}\n />\n );\n default:\n return null;\n }\n};\n\nexport default FilterField;\n"],"names":["React","useCallback","useTranslation","rtlLanguages","DateFilter","SmallSelectFilter","SelectFilter","CheckboxFilter","FilterField","field","onFilterChange","value","controlledValue","i18n","localeLang","language","isRTL","includes","direction","userLocale","code","handleDateFilterChange","name","handleSelectFilterChange","handleCheckboxFilterChange","state","type","label","onChange","locale","className","width","options","length","map","option","checkboxLabel"],"mappings":"AAAA;;AACA,OAAOA,SAASC,WAAW,QAAQ,QAAQ;AAC3C,SAASC,cAAc,QAAQ,iBAAiB;AAChD,SAASC,YAAY,QAAQ,2BAA2B;
|
|
1
|
+
{"version":3,"sources":["../src/FilterField.tsx"],"sourcesContent":["'use client';\nimport React, { useCallback } from 'react';\nimport { useTranslation } from '@payloadcms/ui';\nimport { getTranslation, rtlLanguages } from '@payloadcms/translations';\nimport { DateFilter } from './filters/components/date-filter';\nimport { Locale } from './filters/types/filters-type';\nimport { SmallSelectFilter } from './filters/components/small-select-filter';\nimport { SelectFilter } from './filters/components/select-filter';\nimport { CheckboxFilter } from './filters/components/checkbox-filter';\n\nconst FilterField = ({\n field,\n onFilterChange,\n value: controlledValue,\n}: {\n field: any;\n onFilterChange: (fieldName: string, value: any) => void;\n value: any;\n}) => {\n const { i18n } = useTranslation();\n const localeLang = i18n.language;\n const isRTL = (rtlLanguages as readonly string[]).includes(localeLang);\n const direction = isRTL ? 'rtl' : 'ltr';\n const userLocale = { code: localeLang, direction };\n\n const handleDateFilterChange = useCallback(\n (value: any) => {\n onFilterChange(field.name, value);\n },\n [onFilterChange, field.name],\n );\n\n const handleSelectFilterChange = useCallback(\n (value: any) => {\n onFilterChange(field.name, value);\n },\n [onFilterChange, field.name],\n );\n\n const handleCheckboxFilterChange = useCallback(\n (state: any) => {\n onFilterChange(field.name, state);\n },\n [onFilterChange, field.name],\n );\n\n switch (field.type) {\n case 'date':\n return (\n <DateFilter\n label={field.label}\n value={controlledValue}\n key={field.name}\n onChange={handleDateFilterChange}\n locale={userLocale as Locale}\n className={` w-[${field.width || '250px'}]`}\n />\n );\n case 'select':\n if (field.options.length <= 3) {\n return (\n <SmallSelectFilter\n label={field.label}\n key={field.name}\n options={(field.options || []).map((option: any) => ({\n label: getTranslation(option.label, i18n),\n value: option.value,\n }))}\n onChange={handleSelectFilterChange}\n value={controlledValue}\n locale={userLocale as Locale}\n className={` w-[${field.width || '250px'}]`}\n />\n );\n }\n return (\n <SelectFilter\n label={field.label}\n key={field.name}\n options={(field.options || []).map((option: any) => ({\n label: getTranslation(option.label, i18n),\n value: option.value,\n }))}\n onChange={handleSelectFilterChange}\n value={controlledValue}\n locale={userLocale as Locale}\n className={` w-[${field.width || '250px'}]`}\n />\n );\n case 'checkbox':\n return (\n <CheckboxFilter\n label={field.label}\n key={field.name}\n onChange={handleCheckboxFilterChange}\n value={controlledValue}\n checkboxLabel={''}\n locale={userLocale as Locale}\n className={` w-[${field.width || '250px'}]`}\n />\n );\n default:\n return null;\n }\n};\n\nexport default FilterField;\n"],"names":["React","useCallback","useTranslation","getTranslation","rtlLanguages","DateFilter","SmallSelectFilter","SelectFilter","CheckboxFilter","FilterField","field","onFilterChange","value","controlledValue","i18n","localeLang","language","isRTL","includes","direction","userLocale","code","handleDateFilterChange","name","handleSelectFilterChange","handleCheckboxFilterChange","state","type","label","onChange","locale","className","width","options","length","map","option","checkboxLabel"],"mappings":"AAAA;;AACA,OAAOA,SAASC,WAAW,QAAQ,QAAQ;AAC3C,SAASC,cAAc,QAAQ,iBAAiB;AAChD,SAASC,cAAc,EAAEC,YAAY,QAAQ,2BAA2B;AACxE,SAASC,UAAU,QAAQ,mCAAmC;AAE9D,SAASC,iBAAiB,QAAQ,2CAA2C;AAC7E,SAASC,YAAY,QAAQ,qCAAqC;AAClE,SAASC,cAAc,QAAQ,uCAAuC;AAEtE,MAAMC,cAAc,CAAC,EACnBC,KAAK,EACLC,cAAc,EACdC,OAAOC,eAAe,EAKvB;IACC,MAAM,EAAEC,IAAI,EAAE,GAAGZ;IACjB,MAAMa,aAAaD,KAAKE,QAAQ;IAChC,MAAMC,QAAQ,AAACb,aAAmCc,QAAQ,CAACH;IAC3D,MAAMI,YAAYF,QAAQ,QAAQ;IAClC,MAAMG,aAAa;QAAEC,MAAMN;QAAYI;IAAU;IAEjD,MAAMG,yBAAyBrB,YAC7B,CAACW;QACCD,eAAeD,MAAMa,IAAI,EAAEX;IAC7B,GACA;QAACD;QAAgBD,MAAMa,IAAI;KAAC;IAG9B,MAAMC,2BAA2BvB,YAC/B,CAACW;QACCD,eAAeD,MAAMa,IAAI,EAAEX;IAC7B,GACA;QAACD;QAAgBD,MAAMa,IAAI;KAAC;IAG9B,MAAME,6BAA6BxB,YACjC,CAACyB;QACCf,eAAeD,MAAMa,IAAI,EAAEG;IAC7B,GACA;QAACf;QAAgBD,MAAMa,IAAI;KAAC;IAG9B,OAAQb,MAAMiB,IAAI;QAChB,KAAK;YACH,qBACE,KAACtB;gBACCuB,OAAOlB,MAAMkB,KAAK;gBAClBhB,OAAOC;gBAEPgB,UAAUP;gBACVQ,QAAQV;gBACRW,WAAW,CAAC,IAAI,EAAErB,MAAMsB,KAAK,IAAI,QAAQ,CAAC,CAAC;eAHtCtB,MAAMa,IAAI;QAMrB,KAAK;YACH,IAAIb,MAAMuB,OAAO,CAACC,MAAM,IAAI,GAAG;gBAC7B,qBACE,KAAC5B;oBACCsB,OAAOlB,MAAMkB,KAAK;oBAElBK,SAAS,AAACvB,CAAAA,MAAMuB,OAAO,IAAI,EAAE,AAAD,EAAGE,GAAG,CAAC,CAACC,SAAiB,CAAA;4BACnDR,OAAOzB,eAAeiC,OAAOR,KAAK,EAAEd;4BACpCF,OAAOwB,OAAOxB,KAAK;wBACrB,CAAA;oBACAiB,UAAUL;oBACVZ,OAAOC;oBACPiB,QAAQV;oBACRW,WAAW,CAAC,IAAI,EAAErB,MAAMsB,KAAK,IAAI,QAAQ,CAAC,CAAC;mBARtCtB,MAAMa,IAAI;YAWrB;YACA,qBACE,KAAChB;gBACCqB,OAAOlB,MAAMkB,KAAK;gBAElBK,SAAS,AAACvB,CAAAA,MAAMuB,OAAO,IAAI,EAAE,AAAD,EAAGE,GAAG,CAAC,CAACC,SAAiB,CAAA;wBACnDR,OAAOzB,eAAeiC,OAAOR,KAAK,EAAEd;wBACpCF,OAAOwB,OAAOxB,KAAK;oBACrB,CAAA;gBACAiB,UAAUL;gBACVZ,OAAOC;gBACPiB,QAAQV;gBACRW,WAAW,CAAC,IAAI,EAAErB,MAAMsB,KAAK,IAAI,QAAQ,CAAC,CAAC;eARtCtB,MAAMa,IAAI;QAWrB,KAAK;YACH,qBACE,KAACf;gBACCoB,OAAOlB,MAAMkB,KAAK;gBAElBC,UAAUJ;gBACVb,OAAOC;gBACPwB,eAAe;gBACfP,QAAQV;gBACRW,WAAW,CAAC,IAAI,EAAErB,MAAMsB,KAAK,IAAI,QAAQ,CAAC,CAAC;eALtCtB,MAAMa,IAAI;QAQrB;YACE,OAAO;IACX;AACF;AAEA,eAAed,YAAY"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuickFilter.d.ts","sourceRoot":"","sources":["../src/QuickFilter.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"QuickFilter.d.ts","sourceRoot":"","sources":["../src/QuickFilter.tsx"],"names":[],"mappings":"AAiIA,QAAA,MAAM,WAAW,0BAGd;IACD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,CAAC,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,EAAE,CAAC;CAC5D,gCA0PA,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
package/dist/QuickFilter.js
CHANGED
|
@@ -7,6 +7,7 @@ import FilterField from './FilterField';
|
|
|
7
7
|
import { groupFiltersByRow, parseColumns } from './filters/utils/layout-helpers';
|
|
8
8
|
import { ChevronDown, ChevronUp, Filter, X } from 'lucide-react';
|
|
9
9
|
import { futureDateFilterOptions, pastDateFilterOptions } from './filters/constants/date-filter-options';
|
|
10
|
+
import { getDateRangeForOption } from './filters/utils/date-helpers';
|
|
10
11
|
import { Button } from './ui/button';
|
|
11
12
|
// Recursive function to find fields by name
|
|
12
13
|
function findFieldsByName(fields, fieldNames) {
|
|
@@ -36,7 +37,7 @@ function findFieldsByName(fields, fieldNames) {
|
|
|
36
37
|
return results;
|
|
37
38
|
}
|
|
38
39
|
// Helper function to convert UI state to a where query
|
|
39
|
-
const buildWhereClause = (values, fieldDefs)=>{
|
|
40
|
+
const buildWhereClause = (values, fieldDefs, isHebrew)=>{
|
|
40
41
|
const where = {};
|
|
41
42
|
Object.entries(values).forEach(([fieldName, value])=>{
|
|
42
43
|
if (!value) return;
|
|
@@ -46,8 +47,23 @@ const buildWhereClause = (values, fieldDefs)=>{
|
|
|
46
47
|
case 'date':
|
|
47
48
|
{
|
|
48
49
|
const dateValue = value;
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
let from;
|
|
51
|
+
let to;
|
|
52
|
+
if (dateValue.predefinedValue) {
|
|
53
|
+
const locale = isHebrew ? 'he' : 'en';
|
|
54
|
+
const range = getDateRangeForOption(dateValue.predefinedValue, locale);
|
|
55
|
+
from = range.from;
|
|
56
|
+
to = range.to;
|
|
57
|
+
} else if (dateValue.customRange) {
|
|
58
|
+
if (dateValue.customRange.from) {
|
|
59
|
+
from = new Date(dateValue.customRange.from);
|
|
60
|
+
}
|
|
61
|
+
if (dateValue.customRange.to) {
|
|
62
|
+
to = new Date(dateValue.customRange.to);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Construct the query
|
|
66
|
+
if (from || to) {
|
|
51
67
|
const dateQuery = {};
|
|
52
68
|
if (from) dateQuery.greater_than_equal = from;
|
|
53
69
|
if (to) dateQuery.less_than_equal = to;
|
|
@@ -102,11 +118,22 @@ const QuickFilter = ({ slug, filterList })=>{
|
|
|
102
118
|
const { getEntityConfig } = useConfig();
|
|
103
119
|
const { i18n } = useTranslation();
|
|
104
120
|
const [filterValues, setFilterValues] = useState(()=>{
|
|
121
|
+
if (typeof window == 'undefined') return {};
|
|
105
122
|
try {
|
|
106
123
|
const item = window.localStorage.getItem(localStorageKey);
|
|
107
|
-
|
|
124
|
+
if (!item) {
|
|
125
|
+
return {};
|
|
126
|
+
}
|
|
127
|
+
const dateTimeReviver = (key, value)=>{
|
|
128
|
+
const isoDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$/;
|
|
129
|
+
if (typeof value === 'string' && isoDateRegex.test(value)) {
|
|
130
|
+
return new Date(value);
|
|
131
|
+
}
|
|
132
|
+
return value;
|
|
133
|
+
};
|
|
134
|
+
return JSON.parse(item, dateTimeReviver);
|
|
108
135
|
} catch (error) {
|
|
109
|
-
console.error('Error reading filters from localStorage.', error);
|
|
136
|
+
console.error('Error reading and parsing filters from localStorage.', error);
|
|
110
137
|
return {};
|
|
111
138
|
}
|
|
112
139
|
});
|
|
@@ -148,16 +175,16 @@ const QuickFilter = ({ slug, filterList })=>{
|
|
|
148
175
|
i18n
|
|
149
176
|
]);
|
|
150
177
|
useEffect(()=>{
|
|
151
|
-
// Wait until field metadata has been loaded.
|
|
152
178
|
if (fields.length === 0) {
|
|
153
179
|
return;
|
|
154
180
|
}
|
|
155
|
-
const where = buildWhereClause(filterValues, fields);
|
|
181
|
+
const where = buildWhereClause(filterValues, fields, isHebrew);
|
|
156
182
|
try {
|
|
157
183
|
if (Object.keys(filterValues).length > 0) {
|
|
158
184
|
localStorage.setItem(localStorageKey, JSON.stringify(filterValues));
|
|
159
185
|
} else {
|
|
160
186
|
localStorage.removeItem(localStorageKey);
|
|
187
|
+
return;
|
|
161
188
|
}
|
|
162
189
|
} catch (error) {
|
|
163
190
|
console.error('Failed to save filters to localStorage', error);
|
|
@@ -169,11 +196,10 @@ const QuickFilter = ({ slug, filterList })=>{
|
|
|
169
196
|
page: '1'
|
|
170
197
|
});
|
|
171
198
|
}
|
|
199
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
172
200
|
}, [
|
|
173
201
|
filterValues,
|
|
174
202
|
fields,
|
|
175
|
-
query,
|
|
176
|
-
refineListData,
|
|
177
203
|
localStorageKey
|
|
178
204
|
]);
|
|
179
205
|
const handleFilterChange = useCallback((fieldName, value)=>{
|
|
@@ -241,6 +267,11 @@ const QuickFilter = ({ slug, filterList })=>{
|
|
|
241
267
|
return activeFilters;
|
|
242
268
|
};
|
|
243
269
|
const clearAllFilters = ()=>{
|
|
270
|
+
refineListData({
|
|
271
|
+
columns: parseColumns(query.columns),
|
|
272
|
+
where: {},
|
|
273
|
+
page: '1'
|
|
274
|
+
});
|
|
244
275
|
setFilterValues({});
|
|
245
276
|
};
|
|
246
277
|
const memoizedFilterRows = useMemo(()=>{
|
|
@@ -320,7 +351,7 @@ const QuickFilter = ({ slug, filterList })=>{
|
|
|
320
351
|
})
|
|
321
352
|
}),
|
|
322
353
|
showFilters && /*#__PURE__*/ _jsx("div", {
|
|
323
|
-
className: 'p-4 pb-2 bg-muted
|
|
354
|
+
className: 'p-4 pb-2 bg-muted',
|
|
324
355
|
children: memoizedFilterRows
|
|
325
356
|
})
|
|
326
357
|
]
|
package/dist/QuickFilter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/QuickFilter.tsx"],"sourcesContent":["'use client';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useConfig, useListQuery, useTranslation } from '@payloadcms/ui';\nimport type { ClientField, FieldAffectingData, OptionObject, SelectField } from 'payload';\nimport { getTranslation } from '@payloadcms/translations';\nimport FilterField from './FilterField';\nimport type {\n CheckboxFilterState,\n DateFilterValue,\n FilterDetaild,\n FilterRow,\n SelectFilterValue,\n} from './filters/types/filters-type';\nimport { groupFiltersByRow, parseColumns } from './filters/utils/layout-helpers';\nimport { ChevronDown, ChevronUp, Filter, X } from 'lucide-react';\n\nimport {\n futureDateFilterOptions,\n pastDateFilterOptions,\n} from './filters/constants/date-filter-options';\nimport { Button } from './ui/button';\n\n// Recursive function to find fields by name\nfunction findFieldsByName(fields: ClientField[], fieldNames: string[]): ClientField[] {\n const results: ClientField[] = [];\n function recursiveSearch(currentFields: ClientField[]) {\n const filteredFields = currentFields.filter(\n (field) => 'name' in field && fieldNames.includes(field.name as string),\n );\n results.push(...filteredFields);\n currentFields.forEach((item) => {\n if (\n (item.type === 'array' || item.type === 'row' || item.type === 'collapsible') &&\n 'fields' in item &&\n Array.isArray(item.fields)\n ) {\n recursiveSearch(item.fields);\n } else if (item.type === 'tabs' && Array.isArray(item.tabs)) {\n item.tabs.forEach((tab) => {\n if ('fields' in tab && Array.isArray(tab.fields)) {\n recursiveSearch(tab.fields);\n }\n });\n } else if (item.type === 'blocks' && Array.isArray(item.blocks)) {\n item.blocks.forEach((block) => {\n if ('fields' in block && Array.isArray(block.fields)) {\n recursiveSearch(block.fields);\n }\n });\n }\n });\n }\n recursiveSearch(fields);\n return results;\n}\n\n// Helper function to convert UI state to a where query\nconst buildWhereClause = (\n values: Record<string, any>,\n fieldDefs: FilterDetaild[],\n): Record<string, any> => {\n const where: Record<string, any> = {};\n Object.entries(values).forEach(([fieldName, value]) => {\n if (!value) return;\n const fieldDef = fieldDefs.find((f) => f.name === fieldName);\n if (!fieldDef) return;\n switch (fieldDef.type) {\n case 'date': {\n const dateValue = value as DateFilterValue;\n if (dateValue.customRange) {\n const { from, to } = dateValue.customRange;\n const dateQuery: any = {};\n if (from) dateQuery.greater_than_equal = from;\n if (to) dateQuery.less_than_equal = to;\n if (Object.keys(dateQuery).length > 0) {\n where[fieldName] = dateQuery;\n }\n }\n break;\n }\n case 'select': {\n const selectValue = value as SelectFilterValue;\n if (selectValue.selectedValues && selectValue.selectedValues.length > 0) {\n if (selectValue.selectedValues.length === 1) {\n where[fieldName] = { equals: selectValue.selectedValues[0] };\n } else {\n where[fieldName] = { in: selectValue.selectedValues };\n }\n }\n break;\n }\n case 'checkbox': {\n const checkboxState = value as CheckboxFilterState;\n if (checkboxState === 'checked') {\n where[fieldName] = { equals: true };\n } else if (checkboxState === 'unchecked') {\n where[fieldName] = { equals: false };\n }\n // 'indeterminate' will not filter\n break;\n }\n }\n });\n return where;\n};\n\nconst QuickFilter = ({\n slug,\n filterList,\n}: {\n slug: string;\n filterList: (string | { name: string; width: string })[][];\n}) => {\n const localStorageKey = useMemo(() => `direct-filter-${slug}`, [slug]);\n\n const [fields, setFields] = useState<FilterDetaild[]>([]);\n const [filterRows, setFilterRows] = useState<FilterRow[]>([]);\n const [showFilters, setShowFilters] = useState(false);\n const { refineListData, query } = useListQuery();\n const { getEntityConfig } = useConfig();\n const { i18n } = useTranslation();\n\n const [filterValues, setFilterValues] = useState<Record<string, any>>(() => {\n try {\n const item = window.localStorage.getItem(localStorageKey);\n return item ? JSON.parse(item) : {};\n } catch (error) {\n console.error('Error reading filters from localStorage.', error);\n return {};\n }\n });\n\n useEffect(() => {\n const collection = getEntityConfig({ collectionSlug: slug });\n const flattenedFieldConfigs = filterList.flatMap((row, rowIndex) =>\n row.map((field, fieldIndex) => ({\n field,\n rowIndex,\n fieldIndex,\n })),\n );\n const fieldNames = flattenedFieldConfigs.map(({ field }) =>\n typeof field === 'string' ? field : field.name,\n );\n const matchedFields = findFieldsByName(collection?.fields || [], fieldNames);\n const simplifiedFields: FilterDetaild[] = matchedFields.map((field) => {\n const label = (field as FieldAffectingData).label;\n const translatedLabel = getTranslation(label as string, i18n);\n const fieldName = (field as FieldAffectingData).name as string;\n const fieldConfig = flattenedFieldConfigs.find(({ field: f }) =>\n typeof f === 'string' ? f === fieldName : f.name === fieldName,\n );\n return {\n name: fieldName,\n label: translatedLabel as string,\n type: field.type,\n options: (field as SelectField).options as OptionObject[],\n row: fieldConfig ? fieldConfig.rowIndex : 0,\n width:\n typeof fieldConfig?.field === 'object' && 'width' in fieldConfig.field\n ? fieldConfig.field.width\n : undefined,\n };\n });\n const sortedFields = flattenedFieldConfigs\n .map(({ field }) => {\n const fieldName = typeof field === 'string' ? field : field.name;\n return simplifiedFields.find((f) => f.name === fieldName);\n })\n .filter((f): f is FilterDetaild => !!f);\n setFields(sortedFields);\n setFilterRows(groupFiltersByRow(sortedFields));\n }, [slug, filterList, getEntityConfig, i18n]);\n\n useEffect(() => {\n // Wait until field metadata has been loaded.\n if (fields.length === 0) {\n return;\n }\n\n const where = buildWhereClause(filterValues, fields);\n\n try {\n if (Object.keys(filterValues).length > 0) {\n localStorage.setItem(localStorageKey, JSON.stringify(filterValues));\n } else {\n localStorage.removeItem(localStorageKey);\n }\n } catch (error) {\n console.error('Failed to save filters to localStorage', error);\n }\n\n if (JSON.stringify(where) !== JSON.stringify(query.where)) {\n refineListData({\n columns: parseColumns(query.columns),\n where,\n page: '1',\n });\n }\n }, [filterValues, fields, query, refineListData, localStorageKey]);\n\n const handleFilterChange = useCallback((fieldName: string, value: any) => {\n setFilterValues((prev) => {\n const newValues = { ...prev };\n if (\n value === undefined ||\n value === null ||\n value === 'indeterminate' ||\n (value && value.type === 'none')\n ) {\n delete newValues[fieldName];\n } else {\n newValues[fieldName] = value;\n }\n return newValues;\n });\n }, []);\n\n // This function remains largely the same.\n const getActiveFiltersDetails = () => {\n const activeFilters: string[] = [];\n const isHebrew = i18n.language === 'he';\n\n Object.entries(filterValues).forEach(([fieldName, value]) => {\n const field = fields.find((f) => f.name === fieldName);\n if (!field) return;\n\n switch (field.type) {\n case 'date':\n if (value !== undefined) {\n const dateValue = value as DateFilterValue;\n let dateDescription = '';\n\n if (dateValue.type === 'predefined' && dateValue.predefinedValue) {\n const allOptions = [...pastDateFilterOptions, ...futureDateFilterOptions];\n const option = allOptions.find((opt) => opt.value === dateValue.predefinedValue);\n dateDescription = option ? option.label : isHebrew ? 'מותאם אישית' : 'Custom';\n } else if (dateValue.type === 'custom' || dateValue.customRange) {\n dateDescription = isHebrew ? 'מותאם אישית' : 'Custom';\n }\n\n if (dateDescription) {\n activeFilters.push(`${field.label} (${dateDescription})`);\n }\n }\n break;\n case 'select': {\n const selectValue = value as SelectFilterValue;\n if (selectValue && selectValue.selectedValues && selectValue.selectedValues.length > 0) {\n const count = selectValue.selectedValues.length;\n const totalOptions = field.options?.length || 0;\n if (selectValue.selectedValues.length === totalOptions) {\n activeFilters.push(`${field.label} (${isHebrew ? 'הכל' : 'All'})`);\n } else {\n activeFilters.push(`${field.label} (${count})`);\n }\n }\n break;\n }\n case 'checkbox':\n if (value !== 'indeterminate') {\n const checkboxValue =\n value === 'checked' ? (isHebrew ? 'כן' : 'Yes') : isHebrew ? 'לא' : 'No';\n activeFilters.push(`${field.label} (${checkboxValue})`);\n }\n break;\n }\n });\n\n return activeFilters;\n };\n\n const clearAllFilters = () => {\n setFilterValues({});\n };\n\n const memoizedFilterRows = useMemo(() => {\n return filterRows.map((row) => (\n <div key={row.rowNumber}>\n <div className='flex flex-wrap gap-6 mb-4'>\n {row.filters.map((field) => (\n <FilterField\n key={field.name}\n field={field}\n onFilterChange={handleFilterChange}\n value={filterValues[field.name]}\n />\n ))}\n </div>\n </div>\n ));\n }, [filterRows, handleFilterChange, filterValues]);\n\n const toggleFilters = () => {\n setShowFilters((prev) => !prev);\n };\n\n const activeFiltersDetails = getActiveFiltersDetails();\n const hasActiveFilters = activeFiltersDetails.length > 0;\n const isHebrew = i18n.language === 'he';\n\n if (!fields.length) return null;\n\n return (\n <div className='filter-container useTw'>\n <div style={{ position: 'relative', top: '-24px', height: '0px' }}>\n <Button\n variant='outline'\n size='sm'\n onClick={toggleFilters}\n className={`flex items-center gap-2 bg-background border-muted-muted hover:bg-muted ${\n hasActiveFilters ? 'w-auto min-w-fit' : ''\n }`}\n >\n <Filter className={`h-4 w-4 ${hasActiveFilters ? 'fill-current' : ''}`} />\n\n {hasActiveFilters ? (\n <>\n <span className='text-sm truncate'>\n <strong>\n {isHebrew\n ? `${activeFiltersDetails.length === 1 ? 'סינון פעיל בעמודה' : 'סינון פעיל בעמודות'}: `\n : `${activeFiltersDetails.length === 1 ? 'Active filter on column' : 'Active filters on columns'}: `}\n </strong>{' '}\n {activeFiltersDetails.join(' • ')}\n </span>\n\n <span\n onClick={(e) => {\n e.stopPropagation();\n clearAllFilters();\n }}\n className='ml-1 p-0.5 hover:bg-muted rounded-sm transition-colors flex-shrink-0'\n >\n <X className='h-3 w-3 text-gray-500' />\n </span>\n </>\n ) : (\n <span className='text-sm truncate'>{isHebrew ? 'סינון מהיר' : 'Quick Filters'}</span>\n )}\n\n {showFilters ? <ChevronUp className='h-4 w-4' /> : <ChevronDown className='h-4 w-4' />}\n </Button>\n </div>\n {showFilters && <div className={'p-4 pb-2 bg-muted/70'}>{memoizedFilterRows}</div>}\n </div>\n );\n};\n\nexport default QuickFilter;\n"],"names":["useCallback","useEffect","useMemo","useState","useConfig","useListQuery","useTranslation","getTranslation","FilterField","groupFiltersByRow","parseColumns","ChevronDown","ChevronUp","Filter","X","futureDateFilterOptions","pastDateFilterOptions","Button","findFieldsByName","fields","fieldNames","results","recursiveSearch","currentFields","filteredFields","filter","field","includes","name","push","forEach","item","type","Array","isArray","tabs","tab","blocks","block","buildWhereClause","values","fieldDefs","where","Object","entries","fieldName","value","fieldDef","find","f","dateValue","customRange","from","to","dateQuery","greater_than_equal","less_than_equal","keys","length","selectValue","selectedValues","equals","in","checkboxState","QuickFilter","slug","filterList","localStorageKey","setFields","filterRows","setFilterRows","showFilters","setShowFilters","refineListData","query","getEntityConfig","i18n","filterValues","setFilterValues","window","localStorage","getItem","JSON","parse","error","console","collection","collectionSlug","flattenedFieldConfigs","flatMap","row","rowIndex","map","fieldIndex","matchedFields","simplifiedFields","label","translatedLabel","fieldConfig","options","width","undefined","sortedFields","setItem","stringify","removeItem","columns","page","handleFilterChange","prev","newValues","getActiveFiltersDetails","activeFilters","isHebrew","language","dateDescription","predefinedValue","allOptions","option","opt","count","totalOptions","checkboxValue","clearAllFilters","memoizedFilterRows","div","className","filters","onFilterChange","rowNumber","toggleFilters","activeFiltersDetails","hasActiveFilters","style","position","top","height","variant","size","onClick","span","strong","join","e","stopPropagation"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/QuickFilter.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { useConfig, useListQuery, useTranslation } from '@payloadcms/ui';\nimport type { ClientField, FieldAffectingData, OptionObject, SelectField } from 'payload';\nimport { getTranslation } from '@payloadcms/translations';\nimport FilterField from './FilterField';\nimport type {\n CheckboxFilterState,\n DateFilterValue,\n FilterDetaild,\n FilterRow,\n SelectFilterValue,\n} from './filters/types/filters-type';\nimport { groupFiltersByRow, parseColumns } from './filters/utils/layout-helpers';\nimport { ChevronDown, ChevronUp, Filter, X } from 'lucide-react';\n\nimport {\n futureDateFilterOptions,\n pastDateFilterOptions,\n} from './filters/constants/date-filter-options';\nimport { getDateRangeForOption } from './filters/utils/date-helpers';\nimport { Button } from './ui/button';\n\n// Recursive function to find fields by name\nfunction findFieldsByName(fields: ClientField[], fieldNames: string[]): ClientField[] {\n const results: ClientField[] = [];\n function recursiveSearch(currentFields: ClientField[]) {\n const filteredFields = currentFields.filter(\n (field) => 'name' in field && fieldNames.includes(field.name as string),\n );\n results.push(...filteredFields);\n currentFields.forEach((item) => {\n if (\n (item.type === 'array' || item.type === 'row' || item.type === 'collapsible') &&\n 'fields' in item &&\n Array.isArray(item.fields)\n ) {\n recursiveSearch(item.fields);\n } else if (item.type === 'tabs' && Array.isArray(item.tabs)) {\n item.tabs.forEach((tab) => {\n if ('fields' in tab && Array.isArray(tab.fields)) {\n recursiveSearch(tab.fields);\n }\n });\n } else if (item.type === 'blocks' && Array.isArray(item.blocks)) {\n item.blocks.forEach((block) => {\n if ('fields' in block && Array.isArray(block.fields)) {\n recursiveSearch(block.fields);\n }\n });\n }\n });\n }\n recursiveSearch(fields);\n return results;\n}\n\n// Helper function to convert UI state to a where query\nconst buildWhereClause = (\n values: Record<string, any>,\n fieldDefs: FilterDetaild[],\n isHebrew: boolean,\n): Record<string, any> => {\n const where: Record<string, any> = {};\n Object.entries(values).forEach(([fieldName, value]) => {\n if (!value) return;\n const fieldDef = fieldDefs.find((f) => f.name === fieldName);\n if (!fieldDef) return;\n switch (fieldDef.type) {\n case 'date': {\n const dateValue = value as DateFilterValue;\n let from: Date | undefined;\n let to: Date | undefined;\n\n if (dateValue.predefinedValue) {\n const locale = isHebrew ? 'he' : 'en';\n const range = getDateRangeForOption(dateValue.predefinedValue, locale);\n\n from = range.from;\n to = range.to;\n }\n // Fallback for custom date ranges\n else if (dateValue.customRange) {\n if (dateValue.customRange.from) {\n from = new Date(dateValue.customRange.from);\n }\n if (dateValue.customRange.to) {\n to = new Date(dateValue.customRange.to);\n }\n }\n\n // Construct the query\n if (from || to) {\n const dateQuery: any = {};\n if (from) dateQuery.greater_than_equal = from;\n if (to) dateQuery.less_than_equal = to;\n if (Object.keys(dateQuery).length > 0) {\n where[fieldName] = dateQuery;\n }\n }\n break;\n }\n case 'select': {\n const selectValue = value as SelectFilterValue;\n if (selectValue.selectedValues && selectValue.selectedValues.length > 0) {\n if (selectValue.selectedValues.length === 1) {\n where[fieldName] = { equals: selectValue.selectedValues[0] };\n } else {\n where[fieldName] = { in: selectValue.selectedValues };\n }\n }\n break;\n }\n case 'checkbox': {\n const checkboxState = value as CheckboxFilterState;\n if (checkboxState === 'checked') {\n where[fieldName] = { equals: true };\n } else if (checkboxState === 'unchecked') {\n where[fieldName] = { equals: false };\n }\n // 'indeterminate' will not filter\n break;\n }\n }\n });\n return where;\n};\n\nconst QuickFilter = ({\n slug,\n filterList,\n}: {\n slug: string;\n filterList: (string | { name: string; width: string })[][];\n}) => {\n const localStorageKey = useMemo(() => `direct-filter-${slug}`, [slug]);\n\n const [fields, setFields] = useState<FilterDetaild[]>([]);\n const [filterRows, setFilterRows] = useState<FilterRow[]>([]);\n const [showFilters, setShowFilters] = useState(false);\n const { refineListData, query } = useListQuery();\n const { getEntityConfig } = useConfig();\n const { i18n } = useTranslation();\n\n const [filterValues, setFilterValues] = useState<Record<string, any>>(() => {\n if (typeof window == 'undefined') return {};\n try {\n const item = window.localStorage.getItem(localStorageKey);\n if (!item) {\n return {};\n }\n const dateTimeReviver = (key: string, value: any) => {\n const isoDateRegex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$/;\n if (typeof value === 'string' && isoDateRegex.test(value)) {\n return new Date(value);\n }\n return value;\n };\n return JSON.parse(item, dateTimeReviver);\n } catch (error) {\n console.error('Error reading and parsing filters from localStorage.', error);\n return {};\n }\n });\n\n useEffect(() => {\n const collection = getEntityConfig({ collectionSlug: slug });\n const flattenedFieldConfigs = filterList.flatMap((row, rowIndex) =>\n row.map((field, fieldIndex) => ({\n field,\n rowIndex,\n fieldIndex,\n })),\n );\n const fieldNames = flattenedFieldConfigs.map(({ field }) =>\n typeof field === 'string' ? field : field.name,\n );\n const matchedFields = findFieldsByName(collection?.fields || [], fieldNames);\n const simplifiedFields: FilterDetaild[] = matchedFields.map((field) => {\n const label = (field as FieldAffectingData).label;\n const translatedLabel = getTranslation(label as string, i18n);\n const fieldName = (field as FieldAffectingData).name as string;\n const fieldConfig = flattenedFieldConfigs.find(({ field: f }) =>\n typeof f === 'string' ? f === fieldName : f.name === fieldName,\n );\n return {\n name: fieldName,\n label: translatedLabel as string,\n type: field.type,\n options: (field as SelectField).options as OptionObject[],\n row: fieldConfig ? fieldConfig.rowIndex : 0,\n width:\n typeof fieldConfig?.field === 'object' && 'width' in fieldConfig.field\n ? fieldConfig.field.width\n : undefined,\n };\n });\n const sortedFields = flattenedFieldConfigs\n .map(({ field }) => {\n const fieldName = typeof field === 'string' ? field : field.name;\n return simplifiedFields.find((f) => f.name === fieldName);\n })\n .filter((f): f is FilterDetaild => !!f);\n setFields(sortedFields);\n setFilterRows(groupFiltersByRow(sortedFields));\n }, [slug, filterList, getEntityConfig, i18n]);\n\n useEffect(() => {\n if (fields.length === 0) {\n return;\n }\n const where = buildWhereClause(filterValues, fields, isHebrew);\n try {\n if (Object.keys(filterValues).length > 0) {\n localStorage.setItem(localStorageKey, JSON.stringify(filterValues));\n } else {\n localStorage.removeItem(localStorageKey);\n return;\n }\n } catch (error) {\n console.error('Failed to save filters to localStorage', error);\n }\n\n if (JSON.stringify(where) !== JSON.stringify(query.where)) {\n refineListData({\n columns: parseColumns(query.columns),\n where,\n page: '1',\n });\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [filterValues, fields, localStorageKey]);\n\n const handleFilterChange = useCallback((fieldName: string, value: any) => {\n setFilterValues((prev) => {\n const newValues = { ...prev };\n if (\n value === undefined ||\n value === null ||\n value === 'indeterminate' ||\n (value && value.type === 'none')\n ) {\n delete newValues[fieldName];\n } else {\n newValues[fieldName] = value;\n }\n return newValues;\n });\n }, []);\n\n // This function remains largely the same.\n const getActiveFiltersDetails = () => {\n const activeFilters: string[] = [];\n const isHebrew = i18n.language === 'he';\n\n Object.entries(filterValues).forEach(([fieldName, value]) => {\n const field = fields.find((f) => f.name === fieldName);\n if (!field) return;\n\n switch (field.type) {\n case 'date':\n if (value !== undefined) {\n const dateValue = value as DateFilterValue;\n let dateDescription = '';\n\n if (dateValue.type === 'predefined' && dateValue.predefinedValue) {\n const allOptions = [...pastDateFilterOptions, ...futureDateFilterOptions];\n const option = allOptions.find((opt) => opt.value === dateValue.predefinedValue);\n dateDescription = option ? option.label : isHebrew ? 'מותאם אישית' : 'Custom';\n } else if (dateValue.type === 'custom' || dateValue.customRange) {\n dateDescription = isHebrew ? 'מותאם אישית' : 'Custom';\n }\n\n if (dateDescription) {\n activeFilters.push(`${field.label} (${dateDescription})`);\n }\n }\n break;\n case 'select': {\n const selectValue = value as SelectFilterValue;\n if (selectValue && selectValue.selectedValues && selectValue.selectedValues.length > 0) {\n const count = selectValue.selectedValues.length;\n const totalOptions = field.options?.length || 0;\n if (selectValue.selectedValues.length === totalOptions) {\n activeFilters.push(`${field.label} (${isHebrew ? 'הכל' : 'All'})`);\n } else {\n activeFilters.push(`${field.label} (${count})`);\n }\n }\n break;\n }\n case 'checkbox':\n if (value !== 'indeterminate') {\n const checkboxValue =\n value === 'checked' ? (isHebrew ? 'כן' : 'Yes') : isHebrew ? 'לא' : 'No';\n activeFilters.push(`${field.label} (${checkboxValue})`);\n }\n break;\n }\n });\n\n return activeFilters;\n };\n\n const clearAllFilters = () => {\n refineListData({\n columns: parseColumns(query.columns),\n where: {},\n page: '1',\n });\n setFilterValues({});\n };\n\n const memoizedFilterRows = useMemo(() => {\n return filterRows.map((row) => (\n <div key={row.rowNumber}>\n <div className='flex flex-wrap gap-6 mb-4'>\n {row.filters.map((field) => (\n <FilterField\n key={field.name}\n field={field}\n onFilterChange={handleFilterChange}\n value={filterValues[field.name]}\n />\n ))}\n </div>\n </div>\n ));\n }, [filterRows, handleFilterChange, filterValues]);\n\n const toggleFilters = () => {\n setShowFilters((prev) => !prev);\n };\n\n const activeFiltersDetails = getActiveFiltersDetails();\n const hasActiveFilters = activeFiltersDetails.length > 0;\n const isHebrew = i18n.language === 'he';\n\n if (!fields.length) return null;\n\n return (\n <div className='filter-container useTw'>\n <div style={{ position: 'relative', top: '-24px', height: '0px' }}>\n <Button\n variant='outline'\n size='sm'\n onClick={toggleFilters}\n className={`flex items-center gap-2 bg-background border-muted-muted hover:bg-muted ${\n hasActiveFilters ? 'w-auto min-w-fit' : ''\n }`}\n >\n <Filter className={`h-4 w-4 ${hasActiveFilters ? 'fill-current' : ''}`} />\n\n {hasActiveFilters ? (\n <>\n <span className='text-sm truncate'>\n <strong>\n {isHebrew\n ? `${activeFiltersDetails.length === 1 ? 'סינון פעיל בעמודה' : 'סינון פעיל בעמודות'}: `\n : `${activeFiltersDetails.length === 1 ? 'Active filter on column' : 'Active filters on columns'}: `}\n </strong>{' '}\n {activeFiltersDetails.join(' • ')}\n </span>\n\n <span\n onClick={(e) => {\n e.stopPropagation();\n clearAllFilters();\n }}\n className='ml-1 p-0.5 hover:bg-muted rounded-sm transition-colors flex-shrink-0'\n >\n <X className='h-3 w-3 text-gray-500' />\n </span>\n </>\n ) : (\n <span className='text-sm truncate'>{isHebrew ? 'סינון מהיר' : 'Quick Filters'}</span>\n )}\n\n {showFilters ? <ChevronUp className='h-4 w-4' /> : <ChevronDown className='h-4 w-4' />}\n </Button>\n </div>\n {showFilters && <div className={'p-4 pb-2 bg-muted'}>{memoizedFilterRows}</div>}\n </div>\n );\n};\n\nexport default QuickFilter;\n"],"names":["useCallback","useEffect","useMemo","useState","useConfig","useListQuery","useTranslation","getTranslation","FilterField","groupFiltersByRow","parseColumns","ChevronDown","ChevronUp","Filter","X","futureDateFilterOptions","pastDateFilterOptions","getDateRangeForOption","Button","findFieldsByName","fields","fieldNames","results","recursiveSearch","currentFields","filteredFields","filter","field","includes","name","push","forEach","item","type","Array","isArray","tabs","tab","blocks","block","buildWhereClause","values","fieldDefs","isHebrew","where","Object","entries","fieldName","value","fieldDef","find","f","dateValue","from","to","predefinedValue","locale","range","customRange","Date","dateQuery","greater_than_equal","less_than_equal","keys","length","selectValue","selectedValues","equals","in","checkboxState","QuickFilter","slug","filterList","localStorageKey","setFields","filterRows","setFilterRows","showFilters","setShowFilters","refineListData","query","getEntityConfig","i18n","filterValues","setFilterValues","window","localStorage","getItem","dateTimeReviver","key","isoDateRegex","test","JSON","parse","error","console","collection","collectionSlug","flattenedFieldConfigs","flatMap","row","rowIndex","map","fieldIndex","matchedFields","simplifiedFields","label","translatedLabel","fieldConfig","options","width","undefined","sortedFields","setItem","stringify","removeItem","columns","page","handleFilterChange","prev","newValues","getActiveFiltersDetails","activeFilters","language","dateDescription","allOptions","option","opt","count","totalOptions","checkboxValue","clearAllFilters","memoizedFilterRows","div","className","filters","onFilterChange","rowNumber","toggleFilters","activeFiltersDetails","hasActiveFilters","style","position","top","height","variant","size","onClick","span","strong","join","e","stopPropagation"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkbox-filter.d.ts","sourceRoot":"","sources":["../../../src/filters/components/checkbox-filter.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAKpE,UAAU,mBAAmB;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,aAAa,EACb,KAAuB,EACvB,QAAQ,EACR,MAAyC,EACzC,SAAS,GACV,EAAE,mBAAmB,+
|
|
1
|
+
{"version":3,"file":"checkbox-filter.d.ts","sourceRoot":"","sources":["../../../src/filters/components/checkbox-filter.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAKpE,UAAU,mBAAmB;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,aAAa,EACb,KAAuB,EACvB,QAAQ,EACR,MAAyC,EACzC,SAAS,GACV,EAAE,mBAAmB,+BA0HrB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
4
|
import { X } from 'lucide-react';
|
|
5
5
|
import { Label } from '../../ui/label';
|
|
@@ -27,11 +27,11 @@ export function CheckboxFilter({ label, checkboxLabel, value = 'indeterminate',
|
|
|
27
27
|
};
|
|
28
28
|
const isActive = internalState === 'checked' || internalState === 'unchecked';
|
|
29
29
|
const labels_toggle = {
|
|
30
|
-
yes: isHebrew ? 'כן' : '
|
|
31
|
-
no: isHebrew ? 'לא' : '
|
|
30
|
+
yes: isHebrew ? 'כן' : 'Yes',
|
|
31
|
+
no: isHebrew ? 'לא' : 'No'
|
|
32
32
|
};
|
|
33
33
|
return /*#__PURE__*/ _jsxs("div", {
|
|
34
|
-
className: cn('
|
|
34
|
+
className: cn('space-y-1', className),
|
|
35
35
|
dir: locale.direction,
|
|
36
36
|
children: [
|
|
37
37
|
label && /*#__PURE__*/ _jsx(Label, {
|
|
@@ -43,47 +43,44 @@ export function CheckboxFilter({ label, checkboxLabel, value = 'indeterminate',
|
|
|
43
43
|
children: [
|
|
44
44
|
/*#__PURE__*/ _jsx("div", {
|
|
45
45
|
className: cn('flex items-center', locale.direction === 'rtl' && 'order-first'),
|
|
46
|
-
children: /*#__PURE__*/
|
|
46
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
47
47
|
className: "flex rounded-md border overflow-hidden",
|
|
48
|
-
children:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
})
|
|
85
|
-
]
|
|
86
|
-
})
|
|
48
|
+
children: [
|
|
49
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
50
|
+
variant: internalState === 'checked' ? 'default' : 'ghost',
|
|
51
|
+
size: "sm",
|
|
52
|
+
className: cn('useTW px-3 py-1 text-xs rounded-none border-0'),
|
|
53
|
+
style: {
|
|
54
|
+
backgroundColor: internalState === 'checked' ? '#16a34a' : 'var(--background)',
|
|
55
|
+
color: internalState === 'checked' ? '#ffffff' : 'var(--muted-foreground)'
|
|
56
|
+
},
|
|
57
|
+
onClick: ()=>handleToggle('checked'),
|
|
58
|
+
onMouseEnter: (e)=>{
|
|
59
|
+
if (internalState !== 'checked') e.currentTarget.style.backgroundColor = 'var(--muted)';
|
|
60
|
+
},
|
|
61
|
+
onMouseLeave: (e)=>{
|
|
62
|
+
if (internalState !== 'checked') e.currentTarget.style.backgroundColor = 'var(--background)';
|
|
63
|
+
},
|
|
64
|
+
children: labels_toggle.yes
|
|
65
|
+
}),
|
|
66
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
67
|
+
variant: internalState === 'unchecked' ? 'default' : 'ghost',
|
|
68
|
+
size: "sm",
|
|
69
|
+
className: cn('useTw px-3 py-1 text-xs rounded-none border-0 border-l'),
|
|
70
|
+
style: {
|
|
71
|
+
backgroundColor: internalState === 'unchecked' ? '#dc2626' : 'var(--background)',
|
|
72
|
+
color: internalState === 'unchecked' ? '#ffffff' : 'var(--muted-foreground)'
|
|
73
|
+
},
|
|
74
|
+
onClick: ()=>handleToggle('unchecked'),
|
|
75
|
+
onMouseEnter: (e)=>{
|
|
76
|
+
if (internalState !== 'unchecked') e.currentTarget.style.backgroundColor = 'var(--muted)';
|
|
77
|
+
},
|
|
78
|
+
onMouseLeave: (e)=>{
|
|
79
|
+
if (internalState !== 'unchecked') e.currentTarget.style.backgroundColor = 'var(--background)';
|
|
80
|
+
},
|
|
81
|
+
children: labels_toggle.no
|
|
82
|
+
})
|
|
83
|
+
]
|
|
87
84
|
})
|
|
88
85
|
}),
|
|
89
86
|
checkboxLabel && /*#__PURE__*/ _jsx(Label, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/filters/components/checkbox-filter.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\n\nimport { X } from 'lucide-react';\nimport { CheckboxFilterState, Locale } from '../types/filters-type';\nimport { Label } from '../../ui/label';\nimport { cn } from '../../lib/utils';\nimport { Button } from '../../ui/button';\n\ninterface CheckboxFilterProps {\n label?: string;\n checkboxLabel: string;\n value?: CheckboxFilterState;\n onChange: (state: CheckboxFilterState) => void;\n locale?: Locale;\n className?: string;\n}\n\nexport function CheckboxFilter({\n label,\n checkboxLabel,\n value = 'indeterminate',\n onChange,\n locale = { code: 'he', direction: 'rtl' },\n className,\n}: CheckboxFilterProps) {\n const [internalState, setInternalState] = useState<CheckboxFilterState>(value);\n\n const isHebrew = locale.code === 'he';\n\n // Sync internal state with external value prop\n useEffect(() => {\n setInternalState(value);\n }, [value]);\n\n const handleToggle = (newState: 'checked' | 'unchecked') => {\n setInternalState(newState);\n onChange(newState);\n };\n\n const handleClear = () => {\n setInternalState('indeterminate');\n onChange('indeterminate');\n };\n\n const isActive = internalState === 'checked' || internalState === 'unchecked';\n\n const labels_toggle = {\n yes: isHebrew ? 'כן' : '
|
|
1
|
+
{"version":3,"sources":["../../../src/filters/components/checkbox-filter.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\n\nimport { X } from 'lucide-react';\nimport { CheckboxFilterState, Locale } from '../types/filters-type';\nimport { Label } from '../../ui/label';\nimport { cn } from '../../lib/utils';\nimport { Button } from '../../ui/button';\n\ninterface CheckboxFilterProps {\n label?: string;\n checkboxLabel: string;\n value?: CheckboxFilterState;\n onChange: (state: CheckboxFilterState) => void;\n locale?: Locale;\n className?: string;\n}\n\nexport function CheckboxFilter({\n label,\n checkboxLabel,\n value = 'indeterminate',\n onChange,\n locale = { code: 'he', direction: 'rtl' },\n className,\n}: CheckboxFilterProps) {\n const [internalState, setInternalState] = useState<CheckboxFilterState>(value);\n\n const isHebrew = locale.code === 'he';\n\n // Sync internal state with external value prop\n useEffect(() => {\n setInternalState(value);\n }, [value]);\n\n const handleToggle = (newState: 'checked' | 'unchecked') => {\n setInternalState(newState);\n onChange(newState);\n };\n\n const handleClear = () => {\n setInternalState('indeterminate');\n onChange('indeterminate');\n };\n\n const isActive = internalState === 'checked' || internalState === 'unchecked';\n\n const labels_toggle = {\n yes: isHebrew ? 'כן' : 'Yes',\n no: isHebrew ? 'לא' : 'No',\n };\n\n return (\n <div className={cn('space-y-1', className)} dir={locale.direction}>\n {label && (\n <Label className={cn('useTw text-sm font-medium', isHebrew && 'text-right block')}>\n {label}\n </Label>\n )}\n\n <div\n className={cn(\n 'flex items-center gap-3 transition-colors py-px',\n locale.direction === 'rtl' && 'justify-start',\n )}\n >\n <div className={cn('flex items-center', locale.direction === 'rtl' && 'order-first')}>\n {/* Two Button Toggle */}\n <div className='flex rounded-md border overflow-hidden'>\n {/* In RTL, YES comes first, in LTR, NO comes first */}\n <Button\n variant={internalState === 'checked' ? 'default' : 'ghost'}\n size='sm'\n className={cn('useTW px-3 py-1 text-xs rounded-none border-0')}\n style={{\n backgroundColor: internalState === 'checked' ? '#16a34a' : 'var(--background)',\n color: internalState === 'checked' ? '#ffffff' : 'var(--muted-foreground)',\n }}\n onClick={() => handleToggle('checked')}\n onMouseEnter={(e) => {\n if (internalState !== 'checked')\n e.currentTarget.style.backgroundColor = 'var(--muted)';\n }}\n onMouseLeave={(e) => {\n if (internalState !== 'checked')\n e.currentTarget.style.backgroundColor = 'var(--background)';\n }}\n >\n {labels_toggle.yes}\n </Button>\n <Button\n variant={internalState === 'unchecked' ? 'default' : 'ghost'}\n size='sm'\n className={cn('useTw px-3 py-1 text-xs rounded-none border-0 border-l')}\n style={{\n backgroundColor: internalState === 'unchecked' ? '#dc2626' : 'var(--background)',\n color: internalState === 'unchecked' ? '#ffffff' : 'var(--muted-foreground)',\n }}\n onClick={() => handleToggle('unchecked')}\n onMouseEnter={(e) => {\n if (internalState !== 'unchecked')\n e.currentTarget.style.backgroundColor = 'var(--muted)';\n }}\n onMouseLeave={(e) => {\n if (internalState !== 'unchecked')\n e.currentTarget.style.backgroundColor = 'var(--background)';\n }}\n >\n {labels_toggle.no}\n </Button>\n </div>\n </div>\n\n {checkboxLabel && (\n <Label\n className={cn(\n 'useTw cursor-pointer select-none text-sm',\n isHebrew && 'text-right',\n locale.direction === 'rtl' && 'order-2',\n )}\n >\n {checkboxLabel}\n </Label>\n )}\n\n {(internalState === 'checked' || internalState === 'unchecked') && (\n <Button\n variant='ghost'\n size='sm'\n className={cn(\n 'h-5 w-5 p-0 hover:bg-muted rounded-full -mt-1',\n checkboxLabel\n ? locale.direction === 'rtl'\n ? 'order-last -ml-1'\n : 'order-last -mr-1'\n : locale.direction === 'rtl'\n ? 'ml-[80px] order-last'\n : 'mr-[80px] order-last',\n )}\n onClick={handleClear}\n >\n <X className='h-3 w-3' />\n </Button>\n )}\n </div>\n </div>\n );\n}\n"],"names":["useEffect","useState","X","Label","cn","Button","CheckboxFilter","label","checkboxLabel","value","onChange","locale","code","direction","className","internalState","setInternalState","isHebrew","handleToggle","newState","handleClear","isActive","labels_toggle","yes","no","div","dir","variant","size","style","backgroundColor","color","onClick","onMouseEnter","e","currentTarget","onMouseLeave"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-filter.d.ts","sourceRoot":"","sources":["../../../src/filters/components/date-filter.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"date-filter.d.ts","sourceRoot":"","sources":["../../../src/filters/components/date-filter.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAE,eAAe,EAAa,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAQ3E,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,QAAQ,EACR,MAAyC,EACzC,SAAS,GACV,EAAE,eAAe,+BA6VjB"}
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
4
|
import { CalendarIcon, ChevronDown, X } from 'lucide-react';
|
|
5
|
-
import {
|
|
5
|
+
import { futureDateFilterOptions, futureDateFilterOptionsEn, pastDateFilterOptions, pastDateFilterOptionsEn } from '../constants/date-filter-options';
|
|
6
|
+
import { formatDate, getDateRangeForOption } from '../utils/date-helpers';
|
|
6
7
|
import { Button } from '../../ui/button';
|
|
8
|
+
import { cn } from '../../lib/utils';
|
|
9
|
+
import { Label } from '../../ui/label';
|
|
7
10
|
import { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover';
|
|
8
11
|
import { Separator } from '../../ui/separator';
|
|
9
|
-
import { futureDateFilterOptions, futureDateFilterOptionsEn, pastDateFilterOptions, pastDateFilterOptionsEn } from '../constants/date-filter-options';
|
|
10
|
-
import { formatDate, getDateRangeForOption } from '../utils/date-helpers';
|
|
11
12
|
import { Calendar } from '../../ui/calendar';
|
|
12
|
-
import { Label } from '../../ui/label';
|
|
13
13
|
export function DateFilter({ label, value, onChange, locale = {
|
|
14
14
|
code: 'he',
|
|
15
15
|
direction: 'rtl'
|
|
@@ -21,6 +21,8 @@ export function DateFilter({ label, value, onChange, locale = {
|
|
|
21
21
|
});
|
|
22
22
|
const [showCustom, setShowCustom] = useState(false);
|
|
23
23
|
const [isOpen, setIsOpen] = useState(false);
|
|
24
|
+
const [openFromCalendar, setOpenFromCalendar] = useState(false);
|
|
25
|
+
const [openToCalendar, setOpenToCalendar] = useState(false);
|
|
24
26
|
const isHebrew = locale.code === 'he';
|
|
25
27
|
const pastOptions = isHebrew ? pastDateFilterOptions : pastDateFilterOptionsEn;
|
|
26
28
|
const futureOptions = isHebrew ? futureDateFilterOptions : futureDateFilterOptionsEn;
|
|
@@ -35,8 +37,8 @@ export function DateFilter({ label, value, onChange, locale = {
|
|
|
35
37
|
]);
|
|
36
38
|
const labels = {
|
|
37
39
|
selectOption: isHebrew ? 'בחר אפשרות' : 'Select Option',
|
|
38
|
-
from: isHebrew ? 'מתאריך' : 'From
|
|
39
|
-
to: isHebrew ? 'עד תאריך' : 'To
|
|
40
|
+
from: isHebrew ? 'מתאריך' : 'From',
|
|
41
|
+
to: isHebrew ? 'עד תאריך' : 'To',
|
|
40
42
|
selectDate: isHebrew ? 'בחר תאריך' : 'Select Date',
|
|
41
43
|
past: isHebrew ? 'עבר' : 'Past',
|
|
42
44
|
future: isHebrew ? 'עתיד' : 'Future',
|
|
@@ -252,6 +254,8 @@ export function DateFilter({ label, value, onChange, locale = {
|
|
|
252
254
|
children: labels.from
|
|
253
255
|
}),
|
|
254
256
|
/*#__PURE__*/ _jsxs(Popover, {
|
|
257
|
+
open: openFromCalendar,
|
|
258
|
+
onOpenChange: setOpenFromCalendar,
|
|
255
259
|
children: [
|
|
256
260
|
/*#__PURE__*/ _jsx(PopoverTrigger, {
|
|
257
261
|
asChild: true,
|
|
@@ -276,10 +280,13 @@ export function DateFilter({ label, value, onChange, locale = {
|
|
|
276
280
|
children: /*#__PURE__*/ _jsx(Calendar, {
|
|
277
281
|
mode: "single",
|
|
278
282
|
selected: customRange.from,
|
|
279
|
-
onSelect: (date)=>
|
|
283
|
+
onSelect: (date)=>{
|
|
284
|
+
handleCustomRangeChange({
|
|
280
285
|
...customRange,
|
|
281
286
|
from: date
|
|
282
|
-
})
|
|
287
|
+
});
|
|
288
|
+
setOpenFromCalendar(false);
|
|
289
|
+
},
|
|
283
290
|
initialFocus: true,
|
|
284
291
|
className: "useTw"
|
|
285
292
|
})
|
|
@@ -296,6 +303,8 @@ export function DateFilter({ label, value, onChange, locale = {
|
|
|
296
303
|
children: labels.to
|
|
297
304
|
}),
|
|
298
305
|
/*#__PURE__*/ _jsxs(Popover, {
|
|
306
|
+
open: openToCalendar,
|
|
307
|
+
onOpenChange: setOpenToCalendar,
|
|
299
308
|
children: [
|
|
300
309
|
/*#__PURE__*/ _jsx(PopoverTrigger, {
|
|
301
310
|
asChild: true,
|
|
@@ -320,10 +329,13 @@ export function DateFilter({ label, value, onChange, locale = {
|
|
|
320
329
|
children: /*#__PURE__*/ _jsx(Calendar, {
|
|
321
330
|
mode: "single",
|
|
322
331
|
selected: customRange.to,
|
|
323
|
-
onSelect: (date)=>
|
|
332
|
+
onSelect: (date)=>{
|
|
333
|
+
handleCustomRangeChange({
|
|
324
334
|
...customRange,
|
|
325
335
|
to: date
|
|
326
|
-
})
|
|
336
|
+
});
|
|
337
|
+
setOpenToCalendar(false);
|
|
338
|
+
},
|
|
327
339
|
initialFocus: true,
|
|
328
340
|
className: "useTw"
|
|
329
341
|
})
|
|
@@ -361,7 +373,7 @@ export function DateFilter({ label, value, onChange, locale = {
|
|
|
361
373
|
]
|
|
362
374
|
}),
|
|
363
375
|
hasValue() && /*#__PURE__*/ _jsx("button", {
|
|
364
|
-
className:
|
|
376
|
+
className: `useTw absolute ${isHebrew ? 'left-8' : 'right-8'} top-1/2 -translate-y-1/2 h-4 w-4 p-0 hover:bg-muted rounded-sm flex items-center justify-center z-10 `,
|
|
365
377
|
onClick: (e)=>{
|
|
366
378
|
e.stopPropagation();
|
|
367
379
|
handleClearAll();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/filters/components/date-filter.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\nimport { CalendarIcon, ChevronDown, X } from 'lucide-react';\nimport { cn } from '../../lib/utils';\nimport { Button } from '../../ui/button';\n\nimport { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover';\n\nimport { Separator } from '../../ui/separator';\nimport { DateFilterValue, DateRange, Locale } from '../types/filters-type';\nimport {\n futureDateFilterOptions,\n futureDateFilterOptionsEn,\n pastDateFilterOptions,\n pastDateFilterOptionsEn,\n} from '../constants/date-filter-options';\nimport { formatDate, getDateRangeForOption } from '../utils/date-helpers';\nimport { Calendar } from '../../ui/calendar';\nimport { Label } from '../../ui/label';\n\ninterface DateFilterProps {\n label?: string;\n value?: DateFilterValue;\n onChange: (value: DateFilterValue) => void;\n locale?: Locale;\n className?: string;\n}\n\nexport function DateFilter({\n label,\n value,\n onChange,\n locale = { code: 'he', direction: 'rtl' },\n className,\n}: DateFilterProps) {\n const [internalValue, setInternalValue] = useState<DateFilterValue | undefined>(value);\n const [customRange, setCustomRange] = useState<DateRange>({ from: undefined, to: undefined });\n const [showCustom, setShowCustom] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n\n const isHebrew = locale.code === 'he';\n const pastOptions = isHebrew ? pastDateFilterOptions : pastDateFilterOptionsEn;\n const futureOptions = isHebrew ? futureDateFilterOptions : futureDateFilterOptionsEn;\n\n // Sync internal state with external value prop\n useEffect(() => {\n setInternalValue(value);\n if (value?.type === 'custom' && value.customRange) {\n setCustomRange(value.customRange);\n }\n }, [value]);\n\n const labels = {\n selectOption: isHebrew ? 'בחר אפשרות' : 'Select Option',\n from: isHebrew ? 'מתאריך' : 'From Date',\n to: isHebrew ? 'עד תאריך' : 'To Date',\n selectDate: isHebrew ? 'בחר תאריך' : 'Select Date',\n past: isHebrew ? 'עבר' : 'Past',\n future: isHebrew ? 'עתיד' : 'Future',\n custom: isHebrew ? 'טווח מותאם אישית' : 'Custom Range',\n apply: isHebrew ? 'החל' : 'Apply',\n cancel: isHebrew ? 'ביטול' : 'Cancel',\n };\n\n const handlePredefinedSelect = (optionValue: string) => {\n setShowCustom(false);\n setIsOpen(false);\n\n const dateRange = getDateRangeForOption(optionValue, locale.code);\n const newValue: DateFilterValue = {\n type: 'predefined',\n predefinedValue: optionValue,\n customRange: { from: dateRange.from, to: dateRange.to },\n };\n\n setInternalValue(newValue);\n onChange(newValue);\n };\n\n const handleCustomSelect = () => {\n setShowCustom(true);\n };\n\n const handleCustomRangeChange = (newRange: DateRange) => {\n setCustomRange(newRange);\n };\n\n const handleApplyCustomRange = () => {\n const newValue: DateFilterValue = {\n type: 'custom',\n customRange,\n };\n\n setInternalValue(newValue);\n onChange(newValue);\n setIsOpen(false);\n setShowCustom(false);\n };\n\n const handleCancelCustomRange = () => {\n setIsOpen(false);\n setShowCustom(false);\n setCustomRange({ from: undefined, to: undefined });\n };\n\n const handleClearAll = () => {\n setInternalValue(undefined);\n setCustomRange({ from: undefined, to: undefined });\n setShowCustom(false);\n onChange({} as DateFilterValue);\n };\n\n const hasValue = () => {\n return (\n internalValue && (internalValue.type === 'predefined' || internalValue.type === 'custom')\n );\n };\n\n const getDisplayValue = () => {\n if (internalValue?.type === 'custom' && internalValue.customRange) {\n const { from, to } = internalValue.customRange;\n if (from && to) {\n return `${formatDate(from, 'dd/MM/yyyy')}-${formatDate(to, 'dd/MM/yyyy')}`;\n } else if (from) {\n return `${labels.from}: ${formatDate(from, 'dd/MM/yyyy')}`;\n } else if (to) {\n return `${labels.to}: ${formatDate(to, 'dd/MM/yyyy')}`;\n }\n return labels.custom;\n }\n\n if (internalValue?.type === 'predefined' && internalValue.predefinedValue) {\n const allOptions = [...pastOptions, ...futureOptions];\n const option = allOptions.find((opt) => opt.value === internalValue.predefinedValue);\n const dateRange = getDateRangeForOption(internalValue.predefinedValue, locale.code);\n return `${option?.label || internalValue.predefinedValue} ${dateRange.description}`;\n }\n\n return labels.selectOption;\n };\n\n const formatDateRange = (description: string) => {\n // Check if description contains a date range (has \" - \" in it)\n if (description.includes(' - ') && isHebrew) {\n // Split by \" - \" and reverse the order for RTL\n const parts = description.replace(/[()]/g, '').split(' - ');\n if (parts.length === 2) {\n return `(${parts[1]}-${parts[0]})`;\n }\n }\n return description;\n };\n\n const renderOptionWithDate = (option: { value: string; label: string }) => {\n const dateRange = getDateRangeForOption(option.value, locale.code);\n const formattedDescription = formatDateRange(dateRange.description);\n\n return (\n <Button\n key={option.value}\n variant='ghost'\n className={cn(\n ' w-full h-auto py-1 px-2 text-xs leading-tight justify-start',\n isHebrew ? ' text-right' : ' text-left',\n internalValue?.predefinedValue === option.value && 'bg-accent',\n )}\n onClick={() => handlePredefinedSelect(option.value)}\n >\n <div className={cn('flex flex-col')}>\n <span className='font-medium'>{option.label}</span>\n <span className='text-[10px] text-muted-foreground' dir={locale.direction}>\n {formattedDescription}\n </span>\n </div>\n </Button>\n );\n };\n\n return (\n <div className={cn('useTw space-y-1', className)} dir={locale.direction}>\n {label && (\n <Label className={cn('useTw text-sm font-medium', isHebrew && 'text-right block')}>\n {label}\n </Label>\n )}\n\n <div className='relative useTw'>\n <Popover open={isOpen} onOpenChange={setIsOpen}>\n <PopoverTrigger asChild className='useTw'>\n <Button\n variant='outline'\n role='combobox'\n aria-expanded={isOpen}\n className='useTw w-full justify-between bg-background relative min-w-70'\n >\n <span className={`useTw truncate ${isHebrew && 'text-right'}`}>\n {getDisplayValue()}\n </span>\n <ChevronDown className='useTw h-4 w-4 shrink-0 opacity-50' />\n </Button>\n </PopoverTrigger>\n <PopoverContent className='useTw w-80 p-0'>\n <div className='p-4'>\n <div className='grid grid-cols-2 gap-4'>\n {/* Future Options - Left column */}\n <div className='space-y-1'>\n <div\n className={cn(\n 'text-sm font-semibold text-muted-foreground mb-2',\n isHebrew && 'text-right',\n )}\n >\n {labels.future}\n </div>\n <div className='space-y-0.5'>\n {futureOptions.map((option) => (\n <div key={option.value}>{renderOptionWithDate(option)}</div>\n ))}\n </div>\n </div>\n\n {/* Past Options - Right column */}\n <div className='space-y-1'>\n <div\n className={cn(\n 'text-sm font-semibold text-muted-foreground mb-2',\n isHebrew && 'text-right',\n )}\n >\n {labels.past}\n </div>\n <div className='space-y-0.5'>\n {pastOptions.map((option) => (\n <div key={option.value}>{renderOptionWithDate(option)}</div>\n ))}\n </div>\n </div>\n </div>\n\n <Separator className='my-4' />\n\n {/* Custom Option */}\n <div className='space-y-3'>\n <Button\n variant='ghost'\n className={cn(\n 'useTw w-full justify-start h-auto py-2 px-2',\n (showCustom || internalValue?.type === 'custom') && 'bg-accent',\n isHebrew && 'justify-start text-right',\n )}\n onClick={handleCustomSelect}\n >\n {labels.custom}\n </Button>\n\n {/* Custom Date Range - appears next to custom label */}\n {showCustom && (\n <div className='space-y-3 pl-2'>\n <div className='grid grid-cols-1 gap-3'>\n {/* From Date */}\n <div className={cn('flex items-center gap-2')}>\n <Label\n className={cn(\n 'useTw text-xs w-[20%]',\n isHebrew && 'text-right text-start',\n )}\n >\n {labels.from}\n </Label>\n <Popover>\n <PopoverTrigger asChild className='useTw'>\n <Button\n variant='outline'\n className={cn(\n 'useTw w-[60%] justify-start text-left font-normal text-xs h-8 bg-background',\n !customRange.from && 'text-muted-foreground',\n )}\n >\n <CalendarIcon className='useTw mr-1 h-3 w-3' />\n <span dir={locale.direction}>\n {customRange.from\n ? formatDate(customRange.from, 'dd/MM/yyyy')\n : labels.selectDate}\n </span>\n </Button>\n </PopoverTrigger>\n <PopoverContent className='useTw w-auto p-0' align='start'>\n <Calendar\n mode='single'\n selected={customRange.from}\n onSelect={(date) =>\n handleCustomRangeChange({ ...customRange, from: date })\n }\n initialFocus\n className='useTw'\n />\n </PopoverContent>\n </Popover>\n </div>\n\n {/* To Date */}\n <div className={cn('flex items-center gap-2')}>\n <Label\n className={cn(\n 'useTw useTw text-xs w-[20%]',\n isHebrew && 'text-right text-strat',\n )}\n >\n {labels.to}\n </Label>\n <Popover>\n <PopoverTrigger asChild className='useTw'>\n <Button\n variant='outline'\n className={cn(\n 'useTw w-[60%] justify-start text-left font-normal text-xs h-8 bg-background',\n !customRange.to && 'text-muted-foreground',\n )}\n >\n <CalendarIcon className='useTw mr-1 h-3 w-3' />\n <span dir={locale.direction}>\n {customRange.to\n ? formatDate(customRange.to, 'dd/MM/yyyy')\n : labels.selectDate}\n </span>\n </Button>\n </PopoverTrigger>\n <PopoverContent className='useTw w-auto p-0' align='start'>\n <Calendar\n mode='single'\n selected={customRange.to}\n onSelect={(date) =>\n handleCustomRangeChange({ ...customRange, to: date })\n }\n initialFocus\n className='useTw'\n />\n </PopoverContent>\n </Popover>\n </div>\n </div>\n\n {/* Action Buttons */}\n <div className='flex gap-2'>\n <Button\n onClick={handleApplyCustomRange}\n className='useTw flex-1 text-xs h-8'\n disabled={!customRange.from && !customRange.to}\n >\n {labels.apply}\n </Button>\n <Button\n onClick={handleCancelCustomRange}\n variant='outline'\n className='useTw flex-1 text-xs h-8 bg-transparent'\n >\n {labels.cancel}\n </Button>\n </div>\n </div>\n )}\n </div>\n </div>\n </PopoverContent>\n </Popover>\n {hasValue() && (\n <button\n className='useTw absolute left-8 top-1/2 -translate-y-1/2 h-4 w-4 p-0 hover:bg-muted rounded-sm flex items-center justify-center z-10'\n onClick={(e) => {\n e.stopPropagation();\n handleClearAll();\n }}\n >\n <X className='useTw h-3 w-3' />\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"names":["useEffect","useState","CalendarIcon","ChevronDown","X","cn","Button","Popover","PopoverContent","PopoverTrigger","Separator","futureDateFilterOptions","futureDateFilterOptionsEn","pastDateFilterOptions","pastDateFilterOptionsEn","formatDate","getDateRangeForOption","Calendar","Label","DateFilter","label","value","onChange","locale","code","direction","className","internalValue","setInternalValue","customRange","setCustomRange","from","undefined","to","showCustom","setShowCustom","isOpen","setIsOpen","isHebrew","pastOptions","futureOptions","type","labels","selectOption","selectDate","past","future","custom","apply","cancel","handlePredefinedSelect","optionValue","dateRange","newValue","predefinedValue","handleCustomSelect","handleCustomRangeChange","newRange","handleApplyCustomRange","handleCancelCustomRange","handleClearAll","hasValue","getDisplayValue","allOptions","option","find","opt","description","formatDateRange","includes","parts","replace","split","length","renderOptionWithDate","formattedDescription","variant","onClick","div","span","dir","open","onOpenChange","asChild","role","aria-expanded","map","align","mode","selected","onSelect","date","initialFocus","disabled","button","e","stopPropagation"],"mappings":"AAAA;;AAEA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,QAAQ;AAC5C,SAASC,YAAY,EAAEC,WAAW,EAAEC,CAAC,QAAQ,eAAe;AAC5D,SAASC,EAAE,QAAQ,kBAAkB;AACrC,SAASC,MAAM,QAAQ,kBAAkB;AAEzC,SAASC,OAAO,EAAEC,cAAc,EAAEC,cAAc,QAAQ,mBAAmB;AAE3E,SAASC,SAAS,QAAQ,qBAAqB;AAE/C,SACEC,uBAAuB,EACvBC,yBAAyB,EACzBC,qBAAqB,EACrBC,uBAAuB,QAClB,mCAAmC;AAC1C,SAASC,UAAU,EAAEC,qBAAqB,QAAQ,wBAAwB;AAC1E,SAASC,QAAQ,QAAQ,oBAAoB;AAC7C,SAASC,KAAK,QAAQ,iBAAiB;AAUvC,OAAO,SAASC,WAAW,EACzBC,KAAK,EACLC,KAAK,EACLC,QAAQ,EACRC,SAAS;IAAEC,MAAM;IAAMC,WAAW;AAAM,CAAC,EACzCC,SAAS,EACO;IAChB,MAAM,CAACC,eAAeC,iBAAiB,GAAG3B,SAAsCoB;IAChF,MAAM,CAACQ,aAAaC,eAAe,GAAG7B,SAAoB;QAAE8B,MAAMC;QAAWC,IAAID;IAAU;IAC3F,MAAM,CAACE,YAAYC,cAAc,GAAGlC,SAAS;IAC7C,MAAM,CAACmC,QAAQC,UAAU,GAAGpC,SAAS;IAErC,MAAMqC,WAAWf,OAAOC,IAAI,KAAK;IACjC,MAAMe,cAAcD,WAAWzB,wBAAwBC;IACvD,MAAM0B,gBAAgBF,WAAW3B,0BAA0BC;IAE3D,+CAA+C;IAC/CZ,UAAU;QACR4B,iBAAiBP;QACjB,IAAIA,OAAOoB,SAAS,YAAYpB,MAAMQ,WAAW,EAAE;YACjDC,eAAeT,MAAMQ,WAAW;QAClC;IACF,GAAG;QAACR;KAAM;IAEV,MAAMqB,SAAS;QACbC,cAAcL,WAAW,eAAe;QACxCP,MAAMO,WAAW,WAAW;QAC5BL,IAAIK,WAAW,aAAa;QAC5BM,YAAYN,WAAW,cAAc;QACrCO,MAAMP,WAAW,QAAQ;QACzBQ,QAAQR,WAAW,SAAS;QAC5BS,QAAQT,WAAW,qBAAqB;QACxCU,OAAOV,WAAW,QAAQ;QAC1BW,QAAQX,WAAW,UAAU;IAC/B;IAEA,MAAMY,yBAAyB,CAACC;QAC9BhB,cAAc;QACdE,UAAU;QAEV,MAAMe,YAAYpC,sBAAsBmC,aAAa5B,OAAOC,IAAI;QAChE,MAAM6B,WAA4B;YAChCZ,MAAM;YACNa,iBAAiBH;YACjBtB,aAAa;gBAAEE,MAAMqB,UAAUrB,IAAI;gBAAEE,IAAImB,UAAUnB,EAAE;YAAC;QACxD;QAEAL,iBAAiByB;QACjB/B,SAAS+B;IACX;IAEA,MAAME,qBAAqB;QACzBpB,cAAc;IAChB;IAEA,MAAMqB,0BAA0B,CAACC;QAC/B3B,eAAe2B;IACjB;IAEA,MAAMC,yBAAyB;QAC7B,MAAML,WAA4B;YAChCZ,MAAM;YACNZ;QACF;QAEAD,iBAAiByB;QACjB/B,SAAS+B;QACThB,UAAU;QACVF,cAAc;IAChB;IAEA,MAAMwB,0BAA0B;QAC9BtB,UAAU;QACVF,cAAc;QACdL,eAAe;YAAEC,MAAMC;YAAWC,IAAID;QAAU;IAClD;IAEA,MAAM4B,iBAAiB;QACrBhC,iBAAiBI;QACjBF,eAAe;YAAEC,MAAMC;YAAWC,IAAID;QAAU;QAChDG,cAAc;QACdb,SAAS,CAAC;IACZ;IAEA,MAAMuC,WAAW;QACf,OACElC,iBAAkBA,CAAAA,cAAcc,IAAI,KAAK,gBAAgBd,cAAcc,IAAI,KAAK,QAAO;IAE3F;IAEA,MAAMqB,kBAAkB;QACtB,IAAInC,eAAec,SAAS,YAAYd,cAAcE,WAAW,EAAE;YACjE,MAAM,EAAEE,IAAI,EAAEE,EAAE,EAAE,GAAGN,cAAcE,WAAW;YAC9C,IAAIE,QAAQE,IAAI;gBACd,OAAO,GAAGlB,WAAWgB,MAAM,cAAc,CAAC,EAAEhB,WAAWkB,IAAI,eAAe;YAC5E,OAAO,IAAIF,MAAM;gBACf,OAAO,GAAGW,OAAOX,IAAI,CAAC,EAAE,EAAEhB,WAAWgB,MAAM,eAAe;YAC5D,OAAO,IAAIE,IAAI;gBACb,OAAO,GAAGS,OAAOT,EAAE,CAAC,EAAE,EAAElB,WAAWkB,IAAI,eAAe;YACxD;YACA,OAAOS,OAAOK,MAAM;QACtB;QAEA,IAAIpB,eAAec,SAAS,gBAAgBd,cAAc2B,eAAe,EAAE;YACzE,MAAMS,aAAa;mBAAIxB;mBAAgBC;aAAc;YACrD,MAAMwB,SAASD,WAAWE,IAAI,CAAC,CAACC,MAAQA,IAAI7C,KAAK,KAAKM,cAAc2B,eAAe;YACnF,MAAMF,YAAYpC,sBAAsBW,cAAc2B,eAAe,EAAE/B,OAAOC,IAAI;YAClF,OAAO,GAAGwC,QAAQ5C,SAASO,cAAc2B,eAAe,CAAC,CAAC,EAAEF,UAAUe,WAAW,EAAE;QACrF;QAEA,OAAOzB,OAAOC,YAAY;IAC5B;IAEA,MAAMyB,kBAAkB,CAACD;QACvB,+DAA+D;QAC/D,IAAIA,YAAYE,QAAQ,CAAC,UAAU/B,UAAU;YAC3C,+CAA+C;YAC/C,MAAMgC,QAAQH,YAAYI,OAAO,CAAC,SAAS,IAAIC,KAAK,CAAC;YACrD,IAAIF,MAAMG,MAAM,KAAK,GAAG;gBACtB,OAAO,CAAC,CAAC,EAAEH,KAAK,CAAC,EAAE,CAAC,CAAC,EAAEA,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;YACpC;QACF;QACA,OAAOH;IACT;IAEA,MAAMO,uBAAuB,CAACV;QAC5B,MAAMZ,YAAYpC,sBAAsBgD,OAAO3C,KAAK,EAAEE,OAAOC,IAAI;QACjE,MAAMmD,uBAAuBP,gBAAgBhB,UAAUe,WAAW;QAElE,qBACE,KAAC7D;YAECsE,SAAQ;YACRlD,WAAWrB,GACT,gEACAiC,WAAW,gBAAgB,cAC3BX,eAAe2B,oBAAoBU,OAAO3C,KAAK,IAAI;YAErDwD,SAAS,IAAM3B,uBAAuBc,OAAO3C,KAAK;sBAElD,cAAA,MAACyD;gBAAIpD,WAAWrB,GAAG;;kCACjB,KAAC0E;wBAAKrD,WAAU;kCAAesC,OAAO5C,KAAK;;kCAC3C,KAAC2D;wBAAKrD,WAAU;wBAAoCsD,KAAKzD,OAAOE,SAAS;kCACtEkD;;;;WAZAX,OAAO3C,KAAK;IAiBvB;IAEA,qBACE,MAACyD;QAAIpD,WAAWrB,GAAG,mBAAmBqB;QAAYsD,KAAKzD,OAAOE,SAAS;;YACpEL,uBACC,KAACF;gBAAMQ,WAAWrB,GAAG,6BAA6BiC,YAAY;0BAC3DlB;;0BAIL,MAAC0D;gBAAIpD,WAAU;;kCACb,MAACnB;wBAAQ0E,MAAM7C;wBAAQ8C,cAAc7C;;0CACnC,KAAC5B;gCAAe0E,OAAO;gCAACzD,WAAU;0CAChC,cAAA,MAACpB;oCACCsE,SAAQ;oCACRQ,MAAK;oCACLC,iBAAejD;oCACfV,WAAU;;sDAEV,KAACqD;4CAAKrD,WAAW,CAAC,eAAe,EAAEY,YAAY,cAAc;sDAC1DwB;;sDAEH,KAAC3D;4CAAYuB,WAAU;;;;;0CAG3B,KAAClB;gCAAekB,WAAU;0CACxB,cAAA,MAACoD;oCAAIpD,WAAU;;sDACb,MAACoD;4CAAIpD,WAAU;;8DAEb,MAACoD;oDAAIpD,WAAU;;sEACb,KAACoD;4DACCpD,WAAWrB,GACT,oDACAiC,YAAY;sEAGbI,OAAOI,MAAM;;sEAEhB,KAACgC;4DAAIpD,WAAU;sEACZc,cAAc8C,GAAG,CAAC,CAACtB,uBAClB,KAACc;8EAAwBJ,qBAAqBV;mEAApCA,OAAO3C,KAAK;;;;8DAM5B,MAACyD;oDAAIpD,WAAU;;sEACb,KAACoD;4DACCpD,WAAWrB,GACT,oDACAiC,YAAY;sEAGbI,OAAOG,IAAI;;sEAEd,KAACiC;4DAAIpD,WAAU;sEACZa,YAAY+C,GAAG,CAAC,CAACtB,uBAChB,KAACc;8EAAwBJ,qBAAqBV;mEAApCA,OAAO3C,KAAK;;;;;;sDAM9B,KAACX;4CAAUgB,WAAU;;sDAGrB,MAACoD;4CAAIpD,WAAU;;8DACb,KAACpB;oDACCsE,SAAQ;oDACRlD,WAAWrB,GACT,+CACA,AAAC6B,CAAAA,cAAcP,eAAec,SAAS,QAAO,KAAM,aACpDH,YAAY;oDAEduC,SAAStB;8DAERb,OAAOK,MAAM;;gDAIfb,4BACC,MAAC4C;oDAAIpD,WAAU;;sEACb,MAACoD;4DAAIpD,WAAU;;8EAEb,MAACoD;oEAAIpD,WAAWrB,GAAG;;sFACjB,KAACa;4EACCQ,WAAWrB,GACT,yBACAiC,YAAY;sFAGbI,OAAOX,IAAI;;sFAEd,MAACxB;;8FACC,KAACE;oFAAe0E,OAAO;oFAACzD,WAAU;8FAChC,cAAA,MAACpB;wFACCsE,SAAQ;wFACRlD,WAAWrB,GACT,+EACA,CAACwB,YAAYE,IAAI,IAAI;;0GAGvB,KAAC7B;gGAAawB,WAAU;;0GACxB,KAACqD;gGAAKC,KAAKzD,OAAOE,SAAS;0GACxBI,YAAYE,IAAI,GACbhB,WAAWc,YAAYE,IAAI,EAAE,gBAC7BW,OAAOE,UAAU;;;;;8FAI3B,KAACpC;oFAAekB,WAAU;oFAAmB6D,OAAM;8FACjD,cAAA,KAACtE;wFACCuE,MAAK;wFACLC,UAAU5D,YAAYE,IAAI;wFAC1B2D,UAAU,CAACC,OACTnC,wBAAwB;gGAAE,GAAG3B,WAAW;gGAAEE,MAAM4D;4FAAK;wFAEvDC,YAAY;wFACZlE,WAAU;;;;;;;8EAOlB,MAACoD;oEAAIpD,WAAWrB,GAAG;;sFACjB,KAACa;4EACCQ,WAAWrB,GACT,+BACAiC,YAAY;sFAGbI,OAAOT,EAAE;;sFAEZ,MAAC1B;;8FACC,KAACE;oFAAe0E,OAAO;oFAACzD,WAAU;8FAChC,cAAA,MAACpB;wFACCsE,SAAQ;wFACRlD,WAAWrB,GACT,+EACA,CAACwB,YAAYI,EAAE,IAAI;;0GAGrB,KAAC/B;gGAAawB,WAAU;;0GACxB,KAACqD;gGAAKC,KAAKzD,OAAOE,SAAS;0GACxBI,YAAYI,EAAE,GACXlB,WAAWc,YAAYI,EAAE,EAAE,gBAC3BS,OAAOE,UAAU;;;;;8FAI3B,KAACpC;oFAAekB,WAAU;oFAAmB6D,OAAM;8FACjD,cAAA,KAACtE;wFACCuE,MAAK;wFACLC,UAAU5D,YAAYI,EAAE;wFACxByD,UAAU,CAACC,OACTnC,wBAAwB;gGAAE,GAAG3B,WAAW;gGAAEI,IAAI0D;4FAAK;wFAErDC,YAAY;wFACZlE,WAAU;;;;;;;;;sEAQpB,MAACoD;4DAAIpD,WAAU;;8EACb,KAACpB;oEACCuE,SAASnB;oEACThC,WAAU;oEACVmE,UAAU,CAAChE,YAAYE,IAAI,IAAI,CAACF,YAAYI,EAAE;8EAE7CS,OAAOM,KAAK;;8EAEf,KAAC1C;oEACCuE,SAASlB;oEACTiB,SAAQ;oEACRlD,WAAU;8EAETgB,OAAOO,MAAM;;;;;;;;;;;;;oBAS7BY,4BACC,KAACiC;wBACCpE,WAAU;wBACVmD,SAAS,CAACkB;4BACRA,EAAEC,eAAe;4BACjBpC;wBACF;kCAEA,cAAA,KAACxD;4BAAEsB,WAAU;;;;;;;AAMzB"}
|
|
1
|
+
{"version":3,"sources":["../../../src/filters/components/date-filter.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\nimport { CalendarIcon, ChevronDown, X } from 'lucide-react';\n\nimport {\n futureDateFilterOptions,\n futureDateFilterOptionsEn,\n pastDateFilterOptions,\n pastDateFilterOptionsEn,\n} from '../constants/date-filter-options';\nimport { formatDate, getDateRangeForOption } from '../utils/date-helpers';\nimport { DateFilterValue, DateRange, Locale } from '../types/filters-type';\nimport { Button } from '../../ui/button';\nimport { cn } from '../../lib/utils';\nimport { Label } from '../../ui/label';\nimport { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover';\nimport { Separator } from '../../ui/separator';\nimport { Calendar } from '../../ui/calendar';\n\ninterface DateFilterProps {\n label?: string;\n value?: DateFilterValue;\n onChange: (value: DateFilterValue) => void;\n locale?: Locale;\n className?: string;\n}\n\nexport function DateFilter({\n label,\n value,\n onChange,\n locale = { code: 'he', direction: 'rtl' },\n className,\n}: DateFilterProps) {\n const [internalValue, setInternalValue] = useState<DateFilterValue | undefined>(value);\n const [customRange, setCustomRange] = useState<DateRange>({ from: undefined, to: undefined });\n const [showCustom, setShowCustom] = useState(false);\n const [isOpen, setIsOpen] = useState(false);\n const [openFromCalendar, setOpenFromCalendar] = useState(false);\n const [openToCalendar, setOpenToCalendar] = useState(false);\n\n const isHebrew = locale.code === 'he';\n const pastOptions = isHebrew ? pastDateFilterOptions : pastDateFilterOptionsEn;\n const futureOptions = isHebrew ? futureDateFilterOptions : futureDateFilterOptionsEn;\n\n // Sync internal state with external value prop\n useEffect(() => {\n setInternalValue(value);\n if (value?.type === 'custom' && value.customRange) {\n setCustomRange(value.customRange);\n }\n }, [value]);\n\n const labels = {\n selectOption: isHebrew ? 'בחר אפשרות' : 'Select Option',\n from: isHebrew ? 'מתאריך' : 'From',\n to: isHebrew ? 'עד תאריך' : 'To',\n selectDate: isHebrew ? 'בחר תאריך' : 'Select Date',\n past: isHebrew ? 'עבר' : 'Past',\n future: isHebrew ? 'עתיד' : 'Future',\n custom: isHebrew ? 'טווח מותאם אישית' : 'Custom Range',\n apply: isHebrew ? 'החל' : 'Apply',\n cancel: isHebrew ? 'ביטול' : 'Cancel',\n };\n\n const handlePredefinedSelect = (optionValue: string) => {\n setShowCustom(false);\n setIsOpen(false);\n\n const dateRange = getDateRangeForOption(optionValue, locale.code);\n const newValue: DateFilterValue = {\n type: 'predefined',\n predefinedValue: optionValue,\n customRange: { from: dateRange.from, to: dateRange.to },\n };\n\n setInternalValue(newValue);\n onChange(newValue);\n };\n\n const handleCustomSelect = () => {\n setShowCustom(true);\n };\n\n const handleCustomRangeChange = (newRange: DateRange) => {\n setCustomRange(newRange);\n };\n\n const handleApplyCustomRange = () => {\n const newValue: DateFilterValue = {\n type: 'custom',\n customRange,\n };\n\n setInternalValue(newValue);\n onChange(newValue);\n setIsOpen(false);\n setShowCustom(false);\n };\n\n const handleCancelCustomRange = () => {\n setIsOpen(false);\n setShowCustom(false);\n setCustomRange({ from: undefined, to: undefined });\n };\n\n const handleClearAll = () => {\n setInternalValue(undefined);\n setCustomRange({ from: undefined, to: undefined });\n setShowCustom(false);\n onChange({} as DateFilterValue);\n };\n\n const hasValue = () => {\n return (\n internalValue && (internalValue.type === 'predefined' || internalValue.type === 'custom')\n );\n };\n\n const getDisplayValue = () => {\n if (internalValue?.type === 'custom' && internalValue.customRange) {\n const { from, to } = internalValue.customRange;\n if (from && to) {\n return `${formatDate(from, 'dd/MM/yyyy')}-${formatDate(to, 'dd/MM/yyyy')}`;\n } else if (from) {\n return `${labels.from}: ${formatDate(from, 'dd/MM/yyyy')}`;\n } else if (to) {\n return `${labels.to}: ${formatDate(to, 'dd/MM/yyyy')}`;\n }\n return labels.custom;\n }\n\n if (internalValue?.type === 'predefined' && internalValue.predefinedValue) {\n const allOptions = [...pastOptions, ...futureOptions];\n const option = allOptions.find((opt) => opt.value === internalValue.predefinedValue);\n const dateRange = getDateRangeForOption(internalValue.predefinedValue, locale.code);\n return `${option?.label || internalValue.predefinedValue} ${dateRange.description}`;\n }\n\n return labels.selectOption;\n };\n\n const formatDateRange = (description: string) => {\n // Check if description contains a date range (has \" - \" in it)\n if (description.includes(' - ') && isHebrew) {\n // Split by \" - \" and reverse the order for RTL\n const parts = description.replace(/[()]/g, '').split(' - ');\n if (parts.length === 2) {\n return `(${parts[1]}-${parts[0]})`;\n }\n }\n return description;\n };\n\n const renderOptionWithDate = (option: { value: string; label: string }) => {\n const dateRange = getDateRangeForOption(option.value, locale.code);\n const formattedDescription = formatDateRange(dateRange.description);\n\n return (\n <Button\n key={option.value}\n variant='ghost'\n className={cn(\n ' w-full h-auto py-1 px-2 text-xs leading-tight justify-start',\n isHebrew ? ' text-right' : ' text-left',\n internalValue?.predefinedValue === option.value && 'bg-accent',\n )}\n onClick={() => handlePredefinedSelect(option.value)}\n >\n <div className={cn('flex flex-col')}>\n <span className='font-medium'>{option.label}</span>\n <span className='text-[10px] text-muted-foreground' dir={locale.direction}>\n {formattedDescription}\n </span>\n </div>\n </Button>\n );\n };\n\n return (\n <div className={cn('useTw space-y-1', className)} dir={locale.direction}>\n {label && (\n <Label className={cn('useTw text-sm font-medium', isHebrew && 'text-right block')}>\n {label}\n </Label>\n )}\n\n <div className='relative useTw'>\n <Popover open={isOpen} onOpenChange={setIsOpen}>\n <PopoverTrigger asChild className='useTw'>\n <Button\n variant='outline'\n role='combobox'\n aria-expanded={isOpen}\n className='useTw w-full justify-between bg-background relative min-w-70'\n >\n <span className={`useTw truncate ${isHebrew && 'text-right'}`}>\n {getDisplayValue()}\n </span>\n <ChevronDown className='useTw h-4 w-4 shrink-0 opacity-50' />\n </Button>\n </PopoverTrigger>\n <PopoverContent className='useTw w-80 p-0'>\n <div className='p-4'>\n <div className='grid grid-cols-2 gap-4'>\n {/* Future Options - Left column */}\n <div className='space-y-1'>\n <div\n className={cn(\n 'text-sm font-semibold text-muted-foreground mb-2',\n isHebrew && 'text-right',\n )}\n >\n {labels.future}\n </div>\n <div className='space-y-0.5'>\n {futureOptions.map((option) => (\n <div key={option.value}>{renderOptionWithDate(option)}</div>\n ))}\n </div>\n </div>\n\n {/* Past Options - Right column */}\n <div className='space-y-1'>\n <div\n className={cn(\n 'text-sm font-semibold text-muted-foreground mb-2',\n isHebrew && 'text-right',\n )}\n >\n {labels.past}\n </div>\n <div className='space-y-0.5'>\n {pastOptions.map((option) => (\n <div key={option.value}>{renderOptionWithDate(option)}</div>\n ))}\n </div>\n </div>\n </div>\n\n <Separator className='my-4' />\n\n {/* Custom Option */}\n <div className='space-y-3'>\n <Button\n variant='ghost'\n className={cn(\n 'useTw w-full justify-start h-auto py-2 px-2',\n (showCustom || internalValue?.type === 'custom') && 'bg-accent',\n isHebrew && 'justify-start text-right',\n )}\n onClick={handleCustomSelect}\n >\n {labels.custom}\n </Button>\n\n {/* Custom Date Range - appears next to custom label */}\n {showCustom && (\n <div className='space-y-3 pl-2'>\n <div className='grid grid-cols-1 gap-3'>\n {/* From Date */}\n <div className={cn('flex items-center gap-2')}>\n <Label\n className={cn(\n 'useTw text-xs w-[20%]',\n isHebrew && 'text-right text-start',\n )}\n >\n {labels.from}\n </Label>\n <Popover open={openFromCalendar} onOpenChange={setOpenFromCalendar}>\n <PopoverTrigger asChild className='useTw'>\n <Button\n variant='outline'\n className={cn(\n 'useTw w-[60%] justify-start text-left font-normal text-xs h-8 bg-background',\n !customRange.from && 'text-muted-foreground',\n )}\n >\n <CalendarIcon className='useTw mr-1 h-3 w-3' />\n <span dir={locale.direction}>\n {customRange.from\n ? formatDate(customRange.from, 'dd/MM/yyyy')\n : labels.selectDate}\n </span>\n </Button>\n </PopoverTrigger>\n <PopoverContent className='useTw w-auto p-0' align='start'>\n <Calendar\n mode='single'\n selected={customRange.from}\n onSelect={(date) => {\n handleCustomRangeChange({ ...customRange, from: date });\n setOpenFromCalendar(false);\n }}\n initialFocus\n className='useTw'\n />\n </PopoverContent>\n </Popover>\n </div>\n\n {/* To Date */}\n <div className={cn('flex items-center gap-2')}>\n <Label\n className={cn(\n 'useTw useTw text-xs w-[20%]',\n isHebrew && 'text-right text-strat',\n )}\n >\n {labels.to}\n </Label>\n <Popover open={openToCalendar} onOpenChange={setOpenToCalendar}>\n <PopoverTrigger asChild className='useTw'>\n <Button\n variant='outline'\n className={cn(\n 'useTw w-[60%] justify-start text-left font-normal text-xs h-8 bg-background',\n !customRange.to && 'text-muted-foreground',\n )}\n >\n <CalendarIcon className='useTw mr-1 h-3 w-3' />\n <span dir={locale.direction}>\n {customRange.to\n ? formatDate(customRange.to, 'dd/MM/yyyy')\n : labels.selectDate}\n </span>\n </Button>\n </PopoverTrigger>\n <PopoverContent className='useTw w-auto p-0' align='start'>\n <Calendar\n mode='single'\n selected={customRange.to}\n onSelect={(date) => {\n handleCustomRangeChange({ ...customRange, to: date });\n setOpenToCalendar(false);\n }}\n initialFocus\n className='useTw'\n />\n </PopoverContent>\n </Popover>\n </div>\n </div>\n\n {/* Action Buttons */}\n <div className='flex gap-2'>\n <Button\n onClick={handleApplyCustomRange}\n className='useTw flex-1 text-xs h-8'\n disabled={!customRange.from && !customRange.to}\n >\n {labels.apply}\n </Button>\n <Button\n onClick={handleCancelCustomRange}\n variant='outline'\n className='useTw flex-1 text-xs h-8 bg-transparent'\n >\n {labels.cancel}\n </Button>\n </div>\n </div>\n )}\n </div>\n </div>\n </PopoverContent>\n </Popover>\n {hasValue() && (\n <button\n className={`useTw absolute ${isHebrew ? 'left-8' : 'right-8'} top-1/2 -translate-y-1/2 h-4 w-4 p-0 hover:bg-muted rounded-sm flex items-center justify-center z-10 `}\n onClick={(e) => {\n e.stopPropagation();\n handleClearAll();\n }}\n >\n <X className='useTw h-3 w-3' />\n </button>\n )}\n </div>\n </div>\n );\n}\n"],"names":["useEffect","useState","CalendarIcon","ChevronDown","X","futureDateFilterOptions","futureDateFilterOptionsEn","pastDateFilterOptions","pastDateFilterOptionsEn","formatDate","getDateRangeForOption","Button","cn","Label","Popover","PopoverContent","PopoverTrigger","Separator","Calendar","DateFilter","label","value","onChange","locale","code","direction","className","internalValue","setInternalValue","customRange","setCustomRange","from","undefined","to","showCustom","setShowCustom","isOpen","setIsOpen","openFromCalendar","setOpenFromCalendar","openToCalendar","setOpenToCalendar","isHebrew","pastOptions","futureOptions","type","labels","selectOption","selectDate","past","future","custom","apply","cancel","handlePredefinedSelect","optionValue","dateRange","newValue","predefinedValue","handleCustomSelect","handleCustomRangeChange","newRange","handleApplyCustomRange","handleCancelCustomRange","handleClearAll","hasValue","getDisplayValue","allOptions","option","find","opt","description","formatDateRange","includes","parts","replace","split","length","renderOptionWithDate","formattedDescription","variant","onClick","div","span","dir","open","onOpenChange","asChild","role","aria-expanded","map","align","mode","selected","onSelect","date","initialFocus","disabled","button","e","stopPropagation"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select-filter.d.ts","sourceRoot":"","sources":["../../../src/filters/components/select-filter.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"select-filter.d.ts","sourceRoot":"","sources":["../../../src/filters/components/select-filter.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAgBtF,UAAU,iBAAiB;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,WAAW,EACX,MAAyC,EACzC,SAAS,EACT,WAAkB,GACnB,EAAE,iBAAiB,+BAmMnB"}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
4
|
import { Check, ChevronsUpDown, X } from 'lucide-react';
|
|
5
|
-
import { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover';
|
|
6
5
|
import { Label } from '../../ui/label';
|
|
7
6
|
import { cn } from '../../lib/utils';
|
|
7
|
+
import { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover';
|
|
8
8
|
import { Button } from '../../ui/button';
|
|
9
9
|
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '../../ui/command';
|
|
10
10
|
import { Checkbox } from '../../ui/checkbox';
|
|
@@ -31,7 +31,8 @@ export function SelectFilter({ label, options, value, onChange, placeholder, loc
|
|
|
31
31
|
deselectAll: isHebrew ? 'בטל בחירת הכל' : 'Deselect All',
|
|
32
32
|
search: isHebrew ? 'חפש...' : 'Search...',
|
|
33
33
|
noResults: isHebrew ? 'לא נמצאו תוצאות' : 'No results found',
|
|
34
|
-
selected: isHebrew ? 'נבחרו' : 'selected'
|
|
34
|
+
selected: isHebrew ? 'נבחרו' : 'selected',
|
|
35
|
+
selectedOne: isHebrew ? 'נבחר' : 'selected'
|
|
35
36
|
};
|
|
36
37
|
const getFilterValue = (values)=>{
|
|
37
38
|
if (values.length === 0) {
|
|
@@ -92,7 +93,7 @@ export function SelectFilter({ label, options, value, onChange, placeholder, loc
|
|
|
92
93
|
} else if (selectedValues.length === options.length) {
|
|
93
94
|
return labels.selectAll;
|
|
94
95
|
} else {
|
|
95
|
-
return `${selectedValues.length} ${labels.selected}`;
|
|
96
|
+
return `${selectedValues.length} ${selectedValues.length > 1 ? labels.selected : labels.selectedOne} `;
|
|
96
97
|
}
|
|
97
98
|
};
|
|
98
99
|
return /*#__PURE__*/ _jsxs("div", {
|
|
@@ -129,7 +130,7 @@ export function SelectFilter({ label, options, value, onChange, placeholder, loc
|
|
|
129
130
|
})
|
|
130
131
|
}),
|
|
131
132
|
/*#__PURE__*/ _jsx(PopoverContent, {
|
|
132
|
-
className: "w-80 p-0",
|
|
133
|
+
className: "useTw w-80 p-0",
|
|
133
134
|
align: "start",
|
|
134
135
|
children: /*#__PURE__*/ _jsxs(Command, {
|
|
135
136
|
children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/filters/components/select-filter.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\nimport { Check, ChevronsUpDown, X } from 'lucide-react';\n\nimport { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover';\n\nimport { Label } from '../../ui/label';\n\nimport { cn } from '../../lib/utils';\nimport { Button } from '../../ui/button';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '../../ui/command';\nimport { Locale, SelectFilterOption, SelectFilterValue } from '../types/filters-type';\nimport { Checkbox } from '../../ui/checkbox';\nimport { Badge } from '../../ui/badge';\n\ninterface SelectFilterProps {\n label?: string;\n options: SelectFilterOption[];\n value?: SelectFilterValue;\n onChange: (value: SelectFilterValue) => void;\n placeholder?: string;\n locale?: Locale;\n className?: string;\n multiSelect?: boolean;\n}\n\nexport function SelectFilter({\n label,\n options,\n value,\n onChange,\n placeholder,\n locale = { code: 'he', direction: 'rtl' },\n className,\n multiSelect = true,\n}: SelectFilterProps) {\n const [open, setOpen] = useState(false);\n const [internalValue, setInternalValue] = useState<SelectFilterValue | undefined>(value);\n\n const isHebrew = locale.code === 'he';\n const showSearch = options.length > 10;\n const showSelectAll = multiSelect && options.length > 3;\n\n // Sync internal state with external value prop\n useEffect(() => {\n setInternalValue(value);\n }, [value]);\n\n const selectedValues = internalValue?.selectedValues || [];\n const allSelected = selectedValues.length === options.length;\n\n const labels = {\n selectAll: isHebrew ? 'בחר הכל' : 'Select All',\n deselectAll: isHebrew ? 'בטל בחירת הכל' : 'Deselect All',\n search: isHebrew ? 'חפש...' : 'Search...',\n noResults: isHebrew ? 'לא נמצאו תוצאות' : 'No results found',\n selected: isHebrew ? 'נבחרו' : 'selected',\n };\n\n const getFilterValue = (values: string[]): SelectFilterValue => {\n if (values.length === 0) {\n return { type: 'none', selectedValues: [] };\n } else if (values.length === options.length) {\n return { type: 'all', selectedValues: values };\n } else {\n return { type: 'some', selectedValues: values };\n }\n };\n\n const handleSelectAll = () => {\n const allValues = options.map((option) => option.value);\n const newValue = getFilterValue(allValues);\n setInternalValue(newValue);\n onChange(newValue);\n };\n\n const handleClearAll = () => {\n const newValue = getFilterValue([]);\n setInternalValue(newValue);\n onChange(newValue);\n };\n\n const handleToggleSelectAll = () => {\n if (allSelected) {\n handleClearAll();\n } else {\n handleSelectAll();\n }\n };\n\n const handleToggleOption = (optionValue: string) => {\n let newValues: string[];\n\n if (multiSelect) {\n newValues = selectedValues.includes(optionValue)\n ? selectedValues.filter((val) => val !== optionValue)\n : [...selectedValues, optionValue];\n } else {\n newValues = [optionValue];\n setOpen(false);\n }\n\n const newValue = getFilterValue(newValues);\n setInternalValue(newValue);\n onChange(newValue);\n };\n\n const getDisplayText = () => {\n if (selectedValues.length === 0) {\n return placeholder || (isHebrew ? 'בחר אפשרויות' : 'Select options');\n } else if (selectedValues.length === options.length) {\n return labels.selectAll;\n } else {\n return `${selectedValues.length} ${labels.selected}`;\n }\n };\n\n return (\n <div className={cn('space-y-1', className)} dir={locale.direction}>\n {label && (\n <Label className={cn('useTw text-sm font-medium', isHebrew && 'text-right block')}>\n {label}\n </Label>\n )}\n\n <div className='relative'>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant='outline'\n role='combobox'\n aria-expanded={open}\n className='w-full justify-between bg-background relative'\n >\n <span className='truncate'>{getDisplayText()}</span>\n <ChevronsUpDown className='h-4 w-4 shrink-0 opacity-50' />\n </Button>\n </PopoverTrigger>\n <PopoverContent className='w-80 p-0' align='start'>\n <Command>\n {showSearch && <CommandInput placeholder={labels.search} />}\n <CommandList>\n <CommandEmpty>{labels.noResults}</CommandEmpty>\n <CommandGroup>\n {showSelectAll && (\n <CommandItem onSelect={handleToggleSelectAll}>\n <div\n className={cn(\n 'useTw flex items-center w-full justify-between',\n isHebrew && 'flex-row-reverse',\n )}\n >\n <Checkbox\n checked={allSelected}\n className={cn(isHebrew ? 'useTw ml-2' : 'useTw mr-2')}\n />\n <span className={cn(isHebrew && 'useTw text-right flex-1 mr-2')}>\n {allSelected ? labels.deselectAll : labels.selectAll}\n </span>\n </div>\n </CommandItem>\n )}\n {options.map((option) => (\n <CommandItem\n key={option.value}\n onSelect={() => handleToggleOption(option.value)}\n >\n <div\n className={cn(\n 'flex items-center w-full justify-between',\n isHebrew && 'flex-row-reverse',\n )}\n >\n {multiSelect ? (\n <Checkbox\n checked={selectedValues.includes(option.value)}\n className={cn(isHebrew ? 'useTw ml-2' : 'useTw mx-2')}\n />\n ) : (\n <Check\n className={cn(\n 'useTw h-4 w-4',\n isHebrew ? 'ml-2' : 'mr-2',\n selectedValues.includes(option.value) ? 'opacity-100' : 'opacity-0',\n )}\n />\n )}\n <span className={cn(isHebrew && 'text-right flex-1')}>{option.label}</span>\n </div>\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n {selectedValues.length > 0 && (\n <button\n className={`useTw absolute ${isHebrew ? 'left-8' : 'right-8'} top-1/2 -translate-y-1/2 h-4 w-4 p-0 hover:bg-muted rounded-sm flex items-center justify-center z-10 `}\n onClick={(e) => {\n e.stopPropagation();\n handleClearAll();\n }}\n >\n <X className='h-3 w-3' />\n </button>\n )}\n </div>\n\n {multiSelect && selectedValues.length > 0 && selectedValues.length < options.length && (\n <div className='flex flex-wrap gap-1 mt-2'>\n {selectedValues.map((value) => {\n const option = options.find((opt) => opt.value === value);\n return (\n <Badge key={value} variant='secondary' className='text-xs bg-background border'>\n {option?.label || value}\n <button\n className='ml-1 hover:bg-muted rounded-full'\n onClick={() => handleToggleOption(value)}\n >\n ×\n </button>\n </Badge>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n"],"names":["useEffect","useState","Check","ChevronsUpDown","X","Popover","PopoverContent","PopoverTrigger","Label","cn","Button","Command","CommandEmpty","CommandGroup","CommandInput","CommandItem","CommandList","Checkbox","Badge","SelectFilter","label","options","value","onChange","placeholder","locale","code","direction","className","multiSelect","open","setOpen","internalValue","setInternalValue","isHebrew","showSearch","length","showSelectAll","selectedValues","allSelected","labels","selectAll","deselectAll","search","noResults","selected","getFilterValue","values","type","handleSelectAll","allValues","map","option","newValue","handleClearAll","handleToggleSelectAll","handleToggleOption","optionValue","newValues","includes","filter","val","getDisplayText","div","dir","onOpenChange","asChild","variant","role","aria-expanded","span","align","onSelect","checked","button","onClick","e","stopPropagation","find","opt"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/filters/components/select-filter.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\nimport { Check, ChevronsUpDown, X } from 'lucide-react';\nimport { Locale, SelectFilterOption, SelectFilterValue } from '../types/filters-type';\nimport { Label } from '../../ui/label';\nimport { cn } from '../../lib/utils';\nimport { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover';\nimport { Button } from '../../ui/button';\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '../../ui/command';\nimport { Checkbox } from '../../ui/checkbox';\nimport { Badge } from '../../ui/badge';\n\ninterface SelectFilterProps {\n label?: string;\n options: SelectFilterOption[];\n value?: SelectFilterValue;\n onChange: (value: SelectFilterValue) => void;\n placeholder?: string;\n locale?: Locale;\n className?: string;\n multiSelect?: boolean;\n}\n\nexport function SelectFilter({\n label,\n options,\n value,\n onChange,\n placeholder,\n locale = { code: 'he', direction: 'rtl' },\n className,\n multiSelect = true,\n}: SelectFilterProps) {\n const [open, setOpen] = useState(false);\n const [internalValue, setInternalValue] = useState<SelectFilterValue | undefined>(value);\n\n const isHebrew = locale.code === 'he';\n const showSearch = options.length > 10;\n const showSelectAll = multiSelect && options.length > 3;\n\n // Sync internal state with external value prop\n useEffect(() => {\n setInternalValue(value);\n }, [value]);\n\n const selectedValues = internalValue?.selectedValues || [];\n const allSelected = selectedValues.length === options.length;\n\n const labels = {\n selectAll: isHebrew ? 'בחר הכל' : 'Select All',\n deselectAll: isHebrew ? 'בטל בחירת הכל' : 'Deselect All',\n search: isHebrew ? 'חפש...' : 'Search...',\n noResults: isHebrew ? 'לא נמצאו תוצאות' : 'No results found',\n selected: isHebrew ? 'נבחרו' : 'selected',\n selectedOne: isHebrew ? 'נבחר' : 'selected',\n };\n\n const getFilterValue = (values: string[]): SelectFilterValue => {\n if (values.length === 0) {\n return { type: 'none', selectedValues: [] };\n } else if (values.length === options.length) {\n return { type: 'all', selectedValues: values };\n } else {\n return { type: 'some', selectedValues: values };\n }\n };\n\n const handleSelectAll = () => {\n const allValues = options.map((option) => option.value);\n const newValue = getFilterValue(allValues);\n setInternalValue(newValue);\n onChange(newValue);\n };\n\n const handleClearAll = () => {\n const newValue = getFilterValue([]);\n setInternalValue(newValue);\n onChange(newValue);\n };\n\n const handleToggleSelectAll = () => {\n if (allSelected) {\n handleClearAll();\n } else {\n handleSelectAll();\n }\n };\n\n const handleToggleOption = (optionValue: string) => {\n let newValues: string[];\n\n if (multiSelect) {\n newValues = selectedValues.includes(optionValue)\n ? selectedValues.filter((val) => val !== optionValue)\n : [...selectedValues, optionValue];\n } else {\n newValues = [optionValue];\n setOpen(false);\n }\n\n const newValue = getFilterValue(newValues);\n setInternalValue(newValue);\n onChange(newValue);\n };\n\n const getDisplayText = () => {\n if (selectedValues.length === 0) {\n return placeholder || (isHebrew ? 'בחר אפשרויות' : 'Select options');\n } else if (selectedValues.length === options.length) {\n return labels.selectAll;\n } else {\n return `${selectedValues.length} ${selectedValues.length > 1 ? labels.selected : labels.selectedOne} `;\n }\n };\n\n return (\n <div className={cn('space-y-1', className)} dir={locale.direction}>\n {label && (\n <Label className={cn('useTw text-sm font-medium', isHebrew && 'text-right block')}>\n {label}\n </Label>\n )}\n\n <div className='relative'>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant='outline'\n role='combobox'\n aria-expanded={open}\n className='w-full justify-between bg-background relative'\n >\n <span className='truncate'>{getDisplayText()}</span>\n <ChevronsUpDown className='h-4 w-4 shrink-0 opacity-50' />\n </Button>\n </PopoverTrigger>\n <PopoverContent className='useTw w-80 p-0' align='start'>\n <Command>\n {showSearch && <CommandInput placeholder={labels.search} />}\n <CommandList>\n <CommandEmpty>{labels.noResults}</CommandEmpty>\n <CommandGroup>\n {showSelectAll && (\n <CommandItem onSelect={handleToggleSelectAll}>\n <div\n className={cn(\n 'useTw flex items-center w-full justify-between',\n isHebrew && 'flex-row-reverse',\n )}\n >\n <Checkbox\n checked={allSelected}\n className={cn(isHebrew ? 'useTw ml-2' : 'useTw mr-2')}\n />\n <span className={cn(isHebrew && 'useTw text-right flex-1 mr-2')}>\n {allSelected ? labels.deselectAll : labels.selectAll}\n </span>\n </div>\n </CommandItem>\n )}\n {options.map((option) => (\n <CommandItem\n key={option.value}\n onSelect={() => handleToggleOption(option.value)}\n >\n <div\n className={cn(\n 'flex items-center w-full justify-between',\n isHebrew && 'flex-row-reverse',\n )}\n >\n {multiSelect ? (\n <Checkbox\n checked={selectedValues.includes(option.value)}\n className={cn(isHebrew ? 'useTw ml-2' : 'useTw mx-2')}\n />\n ) : (\n <Check\n className={cn(\n 'useTw h-4 w-4',\n isHebrew ? 'ml-2' : 'mr-2',\n selectedValues.includes(option.value) ? 'opacity-100' : 'opacity-0',\n )}\n />\n )}\n <span className={cn(isHebrew && 'text-right flex-1')}>{option.label}</span>\n </div>\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n {selectedValues.length > 0 && (\n <button\n className={`useTw absolute ${isHebrew ? 'left-8' : 'right-8'} top-1/2 -translate-y-1/2 h-4 w-4 p-0 hover:bg-muted rounded-sm flex items-center justify-center z-10 `}\n onClick={(e) => {\n e.stopPropagation();\n handleClearAll();\n }}\n >\n <X className='h-3 w-3' />\n </button>\n )}\n </div>\n\n {multiSelect && selectedValues.length > 0 && selectedValues.length < options.length && (\n <div className='flex flex-wrap gap-1 mt-2'>\n {selectedValues.map((value) => {\n const option = options.find((opt) => opt.value === value);\n return (\n <Badge key={value} variant='secondary' className='text-xs bg-background border'>\n {option?.label || value}\n <button\n className='ml-1 hover:bg-muted rounded-full'\n onClick={() => handleToggleOption(value)}\n >\n ×\n </button>\n </Badge>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n"],"names":["useEffect","useState","Check","ChevronsUpDown","X","Label","cn","Popover","PopoverContent","PopoverTrigger","Button","Command","CommandEmpty","CommandGroup","CommandInput","CommandItem","CommandList","Checkbox","Badge","SelectFilter","label","options","value","onChange","placeholder","locale","code","direction","className","multiSelect","open","setOpen","internalValue","setInternalValue","isHebrew","showSearch","length","showSelectAll","selectedValues","allSelected","labels","selectAll","deselectAll","search","noResults","selected","selectedOne","getFilterValue","values","type","handleSelectAll","allValues","map","option","newValue","handleClearAll","handleToggleSelectAll","handleToggleOption","optionValue","newValues","includes","filter","val","getDisplayText","div","dir","onOpenChange","asChild","variant","role","aria-expanded","span","align","onSelect","checked","button","onClick","e","stopPropagation","find","opt"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"small-select-filter.d.ts","sourceRoot":"","sources":["../../../src/filters/components/small-select-filter.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"small-select-filter.d.ts","sourceRoot":"","sources":["../../../src/filters/components/small-select-filter.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAKlE,UAAU,iBAAiB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,sBAAsB;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,MAAyC,EACzC,SAAS,EACT,WAAkB,EAClB,UAAc,GACf,EAAE,sBAAsB,+BA4HxB"}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
4
|
import { X } from 'lucide-react';
|
|
5
|
+
import { Label } from '../../ui/label';
|
|
5
6
|
import { cn } from '../../lib/utils';
|
|
6
7
|
import { Button } from '../../ui/button';
|
|
7
|
-
import { Label } from '../../ui/label';
|
|
8
8
|
export function SmallSelectFilter({ label, options, value, onChange, locale = {
|
|
9
9
|
code: 'he',
|
|
10
10
|
direction: 'rtl'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/filters/components/small-select-filter.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\n\nimport { X } from 'lucide-react';\
|
|
1
|
+
{"version":3,"sources":["../../../src/filters/components/small-select-filter.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\n\nimport { X } from 'lucide-react';\nimport { Locale, SelectFilterValue } from '../types/filters-type';\nimport { Label } from '../../ui/label';\nimport { cn } from '../../lib/utils';\nimport { Button } from '../../ui/button';\n\ninterface SmallSelectOption {\n value: string;\n label: string;\n}\n\ninterface SmallSelectFilterProps {\n label?: string;\n options: SmallSelectOption[];\n value?: SelectFilterValue;\n onChange: (value: SelectFilterValue) => void;\n locale?: Locale;\n className?: string;\n multiSelect?: boolean;\n maxOptions?: number;\n}\n\nexport function SmallSelectFilter({\n label,\n options,\n value,\n onChange,\n locale = { code: 'he', direction: 'rtl' },\n className,\n multiSelect = true,\n maxOptions = 3,\n}: SmallSelectFilterProps) {\n const [internalValue, setInternalValue] = useState<SelectFilterValue>(\n value || { type: 'none', selectedValues: [] },\n );\n\n const isHebrew = locale.code === 'he';\n\n // Limit options to maxOptions\n const limitedOptions = options.slice(0, maxOptions);\n\n // Sync internal state with external value prop\n useEffect(() => {\n setInternalValue(value || { type: 'none', selectedValues: [] });\n }, [value]);\n\n const handleOptionToggle = (optionValue: string) => {\n let newSelectedValues: string[];\n\n if (multiSelect) {\n // Multiple selection mode - allow multiple choices\n if (internalValue.selectedValues.includes(optionValue)) {\n newSelectedValues = internalValue.selectedValues.filter((val) => val !== optionValue);\n } else {\n newSelectedValues = [...internalValue.selectedValues, optionValue];\n }\n } else {\n // Single selection mode\n if (internalValue.selectedValues.includes(optionValue)) {\n newSelectedValues = []; // Deselect if already selected\n } else {\n newSelectedValues = [optionValue]; // Select only this option\n }\n }\n\n const newValue: SelectFilterValue = {\n type:\n newSelectedValues.length === 0\n ? 'none'\n : newSelectedValues.length === options.length\n ? 'all'\n : 'some',\n selectedValues: newSelectedValues,\n };\n setInternalValue(newValue);\n onChange(newValue);\n };\n\n const handleClear = () => {\n const newValue: SelectFilterValue = { type: 'none', selectedValues: [] };\n setInternalValue(newValue);\n onChange(newValue);\n };\n\n const hasSelection = internalValue.selectedValues.length > 0;\n\n const isOptionSelected = (optionValue: string) => {\n return internalValue.selectedValues.includes(optionValue);\n };\n\n const getButtonColor = (optionValue: string, index: number) => {\n if (!isOptionSelected(optionValue)) {\n return 'useTw bg-background text-muted-foreground hover:bg-muted';\n }\n\n // Different colors for different options when selected\n const colors = [\n 'bg-blue-600 text-white hover:bg-blue-700', // First option - blue\n 'bg-green-600 text-white hover:bg-green-700', // Second option - green\n 'bg-purple-600 text-white hover:bg-purple-700', // Third option - purple\n ];\n return colors[index] || 'bg-accent text-accent-foreground hover:bg-accent/80';\n };\n\n return (\n <div className={cn('space-y-2', className)} dir={locale.direction}>\n {label && (\n <Label className={cn('useTw text-sm font-medium', isHebrew && 'text-right block')}>\n {label}\n </Label>\n )}\n\n <div\n className={cn(\n 'flex items-center gap-3 transition-colors py-0.5',\n locale.direction === 'rtl' && 'justify-start',\n )}\n >\n <div className={cn('flex items-center', locale.direction === 'rtl' && 'order-first')}>\n {/* Toggle Options */}\n <div className='flex rounded-md border overflow-hidden'>\n {limitedOptions.map((option, index) => (\n <Button\n key={option.value}\n variant='ghost'\n size='sm'\n className={cn(\n 'px-3 py-1 text-xs rounded-none border-0',\n index > 0 && 'border-l',\n getButtonColor(option.value, index),\n )}\n onClick={() => handleOptionToggle(option.value)}\n >\n {option.label}\n </Button>\n ))}\n </div>\n </div>\n\n {hasSelection && (\n <Button\n variant='ghost'\n size='sm'\n className={cn(\n 'h-5 w-5 p-0 hover:bg-muted rounded-full -mt-1 -ml-1',\n locale.direction === 'rtl' ? 'order-last' : 'order-last',\n )}\n onClick={handleClear}\n >\n <X className='useTw h-3 w-3' />\n </Button>\n )}\n </div>\n </div>\n );\n}\n"],"names":["useEffect","useState","X","Label","cn","Button","SmallSelectFilter","label","options","value","onChange","locale","code","direction","className","multiSelect","maxOptions","internalValue","setInternalValue","type","selectedValues","isHebrew","limitedOptions","slice","handleOptionToggle","optionValue","newSelectedValues","includes","filter","val","newValue","length","handleClear","hasSelection","isOptionSelected","getButtonColor","index","colors","div","dir","map","option","variant","size","onClick"],"mappings":"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"}
|