@meshmakers/shared-ui 3.3.560 → 3.3.570

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.
@@ -654,21 +654,122 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
654
654
  `, styles: [".message-details-content{display:flex;flex-direction:column;height:100%;padding:16px;box-sizing:border-box;overflow:hidden}.loading-section{flex:1;display:flex;align-items:center;justify-content:center}.details-pre{flex:1;margin:0;font-family:Courier New,monospace;font-size:13px;line-height:1.5;border:1px solid var(--kendo-color-border);background:var(--kendo-color-base-subtle);border-radius:4px;padding:12px;overflow:scroll;white-space:pre;min-height:0}.details-pre::-webkit-scrollbar{width:10px;height:10px}.details-pre::-webkit-scrollbar-track{background:var(--kendo-color-base-subtle, #f5f5f5);border-radius:4px}.details-pre::-webkit-scrollbar-thumb{background:var(--kendo-color-border, #ccc);border-radius:4px}.details-pre::-webkit-scrollbar-thumb:hover{background:#999}.dialog-actions{flex-shrink:0;padding-top:16px;margin-top:16px;border-top:1px solid var(--kendo-color-border);display:flex;flex-direction:row;justify-content:space-between;gap:12px}\n"] }]
655
655
  }] });
656
656
 
657
+ class WindowStateService {
658
+ storageKey = 'mm-window-states';
659
+ activeBackdrops = 0;
660
+ getDimensions(dialogKey) {
661
+ const states = this.loadStates();
662
+ return states[dialogKey] ?? null;
663
+ }
664
+ saveDimensions(dialogKey, dimensions) {
665
+ const states = this.loadStates();
666
+ states[dialogKey] = dimensions;
667
+ this.saveStates(states);
668
+ }
669
+ clearDimensions(dialogKey) {
670
+ const states = this.loadStates();
671
+ delete states[dialogKey];
672
+ this.saveStates(states);
673
+ }
674
+ resolveWindowSize(dialogKey, defaults) {
675
+ return this.getDimensions(dialogKey) ?? defaults;
676
+ }
677
+ captureAndSave(dialogKey, windowElement) {
678
+ const rect = windowElement.getBoundingClientRect();
679
+ if (rect.width > 0 && rect.height > 0) {
680
+ this.saveDimensions(dialogKey, {
681
+ width: Math.round(rect.width),
682
+ height: Math.round(rect.height)
683
+ });
684
+ }
685
+ }
686
+ /**
687
+ * Applies modal behavior to a Kendo WindowRef: shows a dark backdrop overlay
688
+ * that blocks interaction with the background, and removes it when the window closes.
689
+ * Also captures and saves window dimensions on close.
690
+ */
691
+ applyModalBehavior(dialogKey, windowRef) {
692
+ const windowEl = windowRef.window.location.nativeElement;
693
+ this.showBackdrop();
694
+ windowRef.result.subscribe({
695
+ next: () => {
696
+ this.captureAndSave(dialogKey, windowEl);
697
+ this.hideBackdrop();
698
+ },
699
+ error: () => {
700
+ this.captureAndSave(dialogKey, windowEl);
701
+ this.hideBackdrop();
702
+ }
703
+ });
704
+ }
705
+ showBackdrop() {
706
+ this.activeBackdrops++;
707
+ if (this.activeBackdrops === 1) {
708
+ this.getOrCreateBackdropElement().style.display = 'block';
709
+ }
710
+ }
711
+ hideBackdrop() {
712
+ this.activeBackdrops = Math.max(0, this.activeBackdrops - 1);
713
+ if (this.activeBackdrops === 0) {
714
+ const el = document.querySelector('.mm-window-backdrop');
715
+ if (el) {
716
+ el.style.display = 'none';
717
+ }
718
+ }
719
+ }
720
+ getOrCreateBackdropElement() {
721
+ let el = document.querySelector('.mm-window-backdrop');
722
+ if (!el) {
723
+ el = document.createElement('div');
724
+ el.className = 'mm-window-backdrop';
725
+ el.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.4);z-index:11499;display:none;';
726
+ document.body.appendChild(el);
727
+ }
728
+ return el;
729
+ }
730
+ loadStates() {
731
+ try {
732
+ const raw = sessionStorage.getItem(this.storageKey);
733
+ return raw ? JSON.parse(raw) : {};
734
+ }
735
+ catch {
736
+ return {};
737
+ }
738
+ }
739
+ saveStates(states) {
740
+ try {
741
+ sessionStorage.setItem(this.storageKey, JSON.stringify(states));
742
+ }
743
+ catch {
744
+ // sessionStorage full or unavailable
745
+ }
746
+ }
747
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: WindowStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
748
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: WindowStateService, providedIn: 'root' });
749
+ }
750
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: WindowStateService, decorators: [{
751
+ type: Injectable,
752
+ args: [{ providedIn: 'root' }]
753
+ }] });
754
+
657
755
  class MessageDetailsDialogService {
658
756
  windowService = inject(WindowService);
757
+ windowStateService = inject(WindowStateService);
659
758
  /**
660
759
  * Opens a resizable window to show message details with copy-to-clipboard functionality
661
760
  */
662
761
  showDetailsDialog(data) {
762
+ const size = this.windowStateService.resolveWindowSize('message-details', { width: 900, height: 600 });
663
763
  const windowRef = this.windowService.open({
664
764
  content: MessageDetailsDialogComponent,
665
765
  title: data.title,
666
- width: 900,
667
- height: 600,
766
+ width: size.width,
767
+ height: size.height,
668
768
  minWidth: 500,
669
769
  minHeight: 400,
670
770
  resizable: true,
671
771
  });
772
+ this.windowStateService.applyModalBehavior('message-details', windowRef);
672
773
  const contentRef = windowRef.content;
673
774
  if (contentRef?.instance) {
674
775
  contentRef.instance.data = data;
@@ -2803,6 +2904,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2803
2904
 
2804
2905
  class EntitySelectDialogService {
2805
2906
  windowService = inject(WindowService);
2907
+ windowStateService = inject(WindowStateService);
2806
2908
  /**
2807
2909
  * Opens the entity select dialog
2808
2910
  * @param dataSource The data source providing grid data and column definitions
@@ -2810,15 +2912,19 @@ class EntitySelectDialogService {
2810
2912
  * @returns Promise resolving to selected entities or null if cancelled
2811
2913
  */
2812
2914
  async open(dataSource, options) {
2915
+ const defaultWidth = options.width ?? 800;
2916
+ const defaultHeight = options.height ?? 600;
2917
+ const size = this.windowStateService.resolveWindowSize('entity-select', { width: defaultWidth, height: defaultHeight });
2813
2918
  const windowRef = this.windowService.open({
2814
2919
  title: options.title,
2815
2920
  content: EntitySelectDialogComponent,
2816
- width: options.width ?? 800,
2817
- height: options.height ?? 600,
2921
+ width: size.width,
2922
+ height: size.height,
2818
2923
  minWidth: 550,
2819
2924
  minHeight: 400,
2820
2925
  resizable: true
2821
2926
  });
2927
+ this.windowStateService.applyModalBehavior('entity-select', windowRef);
2822
2928
  const contentRef = windowRef.content;
2823
2929
  if (contentRef?.instance) {
2824
2930
  contentRef.instance.dataSource = dataSource;
@@ -2854,6 +2960,12 @@ class EntitySelectInputComponent {
2854
2960
  maxResults = 50;
2855
2961
  debounceMs = 300;
2856
2962
  prefix = '';
2963
+ // Initial display value (e.g. when restoring a previously selected entity by name)
2964
+ set initialDisplayValue(value) {
2965
+ if (value && !this.selectedEntity) {
2966
+ this.searchFormControl.setValue(value, { emitEvent: false });
2967
+ }
2968
+ }
2857
2969
  // Dialog inputs
2858
2970
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- generic component accepts any entity type
2859
2971
  dialogDataSource;
@@ -3101,7 +3213,7 @@ class EntitySelectInputComponent {
3101
3213
  }
3102
3214
  }
3103
3215
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EntitySelectInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3104
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.0", type: EntitySelectInputComponent, isStandalone: true, selector: "mm-entity-select-input", inputs: { dataSource: "dataSource", placeholder: "placeholder", minSearchLength: "minSearchLength", maxResults: "maxResults", debounceMs: "debounceMs", prefix: "prefix", dialogDataSource: "dialogDataSource", dialogTitle: "dialogTitle", multiSelect: "multiSelect", advancedSearchLabel: "advancedSearchLabel", dialogMessages: "dialogMessages", messages: "messages", disabled: "disabled", required: "required" }, outputs: { entitySelected: "entitySelected", entityCleared: "entityCleared", entitiesSelected: "entitiesSelected" }, providers: [
3216
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.0", type: EntitySelectInputComponent, isStandalone: true, selector: "mm-entity-select-input", inputs: { dataSource: "dataSource", placeholder: "placeholder", minSearchLength: "minSearchLength", maxResults: "maxResults", debounceMs: "debounceMs", prefix: "prefix", initialDisplayValue: "initialDisplayValue", dialogDataSource: "dialogDataSource", dialogTitle: "dialogTitle", multiSelect: "multiSelect", advancedSearchLabel: "advancedSearchLabel", dialogMessages: "dialogMessages", messages: "messages", disabled: "disabled", required: "required" }, outputs: { entitySelected: "entitySelected", entityCleared: "entityCleared", entitiesSelected: "entitiesSelected" }, providers: [
3105
3217
  {
3106
3218
  provide: NG_VALUE_ACCESSOR,
3107
3219
  useExisting: forwardRef(() => EntitySelectInputComponent),
@@ -3163,6 +3275,7 @@ class EntitySelectInputComponent {
3163
3275
  <button *ngIf="dialogDataSource"
3164
3276
  kendoButton
3165
3277
  type="button"
3278
+ fillMode="flat"
3166
3279
  [svgIcon]="searchIcon"
3167
3280
  [disabled]="disabled"
3168
3281
  [title]="advancedSearchLabel || _messages.advancedSearchLabel"
@@ -3244,6 +3357,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
3244
3357
  <button *ngIf="dialogDataSource"
3245
3358
  kendoButton
3246
3359
  type="button"
3360
+ fillMode="flat"
3247
3361
  [svgIcon]="searchIcon"
3248
3362
  [disabled]="disabled"
3249
3363
  [title]="advancedSearchLabel || _messages.advancedSearchLabel"
@@ -3267,6 +3381,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
3267
3381
  type: Input
3268
3382
  }], prefix: [{
3269
3383
  type: Input
3384
+ }], initialDisplayValue: [{
3385
+ type: Input
3270
3386
  }], dialogDataSource: [{
3271
3387
  type: Input
3272
3388
  }], dialogTitle: [{
@@ -5189,5 +5305,5 @@ function provideMmSharedUi() {
5189
5305
  * Generated bundle index. Do not edit.
5190
5306
  */
5191
5307
 
5192
- export { BaseFormComponent, BaseTreeDetailComponent, ButtonTypes, BytesToSizePipe, CRON_PRESETS, ConfirmationService, ConfirmationWindowResult, CopyableTextComponent, CronBuilderComponent, CronHumanizerService, CronParserService, DEFAULT_CRON_BUILDER_CONFIG, DEFAULT_ENTITY_SELECT_DIALOG_MESSAGES, DEFAULT_ENTITY_SELECT_INPUT_MESSAGES, DEFAULT_LIST_VIEW_MESSAGES, DEFAULT_RESPONSIVE_COLSPAN, DEFAULT_TIME_RANGE_LABELS, DataSourceBase, DataSourceTyped, DialogType, EntitySelectDialogComponent, EntitySelectDialogService, EntitySelectInputComponent, FetchResultBase, FetchResultTyped, FileUploadResult, FileUploadService, FormTitleExtraDirective, HAS_UNSAVED_CHANGES, HOUR_INTERVALS, HierarchyDataSource, HierarchyDataSourceBase, ImportStrategyDialogComponent, ImportStrategyDialogResult, ImportStrategyDialogService, ImportStrategyDto, InputDialogComponent, InputService, ListViewComponent, MINUTE_INTERVALS, MessageDetailsDialogComponent, MessageDetailsDialogService, MessageListenerService, MmListViewDataBindingDirective, NotificationDisplayService, PascalCasePipe, ProgressValue, ProgressWindowComponent, ProgressWindowService, RELATIVE_WEEKS, SECOND_INTERVALS, SaveAsDialogComponent, SaveAsDialogService, TimeRangePickerComponent, TimeRangeUtils, TreeComponent, UnsavedChangesDirective, UnsavedChangesGuard, UploadFileDialogComponent, WEEKDAYS, WEEKDAY_ABBREVIATIONS, generateDayOfMonthOptions, generateHourOptions, generateMinuteOptions, provideMmSharedUi };
5308
+ export { BaseFormComponent, BaseTreeDetailComponent, ButtonTypes, BytesToSizePipe, CRON_PRESETS, ConfirmationService, ConfirmationWindowResult, CopyableTextComponent, CronBuilderComponent, CronHumanizerService, CronParserService, DEFAULT_CRON_BUILDER_CONFIG, DEFAULT_ENTITY_SELECT_DIALOG_MESSAGES, DEFAULT_ENTITY_SELECT_INPUT_MESSAGES, DEFAULT_LIST_VIEW_MESSAGES, DEFAULT_RESPONSIVE_COLSPAN, DEFAULT_TIME_RANGE_LABELS, DataSourceBase, DataSourceTyped, DialogType, EntitySelectDialogComponent, EntitySelectDialogService, EntitySelectInputComponent, FetchResultBase, FetchResultTyped, FileUploadResult, FileUploadService, FormTitleExtraDirective, HAS_UNSAVED_CHANGES, HOUR_INTERVALS, HierarchyDataSource, HierarchyDataSourceBase, ImportStrategyDialogComponent, ImportStrategyDialogResult, ImportStrategyDialogService, ImportStrategyDto, InputDialogComponent, InputService, ListViewComponent, MINUTE_INTERVALS, MessageDetailsDialogComponent, MessageDetailsDialogService, MessageListenerService, MmListViewDataBindingDirective, NotificationDisplayService, PascalCasePipe, ProgressValue, ProgressWindowComponent, ProgressWindowService, RELATIVE_WEEKS, SECOND_INTERVALS, SaveAsDialogComponent, SaveAsDialogService, TimeRangePickerComponent, TimeRangeUtils, TreeComponent, UnsavedChangesDirective, UnsavedChangesGuard, UploadFileDialogComponent, WEEKDAYS, WEEKDAY_ABBREVIATIONS, WindowStateService, generateDayOfMonthOptions, generateHourOptions, generateMinuteOptions, provideMmSharedUi };
5193
5309
  //# sourceMappingURL=meshmakers-shared-ui.mjs.map