@meshmakers/shared-ui 3.5.210 → 3.5.270

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.
@@ -17,7 +17,7 @@ import { LabelComponent, LabelModule } from '@progress/kendo-angular-label';
17
17
  import * as i5 from '@progress/kendo-angular-inputs';
18
18
  import { TextBoxComponent, CheckBoxComponent, SeparatorComponent, NumericTextBoxComponent, InputsModule, NumericTextBoxModule } from '@progress/kendo-angular-inputs';
19
19
  import { ProgressBarComponent } from '@progress/kendo-angular-progressbar';
20
- import { copyIcon, xIcon, calculatorIcon, clockArrowRotateIcon, passwordIcon, cellsMergeIcon, unpinIcon, pinIcon, undoIcon, fileReportIcon, downloadIcon, importIcon, exportIcon, stopIcon, playIcon, xCircleIcon, uploadIcon, arrowRotateCwIcon, fileDataIcon, eraserIcon, trashIcon, hyperlinkOpenIcon, eyeIcon, pencilIcon, plusIcon, checkIcon, filterIcon, filePdfIcon, fileExcelIcon, filterClearIcon, moreVerticalIcon, slidersIcon, saveIcon, cancelIcon, searchIcon, clockIcon } from '@progress/kendo-svg-icons';
20
+ import { copyIcon, xIcon, calculatorIcon, clockArrowRotateIcon, passwordIcon, cellsMergeIcon, arrowRightIcon, unpinIcon, pinIcon, undoIcon, fileReportIcon, downloadIcon, importIcon, exportIcon, stopIcon, playIcon, xCircleIcon, uploadIcon, arrowRotateCwIcon, fileDataIcon, eraserIcon, trashIcon, hyperlinkOpenIcon, eyeIcon, pencilIcon, plusIcon, checkIcon, filterIcon, filePdfIcon, fileExcelIcon, filterClearIcon, moreVerticalIcon, slidersIcon, saveIcon, cancelIcon, searchIcon, clockIcon } from '@progress/kendo-svg-icons';
21
21
  import { Router, NavigationEnd, RouterLink, ActivatedRoute } from '@angular/router';
22
22
  import { filter, debounceTime, distinctUntilChanged, takeUntil, observeOn, tap, switchMap, catchError } from 'rxjs/operators';
23
23
  import { MessageService, CommandBaseService, CommandSettingsService, provideMmSharedServices } from '@meshmakers/shared-services';
@@ -2160,6 +2160,8 @@ const MM_ACTION_ICONS = {
2160
2160
  pin: pinIcon,
2161
2161
  /** Remove a pin ("Unpin from Home"). */
2162
2162
  unpin: unpinIcon,
2163
+ /** Move an item to another folder / container (never `arrowsMoveIcon`: it reads as "add"). */
2164
+ move: arrowRightIcon,
2163
2165
  /** Merge one item into another (e.g. merge users); usually `danger`. */
2164
2166
  merge: cellsMergeIcon,
2165
2167
  /** Reset / set a password. */
@@ -5444,6 +5446,7 @@ class EntitySelectInputComponent {
5444
5446
  entityMap = new Map();
5445
5447
  // Private members
5446
5448
  searchSubject = new Subject();
5449
+ typedText = '';
5447
5450
  destroy$ = new Subject();
5448
5451
  onChange = () => { };
5449
5452
  onTouched = () => { };
@@ -5501,25 +5504,30 @@ class EntitySelectInputComponent {
5501
5504
  // Event handlers
5502
5505
  onFilterChange(event) {
5503
5506
  const filter = event;
5504
- if (!filter || filter.length < this.minSearchLength) {
5507
+ this.typedText = filter ?? '';
5508
+ if (this.typedText.length < this.minSearchLength) {
5505
5509
  this.filteredEntities = [];
5506
- return;
5507
5510
  }
5508
- this.searchSubject.next(filter);
5511
+ this.searchSubject.next(this.typedText);
5509
5512
  }
5510
5513
  onSelectionChange(value) {
5511
- if (value && typeof value === 'string') {
5512
- // Find the entity that matches the selected display text
5513
- const entity = this.entityMap.get(value);
5514
- if (entity) {
5515
- this.selectEntity(entity);
5514
+ if (!value) {
5515
+ if (this.selectedEntity) {
5516
+ this.clearSelection();
5516
5517
  }
5518
+ return;
5519
+ }
5520
+ // Find the entity that matches the selected display text
5521
+ const entity = this.entityMap.get(value);
5522
+ if (entity) {
5523
+ this.selectEntity(entity);
5517
5524
  }
5518
5525
  }
5519
5526
  onFocus() {
5520
5527
  // Optional: Trigger search on focus if there's already text
5521
5528
  const currentValue = this.searchFormControl.value;
5522
5529
  if (currentValue && currentValue.length >= this.minSearchLength && this.filteredEntities.length === 0) {
5530
+ this.typedText = currentValue;
5523
5531
  this.searchSubject.next(currentValue);
5524
5532
  }
5525
5533
  }
@@ -5536,12 +5544,10 @@ class EntitySelectInputComponent {
5536
5544
  }
5537
5545
  // Public methods
5538
5546
  clear() {
5539
- this.selectedEntity = null;
5540
5547
  this.filteredEntities = [];
5541
5548
  this.entityMap.clear();
5542
5549
  this.searchFormControl.setValue('', { emitEvent: false });
5543
- this.onChange(null);
5544
- this.entityCleared.emit();
5550
+ this.clearSelection();
5545
5551
  this.autocomplete.focus();
5546
5552
  }
5547
5553
  focus() {
@@ -5553,18 +5559,23 @@ class EntitySelectInputComponent {
5553
5559
  this.clear();
5554
5560
  }
5555
5561
  // Private methods
5562
+ clearSelection() {
5563
+ this.selectedEntity = null;
5564
+ this.onChange(null);
5565
+ this.entityCleared.emit();
5566
+ }
5556
5567
  setupSearch() {
5557
- this.searchSubject.pipe(debounceTime(this.debounceMs), distinctUntilChanged(), tap(() => {
5568
+ this.searchSubject.pipe(debounceTime(this.debounceMs), distinctUntilChanged(), filter(text => text.length >= this.minSearchLength), tap(() => {
5558
5569
  this.isLoading = true;
5559
5570
  this.filteredEntities = [];
5560
- }), switchMap(filter => {
5571
+ }), switchMap(searchText => {
5561
5572
  if (!this.dataSource) {
5562
5573
  return of({ totalCount: 0, items: [] });
5563
5574
  }
5564
- if (filter.startsWith(this.prefix)) {
5565
- if (typeof filter === 'string') {
5566
- filter = filter.replace(this.prefix, '').trim();
5567
- return this.dataSource.onFilter(filter, this.maxResults).catch(error => {
5575
+ if (searchText.startsWith(this.prefix)) {
5576
+ if (typeof searchText === 'string') {
5577
+ searchText = searchText.replace(this.prefix, '').trim();
5578
+ return this.dataSource.onFilter(searchText, this.maxResults).catch(error => {
5568
5579
  console.error('Entity search error:', error);
5569
5580
  return { totalCount: 0, items: [] };
5570
5581
  });
@@ -5574,7 +5585,7 @@ class EntitySelectInputComponent {
5574
5585
  }
5575
5586
  }
5576
5587
  else {
5577
- return this.dataSource.onFilter(filter, this.maxResults).catch(error => {
5588
+ return this.dataSource.onFilter(searchText, this.maxResults).catch(error => {
5578
5589
  console.error('Entity search error:', error);
5579
5590
  return { totalCount: 0, items: [] };
5580
5591
  });
@@ -5584,6 +5595,9 @@ class EntitySelectInputComponent {
5584
5595
  return of({ totalCount: 0, items: [] });
5585
5596
  })).subscribe(result => {
5586
5597
  this.isLoading = false;
5598
+ if (this.typedText.length < this.minSearchLength) {
5599
+ return;
5600
+ }
5587
5601
  if (this.prefix && result.items.length === 1) {
5588
5602
  // Auto-select if exactly one match in prefix mode
5589
5603
  this.selectEntity(result.items[0]);