@bit.rhplus/ag-grid 0.0.116 → 0.0.118

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,60 +1,498 @@
1
1
  /* eslint-disable */
2
- import React, { useState } from 'react';
2
+ import React, { useState, useEffect, useRef, useCallback } from 'react';
3
3
  import { useGridCellEditor } from 'ag-grid-react';
4
- import ModuleDropdownList from '@bit.rhplus/ui2.module-dropdown-list';
4
+ import { AgGridReact } from 'ag-grid-react';
5
+ import AutoComplete from 'antd/es/auto-complete';
6
+ import Select from 'antd/es/select';
7
+ import Button from 'antd/es/button';
8
+ import { SearchOutlined } from '@ant-design/icons';
9
+ import DraggableModal from '@bit.rhplus/draggable-modal';
10
+ import useData from '@bit.rhplus/data';
11
+ import { useOidcAccessToken } from '@axa-fr/react-oidc';
12
+
13
+ // Module-level cache — přetrvává po dobu session, sdílí se napříč instancemi editoru
14
+ const _lookupCache = {};
15
+
16
+ // ─── Module-level ochrana proti AG Grid outside-click detekci ─────────────────
17
+ // Registruje se při načtení modulu — PŘED mountem AG Gridu, takže v capture fázi
18
+ // poběží dříve než AG Grid's handler (který se registruje při startu editace).
19
+ let _editorMounted = false;
20
+ let _editorModalOpen = false;
21
+
22
+ document.addEventListener('mousedown', (e) => {
23
+ if (!_editorMounted) return;
24
+ if (e.target.closest?.('.ant-select-dropdown')) {
25
+ e.preventDefault(); // zachová focus na inputu → input se neodbluruje → handleFreeTextCommit se nezavolá před onSelect
26
+ e.stopImmediatePropagation();
27
+ return;
28
+ }
29
+ if (_editorModalOpen && e.target.closest?.('.ant-modal-wrap')) {
30
+ e.stopImmediatePropagation();
31
+ }
32
+ }, true);
33
+
34
+ document.addEventListener('focusin', (e) => {
35
+ if (!_editorMounted) return;
36
+ const target = e.target;
37
+ if (target.closest?.('.ant-select-dropdown') ||
38
+ (_editorModalOpen && target.closest?.('.ant-modal-wrap'))) {
39
+ e.stopImmediatePropagation();
40
+ }
41
+ }, true);
5
42
 
6
43
  /**
7
- * ModuleLookupEditor - AG Grid cell editor s ModuleDropdownList
8
- * Zobrazí Select dropdown + tlačítko pro modální vyhledávání
9
- * Při výběru položky ukončí editaci a vrátí celý objekt
44
+ * ModuleLookupEditor AG Grid cell editor
45
+ *
46
+ * Dva módy:
47
+ * - allowFreeText=false (výchozí): Select s plným seznamem + search modal
48
+ * - allowFreeText=true: AutoComplete s lokálním filtrováním + volný text + async validace
49
+ *
50
+ * Data se načtou jednou přes TanStack Query (cache key: [moduleName, 'lookup']).
51
+ * Filtrování probíhá lokálně — žádné API volání při každém stisku klávesy.
52
+ *
53
+ * Free-text flow (Enter / blur):
54
+ * 0 shod → { id: null, text } + ikona ✏️
55
+ * 1 shoda → auto-výběr + ikona 🔗
56
+ * 2+ shody → multi-match modal → uživatel vybere → 🔗
10
57
  */
11
58
  const ModuleLookupEditor = React.forwardRef(({
12
59
  value,
13
60
  onValueChange,
14
61
  stopEditing,
15
62
  moduleDefinition,
16
- }, ref) => {
17
- const [selectedValue, setSelectedValue] = useState(value);
63
+ allowFreeText = false,
64
+ }, _ref) => {
65
+
66
+ // ─── Hooks (vždy voláno) ──────────────────────────────────────────────────────
67
+ const { fetchDataUIAsync } = useData();
68
+ const { accessToken } = useOidcAccessToken();
69
+
70
+ // ─── Module-level cache: načtení položek jednou per moduleName ──────────────
71
+ const moduleName = moduleDefinition?.moduleName;
72
+ const [allItems, setAllItems] = useState(() => _lookupCache[moduleName] || []);
73
+ const [allItemsLoading, setAllItemsLoading] = useState(!_lookupCache[moduleName]);
74
+
75
+ useEffect(() => {
76
+ if (!moduleName || !moduleDefinition) return;
77
+ if (_lookupCache[moduleName]) {
78
+ setAllItems(_lookupCache[moduleName]);
79
+ setAllItemsLoading(false);
80
+ return;
81
+ }
82
+ setAllItemsLoading(true);
83
+ moduleDefinition.fetchData('', fetchDataUIAsync, accessToken)
84
+ .then(data => {
85
+ const items = Array.isArray(data) ? data : [];
86
+ _lookupCache[moduleName] = items;
87
+ setAllItems(items);
88
+ })
89
+ .catch(() => setAllItems([]))
90
+ .finally(() => setAllItemsLoading(false));
91
+ }, []); // jen při mount
92
+
93
+ // ─── Sdílený stav: catalog modal ─────────────────────────────────────────────
94
+ const [catalogModalOpen, setCatalogModalOpen] = useState(false);
95
+
96
+ // ─── Catalog-only stav ───────────────────────────────────────────────────────
97
+ const [catalogSelected, setCatalogSelected] = useState(allowFreeText ? null : value);
98
+
99
+ // ─── Free-text stav ──────────────────────────────────────────────────────────
100
+ const initialText = React.useMemo(() => {
101
+ if (!allowFreeText) return '';
102
+ if (value && typeof value === 'object') return value.text || '';
103
+ if (typeof value === 'string') return value;
104
+ return '';
105
+ }, []); // jen při mount
18
106
 
19
- // Expose getValue method to AG Grid
20
- React.useImperativeHandle(ref, () => ({
21
- getValue: () => selectedValue,
22
- }));
107
+ const [inputText, setInputText] = useState(initialText);
108
+ const [dropdownOpen, setDropdownOpen] = useState(false);
109
+ const [multiMatchData, setMultiMatchData] = useState([]);
110
+ const [multiMatchModalOpen, setMultiMatchModalOpen] = useState(false);
111
+ const catalogModalOpenRef = useRef(false);
112
+ catalogModalOpenRef.current = catalogModalOpen;
113
+ const multiMatchModalOpenRef = useRef(false);
114
+ multiMatchModalOpenRef.current = multiMatchModalOpen;
115
+ const currentTextRef = useRef(initialText);
116
+ const inputTextRef = useRef(initialText); // vždy aktuální inputText pro native handler
117
+ const freeTextWrapperRef = useRef(null); // ref na wrapper div → querySelector('input')
118
+ const isStoppedRef = useRef(false);
119
+ const justSelectedRef = useRef(false);
120
+ // Nastaven synchronně před každým stopEditing() voláním.
121
+ // isCancelAfterEnd: pokud je nastaven → uživatel explicitně potvrdil → nikdy nerušit commit.
122
+ const pendingValueRef = useRef(null);
123
+ // Stabilní ref na onValueChange pro použití v native event handlerech (mimo React deps)
124
+ const onValueChangeRef = useRef(onValueChange);
125
+ useEffect(() => { onValueChangeRef.current = onValueChange; });
23
126
 
24
- // Zrušit editaci pokud se hodnota nezměnila
127
+ // Udržuj inputTextRef synchronizovaný s každým renderem
128
+ inputTextRef.current = inputText;
129
+
130
+ // Ref na suggestions a handleAutoCompleteSelect — přístupné v capture handleru bez stale closure
131
+ const suggestionsRef = useRef([]);
132
+ const handleAutoCompleteSelectRef = useRef(null);
133
+
134
+ // ─── Lokální filtrování návrhů (bez API volání) ───────────────────────────────
135
+ const suggestions = React.useMemo(() => {
136
+ const vf = moduleDefinition?.valueField || 'id';
137
+ const source = (!inputText || !inputText.trim())
138
+ ? allItems
139
+ : allItems.filter(item => {
140
+ const label = moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || '';
141
+ return label.toLowerCase().includes(inputText.toLowerCase());
142
+ });
143
+ return source.slice(0, 15).map(item => ({
144
+ value: String(item[vf]),
145
+ label: moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || '',
146
+ item,
147
+ }));
148
+ }, [allItems, inputText, moduleDefinition]);
149
+ suggestionsRef.current = suggestions;
150
+
151
+ // ─── AG Grid isCancelAfterEnd ─────────────────────────────────────────────────
152
+ // Poznámka: AG Grid 35 používá CellEditorCompProxy.getValue() (vrací compProxy.value aktualizované
153
+ // přes onValueChange prop), nikoli useImperativeHandle ref. useImperativeHandle zde není potřeba.
25
154
  useGridCellEditor({
26
- isCancelAfterEnd: () => !selectedValue || selectedValue === value,
155
+ isCancelAfterEnd: () => {
156
+ if (!allowFreeText) {
157
+ return !catalogSelected || catalogSelected === value;
158
+ }
159
+ const currentText = currentTextRef.current ?? '';
160
+ const originalText = typeof value === 'object' ? (value?.text || '') : (value || '');
161
+ const result = pendingValueRef.current !== null ? false : currentText === originalText;
162
+ console.log('[MLE] isCancelAfterEnd', { pendingValue: pendingValueRef.current, currentText, originalText, result });
163
+ return result;
164
+ },
27
165
  });
28
166
 
29
- // Extrahovat ID z objektu pro ModuleDropdownList
30
- const currentId = React.useMemo(() => {
31
- if (!value) return null;
32
- if (typeof value === 'object') {
33
- return value[moduleDefinition?.valueField || 'id'];
34
- }
167
+ // ─── Sync module-level flags pro ochranu před AG Grid outside-click detekcí ──
168
+ useEffect(() => {
169
+ _editorMounted = true;
170
+ return () => { _editorMounted = false; };
171
+ }, []);
172
+
173
+ useEffect(() => {
174
+ _editorModalOpen = catalogModalOpen || multiMatchModalOpen;
175
+ }, [catalogModalOpen, multiMatchModalOpen]);
176
+
177
+ // ─── Catalog-only: výběr ze Select ──────────────────────────────────────────
178
+ const handleCatalogSelectChange = useCallback((selectedId) => {
179
+ const vf = moduleDefinition?.valueField || 'id';
180
+ const item = allItems.find(i => String(i[vf]) === String(selectedId));
181
+ if (!item) return;
182
+ setCatalogSelected(item);
183
+ if (onValueChange) onValueChange(item);
184
+ setTimeout(() => stopEditing(), 0);
185
+ }, [allItems, moduleDefinition, onValueChange, stopEditing]);
186
+
187
+ const catalogCurrentId = React.useMemo(() => {
188
+ if (allowFreeText || !value) return null;
189
+ const vf = moduleDefinition?.valueField || 'id';
190
+ if (typeof value === 'object') return value[vf];
35
191
  return value;
36
- }, [value, moduleDefinition]);
192
+ }, [value, moduleDefinition, allowFreeText]);
193
+
194
+ // ─── Shared: výběr z katalogu modal ─────────────────────────────────────────
195
+ const handleCatalogModalSelect = useCallback((params) => {
196
+ if (!params.data) return;
197
+ console.log('[MLE] handleCatalogModalSelect', params.data);
198
+ const item = params.data;
199
+ const vf = moduleDefinition?.valueField || 'id';
200
+ const displayText = moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || '';
201
+ justSelectedRef.current = true; // zabrání handleBlur → handleFreeTextCommit při unmount inputu
202
+ if (allowFreeText) {
203
+ const selected = { id: item[vf], text: displayText, _catalogItem: item };
204
+ pendingValueRef.current = selected;
205
+ if (onValueChange) onValueChange(selected);
206
+ } else {
207
+ setCatalogSelected(item);
208
+ if (onValueChange) onValueChange(item);
209
+ }
210
+ setCatalogModalOpen(false);
211
+ setTimeout(() => stopEditing(), 0);
212
+ }, [allowFreeText, moduleDefinition, onValueChange, stopEditing]);
213
+
214
+ // ─── Free-text: clear button (X) ────────────────────────────────────────────
215
+ const handleClear = useCallback(() => {
216
+ setInputText('');
217
+ currentTextRef.current = '';
218
+ const cleared = { id: null, text: '' };
219
+ pendingValueRef.current = cleared;
220
+ if (onValueChange) onValueChange(cleared);
221
+ // editor zůstane otevřený — uživatel může psát novou hodnotu
222
+ }, [onValueChange]);
223
+
224
+ // ─── Free-text: změna textu (lokální filtrování, bez API) ────────────────────
225
+ const handleInputChange = useCallback((text) => {
226
+ setInputText(text);
227
+ currentTextRef.current = text;
228
+ }, []);
37
229
 
38
- const handleChange = (id, fullObject) => {
39
- setSelectedValue(fullObject);
40
- if (onValueChange) {
41
- onValueChange(fullObject);
230
+ // ─── Free-text: výběr návrhu z AutoComplete ───────────────────────────────────
231
+ const handleAutoCompleteSelect = useCallback((optionValue, option) => {
232
+ console.log('[MLE] handleAutoCompleteSelect', optionValue);
233
+ justSelectedRef.current = true;
234
+ const item = option.item;
235
+ const vf = moduleDefinition?.valueField || 'id';
236
+ const displayText = moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || '';
237
+ const selected = { id: item[vf], text: displayText, _catalogItem: item };
238
+ pendingValueRef.current = selected;
239
+ if (onValueChange) onValueChange(selected);
240
+ setTimeout(() => stopEditing(), 0);
241
+ }, [moduleDefinition, onValueChange, stopEditing]);
242
+ handleAutoCompleteSelectRef.current = handleAutoCompleteSelect;
243
+
244
+ // ─── Free-text: validace textu po Enter / blur ────────────────────────────────
245
+ const handleFreeTextCommit = useCallback(async (text) => {
246
+ console.log('[MLE] handleFreeTextCommit', text, 'pendingValue:', pendingValueRef.current);
247
+ if (!text || !text.trim()) {
248
+ const cleared = { id: null, text: '' };
249
+ pendingValueRef.current = cleared;
250
+ if (onValueChange) onValueChange(cleared);
251
+ if (!isStoppedRef.current) stopEditing();
252
+ return;
253
+ }
254
+
255
+ // Nejprve hledáme v již načtených datech (lokální shoda)
256
+ const searchLower = text.trim().toLowerCase();
257
+ const vf = moduleDefinition?.valueField || 'id';
258
+ const localMatches = allItems.filter(item => {
259
+ const label = moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || '';
260
+ return label.toLowerCase() === searchLower;
261
+ });
262
+
263
+ if (isStoppedRef.current) return;
264
+
265
+ if (localMatches.length === 0) {
266
+ const selected = { id: null, text: text.trim() };
267
+ pendingValueRef.current = selected;
268
+ if (onValueChange) onValueChange(selected);
269
+ setTimeout(() => stopEditing(), 0);
270
+ } else if (localMatches.length === 1) {
271
+ const item = localMatches[0];
272
+ const displayText = moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || text.trim();
273
+ const selected = { id: item[vf], text: displayText, _catalogItem: item };
274
+ pendingValueRef.current = selected;
275
+ if (onValueChange) onValueChange(selected);
276
+ setTimeout(() => stopEditing(), 0);
277
+ } else {
278
+ setMultiMatchData(localMatches);
279
+ setMultiMatchModalOpen(true);
42
280
  }
43
- setTimeout(() => {
44
- stopEditing();
45
- }, 0);
46
- };
281
+ }, [allItems, moduleDefinition, stopEditing, onValueChange]);
282
+
283
+ // ─── Free-text: blur ──────────────────────────────────────────────────────────
284
+ const handleBlur = useCallback(() => {
285
+ console.log('[MLE] handleBlur', {
286
+ justSelected: justSelectedRef.current,
287
+ pendingValue: pendingValueRef.current,
288
+ currentText: currentTextRef.current,
289
+ catalogOpen: catalogModalOpenRef.current,
290
+ multiMatchOpen: multiMatchModalOpenRef.current,
291
+ });
292
+ if (justSelectedRef.current) {
293
+ justSelectedRef.current = false;
294
+ return;
295
+ }
296
+ // Pokud už byla hodnota commitnuta (katalog / autocomplete), neoverwritovat
297
+ if (pendingValueRef.current !== null) return;
298
+ // Refy místo state — vždy aktuální hodnota, bez stale closure problémů
299
+ if (currentTextRef.current && !multiMatchModalOpenRef.current && !catalogModalOpenRef.current) {
300
+ handleFreeTextCommit(currentTextRef.current);
301
+ }
302
+ }, [handleFreeTextCommit]);
303
+
304
+ // ─── Free-text: výběr z multi-match modalu ────────────────────────────────────
305
+ const handleMultiMatchSelect = useCallback((params) => {
306
+ if (!params.data) return;
307
+ const item = params.data;
308
+ const vf = moduleDefinition?.valueField || 'id';
309
+ const displayText = moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || '';
310
+ justSelectedRef.current = true; // zabrání handleBlur → handleFreeTextCommit při unmount inputu
311
+ const selected = { id: item[vf], text: displayText, _catalogItem: item };
312
+ pendingValueRef.current = selected;
313
+ setMultiMatchModalOpen(false);
314
+ if (onValueChange) onValueChange(selected);
315
+ setTimeout(() => stopEditing(), 0);
316
+ }, [moduleDefinition, onValueChange, stopEditing]);
317
+
318
+ // ─── Cleanup ──────────────────────────────────────────────────────────────────
319
+ useEffect(() => {
320
+ return () => { isStoppedRef.current = true; };
321
+ }, []);
322
+
323
+ // ─── Native capture Enter handler ────────────────────────────────────────────
324
+ // rc-select volá stopPropagation() na Enter v bubble fázi → náš React onKeyDown
325
+ // na wrapperu ho nikdy nedostane. Capture-phase native listener se spustí jako první.
326
+ useEffect(() => {
327
+ if (!allowFreeText) return;
328
+ const el = freeTextWrapperRef.current;
329
+ if (!el) return;
330
+ const input = el.querySelector('input');
331
+ if (!input) return;
47
332
 
333
+ const handler = (e) => {
334
+ // Tab s prázdným inputem: nastav hodnotu před tím, než AG Grid zpracuje Tab
335
+ if (e.key === 'Tab') {
336
+ const text = inputTextRef.current || '';
337
+ if (!text.trim() && (pendingValueRef.current !== null || initialText)) {
338
+ const cleared = { id: null, text: '' };
339
+ pendingValueRef.current = cleared;
340
+ onValueChangeRef.current?.(cleared);
341
+ }
342
+ return; // Tab navigaci necháme AG Gridu
343
+ }
344
+
345
+ if (e.key !== 'Enter') return;
346
+
347
+ // Pokud je v dropdown označená položka šipkou, ručně ji vybereme
348
+ const activeOptionEl = document.querySelector('.ant-select-item-option-active');
349
+ if (activeOptionEl) {
350
+ e.stopImmediatePropagation();
351
+ e.preventDefault();
352
+ const labelText = activeOptionEl.querySelector('.ant-select-item-option-content')?.textContent?.trim();
353
+ if (labelText) {
354
+ const matched = suggestionsRef.current.find((s) => s.label === labelText);
355
+ if (matched) {
356
+ handleAutoCompleteSelectRef.current?.(matched.value, matched);
357
+ return;
358
+ }
359
+ }
360
+ return;
361
+ }
362
+
363
+ const text = inputTextRef.current || '';
364
+ // Prázdný input bez předchozí hodnoty → nechat AG Grid zpracovat (cancel)
365
+ if (!text.trim() && pendingValueRef.current === null && !initialText) return;
366
+ e.stopImmediatePropagation();
367
+ e.preventDefault();
368
+ currentTextRef.current = text;
369
+ handleFreeTextCommit(text);
370
+ };
371
+
372
+ input.addEventListener('keydown', handler, true); // capture = před rc-select
373
+ return () => input.removeEventListener('keydown', handler, true);
374
+ }, [allowFreeText, handleFreeTextCommit]);
375
+
376
+ // ─── Sdílený katalog modal (allItems = stejná kešovaná data) ─────────────────
377
+ const catalogModalContent = (
378
+ <DraggableModal
379
+ open={catalogModalOpen}
380
+ title={moduleDefinition?.modalTitle || `Vybrat z modulu: ${moduleDefinition?.moduleName}`}
381
+ width={moduleDefinition?.modalWidth || 800}
382
+ onCancel={() => {
383
+ setCatalogModalOpen(false);
384
+ // Pokud uživatel zavřel modal bez výběru a text ještě nebyl commitnutý, commitni ho
385
+ if (allowFreeText && inputTextRef.current && pendingValueRef.current === null) {
386
+ setTimeout(() => handleFreeTextCommit(inputTextRef.current), 0);
387
+ }
388
+ }}
389
+ maskClosable={false}
390
+ getContainer={() => document.body}
391
+ zIndex={99999999}
392
+ footer={null}
393
+ >
394
+ {allItemsLoading ? (
395
+ <div style={{ padding: 24, textAlign: 'center' }}>Načítání...</div>
396
+ ) : (
397
+ <div className="ag-theme-alpine" style={{ height: 400, width: '100%' }}>
398
+ <AgGridReact
399
+ columnDefs={moduleDefinition?.columnDefs || []}
400
+ rowData={allItems}
401
+ onRowDoubleClicked={handleCatalogModalSelect}
402
+ />
403
+ </div>
404
+ )}
405
+ </DraggableModal>
406
+ );
407
+
408
+ // ─── Render: catalog-only mód ─────────────────────────────────────────────────
409
+ if (!allowFreeText) {
410
+ const vf = moduleDefinition?.valueField || 'id';
411
+ const selectOptions = allItems.map(item => ({
412
+ value: item[vf],
413
+ label: moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || String(item[vf]),
414
+ }));
415
+
416
+ return (
417
+ <div style={{ width: '100%', minWidth: 250, padding: 4, borderRadius: 0, background: '#fff', boxShadow: '0 2px 8px rgba(0,0,0,0.15)' }}>
418
+ <div style={{ display: 'flex', gap: 4 }}>
419
+ <Select
420
+ style={{ flex: 1 }}
421
+ value={catalogCurrentId}
422
+ options={selectOptions}
423
+ loading={allItemsLoading}
424
+ showSearch
425
+ filterOption={(input, option) =>
426
+ String(option?.label || '').toLowerCase().includes(input.toLowerCase())
427
+ }
428
+ onChange={handleCatalogSelectChange}
429
+ getPopupContainer={() => document.body}
430
+ dropdownStyle={{ zIndex: 9999 }}
431
+ placeholder={moduleDefinition?.placeholder || 'Vyberte...'}
432
+ autoFocus
433
+ />
434
+ <Button icon={<SearchOutlined />} onMouseDown={e => e.preventDefault()} onClick={() => setCatalogModalOpen(true)} type="primary" />
435
+ </div>
436
+ {catalogModalContent}
437
+ </div>
438
+ );
439
+ }
440
+
441
+ // ─── Render: free-text mód ────────────────────────────────────────────────────
48
442
  return (
49
- <div style={{ width: '100%', minWidth: 200 }}>
50
- <ModuleDropdownList
51
- moduleDefinition={moduleDefinition}
52
- value={currentId}
53
- onChange={handleChange}
54
- displayMode="full"
443
+ <div style={{ width: '100%', minWidth: 250, padding: 4, borderRadius: 0, background: '#fff', boxShadow: '0 2px 8px rgba(0,0,0,0.15)' }}>
444
+ <div ref={freeTextWrapperRef} style={{ display: 'flex', gap: 4 }}>
445
+ <AutoComplete
446
+ style={{ flex: 1 }}
447
+ value={inputText}
448
+ options={suggestions}
449
+ open={dropdownOpen && suggestions.length > 0}
450
+ defaultActiveFirstOption={false}
451
+ allowClear
452
+ onChange={handleInputChange}
453
+ onClear={handleClear}
454
+ onSelect={handleAutoCompleteSelect}
455
+ onFocus={() => setDropdownOpen(true)}
456
+ onBlur={() => {
457
+ setTimeout(() => setDropdownOpen(false), 150);
458
+ handleBlur();
459
+ }}
460
+ notFoundContent={allItemsLoading ? 'Načítání...' : null}
461
+ placeholder={moduleDefinition?.placeholder || 'Zadejte nebo vyberte...'}
462
+ autoFocus
463
+ />
464
+ <Button
465
+ icon={<SearchOutlined />}
466
+ onMouseDown={e => e.preventDefault()}
467
+ onClick={() => {
468
+ catalogModalOpenRef.current = true; // synchronně před blur eventem
469
+ setCatalogModalOpen(true);
470
+ }}
471
+ type="primary"
472
+ />
473
+ </div>
474
+
475
+ {catalogModalContent}
476
+
477
+ {/* Multi-match modal — zobrazí se když text odpovídá více produktům */}
478
+ <DraggableModal
479
+ open={multiMatchModalOpen}
480
+ title="Nalezeno více shod — vyberte produkt"
481
+ width={moduleDefinition?.modalWidth || 800}
482
+ onCancel={() => setMultiMatchModalOpen(false)}
483
+ maskClosable={false}
55
484
  getContainer={() => document.body}
56
- style={{ width: '100%' }}
57
- />
485
+ zIndex={99999999}
486
+ footer={null}
487
+ >
488
+ <div className="ag-theme-alpine" style={{ height: 400, width: '100%' }}>
489
+ <AgGridReact
490
+ columnDefs={moduleDefinition?.columnDefs || []}
491
+ rowData={multiMatchData}
492
+ onRowDoubleClicked={handleMultiMatchSelect}
493
+ />
494
+ </div>
495
+ </DraggableModal>
58
496
  </div>
59
497
  );
60
498
  });
@@ -1,15 +1,35 @@
1
1
  /* eslint-disable */
2
2
  import * as React from 'react';
3
+ import { LinkOutlined, EditOutlined } from '@ant-design/icons';
3
4
  import { createMemoComparison } from '@bit.rhplus/react-memo';
4
5
 
5
6
  function ModuleLookupRenderer(props) {
6
7
  const { value, colDef: { cellRendererParams = {} } = {} } = props;
7
8
  const { getDisplayValue } = cellRendererParams;
8
9
 
9
- const displayText = React.useMemo(() => {
10
- if (!value) return '';
11
- if (getDisplayValue) return getDisplayValue(value);
12
- return value.code || value.name || '';
10
+ const { displayText, icon } = React.useMemo(() => {
11
+ if (!value) return { displayText: '', icon: null };
12
+
13
+ // Compound hodnota { id, text } z free-text / allowFreeText módu
14
+ if (typeof value === 'object' && 'text' in value) {
15
+ const text = value.text || '';
16
+ const hasLink = !!value.id;
17
+ return {
18
+ displayText: text,
19
+ icon: text
20
+ ? (hasLink
21
+ ? <LinkOutlined style={{ color: '#52c41a', marginLeft: 4, flexShrink: 0 }} />
22
+ : <EditOutlined style={{ color: '#faad14', marginLeft: 4, flexShrink: 0 }} />)
23
+ : null,
24
+ };
25
+ }
26
+
27
+ // Přímý string
28
+ if (typeof value === 'string') return { displayText: value, icon: null };
29
+
30
+ // Katalogový objekt (původní chování)
31
+ const text = getDisplayValue ? getDisplayValue(value) : (value.code || value.name || '');
32
+ return { displayText: text, icon: null };
13
33
  }, [value, getDisplayValue]);
14
34
 
15
35
  if (!displayText) return null;
@@ -19,10 +39,12 @@ function ModuleLookupRenderer(props) {
19
39
  overflow: 'hidden',
20
40
  textOverflow: 'ellipsis',
21
41
  whiteSpace: 'nowrap',
22
- display: 'block',
42
+ display: 'flex',
43
+ alignItems: 'center',
23
44
  lineHeight: 'inherit',
24
45
  }}>
25
- {displayText}
46
+ <span style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>{displayText}</span>
47
+ {icon}
26
48
  </span>
27
49
  );
28
50
  }
@@ -1,8 +1,18 @@
1
1
  export default ModuleLookupEditor;
2
2
  /**
3
- * ModuleLookupEditor - AG Grid cell editor s ModuleDropdownList
4
- * Zobrazí Select dropdown + tlačítko pro modální vyhledávání
5
- * Při výběru položky ukončí editaci a vrátí celý objekt
3
+ * ModuleLookupEditor AG Grid cell editor
4
+ *
5
+ * Dva módy:
6
+ * - allowFreeText=false (výchozí): Select s plným seznamem + search modal
7
+ * - allowFreeText=true: AutoComplete s lokálním filtrováním + volný text + async validace
8
+ *
9
+ * Data se načtou jednou přes TanStack Query (cache key: [moduleName, 'lookup']).
10
+ * Filtrování probíhá lokálně — žádné API volání při každém stisku klávesy.
11
+ *
12
+ * Free-text flow (Enter / blur):
13
+ * 0 shod → { id: null, text } + ikona ✏️
14
+ * 1 shoda → auto-výběr + ikona 🔗
15
+ * 2+ shody → multi-match modal → uživatel vybere → 🔗
6
16
  */
7
17
  declare const ModuleLookupEditor: React.ForwardRefExoticComponent<React.RefAttributes<any>>;
8
18
  import React from 'react';
@@ -1,42 +1,391 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /* eslint-disable */
3
- import React, { useState } from 'react';
3
+ import React, { useState, useEffect, useRef, useCallback } from 'react';
4
4
  import { useGridCellEditor } from 'ag-grid-react';
5
- import ModuleDropdownList from '@bit.rhplus/ui2.module-dropdown-list';
5
+ import { AgGridReact } from 'ag-grid-react';
6
+ import AutoComplete from 'antd/es/auto-complete';
7
+ import Select from 'antd/es/select';
8
+ import Button from 'antd/es/button';
9
+ import { SearchOutlined } from '@ant-design/icons';
10
+ import DraggableModal from '@bit.rhplus/draggable-modal';
11
+ import useData from '@bit.rhplus/data';
12
+ import { useOidcAccessToken } from '@axa-fr/react-oidc';
13
+ // Module-level cache — přetrvává po dobu session, sdílí se napříč instancemi editoru
14
+ const _lookupCache = {};
15
+ // ─── Module-level ochrana proti AG Grid outside-click detekci ─────────────────
16
+ // Registruje se při načtení modulu — PŘED mountem AG Gridu, takže v capture fázi
17
+ // poběží dříve než AG Grid's handler (který se registruje při startu editace).
18
+ let _editorMounted = false;
19
+ let _editorModalOpen = false;
20
+ document.addEventListener('mousedown', (e) => {
21
+ if (!_editorMounted)
22
+ return;
23
+ if (e.target.closest?.('.ant-select-dropdown')) {
24
+ e.preventDefault(); // zachová focus na inputu → input se neodbluruje → handleFreeTextCommit se nezavolá před onSelect
25
+ e.stopImmediatePropagation();
26
+ return;
27
+ }
28
+ if (_editorModalOpen && e.target.closest?.('.ant-modal-wrap')) {
29
+ e.stopImmediatePropagation();
30
+ }
31
+ }, true);
32
+ document.addEventListener('focusin', (e) => {
33
+ if (!_editorMounted)
34
+ return;
35
+ const target = e.target;
36
+ if (target.closest?.('.ant-select-dropdown') ||
37
+ (_editorModalOpen && target.closest?.('.ant-modal-wrap'))) {
38
+ e.stopImmediatePropagation();
39
+ }
40
+ }, true);
6
41
  /**
7
- * ModuleLookupEditor - AG Grid cell editor s ModuleDropdownList
8
- * Zobrazí Select dropdown + tlačítko pro modální vyhledávání
9
- * Při výběru položky ukončí editaci a vrátí celý objekt
42
+ * ModuleLookupEditor AG Grid cell editor
43
+ *
44
+ * Dva módy:
45
+ * - allowFreeText=false (výchozí): Select s plným seznamem + search modal
46
+ * - allowFreeText=true: AutoComplete s lokálním filtrováním + volný text + async validace
47
+ *
48
+ * Data se načtou jednou přes TanStack Query (cache key: [moduleName, 'lookup']).
49
+ * Filtrování probíhá lokálně — žádné API volání při každém stisku klávesy.
50
+ *
51
+ * Free-text flow (Enter / blur):
52
+ * 0 shod → { id: null, text } + ikona ✏️
53
+ * 1 shoda → auto-výběr + ikona 🔗
54
+ * 2+ shody → multi-match modal → uživatel vybere → 🔗
10
55
  */
11
- const ModuleLookupEditor = React.forwardRef(({ value, onValueChange, stopEditing, moduleDefinition, }, ref) => {
12
- const [selectedValue, setSelectedValue] = useState(value);
13
- // Expose getValue method to AG Grid
14
- React.useImperativeHandle(ref, () => ({
15
- getValue: () => selectedValue,
16
- }));
17
- // Zrušit editaci pokud se hodnota nezměnila
56
+ const ModuleLookupEditor = React.forwardRef(({ value, onValueChange, stopEditing, moduleDefinition, allowFreeText = false, }, _ref) => {
57
+ // ─── Hooks (vždy voláno) ──────────────────────────────────────────────────────
58
+ const { fetchDataUIAsync } = useData();
59
+ const { accessToken } = useOidcAccessToken();
60
+ // ─── Module-level cache: načtení položek jednou per moduleName ──────────────
61
+ const moduleName = moduleDefinition?.moduleName;
62
+ const [allItems, setAllItems] = useState(() => _lookupCache[moduleName] || []);
63
+ const [allItemsLoading, setAllItemsLoading] = useState(!_lookupCache[moduleName]);
64
+ useEffect(() => {
65
+ if (!moduleName || !moduleDefinition)
66
+ return;
67
+ if (_lookupCache[moduleName]) {
68
+ setAllItems(_lookupCache[moduleName]);
69
+ setAllItemsLoading(false);
70
+ return;
71
+ }
72
+ setAllItemsLoading(true);
73
+ moduleDefinition.fetchData('', fetchDataUIAsync, accessToken)
74
+ .then(data => {
75
+ const items = Array.isArray(data) ? data : [];
76
+ _lookupCache[moduleName] = items;
77
+ setAllItems(items);
78
+ })
79
+ .catch(() => setAllItems([]))
80
+ .finally(() => setAllItemsLoading(false));
81
+ }, []); // jen při mount
82
+ // ─── Sdílený stav: catalog modal ─────────────────────────────────────────────
83
+ const [catalogModalOpen, setCatalogModalOpen] = useState(false);
84
+ // ─── Catalog-only stav ───────────────────────────────────────────────────────
85
+ const [catalogSelected, setCatalogSelected] = useState(allowFreeText ? null : value);
86
+ // ─── Free-text stav ──────────────────────────────────────────────────────────
87
+ const initialText = React.useMemo(() => {
88
+ if (!allowFreeText)
89
+ return '';
90
+ if (value && typeof value === 'object')
91
+ return value.text || '';
92
+ if (typeof value === 'string')
93
+ return value;
94
+ return '';
95
+ }, []); // jen při mount
96
+ const [inputText, setInputText] = useState(initialText);
97
+ const [dropdownOpen, setDropdownOpen] = useState(false);
98
+ const [multiMatchData, setMultiMatchData] = useState([]);
99
+ const [multiMatchModalOpen, setMultiMatchModalOpen] = useState(false);
100
+ const catalogModalOpenRef = useRef(false);
101
+ catalogModalOpenRef.current = catalogModalOpen;
102
+ const multiMatchModalOpenRef = useRef(false);
103
+ multiMatchModalOpenRef.current = multiMatchModalOpen;
104
+ const currentTextRef = useRef(initialText);
105
+ const inputTextRef = useRef(initialText); // vždy aktuální inputText pro native handler
106
+ const freeTextWrapperRef = useRef(null); // ref na wrapper div → querySelector('input')
107
+ const isStoppedRef = useRef(false);
108
+ const justSelectedRef = useRef(false);
109
+ // Nastaven synchronně před každým stopEditing() voláním.
110
+ // isCancelAfterEnd: pokud je nastaven → uživatel explicitně potvrdil → nikdy nerušit commit.
111
+ const pendingValueRef = useRef(null);
112
+ // Stabilní ref na onValueChange pro použití v native event handlerech (mimo React deps)
113
+ const onValueChangeRef = useRef(onValueChange);
114
+ useEffect(() => { onValueChangeRef.current = onValueChange; });
115
+ // Udržuj inputTextRef synchronizovaný s každým renderem
116
+ inputTextRef.current = inputText;
117
+ // Ref na suggestions a handleAutoCompleteSelect — přístupné v capture handleru bez stale closure
118
+ const suggestionsRef = useRef([]);
119
+ const handleAutoCompleteSelectRef = useRef(null);
120
+ // ─── Lokální filtrování návrhů (bez API volání) ───────────────────────────────
121
+ const suggestions = React.useMemo(() => {
122
+ const vf = moduleDefinition?.valueField || 'id';
123
+ const source = (!inputText || !inputText.trim())
124
+ ? allItems
125
+ : allItems.filter(item => {
126
+ const label = moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || '';
127
+ return label.toLowerCase().includes(inputText.toLowerCase());
128
+ });
129
+ return source.slice(0, 15).map(item => ({
130
+ value: String(item[vf]),
131
+ label: moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || '',
132
+ item,
133
+ }));
134
+ }, [allItems, inputText, moduleDefinition]);
135
+ suggestionsRef.current = suggestions;
136
+ // ─── AG Grid isCancelAfterEnd ─────────────────────────────────────────────────
137
+ // Poznámka: AG Grid 35 používá CellEditorCompProxy.getValue() (vrací compProxy.value aktualizované
138
+ // přes onValueChange prop), nikoli useImperativeHandle ref. useImperativeHandle zde není potřeba.
18
139
  useGridCellEditor({
19
- isCancelAfterEnd: () => !selectedValue || selectedValue === value,
140
+ isCancelAfterEnd: () => {
141
+ if (!allowFreeText) {
142
+ return !catalogSelected || catalogSelected === value;
143
+ }
144
+ const currentText = currentTextRef.current ?? '';
145
+ const originalText = typeof value === 'object' ? (value?.text || '') : (value || '');
146
+ const result = pendingValueRef.current !== null ? false : currentText === originalText;
147
+ console.log('[MLE] isCancelAfterEnd', { pendingValue: pendingValueRef.current, currentText, originalText, result });
148
+ return result;
149
+ },
20
150
  });
21
- // Extrahovat ID z objektu pro ModuleDropdownList
22
- const currentId = React.useMemo(() => {
23
- if (!value)
151
+ // ─── Sync module-level flags pro ochranu před AG Grid outside-click detekcí ──
152
+ useEffect(() => {
153
+ _editorMounted = true;
154
+ return () => { _editorMounted = false; };
155
+ }, []);
156
+ useEffect(() => {
157
+ _editorModalOpen = catalogModalOpen || multiMatchModalOpen;
158
+ }, [catalogModalOpen, multiMatchModalOpen]);
159
+ // ─── Catalog-only: výběr ze Select ──────────────────────────────────────────
160
+ const handleCatalogSelectChange = useCallback((selectedId) => {
161
+ const vf = moduleDefinition?.valueField || 'id';
162
+ const item = allItems.find(i => String(i[vf]) === String(selectedId));
163
+ if (!item)
164
+ return;
165
+ setCatalogSelected(item);
166
+ if (onValueChange)
167
+ onValueChange(item);
168
+ setTimeout(() => stopEditing(), 0);
169
+ }, [allItems, moduleDefinition, onValueChange, stopEditing]);
170
+ const catalogCurrentId = React.useMemo(() => {
171
+ if (allowFreeText || !value)
24
172
  return null;
25
- if (typeof value === 'object') {
26
- return value[moduleDefinition?.valueField || 'id'];
27
- }
173
+ const vf = moduleDefinition?.valueField || 'id';
174
+ if (typeof value === 'object')
175
+ return value[vf];
28
176
  return value;
29
- }, [value, moduleDefinition]);
30
- const handleChange = (id, fullObject) => {
31
- setSelectedValue(fullObject);
32
- if (onValueChange) {
33
- onValueChange(fullObject);
34
- }
35
- setTimeout(() => {
36
- stopEditing();
37
- }, 0);
38
- };
39
- return (_jsx("div", { style: { width: '100%', minWidth: 200 }, children: _jsx(ModuleDropdownList, { moduleDefinition: moduleDefinition, value: currentId, onChange: handleChange, displayMode: "full", getContainer: () => document.body, style: { width: '100%' } }) }));
177
+ }, [value, moduleDefinition, allowFreeText]);
178
+ // ─── Shared: výběr z katalogu modal ─────────────────────────────────────────
179
+ const handleCatalogModalSelect = useCallback((params) => {
180
+ if (!params.data)
181
+ return;
182
+ console.log('[MLE] handleCatalogModalSelect', params.data);
183
+ const item = params.data;
184
+ const vf = moduleDefinition?.valueField || 'id';
185
+ const displayText = moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || '';
186
+ justSelectedRef.current = true; // zabrání handleBlur → handleFreeTextCommit při unmount inputu
187
+ if (allowFreeText) {
188
+ const selected = { id: item[vf], text: displayText, _catalogItem: item };
189
+ pendingValueRef.current = selected;
190
+ if (onValueChange)
191
+ onValueChange(selected);
192
+ }
193
+ else {
194
+ setCatalogSelected(item);
195
+ if (onValueChange)
196
+ onValueChange(item);
197
+ }
198
+ setCatalogModalOpen(false);
199
+ setTimeout(() => stopEditing(), 0);
200
+ }, [allowFreeText, moduleDefinition, onValueChange, stopEditing]);
201
+ // ─── Free-text: clear button (X) ────────────────────────────────────────────
202
+ const handleClear = useCallback(() => {
203
+ setInputText('');
204
+ currentTextRef.current = '';
205
+ const cleared = { id: null, text: '' };
206
+ pendingValueRef.current = cleared;
207
+ if (onValueChange)
208
+ onValueChange(cleared);
209
+ // editor zůstane otevřený — uživatel může psát novou hodnotu
210
+ }, [onValueChange]);
211
+ // ─── Free-text: změna textu (lokální filtrování, bez API) ────────────────────
212
+ const handleInputChange = useCallback((text) => {
213
+ setInputText(text);
214
+ currentTextRef.current = text;
215
+ }, []);
216
+ // ─── Free-text: výběr návrhu z AutoComplete ───────────────────────────────────
217
+ const handleAutoCompleteSelect = useCallback((optionValue, option) => {
218
+ console.log('[MLE] handleAutoCompleteSelect', optionValue);
219
+ justSelectedRef.current = true;
220
+ const item = option.item;
221
+ const vf = moduleDefinition?.valueField || 'id';
222
+ const displayText = moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || '';
223
+ const selected = { id: item[vf], text: displayText, _catalogItem: item };
224
+ pendingValueRef.current = selected;
225
+ if (onValueChange)
226
+ onValueChange(selected);
227
+ setTimeout(() => stopEditing(), 0);
228
+ }, [moduleDefinition, onValueChange, stopEditing]);
229
+ handleAutoCompleteSelectRef.current = handleAutoCompleteSelect;
230
+ // ─── Free-text: validace textu po Enter / blur ────────────────────────────────
231
+ const handleFreeTextCommit = useCallback(async (text) => {
232
+ console.log('[MLE] handleFreeTextCommit', text, 'pendingValue:', pendingValueRef.current);
233
+ if (!text || !text.trim()) {
234
+ const cleared = { id: null, text: '' };
235
+ pendingValueRef.current = cleared;
236
+ if (onValueChange)
237
+ onValueChange(cleared);
238
+ if (!isStoppedRef.current)
239
+ stopEditing();
240
+ return;
241
+ }
242
+ // Nejprve hledáme v již načtených datech (lokální shoda)
243
+ const searchLower = text.trim().toLowerCase();
244
+ const vf = moduleDefinition?.valueField || 'id';
245
+ const localMatches = allItems.filter(item => {
246
+ const label = moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || '';
247
+ return label.toLowerCase() === searchLower;
248
+ });
249
+ if (isStoppedRef.current)
250
+ return;
251
+ if (localMatches.length === 0) {
252
+ const selected = { id: null, text: text.trim() };
253
+ pendingValueRef.current = selected;
254
+ if (onValueChange)
255
+ onValueChange(selected);
256
+ setTimeout(() => stopEditing(), 0);
257
+ }
258
+ else if (localMatches.length === 1) {
259
+ const item = localMatches[0];
260
+ const displayText = moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || text.trim();
261
+ const selected = { id: item[vf], text: displayText, _catalogItem: item };
262
+ pendingValueRef.current = selected;
263
+ if (onValueChange)
264
+ onValueChange(selected);
265
+ setTimeout(() => stopEditing(), 0);
266
+ }
267
+ else {
268
+ setMultiMatchData(localMatches);
269
+ setMultiMatchModalOpen(true);
270
+ }
271
+ }, [allItems, moduleDefinition, stopEditing, onValueChange]);
272
+ // ─── Free-text: blur ──────────────────────────────────────────────────────────
273
+ const handleBlur = useCallback(() => {
274
+ console.log('[MLE] handleBlur', {
275
+ justSelected: justSelectedRef.current,
276
+ pendingValue: pendingValueRef.current,
277
+ currentText: currentTextRef.current,
278
+ catalogOpen: catalogModalOpenRef.current,
279
+ multiMatchOpen: multiMatchModalOpenRef.current,
280
+ });
281
+ if (justSelectedRef.current) {
282
+ justSelectedRef.current = false;
283
+ return;
284
+ }
285
+ // Pokud už byla hodnota commitnuta (katalog / autocomplete), neoverwritovat
286
+ if (pendingValueRef.current !== null)
287
+ return;
288
+ // Refy místo state — vždy aktuální hodnota, bez stale closure problémů
289
+ if (currentTextRef.current && !multiMatchModalOpenRef.current && !catalogModalOpenRef.current) {
290
+ handleFreeTextCommit(currentTextRef.current);
291
+ }
292
+ }, [handleFreeTextCommit]);
293
+ // ─── Free-text: výběr z multi-match modalu ────────────────────────────────────
294
+ const handleMultiMatchSelect = useCallback((params) => {
295
+ if (!params.data)
296
+ return;
297
+ const item = params.data;
298
+ const vf = moduleDefinition?.valueField || 'id';
299
+ const displayText = moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || '';
300
+ justSelectedRef.current = true; // zabrání handleBlur → handleFreeTextCommit při unmount inputu
301
+ const selected = { id: item[vf], text: displayText, _catalogItem: item };
302
+ pendingValueRef.current = selected;
303
+ setMultiMatchModalOpen(false);
304
+ if (onValueChange)
305
+ onValueChange(selected);
306
+ setTimeout(() => stopEditing(), 0);
307
+ }, [moduleDefinition, onValueChange, stopEditing]);
308
+ // ─── Cleanup ──────────────────────────────────────────────────────────────────
309
+ useEffect(() => {
310
+ return () => { isStoppedRef.current = true; };
311
+ }, []);
312
+ // ─── Native capture Enter handler ────────────────────────────────────────────
313
+ // rc-select volá stopPropagation() na Enter v bubble fázi → náš React onKeyDown
314
+ // na wrapperu ho nikdy nedostane. Capture-phase native listener se spustí jako první.
315
+ useEffect(() => {
316
+ if (!allowFreeText)
317
+ return;
318
+ const el = freeTextWrapperRef.current;
319
+ if (!el)
320
+ return;
321
+ const input = el.querySelector('input');
322
+ if (!input)
323
+ return;
324
+ const handler = (e) => {
325
+ // Tab s prázdným inputem: nastav hodnotu před tím, než AG Grid zpracuje Tab
326
+ if (e.key === 'Tab') {
327
+ const text = inputTextRef.current || '';
328
+ if (!text.trim() && (pendingValueRef.current !== null || initialText)) {
329
+ const cleared = { id: null, text: '' };
330
+ pendingValueRef.current = cleared;
331
+ onValueChangeRef.current?.(cleared);
332
+ }
333
+ return; // Tab navigaci necháme AG Gridu
334
+ }
335
+ if (e.key !== 'Enter')
336
+ return;
337
+ // Pokud je v dropdown označená položka šipkou, ručně ji vybereme
338
+ const activeOptionEl = document.querySelector('.ant-select-item-option-active');
339
+ if (activeOptionEl) {
340
+ e.stopImmediatePropagation();
341
+ e.preventDefault();
342
+ const labelText = activeOptionEl.querySelector('.ant-select-item-option-content')?.textContent?.trim();
343
+ if (labelText) {
344
+ const matched = suggestionsRef.current.find((s) => s.label === labelText);
345
+ if (matched) {
346
+ handleAutoCompleteSelectRef.current?.(matched.value, matched);
347
+ return;
348
+ }
349
+ }
350
+ return;
351
+ }
352
+ const text = inputTextRef.current || '';
353
+ // Prázdný input bez předchozí hodnoty → nechat AG Grid zpracovat (cancel)
354
+ if (!text.trim() && pendingValueRef.current === null && !initialText)
355
+ return;
356
+ e.stopImmediatePropagation();
357
+ e.preventDefault();
358
+ currentTextRef.current = text;
359
+ handleFreeTextCommit(text);
360
+ };
361
+ input.addEventListener('keydown', handler, true); // capture = před rc-select
362
+ return () => input.removeEventListener('keydown', handler, true);
363
+ }, [allowFreeText, handleFreeTextCommit]);
364
+ // ─── Sdílený katalog modal (allItems = stejná kešovaná data) ─────────────────
365
+ const catalogModalContent = (_jsx(DraggableModal, { open: catalogModalOpen, title: moduleDefinition?.modalTitle || `Vybrat z modulu: ${moduleDefinition?.moduleName}`, width: moduleDefinition?.modalWidth || 800, onCancel: () => {
366
+ setCatalogModalOpen(false);
367
+ // Pokud uživatel zavřel modal bez výběru a text ještě nebyl commitnutý, commitni ho
368
+ if (allowFreeText && inputTextRef.current && pendingValueRef.current === null) {
369
+ setTimeout(() => handleFreeTextCommit(inputTextRef.current), 0);
370
+ }
371
+ }, maskClosable: false, getContainer: () => document.body, zIndex: 99999999, footer: null, children: allItemsLoading ? (_jsx("div", { style: { padding: 24, textAlign: 'center' }, children: "Na\u010D\u00EDt\u00E1n\u00ED..." })) : (_jsx("div", { className: "ag-theme-alpine", style: { height: 400, width: '100%' }, children: _jsx(AgGridReact, { columnDefs: moduleDefinition?.columnDefs || [], rowData: allItems, onRowDoubleClicked: handleCatalogModalSelect }) })) }));
372
+ // ─── Render: catalog-only mód ─────────────────────────────────────────────────
373
+ if (!allowFreeText) {
374
+ const vf = moduleDefinition?.valueField || 'id';
375
+ const selectOptions = allItems.map(item => ({
376
+ value: item[vf],
377
+ label: moduleDefinition?.getDisplayValue?.(item) || item.code || item.name || String(item[vf]),
378
+ }));
379
+ return (_jsxs("div", { style: { width: '100%', minWidth: 250, padding: 4, borderRadius: 0, background: '#fff', boxShadow: '0 2px 8px rgba(0,0,0,0.15)' }, children: [_jsxs("div", { style: { display: 'flex', gap: 4 }, children: [_jsx(Select, { style: { flex: 1 }, value: catalogCurrentId, options: selectOptions, loading: allItemsLoading, showSearch: true, filterOption: (input, option) => String(option?.label || '').toLowerCase().includes(input.toLowerCase()), onChange: handleCatalogSelectChange, getPopupContainer: () => document.body, dropdownStyle: { zIndex: 9999 }, placeholder: moduleDefinition?.placeholder || 'Vyberte...', autoFocus: true }), _jsx(Button, { icon: _jsx(SearchOutlined, {}), onMouseDown: e => e.preventDefault(), onClick: () => setCatalogModalOpen(true), type: "primary" })] }), catalogModalContent] }));
380
+ }
381
+ // ─── Render: free-text mód ────────────────────────────────────────────────────
382
+ return (_jsxs("div", { style: { width: '100%', minWidth: 250, padding: 4, borderRadius: 0, background: '#fff', boxShadow: '0 2px 8px rgba(0,0,0,0.15)' }, children: [_jsxs("div", { ref: freeTextWrapperRef, style: { display: 'flex', gap: 4 }, children: [_jsx(AutoComplete, { style: { flex: 1 }, value: inputText, options: suggestions, open: dropdownOpen && suggestions.length > 0, defaultActiveFirstOption: false, allowClear: true, onChange: handleInputChange, onClear: handleClear, onSelect: handleAutoCompleteSelect, onFocus: () => setDropdownOpen(true), onBlur: () => {
383
+ setTimeout(() => setDropdownOpen(false), 150);
384
+ handleBlur();
385
+ }, notFoundContent: allItemsLoading ? 'Načítání...' : null, placeholder: moduleDefinition?.placeholder || 'Zadejte nebo vyberte...', autoFocus: true }), _jsx(Button, { icon: _jsx(SearchOutlined, {}), onMouseDown: e => e.preventDefault(), onClick: () => {
386
+ catalogModalOpenRef.current = true; // synchronně před blur eventem
387
+ setCatalogModalOpen(true);
388
+ }, type: "primary" })] }), catalogModalContent, _jsx(DraggableModal, { open: multiMatchModalOpen, title: "Nalezeno v\u00EDce shod \u2014 vyberte produkt", width: moduleDefinition?.modalWidth || 800, onCancel: () => setMultiMatchModalOpen(false), maskClosable: false, getContainer: () => document.body, zIndex: 99999999, footer: null, children: _jsx("div", { className: "ag-theme-alpine", style: { height: 400, width: '100%' }, children: _jsx(AgGridReact, { columnDefs: moduleDefinition?.columnDefs || [], rowData: multiMatchData, onRowDoubleClicked: handleMultiMatchSelect }) }) })] }));
40
389
  });
41
390
  ModuleLookupEditor.displayName = 'ModuleLookupEditor';
42
391
  export default ModuleLookupEditor;
@@ -1 +1 @@
1
- {"version":3,"file":"ModuleLookupEditor.js","sourceRoot":"","sources":["../../Editors/ModuleLookupEditor.jsx"],"names":[],"mappings":";AAAA,oBAAoB;AACpB,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,kBAAkB,MAAM,sCAAsC,CAAC;AAEtE;;;;GAIG;AACH,MAAM,kBAAkB,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,EAC3C,KAAK,EACL,aAAa,EACb,WAAW,EACX,gBAAgB,GACjB,EAAE,GAAG,EAAE,EAAE;IACR,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE1D,oCAAoC;IACpC,KAAK,CAAC,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QACpC,QAAQ,EAAE,GAAG,EAAE,CAAC,aAAa;KAC9B,CAAC,CAAC,CAAC;IAEJ,4CAA4C;IAC5C,iBAAiB,CAAC;QAChB,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC,aAAa,IAAI,aAAa,KAAK,KAAK;KAClE,CAAC,CAAC;IAEH,iDAAiD;IACjD,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACnC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC,gBAAgB,EAAE,UAAU,IAAI,IAAI,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE9B,MAAM,YAAY,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,EAAE;QACtC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC7B,IAAI,aAAa,EAAE,CAAC;YAClB,aAAa,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;QACD,UAAU,CAAC,GAAG,EAAE;YACd,WAAW,EAAE,CAAC;QAChB,CAAC,EAAE,CAAC,CAAC,CAAC;IACR,CAAC,CAAC;IAEF,OAAO,CACL,cAAK,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,YAC1C,KAAC,kBAAkB,IACjB,gBAAgB,EAAE,gBAAgB,EAClC,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,YAAY,EACtB,WAAW,EAAC,MAAM,EAClB,YAAY,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,EACjC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GACxB,GACE,CACP,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,kBAAkB,CAAC,WAAW,GAAG,oBAAoB,CAAC;AAEtD,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"ModuleLookupEditor.js","sourceRoot":"","sources":["../../Editors/ModuleLookupEditor.jsx"],"names":[],"mappings":"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"}
@@ -1,26 +1,44 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /* eslint-disable */
3
3
  import * as React from 'react';
4
+ import { LinkOutlined, EditOutlined } from '@ant-design/icons';
4
5
  import { createMemoComparison } from '@bit.rhplus/react-memo';
5
6
  function ModuleLookupRenderer(props) {
6
7
  const { value, colDef: { cellRendererParams = {} } = {} } = props;
7
8
  const { getDisplayValue } = cellRendererParams;
8
- const displayText = React.useMemo(() => {
9
+ const { displayText, icon } = React.useMemo(() => {
9
10
  if (!value)
10
- return '';
11
- if (getDisplayValue)
12
- return getDisplayValue(value);
13
- return value.code || value.name || '';
11
+ return { displayText: '', icon: null };
12
+ // Compound hodnota { id, text } z free-text / allowFreeText módu
13
+ if (typeof value === 'object' && 'text' in value) {
14
+ const text = value.text || '';
15
+ const hasLink = !!value.id;
16
+ return {
17
+ displayText: text,
18
+ icon: text
19
+ ? (hasLink
20
+ ? _jsx(LinkOutlined, { style: { color: '#52c41a', marginLeft: 4, flexShrink: 0 } })
21
+ : _jsx(EditOutlined, { style: { color: '#faad14', marginLeft: 4, flexShrink: 0 } }))
22
+ : null,
23
+ };
24
+ }
25
+ // Přímý string
26
+ if (typeof value === 'string')
27
+ return { displayText: value, icon: null };
28
+ // Katalogový objekt (původní chování)
29
+ const text = getDisplayValue ? getDisplayValue(value) : (value.code || value.name || '');
30
+ return { displayText: text, icon: null };
14
31
  }, [value, getDisplayValue]);
15
32
  if (!displayText)
16
33
  return null;
17
- return (_jsx("span", { style: {
34
+ return (_jsxs("span", { style: {
18
35
  overflow: 'hidden',
19
36
  textOverflow: 'ellipsis',
20
37
  whiteSpace: 'nowrap',
21
- display: 'block',
38
+ display: 'flex',
39
+ alignItems: 'center',
22
40
  lineHeight: 'inherit',
23
- }, children: displayText }));
41
+ }, children: [_jsx("span", { style: { overflow: 'hidden', textOverflow: 'ellipsis' }, children: displayText }), icon] }));
24
42
  }
25
43
  ModuleLookupRenderer.displayName = 'ModuleLookupRenderer';
26
44
  const arePropsEqual = createMemoComparison(['value', 'data'], ['colDef'], false, 'ModuleLookupRenderer');
@@ -1 +1 @@
1
- {"version":3,"file":"ModuleLookupRenderer.js","sourceRoot":"","sources":["../../Renderers/ModuleLookupRenderer.jsx"],"names":[],"mappings":";AAAA,oBAAoB;AACpB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,SAAS,oBAAoB,CAAC,KAAK;IACjC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,kBAAkB,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC;IAClE,MAAM,EAAE,eAAe,EAAE,GAAG,kBAAkB,CAAC;IAE/C,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACrC,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;QACtB,IAAI,eAAe;YAAE,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QACnD,OAAO,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;IACxC,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC;IAE7B,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE9B,OAAO,CACL,eAAM,KAAK,EAAE;YACX,QAAQ,EAAE,QAAQ;YAClB,YAAY,EAAE,UAAU;YACxB,UAAU,EAAE,QAAQ;YACpB,OAAO,EAAE,OAAO;YAChB,UAAU,EAAE,SAAS;SACtB,YACE,WAAW,GACP,CACR,CAAC;AACJ,CAAC;AAED,oBAAoB,CAAC,WAAW,GAAG,sBAAsB,CAAC;AAE1D,MAAM,aAAa,GAAG,oBAAoB,CACxC,CAAC,OAAO,EAAE,MAAM,CAAC,EACjB,CAAC,QAAQ,CAAC,EACV,KAAK,EACL,sBAAsB,CACvB,CAAC;AAEF,eAAe,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,aAAa,CAAC,CAAC"}
1
+ {"version":3,"file":"ModuleLookupRenderer.js","sourceRoot":"","sources":["../../Renderers/ModuleLookupRenderer.jsx"],"names":[],"mappings":";AAAA,oBAAoB;AACpB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,SAAS,oBAAoB,CAAC,KAAK;IACjC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,kBAAkB,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC;IAClE,MAAM,EAAE,eAAe,EAAE,GAAG,kBAAkB,CAAC;IAE/C,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC/C,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAEnD,iEAAiE;QACjE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;YACjD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO;gBACL,WAAW,EAAE,IAAI;gBACjB,IAAI,EAAE,IAAI;oBACR,CAAC,CAAC,CAAC,OAAO;wBACN,CAAC,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAI;wBAC7E,CAAC,CAAC,KAAC,YAAY,IAAC,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,GAAI,CAAC;oBAClF,CAAC,CAAC,IAAI;aACT,CAAC;QACJ,CAAC;QAED,eAAe;QACf,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAEzE,sCAAsC;QACtC,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACzF,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC3C,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC;IAE7B,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAE9B,OAAO,CACL,gBAAM,KAAK,EAAE;YACX,QAAQ,EAAE,QAAQ;YAClB,YAAY,EAAE,UAAU;YACxB,UAAU,EAAE,QAAQ;YACpB,OAAO,EAAE,MAAM;YACf,UAAU,EAAE,QAAQ;YACpB,UAAU,EAAE,SAAS;SACtB,aACC,eAAM,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,YAAG,WAAW,GAAQ,EAClF,IAAI,IACA,CACR,CAAC;AACJ,CAAC;AAED,oBAAoB,CAAC,WAAW,GAAG,sBAAsB,CAAC;AAE1D,MAAM,aAAa,GAAG,oBAAoB,CACxC,CAAC,OAAO,EAAE,MAAM,CAAC,EACjB,CAAC,QAAQ,CAAC,EACV,KAAK,EACL,sBAAsB,CACvB,CAAC;AAEF,eAAe,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,aAAa,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bit.rhplus/ag-grid",
3
- "version": "0.0.116",
3
+ "version": "0.0.118",
4
4
  "homepage": "https://bit.cloud/remote-scope/ag-grid",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "remote-scope",
8
8
  "name": "ag-grid",
9
- "version": "0.0.116"
9
+ "version": "0.0.118"
10
10
  },
11
11
  "dependencies": {
12
12
  "moment": "^2.30.1",
@@ -20,16 +20,18 @@
20
20
  "dayjs": "^1.11.13",
21
21
  "styled-components": "^6.1.19",
22
22
  "lucide-react": "^0.503.0",
23
+ "@axa-fr/react-oidc": "7.25.13",
23
24
  "linq": "^4.0.3",
24
- "@bit.rhplus/ui.grid": "0.0.134",
25
- "@bit.rhplus/react-memo": "0.0.7",
26
- "@bit.rhplus/linq": "0.0.10",
27
- "@bit.rhplus/ui2.module-dropdown-list": "0.1.110",
28
- "@bit.rhplus/data": "0.0.87",
29
- "@bit.rhplus/ui.avatar": "0.0.18"
25
+ "@bit.rhplus/ui.grid": "0.0.136",
26
+ "@bit.rhplus/react-memo": "0.0.8",
27
+ "@bit.rhplus/linq": "0.0.11",
28
+ "@bit.rhplus/ui2.module-dropdown-list": "0.1.112",
29
+ "@bit.rhplus/data": "0.0.89",
30
+ "@bit.rhplus/draggable-modal": "0.0.17",
31
+ "@bit.rhplus/ui.avatar": "0.0.19"
30
32
  },
31
33
  "devDependencies": {
32
- "@bitdev/react.react-env": "4.0.14"
34
+ "@bitdev/react.react-env": "5.0.5"
33
35
  },
34
36
  "peerDependencies": {
35
37
  "react": "^17.0.0 || ^18.0.0 || ^19.0.0",