@foxeltech/angular-ui 0.0.7 → 0.0.9

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.
@@ -313,13 +313,40 @@ class FxUtils {
313
313
  return _.isEqual(model, compareModel);
314
314
  }
315
315
  static parseError(err) {
316
- if (_.get(err, 'status') === 401) {
317
- return 'Session timeout. Please login again.';
318
- }
316
+ const status = _.get(err, 'status');
317
+ switch (status) {
318
+ case 401:
319
+ return 'Session timeout. Please login again.';
320
+ case 403:
321
+ return 'You do not have permission to perform this action.';
322
+ case 404:
323
+ return 'The requested resource was not found.';
324
+ case 408:
325
+ return 'The request timed out. Please try again.';
326
+ case 409:
327
+ return 'A conflict occurred. Please refresh and try again.';
328
+ case 413:
329
+ return 'The uploaded data is too large.';
330
+ case 415:
331
+ return 'Unsupported media type. Please check the file format.';
332
+ case 429:
333
+ return 'Too many requests. Please wait a moment and try again.';
334
+ case 500:
335
+ return 'An internal server error occurred. Please try again later.';
336
+ case 502:
337
+ return 'The server is temporarily unavailable. Please try again later.';
338
+ case 503:
339
+ return 'The service is currently unavailable. Please try again later.';
340
+ case 504:
341
+ return 'The server took too long to respond. Please try again later.';
342
+ }
343
+ const message = this.isStringEmpty(_.get(err, 'error.errors', ''))
344
+ ? _.get(err, 'error.message', 'Unknown Error')
345
+ : _.get(err, 'error.errors');
319
346
  if (this.isStringEmpty(_.get(err, 'error.code'))) {
320
- return _.get(err, 'error.errors', 'Unknown Error');
347
+ return message;
321
348
  }
322
- return `${_.get(err, 'error.code')}: ${_.get(err, 'error.errors', 'Unknown Error')}`;
349
+ return `${_.get(err, 'error.code')}: ${message}`;
323
350
  }
324
351
  static convertColorFromVariable(name, alpha = 1) {
325
352
  const value = getComputedStyle(document.body)
@@ -1626,11 +1653,13 @@ class ChartComponent {
1626
1653
  showPieLabel = true;
1627
1654
  mobileWidth = 350;
1628
1655
  labelFontFamily = 'DMSans';
1656
+ emptyText = 'No data available';
1629
1657
  /* ================= OUTPUTS ================= */
1630
1658
  chartClick = new EventEmitter();
1631
1659
  chartInit = new EventEmitter();
1632
1660
  /* ================= INTERNAL ================= */
1633
1661
  chartOptions = {};
1662
+ isEmpty = false;
1634
1663
  labelFontSize = 12;
1635
1664
  chartInstance;
1636
1665
  resizeObserver;
@@ -1707,12 +1736,34 @@ class ChartComponent {
1707
1736
  this.chartInstance.resize();
1708
1737
  }
1709
1738
  rebuildChart() {
1739
+ this.isEmpty = this.checkEmpty();
1740
+ if (this.isEmpty) {
1741
+ if (this.chartInstance) {
1742
+ this.chartInstance.clear();
1743
+ }
1744
+ return;
1745
+ }
1710
1746
  this.chartOptions = this.buildOptions();
1711
1747
  if (this.chartInstance) {
1712
1748
  this.chartInstance.clear();
1713
1749
  this.chartInstance.setOption(this.chartOptions, true);
1714
1750
  }
1715
1751
  }
1752
+ checkEmpty() {
1753
+ const type = this.detectType();
1754
+ if (type === 'bar') {
1755
+ const categories = this.data?.categories;
1756
+ const values = this.data?.values;
1757
+ return !categories?.length || !values?.length;
1758
+ }
1759
+ if (type === 'pie') {
1760
+ if (!Array.isArray(this.data) || this.data.length === 0)
1761
+ return true;
1762
+ const total = this.data.reduce((sum, d) => sum + (d.value || 0), 0);
1763
+ return total === 0;
1764
+ }
1765
+ return false;
1766
+ }
1716
1767
  /* ================= REGISTRY ================= */
1717
1768
  registry = {
1718
1769
  bar: (data, colors) => ({
@@ -1952,11 +2003,11 @@ class ChartComponent {
1952
2003
  });
1953
2004
  }
1954
2005
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChartComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1955
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: ChartComponent, isStandalone: false, selector: "fx-ui-chart", inputs: { type: "type", data: "data", options: "options", palette: "palette", height: "height", loading: "loading", pieLegendAlign: "pieLegendAlign", pieLegendPosition: "pieLegendPosition", showPieLabel: "showPieLabel", mobileWidth: "mobileWidth", labelFontFamily: "labelFontFamily" }, outputs: { chartClick: "chartClick", chartInit: "chartInit" }, host: { listeners: { "window:theme-changed": "onThemeChange()" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"chart-wrapper\" [style.height]=\"height\">\n <div\n echarts\n [options]=\"chartOptions\"\n [loading]=\"loading\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n class=\"fx-chart\"\n [style.height]=\"height\"\n ></div>\n</div>\n", styles: [":host{display:block;width:100%}.chart-wrapper{position:relative;width:100%;height:100%}.chart-container{width:100%;height:100%}.chart-loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(var(--bg-primary-hover)/.6);font-weight:500;font-size:1.1rem;z-index:2;border-radius:4px}\n"], dependencies: [{ kind: "directive", type: i1$5.NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }] });
2006
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ChartComponent, isStandalone: false, selector: "fx-ui-chart", inputs: { type: "type", data: "data", options: "options", palette: "palette", height: "height", loading: "loading", pieLegendAlign: "pieLegendAlign", pieLegendPosition: "pieLegendPosition", showPieLabel: "showPieLabel", mobileWidth: "mobileWidth", labelFontFamily: "labelFontFamily", emptyText: "emptyText" }, outputs: { chartClick: "chartClick", chartInit: "chartInit" }, host: { listeners: { "window:theme-changed": "onThemeChange()" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"chart-wrapper\" [style.height]=\"height\">\n @if (isEmpty) {\n <div class=\"chart-empty\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"chart-empty-icon\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z\" />\n </svg>\n <span class=\"chart-empty-text\">{{ emptyText }}</span>\n </div>\n } @else {\n <div\n echarts\n [options]=\"chartOptions\"\n [loading]=\"loading\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n class=\"fx-chart\"\n [style.height]=\"height\"\n ></div>\n }\n</div>\n", styles: [":host{display:block;width:100%}.chart-wrapper{position:relative;width:100%;height:100%}.chart-container{width:100%;height:100%}.chart-loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(var(--bg-primary-hover)/.6);font-weight:500;font-size:1.1rem;z-index:2;border-radius:4px}.chart-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;color:rgba(var(--text-secondary)/1)}.chart-empty-icon{width:48px;height:48px;opacity:.4}.chart-empty-text{font-size:14px;font-weight:500}\n"], dependencies: [{ kind: "directive", type: i1$5.NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }] });
1956
2007
  }
1957
2008
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChartComponent, decorators: [{
1958
2009
  type: Component,
1959
- args: [{ selector: 'fx-ui-chart', standalone: false, template: "<div class=\"chart-wrapper\" [style.height]=\"height\">\n <div\n echarts\n [options]=\"chartOptions\"\n [loading]=\"loading\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n class=\"fx-chart\"\n [style.height]=\"height\"\n ></div>\n</div>\n", styles: [":host{display:block;width:100%}.chart-wrapper{position:relative;width:100%;height:100%}.chart-container{width:100%;height:100%}.chart-loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(var(--bg-primary-hover)/.6);font-weight:500;font-size:1.1rem;z-index:2;border-radius:4px}\n"] }]
2010
+ args: [{ selector: 'fx-ui-chart', standalone: false, template: "<div class=\"chart-wrapper\" [style.height]=\"height\">\n @if (isEmpty) {\n <div class=\"chart-empty\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"chart-empty-icon\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z\" />\n </svg>\n <span class=\"chart-empty-text\">{{ emptyText }}</span>\n </div>\n } @else {\n <div\n echarts\n [options]=\"chartOptions\"\n [loading]=\"loading\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n class=\"fx-chart\"\n [style.height]=\"height\"\n ></div>\n }\n</div>\n", styles: [":host{display:block;width:100%}.chart-wrapper{position:relative;width:100%;height:100%}.chart-container{width:100%;height:100%}.chart-loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(var(--bg-primary-hover)/.6);font-weight:500;font-size:1.1rem;z-index:2;border-radius:4px}.chart-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;color:rgba(var(--text-secondary)/1)}.chart-empty-icon{width:48px;height:48px;opacity:.4}.chart-empty-text{font-size:14px;font-weight:500}\n"] }]
1960
2011
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { type: [{
1961
2012
  type: Input
1962
2013
  }], data: [{
@@ -1979,6 +2030,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
1979
2030
  type: Input
1980
2031
  }], labelFontFamily: [{
1981
2032
  type: Input
2033
+ }], emptyText: [{
2034
+ type: Input
1982
2035
  }], chartClick: [{
1983
2036
  type: Output
1984
2037
  }], chartInit: [{
@@ -3339,6 +3392,7 @@ class DrawerComponent {
3339
3392
  items = [];
3340
3393
  isExpanded = true;
3341
3394
  logo;
3395
+ version;
3342
3396
  toggleExpanded = new EventEmitter();
3343
3397
  itemClicked = new EventEmitter();
3344
3398
  expandedItems = new Set();
@@ -3436,7 +3490,7 @@ class DrawerComponent {
3436
3490
  return this.isExpanded ? 'expanded' : 'collapsed';
3437
3491
  }
3438
3492
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DrawerComponent, deps: [{ token: i1$4.Router }], target: i0.ɵɵFactoryTarget.Component });
3439
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: DrawerComponent, isStandalone: false, selector: "fx-ui-drawer", inputs: { items: "items", isExpanded: "isExpanded", logo: "logo" }, outputs: { toggleExpanded: "toggleExpanded", itemClicked: "itemClicked" }, ngImport: i0, template: "<div class=\"drawer-host-wrapper\">\n <a\n href=\"/\"\n class=\"h-[60px]\"\n [ngClass]=\"{ 'flex items-center justify-center': !isExpanded, 'p-4': isExpanded }\"\n >\n @if (logo) {\n <img\n [src]=\"logo\"\n class=\"h-[20px] w-auto transition-all duration-300 ease-in-out\"\n [ngClass]=\"{ 'scale-90': !isExpanded, 'ml-5': isExpanded }\"\n />\n } @else {\n <div class=\"h-[30px] w-auto transition-all duration-300 ease-in-out\"></div>\n }\n </a>\n <div class=\"drawer-container\" [@drawerExpand]=\"getDrawerState()\">\n <!-- Navigation Items -->\n <nav class=\"drawer-nav\">\n <ng-container *ngFor=\"let item of items\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: item, level: 0 }\"\n ></ng-container>\n </ng-container>\n </nav>\n </div>\n\n <!-- Floating Toggle Button on right border -->\n <button\n type=\"button\"\n class=\"toggle-btn\"\n (click)=\"toggleDrawer()\"\n [matTooltip]=\"isExpanded ? 'Collapse' : 'Expand'\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n matTooltipPosition=\"right\"\n >\n <fx-ui-hero-icon\n [icon]=\"isExpanded ? 'chevron-left' : 'chevron-right'\"\n [size]=\"16\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n </button>\n</div>\n\n<!-- Recursive Template for Drawer Items -->\n<ng-template #drawerItem let-item let-level=\"level\">\n <div class=\"drawer-item-wrapper\">\n <!-- Item Button/Link -->\n <a\n *ngIf=\"item.route && !item.children\"\n [routerLink]=\"item.route\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n </div>\n </a>\n\n <button\n *ngIf=\"!item.route || item.children\"\n type=\"button\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-sm font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n <fx-ui-hero-icon\n *ngIf=\"isExpanded && item.children && item.children.length > 0\"\n [icon]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"chevron-icon\"\n [class.rotated]=\"isAccordionExpanded(item.id)\"\n ></fx-ui-hero-icon>\n </div>\n </button>\n\n <!-- Accordion Children -->\n <div\n *ngIf=\"item.children && item.children.length > 0\"\n class=\"accordion-children\"\n [@accordionExpand]=\"getAccordionState(item.id)\"\n >\n <ng-container *ngFor=\"let child of item.children\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: child, level: level + 1 }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.drawer-host-wrapper{position:relative;height:100%;border-right-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1))}.drawer-container{display:flex;height:100%;flex-direction:column;overflow:auto;--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));padding-left:.5rem;padding-right:.5rem;transition:width .3s cubic-bezier(.4,0,.2,1)}.toggle-btn{position:absolute;top:50%;z-index:50;display:flex;height:1.5rem;width:1.5rem;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));--tw-shadow: 0 1px 2px 0 rgb(var(--shadow-color) / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);right:-12px;transition:all .2s ease}.toggle-btn:hover{--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1));--tw-shadow: 0 4px 6px -1px rgb(var(--shadow-color) / .1), 0 2px 4px -2px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.toggle-btn:active{transform:translateY(-50%) scale(.9)}.toggle-btn:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary) / 1)}.drawer-nav{flex:1 1 0%;overflow-y:auto;overflow-x:hidden;padding-top:.5rem;padding-bottom:.5rem}.drawer-nav::-webkit-scrollbar{width:.375rem}.drawer-nav::-webkit-scrollbar-track{background-color:transparent}.drawer-nav::-webkit-scrollbar-thumb{border-radius:.125rem;--tw-bg-opacity: 1;background-color:rgb(var(--border-default) / var(--tw-bg-opacity, 1))}.drawer-nav::-webkit-scrollbar-thumb:hover{--tw-bg-opacity: 1;background-color:rgb(var(--text-placeholder) / var(--tw-bg-opacity, 1))}.drawer-item-wrapper{position:relative}.drawer-item{position:relative;margin-top:.25rem;display:flex;min-height:2rem;width:100%;cursor:pointer;align-items:center;border-radius:.25rem;border-style:none;background-color:transparent;padding:.5rem 1rem;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1));text-decoration-line:none;transition:all .2s ease}.drawer-item:hover{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1))}.drawer-item.active{background-image:linear-gradient(135deg,rgb(var(--gradient-primary-start)),rgb(var(--gradient-primary-end)));font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.drawer-item.active .item-icon{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.drawer-item:active{transform:scale(.98)}.drawer-item:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary) / 1)}.drawer-item{-webkit-tap-highlight-color:transparent;outline:2px solid transparent;outline-offset:2px}.item-content{display:flex;width:100%;align-items:center;gap:.75rem;overflow:hidden}.item-icon{flex-shrink:0;color:inherit}.item-label{flex:1 1 0%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;font-size:13px;line-height:1.25rem}.chevron-icon{margin-left:auto;flex-shrink:0;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1));transition:transform .3s cubic-bezier(.4,0,.2,1)}.chevron-icon.rotated{transform:rotate(180deg)}.accordion-children{overflow:hidden}.drawer-container[style*=\"width: 64px\"] .drawer-item{justify-content:center;padding-left:16px!important}.drawer-container[style*=\"width: 64px\"] .item-content{justify-content:center}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$4.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i47.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], animations: [
3493
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: DrawerComponent, isStandalone: false, selector: "fx-ui-drawer", inputs: { items: "items", isExpanded: "isExpanded", logo: "logo", version: "version" }, outputs: { toggleExpanded: "toggleExpanded", itemClicked: "itemClicked" }, ngImport: i0, template: "<div class=\"drawer-host-wrapper\">\n <a\n href=\"/\"\n class=\"h-[60px]\"\n [ngClass]=\"{ 'flex items-center justify-center': !isExpanded, 'p-4': isExpanded }\"\n >\n @if (logo) {\n <img\n [src]=\"logo\"\n class=\"h-[20px] w-auto transition-all duration-300 ease-in-out\"\n [ngClass]=\"{ 'scale-90': !isExpanded, 'ml-5': isExpanded }\"\n />\n } @else {\n <div class=\"h-[30px] w-auto transition-all duration-300 ease-in-out\"></div>\n }\n </a>\n <div class=\"drawer-container\" [@drawerExpand]=\"getDrawerState()\">\n <!-- Navigation Items -->\n <nav class=\"drawer-nav\">\n <ng-container *ngFor=\"let item of items\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: item, level: 0 }\"\n ></ng-container>\n </ng-container>\n </nav>\n\n <!-- Version -->\n <div *ngIf=\"version\" class=\"drawer-version\" [matTooltip]=\"!isExpanded ? version : ''\" matTooltipPosition=\"right\">\n <span *ngIf=\"isExpanded\">{{ version }}</span>\n <span *ngIf=\"!isExpanded\" class=\"drawer-version-dot\"></span>\n </div>\n </div>\n\n <!-- Floating Toggle Button on right border -->\n <button\n type=\"button\"\n class=\"toggle-btn\"\n (click)=\"toggleDrawer()\"\n [matTooltip]=\"isExpanded ? 'Collapse' : 'Expand'\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n matTooltipPosition=\"right\"\n >\n <fx-ui-hero-icon\n [icon]=\"isExpanded ? 'chevron-left' : 'chevron-right'\"\n [size]=\"16\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n </button>\n</div>\n\n<!-- Recursive Template for Drawer Items -->\n<ng-template #drawerItem let-item let-level=\"level\">\n <div class=\"drawer-item-wrapper\">\n <!-- Item Button/Link -->\n <a\n *ngIf=\"item.route && !item.children\"\n [routerLink]=\"item.route\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n </div>\n </a>\n\n <button\n *ngIf=\"!item.route || item.children\"\n type=\"button\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-sm font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n <fx-ui-hero-icon\n *ngIf=\"isExpanded && item.children && item.children.length > 0\"\n [icon]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"chevron-icon\"\n [class.rotated]=\"isAccordionExpanded(item.id)\"\n ></fx-ui-hero-icon>\n </div>\n </button>\n\n <!-- Accordion Children -->\n <div\n *ngIf=\"item.children && item.children.length > 0\"\n class=\"accordion-children\"\n [@accordionExpand]=\"getAccordionState(item.id)\"\n >\n <ng-container *ngFor=\"let child of item.children\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: child, level: level + 1 }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.drawer-host-wrapper{position:relative;height:100%;border-right-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1))}.drawer-container{display:flex;height:100%;flex-direction:column;overflow:auto;--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));padding-left:.5rem;padding-right:.5rem;transition:width .3s cubic-bezier(.4,0,.2,1)}.toggle-btn{position:absolute;top:50%;z-index:50;display:flex;height:1.5rem;width:1.5rem;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));--tw-shadow: 0 1px 2px 0 rgb(var(--shadow-color) / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);right:-12px;transition:all .2s ease}.toggle-btn:hover{--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1));--tw-shadow: 0 4px 6px -1px rgb(var(--shadow-color) / .1), 0 2px 4px -2px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.toggle-btn:active{transform:translateY(-50%) scale(.9)}.toggle-btn:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary) / 1)}.drawer-nav{flex:1 1 0%;overflow-y:auto;overflow-x:hidden;padding-top:.5rem;padding-bottom:.5rem}.drawer-nav::-webkit-scrollbar{width:.375rem}.drawer-nav::-webkit-scrollbar-track{background-color:transparent}.drawer-nav::-webkit-scrollbar-thumb{border-radius:.125rem;--tw-bg-opacity: 1;background-color:rgb(var(--border-default) / var(--tw-bg-opacity, 1))}.drawer-nav::-webkit-scrollbar-thumb:hover{--tw-bg-opacity: 1;background-color:rgb(var(--text-placeholder) / var(--tw-bg-opacity, 1))}.drawer-item-wrapper{position:relative}.drawer-item{position:relative;margin-top:.25rem;display:flex;min-height:2rem;width:100%;cursor:pointer;align-items:center;border-radius:.25rem;border-style:none;background-color:transparent;padding:.5rem 1rem;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1));text-decoration-line:none;transition:all .2s ease}.drawer-item:hover{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1))}.drawer-item.active{background-image:linear-gradient(135deg,rgb(var(--gradient-primary-start)),rgb(var(--gradient-primary-end)));font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.drawer-item.active .item-icon{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.drawer-item:active{transform:scale(.98)}.drawer-item:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary) / 1)}.drawer-item{-webkit-tap-highlight-color:transparent;outline:2px solid transparent;outline-offset:2px}.item-content{display:flex;width:100%;align-items:center;gap:.75rem;overflow:hidden}.item-icon{flex-shrink:0;color:inherit}.item-label{flex:1 1 0%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;font-size:13px;line-height:1.25rem}.chevron-icon{margin-left:auto;flex-shrink:0;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1));transition:transform .3s cubic-bezier(.4,0,.2,1)}.chevron-icon.rotated{transform:rotate(180deg)}.accordion-children{overflow:hidden}.drawer-version{display:flex;-webkit-user-select:none;user-select:none;align-items:center;justify-content:center;border-top-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));padding:.75rem 1rem;font-size:11px;--tw-text-opacity: 1;color:rgb(var(--text-placeholder) / var(--tw-text-opacity, 1));font-family:DMSans,monospace}.drawer-version-dot{display:block;height:.375rem;width:.375rem;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(var(--text-placeholder) / var(--tw-bg-opacity, 1))}.drawer-container[style*=\"width: 64px\"] .drawer-item{justify-content:center;padding-left:16px!important}.drawer-container[style*=\"width: 64px\"] .item-content{justify-content:center}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$4.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i47.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], animations: [
3440
3494
  trigger('drawerExpand', [
3441
3495
  state('collapsed', style({ width: '70px' })),
3442
3496
  state('expanded', style({ width: '260px' })),
@@ -3462,13 +3516,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
3462
3516
  state('expanded', style({ height: '*', overflow: 'visible', opacity: 1 })),
3463
3517
  transition('collapsed <=> expanded', animate('300ms cubic-bezier(0.4, 0, 0.2, 1)')),
3464
3518
  ]),
3465
- ], template: "<div class=\"drawer-host-wrapper\">\n <a\n href=\"/\"\n class=\"h-[60px]\"\n [ngClass]=\"{ 'flex items-center justify-center': !isExpanded, 'p-4': isExpanded }\"\n >\n @if (logo) {\n <img\n [src]=\"logo\"\n class=\"h-[20px] w-auto transition-all duration-300 ease-in-out\"\n [ngClass]=\"{ 'scale-90': !isExpanded, 'ml-5': isExpanded }\"\n />\n } @else {\n <div class=\"h-[30px] w-auto transition-all duration-300 ease-in-out\"></div>\n }\n </a>\n <div class=\"drawer-container\" [@drawerExpand]=\"getDrawerState()\">\n <!-- Navigation Items -->\n <nav class=\"drawer-nav\">\n <ng-container *ngFor=\"let item of items\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: item, level: 0 }\"\n ></ng-container>\n </ng-container>\n </nav>\n </div>\n\n <!-- Floating Toggle Button on right border -->\n <button\n type=\"button\"\n class=\"toggle-btn\"\n (click)=\"toggleDrawer()\"\n [matTooltip]=\"isExpanded ? 'Collapse' : 'Expand'\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n matTooltipPosition=\"right\"\n >\n <fx-ui-hero-icon\n [icon]=\"isExpanded ? 'chevron-left' : 'chevron-right'\"\n [size]=\"16\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n </button>\n</div>\n\n<!-- Recursive Template for Drawer Items -->\n<ng-template #drawerItem let-item let-level=\"level\">\n <div class=\"drawer-item-wrapper\">\n <!-- Item Button/Link -->\n <a\n *ngIf=\"item.route && !item.children\"\n [routerLink]=\"item.route\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n </div>\n </a>\n\n <button\n *ngIf=\"!item.route || item.children\"\n type=\"button\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-sm font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n <fx-ui-hero-icon\n *ngIf=\"isExpanded && item.children && item.children.length > 0\"\n [icon]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"chevron-icon\"\n [class.rotated]=\"isAccordionExpanded(item.id)\"\n ></fx-ui-hero-icon>\n </div>\n </button>\n\n <!-- Accordion Children -->\n <div\n *ngIf=\"item.children && item.children.length > 0\"\n class=\"accordion-children\"\n [@accordionExpand]=\"getAccordionState(item.id)\"\n >\n <ng-container *ngFor=\"let child of item.children\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: child, level: level + 1 }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.drawer-host-wrapper{position:relative;height:100%;border-right-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1))}.drawer-container{display:flex;height:100%;flex-direction:column;overflow:auto;--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));padding-left:.5rem;padding-right:.5rem;transition:width .3s cubic-bezier(.4,0,.2,1)}.toggle-btn{position:absolute;top:50%;z-index:50;display:flex;height:1.5rem;width:1.5rem;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));--tw-shadow: 0 1px 2px 0 rgb(var(--shadow-color) / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);right:-12px;transition:all .2s ease}.toggle-btn:hover{--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1));--tw-shadow: 0 4px 6px -1px rgb(var(--shadow-color) / .1), 0 2px 4px -2px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.toggle-btn:active{transform:translateY(-50%) scale(.9)}.toggle-btn:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary) / 1)}.drawer-nav{flex:1 1 0%;overflow-y:auto;overflow-x:hidden;padding-top:.5rem;padding-bottom:.5rem}.drawer-nav::-webkit-scrollbar{width:.375rem}.drawer-nav::-webkit-scrollbar-track{background-color:transparent}.drawer-nav::-webkit-scrollbar-thumb{border-radius:.125rem;--tw-bg-opacity: 1;background-color:rgb(var(--border-default) / var(--tw-bg-opacity, 1))}.drawer-nav::-webkit-scrollbar-thumb:hover{--tw-bg-opacity: 1;background-color:rgb(var(--text-placeholder) / var(--tw-bg-opacity, 1))}.drawer-item-wrapper{position:relative}.drawer-item{position:relative;margin-top:.25rem;display:flex;min-height:2rem;width:100%;cursor:pointer;align-items:center;border-radius:.25rem;border-style:none;background-color:transparent;padding:.5rem 1rem;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1));text-decoration-line:none;transition:all .2s ease}.drawer-item:hover{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1))}.drawer-item.active{background-image:linear-gradient(135deg,rgb(var(--gradient-primary-start)),rgb(var(--gradient-primary-end)));font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.drawer-item.active .item-icon{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.drawer-item:active{transform:scale(.98)}.drawer-item:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary) / 1)}.drawer-item{-webkit-tap-highlight-color:transparent;outline:2px solid transparent;outline-offset:2px}.item-content{display:flex;width:100%;align-items:center;gap:.75rem;overflow:hidden}.item-icon{flex-shrink:0;color:inherit}.item-label{flex:1 1 0%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;font-size:13px;line-height:1.25rem}.chevron-icon{margin-left:auto;flex-shrink:0;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1));transition:transform .3s cubic-bezier(.4,0,.2,1)}.chevron-icon.rotated{transform:rotate(180deg)}.accordion-children{overflow:hidden}.drawer-container[style*=\"width: 64px\"] .drawer-item{justify-content:center;padding-left:16px!important}.drawer-container[style*=\"width: 64px\"] .item-content{justify-content:center}\n"] }]
3519
+ ], template: "<div class=\"drawer-host-wrapper\">\n <a\n href=\"/\"\n class=\"h-[60px]\"\n [ngClass]=\"{ 'flex items-center justify-center': !isExpanded, 'p-4': isExpanded }\"\n >\n @if (logo) {\n <img\n [src]=\"logo\"\n class=\"h-[20px] w-auto transition-all duration-300 ease-in-out\"\n [ngClass]=\"{ 'scale-90': !isExpanded, 'ml-5': isExpanded }\"\n />\n } @else {\n <div class=\"h-[30px] w-auto transition-all duration-300 ease-in-out\"></div>\n }\n </a>\n <div class=\"drawer-container\" [@drawerExpand]=\"getDrawerState()\">\n <!-- Navigation Items -->\n <nav class=\"drawer-nav\">\n <ng-container *ngFor=\"let item of items\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: item, level: 0 }\"\n ></ng-container>\n </ng-container>\n </nav>\n\n <!-- Version -->\n <div *ngIf=\"version\" class=\"drawer-version\" [matTooltip]=\"!isExpanded ? version : ''\" matTooltipPosition=\"right\">\n <span *ngIf=\"isExpanded\">{{ version }}</span>\n <span *ngIf=\"!isExpanded\" class=\"drawer-version-dot\"></span>\n </div>\n </div>\n\n <!-- Floating Toggle Button on right border -->\n <button\n type=\"button\"\n class=\"toggle-btn\"\n (click)=\"toggleDrawer()\"\n [matTooltip]=\"isExpanded ? 'Collapse' : 'Expand'\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n matTooltipPosition=\"right\"\n >\n <fx-ui-hero-icon\n [icon]=\"isExpanded ? 'chevron-left' : 'chevron-right'\"\n [size]=\"16\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n </button>\n</div>\n\n<!-- Recursive Template for Drawer Items -->\n<ng-template #drawerItem let-item let-level=\"level\">\n <div class=\"drawer-item-wrapper\">\n <!-- Item Button/Link -->\n <a\n *ngIf=\"item.route && !item.children\"\n [routerLink]=\"item.route\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n </div>\n </a>\n\n <button\n *ngIf=\"!item.route || item.children\"\n type=\"button\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-sm font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n <fx-ui-hero-icon\n *ngIf=\"isExpanded && item.children && item.children.length > 0\"\n [icon]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"chevron-icon\"\n [class.rotated]=\"isAccordionExpanded(item.id)\"\n ></fx-ui-hero-icon>\n </div>\n </button>\n\n <!-- Accordion Children -->\n <div\n *ngIf=\"item.children && item.children.length > 0\"\n class=\"accordion-children\"\n [@accordionExpand]=\"getAccordionState(item.id)\"\n >\n <ng-container *ngFor=\"let child of item.children\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: child, level: level + 1 }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.drawer-host-wrapper{position:relative;height:100%;border-right-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1))}.drawer-container{display:flex;height:100%;flex-direction:column;overflow:auto;--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));padding-left:.5rem;padding-right:.5rem;transition:width .3s cubic-bezier(.4,0,.2,1)}.toggle-btn{position:absolute;top:50%;z-index:50;display:flex;height:1.5rem;width:1.5rem;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));--tw-shadow: 0 1px 2px 0 rgb(var(--shadow-color) / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);right:-12px;transition:all .2s ease}.toggle-btn:hover{--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1));--tw-shadow: 0 4px 6px -1px rgb(var(--shadow-color) / .1), 0 2px 4px -2px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.toggle-btn:active{transform:translateY(-50%) scale(.9)}.toggle-btn:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary) / 1)}.drawer-nav{flex:1 1 0%;overflow-y:auto;overflow-x:hidden;padding-top:.5rem;padding-bottom:.5rem}.drawer-nav::-webkit-scrollbar{width:.375rem}.drawer-nav::-webkit-scrollbar-track{background-color:transparent}.drawer-nav::-webkit-scrollbar-thumb{border-radius:.125rem;--tw-bg-opacity: 1;background-color:rgb(var(--border-default) / var(--tw-bg-opacity, 1))}.drawer-nav::-webkit-scrollbar-thumb:hover{--tw-bg-opacity: 1;background-color:rgb(var(--text-placeholder) / var(--tw-bg-opacity, 1))}.drawer-item-wrapper{position:relative}.drawer-item{position:relative;margin-top:.25rem;display:flex;min-height:2rem;width:100%;cursor:pointer;align-items:center;border-radius:.25rem;border-style:none;background-color:transparent;padding:.5rem 1rem;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1));text-decoration-line:none;transition:all .2s ease}.drawer-item:hover{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1))}.drawer-item.active{background-image:linear-gradient(135deg,rgb(var(--gradient-primary-start)),rgb(var(--gradient-primary-end)));font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.drawer-item.active .item-icon{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.drawer-item:active{transform:scale(.98)}.drawer-item:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary) / 1)}.drawer-item{-webkit-tap-highlight-color:transparent;outline:2px solid transparent;outline-offset:2px}.item-content{display:flex;width:100%;align-items:center;gap:.75rem;overflow:hidden}.item-icon{flex-shrink:0;color:inherit}.item-label{flex:1 1 0%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;font-size:13px;line-height:1.25rem}.chevron-icon{margin-left:auto;flex-shrink:0;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1));transition:transform .3s cubic-bezier(.4,0,.2,1)}.chevron-icon.rotated{transform:rotate(180deg)}.accordion-children{overflow:hidden}.drawer-version{display:flex;-webkit-user-select:none;user-select:none;align-items:center;justify-content:center;border-top-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));padding:.75rem 1rem;font-size:11px;--tw-text-opacity: 1;color:rgb(var(--text-placeholder) / var(--tw-text-opacity, 1));font-family:DMSans,monospace}.drawer-version-dot{display:block;height:.375rem;width:.375rem;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(var(--text-placeholder) / var(--tw-bg-opacity, 1))}.drawer-container[style*=\"width: 64px\"] .drawer-item{justify-content:center;padding-left:16px!important}.drawer-container[style*=\"width: 64px\"] .item-content{justify-content:center}\n"] }]
3466
3520
  }], ctorParameters: () => [{ type: i1$4.Router }], propDecorators: { items: [{
3467
3521
  type: Input
3468
3522
  }], isExpanded: [{
3469
3523
  type: Input
3470
3524
  }], logo: [{
3471
3525
  type: Input
3526
+ }], version: [{
3527
+ type: Input
3472
3528
  }], toggleExpanded: [{
3473
3529
  type: Output
3474
3530
  }], itemClicked: [{