@masterteam/components 0.0.123 → 0.0.124

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 (26) hide show
  1. package/assets/common.css +1 -1
  2. package/assets/i18n/ar.json +94 -36
  3. package/assets/i18n/en.json +37 -0
  4. package/fesm2022/masterteam-components-client-page.mjs +72 -5
  5. package/fesm2022/masterteam-components-client-page.mjs.map +1 -1
  6. package/fesm2022/masterteam-components-date-field.mjs +1 -2
  7. package/fesm2022/masterteam-components-date-field.mjs.map +1 -1
  8. package/fesm2022/masterteam-components-entities.mjs +16 -11
  9. package/fesm2022/masterteam-components-entities.mjs.map +1 -1
  10. package/fesm2022/masterteam-components-formula.mjs +7 -10
  11. package/fesm2022/masterteam-components-formula.mjs.map +1 -1
  12. package/fesm2022/masterteam-components-menu.mjs +1 -2
  13. package/fesm2022/masterteam-components-menu.mjs.map +1 -1
  14. package/fesm2022/masterteam-components-page-header.mjs +2 -2
  15. package/fesm2022/masterteam-components-page-header.mjs.map +1 -1
  16. package/fesm2022/masterteam-components-property-filter-builder.mjs +7 -4
  17. package/fesm2022/masterteam-components-property-filter-builder.mjs.map +1 -1
  18. package/fesm2022/masterteam-components-table.mjs +13 -11
  19. package/fesm2022/masterteam-components-table.mjs.map +1 -1
  20. package/fesm2022/masterteam-components-topbar.mjs +2 -2
  21. package/fesm2022/masterteam-components-topbar.mjs.map +1 -1
  22. package/package.json +1 -1
  23. package/types/masterteam-components-client-page.d.ts +18 -4
  24. package/types/masterteam-components-entities.d.ts +2 -1
  25. package/types/masterteam-components-formula.d.ts +0 -4
  26. package/types/masterteam-components-property-filter-builder.d.ts +2 -2
@@ -1,12 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, model, contentChild, output, linkedSignal, computed, effect, signal, Component } from '@angular/core';
3
- import { NgTemplateOutlet } from '@angular/common';
2
+ import { inject, PLATFORM_ID, input, model, contentChild, output, linkedSignal, computed, effect, signal, Component } from '@angular/core';
3
+ import { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
4
4
  import { Avatar } from '@masterteam/components/avatar';
5
5
  import { Card } from '@masterteam/components/card';
6
6
  import { ClientPageMenu } from '@masterteam/components/client-page-menu';
7
7
  import { Icon } from '@masterteam/icons';
8
8
 
9
9
  class ClientPage {
10
+ platformId = inject(PLATFORM_ID);
11
+ mediaQueryList = null;
10
12
  /** Icon for the left sidebar header */
11
13
  menuIcon = input(...(ngDevMode ? [undefined, { debugName: "menuIcon" }] : []));
12
14
  /** Title for the left sidebar header */
@@ -44,25 +46,66 @@ class ClientPage {
44
46
  this.menuItemClick.emit(item);
45
47
  }
46
48
  });
49
+ this.setupResponsiveBehavior();
47
50
  }
48
51
  /** Whether the divider/toggle area is being hovered */
49
52
  dividerHovered = signal(false, ...(ngDevMode ? [{ debugName: "dividerHovered" }] : []));
53
+ /** Whether the viewport is at or below the responsive breakpoint */
54
+ isResponsive = signal(false, ...(ngDevMode ? [{ debugName: "isResponsive" }] : []));
55
+ /** Whether the responsive top navigation is expanded */
56
+ responsiveMenuExpanded = signal(false, ...(ngDevMode ? [{ debugName: "responsiveMenuExpanded" }] : []));
57
+ /** Whether the menu section is currently visible */
58
+ showSidebarMenu = computed(() => this.isResponsive() ? this.responsiveMenuExpanded() : !this.collapsed(), ...(ngDevMode ? [{ debugName: "showSidebarMenu" }] : []));
50
59
  /** Sidebar width reacts to collapsed + hover */
51
60
  sidebarWidth = computed(() => {
61
+ if (this.isResponsive()) {
62
+ return '100%';
63
+ }
52
64
  if (this.collapsed()) {
53
65
  return this.dividerHovered() ? '12px' : '9px';
54
66
  }
55
67
  return this.dividerHovered() ? '15.8%' : '16%';
56
68
  }, ...(ngDevMode ? [{ debugName: "sidebarWidth" }] : []));
57
69
  /** Icon for the collapse toggle button */
58
- toggleIcon = computed(() => this.collapsed() ? 'arrow.chevron-right' : 'arrow.chevron-left', ...(ngDevMode ? [{ debugName: "toggleIcon" }] : []));
70
+ toggleIcon = computed(() => this.isResponsive()
71
+ ? this.responsiveMenuExpanded()
72
+ ? 'arrow.chevron-up'
73
+ : 'arrow.chevron-down'
74
+ : this.collapsed()
75
+ ? 'arrow.chevron-right'
76
+ : 'arrow.chevron-left', ...(ngDevMode ? [{ debugName: "toggleIcon" }] : []));
77
+ /** Accessible label for the toggle button */
78
+ toggleAriaLabel = computed(() => this.isResponsive()
79
+ ? this.responsiveMenuExpanded()
80
+ ? 'Collapse menu'
81
+ : 'Expand menu'
82
+ : this.collapsed()
83
+ ? 'Expand sidebar'
84
+ : 'Collapse sidebar', ...(ngDevMode ? [{ debugName: "toggleAriaLabel" }] : []));
59
85
  toggleCollapsed() {
86
+ if (this.isResponsive()) {
87
+ this.responsiveMenuExpanded.update((expanded) => !expanded);
88
+ return;
89
+ }
60
90
  this.collapsed.update((v) => !v);
61
91
  }
62
92
  selectItem(item) {
63
93
  this.selectedKey.set(item.key);
94
+ if (this.isResponsive()) {
95
+ this.responsiveMenuExpanded.set(false);
96
+ }
64
97
  this.menuItemClick.emit(item);
65
98
  }
99
+ ngOnDestroy() {
100
+ if (!this.mediaQueryList) {
101
+ return;
102
+ }
103
+ if (typeof this.mediaQueryList.removeEventListener === 'function') {
104
+ this.mediaQueryList.removeEventListener('change', this.handleResponsiveBreakpointChange);
105
+ return;
106
+ }
107
+ this.mediaQueryList.removeListener(this.handleResponsiveBreakpointChange);
108
+ }
66
109
  getAvatarStyle(color) {
67
110
  if (color.startsWith('#')) {
68
111
  return {
@@ -75,14 +118,38 @@ class ClientPage {
75
118
  '--p-avatar-color': `var(--p-${color}-700)`,
76
119
  };
77
120
  }
121
+ handleResponsiveBreakpointChange = (event) => {
122
+ this.syncResponsiveState(event.matches);
123
+ };
124
+ setupResponsiveBehavior() {
125
+ if (!isPlatformBrowser(this.platformId) ||
126
+ typeof window.matchMedia !== 'function') {
127
+ return;
128
+ }
129
+ this.mediaQueryList = window.matchMedia('(max-width: 1024px)');
130
+ this.syncResponsiveState(this.mediaQueryList.matches);
131
+ if (typeof this.mediaQueryList.addEventListener === 'function') {
132
+ this.mediaQueryList.addEventListener('change', this.handleResponsiveBreakpointChange);
133
+ return;
134
+ }
135
+ this.mediaQueryList.addListener(this.handleResponsiveBreakpointChange);
136
+ }
137
+ syncResponsiveState(isResponsive) {
138
+ const wasResponsive = this.isResponsive();
139
+ this.isResponsive.set(isResponsive);
140
+ this.dividerHovered.set(false);
141
+ if (wasResponsive !== isResponsive) {
142
+ this.responsiveMenuExpanded.set(false);
143
+ }
144
+ }
78
145
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ClientPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
79
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ClientPage, isStandalone: true, selector: "mt-client-page", inputs: { menuIcon: { classPropertyName: "menuIcon", publicName: "menuIcon", isSignal: true, isRequired: false, transformFunction: null }, menuTitle: { classPropertyName: "menuTitle", publicName: "menuTitle", isSignal: true, isRequired: false, transformFunction: null }, menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: false, transformFunction: null }, menuItemsLoading: { classPropertyName: "menuItemsLoading", publicName: "menuItemsLoading", isSignal: true, isRequired: false, transformFunction: null }, activeItem: { classPropertyName: "activeItem", publicName: "activeItem", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange", menuItemClick: "menuItemClick" }, host: { classAttribute: "block h-full" }, queries: [{ propertyName: "headerEnd", first: true, predicate: ["headerClientPageEnd"], descendants: true, isSignal: true }], ngImport: i0, template: "<mt-card class=\"bg-gray-200 w-full h-full\">\r\n <ng-template #headless>\r\n <div class=\"flex h-full min-h-0\">\r\n <!-- Left Sidebar -->\r\n <div\r\n class=\"flex min-h-0 flex-col overflow-hidden transition-all duration-300 ease-in-out\"\r\n [style.width]=\"sidebarWidth()\"\r\n >\r\n <!-- Sidebar Header -->\r\n <div\r\n class=\"flex shrink-0 items-center justify-between overflow-hidden border-b border-gray-300 px-5 py-4 whitespace-nowrap\"\r\n >\r\n <div class=\"flex gap-2 items-center\">\r\n @if (menuIcon()) {\r\n <div class=\"text-lg shrink-0\">\r\n <mt-icon [icon]=\"menuIcon()!\" />\r\n </div>\r\n }\r\n @if (menuTitle()) {\r\n <div class=\"font-semibold\">{{ menuTitle() }}</div>\r\n }\r\n </div>\r\n </div>\r\n @if (!collapsed()) {\r\n <!-- Menu Items -->\r\n <mt-client-page-menu\r\n [menuItems]=\"menuItems()\"\r\n [selectedItem]=\"selectedItem()\"\r\n [loading]=\"menuItemsLoading()\"\r\n (menuItemClick)=\"selectItem($event)\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Vertical Divider with Toggle Button -->\r\n <div\r\n class=\"relative flex-shrink-0 w-px\"\r\n (mouseenter)=\"dividerHovered.set(true)\"\r\n (mouseleave)=\"dividerHovered.set(false)\"\r\n >\r\n <!-- Toggle Button at bottom of divider -->\r\n <button\r\n type=\"button\"\r\n (click)=\"toggleCollapsed()\"\r\n class=\"absolute bottom-6 -translate-x-1/2 left-1/2 z-10 flex items-center justify-center w-6 h-6 rounded-full bg-white border border-gray-300 shadow-sm hover:shadow-md hover:scale-125 hover:bg-gray-50 active:scale-95 active:bg-gray-100 transition-all duration-200 ease-in-out cursor-pointer group\"\r\n [attr.aria-label]=\"\r\n collapsed() ? 'Expand sidebar' : 'Collapse sidebar'\r\n \"\r\n >\r\n <mt-icon\r\n [icon]=\"toggleIcon()\"\r\n class=\"text-gray-500 group-hover:text-primary-600 text-xs transition-all duration-200 group-hover:animate-pulse\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <!-- Right Content Panel -->\r\n <div class=\"flex min-h-0 min-w-0 flex-1 flex-col\">\r\n <mt-card class=\"h-full min-h-0\">\r\n <ng-template #headless>\r\n <!-- Content Header -->\r\n <div\r\n class=\"flex shrink-0 items-center justify-between border-b border-surface px-5 py-4\"\r\n >\r\n <div class=\"flex gap-2 items-center\">\r\n @if (selectedItem(); as selected) {\r\n <mt-avatar\r\n [style]=\"getAvatarStyle(selected.color)\"\r\n [icon]=\"selected.icon\"\r\n shape=\"square\"\r\n size=\"large\"\r\n />\r\n <div>\r\n <div class=\"text-md font-semibold\">\r\n {{ selected.title }}\r\n </div>\r\n @if (selected.subtitle) {\r\n <div class=\"text-sm text-gray-500 font-semibold\">\r\n {{ selected.subtitle }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n @if (headerEnd(); as template) {\r\n <div class=\"flex gap-2\">\r\n <ng-container [ngTemplateOutlet]=\"template\" />\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Content Body -->\r\n <div class=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto p-5\">\r\n <ng-content />\r\n </div>\r\n </ng-template>\r\n </mt-card>\r\n </div>\r\n </div>\r\n </ng-template>\r\n</mt-card>\r\n", dependencies: [{ kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: ClientPageMenu, selector: "mt-client-page-menu", inputs: ["menuItems", "loading", "selectedItem"], outputs: ["menuItemClick"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
146
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ClientPage, isStandalone: true, selector: "mt-client-page", inputs: { menuIcon: { classPropertyName: "menuIcon", publicName: "menuIcon", isSignal: true, isRequired: false, transformFunction: null }, menuTitle: { classPropertyName: "menuTitle", publicName: "menuTitle", isSignal: true, isRequired: false, transformFunction: null }, menuItems: { classPropertyName: "menuItems", publicName: "menuItems", isSignal: true, isRequired: false, transformFunction: null }, menuItemsLoading: { classPropertyName: "menuItemsLoading", publicName: "menuItemsLoading", isSignal: true, isRequired: false, transformFunction: null }, activeItem: { classPropertyName: "activeItem", publicName: "activeItem", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapsed: "collapsedChange", menuItemClick: "menuItemClick" }, host: { classAttribute: "block h-full" }, queries: [{ propertyName: "headerEnd", first: true, predicate: ["headerClientPageEnd"], descendants: true, isSignal: true }], ngImport: i0, template: "<mt-card class=\"bg-gray-200 w-full h-full\">\r\n <ng-template #headless>\r\n <div class=\"flex h-full min-h-0\" [class.flex-col]=\"isResponsive()\">\r\n <!-- Left Sidebar -->\r\n <div\r\n class=\"flex min-h-0 flex-col overflow-hidden transition-all duration-300 ease-in-out\"\r\n [style.width]=\"sidebarWidth()\"\r\n >\r\n <!-- Sidebar Header -->\r\n <div\r\n class=\"flex shrink-0 items-center justify-between overflow-hidden border-b border-gray-300 px-5 py-4\"\r\n [class.whitespace-nowrap]=\"!isResponsive()\"\r\n >\r\n <div class=\"flex min-w-0 items-center gap-2\">\r\n @if (menuIcon()) {\r\n <div class=\"text-lg shrink-0\">\r\n <mt-icon [icon]=\"menuIcon()!\" />\r\n </div>\r\n }\r\n @if (menuTitle()) {\r\n <div class=\"min-w-0 truncate font-semibold\">\r\n {{ menuTitle() }}\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (isResponsive()) {\r\n <button\r\n type=\"button\"\r\n (click)=\"toggleCollapsed()\"\r\n class=\"ml-3 flex h-9 w-9 shrink-0 items-center justify-center rounded-full border border-gray-300 bg-white text-gray-500 transition-all duration-200 ease-in-out hover:bg-gray-50 hover:text-primary-600 active:scale-95 active:bg-gray-100\"\r\n [attr.aria-label]=\"toggleAriaLabel()\"\r\n >\r\n <mt-icon [icon]=\"toggleIcon()\" class=\"text-sm\" />\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (showSidebarMenu()) {\r\n <!-- Menu Items -->\r\n <div\r\n class=\"min-h-0 overflow-hidden\"\r\n [class.flex-1]=\"!isResponsive()\"\r\n [style.maxHeight]=\"isResponsive() ? '22rem' : null\"\r\n >\r\n <mt-client-page-menu\r\n class=\"h-full\"\r\n [menuItems]=\"menuItems()\"\r\n [selectedItem]=\"selectedItem()\"\r\n [loading]=\"menuItemsLoading()\"\r\n (menuItemClick)=\"selectItem($event)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Vertical Divider with Toggle Button -->\r\n @if (!isResponsive()) {\r\n <div\r\n class=\"relative w-px flex-shrink-0\"\r\n (mouseenter)=\"dividerHovered.set(true)\"\r\n (mouseleave)=\"dividerHovered.set(false)\"\r\n >\r\n <!-- Toggle Button at bottom of divider -->\r\n <button\r\n type=\"button\"\r\n (click)=\"toggleCollapsed()\"\r\n class=\"absolute bottom-6 left-1/2 z-10 flex h-6 w-6 -translate-x-1/2 cursor-pointer items-center justify-center rounded-full border border-gray-300 bg-white shadow-sm transition-all duration-200 ease-in-out hover:scale-125 hover:bg-gray-50 hover:shadow-md active:scale-95 active:bg-gray-100 group\"\r\n [attr.aria-label]=\"toggleAriaLabel()\"\r\n >\r\n <mt-icon\r\n [icon]=\"toggleIcon()\"\r\n class=\"text-xs text-gray-500 transition-all duration-200 group-hover:animate-pulse group-hover:text-primary-600\"\r\n />\r\n </button>\r\n </div>\r\n }\r\n\r\n <!-- Right Content Panel -->\r\n <div class=\"flex min-h-0 min-w-0 flex-1 flex-col\">\r\n <mt-card class=\"h-full min-h-0\">\r\n <ng-template #headless>\r\n <!-- Content Header -->\r\n <div\r\n class=\"flex shrink-0 items-center justify-between border-b border-surface px-5 py-4\"\r\n [class.flex-col]=\"isResponsive()\"\r\n [class.items-start]=\"isResponsive()\"\r\n [class.gap-3]=\"isResponsive()\"\r\n >\r\n <div class=\"flex min-w-0 items-center gap-3\">\r\n @if (selectedItem(); as selected) {\r\n <mt-avatar\r\n [style]=\"getAvatarStyle(selected.color)\"\r\n [icon]=\"selected.icon\"\r\n shape=\"square\"\r\n size=\"large\"\r\n />\r\n <div class=\"min-w-0\">\r\n <div class=\"text-md truncate font-semibold\">\r\n {{ selected.title }}\r\n </div>\r\n @if (selected.subtitle) {\r\n <div class=\"truncate text-sm font-semibold text-gray-500\">\r\n {{ selected.subtitle }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n @if (headerEnd(); as template) {\r\n <div\r\n class=\"flex gap-2\"\r\n [class.w-full]=\"isResponsive()\"\r\n [class.flex-wrap]=\"isResponsive()\"\r\n [class.justify-end]=\"isResponsive()\"\r\n >\r\n <ng-container [ngTemplateOutlet]=\"template\" />\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Content Body -->\r\n <div\r\n class=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto p-5\"\r\n >\r\n <ng-content />\r\n </div>\r\n </ng-template>\r\n </mt-card>\r\n </div>\r\n </div>\r\n </ng-template>\r\n</mt-card>\r\n", dependencies: [{ kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: ClientPageMenu, selector: "mt-client-page-menu", inputs: ["menuItems", "loading", "selectedItem"], outputs: ["menuItemClick"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
80
147
  }
81
148
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ClientPage, decorators: [{
82
149
  type: Component,
83
150
  args: [{ selector: 'mt-client-page', standalone: true, imports: [Avatar, Card, ClientPageMenu, Icon, NgTemplateOutlet], host: {
84
151
  class: 'block h-full',
85
- }, template: "<mt-card class=\"bg-gray-200 w-full h-full\">\r\n <ng-template #headless>\r\n <div class=\"flex h-full min-h-0\">\r\n <!-- Left Sidebar -->\r\n <div\r\n class=\"flex min-h-0 flex-col overflow-hidden transition-all duration-300 ease-in-out\"\r\n [style.width]=\"sidebarWidth()\"\r\n >\r\n <!-- Sidebar Header -->\r\n <div\r\n class=\"flex shrink-0 items-center justify-between overflow-hidden border-b border-gray-300 px-5 py-4 whitespace-nowrap\"\r\n >\r\n <div class=\"flex gap-2 items-center\">\r\n @if (menuIcon()) {\r\n <div class=\"text-lg shrink-0\">\r\n <mt-icon [icon]=\"menuIcon()!\" />\r\n </div>\r\n }\r\n @if (menuTitle()) {\r\n <div class=\"font-semibold\">{{ menuTitle() }}</div>\r\n }\r\n </div>\r\n </div>\r\n @if (!collapsed()) {\r\n <!-- Menu Items -->\r\n <mt-client-page-menu\r\n [menuItems]=\"menuItems()\"\r\n [selectedItem]=\"selectedItem()\"\r\n [loading]=\"menuItemsLoading()\"\r\n (menuItemClick)=\"selectItem($event)\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Vertical Divider with Toggle Button -->\r\n <div\r\n class=\"relative flex-shrink-0 w-px\"\r\n (mouseenter)=\"dividerHovered.set(true)\"\r\n (mouseleave)=\"dividerHovered.set(false)\"\r\n >\r\n <!-- Toggle Button at bottom of divider -->\r\n <button\r\n type=\"button\"\r\n (click)=\"toggleCollapsed()\"\r\n class=\"absolute bottom-6 -translate-x-1/2 left-1/2 z-10 flex items-center justify-center w-6 h-6 rounded-full bg-white border border-gray-300 shadow-sm hover:shadow-md hover:scale-125 hover:bg-gray-50 active:scale-95 active:bg-gray-100 transition-all duration-200 ease-in-out cursor-pointer group\"\r\n [attr.aria-label]=\"\r\n collapsed() ? 'Expand sidebar' : 'Collapse sidebar'\r\n \"\r\n >\r\n <mt-icon\r\n [icon]=\"toggleIcon()\"\r\n class=\"text-gray-500 group-hover:text-primary-600 text-xs transition-all duration-200 group-hover:animate-pulse\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <!-- Right Content Panel -->\r\n <div class=\"flex min-h-0 min-w-0 flex-1 flex-col\">\r\n <mt-card class=\"h-full min-h-0\">\r\n <ng-template #headless>\r\n <!-- Content Header -->\r\n <div\r\n class=\"flex shrink-0 items-center justify-between border-b border-surface px-5 py-4\"\r\n >\r\n <div class=\"flex gap-2 items-center\">\r\n @if (selectedItem(); as selected) {\r\n <mt-avatar\r\n [style]=\"getAvatarStyle(selected.color)\"\r\n [icon]=\"selected.icon\"\r\n shape=\"square\"\r\n size=\"large\"\r\n />\r\n <div>\r\n <div class=\"text-md font-semibold\">\r\n {{ selected.title }}\r\n </div>\r\n @if (selected.subtitle) {\r\n <div class=\"text-sm text-gray-500 font-semibold\">\r\n {{ selected.subtitle }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n @if (headerEnd(); as template) {\r\n <div class=\"flex gap-2\">\r\n <ng-container [ngTemplateOutlet]=\"template\" />\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Content Body -->\r\n <div class=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto p-5\">\r\n <ng-content />\r\n </div>\r\n </ng-template>\r\n </mt-card>\r\n </div>\r\n </div>\r\n </ng-template>\r\n</mt-card>\r\n" }]
152
+ }, template: "<mt-card class=\"bg-gray-200 w-full h-full\">\r\n <ng-template #headless>\r\n <div class=\"flex h-full min-h-0\" [class.flex-col]=\"isResponsive()\">\r\n <!-- Left Sidebar -->\r\n <div\r\n class=\"flex min-h-0 flex-col overflow-hidden transition-all duration-300 ease-in-out\"\r\n [style.width]=\"sidebarWidth()\"\r\n >\r\n <!-- Sidebar Header -->\r\n <div\r\n class=\"flex shrink-0 items-center justify-between overflow-hidden border-b border-gray-300 px-5 py-4\"\r\n [class.whitespace-nowrap]=\"!isResponsive()\"\r\n >\r\n <div class=\"flex min-w-0 items-center gap-2\">\r\n @if (menuIcon()) {\r\n <div class=\"text-lg shrink-0\">\r\n <mt-icon [icon]=\"menuIcon()!\" />\r\n </div>\r\n }\r\n @if (menuTitle()) {\r\n <div class=\"min-w-0 truncate font-semibold\">\r\n {{ menuTitle() }}\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (isResponsive()) {\r\n <button\r\n type=\"button\"\r\n (click)=\"toggleCollapsed()\"\r\n class=\"ml-3 flex h-9 w-9 shrink-0 items-center justify-center rounded-full border border-gray-300 bg-white text-gray-500 transition-all duration-200 ease-in-out hover:bg-gray-50 hover:text-primary-600 active:scale-95 active:bg-gray-100\"\r\n [attr.aria-label]=\"toggleAriaLabel()\"\r\n >\r\n <mt-icon [icon]=\"toggleIcon()\" class=\"text-sm\" />\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (showSidebarMenu()) {\r\n <!-- Menu Items -->\r\n <div\r\n class=\"min-h-0 overflow-hidden\"\r\n [class.flex-1]=\"!isResponsive()\"\r\n [style.maxHeight]=\"isResponsive() ? '22rem' : null\"\r\n >\r\n <mt-client-page-menu\r\n class=\"h-full\"\r\n [menuItems]=\"menuItems()\"\r\n [selectedItem]=\"selectedItem()\"\r\n [loading]=\"menuItemsLoading()\"\r\n (menuItemClick)=\"selectItem($event)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Vertical Divider with Toggle Button -->\r\n @if (!isResponsive()) {\r\n <div\r\n class=\"relative w-px flex-shrink-0\"\r\n (mouseenter)=\"dividerHovered.set(true)\"\r\n (mouseleave)=\"dividerHovered.set(false)\"\r\n >\r\n <!-- Toggle Button at bottom of divider -->\r\n <button\r\n type=\"button\"\r\n (click)=\"toggleCollapsed()\"\r\n class=\"absolute bottom-6 left-1/2 z-10 flex h-6 w-6 -translate-x-1/2 cursor-pointer items-center justify-center rounded-full border border-gray-300 bg-white shadow-sm transition-all duration-200 ease-in-out hover:scale-125 hover:bg-gray-50 hover:shadow-md active:scale-95 active:bg-gray-100 group\"\r\n [attr.aria-label]=\"toggleAriaLabel()\"\r\n >\r\n <mt-icon\r\n [icon]=\"toggleIcon()\"\r\n class=\"text-xs text-gray-500 transition-all duration-200 group-hover:animate-pulse group-hover:text-primary-600\"\r\n />\r\n </button>\r\n </div>\r\n }\r\n\r\n <!-- Right Content Panel -->\r\n <div class=\"flex min-h-0 min-w-0 flex-1 flex-col\">\r\n <mt-card class=\"h-full min-h-0\">\r\n <ng-template #headless>\r\n <!-- Content Header -->\r\n <div\r\n class=\"flex shrink-0 items-center justify-between border-b border-surface px-5 py-4\"\r\n [class.flex-col]=\"isResponsive()\"\r\n [class.items-start]=\"isResponsive()\"\r\n [class.gap-3]=\"isResponsive()\"\r\n >\r\n <div class=\"flex min-w-0 items-center gap-3\">\r\n @if (selectedItem(); as selected) {\r\n <mt-avatar\r\n [style]=\"getAvatarStyle(selected.color)\"\r\n [icon]=\"selected.icon\"\r\n shape=\"square\"\r\n size=\"large\"\r\n />\r\n <div class=\"min-w-0\">\r\n <div class=\"text-md truncate font-semibold\">\r\n {{ selected.title }}\r\n </div>\r\n @if (selected.subtitle) {\r\n <div class=\"truncate text-sm font-semibold text-gray-500\">\r\n {{ selected.subtitle }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n @if (headerEnd(); as template) {\r\n <div\r\n class=\"flex gap-2\"\r\n [class.w-full]=\"isResponsive()\"\r\n [class.flex-wrap]=\"isResponsive()\"\r\n [class.justify-end]=\"isResponsive()\"\r\n >\r\n <ng-container [ngTemplateOutlet]=\"template\" />\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Content Body -->\r\n <div\r\n class=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto p-5\"\r\n >\r\n <ng-content />\r\n </div>\r\n </ng-template>\r\n </mt-card>\r\n </div>\r\n </div>\r\n </ng-template>\r\n</mt-card>\r\n" }]
86
153
  }], ctorParameters: () => [], propDecorators: { menuIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuIcon", required: false }] }], menuTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuTitle", required: false }] }], menuItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuItems", required: false }] }], menuItemsLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuItemsLoading", required: false }] }], activeItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeItem", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }, { type: i0.Output, args: ["collapsedChange"] }], headerEnd: [{ type: i0.ContentChild, args: ['headerClientPageEnd', { isSignal: true }] }], menuItemClick: [{ type: i0.Output, args: ["menuItemClick"] }] } });
87
154
 
88
155
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"masterteam-components-client-page.mjs","sources":["../../../../packages/masterteam/components/client-page/client-page.ts","../../../../packages/masterteam/components/client-page/client-page.html","../../../../packages/masterteam/components/client-page/masterteam-components-client-page.ts"],"sourcesContent":["import {\r\n Component,\r\n contentChild,\r\n computed,\r\n effect,\r\n input,\r\n linkedSignal,\r\n model,\r\n output,\r\n signal,\r\n TemplateRef,\r\n} from '@angular/core';\r\nimport { NgTemplateOutlet } from '@angular/common';\r\nimport { Avatar } from '@masterteam/components/avatar';\r\nimport { Card } from '@masterteam/components/card';\r\nimport {\r\n ClientPageMenu,\r\n ClientPageMenuItem,\r\n} from '@masterteam/components/client-page-menu';\r\nimport { Icon } from '@masterteam/icons';\r\n\r\n@Component({\r\n selector: 'mt-client-page',\r\n standalone: true,\r\n imports: [Avatar, Card, ClientPageMenu, Icon, NgTemplateOutlet],\r\n templateUrl: './client-page.html',\r\n host: {\r\n class: 'block h-full',\r\n },\r\n})\r\nexport class ClientPage {\r\n /** Icon for the left sidebar header */\r\n readonly menuIcon = input<string>();\r\n\r\n /** Title for the left sidebar header */\r\n readonly menuTitle = input<string>();\r\n\r\n /** List of menu items for the left sidebar */\r\n readonly menuItems = input<ClientPageMenuItem[]>([]);\r\n\r\n /** Whether menu items are loading */\r\n readonly menuItemsLoading = input<boolean>(false);\r\n\r\n /** Key of the active menu item (defaults to first item) */\r\n readonly activeItem = input<string>();\r\n\r\n /** Whether the sidebar menu is collapsed (two-way bindable) */\r\n readonly collapsed = model<boolean>(false);\r\n\r\n /** Template projected into the left sidebar header end */\r\n readonly headerEnd = contentChild<TemplateRef<any>>('headerClientPageEnd');\r\n\r\n /** Emitted when a menu item is clicked */\r\n readonly menuItemClick = output<ClientPageMenuItem>();\r\n\r\n /** Tracks activeItem input, overridable by user clicks */\r\n private readonly selectedKey = linkedSignal(() => this.activeItem());\r\n\r\n /** Currently selected menu item */\r\n readonly selectedItem = computed(() => {\r\n const key = this.selectedKey();\r\n const items = this.menuItems();\r\n if (key) {\r\n return items.find((item) => item.key === key) ?? items[0] ?? null;\r\n }\r\n return items[0] ?? null;\r\n });\r\n\r\n /** Whether the initial default selection has been emitted */\r\n private initialEmitted = false;\r\n\r\n constructor() {\r\n effect(() => {\r\n const item = this.selectedItem();\r\n if (item && !this.initialEmitted) {\r\n this.initialEmitted = true;\r\n this.menuItemClick.emit(item);\r\n }\r\n });\r\n }\r\n\r\n /** Whether the divider/toggle area is being hovered */\r\n readonly dividerHovered = signal(false);\r\n\r\n /** Sidebar width reacts to collapsed + hover */\r\n readonly sidebarWidth = computed(() => {\r\n if (this.collapsed()) {\r\n return this.dividerHovered() ? '12px' : '9px';\r\n }\r\n return this.dividerHovered() ? '15.8%' : '16%';\r\n });\r\n\r\n /** Icon for the collapse toggle button */\r\n readonly toggleIcon = computed(() =>\r\n this.collapsed() ? 'arrow.chevron-right' : 'arrow.chevron-left',\r\n );\r\n\r\n toggleCollapsed(): void {\r\n this.collapsed.update((v) => !v);\r\n }\r\n\r\n selectItem(item: ClientPageMenuItem): void {\r\n this.selectedKey.set(item.key);\r\n this.menuItemClick.emit(item);\r\n }\r\n\r\n getAvatarStyle(color: string): Record<string, string> {\r\n if (color.startsWith('#')) {\r\n return {\r\n '--p-avatar-background': color + '1a',\r\n '--p-avatar-color': color,\r\n };\r\n }\r\n return {\r\n '--p-avatar-background': `var(--p-${color}-100)`,\r\n '--p-avatar-color': `var(--p-${color}-700)`,\r\n };\r\n }\r\n}\r\n","<mt-card class=\"bg-gray-200 w-full h-full\">\r\n <ng-template #headless>\r\n <div class=\"flex h-full min-h-0\">\r\n <!-- Left Sidebar -->\r\n <div\r\n class=\"flex min-h-0 flex-col overflow-hidden transition-all duration-300 ease-in-out\"\r\n [style.width]=\"sidebarWidth()\"\r\n >\r\n <!-- Sidebar Header -->\r\n <div\r\n class=\"flex shrink-0 items-center justify-between overflow-hidden border-b border-gray-300 px-5 py-4 whitespace-nowrap\"\r\n >\r\n <div class=\"flex gap-2 items-center\">\r\n @if (menuIcon()) {\r\n <div class=\"text-lg shrink-0\">\r\n <mt-icon [icon]=\"menuIcon()!\" />\r\n </div>\r\n }\r\n @if (menuTitle()) {\r\n <div class=\"font-semibold\">{{ menuTitle() }}</div>\r\n }\r\n </div>\r\n </div>\r\n @if (!collapsed()) {\r\n <!-- Menu Items -->\r\n <mt-client-page-menu\r\n [menuItems]=\"menuItems()\"\r\n [selectedItem]=\"selectedItem()\"\r\n [loading]=\"menuItemsLoading()\"\r\n (menuItemClick)=\"selectItem($event)\"\r\n />\r\n }\r\n </div>\r\n\r\n <!-- Vertical Divider with Toggle Button -->\r\n <div\r\n class=\"relative flex-shrink-0 w-px\"\r\n (mouseenter)=\"dividerHovered.set(true)\"\r\n (mouseleave)=\"dividerHovered.set(false)\"\r\n >\r\n <!-- Toggle Button at bottom of divider -->\r\n <button\r\n type=\"button\"\r\n (click)=\"toggleCollapsed()\"\r\n class=\"absolute bottom-6 -translate-x-1/2 left-1/2 z-10 flex items-center justify-center w-6 h-6 rounded-full bg-white border border-gray-300 shadow-sm hover:shadow-md hover:scale-125 hover:bg-gray-50 active:scale-95 active:bg-gray-100 transition-all duration-200 ease-in-out cursor-pointer group\"\r\n [attr.aria-label]=\"\r\n collapsed() ? 'Expand sidebar' : 'Collapse sidebar'\r\n \"\r\n >\r\n <mt-icon\r\n [icon]=\"toggleIcon()\"\r\n class=\"text-gray-500 group-hover:text-primary-600 text-xs transition-all duration-200 group-hover:animate-pulse\"\r\n />\r\n </button>\r\n </div>\r\n\r\n <!-- Right Content Panel -->\r\n <div class=\"flex min-h-0 min-w-0 flex-1 flex-col\">\r\n <mt-card class=\"h-full min-h-0\">\r\n <ng-template #headless>\r\n <!-- Content Header -->\r\n <div\r\n class=\"flex shrink-0 items-center justify-between border-b border-surface px-5 py-4\"\r\n >\r\n <div class=\"flex gap-2 items-center\">\r\n @if (selectedItem(); as selected) {\r\n <mt-avatar\r\n [style]=\"getAvatarStyle(selected.color)\"\r\n [icon]=\"selected.icon\"\r\n shape=\"square\"\r\n size=\"large\"\r\n />\r\n <div>\r\n <div class=\"text-md font-semibold\">\r\n {{ selected.title }}\r\n </div>\r\n @if (selected.subtitle) {\r\n <div class=\"text-sm text-gray-500 font-semibold\">\r\n {{ selected.subtitle }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n @if (headerEnd(); as template) {\r\n <div class=\"flex gap-2\">\r\n <ng-container [ngTemplateOutlet]=\"template\" />\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Content Body -->\r\n <div class=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto p-5\">\r\n <ng-content />\r\n </div>\r\n </ng-template>\r\n </mt-card>\r\n </div>\r\n </div>\r\n </ng-template>\r\n</mt-card>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"masterteam-components-client-page.mjs","sources":["../../../../packages/masterteam/components/client-page/client-page.ts","../../../../packages/masterteam/components/client-page/client-page.html","../../../../packages/masterteam/components/client-page/masterteam-components-client-page.ts"],"sourcesContent":["import {\r\n Component,\r\n contentChild,\r\n computed,\r\n effect,\r\n inject,\r\n input,\r\n linkedSignal,\r\n model,\r\n OnDestroy,\r\n output,\r\n PLATFORM_ID,\r\n signal,\r\n TemplateRef,\r\n} from '@angular/core';\r\nimport { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';\r\nimport { Avatar } from '@masterteam/components/avatar';\r\nimport { Card } from '@masterteam/components/card';\r\nimport {\r\n ClientPageMenu,\r\n ClientPageMenuItem,\r\n} from '@masterteam/components/client-page-menu';\r\nimport { Icon } from '@masterteam/icons';\r\n\r\n@Component({\r\n selector: 'mt-client-page',\r\n standalone: true,\r\n imports: [Avatar, Card, ClientPageMenu, Icon, NgTemplateOutlet],\r\n templateUrl: './client-page.html',\r\n host: {\r\n class: 'block h-full',\r\n },\r\n})\r\nexport class ClientPage implements OnDestroy {\r\n private readonly platformId = inject(PLATFORM_ID);\r\n private mediaQueryList: MediaQueryList | null = null;\r\n\r\n /** Icon for the left sidebar header */\r\n readonly menuIcon = input<string>();\r\n\r\n /** Title for the left sidebar header */\r\n readonly menuTitle = input<string>();\r\n\r\n /** List of menu items for the left sidebar */\r\n readonly menuItems = input<ClientPageMenuItem[]>([]);\r\n\r\n /** Whether menu items are loading */\r\n readonly menuItemsLoading = input<boolean>(false);\r\n\r\n /** Key of the active menu item (defaults to first item) */\r\n readonly activeItem = input<string>();\r\n\r\n /** Whether the sidebar menu is collapsed (two-way bindable) */\r\n readonly collapsed = model<boolean>(false);\r\n\r\n /** Template projected into the left sidebar header end */\r\n readonly headerEnd = contentChild<TemplateRef<any>>('headerClientPageEnd');\r\n\r\n /** Emitted when a menu item is clicked */\r\n readonly menuItemClick = output<ClientPageMenuItem>();\r\n\r\n /** Tracks activeItem input, overridable by user clicks */\r\n private readonly selectedKey = linkedSignal(() => this.activeItem());\r\n\r\n /** Currently selected menu item */\r\n readonly selectedItem = computed(() => {\r\n const key = this.selectedKey();\r\n const items = this.menuItems();\r\n if (key) {\r\n return items.find((item) => item.key === key) ?? items[0] ?? null;\r\n }\r\n return items[0] ?? null;\r\n });\r\n\r\n /** Whether the initial default selection has been emitted */\r\n private initialEmitted = false;\r\n\r\n constructor() {\r\n effect(() => {\r\n const item = this.selectedItem();\r\n if (item && !this.initialEmitted) {\r\n this.initialEmitted = true;\r\n this.menuItemClick.emit(item);\r\n }\r\n });\r\n\r\n this.setupResponsiveBehavior();\r\n }\r\n\r\n /** Whether the divider/toggle area is being hovered */\r\n readonly dividerHovered = signal(false);\r\n\r\n /** Whether the viewport is at or below the responsive breakpoint */\r\n readonly isResponsive = signal(false);\r\n\r\n /** Whether the responsive top navigation is expanded */\r\n readonly responsiveMenuExpanded = signal(false);\r\n\r\n /** Whether the menu section is currently visible */\r\n readonly showSidebarMenu = computed(() =>\r\n this.isResponsive() ? this.responsiveMenuExpanded() : !this.collapsed(),\r\n );\r\n\r\n /** Sidebar width reacts to collapsed + hover */\r\n readonly sidebarWidth = computed(() => {\r\n if (this.isResponsive()) {\r\n return '100%';\r\n }\r\n if (this.collapsed()) {\r\n return this.dividerHovered() ? '12px' : '9px';\r\n }\r\n return this.dividerHovered() ? '15.8%' : '16%';\r\n });\r\n\r\n /** Icon for the collapse toggle button */\r\n readonly toggleIcon = computed(() =>\r\n this.isResponsive()\r\n ? this.responsiveMenuExpanded()\r\n ? 'arrow.chevron-up'\r\n : 'arrow.chevron-down'\r\n : this.collapsed()\r\n ? 'arrow.chevron-right'\r\n : 'arrow.chevron-left',\r\n );\r\n\r\n /** Accessible label for the toggle button */\r\n readonly toggleAriaLabel = computed(() =>\r\n this.isResponsive()\r\n ? this.responsiveMenuExpanded()\r\n ? 'Collapse menu'\r\n : 'Expand menu'\r\n : this.collapsed()\r\n ? 'Expand sidebar'\r\n : 'Collapse sidebar',\r\n );\r\n\r\n toggleCollapsed(): void {\r\n if (this.isResponsive()) {\r\n this.responsiveMenuExpanded.update((expanded) => !expanded);\r\n return;\r\n }\r\n this.collapsed.update((v) => !v);\r\n }\r\n\r\n selectItem(item: ClientPageMenuItem): void {\r\n this.selectedKey.set(item.key);\r\n if (this.isResponsive()) {\r\n this.responsiveMenuExpanded.set(false);\r\n }\r\n this.menuItemClick.emit(item);\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (!this.mediaQueryList) {\r\n return;\r\n }\r\n\r\n if (typeof this.mediaQueryList.removeEventListener === 'function') {\r\n this.mediaQueryList.removeEventListener(\r\n 'change',\r\n this.handleResponsiveBreakpointChange,\r\n );\r\n return;\r\n }\r\n\r\n this.mediaQueryList.removeListener(this.handleResponsiveBreakpointChange);\r\n }\r\n\r\n getAvatarStyle(color: string): Record<string, string> {\r\n if (color.startsWith('#')) {\r\n return {\r\n '--p-avatar-background': color + '1a',\r\n '--p-avatar-color': color,\r\n };\r\n }\r\n return {\r\n '--p-avatar-background': `var(--p-${color}-100)`,\r\n '--p-avatar-color': `var(--p-${color}-700)`,\r\n };\r\n }\r\n\r\n private readonly handleResponsiveBreakpointChange = (\r\n event: MediaQueryListEvent,\r\n ): void => {\r\n this.syncResponsiveState(event.matches);\r\n };\r\n\r\n private setupResponsiveBehavior(): void {\r\n if (\r\n !isPlatformBrowser(this.platformId) ||\r\n typeof window.matchMedia !== 'function'\r\n ) {\r\n return;\r\n }\r\n\r\n this.mediaQueryList = window.matchMedia('(max-width: 1024px)');\r\n this.syncResponsiveState(this.mediaQueryList.matches);\r\n\r\n if (typeof this.mediaQueryList.addEventListener === 'function') {\r\n this.mediaQueryList.addEventListener(\r\n 'change',\r\n this.handleResponsiveBreakpointChange,\r\n );\r\n return;\r\n }\r\n\r\n this.mediaQueryList.addListener(this.handleResponsiveBreakpointChange);\r\n }\r\n\r\n private syncResponsiveState(isResponsive: boolean): void {\r\n const wasResponsive = this.isResponsive();\r\n this.isResponsive.set(isResponsive);\r\n this.dividerHovered.set(false);\r\n\r\n if (wasResponsive !== isResponsive) {\r\n this.responsiveMenuExpanded.set(false);\r\n }\r\n }\r\n}\r\n","<mt-card class=\"bg-gray-200 w-full h-full\">\r\n <ng-template #headless>\r\n <div class=\"flex h-full min-h-0\" [class.flex-col]=\"isResponsive()\">\r\n <!-- Left Sidebar -->\r\n <div\r\n class=\"flex min-h-0 flex-col overflow-hidden transition-all duration-300 ease-in-out\"\r\n [style.width]=\"sidebarWidth()\"\r\n >\r\n <!-- Sidebar Header -->\r\n <div\r\n class=\"flex shrink-0 items-center justify-between overflow-hidden border-b border-gray-300 px-5 py-4\"\r\n [class.whitespace-nowrap]=\"!isResponsive()\"\r\n >\r\n <div class=\"flex min-w-0 items-center gap-2\">\r\n @if (menuIcon()) {\r\n <div class=\"text-lg shrink-0\">\r\n <mt-icon [icon]=\"menuIcon()!\" />\r\n </div>\r\n }\r\n @if (menuTitle()) {\r\n <div class=\"min-w-0 truncate font-semibold\">\r\n {{ menuTitle() }}\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (isResponsive()) {\r\n <button\r\n type=\"button\"\r\n (click)=\"toggleCollapsed()\"\r\n class=\"ml-3 flex h-9 w-9 shrink-0 items-center justify-center rounded-full border border-gray-300 bg-white text-gray-500 transition-all duration-200 ease-in-out hover:bg-gray-50 hover:text-primary-600 active:scale-95 active:bg-gray-100\"\r\n [attr.aria-label]=\"toggleAriaLabel()\"\r\n >\r\n <mt-icon [icon]=\"toggleIcon()\" class=\"text-sm\" />\r\n </button>\r\n }\r\n </div>\r\n\r\n @if (showSidebarMenu()) {\r\n <!-- Menu Items -->\r\n <div\r\n class=\"min-h-0 overflow-hidden\"\r\n [class.flex-1]=\"!isResponsive()\"\r\n [style.maxHeight]=\"isResponsive() ? '22rem' : null\"\r\n >\r\n <mt-client-page-menu\r\n class=\"h-full\"\r\n [menuItems]=\"menuItems()\"\r\n [selectedItem]=\"selectedItem()\"\r\n [loading]=\"menuItemsLoading()\"\r\n (menuItemClick)=\"selectItem($event)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Vertical Divider with Toggle Button -->\r\n @if (!isResponsive()) {\r\n <div\r\n class=\"relative w-px flex-shrink-0\"\r\n (mouseenter)=\"dividerHovered.set(true)\"\r\n (mouseleave)=\"dividerHovered.set(false)\"\r\n >\r\n <!-- Toggle Button at bottom of divider -->\r\n <button\r\n type=\"button\"\r\n (click)=\"toggleCollapsed()\"\r\n class=\"absolute bottom-6 left-1/2 z-10 flex h-6 w-6 -translate-x-1/2 cursor-pointer items-center justify-center rounded-full border border-gray-300 bg-white shadow-sm transition-all duration-200 ease-in-out hover:scale-125 hover:bg-gray-50 hover:shadow-md active:scale-95 active:bg-gray-100 group\"\r\n [attr.aria-label]=\"toggleAriaLabel()\"\r\n >\r\n <mt-icon\r\n [icon]=\"toggleIcon()\"\r\n class=\"text-xs text-gray-500 transition-all duration-200 group-hover:animate-pulse group-hover:text-primary-600\"\r\n />\r\n </button>\r\n </div>\r\n }\r\n\r\n <!-- Right Content Panel -->\r\n <div class=\"flex min-h-0 min-w-0 flex-1 flex-col\">\r\n <mt-card class=\"h-full min-h-0\">\r\n <ng-template #headless>\r\n <!-- Content Header -->\r\n <div\r\n class=\"flex shrink-0 items-center justify-between border-b border-surface px-5 py-4\"\r\n [class.flex-col]=\"isResponsive()\"\r\n [class.items-start]=\"isResponsive()\"\r\n [class.gap-3]=\"isResponsive()\"\r\n >\r\n <div class=\"flex min-w-0 items-center gap-3\">\r\n @if (selectedItem(); as selected) {\r\n <mt-avatar\r\n [style]=\"getAvatarStyle(selected.color)\"\r\n [icon]=\"selected.icon\"\r\n shape=\"square\"\r\n size=\"large\"\r\n />\r\n <div class=\"min-w-0\">\r\n <div class=\"text-md truncate font-semibold\">\r\n {{ selected.title }}\r\n </div>\r\n @if (selected.subtitle) {\r\n <div class=\"truncate text-sm font-semibold text-gray-500\">\r\n {{ selected.subtitle }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n @if (headerEnd(); as template) {\r\n <div\r\n class=\"flex gap-2\"\r\n [class.w-full]=\"isResponsive()\"\r\n [class.flex-wrap]=\"isResponsive()\"\r\n [class.justify-end]=\"isResponsive()\"\r\n >\r\n <ng-container [ngTemplateOutlet]=\"template\" />\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Content Body -->\r\n <div\r\n class=\"flex min-h-0 min-w-0 flex-1 flex-col overflow-y-auto p-5\"\r\n >\r\n <ng-content />\r\n </div>\r\n </ng-template>\r\n </mt-card>\r\n </div>\r\n </div>\r\n </ng-template>\r\n</mt-card>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -4,7 +4,6 @@ import * as i1 from '@angular/forms';
4
4
  import { Validators, NgControl, FormsModule } from '@angular/forms';
5
5
  import * as i2 from 'primeng/datepicker';
6
6
  import { DatePickerModule } from 'primeng/datepicker';
7
- import { FieldValidation } from '@masterteam/components/field-validation';
8
7
  import { isInvalid } from '@masterteam/components';
9
8
  import { Icon } from '@masterteam/icons';
10
9
 
@@ -75,7 +74,7 @@ class DateField {
75
74
  }
76
75
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: DateField, decorators: [{
77
76
  type: Component,
78
- args: [{ selector: 'mt-date-field', standalone: true, imports: [FormsModule, DatePickerModule, FieldValidation, Icon], changeDetection: ChangeDetectionStrategy.OnPush, host: {
77
+ args: [{ selector: 'mt-date-field', standalone: true, imports: [FormsModule, DatePickerModule, Icon], changeDetection: ChangeDetectionStrategy.OnPush, host: {
79
78
  class: 'grid gap-1',
80
79
  }, template: "@if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >{{ label() }}</label\r\n >\r\n}\r\n<p-datepicker\r\n #calendar\r\n [ngModel]=\"value()\"\r\n (ngModelChange)=\"onValueChange($event)\"\r\n (onBlur)=\"onTouched()\"\r\n [disabled]=\"disabled() || readonly()\"\r\n [inputId]=\"ngControl?.name ? ngControl?.name?.toString() : label()\"\r\n [invalid]=\"isInvalid(ngControl?.control)\"\r\n [baseZIndex]=\"1051\"\r\n placeholder=\"{{ placeholder() ?? label() ?? '' }}\"\r\n inputStyleClass=\"w-full\"\r\n [showIcon]=\"showIcon()\"\r\n [showClear]=\"showClear()\"\r\n [showTime]=\"showTime()\"\r\n dateFormat=\"dd/mm/yy\"\r\n appendTo=\"body\"\r\n>\r\n <ng-template #previousicon>\r\n <mt-icon\r\n [icon]=\"rtl() ? 'arrow.chevron-right' : 'arrow.chevron-left'\"\r\n class=\"text-2xl\"\r\n />\r\n </ng-template>\r\n <ng-template #nexticon>\r\n <mt-icon\r\n [icon]=\"rtl() ? 'arrow.chevron-left' : 'arrow.chevron-right'\"\r\n class=\"text-2xl\"\r\n />\r\n </ng-template>\r\n</p-datepicker>\r\n\r\n<!-- <mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation> -->\r\n" }]
81
80
  }], ctorParameters: () => [], propDecorators: { calendar: [{
@@ -1 +1 @@
1
- {"version":3,"file":"masterteam-components-date-field.mjs","sources":["../../../../packages/masterteam/components/date-field/date-field.ts","../../../../packages/masterteam/components/date-field/date-field.html","../../../../packages/masterteam/components/date-field/masterteam-components-date-field.ts"],"sourcesContent":["import {\r\n Component,\r\n HostBinding,\r\n OnChanges,\r\n OnInit,\r\n SimpleChanges,\r\n ViewChild,\r\n signal,\r\n input,\r\n inject,\r\n ChangeDetectionStrategy,\r\n effect,\r\n} from '@angular/core';\r\nimport {\r\n ControlValueAccessor,\r\n FormsModule,\r\n NgControl,\r\n Validators,\r\n} from '@angular/forms';\r\nimport { DatePickerModule, DatePicker } from 'primeng/datepicker';\r\nimport { FieldValidation } from '@masterteam/components/field-validation';\r\nimport { isInvalid } from '@masterteam/components';\r\nimport { Icon } from '@masterteam/icons';\r\n\r\n@Component({\r\n selector: 'mt-date-field',\r\n standalone: true,\r\n imports: [FormsModule, DatePickerModule, FieldValidation, Icon],\r\n templateUrl: './date-field.html',\r\n styleUrls: ['./date-field.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'grid gap-1',\r\n },\r\n})\r\nexport class DateField implements ControlValueAccessor, OnInit, OnChanges {\r\n @ViewChild('calendar', { static: true })\r\n calendar: DatePicker;\r\n\r\n readonly field = input<boolean>(true);\r\n readonly label = input<string>();\r\n readonly placeholder = input<string>();\r\n readonly class = input<string>('');\r\n readonly readonly = input<boolean>(false);\r\n readonly showIcon = input<boolean>(true);\r\n readonly showClear = input<boolean>(false);\r\n readonly showTime = input<boolean>(false);\r\n readonly pInputs = input<Partial<DatePicker>>();\r\n readonly required = input<boolean>(false);\r\n\r\n rtl = signal<boolean>(document.documentElement.dir === 'rtl');\r\n\r\n @HostBinding('class') styleClass: string;\r\n\r\n requiredValidator = Validators.required;\r\n value = signal<string | null>(null);\r\n disabled = signal<boolean>(false);\r\n\r\n onTouched: () => void = () => {};\r\n onModelChange: (value: string) => void = () => {};\r\n\r\n public ngControl = inject(NgControl, { self: true });\r\n\r\n isInvalid = isInvalid;\r\n\r\n constructor() {\r\n if (this.ngControl) {\r\n this.ngControl.valueAccessor = this;\r\n }\r\n effect(() => {\r\n if (this.ngControl.control && this.required()) {\r\n this.ngControl.control.addValidators(Validators.required);\r\n this.ngControl.control.updateValueAndValidity();\r\n }\r\n });\r\n }\r\n\r\n applyInputsToCalendar() {\r\n Object.assign(this.calendar, this.pInputs());\r\n }\r\n\r\n ngOnInit() {\r\n this.styleClass = this.class();\r\n if (this.pInputs()) {\r\n this.applyInputsToCalendar();\r\n }\r\n }\r\n onValueChange(value: string) {\r\n this.onModelChange(value);\r\n this.value.set(value);\r\n }\r\n ngOnChanges(changes: SimpleChanges) {\r\n if (changes['pInputs']) {\r\n this.applyInputsToCalendar();\r\n }\r\n }\r\n\r\n writeValue(value: string) {\r\n this.value.set(value);\r\n }\r\n\r\n registerOnChange(fn: any) {\r\n this.onModelChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: any) {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState(disabled: boolean) {\r\n this.disabled.set(disabled);\r\n }\r\n}\r\n","@if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >{{ label() }}</label\r\n >\r\n}\r\n<p-datepicker\r\n #calendar\r\n [ngModel]=\"value()\"\r\n (ngModelChange)=\"onValueChange($event)\"\r\n (onBlur)=\"onTouched()\"\r\n [disabled]=\"disabled() || readonly()\"\r\n [inputId]=\"ngControl?.name ? ngControl?.name?.toString() : label()\"\r\n [invalid]=\"isInvalid(ngControl?.control)\"\r\n [baseZIndex]=\"1051\"\r\n placeholder=\"{{ placeholder() ?? label() ?? '' }}\"\r\n inputStyleClass=\"w-full\"\r\n [showIcon]=\"showIcon()\"\r\n [showClear]=\"showClear()\"\r\n [showTime]=\"showTime()\"\r\n dateFormat=\"dd/mm/yy\"\r\n appendTo=\"body\"\r\n>\r\n <ng-template #previousicon>\r\n <mt-icon\r\n [icon]=\"rtl() ? 'arrow.chevron-right' : 'arrow.chevron-left'\"\r\n class=\"text-2xl\"\r\n />\r\n </ng-template>\r\n <ng-template #nexticon>\r\n <mt-icon\r\n [icon]=\"rtl() ? 'arrow.chevron-left' : 'arrow.chevron-right'\"\r\n class=\"text-2xl\"\r\n />\r\n </ng-template>\r\n</p-datepicker>\r\n\r\n<!-- <mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation> -->\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"masterteam-components-date-field.mjs","sources":["../../../../packages/masterteam/components/date-field/date-field.ts","../../../../packages/masterteam/components/date-field/date-field.html","../../../../packages/masterteam/components/date-field/masterteam-components-date-field.ts"],"sourcesContent":["import {\r\n Component,\r\n HostBinding,\r\n OnChanges,\r\n OnInit,\r\n SimpleChanges,\r\n ViewChild,\r\n signal,\r\n input,\r\n inject,\r\n ChangeDetectionStrategy,\r\n effect,\r\n} from '@angular/core';\r\nimport {\r\n ControlValueAccessor,\r\n FormsModule,\r\n NgControl,\r\n Validators,\r\n} from '@angular/forms';\r\nimport { DatePickerModule, DatePicker } from 'primeng/datepicker';\r\nimport { isInvalid } from '@masterteam/components';\r\nimport { Icon } from '@masterteam/icons';\r\n\r\n@Component({\r\n selector: 'mt-date-field',\r\n standalone: true,\r\n imports: [FormsModule, DatePickerModule, Icon],\r\n templateUrl: './date-field.html',\r\n styleUrls: ['./date-field.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n host: {\r\n class: 'grid gap-1',\r\n },\r\n})\r\nexport class DateField implements ControlValueAccessor, OnInit, OnChanges {\r\n @ViewChild('calendar', { static: true })\r\n calendar: DatePicker;\r\n\r\n readonly field = input<boolean>(true);\r\n readonly label = input<string>();\r\n readonly placeholder = input<string>();\r\n readonly class = input<string>('');\r\n readonly readonly = input<boolean>(false);\r\n readonly showIcon = input<boolean>(true);\r\n readonly showClear = input<boolean>(false);\r\n readonly showTime = input<boolean>(false);\r\n readonly pInputs = input<Partial<DatePicker>>();\r\n readonly required = input<boolean>(false);\r\n\r\n rtl = signal<boolean>(document.documentElement.dir === 'rtl');\r\n\r\n @HostBinding('class') styleClass: string;\r\n\r\n requiredValidator = Validators.required;\r\n value = signal<string | null>(null);\r\n disabled = signal<boolean>(false);\r\n\r\n onTouched: () => void = () => {};\r\n onModelChange: (value: string) => void = () => {};\r\n\r\n public ngControl = inject(NgControl, { self: true });\r\n\r\n isInvalid = isInvalid;\r\n\r\n constructor() {\r\n if (this.ngControl) {\r\n this.ngControl.valueAccessor = this;\r\n }\r\n effect(() => {\r\n if (this.ngControl.control && this.required()) {\r\n this.ngControl.control.addValidators(Validators.required);\r\n this.ngControl.control.updateValueAndValidity();\r\n }\r\n });\r\n }\r\n\r\n applyInputsToCalendar() {\r\n Object.assign(this.calendar, this.pInputs());\r\n }\r\n\r\n ngOnInit() {\r\n this.styleClass = this.class();\r\n if (this.pInputs()) {\r\n this.applyInputsToCalendar();\r\n }\r\n }\r\n onValueChange(value: string) {\r\n this.onModelChange(value);\r\n this.value.set(value);\r\n }\r\n ngOnChanges(changes: SimpleChanges) {\r\n if (changes['pInputs']) {\r\n this.applyInputsToCalendar();\r\n }\r\n }\r\n\r\n writeValue(value: string) {\r\n this.value.set(value);\r\n }\r\n\r\n registerOnChange(fn: any) {\r\n this.onModelChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: any) {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState(disabled: boolean) {\r\n this.disabled.set(disabled);\r\n }\r\n}\r\n","@if (label()) {\r\n <label\r\n [class.required]=\"ngControl?.control?.hasValidator(requiredValidator)\"\r\n [for]=\"ngControl?.name || label()\"\r\n >{{ label() }}</label\r\n >\r\n}\r\n<p-datepicker\r\n #calendar\r\n [ngModel]=\"value()\"\r\n (ngModelChange)=\"onValueChange($event)\"\r\n (onBlur)=\"onTouched()\"\r\n [disabled]=\"disabled() || readonly()\"\r\n [inputId]=\"ngControl?.name ? ngControl?.name?.toString() : label()\"\r\n [invalid]=\"isInvalid(ngControl?.control)\"\r\n [baseZIndex]=\"1051\"\r\n placeholder=\"{{ placeholder() ?? label() ?? '' }}\"\r\n inputStyleClass=\"w-full\"\r\n [showIcon]=\"showIcon()\"\r\n [showClear]=\"showClear()\"\r\n [showTime]=\"showTime()\"\r\n dateFormat=\"dd/mm/yy\"\r\n appendTo=\"body\"\r\n>\r\n <ng-template #previousicon>\r\n <mt-icon\r\n [icon]=\"rtl() ? 'arrow.chevron-right' : 'arrow.chevron-left'\"\r\n class=\"text-2xl\"\r\n />\r\n </ng-template>\r\n <ng-template #nexticon>\r\n <mt-icon\r\n [icon]=\"rtl() ? 'arrow.chevron-left' : 'arrow.chevron-right'\"\r\n class=\"text-2xl\"\r\n />\r\n </ng-template>\r\n</p-datepicker>\r\n\r\n<!-- <mt-field-validation [control]=\"ngControl?.control\"></mt-field-validation> -->\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -100,6 +100,7 @@ class EntityStatus {
100
100
  }, ...(ngDevMode ? [{ debugName: "badgeStyle" }] : []));
101
101
  emptyLabel = ENTITY_EMPTY_VALUE_PLACEHOLDER;
102
102
  statusLabel = computed(() => displayOrPlaceholder(this.statusValue()?.display), ...(ngDevMode ? [{ debugName: "statusLabel" }] : []));
103
+ hideName = computed(() => this.data()?.configuration?.hideName ?? false, ...(ngDevMode ? [{ debugName: "hideName" }] : []));
103
104
  hexToRgba(hex, alpha) {
104
105
  const r = parseInt(hex.slice(1, 3), 16);
105
106
  const g = parseInt(hex.slice(3, 5), 16);
@@ -107,11 +108,11 @@ class EntityStatus {
107
108
  return `rgba(${r}, ${g}, ${b}, ${alpha})`;
108
109
  }
109
110
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityStatus, deps: [], target: i0.ɵɵFactoryTarget.Component });
110
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityStatus, isStandalone: true, selector: "mt-entity-status", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex flex-col gap-1\">\r\n @if (statusValue(); as status) {\r\n <span\r\n class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit\"\r\n [style]=\"badgeStyle()\"\r\n >\r\n {{ statusLabel() }}\r\n </span>\r\n } @else {\r\n <span\r\n class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit text-gray-500 bg-gray-100\"\r\n >\r\n {{ emptyLabel }}\r\n </span>\r\n }\r\n <!-- <span class=\"text-xs text-gray-500\">{{ displayName() }}</span> -->\r\n</div>\r\n" });
111
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityStatus, isStandalone: true, selector: "mt-entity-status", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"flex flex-col gap-1\">\r\n @if (statusValue(); as status) {\r\n <span\r\n class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit\"\r\n [style]=\"badgeStyle()\"\r\n >\r\n {{ statusLabel() }}\r\n </span>\r\n } @else {\r\n <span\r\n class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit text-gray-500 bg-gray-100\"\r\n >\r\n {{ emptyLabel }}\r\n </span>\r\n }\r\n @if (!hideName()) {\r\n <span class=\"text-sm text-gray-500\">{{ displayName() }}</span>\r\n }\r\n</div>\r\n" });
111
112
  }
112
113
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityStatus, decorators: [{
113
114
  type: Component,
114
- args: [{ selector: 'mt-entity-status', standalone: true, template: "<div class=\"flex flex-col gap-1\">\r\n @if (statusValue(); as status) {\r\n <span\r\n class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit\"\r\n [style]=\"badgeStyle()\"\r\n >\r\n {{ statusLabel() }}\r\n </span>\r\n } @else {\r\n <span\r\n class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit text-gray-500 bg-gray-100\"\r\n >\r\n {{ emptyLabel }}\r\n </span>\r\n }\r\n <!-- <span class=\"text-xs text-gray-500\">{{ displayName() }}</span> -->\r\n</div>\r\n" }]
115
+ args: [{ selector: 'mt-entity-status', standalone: true, template: "<div class=\"flex flex-col gap-1\">\r\n @if (statusValue(); as status) {\r\n <span\r\n class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit\"\r\n [style]=\"badgeStyle()\"\r\n >\r\n {{ statusLabel() }}\r\n </span>\r\n } @else {\r\n <span\r\n class=\"inline-flex items-center px-3 py-2 rounded-md text-xs font-semibold w-fit text-gray-500 bg-gray-100\"\r\n >\r\n {{ emptyLabel }}\r\n </span>\r\n }\r\n @if (!hideName()) {\r\n <span class=\"text-sm text-gray-500\">{{ displayName() }}</span>\r\n }\r\n</div>\r\n" }]
115
116
  }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });
116
117
 
117
118
  class EntityUser {
@@ -580,12 +581,10 @@ class EntityPreview {
580
581
  attachmentShape = input('default', ...(ngDevMode ? [{ debugName: "attachmentShape" }] : []));
581
582
  previewType = computed(() => {
582
583
  const viewType = this.data().viewType;
583
- return viewType === 'LookupMatrix' || viewType === 'Status'
584
- ? 'Lookup'
585
- : viewType;
584
+ return viewType === 'LookupMatrix' ? 'Lookup' : viewType;
586
585
  }, ...(ngDevMode ? [{ debugName: "previewType" }] : []));
587
586
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityPreview, deps: [], target: i0.ɵɵFactoryTarget.Component });
588
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityPreview, isStandalone: true, selector: "mt-entity-preview", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, attachmentShape: { classPropertyName: "attachmentShape", publicName: "attachmentShape", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "w-full" }, ngImport: i0, template: "@switch (previewType()) {\r\n @case (\"Text\") {\r\n <mt-entity-text [data]=\"data()\" />\r\n }\r\n @case (\"LongText\") {\r\n <mt-entity-long-text [data]=\"data()\" />\r\n }\r\n @case (\"Date\") {\r\n <mt-entity-date [data]=\"data()\" />\r\n }\r\n @case (\"DateTime\") {\r\n <mt-entity-date [data]=\"data()\" />\r\n }\r\n @case (\"User\") {\r\n <mt-entity-user [data]=\"data()\" />\r\n }\r\n @case (\"Percentage\") {\r\n <mt-entity-percentage [data]=\"data()\" />\r\n }\r\n @case (\"Currency\") {\r\n <mt-entity-currency [data]=\"data()\" />\r\n }\r\n @case (\"Checkbox\") {\r\n <mt-entity-checkbox [data]=\"data()\" />\r\n }\r\n @case (\"Lookup\") {\r\n <mt-entity-lookup [data]=\"data()\" />\r\n }\r\n @case (\"Attachment\") {\r\n <mt-entity-attachment [data]=\"data()\" [shape]=\"attachmentShape()\" />\r\n }\r\n @default {\r\n <mt-entity-text [data]=\"data()\" />\r\n }\r\n}\r\n", dependencies: [{ kind: "component", type: EntityText, selector: "mt-entity-text", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityLongText, selector: "mt-entity-long-text", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityDate, selector: "mt-entity-date", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityUser, selector: "mt-entity-user", inputs: ["data"] }, { kind: "component", type: EntityPercentage, selector: "mt-entity-percentage", inputs: ["data", "name", "value", "rawValue"] }, { kind: "component", type: EntityCurrency, selector: "mt-entity-currency", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityCheckbox, selector: "mt-entity-checkbox", inputs: ["data", "name", "value", "rawValue"] }, { kind: "component", type: EntityLookup, selector: "mt-entity-lookup", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityAttachment, selector: "mt-entity-attachment", inputs: ["data", "name", "shape", "value", "endPoint", "context"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
587
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntityPreview, isStandalone: true, selector: "mt-entity-preview", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: true, transformFunction: null }, attachmentShape: { classPropertyName: "attachmentShape", publicName: "attachmentShape", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "w-full" }, ngImport: i0, template: "@switch (previewType()) {\r\n @case (\"Text\") {\r\n <mt-entity-text [data]=\"data()\" />\r\n }\r\n @case (\"LongText\") {\r\n <mt-entity-long-text [data]=\"data()\" />\r\n }\r\n @case (\"Date\") {\r\n <mt-entity-date [data]=\"data()\" />\r\n }\r\n @case (\"DateTime\") {\r\n <mt-entity-date [data]=\"data()\" />\r\n }\r\n @case (\"User\") {\r\n <mt-entity-user [data]=\"data()\" />\r\n }\r\n @case (\"Percentage\") {\r\n <mt-entity-percentage [data]=\"data()\" />\r\n }\r\n @case (\"Currency\") {\r\n <mt-entity-currency [data]=\"data()\" />\r\n }\r\n @case (\"Checkbox\") {\r\n <mt-entity-checkbox [data]=\"data()\" />\r\n }\r\n @case (\"Lookup\") {\r\n <mt-entity-lookup [data]=\"data()\" />\r\n }\r\n @case (\"Status\") {\r\n <mt-entity-status [data]=\"data()\" />\r\n }\r\n @case (\"Attachment\") {\r\n <mt-entity-attachment [data]=\"data()\" [shape]=\"attachmentShape()\" />\r\n }\r\n @default {\r\n <mt-entity-text [data]=\"data()\" />\r\n }\r\n}\r\n", dependencies: [{ kind: "component", type: EntityText, selector: "mt-entity-text", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityLongText, selector: "mt-entity-long-text", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityDate, selector: "mt-entity-date", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityUser, selector: "mt-entity-user", inputs: ["data"] }, { kind: "component", type: EntityPercentage, selector: "mt-entity-percentage", inputs: ["data", "name", "value", "rawValue"] }, { kind: "component", type: EntityCurrency, selector: "mt-entity-currency", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityCheckbox, selector: "mt-entity-checkbox", inputs: ["data", "name", "value", "rawValue"] }, { kind: "component", type: EntityLookup, selector: "mt-entity-lookup", inputs: ["data", "name", "value"] }, { kind: "component", type: EntityAttachment, selector: "mt-entity-attachment", inputs: ["data", "name", "shape", "value", "endPoint", "context"] }, { kind: "component", type: EntityStatus, selector: "mt-entity-status", inputs: ["data", "name", "value"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
589
588
  }
590
589
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityPreview, decorators: [{
591
590
  type: Component,
@@ -599,9 +598,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
599
598
  EntityCheckbox,
600
599
  EntityLookup,
601
600
  EntityAttachment,
601
+ EntityStatus,
602
602
  ], host: {
603
603
  class: 'w-full',
604
- }, template: "@switch (previewType()) {\r\n @case (\"Text\") {\r\n <mt-entity-text [data]=\"data()\" />\r\n }\r\n @case (\"LongText\") {\r\n <mt-entity-long-text [data]=\"data()\" />\r\n }\r\n @case (\"Date\") {\r\n <mt-entity-date [data]=\"data()\" />\r\n }\r\n @case (\"DateTime\") {\r\n <mt-entity-date [data]=\"data()\" />\r\n }\r\n @case (\"User\") {\r\n <mt-entity-user [data]=\"data()\" />\r\n }\r\n @case (\"Percentage\") {\r\n <mt-entity-percentage [data]=\"data()\" />\r\n }\r\n @case (\"Currency\") {\r\n <mt-entity-currency [data]=\"data()\" />\r\n }\r\n @case (\"Checkbox\") {\r\n <mt-entity-checkbox [data]=\"data()\" />\r\n }\r\n @case (\"Lookup\") {\r\n <mt-entity-lookup [data]=\"data()\" />\r\n }\r\n @case (\"Attachment\") {\r\n <mt-entity-attachment [data]=\"data()\" [shape]=\"attachmentShape()\" />\r\n }\r\n @default {\r\n <mt-entity-text [data]=\"data()\" />\r\n }\r\n}\r\n" }]
604
+ }, template: "@switch (previewType()) {\r\n @case (\"Text\") {\r\n <mt-entity-text [data]=\"data()\" />\r\n }\r\n @case (\"LongText\") {\r\n <mt-entity-long-text [data]=\"data()\" />\r\n }\r\n @case (\"Date\") {\r\n <mt-entity-date [data]=\"data()\" />\r\n }\r\n @case (\"DateTime\") {\r\n <mt-entity-date [data]=\"data()\" />\r\n }\r\n @case (\"User\") {\r\n <mt-entity-user [data]=\"data()\" />\r\n }\r\n @case (\"Percentage\") {\r\n <mt-entity-percentage [data]=\"data()\" />\r\n }\r\n @case (\"Currency\") {\r\n <mt-entity-currency [data]=\"data()\" />\r\n }\r\n @case (\"Checkbox\") {\r\n <mt-entity-checkbox [data]=\"data()\" />\r\n }\r\n @case (\"Lookup\") {\r\n <mt-entity-lookup [data]=\"data()\" />\r\n }\r\n @case (\"Status\") {\r\n <mt-entity-status [data]=\"data()\" />\r\n }\r\n @case (\"Attachment\") {\r\n <mt-entity-attachment [data]=\"data()\" [shape]=\"attachmentShape()\" />\r\n }\r\n @default {\r\n <mt-entity-text [data]=\"data()\" />\r\n }\r\n}\r\n" }]
605
605
  }], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: true }] }], attachmentShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "attachmentShape", required: false }] }] } });
606
606
 
607
607
  class EntitiesPreview {
@@ -686,13 +686,18 @@ class EntitiesResizeBase {
686
686
  const cellEl = event.target.closest('.entity-cell');
687
687
  if (!cellEl)
688
688
  return;
689
- const cellLeft = cellEl.getBoundingClientRect().left;
689
+ const cellRect = cellEl.getBoundingClientRect();
690
+ const isRtl = this.doc.documentElement.getAttribute('dir') === 'rtl' ||
691
+ getComputedStyle(this.doc.documentElement).direction === 'rtl';
690
692
  this.resizingEntity.set(entity);
691
693
  this.resizePreviewSize.set(previousSize);
692
694
  // Run mouse listeners outside Angular zone for performance
693
695
  this.zone.runOutsideAngular(() => {
694
696
  this._onMouseMove = (e) => {
695
- const rawWidth = e.clientX - cellLeft;
697
+ // In RTL the logical end is the left edge; dragging left widens the cell
698
+ const rawWidth = isRtl
699
+ ? cellRect.right - e.clientX
700
+ : e.clientX - cellRect.left;
696
701
  // Snap to nearest full column (min 1, max 12)
697
702
  let cols = Math.round(rawWidth / columnWidth);
698
703
  cols = Math.max(1, Math.min(24, cols));
@@ -785,11 +790,11 @@ class EntitiesManage extends EntitiesResizeBase {
785
790
  });
786
791
  }
787
792
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesManage, deps: null, target: i0.ɵɵFactoryTarget.Component });
788
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntitiesManage, isStandalone: true, selector: "mt-entities-manage", inputs: { entities: { classPropertyName: "entities", publicName: "entities", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { entities: "entitiesChange", entitiesReordered: "entitiesReordered" }, usesInheritance: true, ngImport: i0, template: "<div\r\n cdkDropList\r\n cdkDropListOrientation=\"mixed\"\r\n [cdkDropListData]=\"sortedEntities()\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"grid grid-cols-24 gap-x-4 gap-y-7\"\r\n>\r\n @for (entity of sortedEntities(); track entity.order) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"entity\"\r\n class=\"entity-cell group relative min-w-0 flex items-center p-3 cursor-grab active:cursor-grabbing\"\r\n [class.border]=\"entity.configuration?.showBorder\"\r\n [class.border-dashed]=\"entity.configuration?.showBorder\"\r\n [class.border-gray-200]=\"entity.configuration?.showBorder\"\r\n [class.rounded-lg]=\"entity.configuration?.showBorder\"\r\n [class.resizing]=\"resizingEntity() === entity\"\r\n [style.grid-column]=\"getColSpan(entity)\"\r\n >\r\n <!-- Drag placeholder -->\r\n <div\r\n *cdkDragPlaceholder\r\n class=\"h-full min-h-12 bg-black/10 rounded-xl\"\r\n [style.grid-column]=\"getColSpan(entity)\"\r\n ></div>\r\n\r\n <mt-entity-preview [data]=\"entity\" class=\"flex-1 min-w-0\" />\r\n\r\n <!-- Resize handle (right edge) -->\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, entity)\">\r\n <div class=\"resize-handle-bar\"></div>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".cdk-drag{cursor:grab}.cdk-drag:active{cursor:grabbing}.cdk-drag-preview{cursor:grabbing;overflow:hidden}.cdk-drag-placeholder{opacity:.5}.cdk-drop-list-dragging .cdk-drag{cursor:grabbing}.entity-cell{position:relative}.resize-handle{position:absolute;top:0;right:-4px;width:8px;height:100%;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease}.entity-cell:hover .resize-handle,.entity-cell.resizing .resize-handle{opacity:1}.resize-handle-bar{width:3px;height:24px;border-radius:2px;background-color:var(--p-primary-color, #6366f1);transition:height .15s ease,background-color .15s ease}.resize-handle:hover .resize-handle-bar{height:36px;background-color:var(--p-primary-color, #4f46e5)}.entity-cell.resizing{outline:2px dashed var(--p-primary-color, #6366f1);outline-offset:-1px;border-radius:8px;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "component", type: EntityPreview, selector: "mt-entity-preview", inputs: ["data", "attachmentShape"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }] });
793
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: EntitiesManage, isStandalone: true, selector: "mt-entities-manage", inputs: { entities: { classPropertyName: "entities", publicName: "entities", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { entities: "entitiesChange", entitiesReordered: "entitiesReordered" }, usesInheritance: true, ngImport: i0, template: "<div\r\n cdkDropList\r\n cdkDropListOrientation=\"mixed\"\r\n [cdkDropListData]=\"sortedEntities()\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"grid grid-cols-24 gap-x-4 gap-y-6\"\r\n>\r\n @for (entity of sortedEntities(); track entity.order) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"entity\"\r\n class=\"entity-cell group relative min-w-0 flex items-center p-3 cursor-grab active:cursor-grabbing\"\r\n [class.border]=\"entity.configuration?.showBorder\"\r\n [class.border-dashed]=\"entity.configuration?.showBorder\"\r\n [class.border-gray-200]=\"entity.configuration?.showBorder\"\r\n [class.rounded-lg]=\"entity.configuration?.showBorder\"\r\n [class.resizing]=\"resizingEntity() === entity\"\r\n [style.grid-column]=\"getColSpan(entity)\"\r\n >\r\n <!-- Drag placeholder -->\r\n <div\r\n *cdkDragPlaceholder\r\n class=\"h-full min-h-12 bg-black/10 rounded-xl\"\r\n [style.grid-column]=\"getColSpan(entity)\"\r\n ></div>\r\n\r\n <mt-entity-preview [data]=\"entity\" class=\"flex-1 min-w-0\" />\r\n\r\n <!-- Resize handle (right edge) -->\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, entity)\">\r\n <div class=\"resize-handle-bar\"></div>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".cdk-drag{cursor:grab}.cdk-drag:active{cursor:grabbing}.cdk-drag-preview{cursor:grabbing;overflow:hidden}.cdk-drag-placeholder{opacity:.5}.cdk-drop-list-dragging .cdk-drag{cursor:grabbing}.entity-cell{position:relative}.resize-handle{position:absolute;top:0;inset-inline-end:-4px;width:8px;height:100%;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease}.entity-cell:hover .resize-handle,.entity-cell.resizing .resize-handle{opacity:1}.resize-handle-bar{width:3px;height:24px;border-radius:2px;background-color:var(--p-primary-color, #6366f1);transition:height .15s ease,background-color .15s ease}.resize-handle:hover .resize-handle-bar{height:36px;background-color:var(--p-primary-color, #4f46e5)}.entity-cell.resizing{outline:2px dashed var(--p-primary-color, #6366f1);outline-offset:-1px;border-radius:8px;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "component", type: EntityPreview, selector: "mt-entity-preview", inputs: ["data", "attachmentShape"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }] });
789
794
  }
790
795
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntitiesManage, decorators: [{
791
796
  type: Component,
792
- args: [{ selector: 'mt-entities-manage', standalone: true, imports: [EntityPreview, CdkDrag, CdkDropList, CdkDragPlaceholder], template: "<div\r\n cdkDropList\r\n cdkDropListOrientation=\"mixed\"\r\n [cdkDropListData]=\"sortedEntities()\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"grid grid-cols-24 gap-x-4 gap-y-7\"\r\n>\r\n @for (entity of sortedEntities(); track entity.order) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"entity\"\r\n class=\"entity-cell group relative min-w-0 flex items-center p-3 cursor-grab active:cursor-grabbing\"\r\n [class.border]=\"entity.configuration?.showBorder\"\r\n [class.border-dashed]=\"entity.configuration?.showBorder\"\r\n [class.border-gray-200]=\"entity.configuration?.showBorder\"\r\n [class.rounded-lg]=\"entity.configuration?.showBorder\"\r\n [class.resizing]=\"resizingEntity() === entity\"\r\n [style.grid-column]=\"getColSpan(entity)\"\r\n >\r\n <!-- Drag placeholder -->\r\n <div\r\n *cdkDragPlaceholder\r\n class=\"h-full min-h-12 bg-black/10 rounded-xl\"\r\n [style.grid-column]=\"getColSpan(entity)\"\r\n ></div>\r\n\r\n <mt-entity-preview [data]=\"entity\" class=\"flex-1 min-w-0\" />\r\n\r\n <!-- Resize handle (right edge) -->\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, entity)\">\r\n <div class=\"resize-handle-bar\"></div>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".cdk-drag{cursor:grab}.cdk-drag:active{cursor:grabbing}.cdk-drag-preview{cursor:grabbing;overflow:hidden}.cdk-drag-placeholder{opacity:.5}.cdk-drop-list-dragging .cdk-drag{cursor:grabbing}.entity-cell{position:relative}.resize-handle{position:absolute;top:0;right:-4px;width:8px;height:100%;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease}.entity-cell:hover .resize-handle,.entity-cell.resizing .resize-handle{opacity:1}.resize-handle-bar{width:3px;height:24px;border-radius:2px;background-color:var(--p-primary-color, #6366f1);transition:height .15s ease,background-color .15s ease}.resize-handle:hover .resize-handle-bar{height:36px;background-color:var(--p-primary-color, #4f46e5)}.entity-cell.resizing{outline:2px dashed var(--p-primary-color, #6366f1);outline-offset:-1px;border-radius:8px;-webkit-user-select:none;user-select:none}\n"] }]
797
+ args: [{ selector: 'mt-entities-manage', standalone: true, imports: [EntityPreview, CdkDrag, CdkDropList, CdkDragPlaceholder], template: "<div\r\n cdkDropList\r\n cdkDropListOrientation=\"mixed\"\r\n [cdkDropListData]=\"sortedEntities()\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"grid grid-cols-24 gap-x-4 gap-y-6\"\r\n>\r\n @for (entity of sortedEntities(); track entity.order) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"entity\"\r\n class=\"entity-cell group relative min-w-0 flex items-center p-3 cursor-grab active:cursor-grabbing\"\r\n [class.border]=\"entity.configuration?.showBorder\"\r\n [class.border-dashed]=\"entity.configuration?.showBorder\"\r\n [class.border-gray-200]=\"entity.configuration?.showBorder\"\r\n [class.rounded-lg]=\"entity.configuration?.showBorder\"\r\n [class.resizing]=\"resizingEntity() === entity\"\r\n [style.grid-column]=\"getColSpan(entity)\"\r\n >\r\n <!-- Drag placeholder -->\r\n <div\r\n *cdkDragPlaceholder\r\n class=\"h-full min-h-12 bg-black/10 rounded-xl\"\r\n [style.grid-column]=\"getColSpan(entity)\"\r\n ></div>\r\n\r\n <mt-entity-preview [data]=\"entity\" class=\"flex-1 min-w-0\" />\r\n\r\n <!-- Resize handle (right edge) -->\r\n <div class=\"resize-handle\" (mousedown)=\"onResizeStart($event, entity)\">\r\n <div class=\"resize-handle-bar\"></div>\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".cdk-drag{cursor:grab}.cdk-drag:active{cursor:grabbing}.cdk-drag-preview{cursor:grabbing;overflow:hidden}.cdk-drag-placeholder{opacity:.5}.cdk-drop-list-dragging .cdk-drag{cursor:grabbing}.entity-cell{position:relative}.resize-handle{position:absolute;top:0;inset-inline-end:-4px;width:8px;height:100%;cursor:col-resize;z-index:10;display:flex;align-items:center;justify-content:center;opacity:0;transition:opacity .15s ease}.entity-cell:hover .resize-handle,.entity-cell.resizing .resize-handle{opacity:1}.resize-handle-bar{width:3px;height:24px;border-radius:2px;background-color:var(--p-primary-color, #6366f1);transition:height .15s ease,background-color .15s ease}.resize-handle:hover .resize-handle-bar{height:36px;background-color:var(--p-primary-color, #4f46e5)}.entity-cell.resizing{outline:2px dashed var(--p-primary-color, #6366f1);outline-offset:-1px;border-radius:8px;-webkit-user-select:none;user-select:none}\n"] }]
793
798
  }], propDecorators: { entities: [{ type: i0.Input, args: [{ isSignal: true, alias: "entities", required: true }] }, { type: i0.Output, args: ["entitiesChange"] }], entitiesReordered: [{ type: i0.Output, args: ["entitiesReordered"] }] } });
794
799
 
795
800
  /**