reneco-hierarchized-picker 0.4.3-beta.2 → 0.4.3-beta.20

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.
Files changed (37) hide show
  1. package/dist/cjs/loader.cjs.js +1 -1
  2. package/dist/cjs/reneco-hierarchized-picker.cjs.js +1 -1
  3. package/dist/cjs/reneco-hierarchized-picker_2.cjs.entry.js +452 -246
  4. package/dist/collection/components/hierarchized-picker/hierarchized-picker.css +42 -19
  5. package/dist/collection/components/hierarchized-picker/hierarchized-picker.js +324 -108
  6. package/dist/collection/components/search-input/search-input.css +13 -17
  7. package/dist/collection/components/search-input/search-input.js +2 -2
  8. package/dist/collection/components/treejs/index.js +50 -50
  9. package/dist/collection/core/options-manager.js +2 -0
  10. package/dist/collection/core/raw-data-manager.js +4 -0
  11. package/dist/collection/features/events/focus-handlers.js +15 -11
  12. package/dist/collection/features/keyboard-navigation/keyboard-navigation.js +93 -60
  13. package/dist/collection/features/tree/tree-utils.js +12 -3
  14. package/dist/collection/utils/conf-helper.js +4 -0
  15. package/dist/collection/utils/constants.js +11 -3
  16. package/dist/collection/utils/theme-utils.js +5 -1
  17. package/dist/custom-elements/index.js +452 -246
  18. package/dist/esm/loader.js +1 -1
  19. package/dist/esm/reneco-hierarchized-picker.js +1 -1
  20. package/dist/esm/reneco-hierarchized-picker_2.entry.js +452 -246
  21. package/dist/esm-es5/loader.js +1 -1
  22. package/dist/esm-es5/reneco-hierarchized-picker.js +1 -1
  23. package/dist/esm-es5/reneco-hierarchized-picker_2.entry.js +2 -2
  24. package/dist/reneco-hierarchized-picker/p-0df46cca.system.entry.js +3 -0
  25. package/dist/reneco-hierarchized-picker/p-73168a50.system.js +1 -1
  26. package/dist/reneco-hierarchized-picker/p-cc9ee330.entry.js +1 -0
  27. package/dist/reneco-hierarchized-picker/reneco-hierarchized-picker.esm.js +1 -1
  28. package/dist/types/components/hierarchized-picker/hierarchized-picker.d.ts +19 -2
  29. package/dist/types/components.d.ts +10 -0
  30. package/dist/types/core/options-manager.d.ts +1 -1
  31. package/dist/types/features/keyboard-navigation/keyboard-navigation.d.ts +3 -1
  32. package/dist/types/features/tree/tree-utils.d.ts +1 -1
  33. package/dist/types/utils/constants.d.ts +7 -0
  34. package/dist/types/utils/utils.d.ts +1 -0
  35. package/package.json +1 -1
  36. package/dist/reneco-hierarchized-picker/p-170e1b20.system.entry.js +0 -3
  37. package/dist/reneco-hierarchized-picker/p-763a27e0.entry.js +0 -1
@@ -78,14 +78,42 @@ export class HierarchizedPickerComponent {
78
78
  logError(messageToLog) {
79
79
  try {
80
80
  console.error('--- Hierarchized picker ' + this.componentID + ' ERROR ---', messageToLog);
81
+ this.lastErrorMessage = messageToLog;
81
82
  }
82
83
  catch (_a) {
83
- console.error('--- Hierarchized picker generic ERROR ---');
84
+ const genericErrorMessage = '--- Hierarchized picker generic ERROR ---';
85
+ this.lastErrorMessage = genericErrorMessage;
86
+ console.error(genericErrorMessage);
84
87
  }
88
+ this.errorRaised.emit(this.lastErrorMessage);
85
89
  }
86
90
  get theOptions() {
87
91
  return this.optionsManager.getOptions();
88
92
  }
93
+ diffKeys(obj1, obj2, prefix = '') {
94
+ const diffs = [];
95
+ const commonKeys = Object.keys(obj1 || {}).filter(key => obj2 && Object.prototype.hasOwnProperty.call(obj2, key));
96
+ for (const key of commonKeys) {
97
+ const fullKey = prefix ? `${prefix}.${key}` : key;
98
+ const val1 = obj1[key];
99
+ const val2 = obj2[key];
100
+ if (Array.isArray(val1) && Array.isArray(val2)) {
101
+ if (val1.length !== val2.length || val1.some((v, i) => v !== val2[i])) {
102
+ diffs.push(fullKey);
103
+ }
104
+ }
105
+ else if (val1 &&
106
+ val2 &&
107
+ typeof val1 === 'object' &&
108
+ typeof val2 === 'object') {
109
+ diffs.push(...this.diffKeys(val1, val2, fullKey));
110
+ }
111
+ else if (val1 !== val2) {
112
+ diffs.push(fullKey);
113
+ }
114
+ }
115
+ return diffs;
116
+ }
89
117
  async setNewOption(newValue, oldValue = null) {
90
118
  this.ready = false;
91
119
  // --------------------------------------- DEPRECATED ?
@@ -104,6 +132,7 @@ export class HierarchizedPickerComponent {
104
132
  // });
105
133
  // ---------------------------------------
106
134
  // this.theOptions = newValue;
135
+ const savedOldValue = Object.assign({}, this.theOptions);
107
136
  if (oldValue && JSON.stringify(newValue.options) == JSON.stringify(oldValue.options)) {
108
137
  this.ready = true;
109
138
  return;
@@ -112,6 +141,7 @@ export class HierarchizedPickerComponent {
112
141
  newValue = JSON.parse(newValue);
113
142
  if (typeof oldValue == 'string')
114
143
  oldValue = JSON.parse(oldValue);
144
+ this.value = [];
115
145
  this.optionsManager.updateOptions(newValue);
116
146
  this.setDisplayedValue(this.value);
117
147
  const originOrNodeIdAreDifferent = !oldValue || (newValue.origin != oldValue.origin || newValue.options.StartNodeID != oldValue.options.StartNodeID);
@@ -129,11 +159,29 @@ export class HierarchizedPickerComponent {
129
159
  if (oldValue && JSON.stringify(newValue.options) != JSON.stringify(oldValue.options)) {
130
160
  this.value = [];
131
161
  }
132
- if ((newValue === null || newValue === void 0 ? void 0 : newValue.loading) == 'display') {
162
+ console.log("Setnewoptions 01", newValue, oldValue);
163
+ if ((newValue === null || newValue === void 0 ? void 0 : newValue.loading) == 'display' || (newValue && !newValue.loading)) {
133
164
  if ((oldValue && this.isChangeInOptions(newValue, oldValue)) || !oldValue) {
134
- this.rawDataManager = new RawDataManager(this.getOptionsAsIConf(this.optionsManager.getOptions()).token, this.optionsManager);
135
- await this.loadHierarchizedPicker(true);
136
- this.displayWhenLoaded();
165
+ if (!oldValue) {
166
+ oldValue = savedOldValue;
167
+ }
168
+ console.log("Setnewoptions 02");
169
+ const propDiffs = this.diffKeys(oldValue, this.optionsManager.initializeOptions(newValue));
170
+ const noReloadProps = ["multiple"];
171
+ console.log("Setnewoptions 03", propDiffs);
172
+ if (propDiffs.length == 1 && propDiffs.some(item => noReloadProps.includes(item))) {
173
+ const propChanged = propDiffs[0];
174
+ switch (propChanged) {
175
+ case "multiple":
176
+ document.querySelectorAll('#tree-area-' + this.componentID + ' .treejs-checkbox').forEach((item) => (item.style.display = (this.theOptions.multiple ? 'inline-block' : 'none')));
177
+ break;
178
+ }
179
+ }
180
+ else {
181
+ this.rawDataManager = new RawDataManager(this.getOptionsAsIConf(this.optionsManager.getOptions()).token, this.optionsManager);
182
+ await this.loadHierarchizedPicker(true);
183
+ this.displayWhenLoaded();
184
+ }
137
185
  }
138
186
  else {
139
187
  this.ready = true;
@@ -187,7 +235,12 @@ export class HierarchizedPickerComponent {
187
235
  async filterTree(searchedValue) {
188
236
  this.search(searchedValue);
189
237
  }
238
+ async getError() {
239
+ return Promise.resolve(this.lastErrorMessage);
240
+ }
190
241
  constructor() {
242
+ this.modaleHeight = 200;
243
+ this.modalePosition = 'bottom';
191
244
  this.canload = true; // Determines wether the component may be loaded
192
245
  this.ready = false; // State to determine if all the elements of the component have been loaded
193
246
  this.searchToDisplay = 0; // Counter to trigger the research on proper time
@@ -195,30 +248,80 @@ export class HierarchizedPickerComponent {
195
248
  this.lastSearchMatchCounter = 0; // Counter of number of matches for last search
196
249
  this.setValueOnClick = true; // Tells wether we edit the picker value on click in the tree
197
250
  this.mylog = console.log; // Custom log function for debug purposes
251
+ this.lastErrorMessage = '';
252
+ this.scrollToNode = (targetNodeId = null, displayChildren = false) => {
253
+ var _a;
254
+ let scrollToValue = 0;
255
+ let removeClosedAndLookUp = (element, editScroll = false) => {
256
+ var _a, _b, _c, _d;
257
+ const nodeId = element === null || element === void 0 ? void 0 : element.nodeId;
258
+ if (!element || !nodeId) {
259
+ return;
260
+ }
261
+ const node = this.loadedTreeJs.nodesById[nodeId];
262
+ if ((_b = (_a = node === null || node === void 0 ? void 0 : node.children) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.id) {
263
+ (_c = element.classList) === null || _c === void 0 ? void 0 : _c.remove('treejs-node__close');
264
+ }
265
+ if (editScroll) {
266
+ scrollToValue += element.offsetTop;
267
+ }
268
+ const parent = (_d = element.parentNode) === null || _d === void 0 ? void 0 : _d.closest('.treejs-node');
269
+ if (parent) {
270
+ removeClosedAndLookUp(parent, editScroll);
271
+ }
272
+ };
273
+ try {
274
+ if (targetNodeId) {
275
+ const targetNode = this.loadedTreeJs.liElementsById[targetNodeId];
276
+ if (targetNode) {
277
+ removeClosedAndLookUp(targetNode, true);
278
+ if (displayChildren && targetNode.classList.contains('treejs-node__close')) {
279
+ const leftSwitcher = targetNode.querySelector('.treejs-switcher');
280
+ if (leftSwitcher) {
281
+ (_a = this.loadedTreeJs) === null || _a === void 0 ? void 0 : _a.onSwitcherClick(leftSwitcher);
282
+ }
283
+ }
284
+ }
285
+ }
286
+ else {
287
+ const checkeds = document.querySelectorAll('#tree-area-' + this.componentID + ' .treejs-node__checked');
288
+ checkeds.forEach((item) => removeClosedAndLookUp(item, scrollToValue == 0));
289
+ }
290
+ }
291
+ catch (err) {
292
+ this.errorToLog = "Error in showSelectedNodes";
293
+ }
294
+ if (scrollToValue && this.scrollable) {
295
+ this.scrollable.scrollTop = scrollToValue;
296
+ }
297
+ };
198
298
  this.getShortenedFullpath = (realFullpath) => {
199
299
  var _a, _b, _c, _d;
200
300
  let toret = realFullpath;
201
- try {
202
- const property_nodeid = (this.optionsManager.getOptions().origin == 'classification' ? "startNode" : "StartNodeID");
203
- const property_value = this.optionsManager.getOptions().options[property_nodeid];
204
- if (property_value in ["0", 0])
205
- return toret;
206
- if (isNumeric(property_value)) {
207
- if (this.optionsManager.getOptions().origin == 'classification') {
208
- const { Translations, Properties } = this.rawDataManager.getData();
209
- const currentLanguage = this.optionsManager.getOptions().language;
210
- toret = ((_b = (_a = Translations[currentLanguage]) === null || _a === void 0 ? void 0 : _a.translated_name) !== null && _b !== void 0 ? _b : Properties === null || Properties === void 0 ? void 0 : Properties.System_Name) + realFullpath.replace(((_d = (_c = Translations[currentLanguage]) === null || _c === void 0 ? void 0 : _c.translated_fullpath) !== null && _d !== void 0 ? _d : Properties === null || Properties === void 0 ? void 0 : Properties.System_Fullpath), "");
211
- }
212
- else {
213
- const { fullpath, fullpathTranslated, title, valueTranslated } = this.rawDataManager.getData();
214
- toret = (valueTranslated !== null && valueTranslated !== void 0 ? valueTranslated : title) + realFullpath.replace((fullpathTranslated !== null && fullpathTranslated !== void 0 ? fullpathTranslated : fullpath), "");
301
+ const rdmdata = this.rawDataManager.getData();
302
+ if (rdmdata) {
303
+ try {
304
+ const property_nodeid = (this.optionsManager.getOptions().origin == 'classification' ? "startNode" : "StartNodeID");
305
+ const property_value = this.optionsManager.getOptions().options[property_nodeid];
306
+ if (property_value in ["0", 0])
307
+ return toret;
308
+ if (isNumeric(property_value)) {
309
+ if (this.optionsManager.getOptions().origin == 'classification') {
310
+ const { Translations, Properties } = rdmdata;
311
+ const currentLanguage = this.optionsManager.getOptions().language;
312
+ toret = ((_b = (_a = Translations[currentLanguage]) === null || _a === void 0 ? void 0 : _a.translated_name) !== null && _b !== void 0 ? _b : Properties === null || Properties === void 0 ? void 0 : Properties.System_Name) + realFullpath.replace(((_d = (_c = Translations[currentLanguage]) === null || _c === void 0 ? void 0 : _c.translated_fullpath) !== null && _d !== void 0 ? _d : Properties === null || Properties === void 0 ? void 0 : Properties.System_Fullpath), "");
313
+ }
314
+ else {
315
+ const { fullpath, fullpathTranslated, title, valueTranslated } = rdmdata;
316
+ toret = (valueTranslated !== null && valueTranslated !== void 0 ? valueTranslated : title) + realFullpath.replace((fullpathTranslated !== null && fullpathTranslated !== void 0 ? fullpathTranslated : fullpath), "");
317
+ }
215
318
  }
319
+ else
320
+ this.errorToLog = "Error in getFullpath : startnode is not number";
321
+ }
322
+ catch (error) {
323
+ this.errorToLog = "Error in getFullpath " + error.toString();
216
324
  }
217
- else
218
- this.errorToLog = "Error in getFullpath : startnode is not number";
219
- }
220
- catch (error) {
221
- this.errorToLog = "Error in getFullpath " + error.toString();
222
325
  }
223
326
  return toret;
224
327
  };
@@ -270,7 +373,6 @@ export class HierarchizedPickerComponent {
270
373
  }
271
374
  componentDidLoad() {
272
375
  this.mylog('----- componentDidLoad beginning -----');
273
- setupKeyboardNavigation(this);
274
376
  focusMainInput(this);
275
377
  }
276
378
  displayWhenLoaded() {
@@ -314,6 +416,8 @@ export class HierarchizedPickerComponent {
314
416
  this.optionsManager.getOptions().openTreeWhenLoaded = false;
315
417
  if (!this.optionsManager.getOptions().displayRootNode)
316
418
  this.optionsManager.getOptions().displayRootNode = false;
419
+ if (!this.optionsManager.getOptions().keyboardNavigation)
420
+ this.optionsManager.getOptions().keyboardNavigation = false;
317
421
  if (!this.optionsManager.getOptions().dragAndDropEnabled)
318
422
  this.optionsManager.getOptions().dragAndDropEnabled = false;
319
423
  if (!this.optionsManager.getOptions().defaultValueIsFullpath)
@@ -353,7 +457,7 @@ export class HierarchizedPickerComponent {
353
457
  this.optionsManager.getOptions().defaultValue = defaultFromFullpaths;
354
458
  }
355
459
  if (this.optionsManager.getOptions().options) {
356
- if (!this.optionsManager.getOptions().options.Reach && this.optionsManager.getOptions().defaultValue.length > 0) {
460
+ if (this.optionsManager.getOptions().defaultValue.length > 0) {
357
461
  if (autoAssignReach) {
358
462
  this.optionsManager.getOptions().options.Reach = this.optionsManager.getOptions().defaultValue.map(element => {
359
463
  return Number(element);
@@ -385,8 +489,13 @@ export class HierarchizedPickerComponent {
385
489
  // Setup component unique ID
386
490
  if (this.optionsManager.getOptions().id)
387
491
  this.componentID = this.optionsManager.getOptions().id;
388
- else if (!this.componentID)
389
- this.componentID = (Array.from(document.querySelectorAll('reneco-hierarchized-picker')).indexOf(this.el) + 1).toString();
492
+ else if (!this.componentID) {
493
+ let componentID = (Array.from(document.querySelectorAll('reneco-hierarchized-picker')).indexOf(this.el) + 1);
494
+ while (document.querySelectorAll(`#hierarchized-picker-${componentID}`).length > 0) {
495
+ componentID++;
496
+ }
497
+ this.componentID = componentID.toString();
498
+ }
390
499
  if (!this.optionsManager.getOptions())
391
500
  return;
392
501
  this.optionsManager.updateDefaultValue();
@@ -394,7 +503,9 @@ export class HierarchizedPickerComponent {
394
503
  this.canload = result.toret;
395
504
  this.errorToLog = result.errorToLog;
396
505
  await this.initComponent();
397
- applyPickerTheme(this.optionsManager.getOptions().theme, defaultPickerTheme);
506
+ let defaultPickerThemeForInit = defaultPickerTheme;
507
+ defaultPickerTheme.modale.height = this.modaleHeight + "px";
508
+ applyPickerTheme(this.optionsManager.getOptions().theme, defaultPickerThemeForInit);
398
509
  // Displays option values
399
510
  this.mylog(this.optionsManager.getOptions());
400
511
  window.addEventListener('click', (evt) => {
@@ -452,7 +563,7 @@ export class HierarchizedPickerComponent {
452
563
  this.ignoreOptionsChanges = false;
453
564
  }
454
565
  catch (_b) {
455
- console.error('Error loading webservice data!');
566
+ this.errorToLog = 'Error loading webservice data!';
456
567
  }
457
568
  }
458
569
  displayPickerError(errorMsg = '') {
@@ -464,11 +575,11 @@ export class HierarchizedPickerComponent {
464
575
  }
465
576
  this.displayedValue = errorMsg;
466
577
  this.isDisabled = true;
467
- errorMsg = this.errorToLog;
578
+ this.errorToLog = errorMsg;
468
579
  }
469
580
  }
470
581
  catch (_a) {
471
- console.error(errorMsg);
582
+ this.errorToLog = errorMsg;
472
583
  }
473
584
  }
474
585
  getApiSearchURL() {
@@ -488,17 +599,17 @@ export class HierarchizedPickerComponent {
488
599
  }
489
600
  }
490
601
  // TODO > Celine would rather like the context (thesaurus or position) to be extracted another way
491
- getContextualApiURL(init = false) {
492
- const { options, url } = this.optionsManager.getOptions();
602
+ getContextualApiURL(init = false, forcedOptions = null) {
603
+ const { options, url } = forcedOptions || this.optionsManager.getOptions();
493
604
  if (init && options.Reach) {
494
- // Use a base URL for relative paths
495
- const base = window.location.origin; // fallback for relative URLs
605
+ const base = window.location.origin;
496
606
  const parsedUrl = new URL(url, base);
497
- const pathSegments = parsedUrl.pathname.split('/');
498
- let dynamicType = pathSegments[pathSegments.length - 2];
499
- if (['thesaurus', 'position'].indexOf(dynamicType) == -1)
500
- dynamicType = pathSegments[pathSegments.length - 1];
501
- const newPathname = `/api/v1/classification/reach/${dynamicType}/${options.Reach}`;
607
+ const pathSegments = parsedUrl.pathname.split('/').filter(Boolean);
608
+ const idx = pathSegments.indexOf("getTree");
609
+ if (idx !== -1) {
610
+ pathSegments[idx] = "reach";
611
+ }
612
+ const newPathname = "/" + pathSegments.join("/");
502
613
  return `${parsedUrl.origin}${newPathname}`;
503
614
  }
504
615
  return url;
@@ -510,7 +621,6 @@ export class HierarchizedPickerComponent {
510
621
  if (!init)
511
622
  delete optionsToReturn.Reach;
512
623
  if (optionsToReturn.Reach) {
513
- delete optionsToReturn.Reach;
514
624
  if ("startNode" in optionsToReturn) {
515
625
  optionsToReturn.startingnode = optionsToReturn.startNode;
516
626
  delete optionsToReturn.startNode;
@@ -570,7 +680,7 @@ export class HierarchizedPickerComponent {
570
680
  }
571
681
  })
572
682
  .catch(err => {
573
- console.error('err', err);
683
+ this.errorToLog = err;
574
684
  });
575
685
  }
576
686
  else {
@@ -589,12 +699,12 @@ export class HierarchizedPickerComponent {
589
699
  }
590
700
  })
591
701
  .catch(error => {
592
- console.error("---- MY ERROR ---- ", error);
702
+ this.errorToLog = error;
593
703
  try {
594
704
  this.errorToLog = 'getDataFromSource 1 rejected:' + JSON.stringify(error, replacer, 2);
595
705
  }
596
706
  catch (_a) {
597
- console.error('getDataFromSource 2 rejected:', JSON.stringify(error, replacer, 2));
707
+ this.errorToLog = JSON.stringify(error, replacer, 2);
598
708
  }
599
709
  });
600
710
  }
@@ -675,9 +785,11 @@ export class HierarchizedPickerComponent {
675
785
  this.ignoreOptionsChanges = false;
676
786
  },
677
787
  });
678
- Object.values(myTree.liElementsById).forEach((el) => {
679
- el.classList.remove('treejs-node__searchmatch');
680
- });
788
+ if (this.searchResultData.length == 0) {
789
+ Object.values(myTree.liElementsById).forEach((el) => {
790
+ el.classList.remove('treejs-node__searchmatch');
791
+ });
792
+ }
681
793
  this.loadedTreeJs = myTree;
682
794
  this.collapseAllNodes();
683
795
  // TODO Make something that makes sense, this is a temporary quick fix :
@@ -691,21 +803,44 @@ export class HierarchizedPickerComponent {
691
803
  this.showSelectedNodes();
692
804
  this.deactivateNodesOutOfDepthSettings();
693
805
  // Hides checkboxes in non multiple context
694
- if (!this.optionsManager.getOptions().multiple) {
695
- document.querySelectorAll('#tree-area-' + this.componentID + ' .treejs-checkbox').forEach((item) => (item.style.display = 'none'));
696
- }
806
+ document.querySelectorAll('#tree-area-' + this.componentID + ' .treejs-checkbox').forEach((item) => (item.style.display = (this.theOptions.multiple ? 'inline-block' : 'none')));
697
807
  }
698
808
  onItemContextMenuItemClick(e) {
809
+ if (e.target && e.target.id) {
810
+ function getDirectParentAndDepth(nodesById, targetId) {
811
+ // Find the direct parent
812
+ const parent = Object.values(nodesById).find(node => { var _a; return (_a = node.children) === null || _a === void 0 ? void 0 : _a.some(child => child.id === targetId); }) || null;
813
+ if (!nodesById[targetId])
814
+ return null; // target not found
815
+ // Depth is 0 for root nodes, 1 for children of root, etc.
816
+ let depth = 0;
817
+ let current = targetId;
818
+ while (true) {
819
+ const directParent = Object.values(nodesById).find(node => { var _a; return (_a = node.children) === null || _a === void 0 ? void 0 : _a.some(child => child.id === current); });
820
+ if (!directParent)
821
+ break;
822
+ depth++;
823
+ current = directParent.id;
824
+ }
825
+ return { parent, depth };
826
+ }
827
+ const result = getDirectParentAndDepth(this.loadedTreeJs.nodesById, e.target.id);
828
+ e.target.depth = result.depth;
829
+ e.target.parentId = result.parent.id;
830
+ }
699
831
  this.itemContextMenuItemClick.emit(e);
700
832
  }
701
833
  setNodeAsSelected(id, treeToUpdate, userClick) {
834
+ console.log("setNodeAsSelected", id);
702
835
  // TODO Temporarily ignores disabled mode for selecting nodes if mode is tree
703
836
  if (((this.isDisabled && this.optionsManager.getOptions().mode != "tree") && this.shownTree && this.setValueOnClick) ||
704
837
  (this.loadedTreeJs.liElementsById[id] && this.loadedTreeJs.liElementsById[id].classList.value && this.loadedTreeJs.liElementsById[id].classList.value.indexOf('readonly_node') != -1)) {
705
838
  return;
706
839
  }
707
- if (treeToUpdate.getValues().indexOf(id.toString()) != -1)
840
+ if (!userClick && treeToUpdate.getValues().indexOf(id.toString()) != -1)
708
841
  return;
842
+ if (this.loadedTreeJs && !this.theOptions.multiple)
843
+ this.loadedTreeJs.emptyNodesCheckStatus();
709
844
  this.ignoreOptionsChanges = true;
710
845
  // Override of treejs normal workaround =>> DONT EDIT IT!
711
846
  // ----- BEGIN -----
@@ -742,46 +877,29 @@ export class HierarchizedPickerComponent {
742
877
  * This method display the current selected node to the user by expanding all it's parent nodes and scrolling inside the tree
743
878
  */
744
879
  async showSelectedNodes(addDelay = false) {
745
- if (this.optionsManager.getOptions().multiple) {
746
- console.warn('You are not allowed to scroll to selected nodes in multiple mode');
747
- return;
748
- }
749
- const scrollToNode = () => {
750
- let scrollToValue = 0;
751
- let removeClosedAndLookUp = (element) => {
752
- var _a, _b, _c, _d;
753
- const nodeId = element === null || element === void 0 ? void 0 : element.nodeId;
754
- if (!element || !nodeId) {
755
- return;
756
- }
757
- const node = this.loadedTreeJs.nodesById[nodeId];
758
- if ((_b = (_a = node === null || node === void 0 ? void 0 : node.children) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.id) {
759
- (_c = element.classList) === null || _c === void 0 ? void 0 : _c.remove('treejs-node__close');
760
- }
761
- scrollToValue += element.offsetTop;
762
- const parent = (_d = element.parentNode) === null || _d === void 0 ? void 0 : _d.closest('.treejs-node');
763
- if (parent) {
764
- removeClosedAndLookUp(parent);
765
- }
766
- };
767
- try {
768
- const checkeds = document.querySelectorAll('#tree-area-' + this.componentID + ' .treejs-node__checked');
769
- checkeds.forEach((item) => removeClosedAndLookUp(item));
770
- }
771
- catch (err) {
772
- // console.error("Error in showSelectedNodes", err);
773
- }
774
- if (scrollToValue && this.scrollable) {
775
- this.scrollable.scrollTop = scrollToValue;
776
- }
777
- };
880
+ // if (this.optionsManager.getOptions().multiple) {
881
+ // console.warn('You are not allowed to scroll to selected nodes in multiple mode');
882
+ // return;
883
+ // }
778
884
  if (addDelay) {
779
885
  setTimeout(() => {
780
- scrollToNode();
886
+ this.scrollToNode();
781
887
  }, 200);
782
888
  }
783
889
  else {
784
- scrollToNode();
890
+ this.scrollToNode();
891
+ }
892
+ }
893
+ async scrollToNodeWithId(targetNodeId, displayChildren = false) {
894
+ const targetNode = this.loadedTreeJs.liElementsById[targetNodeId];
895
+ if (!targetNode) {
896
+ const contextualApiParams = this.getContextualApiParams(Object.assign(Object.assign({}, this.theOptions.options), { Reach: [targetNodeId] }), null, true);
897
+ const contextualApiURL = this.getContextualApiURL(true, Object.assign(Object.assign({}, this.theOptions), { options: contextualApiParams }));
898
+ this.rawDataManager.getFromClassification(contextualApiURL, contextualApiParams, document.querySelector("#hierarchized-picker-" + this.componentID + " .loader"))
899
+ .then(data => {
900
+ completeCurrentTreeWithTree(this.loadedTreeJs, data, this.theOptions);
901
+ this.scrollToNode(targetNodeId, displayChildren);
902
+ });
785
903
  }
786
904
  }
787
905
  showTree(focused) {
@@ -793,7 +911,7 @@ export class HierarchizedPickerComponent {
793
911
  const isStillInsidePicker = isInsidePicker(this, document.activeElement);
794
912
  if ((focused === 'hide' || this.isDisabled) && !isStillInsidePicker) {
795
913
  this.hasFocus = ['hide'];
796
- const elem = document.querySelector('#hierarchized-picker-' + this.componentID + ' .hierarchized-picker-search input');
914
+ const elem = document.querySelector('#hierarchized-picker-' + this.componentID + ' input.hierarchized-picker-search');
797
915
  if (elem) {
798
916
  elem.value = '';
799
917
  }
@@ -814,8 +932,16 @@ export class HierarchizedPickerComponent {
814
932
  }
815
933
  const previousShownTree = this.shownTree;
816
934
  this.shownTree = this.hasFocus.length > 0;
817
- if (this.shownTree && !previousShownTree) {
818
- focusSearchInput(this);
935
+ if (this.shownTree && !previousShownTree && this.optionsManager.getOptions().mode == 'input') {
936
+ if (this.shouldOpenModalAbove(document.querySelector('#hierarchized-picker-input-' + this.componentID), this.modaleHeight)) {
937
+ this.modalePosition = 'top';
938
+ }
939
+ else {
940
+ this.modalePosition = 'bottom';
941
+ }
942
+ setTimeout(() => focusSearchInput(this), 100);
943
+ //TODO, this this at the good location ?
944
+ setupKeyboardNavigation(this, this.optionsManager, this.navigateInTree);
819
945
  }
820
946
  }
821
947
  // Changes the value of the component with passed node
@@ -828,9 +954,12 @@ export class HierarchizedPickerComponent {
828
954
  return item.nodeid == node.id;
829
955
  });
830
956
  // If the passed node already exists in the array of values, remove it
831
- if (userClick && result > -1) {
832
- this.value.splice(result, 1);
833
- } // Else, add the node to the array of values
957
+ if (result > -1) {
958
+ if (userClick)
959
+ this.value.splice(result, 1);
960
+ else
961
+ return;
962
+ }
834
963
  else {
835
964
  if (this.optionsManager.getOptions().multiple) {
836
965
  this.value = [
@@ -859,10 +988,11 @@ export class HierarchizedPickerComponent {
859
988
  setDisplayedValue(value = null) {
860
989
  if (!value)
861
990
  value = this.value;
862
- this.displayedValue = value.map(item => {
991
+ const toDisplay = value.map(item => {
863
992
  var _a, _b;
864
993
  return (_b = (this.optionsManager.getOptions().isFullpath ? this.getShortenedFullpath((_a = item.fullpathTranslated) !== null && _a !== void 0 ? _a : item.fullpath) : item.shortpathTranslated)) !== null && _b !== void 0 ? _b : `Node ${item.nodeid}`;
865
994
  }).join(';');
995
+ this.displayedValue = toDisplay;
866
996
  }
867
997
  // Search a value in the tree and triggers a search when necessary
868
998
  search(searched) {
@@ -929,10 +1059,11 @@ export class HierarchizedPickerComponent {
929
1059
  if (init) {
930
1060
  this.formatDefaultValue();
931
1061
  this.showSelectedNodes();
1062
+ this.checkFields(this.value);
932
1063
  }
933
1064
  })
934
1065
  .catch(error => {
935
- console.error('getDataFromSource 3 classification rejected:', error);
1066
+ this.errorToLog = error;
936
1067
  });
937
1068
  }
938
1069
  else {
@@ -945,7 +1076,7 @@ export class HierarchizedPickerComponent {
945
1076
  }
946
1077
  })
947
1078
  .catch(error => {
948
- console.error('getDataFromSource 3 legacy rejected:', error);
1079
+ this.errorToLog = error;
949
1080
  });
950
1081
  }
951
1082
  }
@@ -960,13 +1091,14 @@ export class HierarchizedPickerComponent {
960
1091
  this.translateDataForTree(this.rawDataManager.getData());
961
1092
  }
962
1093
  checkFields(values, allowSetValueOnClick = true) {
1094
+ console.log("checkFields", values);
963
1095
  if (!this.loadedTreeJs)
964
1096
  return;
965
1097
  this.setValueOnClick = allowSetValueOnClick;
966
1098
  let enrichedValues = [];
967
1099
  if (values) {
968
1100
  values.forEach(element => {
969
- var _a, _b;
1101
+ var _a, _b, _c;
970
1102
  let intNodeid = element.nodeid || element.ID || element.key || undefined;
971
1103
  if (typeof intNodeid === 'string' && isNumeric(intNodeid)) {
972
1104
  intNodeid = parseInt(intNodeid);
@@ -976,15 +1108,15 @@ export class HierarchizedPickerComponent {
976
1108
  enrichedValues.push({
977
1109
  nodeid: intNodeid,
978
1110
  shortpathTranslated: (_a = treeNode.text) !== null && _a !== void 0 ? _a : `Node ${intNodeid}`,
979
- fullpathTranslated: (_b = treeNode.fullpath) !== null && _b !== void 0 ? _b : null,
1111
+ fullpathTranslated: (_b = treeNode.fullpathTranslated) !== null && _b !== void 0 ? _b : null,
1112
+ fullpath: (_c = treeNode.fullpath) !== null && _c !== void 0 ? _c : null,
980
1113
  hasChildren: treeNode.children && treeNode.children.length > 0
981
1114
  });
982
- this.setNodeAsSelected(intNodeid, this.loadedTreeJs, false);
983
1115
  }
984
1116
  else {
985
- this.setNodeAsSelected(intNodeid, this.loadedTreeJs, false);
986
1117
  console.warn("Node not found in Tree for:", intNodeid);
987
1118
  }
1119
+ this.setNodeAsSelected(intNodeid, this.loadedTreeJs, false);
988
1120
  });
989
1121
  }
990
1122
  this.setDisplayedValue(enrichedValues);
@@ -994,8 +1126,19 @@ export class HierarchizedPickerComponent {
994
1126
  formatDefaultValue() {
995
1127
  let found = 0;
996
1128
  let that = this;
1129
+ let fieldsToCheck = [];
1130
+ function addToFieldsToCheck(item) {
1131
+ if (Array.isArray(item)) {
1132
+ item.forEach(el => addToFieldsToCheck(el));
1133
+ }
1134
+ else {
1135
+ const exists = fieldsToCheck.some(el => (el.nodeid || el.ID) == (item.nodeid || item.ID));
1136
+ if (!exists) {
1137
+ fieldsToCheck.push(item);
1138
+ }
1139
+ }
1140
+ }
997
1141
  let recursive = function (children) {
998
- //158424
999
1142
  children.forEach(element => {
1000
1143
  that.theOptions.defaultValue.forEach(dfValue => {
1001
1144
  if (typeof dfValue == 'string' && isNumeric(dfValue)) {
@@ -1005,7 +1148,7 @@ export class HierarchizedPickerComponent {
1005
1148
  if ((typeof dfValue == 'string' && getPropertyFromNode(element, 'Properties').FullPath == dfValue) ||
1006
1149
  (typeof dfValue == 'number' && getPropertyFromNode(element, 'ID') == dfValue)) {
1007
1150
  element.nodeid = element.id;
1008
- that.checkFields([element]);
1151
+ addToFieldsToCheck([element]);
1009
1152
  found++;
1010
1153
  }
1011
1154
  }
@@ -1015,7 +1158,7 @@ export class HierarchizedPickerComponent {
1015
1158
  (typeof dfValue == 'string' && getPropertyFromNode(element, 'fullpathTranslated') == dfValue) ||
1016
1159
  (typeof dfValue == 'number' && getPropertyFromNode(element, 'key') == dfValue)) {
1017
1160
  element.nodeid = element.key;
1018
- that.checkFields([element]);
1161
+ addToFieldsToCheck([element]);
1019
1162
  found++;
1020
1163
  }
1021
1164
  }
@@ -1027,6 +1170,7 @@ export class HierarchizedPickerComponent {
1027
1170
  if (this.rawDataManager.getData()) {
1028
1171
  recursive([this.rawDataManager.getData()]);
1029
1172
  }
1173
+ that.checkFields(fieldsToCheck);
1030
1174
  if (this.theOptions.defaultValue.length != found) {
1031
1175
  if (found == 0) {
1032
1176
  try {
@@ -1051,6 +1195,13 @@ export class HierarchizedPickerComponent {
1051
1195
  .map(item => { var _a, _b; return (_b = (_a = this.getShortenedFullpath(item.fullpathTranslated)) !== null && _a !== void 0 ? _a : item.fullpath) !== null && _b !== void 0 ? _b : `Node ${item.nodeid}`; })
1052
1196
  .join('; ');
1053
1197
  }
1198
+ shouldOpenModalAbove(inputElement, modaleHeight) {
1199
+ if (this.optionsManager.getOptions().mode != 'input')
1200
+ return false;
1201
+ const inputRect = inputElement.getBoundingClientRect();
1202
+ const spaceLeft = window.innerHeight - inputRect.y;
1203
+ return spaceLeft < modaleHeight;
1204
+ }
1054
1205
  render() {
1055
1206
  return this.optionsManager.getOptions() ? (h("div", { id: 'hierarchized-picker-' + this.componentID, class: 'hierarchized-picker ' + (this.isDisabled ? 'readonly-mode' : '') }, this.optionsManager.getOptions().mode == 'input' ? (h("div", { class: "hierarchized-picker-container" }, h("div", { style: { display: 'none' }, ref: el => {
1056
1207
  this.loader = el;
@@ -1066,11 +1217,11 @@ export class HierarchizedPickerComponent {
1066
1217
  } }, h("input", { class: "native-input sc-ion-input-md", "aria-labelledby": "ion-input-13-lbl", autocapitalize: "off", autocomplete: "off", autocorrect: "off", name: "ion-input-13", placeholder: "", readonly: "", spellcheck: "false", type: "text", value: this.displayedValue, title: this.getFullpathTooltip() })), this.displayedValue && !this.isDisabled && this.canload ? h("span", { class: "reneco reneco-close", onClick: () => this.clearPicker() }) : ''), h("div", { ref: el => {
1067
1218
  // Uncomment if you want the modale of picker in input mode to scroll to selected node on openning >>>
1068
1219
  this.scrollable = el;
1069
- }, class: 'hierarchized-picker-modal-area ' + (!this.shownTree ? ' hidden ' : ''), onClick: event => {
1220
+ }, class: `hierarchized-picker-modal-area ${!this.shownTree ? ' hidden ' : ''} ${this.modalePosition == 'top' ? "display-modale-top" : ""}`, onClick: event => {
1070
1221
  clickPickerModalArea(this, event);
1071
1222
  } }, h("div", { class: "loader", ref: el => {
1072
1223
  this.loader = el;
1073
- } }, h("div", { class: "loader-inner" }, "Loading...")), h("div", { class: 'hierarchized-picker-modal ' + (!this.ready ? 'hidden' : '') }, h("search-input", { placeholder: getLanguageValue(this.optionsManager.getOptions().searchPlaceholder, this.optionsManager.getOptions().language, defaultLanguage), onInputFocus: () => focusInSearchEvent(this), onInputBlur: () => focusOutSearchEvent(this, event), onSearch: (event) => this.search(event.detail) }), h("ul", { id: "autocomplete-results-area" }), h("div", { id: 'tree-area-' + this.componentID, class: 'hierarchized-picker-tree hierarchized-picker-tree-area ' + this.pickerClass }))))) : (h("div", { class: 'hierarchized-picker-raw-tree-area' + (this.isDisabled ? ' readonly' : ''), onClick: event => {
1224
+ } }, h("div", { class: "loader-inner" }, "Loading...")), h("div", { class: `hierarchized-picker-modal ${!this.ready ? 'hidden' : ''}`, tabindex: "" + this.componentID }, h("search-input", { placeholder: getLanguageValue(this.optionsManager.getOptions().searchPlaceholder, this.optionsManager.getOptions().language, defaultLanguage), onInputFocus: () => focusInSearchEvent(this), onInputBlur: () => focusOutSearchEvent(this, event), onSearch: (event) => this.search(event.detail) }), h("ul", { id: "autocomplete-results-area" }), h("div", { id: 'tree-area-' + this.componentID, class: 'hierarchized-picker-tree hierarchized-picker-tree-area ' + this.pickerClass }))))) : (h("div", { class: 'hierarchized-picker-raw-tree-area' + (this.isDisabled ? ' readonly' : ''), tabindex: "" + this.componentID, onClick: event => {
1074
1225
  clickPickerModalArea(this, event);
1075
1226
  } }, h("div", { class: "loader", ref: el => {
1076
1227
  this.loader = el;
@@ -1278,6 +1429,36 @@ export class HierarchizedPickerComponent {
1278
1429
  "resolved": "any",
1279
1430
  "references": {}
1280
1431
  }
1432
+ }, {
1433
+ "method": "navigateInTree",
1434
+ "name": "navigateInTree",
1435
+ "bubbles": true,
1436
+ "cancelable": true,
1437
+ "composed": true,
1438
+ "docs": {
1439
+ "tags": [],
1440
+ "text": "This event is emitted when the user navigates in the tree"
1441
+ },
1442
+ "complexType": {
1443
+ "original": "any",
1444
+ "resolved": "any",
1445
+ "references": {}
1446
+ }
1447
+ }, {
1448
+ "method": "errorRaised",
1449
+ "name": "errorRaised",
1450
+ "bubbles": true,
1451
+ "cancelable": true,
1452
+ "composed": true,
1453
+ "docs": {
1454
+ "tags": [],
1455
+ "text": "This event is emitted when the picker suffers an error"
1456
+ },
1457
+ "complexType": {
1458
+ "original": "any",
1459
+ "resolved": "any",
1460
+ "references": {}
1461
+ }
1281
1462
  }];
1282
1463
  }
1283
1464
  static get methods() {
@@ -1375,6 +1556,22 @@ export class HierarchizedPickerComponent {
1375
1556
  "tags": []
1376
1557
  }
1377
1558
  },
1559
+ "getError": {
1560
+ "complexType": {
1561
+ "signature": "() => Promise<string>",
1562
+ "parameters": [],
1563
+ "references": {
1564
+ "Promise": {
1565
+ "location": "global"
1566
+ }
1567
+ },
1568
+ "return": "Promise<string>"
1569
+ },
1570
+ "docs": {
1571
+ "text": "",
1572
+ "tags": []
1573
+ }
1574
+ },
1378
1575
  "clearPicker": {
1379
1576
  "complexType": {
1380
1577
  "signature": "() => Promise<void>",
@@ -1401,9 +1598,6 @@ export class HierarchizedPickerComponent {
1401
1598
  "references": {
1402
1599
  "Promise": {
1403
1600
  "location": "global"
1404
- },
1405
- "HTMLElement": {
1406
- "location": "global"
1407
1601
  }
1408
1602
  },
1409
1603
  "return": "Promise<void>"
@@ -1412,6 +1606,28 @@ export class HierarchizedPickerComponent {
1412
1606
  "text": "This method display the current selected node to the user by expanding all it's parent nodes and scrolling inside the tree",
1413
1607
  "tags": []
1414
1608
  }
1609
+ },
1610
+ "scrollToNodeWithId": {
1611
+ "complexType": {
1612
+ "signature": "(targetNodeId: any, displayChildren?: boolean) => Promise<void>",
1613
+ "parameters": [{
1614
+ "tags": [],
1615
+ "text": ""
1616
+ }, {
1617
+ "tags": [],
1618
+ "text": ""
1619
+ }],
1620
+ "references": {
1621
+ "Promise": {
1622
+ "location": "global"
1623
+ }
1624
+ },
1625
+ "return": "Promise<void>"
1626
+ },
1627
+ "docs": {
1628
+ "text": "",
1629
+ "tags": []
1630
+ }
1415
1631
  }
1416
1632
  };
1417
1633
  }