react-restyle-components 0.3.32 → 0.3.34

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.
@@ -1 +1 @@
1
- {"version":3,"file":"auto-complete-filter-group-by-multiple-select-multiple-fields-display.component.d.ts","sourceRoot":"","sources":["../../../../../../src/core-components/src/molecules/auto-complete-filter-group-by-multiple-select-multiple-fields-display/auto-complete-filter-group-by-multiple-select-multiple-fields-display.component.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,iEAAiE;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,GAAG,CAAC;IACV,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAC,CAAC;IAC9D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;CAC3B;AAED,eAAO,MAAM,4DAA4D,wMAiBtE,iEAAiE,4CA4enE,CAAC"}
1
+ {"version":3,"file":"auto-complete-filter-group-by-multiple-select-multiple-fields-display.component.d.ts","sourceRoot":"","sources":["../../../../../../src/core-components/src/molecules/auto-complete-filter-group-by-multiple-select-multiple-fields-display/auto-complete-filter-group-by-multiple-select-multiple-fields-display.component.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,iEAAiE;IAChF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,GAAG,CAAC;IACV,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAC,CAAC;IAC9D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;CAC3B;AAED,eAAO,MAAM,4DAA4D,wMAiBtE,iEAAiE,4CAiuBnE,CAAC"}
@@ -8,6 +8,8 @@ import { debounce } from '@techabl/core-utils';
8
8
  export const AutoCompleteFilterGroupByMultipleSelectMultipleFieldsDisplay = ({ uniqueField = '_id', isSelectedStringArray = false, loader = false, placeholder = 'Search...', data, hasError = false, disable = false, isUpperCase = false, name, showGroupHeaders = true, collapsibleGroups = false, groupByDetails = { groupByName: 'lab', totalItemName: 'department' }, onFilter, onUpdate, onSelect, onBlur, }) => {
9
9
  const [value, setValue] = useState('');
10
10
  const [groupedOptions, setGroupedOptions] = useState({});
11
+ const [originalGroupedOptions, setOriginalGroupedOptions] = useState({});
12
+ const [selectedItems, setSelectedItems] = useState([]);
11
13
  const [collapsedGroups, setCollapsedGroups] = useState(new Set());
12
14
  const [isListOpen, setIsListOpen] = useState(false);
13
15
  const [totalItems, setTotalItems] = useState(0);
@@ -83,7 +85,16 @@ export const AutoCompleteFilterGroupByMultipleSelectMultipleFieldsDisplay = ({ u
83
85
  // If data.list is an object, it's already grouped
84
86
  processedData = processGroupedData(data.list, data.selected || []);
85
87
  }
88
+ // Store both original and current grouped options
89
+ setOriginalGroupedOptions(processedData);
86
90
  setGroupedOptions(processedData);
91
+ // Extract and maintain selected items separately
92
+ const allSelected = [];
93
+ Object.keys(processedData).forEach((groupKey) => {
94
+ const selectedInGroup = (processedData[groupKey] || []).filter((item) => item.selected);
95
+ allSelected.push(...selectedInGroup);
96
+ });
97
+ setSelectedItems(Array.isArray(data?.selected) ? data?.selected : allSelected);
87
98
  }, [data, data.selected, isSelectedStringArray, uniqueField]);
88
99
  const onChange = (e) => {
89
100
  const search = e.target.value;
@@ -122,13 +133,74 @@ export const AutoCompleteFilterGroupByMultipleSelectMultipleFieldsDisplay = ({ u
122
133
  ...prev,
123
134
  [groupName]: updatedGroupItems,
124
135
  }));
136
+ // Update originalGroupedOptions to maintain consistency
137
+ setOriginalGroupedOptions((prev) => ({
138
+ ...prev,
139
+ [groupName]: updatedGroupItems,
140
+ }));
141
+ // Update selected items list
142
+ if (selectAll) {
143
+ // Add all items from this group to selected items
144
+ const newSelectedItems = [...selectedItems];
145
+ groupItems.forEach((item) => {
146
+ const existingIndex = newSelectedItems.findIndex((selected) => selected[uniqueField] === item[uniqueField]);
147
+ if (existingIndex === -1) {
148
+ newSelectedItems.push({ ...item, selected: true });
149
+ }
150
+ });
151
+ setSelectedItems(newSelectedItems);
152
+ }
153
+ else {
154
+ // Remove all items from this group from selected items
155
+ const newSelectedItems = selectedItems.filter((selectedItem) => {
156
+ return !groupItems.some((groupItem) => groupItem[uniqueField] === selectedItem[uniqueField]);
157
+ });
158
+ setSelectedItems(newSelectedItems);
159
+ }
125
160
  };
126
161
  const handleGroupSelectToggle = (groupName, isSelected, itemIndex) => {
162
+ const item = groupedOptions[groupName][itemIndex];
127
163
  const updatedGroupItems = groupedOptions[groupName].map((grpItem, index) => index === itemIndex ? { ...grpItem, selected: !isSelected } : grpItem);
128
164
  setGroupedOptions((prev) => ({
129
165
  ...prev,
130
166
  [groupName]: updatedGroupItems,
131
167
  }));
168
+ // Update originalGroupedOptions to maintain consistency
169
+ setOriginalGroupedOptions((prev) => ({
170
+ ...prev,
171
+ [groupName]: updatedGroupItems,
172
+ }));
173
+ // Update selected items list
174
+ if (!isSelected) {
175
+ // Add item to selected items
176
+ setSelectedItems((prev) => [...prev, { ...item, selected: true }]);
177
+ }
178
+ else {
179
+ // Remove item from selected items
180
+ setSelectedItems((prev) => prev.filter((selectedItem) => selectedItem[uniqueField] !== item[uniqueField]));
181
+ }
182
+ };
183
+ // Handle individual item deselection from selected section
184
+ const handleDeselectItem = (itemToDeselect) => {
185
+ // Remove from selected items
186
+ setSelectedItems((prev) => prev.filter((item) => item[uniqueField] !== itemToDeselect[uniqueField]));
187
+ // Update both grouped options
188
+ Object.keys(groupedOptions).forEach((groupKey) => {
189
+ const updatedGroupItems = groupedOptions[groupKey].map((item) => {
190
+ if (item[uniqueField] === itemToDeselect[uniqueField]) {
191
+ return { ...item, selected: false };
192
+ }
193
+ return item;
194
+ });
195
+ setGroupedOptions((prev) => ({
196
+ ...prev,
197
+ [groupKey]: updatedGroupItems,
198
+ }));
199
+ setOriginalGroupedOptions((prev) => ({
200
+ ...prev,
201
+ [groupKey]: updatedGroupItems,
202
+ }));
203
+ });
132
204
  };
133
205
  const renderGroupedOptions = () => {
134
206
  const groupNames = Object.keys(groupedOptions).sort();
@@ -142,45 +214,64 @@ export const AutoCompleteFilterGroupByMultipleSelectMultipleFieldsDisplay = ({ u
142
214
  const groupItems = groupedOptions[groupName] || [];
143
215
  const isCollapsed = collapsedGroups.has(groupName);
144
216
  const selectedInGroup = groupItems.filter((item) => item.selected).length;
217
+ const unselectedInGroup = groupItems.filter((item) => !item.selected);
145
218
  return (_jsxs("div", { className: cn(s['border-b'], s['border-gray-200'], s['last:border-b-0']), children: [showGroupHeaders && (_jsxs("div", { className: cn(s['flex'], s['items-center'], s['justify-between'], s['p-3'], s['bg-gray-50'], s['border-b'], s['border-gray-200'], s['font-semibold'], s['text-sm'], s['text-gray-700'], collapsibleGroups && s['cursor-pointer'], s['hover:bg-gray-100']), onClick: () => collapsibleGroups && toggleGroupCollapse(groupName), children: [_jsxs("div", { className: cn(s['flex'], s['items-center'], s['gap-2']), children: [collapsibleGroups && (_jsx(Icon, { nameIcon: isCollapsed ? 'FaChevronRight' : 'FaChevronDown', propsIcon: {
146
219
  size: 12,
147
220
  color: '#666',
148
221
  } })), _jsx("span", { className: cn(s['font-bold'], s['text-blue-700']), children: groupName }), _jsxs("span", { className: cn(s['text-xs'], s['bg-blue-100'], s['text-blue-800'], s['px-2'], s['py-1'], s['rounded-full']), children: [selectedInGroup, "/", groupItems.length] })] }), _jsxs("div", { className: cn(s['flex'], s['gap-1']), children: [_jsx("button", { type: "button", onClick: (e) => {
149
222
  e.stopPropagation();
150
223
  handleGroupSelectAll(groupName, groupItems, true);
151
- }, className: cn(s['text-xs'], s['px-2'], s['py-1'], s['bg-green-500'], s['text-white'], s['rounded'], s['hover:bg-green-600'], s['transition-colors'],
152
- // Add disabled styling
153
- selectedInGroup === groupItems.length && s['opacity-50'], selectedInGroup === groupItems.length &&
224
+ }, className: cn(s['text-xs'], s['px-2'], s['py-1'], s['bg-green-500'], s['text-white'], s['rounded'], s['hover:bg-green-600'], s['transition-colors'], selectedInGroup === groupItems.length && s['opacity-50'], selectedInGroup === groupItems.length &&
154
225
  s['cursor-not-allowed']), title: `Select all in ${groupName}`, disabled: selectedInGroup === groupItems.length, children: "All" }), _jsx("button", { type: "button", onClick: (e) => {
155
226
  e.stopPropagation();
156
227
  handleGroupSelectAll(groupName, groupItems, false);
157
- }, className: cn(s['text-xs'], s['px-2'], s['py-1'], s['bg-gray-500'], s['text-white'], s['rounded'], s['hover:bg-gray-600'], s['transition-colors'],
158
- // Add disabled styling
159
- selectedInGroup === 0 && s['opacity-50'], selectedInGroup === 0 && s['cursor-not-allowed']), title: `Deselect all in ${groupName}`, disabled: selectedInGroup === 0, children: "None" })] })] })), (!collapsibleGroups || !isCollapsed) && (_jsx("div", { className: cn(s['max-h-60'], s['overflow-y-auto']), children: groupItems.map((item, index) => (_jsx("div", { className: cn(s['flex'], s['items-center'], s['gap-3'], s['p-3'], s['hover:bg-blue-50'], s['border-l-4'], s['border-transparent'], item.selected && s['border-blue-500'], item.selected && s['bg-blue-50'], s['transition-colors']), children: _jsxs("label", { className: cn(s['flex'], s['items-center'], s['cursor-pointer'], s['w-full']), children: [_jsx("input", { id: `${groupName}-${index}`, className: cn(s['h-4'], s['w-4'], s['text-blue-600'], s['border-gray-300'], s['rounded'], s['focus:ring-blue-500'], s['cursor-pointer']), type: "checkbox", checked: item.selected || false, onChange: () => {
160
- handleGroupSelectToggle(groupName, item.selected, index);
161
- } }), _jsx("div", { className: cn(s['ml-3'], s['flex'], s['flex-col']), children: _jsx("span", { className: cn(s['text-sm'], s['font-medium'], item.selected && s['text-blue-700']), children: data.displayKey
162
- ? data.displayKey
163
- .map((key) => item[key])
164
- .filter(Boolean)
165
- .join(' - ')
166
- : item.name || item.code || 'Unnamed Item' }) })] }) }, `${groupName}-${item[uniqueField] || index}`))) }))] }, groupName));
228
+ }, className: cn(s['text-xs'], s['px-2'], s['py-1'], s['bg-gray-500'], s['text-white'], s['rounded'], s['hover:bg-gray-600'], s['transition-colors'], selectedInGroup === 0 && s['opacity-50'], selectedInGroup === 0 && s['cursor-not-allowed']), title: `Deselect all in ${groupName}`, disabled: selectedInGroup === 0, children: "None" })] })] })), (!collapsibleGroups || !isCollapsed) && (_jsxs("div", { className: cn(s['max-h-60'], s['overflow-y-auto']), children: [unselectedInGroup.map((item, index) => (_jsx("div", { className: cn(s['flex'], s['items-center'], s['gap-3'], s['p-3'], s['hover:bg-blue-50'], s['border-l-4'], s['border-transparent'], s['transition-colors']), children: _jsxs("label", { className: cn(s['flex'], s['items-center'], s['cursor-pointer'], s['w-full']), children: [_jsx("input", { id: `${groupName}-${index}`, className: cn(s['h-4'], s['w-4'], s['text-blue-600'], s['border-gray-300'], s['rounded'], s['focus:ring-blue-500'], s['cursor-pointer']), type: "checkbox", checked: false, onChange: () => {
229
+ const itemIndex = groupedOptions[groupName].findIndex((grpItem) => grpItem[uniqueField] === item[uniqueField]);
230
+ handleGroupSelectToggle(groupName, false, itemIndex);
231
+ } }), _jsx("div", { className: cn(s['ml-3'], s['flex'], s['flex-col']), children: _jsx("span", { className: cn(s['text-sm'], s['font-medium'], s['text-gray-700']), children: data.displayKey
232
+ ? data.displayKey
233
+ .map((key) => item[key])
234
+ .filter(Boolean)
235
+ .join(' - ')
236
+ : item.name || item.code || 'Unnamed Item' }) })] }) }, `${groupName}-${item[uniqueField] || index}`))), unselectedInGroup.length === 0 && groupItems.length > 0 && (_jsx("div", { className: cn(s['p-3'], s['text-center'], s['text-gray-500'], s['text-sm']), children: "All items in this group are selected" }))] }))] }, groupName));
167
237
  });
168
238
  };
169
239
  const getSelectedCount = () => {
170
- let count = 0;
171
- Object.values(groupedOptions).forEach((groupItems) => {
172
- count += groupItems.filter((item) => item.selected).length;
173
- });
174
- return count;
240
+ return selectedItems?.length;
175
241
  };
176
242
  return (_jsx(_Fragment, { children: _jsxs("div", { ref: wrapperRef, className: cn(s['w-full'], s['relative']), children: [_jsxs("div", { className: cn(s['flex'], s['items-center'], s['leading-4'], s['p-2'], s['focus:outline-none'], s['focus:ring'], s['w-full'], s['shadow-sm'], s['sm:text-base'], s['border'], s['rounded-md'], {
177
243
  [s['border-red']]: hasError,
178
244
  [s['border-gray-300']]: !hasError,
179
- }, s['bg-white']), children: [_jsx("input", { placeholder: placeholder, disabled: disable, name: name, value: !isListOpen ? `${getSelectedCount()} Items Selected` : value, className: cn(s['w-full'], s['focus:outline-none'], s['bg-transparent']), onKeyUp: onKeyUp, onChange: onChange, onClick: () => setIsListOpen(true), onBlur: (e) => onBlur && onBlur(e) }), loader ? (_jsx("div", { className: cn(s['animate-spin'], s['w-4'], s['h-4']), children: _jsx(Icon, { nameIcon: "FaSpinner", propsIcon: {
245
+ }, s['bg-white']), children: [_jsx("input", { placeholder: placeholder, disabled: disable, name: name, value: !isListOpen
246
+ ? getSelectedCount() > 0
247
+ ? `${getSelectedCount()} Items Selected`
248
+ : placeholder
249
+ : isUpperCase
250
+ ? value?.toUpperCase()
251
+ : value, className: cn(s['w-full'], s['focus:outline-none'], s['bg-transparent']), onKeyUp: onKeyUp, onChange: onChange, onClick: () => setIsListOpen(true), onBlur: (e) => onBlur && onBlur(e) }), loader ? (_jsx("div", { className: cn(s['animate-spin'], s['w-4'], s['h-4']), children: _jsx(Icon, { nameIcon: "FaSpinner", propsIcon: {
180
252
  size: 16,
181
253
  color: '#666',
182
254
  } }) })) : (_jsx(Icon, { nameIcon: isListOpen ? 'FaChevronUp' : 'FaChevronDown', propsIcon: {
183
255
  size: 16,
184
256
  color: '#000000',
185
- } }))] }), isListOpen && (_jsxs("div", { className: cn(s['mt-1'], s['absolute'], s['rounded-md'], s['bg-white'], s['border'], s['border-gray-300'], s['shadow-lg'], s['z-50'], s['w-full'], s['max-h-96'], s['overflow-hidden']), style: { zIndex: 1000 }, children: [_jsx("div", { className: cn(s['p-3'], s['border-b'], s['border-gray-200'], s['bg-gray-50'], s['text-sm'], s['font-medium'], s['text-gray-700']), children: _jsxs("div", { className: cn(s['flex'], s['justify-between'], s['items-center']), children: [_jsxs("span", { children: [Object.keys(groupedOptions).length, ' ', groupByDetails.groupByName?.toUpperCase(), ", ", totalItems, ' ', groupByDetails.totalItemName?.toUpperCase()] }), _jsxs("span", { className: cn(s['text-blue-600']), children: [getSelectedCount(), " Selected"] })] }) }), _jsx("div", { className: cn(s['max-h-80'], s['overflow-y-auto']), children: renderGroupedOptions() })] }))] }) }));
257
+ } }))] }), isListOpen && (_jsxs("div", { className: cn(s['mt-1'], s['absolute'], s['rounded-md'], s['bg-white'], s['border'], s['border-gray-300'], s['shadow-lg'], s['z-50'], s['w-full'], s['max-h-96'], s['overflow-hidden']), style: { zIndex: 1000 }, children: [_jsx("div", { className: cn(s['p-3'], s['border-b'], s['border-gray-200'], s['bg-gray-50'], s['text-sm'], s['font-medium'], s['text-gray-700']), children: _jsxs("div", { className: cn(s['flex'], s['justify-between'], s['items-center']), children: [_jsxs("span", { children: [Object.keys(groupedOptions).length, ' ', groupByDetails.groupByName?.toUpperCase(), ", ", totalItems, ' ', groupByDetails.totalItemName?.toUpperCase()] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: cn(s['text-blue-600']), children: [getSelectedCount(), " Selected"] }), _jsx("div", { className: cn(s['flex'], s['gap-2']), children: _jsx("button", { type: "button", className: cn(s['text-xs'], s['px-3'], s['py-1'], s['bg-blue-600'], s['text-white'], s['rounded'], s['hover:bg-blue-700'], s['transition-colors']), onClick: () => {
258
+ onSelect(Object.keys(originalGroupedOptions).reduce((acc, groupKey) => {
259
+ const selectedItems = (originalGroupedOptions[groupKey] || []).filter((item) => item.selected);
260
+ if (selectedItems.length > 0) {
261
+ acc[groupKey] = selectedItems;
262
+ }
263
+ return acc;
264
+ }, {}));
265
+ setIsListOpen(false);
266
+ setValue('');
267
+ }, children: "OK" }) })] })] }) }), _jsxs("div", { className: cn(s['max-h-80'], s['overflow-y-auto']), children: [getSelectedCount() > 0 && (_jsxs("div", { className: cn(s['border-b'], s['border-gray-200']), children: [_jsx("div", { className: cn(s['p-3'], s['bg-blue-50'], s['border-b'], s['border-blue-200'], s['font-semibold'], s['text-sm'], s['text-blue-700']), children: _jsxs("div", { className: cn(s['flex'], s['items-center'], s['gap-2']), children: [_jsx(Icon, { nameIcon: "FaCheck", propsIcon: {
268
+ size: 12,
269
+ color: '#1976d2',
270
+ } }), _jsxs("span", { children: ["Selected Items (", getSelectedCount(), ")"] })] }) }), _jsx("div", { className: cn(s['max-h-48'], s['overflow-y-auto']), children: selectedItems?.map((item, index) => (_jsx("div", { className: cn(s['flex'], s['items-center'], s['gap-3'], s['p-3'], s['hover:bg-blue-50'], s['border-l-4'], s['border-blue-500'], s['bg-blue-25'], s['transition-colors']), children: _jsxs("label", { className: cn(s['flex'], s['items-center'], s['cursor-pointer'], s['w-full']), children: [_jsx("input", { type: "checkbox", checked: true, onChange: () => handleDeselectItem(item), className: cn(s['h-4'], s['w-4'], s['text-blue-600'], s['border-gray-300'], s['rounded'], s['focus:ring-blue-500'], s['cursor-pointer']) }), _jsxs("div", { className: cn(s['ml-3'], s['flex'], s['flex-col']), children: [_jsx("span", { className: cn(s['text-sm'], s['font-medium'], s['text-blue-700']), children: data.displayKey
271
+ ?.map((key) => item[key])
272
+ .filter(Boolean)
273
+ .join(' - ') ||
274
+ item.name ||
275
+ item.code ||
276
+ 'Unnamed Item' }), _jsx("span", { className: cn(s['text-xs'], s['text-gray-500']), children: item.lab || 'Default Group' })] })] }) }, `selected-${item[uniqueField] || index}`))) })] })), _jsx("div", { children: renderGroupedOptions() })] })] }))] }) }));
186
277
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-restyle-components",
3
- "version": "0.3.32",
3
+ "version": "0.3.34",
4
4
  "private": false,
5
5
  "description": "Easy use restyle components",
6
6
  "author": {