@webilix/ngx-helper-m3 0.0.10 → 0.0.12

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, makeEnvironmentProviders, Injector, Component, HostBinding, Input, Injectable, Optional, Inject, EventEmitter, Output, inject, Directive, Pipe } from '@angular/core';
2
+ import { InjectionToken, makeEnvironmentProviders, Injector, Component, HostBinding, Input, Pipe, Injectable, Optional, Inject, EventEmitter, Output, inject, Directive, createComponent } from '@angular/core';
3
3
  import { NgComponentOutlet, NgClass } from '@angular/common';
4
4
  import * as i1$2 from '@angular/material/button';
5
5
  import { MatButton, MatIconButton, MatButtonModule } from '@angular/material/button';
@@ -9,15 +9,18 @@ import { MatIcon, MatIconModule } from '@angular/material/icon';
9
9
  import * as i2 from '@angular/material/menu';
10
10
  import { MatMenuModule } from '@angular/material/menu';
11
11
  import { Helper } from '@webilix/helper-library';
12
+ import { JalaliDateTime } from '@webilix/jalali-date-time';
12
13
  import * as i1 from '@angular/router';
13
14
  import * as i3 from '@angular/cdk/clipboard';
14
15
  import { ClipboardModule } from '@angular/cdk/clipboard';
15
- import { JalaliDateTime } from '@webilix/jalali-date-time';
16
16
  import * as i1$1 from '@angular/platform-browser';
17
17
  import * as i2$1 from '@angular/material/dialog';
18
18
  import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
19
19
  import * as i1$3 from '@angular/material/bottom-sheet';
20
20
  import { MAT_BOTTOM_SHEET_DATA } from '@angular/material/bottom-sheet';
21
+ import * as i1$4 from '@angular/common/http';
22
+ import { HttpHeaders, HttpEventType } from '@angular/common/http';
23
+ import { trigger, transition, style, animate } from '@angular/animations';
21
24
 
22
25
  const NGX_HELPER_CONFIG = new InjectionToken('NGX-HELPER-CONFIG');
23
26
  const provideNgxHelperConfig = (config) => {
@@ -76,228 +79,382 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
76
79
  args: [{ required: false }]
77
80
  }] } });
78
81
 
79
- class ComponentService {
80
- getComponentConfig(config) {
81
- const getStickyView = (config) => {
82
- return {
83
- desktopView: typeof config === 'string' ? config : config.desktopView,
84
- mobileView: typeof config === 'string' ? config : config.mobileView,
85
- };
86
- };
87
- return {
88
- mobileWidth: config?.mobileWidth || 600,
89
- pageGroupSidebarWidth: config?.pageGroupSidebarWidth || '200px',
90
- stickyView: config?.stickyView
91
- ? {
92
- top: config.stickyView.top ? getStickyView(config.stickyView.top) : undefined,
93
- bottom: config.stickyView.bottom ? getStickyView(config.stickyView.bottom) : undefined,
94
- }
95
- : undefined,
96
- };
82
+ class NgxHelperBankCardPipe {
83
+ transform(value, options) {
84
+ if (value === undefined || value === null || !Helper.IS.string(value) || value === '')
85
+ return '';
86
+ switch (options?.view) {
87
+ case 'BANK':
88
+ return Helper.BANK.findCard(value)?.title || '';
89
+ default:
90
+ return Helper.STRING.getBankCardView(value, options?.join || '-');
91
+ }
97
92
  }
98
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: ComponentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
99
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: ComponentService });
93
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperBankCardPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
94
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperBankCardPipe, isStandalone: true, name: "ngxHelperBankCard" });
100
95
  }
101
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: ComponentService, decorators: [{
102
- type: Injectable
96
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperBankCardPipe, decorators: [{
97
+ type: Pipe,
98
+ args: [{ name: 'ngxHelperBankCard' }]
103
99
  }] });
104
100
 
105
- class NgxHelperCardComponent {
106
- componentService;
107
- config;
108
- className = 'ngx-helper-m3-card';
109
- title;
110
- subTitle;
111
- icon;
112
- actions = [];
113
- padding = '1rem';
114
- backgroundColor;
115
- hasShadow = false;
116
- isMobile = false;
117
- buttons = [];
118
- componentConfig;
119
- constructor(componentService, config) {
120
- this.componentService = componentService;
121
- this.config = config;
101
+ class NgxHelperDatePipe {
102
+ transform(value, options) {
103
+ if (value === undefined || value === null || (!Helper.IS.date(value) && !Helper.IS.number(value)))
104
+ return '';
105
+ const date = typeof value === 'number' ? new Date(value) : value;
106
+ const jalali = JalaliDateTime();
107
+ const timezone = options?.timezone && jalali.timezones().includes(options?.timezone) ? options?.timezone : 'Asia/Tehran';
108
+ switch (options?.format || 'DATE') {
109
+ case 'FULL':
110
+ return jalali.toFullText(date, { format: 'W، d N Y H:I', timezone });
111
+ case 'SHORT':
112
+ return jalali.toFullText(date, { format: 'Y/M/D', timezone });
113
+ case 'DATE':
114
+ return jalali.toFullText(date, { format: 'W، d N Y', timezone });
115
+ case 'TIME':
116
+ return jalali.toFullText(date, { format: 'H:I', timezone });
117
+ case 'WEEK':
118
+ const { from, to } = jalali.periodWeek(1, date, timezone);
119
+ return Helper.DATE.jalaliPeriod(from, to, timezone);
120
+ case 'MONTH':
121
+ return jalali.toFullText(date, { format: 'N Y', timezone });
122
+ case 'YEAR':
123
+ return jalali.toFullText(date, { format: 'Y', timezone });
124
+ default:
125
+ return jalali.toFullText(date, { format: options?.format, timezone });
126
+ }
122
127
  }
123
- ngOnInit() {
124
- this.componentConfig = this.componentService.getComponentConfig(this.config);
125
- this.onResize();
128
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDatePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
129
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDatePipe, isStandalone: true, name: "ngxHelperDate" });
130
+ }
131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDatePipe, decorators: [{
132
+ type: Pipe,
133
+ args: [{ name: 'ngxHelperDate' }]
134
+ }] });
135
+
136
+ class NgxHelperDurationPipe {
137
+ transform(value, options) {
138
+ if (value === undefined || value === null)
139
+ return '';
140
+ let seconds = 0;
141
+ if (Helper.IS.number(value))
142
+ seconds = Math.abs(value);
143
+ else if (Helper.IS.date(value))
144
+ seconds = Math.floor(Math.abs(new Date().getTime() - value.getTime()) / 1000);
145
+ else if (Helper.IS.object(value)) {
146
+ const from = 'from' in value ? value.from : new Date();
147
+ const to = 'to' in value ? value.to : new Date();
148
+ seconds = Math.floor(Math.abs(from.getTime() - to.getTime()) / 1000);
149
+ }
150
+ const days = Math.floor(seconds / (24 * 60 * 60));
151
+ seconds -= days * (24 * 60 * 60);
152
+ const hours = Math.floor(seconds / (60 * 60));
153
+ seconds -= hours * (60 * 60);
154
+ const minutes = Math.floor(seconds / 60);
155
+ seconds -= minutes * 60;
156
+ const hasDays = days !== 0;
157
+ const time = [hours, minutes, seconds].map((v) => v.toString().padStart(2, '0')).join(':');
158
+ switch (options?.format || 'TEXT') {
159
+ case 'TEXT':
160
+ const hasTime = !!hours || !!minutes || !!seconds;
161
+ const day = hasDays
162
+ ? Helper.NUMBER.format(days, 'EN') + (!!options?.english ? (days === 1 ? ' day' : ' days') : ' روز')
163
+ : '';
164
+ const join = hasDays && hasTime ? (!!options?.english ? ', ' : ' و ') : '';
165
+ return (day + join + (!hasDays || hasTime ? time : '')).trim();
166
+ case 'FULL':
167
+ return (hasDays ? Helper.NUMBER.format(days, 'EN') + ':' : '') + time;
168
+ case 'DAY':
169
+ return Helper.NUMBER.format(days + (hours !== 0 || minutes !== 0 ? 1 : 0), !!options?.english ? 'EN' : 'FA');
170
+ case 'HOUR':
171
+ return Helper.NUMBER.format(days * 24 + hours + (minutes !== 0 ? 1 : 0), !!options?.english ? 'EN' : 'FA');
172
+ case 'MINUTE':
173
+ return Helper.NUMBER.format(days * 24 * 60 + hours * 60 + minutes, !!options?.english ? 'EN' : 'FA');
174
+ case 'SECOND':
175
+ return Helper.NUMBER.format(days * 24 * 3600 + hours * 3600 + minutes * 60 + seconds, !!options?.english ? 'EN' : 'FA');
176
+ }
126
177
  }
127
- ngOnChanges(changes) {
128
- this.className = `ngx-helper-m3-card${this.hasShadow ? ' has-shadow' : ''}`;
129
- this.buttons = this.actions.map((action) => {
130
- return 'buttons' in action ? { type: 'MENU', ...action } : { type: 'BUTTON', ...action };
131
- });
178
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDurationPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
179
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDurationPipe, isStandalone: true, name: "ngxHelperDuration" });
180
+ }
181
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDurationPipe, decorators: [{
182
+ type: Pipe,
183
+ args: [{ name: 'ngxHelperDuration' }]
184
+ }] });
185
+
186
+ class NgxHelperFileSizePipe {
187
+ transform(value, options) {
188
+ if (value === undefined || value === null || !Helper.IS.number(value))
189
+ return '';
190
+ return Helper.NUMBER.toFileSize(value, !!options?.english ? 'EN' : 'FA');
132
191
  }
133
- onResize() {
134
- this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
192
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperFileSizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
193
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperFileSizePipe, isStandalone: true, name: "ngxHelperFileSize" });
194
+ }
195
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperFileSizePipe, decorators: [{
196
+ type: Pipe,
197
+ args: [{ name: 'ngxHelperFileSize' }]
198
+ }] });
199
+
200
+ class NgxHelperMobilePipe {
201
+ transform(value, options) {
202
+ if (value === undefined || value === null || !Helper.IS.string(value) || value === '')
203
+ return '';
204
+ return Helper.STRING.getMobileView(value, options?.join || '-');
135
205
  }
136
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperCardComponent, deps: [{ token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
137
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperCardComponent, isStandalone: true, selector: "ngx-helper-card", inputs: { title: "title", subTitle: "subTitle", icon: "icon", actions: "actions", padding: "padding", backgroundColor: "backgroundColor", hasShadow: "hasShadow" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "className": "this.className" } }, providers: [ComponentService], usesOnChanges: true, ngImport: i0, template: "<div class=\"card-header\" [class.has-sub-title]=\"subTitle\">\n <!-- ICON -->\n @if (icon) { <mat-icon>{{ icon }}</mat-icon> }\n\n <!-- TITLE -->\n <div class=\"content\">\n <div class=\"title\">{{ title }}</div>\n <!-- SUB TITLE -->\n @if (subTitle) {\n <div class=\"sub-title\">{{ subTitle }}</div>\n }\n </div>\n\n <!-- BUTTONS -->\n @if (buttons.length > 0) {\n <div class=\"buttons\" [ngClass]=\"isMobile ? 'mobile-view' : ''\">\n @for (item of buttons; track $index) {\n <!-- TYPE -->\n @switch (item.type) {\n\n <!-- BUTTON -->\n @case('BUTTON') {\n <button mat-button type=\"button\" [style.color]=\"item.color\" (click)=\"item.action()\">\n @if (!isMobile) {\n <div class=\"title\">{{ item.title }}</div>\n }\n <!-- ICON -->\n @if (isMobile || item.showIcon) {\n <mat-icon>{{ item.icon }}</mat-icon>\n }\n </button>\n }\n\n <!-- MENU -->\n @case('MENU') {\n <button mat-button type=\"button\" [style.color]=\"item.color\" [matMenuTriggerFor]=\"actionMenu\">\n @if (!isMobile) {\n <div class=\"title\">{{ item.title }}</div>\n }\n <!-- ICON -->\n @if (isMobile || item.showIcon) {\n <mat-icon>{{ item.icon }}</mat-icon>\n }\n </button>\n <mat-menu #actionMenu=\"matMenu\" class=\"ngx-helper-card-action-menu\">\n @for (menu of item.buttons; track $index) {\n <!-- DIVIDER -->\n @if (menu === 'DIVIDER') { <mat-divider></mat-divider> }\n <!-- BUTTON -->\n @else {\n <button mat-menu-item type=\"button\" (click)=\"menu.action()\" [style.color]=\"menu.color\">\n <div class=\"title\">{{ menu.title }}</div>\n <mat-icon [style.color]=\"menu.color\">{{ menu.icon }}</mat-icon>\n </button>\n } }\n </mat-menu>\n } } }\n </div>\n }\n</div>\n\n<div class=\"card-content\" [style.padding]=\"padding\" [style.background-color]=\"backgroundColor\">\n <ng-content></ng-content>\n</div>\n", styles: ["::ng-deep .ngx-helper-card-action-menu button mat-icon{font-size:115%;margin:0 0 0 .75rem!important}::ng-deep .ngx-helper-card-action-menu button .title{font-size:90%!important}::ng-deep .ngx-helper-card-action-menu .mat-mdc-menu-content{padding:0}::ng-deep .ngx-helper-card-action-menu .mat-mdc-menu-item{direction:rtl;text-align:right}::ng-deep .ngx-helper-card-action-menu .mat-divider{margin:0;border-top-color:var(--outline-variant)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] });
206
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperMobilePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
207
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperMobilePipe, isStandalone: true, name: "ngxHelperMobile" });
138
208
  }
139
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperCardComponent, decorators: [{
140
- type: Component,
141
- args: [{ selector: 'ngx-helper-card', host: { '(window:resize)': 'onResize($event)' }, imports: [NgClass, MatButton, MatDivider, MatIcon, MatMenuModule], providers: [ComponentService], template: "<div class=\"card-header\" [class.has-sub-title]=\"subTitle\">\n <!-- ICON -->\n @if (icon) { <mat-icon>{{ icon }}</mat-icon> }\n\n <!-- TITLE -->\n <div class=\"content\">\n <div class=\"title\">{{ title }}</div>\n <!-- SUB TITLE -->\n @if (subTitle) {\n <div class=\"sub-title\">{{ subTitle }}</div>\n }\n </div>\n\n <!-- BUTTONS -->\n @if (buttons.length > 0) {\n <div class=\"buttons\" [ngClass]=\"isMobile ? 'mobile-view' : ''\">\n @for (item of buttons; track $index) {\n <!-- TYPE -->\n @switch (item.type) {\n\n <!-- BUTTON -->\n @case('BUTTON') {\n <button mat-button type=\"button\" [style.color]=\"item.color\" (click)=\"item.action()\">\n @if (!isMobile) {\n <div class=\"title\">{{ item.title }}</div>\n }\n <!-- ICON -->\n @if (isMobile || item.showIcon) {\n <mat-icon>{{ item.icon }}</mat-icon>\n }\n </button>\n }\n\n <!-- MENU -->\n @case('MENU') {\n <button mat-button type=\"button\" [style.color]=\"item.color\" [matMenuTriggerFor]=\"actionMenu\">\n @if (!isMobile) {\n <div class=\"title\">{{ item.title }}</div>\n }\n <!-- ICON -->\n @if (isMobile || item.showIcon) {\n <mat-icon>{{ item.icon }}</mat-icon>\n }\n </button>\n <mat-menu #actionMenu=\"matMenu\" class=\"ngx-helper-card-action-menu\">\n @for (menu of item.buttons; track $index) {\n <!-- DIVIDER -->\n @if (menu === 'DIVIDER') { <mat-divider></mat-divider> }\n <!-- BUTTON -->\n @else {\n <button mat-menu-item type=\"button\" (click)=\"menu.action()\" [style.color]=\"menu.color\">\n <div class=\"title\">{{ menu.title }}</div>\n <mat-icon [style.color]=\"menu.color\">{{ menu.icon }}</mat-icon>\n </button>\n } }\n </mat-menu>\n } } }\n </div>\n }\n</div>\n\n<div class=\"card-content\" [style.padding]=\"padding\" [style.background-color]=\"backgroundColor\">\n <ng-content></ng-content>\n</div>\n", styles: ["::ng-deep .ngx-helper-card-action-menu button mat-icon{font-size:115%;margin:0 0 0 .75rem!important}::ng-deep .ngx-helper-card-action-menu button .title{font-size:90%!important}::ng-deep .ngx-helper-card-action-menu .mat-mdc-menu-content{padding:0}::ng-deep .ngx-helper-card-action-menu .mat-mdc-menu-item{direction:rtl;text-align:right}::ng-deep .ngx-helper-card-action-menu .mat-divider{margin:0;border-top-color:var(--outline-variant)}\n"] }]
142
- }], ctorParameters: () => [{ type: ComponentService }, { type: undefined, decorators: [{
143
- type: Optional
144
- }, {
145
- type: Inject,
146
- args: [NGX_HELPER_CONFIG]
147
- }] }], propDecorators: { className: [{
148
- type: HostBinding,
149
- args: ['className']
150
- }], title: [{
151
- type: Input,
152
- args: [{ required: true }]
153
- }], subTitle: [{
154
- type: Input,
155
- args: [{ required: false }]
156
- }], icon: [{
157
- type: Input,
158
- args: [{ required: false }]
159
- }], actions: [{
160
- type: Input,
161
- args: [{ required: false }]
162
- }], padding: [{
163
- type: Input,
164
- args: [{ required: false }]
165
- }], backgroundColor: [{
166
- type: Input,
167
- args: [{ required: false }]
168
- }], hasShadow: [{
169
- type: Input,
170
- args: [{ required: false }]
171
- }] } });
209
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperMobilePipe, decorators: [{
210
+ type: Pipe,
211
+ args: [{ name: 'ngxHelperMobile' }]
212
+ }] });
172
213
 
173
- class NgxHelperLoaderComponent {
174
- loaderSize;
175
- loaderColor;
176
- mode;
177
- size;
178
- color;
179
- padding;
180
- ngOnChanges(changes) {
181
- this.loaderSize = `${this.size || 25}px`;
182
- this.loaderColor = this.color || `var(--secondary)`;
214
+ class NgxHelperNumberPipe {
215
+ transform(value, options) {
216
+ if (value === undefined || value === null || !Helper.IS.number(value))
217
+ return '';
218
+ value = options?.fractionDigits ? +value.toFixed(options?.fractionDigits) : value;
219
+ return Helper.NUMBER.format(value, options?.english ? 'EN' : 'FA');
183
220
  }
184
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
185
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperLoaderComponent, isStandalone: true, selector: "ngx-helper-loader", inputs: { mode: "mode", size: "size", color: "color", padding: "padding" }, host: { properties: { "style.--loader-size": "this.loaderSize", "style.--loader-color": "this.loaderColor" } }, usesOnChanges: true, ngImport: i0, template: "<div [style.padding]=\"padding || '0'\">\n <div [class]=\"mode.toLowerCase()\"></div>\n</div>\n", styles: [".spinner{--size: calc(var(--loader-size) / 7);width:var(--loader-size);aspect-ratio:1;border-radius:50%;background:radial-gradient(farthest-side,var(--loader-color) 94%,rgba(0,0,0,0)) top/var(--size) var(--size) no-repeat,conic-gradient(rgba(0,0,0,0) 30%,var(--loader-color));mask:radial-gradient(farthest-side,rgba(0,0,0,0) calc(100% - var(--size)),#000 0);animation:spinner 1s infinite linear}@keyframes spinner{to{transform:rotate(1turn)}}.dots-spinner{--dot: no-repeat radial-gradient(farthest-side, var(--loader-color) 92%, #0000);--size: calc(var(--loader-size) / 4);width:var(--loader-size);aspect-ratio:1;background:var(--dot) top,var(--dot) left,var(--dot) right,var(--dot) bottom;background-size:var(--size) var(--size);animation:dots-spinner 1s infinite}@keyframes dots-spinner{to{transform:rotate(.5turn)}}.wheel-spinner{--size: calc(var(--loader-size) / 9);width:var(--loader-size);aspect-ratio:1;border-radius:50%;background:var(--loader-color);mask:repeating-conic-gradient(rgba(0,0,0,0) 0deg,#000 1deg 70deg,rgba(0,0,0,0) 71deg 90deg),radial-gradient(farthest-side,rgba(0,0,0,0) calc(100% - var(--size) - 1px),#000 calc(100% - var(--size)));-webkit-mask-composite:destination-in;mask-composite:intersect;animation:wheel-spinner 1s infinite}@keyframes wheel-spinner{to{transform:rotate(.5turn)}}\n"] });
221
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperNumberPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
222
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperNumberPipe, isStandalone: true, name: "ngxHelperNumber" });
186
223
  }
187
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperLoaderComponent, decorators: [{
188
- type: Component,
189
- args: [{ selector: 'ngx-helper-loader', imports: [], template: "<div [style.padding]=\"padding || '0'\">\n <div [class]=\"mode.toLowerCase()\"></div>\n</div>\n", styles: [".spinner{--size: calc(var(--loader-size) / 7);width:var(--loader-size);aspect-ratio:1;border-radius:50%;background:radial-gradient(farthest-side,var(--loader-color) 94%,rgba(0,0,0,0)) top/var(--size) var(--size) no-repeat,conic-gradient(rgba(0,0,0,0) 30%,var(--loader-color));mask:radial-gradient(farthest-side,rgba(0,0,0,0) calc(100% - var(--size)),#000 0);animation:spinner 1s infinite linear}@keyframes spinner{to{transform:rotate(1turn)}}.dots-spinner{--dot: no-repeat radial-gradient(farthest-side, var(--loader-color) 92%, #0000);--size: calc(var(--loader-size) / 4);width:var(--loader-size);aspect-ratio:1;background:var(--dot) top,var(--dot) left,var(--dot) right,var(--dot) bottom;background-size:var(--size) var(--size);animation:dots-spinner 1s infinite}@keyframes dots-spinner{to{transform:rotate(.5turn)}}.wheel-spinner{--size: calc(var(--loader-size) / 9);width:var(--loader-size);aspect-ratio:1;border-radius:50%;background:var(--loader-color);mask:repeating-conic-gradient(rgba(0,0,0,0) 0deg,#000 1deg 70deg,rgba(0,0,0,0) 71deg 90deg),radial-gradient(farthest-side,rgba(0,0,0,0) calc(100% - var(--size) - 1px),#000 calc(100% - var(--size)));-webkit-mask-composite:destination-in;mask-composite:intersect;animation:wheel-spinner 1s infinite}@keyframes wheel-spinner{to{transform:rotate(.5turn)}}\n"] }]
190
- }], propDecorators: { loaderSize: [{
191
- type: HostBinding,
192
- args: ['style.--loader-size']
193
- }], loaderColor: [{
194
- type: HostBinding,
195
- args: ['style.--loader-color']
196
- }], mode: [{
197
- type: Input,
198
- args: [{ required: true }]
199
- }], size: [{
200
- type: Input,
201
- args: [{ required: false }]
202
- }], color: [{
203
- type: Input,
204
- args: [{ required: false }]
205
- }], padding: [{
206
- type: Input,
207
- args: [{ required: false }]
208
- }] } });
224
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperNumberPipe, decorators: [{
225
+ type: Pipe,
226
+ args: [{ name: 'ngxHelperNumber' }]
227
+ }] });
209
228
 
210
- const NGX_HELPER_PAGE_GROUP_ITEM = new InjectionToken('NGX-HELPER-PAGE-GROUP-ITEM');
211
- const NGX_HELPER_PAGE_GROUP_DATA = new InjectionToken('NGX-HELPER-PAGE-GROUP-DATA');
212
- const NGX_HELPER_PAGE_GROUP_DATA_CHANGE = new InjectionToken('NGX-HELPER-PAGE-GROUP-DATA-CHANGE');
229
+ class NgxHelperPeriodPipe {
230
+ transform(value, options) {
231
+ if (value === undefined || value === null)
232
+ return '';
233
+ const from = Helper.IS.date(value) ? value : 'from' in value ? value.from : new Date();
234
+ const to = Helper.IS.date(value) ? new Date() : 'to' in value ? value.to : new Date();
235
+ return Helper.DATE.jalaliPeriod(from, to, options?.timezone || '');
236
+ }
237
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPeriodPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
238
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPeriodPipe, isStandalone: true, name: "ngxHelperPeriod" });
239
+ }
240
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPeriodPipe, decorators: [{
241
+ type: Pipe,
242
+ args: [{ name: 'ngxHelperPeriod' }]
243
+ }] });
213
244
 
214
- class NgxHelperPageGroupComponent {
215
- activatedRoute;
216
- router;
245
+ class NgxHelperPricePipe {
246
+ transform(value, options) {
247
+ if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
248
+ return '';
249
+ const getPrice = (...titles) => {
250
+ if (value === undefined || value === null)
251
+ return '';
252
+ const price = Helper.NUMBER.format(+value.toFixed(2), !!options?.english ? 'EN' : 'FA');
253
+ const unit = titles[options?.short ? 0 : 1][options?.english ? 0 : 1];
254
+ const currency = options?.currency ? ' ' + options?.currency : '';
255
+ return `${price} ${unit}${currency}`;
256
+ };
257
+ if (value < 1000)
258
+ return getPrice(['', ''], ['', '']);
259
+ value /= 1000;
260
+ if (value < 1000)
261
+ return getPrice(['T', 'ه'], ['Thousand', 'هزار']);
262
+ value /= 1000;
263
+ if (value < 1000)
264
+ return getPrice(['M', 'م'], ['Million', 'میلیون']);
265
+ value /= 1000;
266
+ return getPrice(['B', 'د'], ['Billion', 'میلیارد']);
267
+ }
268
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPricePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
269
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPricePipe, isStandalone: true, name: "ngxHelperPrice" });
270
+ }
271
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPricePipe, decorators: [{
272
+ type: Pipe,
273
+ args: [{ name: 'ngxHelperPrice' }]
274
+ }] });
275
+
276
+ class NgxHelperVolumePipe {
277
+ transform(value, options) {
278
+ if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
279
+ return '';
280
+ const getVolume = (...titles) => {
281
+ if (value === undefined || value === null)
282
+ return '';
283
+ const volume = Helper.NUMBER.format(+value.toFixed(2), options?.english ? 'EN' : 'FA');
284
+ const shortIndex = options?.short ? 0 : 1;
285
+ const titleIndex = options?.english ? 0 : 1;
286
+ return `${volume} ${titles[shortIndex][titleIndex]}`;
287
+ };
288
+ if (value === 0)
289
+ return getVolume(['', ''], ['', '']);
290
+ if (value < 1000)
291
+ return getVolume(['ML', 'م'], ['Milliliter', 'میلی لیتر']);
292
+ value /= 1000;
293
+ return getVolume(['L', 'ل'], ['Liter', 'لیتر']);
294
+ }
295
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperVolumePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
296
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperVolumePipe, isStandalone: true, name: "ngxHelperVolume" });
297
+ }
298
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperVolumePipe, decorators: [{
299
+ type: Pipe,
300
+ args: [{ name: 'ngxHelperVolume' }]
301
+ }] });
302
+
303
+ class NgxHelperWeightPipe {
304
+ transform(value, options) {
305
+ if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
306
+ return '';
307
+ const getWeight = (...titles) => {
308
+ if (value === undefined || value === null)
309
+ return '';
310
+ const weight = Helper.NUMBER.format(+value.toFixed(2), options?.english ? 'EN' : 'FA');
311
+ const shortIndex = options?.short ? 0 : 1;
312
+ const titleIndex = options?.english ? 0 : 1;
313
+ return `${weight} ${titles[shortIndex][titleIndex]}`;
314
+ };
315
+ if (value === 0)
316
+ return getWeight(['', ''], ['', '']);
317
+ if (value < 1000)
318
+ return getWeight(['G', 'گ'], ['Gram', 'گرم']);
319
+ value /= 1000;
320
+ if (value < 1000)
321
+ return getWeight(['K', 'ک'], ['Kilogram', 'کیلو']);
322
+ value /= 1000;
323
+ if (value < 1000)
324
+ return getWeight(['T', 'ت'], ['Tonne', 'تن']);
325
+ value /= 1000;
326
+ return getWeight(['KT', 'ه'], ['Kilotonne', 'هزار تن']);
327
+ }
328
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperWeightPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
329
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperWeightPipe, isStandalone: true, name: "ngxHelperWeight" });
330
+ }
331
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperWeightPipe, decorators: [{
332
+ type: Pipe,
333
+ args: [{ name: 'ngxHelperWeight' }]
334
+ }] });
335
+
336
+ class NgxHelperValuePipe {
337
+ transform(value, options) {
338
+ const emptyText = options?.emptyText || '';
339
+ if (value === undefined || Helper.IS.empty(value))
340
+ return emptyText;
341
+ switch (value.type) {
342
+ case 'BANK-CARD':
343
+ return new NgxHelperBankCardPipe().transform(value.value, value) || emptyText;
344
+ case 'DATE':
345
+ return new NgxHelperDatePipe().transform(value.value, value) || emptyText;
346
+ case 'DURATION':
347
+ return new NgxHelperDurationPipe().transform(value.value, value) || emptyText;
348
+ case 'FILE-SIZE':
349
+ return new NgxHelperFileSizePipe().transform(value.value, value) || emptyText;
350
+ case 'MOBILE':
351
+ return new NgxHelperMobilePipe().transform(value.value, value) || emptyText;
352
+ case 'NUMBER':
353
+ return new NgxHelperNumberPipe().transform(value.value, value) || emptyText;
354
+ case 'PERIOD':
355
+ return new NgxHelperPeriodPipe().transform(value.value, value) || emptyText;
356
+ case 'PRICE':
357
+ return new NgxHelperPricePipe().transform(value.value, value) || emptyText;
358
+ case 'STRING':
359
+ return Helper.IS.string(value.value) ? value.value : emptyText;
360
+ case 'VOLUME':
361
+ return new NgxHelperVolumePipe().transform(value.value, value) || emptyText;
362
+ case 'WEIGHT':
363
+ return new NgxHelperWeightPipe().transform(value.value, value) || emptyText;
364
+ }
365
+ }
366
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
367
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValuePipe, isStandalone: true, name: "ngxHelperValue" });
368
+ }
369
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValuePipe, decorators: [{
370
+ type: Pipe,
371
+ args: [{ name: 'ngxHelperValue' }]
372
+ }] });
373
+
374
+ class ComponentService {
375
+ getComponentConfig(config) {
376
+ const getStickyView = (config) => {
377
+ return {
378
+ desktopView: typeof config === 'string' ? config : config.desktopView,
379
+ mobileView: typeof config === 'string' ? config : config.mobileView,
380
+ };
381
+ };
382
+ return {
383
+ mobileWidth: config?.mobileWidth || 600,
384
+ pageGroupSidebarWidth: config?.pageGroupSidebarWidth || '200px',
385
+ stickyView: config?.stickyView
386
+ ? {
387
+ top: config.stickyView.top ? getStickyView(config.stickyView.top) : undefined,
388
+ bottom: config.stickyView.bottom ? getStickyView(config.stickyView.bottom) : undefined,
389
+ }
390
+ : undefined,
391
+ };
392
+ }
393
+ getValueData(values) {
394
+ const pipeTransform = new NgxHelperValuePipe().transform;
395
+ const ltrValues = ['BANK-CARD', 'MOBILE', 'NUMBER'];
396
+ return values.map((item) => {
397
+ const value = item.value;
398
+ return value === undefined
399
+ ? { title: item.title, value: '' }
400
+ : typeof value === 'string'
401
+ ? { title: item.title, value: value.trim() }
402
+ : {
403
+ title: item.title,
404
+ value: pipeTransform(value),
405
+ color: item.color,
406
+ action: item.action,
407
+ copyToClipboard: item.copyToClipboard,
408
+ ltr: ltrValues.includes(value.type),
409
+ english: 'english' in value && !!value.english,
410
+ };
411
+ });
412
+ }
413
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: ComponentService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
414
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: ComponentService });
415
+ }
416
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: ComponentService, decorators: [{
417
+ type: Injectable
418
+ }] });
419
+
420
+ class NgxHelperCardComponent {
217
421
  componentService;
218
422
  config;
219
- className = 'ngx-helper-m3-page-group';
220
- display = 'none';
221
- pageGroup;
222
- pageIndex = 0;
223
- data;
224
- pageIndexChanged = new EventEmitter();
225
- dataChanged = new EventEmitter();
423
+ className = 'ngx-helper-m3-card';
424
+ title;
425
+ subTitle;
426
+ icon;
427
+ actions = [];
428
+ padding = '1rem';
429
+ backgroundColor;
430
+ hasShadow = false;
226
431
  isMobile = false;
227
- injector;
228
- sidebarWidth;
432
+ buttons = [];
229
433
  componentConfig;
230
- constructor(activatedRoute, router, componentService, config) {
231
- this.activatedRoute = activatedRoute;
232
- this.router = router;
434
+ constructor(componentService, config) {
233
435
  this.componentService = componentService;
234
436
  this.config = config;
235
437
  }
236
438
  ngOnInit() {
237
- this.display = this.pageGroup.pages.length === 0 ? 'none' : 'flex';
238
- if (this.pageGroup.pages.length === 0)
239
- return;
240
439
  this.componentConfig = this.componentService.getComponentConfig(this.config);
241
- this.sidebarWidth = this.pageGroup.sidebarWidth || this.componentConfig.pageGroupSidebarWidth;
242
- if (this.pageIndex < 0)
243
- this.pageIndex = 0;
244
- else if (this.pageIndex > this.pageGroup.pages.length - 1)
245
- this.pageIndex = this.pageGroup.pages.length - 1;
246
- const queryParams = { ...this.activatedRoute.snapshot.queryParams };
247
- if (!!this.pageGroup.route && Helper.IS.number(+queryParams['ngx-helper-page-group'])) {
248
- const index = +queryParams['ngx-helper-page-group'];
249
- if (index >= 0 && index <= this.pageGroup.pages.length - 1) {
250
- this.pageIndex = index;
251
- this.pageIndexChanged.next(this.pageIndex);
252
- }
253
- }
254
440
  this.onResize();
255
- this.setInjector();
256
441
  }
257
442
  ngOnChanges(changes) {
258
- this.setInjector();
443
+ this.className = `ngx-helper-m3-card${this.hasShadow ? ' has-shadow' : ''}`;
444
+ this.buttons = this.actions.map((action) => {
445
+ return 'buttons' in action ? { type: 'MENU', ...action } : { type: 'BUTTON', ...action };
446
+ });
259
447
  }
260
448
  onResize() {
261
449
  this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
262
- this.className = `ngx-helper-m3-page-group${this.isMobile ? ' mobile-view' : ''}`;
263
- }
264
- setInjector() {
265
- if (this.pageGroup.pages.length === 0)
266
- return;
267
- const item = {
268
- index: this.pageIndex,
269
- title: this.pageGroup.pages[this.pageIndex].title,
270
- icon: this.pageGroup.pages[this.pageIndex].icon,
271
- };
272
- this.injector = Injector.create({
273
- providers: [
274
- { provide: NGX_HELPER_PAGE_GROUP_ITEM, useValue: item },
275
- { provide: NGX_HELPER_PAGE_GROUP_DATA, useValue: this.data },
276
- { provide: NGX_HELPER_PAGE_GROUP_DATA_CHANGE, useValue: (data) => this.dataChanged.next(data) },
277
- ],
278
- });
279
- }
280
- setPage(index) {
281
- if (this.pageGroup.pages.length === 0)
282
- return;
283
- if (this.pageIndex === index || index < 0 || index > this.pageGroup.pages.length - 1)
284
- return;
285
- this.pageIndex = index;
286
- this.pageIndexChanged.next(this.pageIndex);
287
- this.setInjector();
288
- if (this.pageGroup.route) {
289
- const queryParams = { ...this.activatedRoute.snapshot.queryParams };
290
- queryParams['ngx-helper-page-group'] = this.pageIndex.toString();
291
- this.router.navigate(this.pageGroup.route, { queryParams });
292
- }
293
450
  }
294
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPageGroupComponent, deps: [{ token: i1.ActivatedRoute }, { token: i1.Router }, { token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
295
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperPageGroupComponent, isStandalone: true, selector: "ngx-helper-page-group", inputs: { pageGroup: "pageGroup", pageIndex: "pageIndex", data: "data" }, outputs: { pageIndexChanged: "pageIndexChanged", dataChanged: "dataChanged" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "className": "this.className", "style.display": "this.display" } }, providers: [ComponentService], usesOnChanges: true, ngImport: i0, template: "@if (pageGroup.pages.length > 0) {\n<!-- DESKTOP VIEW -->\n@if (!isMobile) {\n<div\n class=\"page-group-aside\"\n [style.width]=\"sidebarWidth\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"componentConfig.stickyView?.top?.desktopView || undefined\"\n>\n @for (item of pageGroup.pages; track $index) {\n <div\n class=\"page\"\n [class.active]=\"pageIndex === $index\"\n [style.cursor]=\"pageIndex === $index ? 'default' : 'pointer'\"\n (click)=\"setPage($index)\"\n >\n <!-- ICON -->\n <mat-icon>{{ item.icon }}</mat-icon>\n <div class=\"title\">{{ item.title }}</div>\n <!-- CURRENT PAGE -->\n @if (pageIndex === $index) { <mat-icon>keyboard_double_arrow_left</mat-icon> }\n </div>\n }\n</div>\n}\n\n<!-- MOBILE VIEW -->\n@if (isMobile) {\n<div\n class=\"page-group-nav\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"componentConfig.stickyView?.top?.mobileView || undefined\"\n>\n @for (item of pageGroup.pages; track $index) {\n <div\n class=\"page\"\n [class.active]=\"pageIndex === $index\"\n [style.cursor]=\"pageIndex === $index ? 'default' : 'pointer'\"\n (click)=\"setPage($index)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n @if (pageIndex === $index) {\n <div class=\"title\">{{ item.title }}</div>\n }\n </div>\n }\n</div>\n\n<div\n class=\"page-group-spacer\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n 'calc(' + (componentConfig.stickyView?.top?.mobileView || undefined) + ' + var(--ngx-helper-m3-toolbar-height))'\n \"\n></div>\n}\n\n<div class=\"page-group-content\">\n <!-- HEADER -->\n @if (pageGroup.header) {\n <header\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n (isMobile\n ? 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-toolbar-height) + 1rem)'\n : componentConfig.stickyView?.top?.desktopView) || undefined\n \"\n >\n <span *ngComponentOutlet=\"pageGroup.header; injector: injector\"></span>\n <div class=\"spacer\"></div>\n </header>\n }\n <span *ngComponentOutlet=\"pageGroup.pages[pageIndex].component; injector: injector\"></span>\n</div>\n}\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
451
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperCardComponent, deps: [{ token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
452
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperCardComponent, isStandalone: true, selector: "ngx-helper-card", inputs: { title: "title", subTitle: "subTitle", icon: "icon", actions: "actions", padding: "padding", backgroundColor: "backgroundColor", hasShadow: "hasShadow" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "className": "this.className" } }, providers: [ComponentService], usesOnChanges: true, ngImport: i0, template: "<div class=\"card-header\" [class.has-sub-title]=\"subTitle\">\n <!-- ICON -->\n @if (icon) { <mat-icon>{{ icon }}</mat-icon> }\n\n <!-- TITLE -->\n <div class=\"content\">\n <div class=\"title\">{{ title }}</div>\n <!-- SUB TITLE -->\n @if (subTitle) {\n <div class=\"sub-title\">{{ subTitle }}</div>\n }\n </div>\n\n <!-- BUTTONS -->\n @if (buttons.length > 0) {\n <div class=\"buttons\" [ngClass]=\"isMobile ? 'mobile-view' : ''\">\n @for (item of buttons; track $index) {\n <!-- TYPE -->\n @switch (item.type) {\n\n <!-- BUTTON -->\n @case('BUTTON') {\n <button mat-button type=\"button\" [style.color]=\"item.color\" (click)=\"item.action()\">\n @if (!isMobile) {\n <div class=\"title\">{{ item.title }}</div>\n }\n <!-- ICON -->\n @if (isMobile || item.showIcon) {\n <mat-icon>{{ item.icon }}</mat-icon>\n }\n </button>\n }\n\n <!-- MENU -->\n @case('MENU') {\n <button mat-button type=\"button\" [style.color]=\"item.color\" [matMenuTriggerFor]=\"actionMenu\">\n @if (!isMobile) {\n <div class=\"title\">{{ item.title }}</div>\n }\n <!-- ICON -->\n @if (isMobile || item.showIcon) {\n <mat-icon>{{ item.icon }}</mat-icon>\n }\n </button>\n <mat-menu #actionMenu=\"matMenu\" class=\"ngx-helper-card-action-menu\">\n @for (menu of item.buttons; track $index) {\n <!-- DIVIDER -->\n @if (menu === 'DIVIDER') { <mat-divider></mat-divider> }\n <!-- BUTTON -->\n @else {\n <button mat-menu-item type=\"button\" (click)=\"menu.action()\" [style.color]=\"menu.color\">\n <div class=\"title\">{{ menu.title }}</div>\n <mat-icon [style.color]=\"menu.color\">{{ menu.icon }}</mat-icon>\n </button>\n } }\n </mat-menu>\n } } }\n </div>\n }\n</div>\n\n<div class=\"card-content\" [style.padding]=\"padding\" [style.background-color]=\"backgroundColor\">\n <ng-content></ng-content>\n</div>\n", styles: ["::ng-deep .ngx-helper-card-action-menu button mat-icon{font-size:115%;margin:0 0 0 .75rem!important}::ng-deep .ngx-helper-card-action-menu button .title{font-size:90%!important}::ng-deep .ngx-helper-card-action-menu .mat-mdc-menu-content{padding:0}::ng-deep .ngx-helper-card-action-menu .mat-mdc-menu-item{direction:rtl;text-align:right}::ng-deep .ngx-helper-card-action-menu .mat-divider{margin:0;border-top-color:var(--outline-variant)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }] });
296
453
  }
297
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPageGroupComponent, decorators: [{
454
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperCardComponent, decorators: [{
298
455
  type: Component,
299
- args: [{ selector: 'ngx-helper-page-group', host: { '(window:resize)': 'onResize($event)' }, imports: [NgComponentOutlet, MatIcon], providers: [ComponentService], template: "@if (pageGroup.pages.length > 0) {\n<!-- DESKTOP VIEW -->\n@if (!isMobile) {\n<div\n class=\"page-group-aside\"\n [style.width]=\"sidebarWidth\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"componentConfig.stickyView?.top?.desktopView || undefined\"\n>\n @for (item of pageGroup.pages; track $index) {\n <div\n class=\"page\"\n [class.active]=\"pageIndex === $index\"\n [style.cursor]=\"pageIndex === $index ? 'default' : 'pointer'\"\n (click)=\"setPage($index)\"\n >\n <!-- ICON -->\n <mat-icon>{{ item.icon }}</mat-icon>\n <div class=\"title\">{{ item.title }}</div>\n <!-- CURRENT PAGE -->\n @if (pageIndex === $index) { <mat-icon>keyboard_double_arrow_left</mat-icon> }\n </div>\n }\n</div>\n}\n\n<!-- MOBILE VIEW -->\n@if (isMobile) {\n<div\n class=\"page-group-nav\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"componentConfig.stickyView?.top?.mobileView || undefined\"\n>\n @for (item of pageGroup.pages; track $index) {\n <div\n class=\"page\"\n [class.active]=\"pageIndex === $index\"\n [style.cursor]=\"pageIndex === $index ? 'default' : 'pointer'\"\n (click)=\"setPage($index)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n @if (pageIndex === $index) {\n <div class=\"title\">{{ item.title }}</div>\n }\n </div>\n }\n</div>\n\n<div\n class=\"page-group-spacer\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n 'calc(' + (componentConfig.stickyView?.top?.mobileView || undefined) + ' + var(--ngx-helper-m3-toolbar-height))'\n \"\n></div>\n}\n\n<div class=\"page-group-content\">\n <!-- HEADER -->\n @if (pageGroup.header) {\n <header\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n (isMobile\n ? 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-toolbar-height) + 1rem)'\n : componentConfig.stickyView?.top?.desktopView) || undefined\n \"\n >\n <span *ngComponentOutlet=\"pageGroup.header; injector: injector\"></span>\n <div class=\"spacer\"></div>\n </header>\n }\n <span *ngComponentOutlet=\"pageGroup.pages[pageIndex].component; injector: injector\"></span>\n</div>\n}\n" }]
300
- }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i1.Router }, { type: ComponentService }, { type: undefined, decorators: [{
456
+ args: [{ selector: 'ngx-helper-card', host: { '(window:resize)': 'onResize($event)' }, imports: [NgClass, MatButton, MatDivider, MatIcon, MatMenuModule], providers: [ComponentService], template: "<div class=\"card-header\" [class.has-sub-title]=\"subTitle\">\n <!-- ICON -->\n @if (icon) { <mat-icon>{{ icon }}</mat-icon> }\n\n <!-- TITLE -->\n <div class=\"content\">\n <div class=\"title\">{{ title }}</div>\n <!-- SUB TITLE -->\n @if (subTitle) {\n <div class=\"sub-title\">{{ subTitle }}</div>\n }\n </div>\n\n <!-- BUTTONS -->\n @if (buttons.length > 0) {\n <div class=\"buttons\" [ngClass]=\"isMobile ? 'mobile-view' : ''\">\n @for (item of buttons; track $index) {\n <!-- TYPE -->\n @switch (item.type) {\n\n <!-- BUTTON -->\n @case('BUTTON') {\n <button mat-button type=\"button\" [style.color]=\"item.color\" (click)=\"item.action()\">\n @if (!isMobile) {\n <div class=\"title\">{{ item.title }}</div>\n }\n <!-- ICON -->\n @if (isMobile || item.showIcon) {\n <mat-icon>{{ item.icon }}</mat-icon>\n }\n </button>\n }\n\n <!-- MENU -->\n @case('MENU') {\n <button mat-button type=\"button\" [style.color]=\"item.color\" [matMenuTriggerFor]=\"actionMenu\">\n @if (!isMobile) {\n <div class=\"title\">{{ item.title }}</div>\n }\n <!-- ICON -->\n @if (isMobile || item.showIcon) {\n <mat-icon>{{ item.icon }}</mat-icon>\n }\n </button>\n <mat-menu #actionMenu=\"matMenu\" class=\"ngx-helper-card-action-menu\">\n @for (menu of item.buttons; track $index) {\n <!-- DIVIDER -->\n @if (menu === 'DIVIDER') { <mat-divider></mat-divider> }\n <!-- BUTTON -->\n @else {\n <button mat-menu-item type=\"button\" (click)=\"menu.action()\" [style.color]=\"menu.color\">\n <div class=\"title\">{{ menu.title }}</div>\n <mat-icon [style.color]=\"menu.color\">{{ menu.icon }}</mat-icon>\n </button>\n } }\n </mat-menu>\n } } }\n </div>\n }\n</div>\n\n<div class=\"card-content\" [style.padding]=\"padding\" [style.background-color]=\"backgroundColor\">\n <ng-content></ng-content>\n</div>\n", styles: ["::ng-deep .ngx-helper-card-action-menu button mat-icon{font-size:115%;margin:0 0 0 .75rem!important}::ng-deep .ngx-helper-card-action-menu button .title{font-size:90%!important}::ng-deep .ngx-helper-card-action-menu .mat-mdc-menu-content{padding:0}::ng-deep .ngx-helper-card-action-menu .mat-mdc-menu-item{direction:rtl;text-align:right}::ng-deep .ngx-helper-card-action-menu .mat-divider{margin:0;border-top-color:var(--outline-variant)}\n"] }]
457
+ }], ctorParameters: () => [{ type: ComponentService }, { type: undefined, decorators: [{
301
458
  type: Optional
302
459
  }, {
303
460
  type: Inject,
@@ -305,453 +462,329 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
305
462
  }] }], propDecorators: { className: [{
306
463
  type: HostBinding,
307
464
  args: ['className']
308
- }], display: [{
309
- type: HostBinding,
310
- args: ['style.display']
311
- }], pageGroup: [{
465
+ }], title: [{
312
466
  type: Input,
313
467
  args: [{ required: true }]
314
- }], pageIndex: [{
468
+ }], subTitle: [{
315
469
  type: Input,
316
470
  args: [{ required: false }]
317
- }], data: [{
471
+ }], icon: [{
472
+ type: Input,
473
+ args: [{ required: false }]
474
+ }], actions: [{
475
+ type: Input,
476
+ args: [{ required: false }]
477
+ }], padding: [{
478
+ type: Input,
479
+ args: [{ required: false }]
480
+ }], backgroundColor: [{
481
+ type: Input,
482
+ args: [{ required: false }]
483
+ }], hasShadow: [{
318
484
  type: Input,
319
485
  args: [{ required: false }]
320
- }], pageIndexChanged: [{
321
- type: Output
322
- }], dataChanged: [{
323
- type: Output
324
486
  }] } });
325
487
 
326
- class NgxHelperSectionStickyDirective {
327
- elementRef;
328
- config;
329
- ngxHelperSectionSticky;
330
- ngxHelperSectionZIndex;
331
- componentService = inject(ComponentService);
332
- componentConfig;
333
- isMobile = false;
334
- constructor(elementRef, config) {
335
- this.elementRef = elementRef;
336
- this.config = config;
337
- }
338
- ngOnInit() {
339
- this.componentConfig = this.componentService.getComponentConfig(this.config);
340
- this.onResize();
341
- }
342
- onResize() {
343
- this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
344
- this.setPosition();
345
- }
346
- setPosition() {
347
- const element = this.elementRef.nativeElement;
348
- if (!element)
349
- return;
350
- switch (this.ngxHelperSectionSticky) {
351
- case 'TOP':
352
- const top = this.componentConfig.stickyView?.top;
353
- if (!top)
354
- return;
355
- element.style.position = 'sticky';
356
- element.style.zIndex = this.ngxHelperSectionZIndex ? this.ngxHelperSectionZIndex.toString() : '1';
357
- element.style.top = this.isMobile ? top.mobileView : top.desktopView;
358
- break;
359
- case 'BOTTOM':
360
- const bottom = this.componentConfig.stickyView?.bottom;
361
- if (!bottom)
362
- return;
363
- element.style.position = 'sticky';
364
- element.style.zIndex = this.ngxHelperSectionZIndex ? this.ngxHelperSectionZIndex.toString() : '1';
365
- element.style.bottom = this.isMobile ? bottom.mobileView : bottom.desktopView;
366
- break;
367
- }
488
+ class NgxHelperLoaderComponent {
489
+ loaderSize;
490
+ loaderColor;
491
+ mode;
492
+ size;
493
+ color;
494
+ padding;
495
+ ngOnChanges(changes) {
496
+ this.loaderSize = `${this.size || 25}px`;
497
+ this.loaderColor = this.color || `var(--secondary)`;
368
498
  }
369
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionStickyDirective, deps: [{ token: i0.ElementRef }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
370
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperSectionStickyDirective, isStandalone: true, selector: "[ngxHelperSectionSticky]", inputs: { ngxHelperSectionSticky: "ngxHelperSectionSticky", ngxHelperSectionZIndex: "ngxHelperSectionZIndex" }, host: { listeners: { "window:resize": "onResize($event)" } }, ngImport: i0 });
499
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
500
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperLoaderComponent, isStandalone: true, selector: "ngx-helper-loader", inputs: { mode: "mode", size: "size", color: "color", padding: "padding" }, host: { properties: { "style.--loader-size": "this.loaderSize", "style.--loader-color": "this.loaderColor" } }, usesOnChanges: true, ngImport: i0, template: "<div [style.padding]=\"padding || '0'\">\n <div [class]=\"mode.toLowerCase()\"></div>\n</div>\n", styles: [".spinner{--size: calc(var(--loader-size) / 7);width:var(--loader-size);aspect-ratio:1;border-radius:50%;background:radial-gradient(farthest-side,var(--loader-color) 94%,rgba(0,0,0,0)) top/var(--size) var(--size) no-repeat,conic-gradient(rgba(0,0,0,0) 30%,var(--loader-color));mask:radial-gradient(farthest-side,rgba(0,0,0,0) calc(100% - var(--size)),#000 0);animation:spinner 1s infinite linear}@keyframes spinner{to{transform:rotate(1turn)}}.dots-spinner{--dot: no-repeat radial-gradient(farthest-side, var(--loader-color) 92%, #0000);--size: calc(var(--loader-size) / 4);width:var(--loader-size);aspect-ratio:1;background:var(--dot) top,var(--dot) left,var(--dot) right,var(--dot) bottom;background-size:var(--size) var(--size);animation:dots-spinner 1s infinite}@keyframes dots-spinner{to{transform:rotate(.5turn)}}.wheel-spinner{--size: calc(var(--loader-size) / 9);width:var(--loader-size);aspect-ratio:1;border-radius:50%;background:var(--loader-color);mask:repeating-conic-gradient(rgba(0,0,0,0) 0deg,#000 1deg 70deg,rgba(0,0,0,0) 71deg 90deg),radial-gradient(farthest-side,rgba(0,0,0,0) calc(100% - var(--size) - 1px),#000 calc(100% - var(--size)));-webkit-mask-composite:destination-in;mask-composite:intersect;animation:wheel-spinner 1s infinite}@keyframes wheel-spinner{to{transform:rotate(.5turn)}}\n"] });
371
501
  }
372
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionStickyDirective, decorators: [{
373
- type: Directive,
374
- args: [{
375
- selector: '[ngxHelperSectionSticky]',
376
- host: { '(window:resize)': 'onResize($event)' },
377
- }]
378
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: undefined, decorators: [{
379
- type: Optional
380
- }, {
381
- type: Inject,
382
- args: [NGX_HELPER_CONFIG]
383
- }] }], propDecorators: { ngxHelperSectionSticky: [{
502
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperLoaderComponent, decorators: [{
503
+ type: Component,
504
+ args: [{ selector: 'ngx-helper-loader', imports: [], template: "<div [style.padding]=\"padding || '0'\">\n <div [class]=\"mode.toLowerCase()\"></div>\n</div>\n", styles: [".spinner{--size: calc(var(--loader-size) / 7);width:var(--loader-size);aspect-ratio:1;border-radius:50%;background:radial-gradient(farthest-side,var(--loader-color) 94%,rgba(0,0,0,0)) top/var(--size) var(--size) no-repeat,conic-gradient(rgba(0,0,0,0) 30%,var(--loader-color));mask:radial-gradient(farthest-side,rgba(0,0,0,0) calc(100% - var(--size)),#000 0);animation:spinner 1s infinite linear}@keyframes spinner{to{transform:rotate(1turn)}}.dots-spinner{--dot: no-repeat radial-gradient(farthest-side, var(--loader-color) 92%, #0000);--size: calc(var(--loader-size) / 4);width:var(--loader-size);aspect-ratio:1;background:var(--dot) top,var(--dot) left,var(--dot) right,var(--dot) bottom;background-size:var(--size) var(--size);animation:dots-spinner 1s infinite}@keyframes dots-spinner{to{transform:rotate(.5turn)}}.wheel-spinner{--size: calc(var(--loader-size) / 9);width:var(--loader-size);aspect-ratio:1;border-radius:50%;background:var(--loader-color);mask:repeating-conic-gradient(rgba(0,0,0,0) 0deg,#000 1deg 70deg,rgba(0,0,0,0) 71deg 90deg),radial-gradient(farthest-side,rgba(0,0,0,0) calc(100% - var(--size) - 1px),#000 calc(100% - var(--size)));-webkit-mask-composite:destination-in;mask-composite:intersect;animation:wheel-spinner 1s infinite}@keyframes wheel-spinner{to{transform:rotate(.5turn)}}\n"] }]
505
+ }], propDecorators: { loaderSize: [{
506
+ type: HostBinding,
507
+ args: ['style.--loader-size']
508
+ }], loaderColor: [{
509
+ type: HostBinding,
510
+ args: ['style.--loader-color']
511
+ }], mode: [{
384
512
  type: Input,
385
513
  args: [{ required: true }]
386
- }], ngxHelperSectionZIndex: [{
514
+ }], size: [{
515
+ type: Input,
516
+ args: [{ required: false }]
517
+ }], color: [{
518
+ type: Input,
519
+ args: [{ required: false }]
520
+ }], padding: [{
387
521
  type: Input,
388
522
  args: [{ required: false }]
389
523
  }] } });
390
524
 
391
- class NgxHelperSectionComponent {
525
+ const NGX_HELPER_PAGE_GROUP_ITEM = new InjectionToken('NGX-HELPER-PAGE-GROUP-ITEM');
526
+ const NGX_HELPER_PAGE_GROUP_DATA = new InjectionToken('NGX-HELPER-PAGE-GROUP-DATA');
527
+ const NGX_HELPER_PAGE_GROUP_DATA_CHANGE = new InjectionToken('NGX-HELPER-PAGE-GROUP-DATA-CHANGE');
528
+
529
+ class NgxHelperPageGroupComponent {
530
+ activatedRoute;
531
+ router;
392
532
  componentService;
393
533
  config;
394
- gap;
395
- gapSize;
396
- componentConfig;
534
+ className = 'ngx-helper-m3-page-group';
535
+ display = 'none';
536
+ pageGroup;
537
+ pageId;
538
+ data;
539
+ pageChanged = new EventEmitter();
540
+ dataChanged = new EventEmitter();
397
541
  isMobile = false;
398
- constructor(componentService, config) {
542
+ pages = [];
543
+ injector;
544
+ sidebarWidth;
545
+ componentConfig;
546
+ constructor(activatedRoute, router, componentService, config) {
547
+ this.activatedRoute = activatedRoute;
548
+ this.router = router;
399
549
  this.componentService = componentService;
400
550
  this.config = config;
401
551
  }
402
552
  ngOnInit() {
553
+ this.pages = Object.keys(this.pageGroup.pages);
554
+ this.display = this.pages.length === 0 ? 'none' : 'flex';
555
+ if (this.pages.length === 0)
556
+ return;
403
557
  this.componentConfig = this.componentService.getComponentConfig(this.config);
404
- this.gap = this.gapSize || '1rem';
558
+ this.sidebarWidth = this.pageGroup.sidebarWidth || this.componentConfig.pageGroupSidebarWidth;
559
+ if (!this.pageGroup.pages[this.pageId])
560
+ this.pageId = this.pages[0];
561
+ const queryParams = { ...this.activatedRoute.snapshot.queryParams };
562
+ if (!!this.pageGroup.route && Helper.IS.string(queryParams['ngx-helper-page-group'])) {
563
+ const id = queryParams['ngx-helper-page-group'];
564
+ if (this.pageId !== id && this.pages.includes(id)) {
565
+ this.pageId = id;
566
+ this.triggerPageChanged();
567
+ }
568
+ }
405
569
  this.onResize();
570
+ this.setInjector();
571
+ }
572
+ ngOnChanges(changes) {
573
+ this.setInjector();
406
574
  }
407
575
  onResize() {
408
576
  this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
577
+ this.className = `ngx-helper-m3-page-group${this.isMobile ? ' mobile-view' : ''}`;
409
578
  }
410
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionComponent, deps: [{ token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
411
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperSectionComponent, isStandalone: true, selector: "ngx-helper-section", inputs: { gapSize: "gapSize" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "style.--section-gap": "this.gap" } }, providers: [ComponentService], ngImport: i0, template: "<div class=\"section-columns\" [class.section-columns-mobile]=\"isMobile\">\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block;direction:rtl}:host .section-columns{display:flex;align-items:flex-start;column-gap:var(--section-gap)}:host ::ng-deep ngx-helper-section-column{flex:1;display:flex;flex-direction:column;row-gap:var(--section-gap)}:host .section-columns-mobile{flex-direction:column;column-gap:0;row-gap:var(--section-gap)}:host .section-columns-mobile ::ng-deep ngx-helper-section-column{width:100%!important}\n"] });
579
+ setInjector() {
580
+ if (this.pages.length === 0)
581
+ return;
582
+ const item = {
583
+ index: this.pages.findIndex((page) => page === this.pageId),
584
+ id: this.pageId,
585
+ title: this.pageGroup.pages[this.pageId].title,
586
+ icon: this.pageGroup.pages[this.pageId].icon,
587
+ };
588
+ this.injector = Injector.create({
589
+ providers: [
590
+ { provide: NGX_HELPER_PAGE_GROUP_ITEM, useValue: item },
591
+ { provide: NGX_HELPER_PAGE_GROUP_DATA, useValue: this.data },
592
+ { provide: NGX_HELPER_PAGE_GROUP_DATA_CHANGE, useValue: (data) => this.dataChanged.next(data) },
593
+ ],
594
+ });
595
+ }
596
+ setPage(id) {
597
+ if (this.pages.length === 0 || this.pageId == id)
598
+ return;
599
+ const page = this.pageGroup.pages[id];
600
+ const index = this.pages.findIndex((p) => p === id);
601
+ if (!page || index === -1)
602
+ return;
603
+ this.pageId = id;
604
+ this.triggerPageChanged();
605
+ this.setInjector();
606
+ if (this.pageGroup.route) {
607
+ const queryParams = { ...this.activatedRoute.snapshot.queryParams };
608
+ queryParams['ngx-helper-page-group'] = this.pageId;
609
+ this.router.navigate(this.pageGroup.route, { queryParams });
610
+ }
611
+ }
612
+ triggerPageChanged() {
613
+ const item = {
614
+ index: this.pages.findIndex((page) => page === this.pageId),
615
+ id: this.pageId,
616
+ title: this.pageGroup.pages[this.pageId].title,
617
+ icon: this.pageGroup.pages[this.pageId].icon,
618
+ };
619
+ this.pageChanged.next(item);
620
+ }
621
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPageGroupComponent, deps: [{ token: i1.ActivatedRoute }, { token: i1.Router }, { token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
622
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperPageGroupComponent, isStandalone: true, selector: "ngx-helper-page-group", inputs: { pageGroup: "pageGroup", pageId: "pageId", data: "data" }, outputs: { pageChanged: "pageChanged", dataChanged: "dataChanged" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "className": "this.className", "style.display": "this.display" } }, providers: [ComponentService], usesOnChanges: true, ngImport: i0, template: "@if (pages.length > 0) {\n<!-- DESKTOP VIEW -->\n@if (!isMobile) {\n<div\n class=\"page-group-aside\"\n [style.width]=\"sidebarWidth\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"componentConfig.stickyView?.top?.desktopView || undefined\"\n>\n @for (item of pages; track $index) {\n <div\n class=\"page\"\n [class.active]=\"pageId === item\"\n [style.cursor]=\"pageId === item ? 'default' : 'pointer'\"\n (click)=\"setPage(item)\"\n >\n <!-- ICON -->\n <mat-icon>{{ pageGroup.pages[item].icon }}</mat-icon>\n <div class=\"title\">{{ pageGroup.pages[item].title }}</div>\n <!-- CURRENT PAGE -->\n @if (pageId === item) { <mat-icon>keyboard_double_arrow_left</mat-icon> }\n </div>\n }\n</div>\n}\n\n<!-- MOBILE VIEW -->\n@if (isMobile) {\n<div\n class=\"page-group-nav\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"componentConfig.stickyView?.top?.mobileView || undefined\"\n>\n @for (item of pages; track $index) {\n <div\n class=\"page\"\n [class.active]=\"pageId === item\"\n [style.cursor]=\"pageId === item ? 'default' : 'pointer'\"\n (click)=\"setPage(item)\"\n >\n <mat-icon>{{ pageGroup.pages[item].icon }}</mat-icon>\n @if (pageId === item) {\n <div class=\"title\">{{ pageGroup.pages[item].title }}</div>\n }\n </div>\n }\n</div>\n\n<div\n class=\"page-group-spacer\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-page-group-toolbar-height))'\n \"\n></div>\n}\n\n<div class=\"page-group-content\">\n <!-- HEADER -->\n @if (pageGroup.header) {\n <div\n class=\"header\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n (isMobile\n ? 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-page-group-toolbar-height) + 1rem)'\n : componentConfig.stickyView?.top?.desktopView) || undefined\n \"\n >\n <span *ngComponentOutlet=\"pageGroup.header; injector: injector\"></span>\n <div class=\"spacer\"></div>\n </div>\n }\n <span *ngComponentOutlet=\"pageGroup.pages[pageId].component; injector: injector\"></span>\n</div>\n}\n", styles: [""], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }] });
412
623
  }
413
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionComponent, decorators: [{
624
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPageGroupComponent, decorators: [{
414
625
  type: Component,
415
- args: [{ selector: 'ngx-helper-section', host: { '(window:resize)': 'onResize($event)' }, imports: [], providers: [ComponentService], template: "<div class=\"section-columns\" [class.section-columns-mobile]=\"isMobile\">\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block;direction:rtl}:host .section-columns{display:flex;align-items:flex-start;column-gap:var(--section-gap)}:host ::ng-deep ngx-helper-section-column{flex:1;display:flex;flex-direction:column;row-gap:var(--section-gap)}:host .section-columns-mobile{flex-direction:column;column-gap:0;row-gap:var(--section-gap)}:host .section-columns-mobile ::ng-deep ngx-helper-section-column{width:100%!important}\n"] }]
416
- }], ctorParameters: () => [{ type: ComponentService }, { type: undefined, decorators: [{
626
+ args: [{ selector: 'ngx-helper-page-group', host: { '(window:resize)': 'onResize($event)' }, imports: [NgComponentOutlet, MatIcon], providers: [ComponentService], template: "@if (pages.length > 0) {\n<!-- DESKTOP VIEW -->\n@if (!isMobile) {\n<div\n class=\"page-group-aside\"\n [style.width]=\"sidebarWidth\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"componentConfig.stickyView?.top?.desktopView || undefined\"\n>\n @for (item of pages; track $index) {\n <div\n class=\"page\"\n [class.active]=\"pageId === item\"\n [style.cursor]=\"pageId === item ? 'default' : 'pointer'\"\n (click)=\"setPage(item)\"\n >\n <!-- ICON -->\n <mat-icon>{{ pageGroup.pages[item].icon }}</mat-icon>\n <div class=\"title\">{{ pageGroup.pages[item].title }}</div>\n <!-- CURRENT PAGE -->\n @if (pageId === item) { <mat-icon>keyboard_double_arrow_left</mat-icon> }\n </div>\n }\n</div>\n}\n\n<!-- MOBILE VIEW -->\n@if (isMobile) {\n<div\n class=\"page-group-nav\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"componentConfig.stickyView?.top?.mobileView || undefined\"\n>\n @for (item of pages; track $index) {\n <div\n class=\"page\"\n [class.active]=\"pageId === item\"\n [style.cursor]=\"pageId === item ? 'default' : 'pointer'\"\n (click)=\"setPage(item)\"\n >\n <mat-icon>{{ pageGroup.pages[item].icon }}</mat-icon>\n @if (pageId === item) {\n <div class=\"title\">{{ pageGroup.pages[item].title }}</div>\n }\n </div>\n }\n</div>\n\n<div\n class=\"page-group-spacer\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-page-group-toolbar-height))'\n \"\n></div>\n}\n\n<div class=\"page-group-content\">\n <!-- HEADER -->\n @if (pageGroup.header) {\n <div\n class=\"header\"\n [style.position]=\"componentConfig.stickyView?.top ? 'sticky' : 'static'\"\n [style.top]=\"\n (isMobile\n ? 'calc(' +\n (componentConfig.stickyView?.top?.mobileView || undefined) +\n ' + var(--ngx-helper-m3-page-group-toolbar-height) + 1rem)'\n : componentConfig.stickyView?.top?.desktopView) || undefined\n \"\n >\n <span *ngComponentOutlet=\"pageGroup.header; injector: injector\"></span>\n <div class=\"spacer\"></div>\n </div>\n }\n <span *ngComponentOutlet=\"pageGroup.pages[pageId].component; injector: injector\"></span>\n</div>\n}\n" }]
627
+ }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i1.Router }, { type: ComponentService }, { type: undefined, decorators: [{
417
628
  type: Optional
418
629
  }, {
419
630
  type: Inject,
420
631
  args: [NGX_HELPER_CONFIG]
421
- }] }], propDecorators: { gap: [{
422
- type: HostBinding,
423
- args: ['style.--section-gap']
424
- }], gapSize: [{
425
- type: Input,
426
- args: [{ required: false }]
427
- }] } });
428
-
429
- class NgxHelperSectionColumnComponent {
430
- flexStyle = '1';
431
- widthStyle = '*';
432
- flex;
433
- width;
434
- sticky;
435
- ngOnChanges(changes) {
436
- this.flexStyle = this.width ? 'unset' : this.flex?.toString() || '1';
437
- this.widthStyle = this.width || '*';
438
- }
439
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
440
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperSectionColumnComponent, isStandalone: true, selector: "ngx-helper-section-column", inputs: { flex: "flex", width: "width", sticky: "sticky" }, host: { properties: { "style.flex": "this.flexStyle", "style.width": "this.widthStyle" } }, usesOnChanges: true, ngImport: i0, template: "<ng-content></ng-content>\n", styles: [""] });
441
- }
442
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionColumnComponent, decorators: [{
443
- type: Component,
444
- args: [{ selector: 'ngx-helper-section-column', imports: [], template: "<ng-content></ng-content>\n" }]
445
- }], propDecorators: { flexStyle: [{
632
+ }] }], propDecorators: { className: [{
446
633
  type: HostBinding,
447
- args: ['style.flex']
448
- }], widthStyle: [{
634
+ args: ['className']
635
+ }], display: [{
449
636
  type: HostBinding,
450
- args: ['style.width']
451
- }], flex: [{
637
+ args: ['style.display']
638
+ }], pageGroup: [{
452
639
  type: Input,
453
- args: [{ required: false }]
454
- }], width: [{
640
+ args: [{ required: true }]
641
+ }], pageId: [{
455
642
  type: Input,
456
643
  args: [{ required: false }]
457
- }], sticky: [{
644
+ }], data: [{
458
645
  type: Input,
459
646
  args: [{ required: false }]
647
+ }], pageChanged: [{
648
+ type: Output
649
+ }], dataChanged: [{
650
+ type: Output
460
651
  }] } });
461
652
 
462
- const ltrValues = ['BANK-CARD', 'MOBILE', 'NUMBER'];
463
-
464
- class NgxHelperBankCardPipe {
465
- transform(value, options) {
466
- if (value === undefined || value === null || !Helper.IS.string(value) || value === '')
467
- return '';
468
- switch (options?.view) {
469
- case 'BANK':
470
- return Helper.BANK.findCard(value)?.title || '';
471
- default:
472
- return Helper.STRING.getBankCardView(value, options?.join || '-');
473
- }
474
- }
475
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperBankCardPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
476
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperBankCardPipe, isStandalone: true, name: "ngxHelperBankCard" });
477
- }
478
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperBankCardPipe, decorators: [{
479
- type: Pipe,
480
- args: [{ name: 'ngxHelperBankCard' }]
481
- }] });
482
-
483
- class NgxHelperDatePipe {
484
- transform(value, options) {
485
- if (value === undefined || value === null || (!Helper.IS.date(value) && !Helper.IS.number(value)))
486
- return '';
487
- const date = typeof value === 'number' ? new Date(value) : value;
488
- const jalali = JalaliDateTime();
489
- const timezone = options?.timezone && jalali.timezones().includes(options?.timezone) ? options?.timezone : 'Asia/Tehran';
490
- switch (options?.format || 'DATE') {
491
- case 'FULL':
492
- return jalali.toFullText(date, { format: 'W، d N Y H:I', timezone });
493
- case 'SHORT':
494
- return jalali.toFullText(date, { format: 'Y/M/D', timezone });
495
- case 'DATE':
496
- return jalali.toFullText(date, { format: 'W، d N Y', timezone });
497
- case 'TIME':
498
- return jalali.toFullText(date, { format: 'H:I', timezone });
499
- case 'WEEK':
500
- const { from, to } = jalali.periodWeek(1, date, timezone);
501
- return Helper.DATE.jalaliPeriod(from, to, timezone);
502
- case 'MONTH':
503
- return jalali.toFullText(date, { format: 'N Y', timezone });
504
- case 'YEAR':
505
- return jalali.toFullText(date, { format: 'Y', timezone });
506
- default:
507
- return jalali.toFullText(date, { format: options?.format, timezone });
508
- }
509
- }
510
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDatePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
511
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDatePipe, isStandalone: true, name: "ngxHelperDate" });
512
- }
513
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDatePipe, decorators: [{
514
- type: Pipe,
515
- args: [{ name: 'ngxHelperDate' }]
516
- }] });
517
-
518
- class NgxHelperDurationPipe {
519
- transform(value, options) {
520
- if (value === undefined || value === null)
521
- return '';
522
- let seconds = 0;
523
- if (Helper.IS.number(value))
524
- seconds = Math.abs(value);
525
- else if (Helper.IS.date(value))
526
- seconds = Math.floor(Math.abs(new Date().getTime() - value.getTime()) / 1000);
527
- else if (Helper.IS.object(value)) {
528
- const from = 'from' in value ? value.from : new Date();
529
- const to = 'to' in value ? value.to : new Date();
530
- seconds = Math.floor(Math.abs(from.getTime() - to.getTime()) / 1000);
531
- }
532
- const days = Math.floor(seconds / (24 * 60 * 60));
533
- seconds -= days * (24 * 60 * 60);
534
- const hours = Math.floor(seconds / (60 * 60));
535
- seconds -= hours * (60 * 60);
536
- const minutes = Math.floor(seconds / 60);
537
- seconds -= minutes * 60;
538
- const hasDays = days !== 0;
539
- const time = [hours, minutes, seconds].map((v) => v.toString().padStart(2, '0')).join(':');
540
- switch (options?.format || 'TEXT') {
541
- case 'TEXT':
542
- const hasTime = !!hours || !!minutes || !!seconds;
543
- const day = hasDays
544
- ? Helper.NUMBER.format(days, 'EN') + (!!options?.english ? (days === 1 ? ' day' : ' days') : ' روز')
545
- : '';
546
- const join = hasDays && hasTime ? (!!options?.english ? ', ' : ' و ') : '';
547
- return (day + join + (!hasDays || hasTime ? time : '')).trim();
548
- case 'FULL':
549
- return (hasDays ? Helper.NUMBER.format(days, 'EN') + ':' : '') + time;
550
- case 'DAY':
551
- return Helper.NUMBER.format(days + (hours !== 0 || minutes !== 0 ? 1 : 0), !!options?.english ? 'EN' : 'FA');
552
- case 'HOUR':
553
- return Helper.NUMBER.format(days * 24 + hours + (minutes !== 0 ? 1 : 0), !!options?.english ? 'EN' : 'FA');
554
- case 'MINUTE':
555
- return Helper.NUMBER.format(days * 24 * 60 + hours * 60 + minutes, !!options?.english ? 'EN' : 'FA');
556
- case 'SECOND':
557
- return Helper.NUMBER.format(days * 24 * 3600 + hours * 3600 + minutes * 60 + seconds, !!options?.english ? 'EN' : 'FA');
558
- }
559
- }
560
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDurationPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
561
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDurationPipe, isStandalone: true, name: "ngxHelperDuration" });
562
- }
563
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperDurationPipe, decorators: [{
564
- type: Pipe,
565
- args: [{ name: 'ngxHelperDuration' }]
566
- }] });
567
-
568
- class NgxHelperFileSizePipe {
569
- transform(value, options) {
570
- if (value === undefined || value === null || !Helper.IS.number(value))
571
- return '';
572
- return Helper.NUMBER.toFileSize(value, !!options?.english ? 'EN' : 'FA');
573
- }
574
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperFileSizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
575
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperFileSizePipe, isStandalone: true, name: "ngxHelperFileSize" });
576
- }
577
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperFileSizePipe, decorators: [{
578
- type: Pipe,
579
- args: [{ name: 'ngxHelperFileSize' }]
580
- }] });
581
-
582
- class NgxHelperMobilePipe {
583
- transform(value, options) {
584
- if (value === undefined || value === null || !Helper.IS.string(value) || value === '')
585
- return '';
586
- return Helper.STRING.getMobileView(value, options?.join || '-');
653
+ class NgxHelperSectionStickyDirective {
654
+ elementRef;
655
+ config;
656
+ ngxHelperSectionSticky;
657
+ ngxHelperSectionZIndex;
658
+ componentService = inject(ComponentService);
659
+ componentConfig;
660
+ isMobile = false;
661
+ constructor(elementRef, config) {
662
+ this.elementRef = elementRef;
663
+ this.config = config;
587
664
  }
588
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperMobilePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
589
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperMobilePipe, isStandalone: true, name: "ngxHelperMobile" });
590
- }
591
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperMobilePipe, decorators: [{
592
- type: Pipe,
593
- args: [{ name: 'ngxHelperMobile' }]
594
- }] });
595
-
596
- class NgxHelperNumberPipe {
597
- transform(value, options) {
598
- if (value === undefined || value === null || !Helper.IS.number(value))
599
- return '';
600
- value = options?.fractionDigits ? +value.toFixed(options?.fractionDigits) : value;
601
- return Helper.NUMBER.format(value, options?.english ? 'EN' : 'FA');
665
+ ngOnInit() {
666
+ this.componentConfig = this.componentService.getComponentConfig(this.config);
667
+ this.onResize();
602
668
  }
603
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperNumberPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
604
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperNumberPipe, isStandalone: true, name: "ngxHelperNumber" });
605
- }
606
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperNumberPipe, decorators: [{
607
- type: Pipe,
608
- args: [{ name: 'ngxHelperNumber' }]
609
- }] });
610
-
611
- class NgxHelperPeriodPipe {
612
- transform(value, options) {
613
- if (value === undefined || value === null)
614
- return '';
615
- const from = Helper.IS.date(value) ? value : 'from' in value ? value.from : new Date();
616
- const to = Helper.IS.date(value) ? new Date() : 'to' in value ? value.to : new Date();
617
- return Helper.DATE.jalaliPeriod(from, to, options?.timezone || '');
669
+ onResize() {
670
+ this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
671
+ this.setPosition();
618
672
  }
619
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPeriodPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
620
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPeriodPipe, isStandalone: true, name: "ngxHelperPeriod" });
621
- }
622
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPeriodPipe, decorators: [{
623
- type: Pipe,
624
- args: [{ name: 'ngxHelperPeriod' }]
625
- }] });
626
-
627
- class NgxHelperPricePipe {
628
- transform(value, options) {
629
- if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
630
- return '';
631
- const getPrice = (...titles) => {
632
- if (value === undefined || value === null)
633
- return '';
634
- const price = Helper.NUMBER.format(+value.toFixed(2), !!options?.english ? 'EN' : 'FA');
635
- const unit = titles[options?.short ? 0 : 1][options?.english ? 0 : 1];
636
- const currency = options?.currency ? ' ' + options?.currency : '';
637
- return `${price} ${unit}${currency}`;
638
- };
639
- if (value < 1000)
640
- return getPrice(['', ''], ['', '']);
641
- value /= 1000;
642
- if (value < 1000)
643
- return getPrice(['T', 'ه'], ['Thousand', 'هزار']);
644
- value /= 1000;
645
- if (value < 1000)
646
- return getPrice(['M', 'م'], ['Million', 'میلیون']);
647
- value /= 1000;
648
- return getPrice(['B', 'د'], ['Billion', 'میلیارد']);
673
+ setPosition() {
674
+ const element = this.elementRef.nativeElement;
675
+ if (!element)
676
+ return;
677
+ switch (this.ngxHelperSectionSticky) {
678
+ case 'TOP':
679
+ const top = this.componentConfig.stickyView?.top;
680
+ if (!top)
681
+ return;
682
+ element.style.position = 'sticky';
683
+ element.style.zIndex = this.ngxHelperSectionZIndex ? this.ngxHelperSectionZIndex.toString() : '1';
684
+ element.style.top = this.isMobile ? top.mobileView : top.desktopView;
685
+ break;
686
+ case 'BOTTOM':
687
+ const bottom = this.componentConfig.stickyView?.bottom;
688
+ if (!bottom)
689
+ return;
690
+ element.style.position = 'sticky';
691
+ element.style.zIndex = this.ngxHelperSectionZIndex ? this.ngxHelperSectionZIndex.toString() : '1';
692
+ element.style.bottom = this.isMobile ? bottom.mobileView : bottom.desktopView;
693
+ break;
694
+ }
649
695
  }
650
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPricePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
651
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPricePipe, isStandalone: true, name: "ngxHelperPrice" });
696
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionStickyDirective, deps: [{ token: i0.ElementRef }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
697
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperSectionStickyDirective, isStandalone: true, selector: "[ngxHelperSectionSticky]", inputs: { ngxHelperSectionSticky: "ngxHelperSectionSticky", ngxHelperSectionZIndex: "ngxHelperSectionZIndex" }, host: { listeners: { "window:resize": "onResize($event)" } }, ngImport: i0 });
652
698
  }
653
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperPricePipe, decorators: [{
654
- type: Pipe,
655
- args: [{ name: 'ngxHelperPrice' }]
656
- }] });
699
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionStickyDirective, decorators: [{
700
+ type: Directive,
701
+ args: [{
702
+ selector: '[ngxHelperSectionSticky]',
703
+ host: { '(window:resize)': 'onResize($event)' },
704
+ }]
705
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: undefined, decorators: [{
706
+ type: Optional
707
+ }, {
708
+ type: Inject,
709
+ args: [NGX_HELPER_CONFIG]
710
+ }] }], propDecorators: { ngxHelperSectionSticky: [{
711
+ type: Input,
712
+ args: [{ required: true }]
713
+ }], ngxHelperSectionZIndex: [{
714
+ type: Input,
715
+ args: [{ required: false }]
716
+ }] } });
657
717
 
658
- class NgxHelperVolumePipe {
659
- transform(value, options) {
660
- if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
661
- return '';
662
- const getVolume = (...titles) => {
663
- if (value === undefined || value === null)
664
- return '';
665
- const volume = Helper.NUMBER.format(+value.toFixed(2), options?.english ? 'EN' : 'FA');
666
- const shortIndex = options?.short ? 0 : 1;
667
- const titleIndex = options?.english ? 0 : 1;
668
- return `${volume} ${titles[shortIndex][titleIndex]}`;
669
- };
670
- if (value === 0)
671
- return getVolume(['', ''], ['', '']);
672
- if (value < 1000)
673
- return getVolume(['ML', 'م'], ['Milliliter', 'میلی لیتر']);
674
- value /= 1000;
675
- return getVolume(['L', 'ل'], ['Liter', 'لیتر']);
718
+ class NgxHelperSectionComponent {
719
+ componentService;
720
+ config;
721
+ gap;
722
+ gapSize;
723
+ componentConfig;
724
+ isMobile = false;
725
+ constructor(componentService, config) {
726
+ this.componentService = componentService;
727
+ this.config = config;
676
728
  }
677
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperVolumePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
678
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperVolumePipe, isStandalone: true, name: "ngxHelperVolume" });
679
- }
680
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperVolumePipe, decorators: [{
681
- type: Pipe,
682
- args: [{ name: 'ngxHelperVolume' }]
683
- }] });
684
-
685
- class NgxHelperWeightPipe {
686
- transform(value, options) {
687
- if (value === undefined || value === null || !Helper.IS.number(value) || value < 0)
688
- return '';
689
- const getWeight = (...titles) => {
690
- if (value === undefined || value === null)
691
- return '';
692
- const weight = Helper.NUMBER.format(+value.toFixed(2), options?.english ? 'EN' : 'FA');
693
- const shortIndex = options?.short ? 0 : 1;
694
- const titleIndex = options?.english ? 0 : 1;
695
- return `${weight} ${titles[shortIndex][titleIndex]}`;
696
- };
697
- if (value === 0)
698
- return getWeight(['', ''], ['', '']);
699
- if (value < 1000)
700
- return getWeight(['G', 'گ'], ['Gram', 'گرم']);
701
- value /= 1000;
702
- if (value < 1000)
703
- return getWeight(['K', 'ک'], ['Kilogram', 'کیلو']);
704
- value /= 1000;
705
- if (value < 1000)
706
- return getWeight(['T', 'ت'], ['Tonne', 'تن']);
707
- value /= 1000;
708
- return getWeight(['KT', 'ه'], ['Kilotonne', 'هزار تن']);
729
+ ngOnInit() {
730
+ this.componentConfig = this.componentService.getComponentConfig(this.config);
731
+ this.gap = this.gapSize || '1rem';
732
+ this.onResize();
709
733
  }
710
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperWeightPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
711
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperWeightPipe, isStandalone: true, name: "ngxHelperWeight" });
734
+ onResize() {
735
+ this.isMobile = window.innerWidth <= this.componentConfig.mobileWidth;
736
+ }
737
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionComponent, deps: [{ token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
738
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperSectionComponent, isStandalone: true, selector: "ngx-helper-section", inputs: { gapSize: "gapSize" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "style.--section-gap": "this.gap" } }, providers: [ComponentService], ngImport: i0, template: "<div class=\"section-columns\" [class.section-columns-mobile]=\"isMobile\">\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block;direction:rtl}:host .section-columns{display:flex;align-items:flex-start;column-gap:var(--section-gap)}:host ::ng-deep ngx-helper-section-column{flex:1;display:flex;flex-direction:column;row-gap:var(--section-gap)}:host .section-columns-mobile{flex-direction:column;column-gap:0;row-gap:var(--section-gap)}:host .section-columns-mobile ::ng-deep ngx-helper-section-column{width:100%!important}\n"] });
712
739
  }
713
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperWeightPipe, decorators: [{
714
- type: Pipe,
715
- args: [{ name: 'ngxHelperWeight' }]
716
- }] });
740
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionComponent, decorators: [{
741
+ type: Component,
742
+ args: [{ selector: 'ngx-helper-section', host: { '(window:resize)': 'onResize($event)' }, imports: [], providers: [ComponentService], template: "<div class=\"section-columns\" [class.section-columns-mobile]=\"isMobile\">\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block;direction:rtl}:host .section-columns{display:flex;align-items:flex-start;column-gap:var(--section-gap)}:host ::ng-deep ngx-helper-section-column{flex:1;display:flex;flex-direction:column;row-gap:var(--section-gap)}:host .section-columns-mobile{flex-direction:column;column-gap:0;row-gap:var(--section-gap)}:host .section-columns-mobile ::ng-deep ngx-helper-section-column{width:100%!important}\n"] }]
743
+ }], ctorParameters: () => [{ type: ComponentService }, { type: undefined, decorators: [{
744
+ type: Optional
745
+ }, {
746
+ type: Inject,
747
+ args: [NGX_HELPER_CONFIG]
748
+ }] }], propDecorators: { gap: [{
749
+ type: HostBinding,
750
+ args: ['style.--section-gap']
751
+ }], gapSize: [{
752
+ type: Input,
753
+ args: [{ required: false }]
754
+ }] } });
717
755
 
718
- class NgxHelperValuePipe {
719
- transform(value, options) {
720
- const emptyText = options?.emptyText || '';
721
- if (value === undefined || Helper.IS.empty(value))
722
- return emptyText;
723
- switch (value.type) {
724
- case 'BANK-CARD':
725
- return new NgxHelperBankCardPipe().transform(value.value, value) || emptyText;
726
- case 'DATE':
727
- return new NgxHelperDatePipe().transform(value.value, value) || emptyText;
728
- case 'DURATION':
729
- return new NgxHelperDurationPipe().transform(value.value, value) || emptyText;
730
- case 'FILE-SIZE':
731
- return new NgxHelperFileSizePipe().transform(value.value, value) || emptyText;
732
- case 'MOBILE':
733
- return new NgxHelperMobilePipe().transform(value.value, value) || emptyText;
734
- case 'NUMBER':
735
- return new NgxHelperNumberPipe().transform(value.value, value) || emptyText;
736
- case 'PERIOD':
737
- return new NgxHelperPeriodPipe().transform(value.value, value) || emptyText;
738
- case 'PRICE':
739
- return new NgxHelperPricePipe().transform(value.value, value) || emptyText;
740
- case 'STRING':
741
- return Helper.IS.string(value.value) ? value.value : emptyText;
742
- case 'VOLUME':
743
- return new NgxHelperVolumePipe().transform(value.value, value) || emptyText;
744
- case 'WEIGHT':
745
- return new NgxHelperWeightPipe().transform(value.value, value) || emptyText;
746
- }
756
+ class NgxHelperSectionColumnComponent {
757
+ flexStyle = '1';
758
+ widthStyle = '*';
759
+ flex;
760
+ width;
761
+ sticky;
762
+ ngOnChanges(changes) {
763
+ this.flexStyle = this.width ? 'unset' : this.flex?.toString() || '1';
764
+ this.widthStyle = this.width || '*';
747
765
  }
748
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
749
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValuePipe, isStandalone: true, name: "ngxHelperValue" });
766
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
767
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: NgxHelperSectionColumnComponent, isStandalone: true, selector: "ngx-helper-section-column", inputs: { flex: "flex", width: "width", sticky: "sticky" }, host: { properties: { "style.flex": "this.flexStyle", "style.width": "this.widthStyle" } }, usesOnChanges: true, ngImport: i0, template: "<ng-content></ng-content>\n", styles: [""] });
750
768
  }
751
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValuePipe, decorators: [{
752
- type: Pipe,
753
- args: [{ name: 'ngxHelperValue' }]
754
- }] });
769
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperSectionColumnComponent, decorators: [{
770
+ type: Component,
771
+ args: [{ selector: 'ngx-helper-section-column', imports: [], template: "<ng-content></ng-content>\n" }]
772
+ }], propDecorators: { flexStyle: [{
773
+ type: HostBinding,
774
+ args: ['style.flex']
775
+ }], widthStyle: [{
776
+ type: HostBinding,
777
+ args: ['style.width']
778
+ }], flex: [{
779
+ type: Input,
780
+ args: [{ required: false }]
781
+ }], width: [{
782
+ type: Input,
783
+ args: [{ required: false }]
784
+ }], sticky: [{
785
+ type: Input,
786
+ args: [{ required: false }]
787
+ }] } });
755
788
 
756
789
  class NgxHelperValueBoxComponent {
757
790
  router;
@@ -770,7 +803,6 @@ class NgxHelperValueBoxComponent {
770
803
  copyIndex;
771
804
  copyTimeout;
772
805
  componentConfig;
773
- pipeTransform = new NgxHelperValuePipe().transform;
774
806
  constructor(router, componentService, config) {
775
807
  this.router = router;
776
808
  this.componentService = componentService;
@@ -783,21 +815,7 @@ class NgxHelperValueBoxComponent {
783
815
  ngOnChanges(changes) {
784
816
  this.boxGap = this.gapSize;
785
817
  this.className = `ngx-helper-m3-value-box${this.hideShadow ? ' hide-shadow' : ''}`;
786
- this.data = this.values.map((item) => {
787
- const value = item.value;
788
- return value === undefined
789
- ? { title: item.title, value: '' }
790
- : typeof value === 'string'
791
- ? { title: item.title, value: value.trim() }
792
- : {
793
- title: item.title,
794
- value: this.pipeTransform(value),
795
- action: item.action,
796
- copyToClipboard: item.copyToClipboard,
797
- ltr: ltrValues.includes(value.type),
798
- english: 'english' in value && !!value.english,
799
- };
800
- });
818
+ this.data = this.componentService.getValueData(this.values);
801
819
  }
802
820
  onResize() {
803
821
  if (this.values.length === 0)
@@ -831,11 +849,11 @@ class NgxHelperValueBoxComponent {
831
849
  }, 2000);
832
850
  }
833
851
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValueBoxComponent, deps: [{ token: i1.Router }, { token: ComponentService }, { token: NGX_HELPER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component });
834
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperValueBoxComponent, isStandalone: true, selector: "ngx-helper-value-box", inputs: { values: "values", column: "column", clearBox: "clearBox", emptyText: "emptyText", gapSize: "gapSize", hideShadow: "hideShadow" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "className": "this.className", "style.grid-template-columns": "this.gridTemplateColumns", "style.--gap-size": "this.boxGap" } }, providers: [ComponentService], usesOnChanges: true, ngImport: i0, template: "@for (item of data; track $index) {\n<div class=\"value-box\" [class.clear]=\"clearBox\" [class.click]=\"!!item.action\">\n <div class=\"title\" (click)=\"onClick(item.action)\">{{ item.title }}</div>\n <div\n class=\"value\"\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ClipboardModule }, { kind: "directive", type: i3.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }] });
852
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperValueBoxComponent, isStandalone: true, selector: "ngx-helper-value-box", inputs: { values: "values", column: "column", clearBox: "clearBox", emptyText: "emptyText", gapSize: "gapSize", hideShadow: "hideShadow" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "className": "this.className", "style.grid-template-columns": "this.gridTemplateColumns", "style.--gap-size": "this.boxGap" } }, providers: [ComponentService], usesOnChanges: true, ngImport: i0, template: "@for (item of data; track $index) {\n<div class=\"value-box\" [class.clear]=\"clearBox\" [class.click]=\"!!item.action\">\n <div class=\"title\" (click)=\"onClick(item.action)\">{{ item.title }}</div>\n <div\n class=\"value\"\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [style.color]=\"item.color\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ClipboardModule }, { kind: "directive", type: i3.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }] });
835
853
  }
836
854
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValueBoxComponent, decorators: [{
837
855
  type: Component,
838
- args: [{ selector: 'ngx-helper-value-box', host: { '(window:resize)': 'onResize($event)' }, imports: [ClipboardModule, MatIcon, MatIconButton], providers: [ComponentService], template: "@for (item of data; track $index) {\n<div class=\"value-box\" [class.clear]=\"clearBox\" [class.click]=\"!!item.action\">\n <div class=\"title\" (click)=\"onClick(item.action)\">{{ item.title }}</div>\n <div\n class=\"value\"\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n" }]
856
+ args: [{ selector: 'ngx-helper-value-box', host: { '(window:resize)': 'onResize($event)' }, imports: [ClipboardModule, MatIcon, MatIconButton], providers: [ComponentService], template: "@for (item of data; track $index) {\n<div class=\"value-box\" [class.clear]=\"clearBox\" [class.click]=\"!!item.action\">\n <div class=\"title\" (click)=\"onClick(item.action)\">{{ item.title }}</div>\n <div\n class=\"value\"\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [style.color]=\"item.color\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n" }]
839
857
  }], ctorParameters: () => [{ type: i1.Router }, { type: ComponentService }, { type: undefined, decorators: [{
840
858
  type: Optional
841
859
  }, {
@@ -872,6 +890,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
872
890
 
873
891
  class NgxHelperValueListComponent {
874
892
  router;
893
+ componentService;
875
894
  className = 'ngx-helper-m3-value-list';
876
895
  values;
877
896
  titleWidth = '20%';
@@ -879,26 +898,12 @@ class NgxHelperValueListComponent {
879
898
  data = [];
880
899
  copyIndex;
881
900
  copyTimeout;
882
- pipeTransform = new NgxHelperValuePipe().transform;
883
- constructor(router) {
901
+ constructor(router, componentService) {
884
902
  this.router = router;
903
+ this.componentService = componentService;
885
904
  }
886
905
  ngOnChanges(changes) {
887
- this.data = this.values.map((item) => {
888
- const value = item.value;
889
- return value === undefined
890
- ? { title: item.title, value: '' }
891
- : typeof value === 'string'
892
- ? { title: item.title, value: value.trim() }
893
- : {
894
- title: item.title,
895
- value: this.pipeTransform(value),
896
- action: item.action,
897
- copyToClipboard: item.copyToClipboard,
898
- ltr: ltrValues.includes(value.type),
899
- english: 'english' in value && !!value.english,
900
- };
901
- });
906
+ this.data = this.componentService.getValueData(this.values);
902
907
  }
903
908
  onClick(action) {
904
909
  if (!action)
@@ -917,13 +922,13 @@ class NgxHelperValueListComponent {
917
922
  this.copyTimeout = undefined;
918
923
  }, 2000);
919
924
  }
920
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValueListComponent, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
921
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperValueListComponent, isStandalone: true, selector: "ngx-helper-value-list", inputs: { values: "values", titleWidth: "titleWidth", emptyText: "emptyText" }, host: { properties: { "className": "this.className" } }, usesOnChanges: true, ngImport: i0, template: "@for (item of data; track $index) {\n<div class=\"value-list-item\" [class.even]=\"$index % 2 === 0\" [class.odd]=\"$index % 2 === 1\">\n <div class=\"title\" [style.width]=\"titleWidth\">{{ item.title }}:</div>\n <div class=\"value\">\n <div\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n [class.click]=\"!!item.action\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- ACTION -->\n @if (item.action) {\n <button mat-icon-button type=\"button\" (click)=\"onClick(item.action)\">\n <mat-icon>open_in_new</mat-icon>\n </button>\n\n }\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ClipboardModule }, { kind: "directive", type: i3.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }] });
925
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValueListComponent, deps: [{ token: i1.Router }, { token: ComponentService }], target: i0.ɵɵFactoryTarget.Component });
926
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.4", type: NgxHelperValueListComponent, isStandalone: true, selector: "ngx-helper-value-list", inputs: { values: "values", titleWidth: "titleWidth", emptyText: "emptyText" }, host: { properties: { "className": "this.className" } }, providers: [ComponentService], usesOnChanges: true, ngImport: i0, template: "@for (item of data; track $index) {\n<div class=\"value-list-item\" [class.even]=\"$index % 2 === 0\" [class.odd]=\"$index % 2 === 1\">\n <div class=\"title\" [style.width]=\"titleWidth\">{{ item.title }}:</div>\n <div class=\"value\">\n <div\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [style.color]=\"item.color\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n [class.click]=\"!!item.action\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- ACTION -->\n @if (item.action) {\n <button mat-icon-button type=\"button\" (click)=\"onClick(item.action)\">\n <mat-icon [style.color]=\"item.color\">open_in_new</mat-icon>\n </button>\n\n }\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ClipboardModule }, { kind: "directive", type: i3.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }] });
922
927
  }
923
928
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperValueListComponent, decorators: [{
924
929
  type: Component,
925
- args: [{ selector: 'ngx-helper-value-list', imports: [ClipboardModule, MatIcon, MatIconButton], template: "@for (item of data; track $index) {\n<div class=\"value-list-item\" [class.even]=\"$index % 2 === 0\" [class.odd]=\"$index % 2 === 1\">\n <div class=\"title\" [style.width]=\"titleWidth\">{{ item.title }}:</div>\n <div class=\"value\">\n <div\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n [class.click]=\"!!item.action\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- ACTION -->\n @if (item.action) {\n <button mat-icon-button type=\"button\" (click)=\"onClick(item.action)\">\n <mat-icon>open_in_new</mat-icon>\n </button>\n\n }\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n" }]
926
- }], ctorParameters: () => [{ type: i1.Router }], propDecorators: { className: [{
930
+ args: [{ selector: 'ngx-helper-value-list', imports: [ClipboardModule, MatIcon, MatIconButton], providers: [ComponentService], template: "@for (item of data; track $index) {\n<div class=\"value-list-item\" [class.even]=\"$index % 2 === 0\" [class.odd]=\"$index % 2 === 1\">\n <div class=\"title\" [style.width]=\"titleWidth\">{{ item.title }}:</div>\n <div class=\"value\">\n <div\n [style.display]=\"'inline-block'\"\n [style.direction]=\"item.ltr ? 'ltr' : '*'\"\n [style.color]=\"item.color\"\n [class.en]=\"item.english\"\n [class.empty]=\"!item.value\"\n [class.click]=\"!!item.action\"\n (click)=\"onClick(item.action)\"\n >\n {{ item.value || emptyText }}\n </div>\n <!-- ACTION -->\n @if (item.action) {\n <button mat-icon-button type=\"button\" (click)=\"onClick(item.action)\">\n <mat-icon [style.color]=\"item.color\">open_in_new</mat-icon>\n </button>\n\n }\n </div>\n <!-- COPY TO CLIPBOARD -->\n @if (item.copyToClipboard && item.value) {\n <button mat-icon-button type=\"button\" [cdkCopyToClipboard]=\"item.value\" (click)=\"onCopy($event, $index)\">\n <mat-icon>{{ copyIndex === $index ? 'done_all' : 'copy' }}</mat-icon>\n </button>\n }\n</div>\n}\n" }]
931
+ }], ctorParameters: () => [{ type: i1.Router }, { type: ComponentService }], propDecorators: { className: [{
927
932
  type: HostBinding,
928
933
  args: ['className']
929
934
  }], values: [{
@@ -1271,6 +1276,152 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
1271
1276
  args: [{ providedIn: 'root' }]
1272
1277
  }], ctorParameters: () => [{ type: i1$3.MatBottomSheet }, { type: i2$1.MatDialog }] });
1273
1278
 
1279
+ class UploadComponent {
1280
+ httpClient;
1281
+ className = 'ngx-helper-m3-http';
1282
+ host = true;
1283
+ bottom = '1rem';
1284
+ id;
1285
+ file;
1286
+ url;
1287
+ config;
1288
+ close;
1289
+ progress = 0;
1290
+ constructor(httpClient) {
1291
+ this.httpClient = httpClient;
1292
+ }
1293
+ ngAfterViewInit() {
1294
+ setTimeout(this.upload.bind(this), 0);
1295
+ }
1296
+ upload() {
1297
+ const formData = new FormData();
1298
+ formData.append('file', this.file);
1299
+ const body = this.config.body || {};
1300
+ Object.keys(body).forEach((k) => formData.append(k, body[k]));
1301
+ let headers = new HttpHeaders();
1302
+ const header = this.config.header || {};
1303
+ Object.keys(header).forEach((key) => (headers = headers.set(key, header[key])));
1304
+ let request;
1305
+ switch (this.config.method || 'POST') {
1306
+ case 'POST':
1307
+ request = this.httpClient.post(this.url, formData, { headers, reportProgress: true, observe: 'events' });
1308
+ break;
1309
+ case 'PUT':
1310
+ request = this.httpClient.put(this.url, formData, { headers, reportProgress: true, observe: 'events' });
1311
+ break;
1312
+ case 'PATCH':
1313
+ request = this.httpClient.patch(this.url, formData, { headers, reportProgress: true, observe: 'events' });
1314
+ break;
1315
+ }
1316
+ request.subscribe({
1317
+ next: (event) => {
1318
+ switch (event.type) {
1319
+ case HttpEventType.UploadProgress:
1320
+ if (!event.loaded || !event.total)
1321
+ return;
1322
+ const progress = (event.loaded / event.total) * 100;
1323
+ this.progress = progress > 100 ? 100 : +progress.toFixed(2);
1324
+ break;
1325
+ case HttpEventType.Response:
1326
+ this.progress = 100;
1327
+ this.close('RESPONSE', event.body, event.status);
1328
+ break;
1329
+ }
1330
+ },
1331
+ error: (error) => this.close('ERROR', error.error, error.status),
1332
+ });
1333
+ }
1334
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: UploadComponent, deps: [{ token: i1$4.HttpClient }], target: i0.ɵɵFactoryTarget.Component });
1335
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.4", type: UploadComponent, isStandalone: true, selector: "ng-component", host: { attributes: { "selector": "upload" }, properties: { "className": "this.className", "@host": "this.host", "style.bottom": "this.bottom" } }, ngImport: i0, template: "<div class=\"content\">\n <mat-icon>file_upload</mat-icon>\n <div class=\"file\">{{ file.name }}</div>\n</div>\n\n<div class=\"progress-container\">\n <div class=\"progress-value\" [style.width]=\"progress + '%'\"></div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], animations: [
1336
+ trigger('host', [
1337
+ transition(':enter', [
1338
+ style({ left: 'calc(-250px - 1rem)' }),
1339
+ animate('100ms ease-in-out', style({ left: '1rem' })),
1340
+ ]),
1341
+ ]),
1342
+ ] });
1343
+ }
1344
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: UploadComponent, decorators: [{
1345
+ type: Component,
1346
+ args: [{ host: { selector: 'upload' }, imports: [MatIcon], animations: [
1347
+ trigger('host', [
1348
+ transition(':enter', [
1349
+ style({ left: 'calc(-250px - 1rem)' }),
1350
+ animate('100ms ease-in-out', style({ left: '1rem' })),
1351
+ ]),
1352
+ ]),
1353
+ ], template: "<div class=\"content\">\n <mat-icon>file_upload</mat-icon>\n <div class=\"file\">{{ file.name }}</div>\n</div>\n\n<div class=\"progress-container\">\n <div class=\"progress-value\" [style.width]=\"progress + '%'\"></div>\n</div>\n" }]
1354
+ }], ctorParameters: () => [{ type: i1$4.HttpClient }], propDecorators: { className: [{
1355
+ type: HostBinding,
1356
+ args: ['className']
1357
+ }], host: [{
1358
+ type: HostBinding,
1359
+ args: ['@host']
1360
+ }], bottom: [{
1361
+ type: HostBinding,
1362
+ args: ['style.bottom']
1363
+ }] } });
1364
+
1365
+ class NgxHelperHttpService {
1366
+ applicationRef;
1367
+ injector;
1368
+ components = [];
1369
+ constructor(applicationRef, injector) {
1370
+ this.applicationRef = applicationRef;
1371
+ this.injector = injector;
1372
+ }
1373
+ getId() {
1374
+ let id = undefined;
1375
+ while (!id || this.components.some((c) => c.id === id))
1376
+ id = Helper.STRING.getRandom(10);
1377
+ return id;
1378
+ }
1379
+ updatePositions() {
1380
+ this.components.forEach((c, index) => {
1381
+ c.componentRef.instance.bottom = `calc(${(index / 1.5).toFixed(1)}rem + calc(${index * 40}px + 1rem))`;
1382
+ });
1383
+ }
1384
+ upload(file, url, arg1, arg2, arg3) {
1385
+ const config = typeof arg3 === 'function' ? arg1 : {};
1386
+ const onSuccess = typeof arg3 === 'function' ? arg2 : arg1;
1387
+ const onError = typeof arg3 === 'function' ? arg3 : arg2;
1388
+ const componentRef = createComponent(UploadComponent, {
1389
+ environmentInjector: this.applicationRef.injector,
1390
+ elementInjector: this.injector,
1391
+ });
1392
+ const id = this.getId();
1393
+ componentRef.instance.id = id;
1394
+ componentRef.instance.file = file;
1395
+ componentRef.instance.url = url;
1396
+ componentRef.instance.config = config;
1397
+ componentRef.instance.close = (type, result, status) => {
1398
+ this.applicationRef.detachView(componentRef.hostView);
1399
+ document.body.removeChild(htmlElement);
1400
+ this.components = this.components.filter((c) => c.id !== componentRef.instance.id);
1401
+ this.updatePositions();
1402
+ switch (type) {
1403
+ case 'RESPONSE':
1404
+ onSuccess(result || undefined, status);
1405
+ break;
1406
+ case 'ERROR':
1407
+ onError(result || undefined, status);
1408
+ break;
1409
+ }
1410
+ };
1411
+ const htmlElement = componentRef.hostView.rootNodes[0];
1412
+ this.applicationRef.attachView(componentRef.hostView);
1413
+ document.body.appendChild(htmlElement);
1414
+ this.components.push({ id, componentRef });
1415
+ this.updatePositions();
1416
+ }
1417
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperHttpService, deps: [{ token: i0.ApplicationRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable });
1418
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperHttpService, providedIn: 'root' });
1419
+ }
1420
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImport: i0, type: NgxHelperHttpService, decorators: [{
1421
+ type: Injectable,
1422
+ args: [{ providedIn: 'root' }]
1423
+ }], ctorParameters: () => [{ type: i0.ApplicationRef }, { type: i0.Injector }] });
1424
+
1274
1425
  /*
1275
1426
  * Public API Surface of ngx-helper-m3
1276
1427
  */
@@ -1279,5 +1430,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.4", ngImpor
1279
1430
  * Generated bundle index. Do not edit.
1280
1431
  */
1281
1432
 
1282
- export { NGX_HELPER_BOX_DATA, NGX_HELPER_CONFIG, NGX_HELPER_CONTAINER_CLOSE, NGX_HELPER_CONTAINER_DATA, NGX_HELPER_CONTAINER_TYPE, NGX_HELPER_PAGE_GROUP_DATA, NGX_HELPER_PAGE_GROUP_DATA_CHANGE, NGX_HELPER_PAGE_GROUP_ITEM, NgxHelperBankCardPipe, NgxHelperBoxComponent, NgxHelperCardComponent, NgxHelperConfirmService, NgxHelperContainerService, NgxHelperDatePipe, NgxHelperDurationPipe, NgxHelperFileSizePipe, NgxHelperLoaderComponent, NgxHelperMobilePipe, NgxHelperMultiLinePipe, NgxHelperNumberPipe, NgxHelperPageGroupComponent, NgxHelperPeriodPipe, NgxHelperPricePipe, NgxHelperSafePipe, NgxHelperSectionColumnComponent, NgxHelperSectionComponent, NgxHelperSectionStickyDirective, NgxHelperValueBoxComponent, NgxHelperValueListComponent, NgxHelperValuePipe, NgxHelperVolumePipe, NgxHelperWeightPipe, provideNgxHelperConfig };
1433
+ export { NGX_HELPER_BOX_DATA, NGX_HELPER_CONFIG, NGX_HELPER_CONTAINER_CLOSE, NGX_HELPER_CONTAINER_DATA, NGX_HELPER_CONTAINER_TYPE, NGX_HELPER_PAGE_GROUP_DATA, NGX_HELPER_PAGE_GROUP_DATA_CHANGE, NGX_HELPER_PAGE_GROUP_ITEM, NgxHelperBankCardPipe, NgxHelperBoxComponent, NgxHelperCardComponent, NgxHelperConfirmService, NgxHelperContainerService, NgxHelperDatePipe, NgxHelperDurationPipe, NgxHelperFileSizePipe, NgxHelperHttpService, NgxHelperLoaderComponent, NgxHelperMobilePipe, NgxHelperMultiLinePipe, NgxHelperNumberPipe, NgxHelperPageGroupComponent, NgxHelperPeriodPipe, NgxHelperPricePipe, NgxHelperSafePipe, NgxHelperSectionColumnComponent, NgxHelperSectionComponent, NgxHelperSectionStickyDirective, NgxHelperValueBoxComponent, NgxHelperValueListComponent, NgxHelperValuePipe, NgxHelperVolumePipe, NgxHelperWeightPipe, provideNgxHelperConfig };
1283
1434
  //# sourceMappingURL=webilix-ngx-helper-m3.mjs.map