@corp-products/ui-components 3.7.1 → 3.7.3

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 { ViewEncapsulation, Component, Input, ChangeDetectionStrategy, model, inject, Pipe, EventEmitter, Output, Injectable, Renderer2, ChangeDetectorRef, signal, effect, HostListener, ViewChild, input, computed, InjectionToken, Injector, createComponent, ViewContainerRef, ApplicationRef, EnvironmentInjector, DestroyRef } from '@angular/core';
2
+ import { ViewEncapsulation, Component, Input, ChangeDetectionStrategy, model, inject, Pipe, EventEmitter, Output, input, signal, computed, ViewChild, Injectable, Renderer2, ChangeDetectorRef, effect, HostListener, InjectionToken, Injector, createComponent, ViewContainerRef, ApplicationRef, EnvironmentInjector, DestroyRef } from '@angular/core';
3
3
  import * as i1 from 'primeng/button';
4
4
  import { Button, ButtonModule, ButtonStyle } from 'primeng/button';
5
5
  import * as i1$1 from '@angular/common';
@@ -35,11 +35,11 @@ import { IconField } from 'primeng/iconfield';
35
35
  import { InputIcon } from 'primeng/inputicon';
36
36
  import * as i2$2 from 'primeng/selectbutton';
37
37
  import { SelectButtonModule } from 'primeng/selectbutton';
38
+ import * as i4 from 'primeng/checkbox';
39
+ import { CheckboxModule } from 'primeng/checkbox';
38
40
  import * as i2$3 from 'primeng/multiselect';
39
41
  import { MultiSelectModule } from 'primeng/multiselect';
40
42
  import { Select } from 'primeng/select';
41
- import * as i4 from 'primeng/checkbox';
42
- import { CheckboxModule } from 'primeng/checkbox';
43
43
  import * as i1$5 from 'primeng/toggleswitch';
44
44
  import { ToggleSwitchModule } from 'primeng/toggleswitch';
45
45
  import * as i1$6 from '@ng-bootstrap/ng-bootstrap';
@@ -298,128 +298,110 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
298
298
  type: Input
299
299
  }] } });
300
300
 
301
- class FormUtils {
302
- static getFormControl(controlName, form) {
303
- if (!form)
304
- throw new Error(`Form is not initialized.`);
305
- const formControl = form.get(controlName);
306
- if (!formControl)
307
- throw new Error(`There's no form control with given name. '${controlName}'`);
308
- return formControl;
301
+ class LocalizedLabelPipe {
302
+ translateService = inject(TranslateService);
303
+ transform(label) {
304
+ if (!label)
305
+ return '';
306
+ const lang = this.translateService.getCurrentLang() || 'ar';
307
+ const suffix = lang.charAt(0).toUpperCase() + lang.slice(1);
308
+ const key = label + `${suffix}`;
309
+ return key;
309
310
  }
311
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: LocalizedLabelPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
312
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: LocalizedLabelPipe, isStandalone: true, name: "localizedLabel", pure: false });
310
313
  }
314
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: LocalizedLabelPipe, decorators: [{
315
+ type: Pipe,
316
+ args: [{
317
+ name: 'localizedLabel',
318
+ standalone: true,
319
+ pure: false,
320
+ }]
321
+ }] });
311
322
 
312
- var BasicErrorKeysEnum;
313
- (function (BasicErrorKeysEnum) {
314
- BasicErrorKeysEnum["required"] = "REQUIRED";
315
- BasicErrorKeysEnum["email"] = "EMAIL";
316
- BasicErrorKeysEnum["pattern"] = "PATTERN";
317
- BasicErrorKeysEnum["invalidArFormat"] = "INVALID_AR_FORMAT";
318
- BasicErrorKeysEnum["invalidLink"] = "INVALID_LINK";
319
- BasicErrorKeysEnum["endDateBeforeStartDate"] = "END_DATE_BEFORE_START_DATE";
320
- BasicErrorKeysEnum["startDateEqualsEndDate"] = "START_DATE_EQUALS_END_DATE";
321
- BasicErrorKeysEnum["endTimeBeforeStartTime"] = "END_TIME_BEFORE_START_TIME";
322
- BasicErrorKeysEnum["startTimeEqualsEndTime"] = "START_TIME_EQUALS_END_TIME";
323
- BasicErrorKeysEnum["integer"] = "INTEGER";
324
- BasicErrorKeysEnum["positiveNumber"] = "POSITIVE_NUMBER";
325
- BasicErrorKeysEnum["fileSelected"] = "FILE_SELECTED";
326
- BasicErrorKeysEnum["default"] = "DEFAULT";
327
- BasicErrorKeysEnum["numbersOnly"] = "NUMBERS_ONLY";
328
- })(BasicErrorKeysEnum || (BasicErrorKeysEnum = {}));
329
- var ErrorsWithValuesKeysEnum;
330
- (function (ErrorsWithValuesKeysEnum) {
331
- ErrorsWithValuesKeysEnum["minlength"] = "MIN_LENGTH";
332
- ErrorsWithValuesKeysEnum["maxlength"] = "MAX_LENGTH";
333
- ErrorsWithValuesKeysEnum["min"] = "MIN";
334
- ErrorsWithValuesKeysEnum["max"] = "MAX";
335
- ErrorsWithValuesKeysEnum["maxSize"] = "MAX_SIZE";
336
- ErrorsWithValuesKeysEnum["maxFiles"] = "MAX_FILES";
337
- ErrorsWithValuesKeysEnum["allowedTypes"] = "ALLOWED_TYPES";
338
- })(ErrorsWithValuesKeysEnum || (ErrorsWithValuesKeysEnum = {}));
323
+ const FileExtentions = [
324
+ 'jpeg',
325
+ 'pptx',
326
+ 'xlsx',
327
+ 'xls',
328
+ 'doc',
329
+ 'docx',
330
+ 'jpg',
331
+ 'png',
332
+ 'pdf',
333
+ 'txt',
334
+ 'csv',
335
+ 'msg',
336
+ 'zip',
337
+ 'win',
338
+ 'xlsb',
339
+ 'ppt',
340
+ 'rar',
341
+ ];
339
342
 
340
- class FormValidationService {
341
- translate = inject(TranslateService);
342
- getTranslation(key, interpolateParams) {
343
- return this.translate.instant(`VALIDATION.${key}`, interpolateParams);
344
- }
345
- getErrorMessage(errorKey, errorValue) {
346
- if (this.isBasicErrorKey(errorKey)) {
347
- return this.getTranslation(BasicErrorKeysEnum[errorKey]);
343
+ /**
344
+ * Transforms file size from bytes to readable format (B, KB, MB, GB, TB).
345
+ *
346
+ * Usage:
347
+ * {{ fileSize | fileSize }} // Default: auto unit, 2 decimals
348
+ * {{ fileSize | fileSize:0 }} // Auto unit, 0 decimals
349
+ * {{ fileSize | fileSize:2:'MB' }} // Force MB, 2 decimals
350
+ *
351
+ * @param value - File size in bytes
352
+ * @param decimals - Number of decimal places (default: 2)
353
+ * @param unit - Unit: 'B', 'KB', 'MB', 'GB', 'TB' (default: auto)
354
+ */
355
+ class FileSizePipe {
356
+ units = ['B', 'KB', 'MB', 'GB', 'TB'];
357
+ k = 1024;
358
+ transform(bytes, decimals = 2, unit) {
359
+ if (bytes === null || bytes === undefined || isNaN(bytes)) {
360
+ return '0 B';
348
361
  }
349
- if (this.isErrorWithValueKey(errorKey)) {
350
- return this.getErrorWithValueMessage(errorKey, errorValue);
362
+ if (bytes === 0) {
363
+ return '0 B';
351
364
  }
352
- return this.getTranslation(BasicErrorKeysEnum.default);
353
- }
354
- // Basic error keys are the keys that don't have any values to interpolate. like required, email, etc.
355
- isBasicErrorKey(key) {
356
- return Object.keys(BasicErrorKeysEnum).includes(key);
357
- }
358
- // Error keys with values are the keys that have values to interpolate. like minlength, maxlength, etc.
359
- isErrorWithValueKey(key) {
360
- return Object.keys(ErrorsWithValuesKeysEnum).includes(key);
365
+ // If a specific unit is requested
366
+ if (unit) {
367
+ const unitIndex = this.units.indexOf(unit);
368
+ if (unitIndex === -1) {
369
+ return this.autoFormat(bytes, decimals);
370
+ }
371
+ const divisor = Math.pow(this.k, unitIndex);
372
+ const value = bytes / divisor;
373
+ return `${this.formatNumber(value, decimals)} ${unit}`;
374
+ }
375
+ // Auto-detect the best unit
376
+ return this.autoFormat(bytes, decimals);
361
377
  }
362
- getErrorWithValueMessage(errorKey, errorValue) {
363
- const messages = {
364
- minlength: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.minlength, {
365
- requiredLength: val?.requiredLength,
366
- actualLength: val?.actualLength,
367
- }),
368
- maxlength: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.maxlength, {
369
- requiredLength: val?.requiredLength,
370
- actualLength: val?.actualLength,
371
- }),
372
- min: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.min, { min: val?.min }),
373
- max: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.max, { max: val?.max }),
374
- maxSize: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.maxSize, { size: val?.requiredLength }),
375
- maxFiles: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.maxFiles, { size: val?.requiredLength }),
376
- allowedTypes: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.allowedTypes, { types: val?.join(', ') }),
377
- };
378
- return messages[errorKey](errorValue);
378
+ autoFormat(bytes, decimals) {
379
+ const i = Math.floor(Math.log(Math.abs(bytes)) / Math.log(this.k));
380
+ const unitIndex = Math.min(i, this.units.length - 1);
381
+ const value = bytes / Math.pow(this.k, unitIndex);
382
+ return `${this.formatNumber(value, decimals)} ${this.units[unitIndex]}`;
379
383
  }
380
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormValidationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
381
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormValidationService, providedIn: 'root' });
382
- }
383
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormValidationService, decorators: [{
384
- type: Injectable,
385
- args: [{
386
- providedIn: 'root',
387
- }]
388
- }] });
389
-
390
- class ValidationErrorsPipe {
391
- formValidationService = inject(FormValidationService);
392
- // allowed keys here to handle errors in case of cross-validators like startDate and endDate validators,
393
- // we pass this custom key to handle the error messages only for the allowed keys
394
- transform(errors, allowedKeys) {
395
- if (!errors)
396
- return [];
397
- return Object.keys(errors)
398
- .filter((errorKey) => !allowedKeys || allowedKeys.includes(errorKey)) // Filter errors if allowedKeys are provided
399
- .map((errorKey) => {
400
- return this.formValidationService.getErrorMessage(errorKey, errors[errorKey]);
401
- });
384
+ formatNumber(value, decimals) {
385
+ return parseFloat(value.toFixed(decimals)).toString();
402
386
  }
403
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ValidationErrorsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
404
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: ValidationErrorsPipe, isStandalone: true, name: "validationErrors" });
387
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FileSizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
388
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: FileSizePipe, isStandalone: true, name: "fileSize" });
405
389
  }
406
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ValidationErrorsPipe, decorators: [{
390
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FileSizePipe, decorators: [{
407
391
  type: Pipe,
408
392
  args: [{
409
- name: "validationErrors",
393
+ name: 'fileSize',
410
394
  standalone: true,
411
- pure: true
412
395
  }]
413
396
  }] });
414
397
 
415
- function numbersOnlyValidator(control) {
416
- const value = control.value;
417
- if (value === null || value === undefined || value === '') {
418
- return null;
419
- }
420
- const isNumbersOnly = /^[0-9]+$/.test(value);
421
- return isNumbersOnly ? null : { numbersOnly: true };
422
- }
398
+ var UploadStatus;
399
+ (function (UploadStatus) {
400
+ UploadStatus["PENDING"] = "pending";
401
+ UploadStatus["SUCCESS"] = "success";
402
+ UploadStatus["UPLOADING"] = "uploading";
403
+ UploadStatus["FAILED"] = "failed";
404
+ })(UploadStatus || (UploadStatus = {}));
423
405
 
424
406
  class BaseInputComponent {
425
407
  control;
@@ -470,1416 +452,1441 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
470
452
  type: Input
471
453
  }] } });
472
454
 
473
- class AutoCompleteComponent extends BaseInputComponent {
474
- selectedItemTemplate = null;
475
- // eslint-disable-next-line @angular-eslint/no-output-on-prefix
476
- onSearch = new EventEmitter();
477
- selectOption = new EventEmitter();
478
- items = [];
479
- minLengthToSearch = 3;
480
- delay = 300; // default value
481
- basicInput;
482
- typeAhead = false;
483
- variant = 'over';
484
- constructor() {
485
- super();
486
- }
487
- search(event) {
488
- this.onSearch.emit(event.query);
489
- }
490
- onSelect(event) {
491
- this.selectOption.emit(event);
492
- }
493
- onKeyDown(event) {
494
- if (!['Enter', 'Tab', ' '].includes(event.key))
495
- return;
496
- event.preventDefault();
497
- const input = event.target;
498
- this.addValueFromInput(input);
499
- }
500
- onBlur(event) {
501
- const input = event.target;
502
- this.addValueFromInput(input);
503
- }
504
- addValueFromInput(input) {
505
- const value = input.value?.trim();
506
- if (!value)
507
- return;
508
- const current = this.control.value ?? [];
509
- if (!current.includes(value)) {
510
- this.control.setValue([...current, value]);
511
- this.control.markAsDirty();
512
- }
513
- input.value = '';
514
- }
515
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AutoCompleteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
516
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: AutoCompleteComponent, isStandalone: true, selector: "stc-auto-complete", inputs: { selectedItemTemplate: "selectedItemTemplate", items: "items", minLengthToSearch: "minLengthToSearch", delay: "delay", basicInput: "basicInput", typeAhead: "typeAhead", variant: "variant" }, outputs: { onSearch: "onSearch", selectOption: "selectOption" }, usesInheritance: true, ngImport: i0, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n @if (!required) {\r\n <span class=\"absolute top-[6px] left-0 text-[10px] text-gray-400\">{{'forms.config.optional' | translate}}</span>\r\n }\r\n <p-floatlabel [variant]=\"variant\" class=\"autoComplete\">\r\n <p-auto-complete (keydown)=\"onKeyDown($event)\" (onBlur)=\"onBlur($event)\" (completeMethod)=\"search($event)\" (onSelect)=\"onSelect($event)\" [delay]=\"delay\"\r\n [disabled]=\"disabled\" [formControl]=\"control\" [id]=\"inputId\" fluid [typeahead]=\"typeAhead\"\r\n [inputStyleClass]=\"'reset-default-styles w-full' + (basicInput ? ' basic-style': ' ')\"\r\n [minLength]=\"minLengthToSearch\" [name]=\"name\" [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid}\"\r\n [placeholder]=\"placeholder\" [styleClass]=\"'w-full'\" multiple [suggestions]=\"items\">\r\n <ng-template let-item pTemplate=\"item\">\r\n @if (selectedItemTemplate) {\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"selectedItemTemplate\" />\r\n }\r\n </ng-template>\r\n </p-auto-complete>\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"isInvalid\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n\r\n</div>\r\n", styles: [".text-required{color:red}.p-error{color:#dc2626}.autoComplete .p-floatlabel-in{height:auto!important}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "directive", type: PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "pipe", type: ValidationErrorsPipe, name: "validationErrors" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None });
517
- }
518
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AutoCompleteComponent, decorators: [{
519
- type: Component,
520
- args: [{ selector: 'stc-auto-complete', standalone: true, imports: [
521
- ReactiveFormsModule,
522
- AutoComplete,
523
- PrimeTemplate,
524
- NgIf,
525
- NgTemplateOutlet,
526
- NgClass,
527
- JsonPipe,
528
- ValidationErrorsPipe,
529
- TranslatePipe,
530
- FloatLabel,
531
- ], encapsulation: ViewEncapsulation.None, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n @if (!required) {\r\n <span class=\"absolute top-[6px] left-0 text-[10px] text-gray-400\">{{'forms.config.optional' | translate}}</span>\r\n }\r\n <p-floatlabel [variant]=\"variant\" class=\"autoComplete\">\r\n <p-auto-complete (keydown)=\"onKeyDown($event)\" (onBlur)=\"onBlur($event)\" (completeMethod)=\"search($event)\" (onSelect)=\"onSelect($event)\" [delay]=\"delay\"\r\n [disabled]=\"disabled\" [formControl]=\"control\" [id]=\"inputId\" fluid [typeahead]=\"typeAhead\"\r\n [inputStyleClass]=\"'reset-default-styles w-full' + (basicInput ? ' basic-style': ' ')\"\r\n [minLength]=\"minLengthToSearch\" [name]=\"name\" [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid}\"\r\n [placeholder]=\"placeholder\" [styleClass]=\"'w-full'\" multiple [suggestions]=\"items\">\r\n <ng-template let-item pTemplate=\"item\">\r\n @if (selectedItemTemplate) {\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"selectedItemTemplate\" />\r\n }\r\n </ng-template>\r\n </p-auto-complete>\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"isInvalid\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n\r\n</div>\r\n", styles: [".text-required{color:red}.p-error{color:#dc2626}.autoComplete .p-floatlabel-in{height:auto!important}\n"] }]
532
- }], ctorParameters: () => [], propDecorators: { selectedItemTemplate: [{
533
- type: Input
534
- }], onSearch: [{
535
- type: Output
536
- }], selectOption: [{
537
- type: Output
538
- }], items: [{
539
- type: Input
540
- }], minLengthToSearch: [{
541
- type: Input
542
- }], delay: [{
543
- type: Input
544
- }], basicInput: [{
545
- type: Input
546
- }], typeAhead: [{
547
- type: Input
548
- }], variant: [{
549
- type: Input
550
- }] } });
551
-
552
- class DatePickerComponent extends BaseInputComponent {
553
- showIcon = false;
554
- showClear = false;
555
- basicInput;
556
- isTimeOnly = false;
557
- minDate;
558
- maxDate;
559
- hourFormat = '12';
560
- nowTime = new Date();
561
- selectionMode = 'single';
562
- onAfterClearDate = new EventEmitter();
563
- variant = 'over';
564
- withoutTime = false;
565
- innerControl = new FormControl(null);
566
- constructor() {
567
- super();
568
- }
569
- ngOnInit() {
570
- if (typeof this.control?.value === 'string') {
571
- const date = new Date(this.control.value);
572
- if (date) {
573
- this.innerControl.setValue(date, { emitEvent: false });
574
- }
575
- }
576
- this.control.valueChanges.subscribe((value) => {
577
- if (!value)
578
- this.innerControl.reset();
579
- });
580
- }
581
- selectCurrentTime(e) {
582
- if (this.withoutTime) {
583
- const d = new Date();
584
- this.control.setValue(d.toISOString().split('T')[0]);
585
- return;
586
- }
587
- this.control.setValue(this.nowTime);
588
- }
589
- clearButtonClick(e) {
590
- this.control.setValue(null);
591
- }
592
- afterClearDate() {
593
- this.control.reset();
594
- this.onAfterClearDate.emit();
595
- }
596
- onDateChange(value) {
597
- const dateOnly = value instanceof Date ? formatDate(value, 'yyyy-MM-dd', 'en-US') : value;
598
- this.control.setValue(dateOnly, { emitEvent: true });
599
- }
600
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
601
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DatePickerComponent, isStandalone: true, selector: "stc-date-picker", inputs: { showIcon: "showIcon", showClear: "showClear", basicInput: "basicInput", isTimeOnly: "isTimeOnly", minDate: "minDate", maxDate: "maxDate", hourFormat: "hourFormat", selectionMode: "selectionMode", variant: "variant", withoutTime: "withoutTime" }, outputs: { onAfterClearDate: "onAfterClearDate" }, usesInheritance: true, ngImport: i0, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n <p-floatlabel [variant]=\"variant\">\r\n <p-datepicker [selectionMode]=\"selectionMode\" [disabled]=\"disabled\" [formControl]=\"innerControl\"\r\n (onSelect)=\"onDateChange($event)\" [iconDisplay]=\"'input'\" [showClear]=\"showClear\" (onClear)=\"afterClearDate()\"\r\n [inputId]=\"inputId\" [inputStyleClass]=\"'reset-default-styles ' + (basicInput ? 'basic-style' : '')\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid }\" [placeholder]=\"placeholder\" [showIcon]=\"showIcon\"\r\n [class]=\"'w-full'\" appendTo=\"body\" [timeOnly]=\"isTimeOnly\" [hourFormat]=\"hourFormat\" [minDate]=\"minDate\"\r\n [maxDate]=\"maxDate\">\r\n @if (isTimeOnly) {\r\n <ng-template #inputicon let-clickCallBack=\"clickCallBack\">\r\n <i class=\"text-[18px] font-icon-time-clock\" (click)=\"clickCallBack($event)\"></i>\r\n </ng-template>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"p-datepicker-buttonbar\">\r\n <button pButton type=\"button\" class=\"p-button-text\" (click)=\"selectCurrentTime($event)\">\u0627\u0644\u0627\u0646\r\n </button>\r\n <button pButton type=\"button\" class=\"p-button-text\" (click)=\"clearButtonClick($event)\"> \u0627\u0644\u063A\u0627\u0621</button>\r\n </div>\r\n </ng-template>\r\n }\r\n </p-datepicker>\r\n\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n</div>\r\n", styles: [".p-datepicker{@apply relative;}.p-datepicker-clear-icon{@apply cursor-pointer absolute top-[50%] left-[13px] text-[var(--p-datepicker-input-icon-color)] ml-[calc(var(--p-icon-size))] leading-none;}.text-required{color:red}.p-error{color:#dc2626}stc-date-picker.w-full,stc-date-picker.w-full .field,stc-date-picker.w-full .p-floatlabel,stc-date-picker.w-full .p-datepicker,stc-date-picker.w-full .p-inputtext{@apply w-full;}stc-date-picker input{width:100%}stc-date-picker.w-full .p-datepicker{@apply block;}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: DatePickerModule }, { kind: "directive", type: i2$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i3$1.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "pipe", type: ValidationErrorsPipe, name: "validationErrors" }], encapsulation: i0.ViewEncapsulation.None });
602
- }
603
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatePickerComponent, decorators: [{
604
- type: Component,
605
- args: [{ selector: 'stc-date-picker', standalone: true, imports: [
606
- FormsModule,
607
- DatePicker,
608
- ReactiveFormsModule,
609
- NgClass,
610
- DatePickerModule,
611
- ValidationErrorsPipe,
612
- FloatLabelModule,
613
- ], encapsulation: ViewEncapsulation.None, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n <p-floatlabel [variant]=\"variant\">\r\n <p-datepicker [selectionMode]=\"selectionMode\" [disabled]=\"disabled\" [formControl]=\"innerControl\"\r\n (onSelect)=\"onDateChange($event)\" [iconDisplay]=\"'input'\" [showClear]=\"showClear\" (onClear)=\"afterClearDate()\"\r\n [inputId]=\"inputId\" [inputStyleClass]=\"'reset-default-styles ' + (basicInput ? 'basic-style' : '')\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid }\" [placeholder]=\"placeholder\" [showIcon]=\"showIcon\"\r\n [class]=\"'w-full'\" appendTo=\"body\" [timeOnly]=\"isTimeOnly\" [hourFormat]=\"hourFormat\" [minDate]=\"minDate\"\r\n [maxDate]=\"maxDate\">\r\n @if (isTimeOnly) {\r\n <ng-template #inputicon let-clickCallBack=\"clickCallBack\">\r\n <i class=\"text-[18px] font-icon-time-clock\" (click)=\"clickCallBack($event)\"></i>\r\n </ng-template>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"p-datepicker-buttonbar\">\r\n <button pButton type=\"button\" class=\"p-button-text\" (click)=\"selectCurrentTime($event)\">\u0627\u0644\u0627\u0646\r\n </button>\r\n <button pButton type=\"button\" class=\"p-button-text\" (click)=\"clearButtonClick($event)\"> \u0627\u0644\u063A\u0627\u0621</button>\r\n </div>\r\n </ng-template>\r\n }\r\n </p-datepicker>\r\n\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n</div>\r\n", styles: [".p-datepicker{@apply relative;}.p-datepicker-clear-icon{@apply cursor-pointer absolute top-[50%] left-[13px] text-[var(--p-datepicker-input-icon-color)] ml-[calc(var(--p-icon-size))] leading-none;}.text-required{color:red}.p-error{color:#dc2626}stc-date-picker.w-full,stc-date-picker.w-full .field,stc-date-picker.w-full .p-floatlabel,stc-date-picker.w-full .p-datepicker,stc-date-picker.w-full .p-inputtext{@apply w-full;}stc-date-picker input{width:100%}stc-date-picker.w-full .p-datepicker{@apply block;}\n"] }]
614
- }], ctorParameters: () => [], propDecorators: { showIcon: [{
615
- type: Input
616
- }], showClear: [{
617
- type: Input
618
- }], basicInput: [{
619
- type: Input
620
- }], isTimeOnly: [{
621
- type: Input
622
- }], minDate: [{
623
- type: Input
624
- }], maxDate: [{
625
- type: Input
626
- }], hourFormat: [{
627
- type: Input
628
- }], selectionMode: [{
629
- type: Input
630
- }], onAfterClearDate: [{
631
- type: Output
632
- }], variant: [{
633
- type: Input
634
- }], withoutTime: [{
635
- type: Input
636
- }] } });
637
-
638
- class InputComponent extends BaseInputComponent {
639
- type = 'text';
640
- contentType = 'text';
641
- size = "small";
642
- prefix;
643
- rows = 2;
644
- cols = 20;
645
- autoResize = false;
646
- basicInput;
647
- noStyle;
648
- canClear;
649
- hideOptionalLabel;
650
- inputDirection = 'inherit';
651
- variant = 'over';
652
- defaultColor = '#DFE0E6';
653
- iconClass;
654
- iconPosition = 'left';
655
- constructor() {
656
- super();
657
- }
658
- clearInput() {
659
- this.control.reset();
660
- }
661
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
662
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: InputComponent, isStandalone: true, selector: "stc-input", inputs: { type: "type", contentType: "contentType", size: "size", prefix: "prefix", rows: "rows", cols: "cols", autoResize: "autoResize", basicInput: "basicInput", noStyle: "noStyle", canClear: "canClear", hideOptionalLabel: "hideOptionalLabel", inputDirection: "inputDirection", variant: "variant", defaultColor: "defaultColor", iconClass: "iconClass", iconPosition: "iconPosition" }, usesInheritance: true, ngImport: i0, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n\r\n <!-- input text align will be handled according to lang when implemented -->\r\n\r\n @switch (type) {\r\n @case ('textarea') {\r\n @if (label) {\r\n <div class=\"flex items-center justify-between gap-2\">\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n <!-- @else if (!hideOptionalLabel) {\r\n <span span class=\"optional-label\">{{'forms.config.optional' | translate}}</span>\r\n } -->\r\n </label>\r\n <ng-content></ng-content>\r\n </div>\r\n }\r\n <textarea [name]=\"name\" [id]=\"inputId\" [formControl]=\"control\" [placeholder]=\"placeholder\" [readonly]=\"readonly\"\r\n [disabled]=\"disabled\" pTextarea [rows]=\"rows\" [cols]=\"cols\" [autoResize]=\"autoResize\" [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \"\r\n [ngClass]=\"{'ng-invalid ng-dirty': control.invalid && (control.dirty || control.touched), 'basic-style': basicInput, 'no-style':noStyle}\">\r\n </textarea>\r\n }\r\n @case ('withIcon') {\r\n <p-iconfield class=\"filter-input\">\r\n <p-inputicon>\r\n <i [class]=\"iconClass\"></i>\r\n </p-inputicon>\r\n <input pInputText [id]=\"inputId\" type=\"text\" [placeholder]=\"placeholder\" [formControl]=\"control\" [readonly]=\"readonly\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid, 'basic-style': basicInput, 'no-style':noStyle}\" />\r\n @if (canClear && control.value) {\r\n <p-inputIcon (click)=\"clearInput()\">\r\n <i class=\"pi pi-times cursor-pointer text-sm text-gray-400 hover:text-gray-600\"></i>\r\n </p-inputIcon>\r\n }\r\n\r\n </p-iconfield>\r\n }\r\n @default {\r\n <p-floatlabel [variant]=\"variant\">\r\n <!-- <input pInputText id=\"value2\" [(ngModel)]=\"value2\" [invalid]=\"!value2\" autocomplete=\"off\" /> -->\r\n <input [id]=\"inputId\" [type]=\"'text-float-label'\" [formControl]=\"control\" [readonly]=\"readonly\" [pSize]=\"size\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \" [disabled]=\"disabled\" [name]=\"name\" pInputText [ngStyle]=\"{'direction': inputDirection || 'inherit'}\"\r\n class=\"w-full\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid, 'basic-style': basicInput, 'no-style':noStyle}\" />\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (prefix) {\r\n <span class=\"absolute top-[40px] font-bold text-[16px] left-[25px]\">\r\n {{ prefix }}\r\n </span>\r\n }\r\n\r\n\r\n }\r\n }\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n</div>", styles: ["textarea{@apply h-auto min-h-[50px] overflow-auto;}textarea,.p-select,input{border-radius:0;border-color:#dfe0e6}textarea:enabled:hover,.p-select:enabled:hover,input:enabled:hover{border-color:#dfe0e6}textarea:not(.p-disabled).p-focus,textarea:not(.p-disabled).p-focus:hover,textarea:focus,.p-select:not(.p-disabled).p-focus,.p-select:not(.p-disabled).p-focus:hover,.p-select:focus,input:not(.p-disabled).p-focus,input:not(.p-disabled).p-focus:hover,input:focus{outline:#DFE0E6;border-color:#dfe0e6}.p-floatlabel:has(input:focus) label,.p-floatlabel:has(input:-webkit-autofill) label,.p-floatlabel:has(textarea:focus) label,.p-floatlabel:has(.p-inputwrapper-focus) label{color:#687078}.p-inputtext:enabled:focus{border-color:#dfe0e6}.text-required{color:red}.p-error{color:#dc2626}.optional-label{@apply text-[10px] text-gray-400;margin-inline-start:4px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i3$1.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "component", type: InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "component", type: IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "pipe", type: ValidationErrorsPipe, name: "validationErrors" }] });
663
- }
664
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InputComponent, decorators: [{
665
- type: Component,
666
- args: [{ selector: 'stc-input', standalone: true, imports: [
667
- ReactiveFormsModule,
668
- InputText,
669
- Textarea,
670
- ValidationErrorsPipe,
671
- NgClass,
672
- NgStyle,
673
- TranslatePipe,
674
- FloatLabelModule,
675
- InputIcon,
676
- IconField,
677
- ], template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n\r\n <!-- input text align will be handled according to lang when implemented -->\r\n\r\n @switch (type) {\r\n @case ('textarea') {\r\n @if (label) {\r\n <div class=\"flex items-center justify-between gap-2\">\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n <!-- @else if (!hideOptionalLabel) {\r\n <span span class=\"optional-label\">{{'forms.config.optional' | translate}}</span>\r\n } -->\r\n </label>\r\n <ng-content></ng-content>\r\n </div>\r\n }\r\n <textarea [name]=\"name\" [id]=\"inputId\" [formControl]=\"control\" [placeholder]=\"placeholder\" [readonly]=\"readonly\"\r\n [disabled]=\"disabled\" pTextarea [rows]=\"rows\" [cols]=\"cols\" [autoResize]=\"autoResize\" [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \"\r\n [ngClass]=\"{'ng-invalid ng-dirty': control.invalid && (control.dirty || control.touched), 'basic-style': basicInput, 'no-style':noStyle}\">\r\n </textarea>\r\n }\r\n @case ('withIcon') {\r\n <p-iconfield class=\"filter-input\">\r\n <p-inputicon>\r\n <i [class]=\"iconClass\"></i>\r\n </p-inputicon>\r\n <input pInputText [id]=\"inputId\" type=\"text\" [placeholder]=\"placeholder\" [formControl]=\"control\" [readonly]=\"readonly\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid, 'basic-style': basicInput, 'no-style':noStyle}\" />\r\n @if (canClear && control.value) {\r\n <p-inputIcon (click)=\"clearInput()\">\r\n <i class=\"pi pi-times cursor-pointer text-sm text-gray-400 hover:text-gray-600\"></i>\r\n </p-inputIcon>\r\n }\r\n\r\n </p-iconfield>\r\n }\r\n @default {\r\n <p-floatlabel [variant]=\"variant\">\r\n <!-- <input pInputText id=\"value2\" [(ngModel)]=\"value2\" [invalid]=\"!value2\" autocomplete=\"off\" /> -->\r\n <input [id]=\"inputId\" [type]=\"'text-float-label'\" [formControl]=\"control\" [readonly]=\"readonly\" [pSize]=\"size\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \" [disabled]=\"disabled\" [name]=\"name\" pInputText [ngStyle]=\"{'direction': inputDirection || 'inherit'}\"\r\n class=\"w-full\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid, 'basic-style': basicInput, 'no-style':noStyle}\" />\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (prefix) {\r\n <span class=\"absolute top-[40px] font-bold text-[16px] left-[25px]\">\r\n {{ prefix }}\r\n </span>\r\n }\r\n\r\n\r\n }\r\n }\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n</div>", styles: ["textarea{@apply h-auto min-h-[50px] overflow-auto;}textarea,.p-select,input{border-radius:0;border-color:#dfe0e6}textarea:enabled:hover,.p-select:enabled:hover,input:enabled:hover{border-color:#dfe0e6}textarea:not(.p-disabled).p-focus,textarea:not(.p-disabled).p-focus:hover,textarea:focus,.p-select:not(.p-disabled).p-focus,.p-select:not(.p-disabled).p-focus:hover,.p-select:focus,input:not(.p-disabled).p-focus,input:not(.p-disabled).p-focus:hover,input:focus{outline:#DFE0E6;border-color:#dfe0e6}.p-floatlabel:has(input:focus) label,.p-floatlabel:has(input:-webkit-autofill) label,.p-floatlabel:has(textarea:focus) label,.p-floatlabel:has(.p-inputwrapper-focus) label{color:#687078}.p-inputtext:enabled:focus{border-color:#dfe0e6}.text-required{color:red}.p-error{color:#dc2626}.optional-label{@apply text-[10px] text-gray-400;margin-inline-start:4px}\n"] }]
678
- }], ctorParameters: () => [], propDecorators: { type: [{
679
- type: Input
680
- }], contentType: [{
681
- type: Input
682
- }], size: [{
683
- type: Input
684
- }], prefix: [{
685
- type: Input
686
- }], rows: [{
687
- type: Input
688
- }], cols: [{
689
- type: Input
690
- }], autoResize: [{
691
- type: Input
692
- }], basicInput: [{
693
- type: Input
694
- }], noStyle: [{
695
- type: Input
696
- }], canClear: [{
697
- type: Input
698
- }], hideOptionalLabel: [{
699
- type: Input
700
- }], inputDirection: [{
701
- type: Input
702
- }], variant: [{
703
- type: Input
704
- }], defaultColor: [{
705
- type: Input
706
- }], iconClass: [{
707
- type: Input
708
- }], iconPosition: [{
709
- type: Input
710
- }] } });
711
-
712
- class SelectButtonComponent extends BaseInputComponent {
713
- onChange = new EventEmitter();
714
- options;
715
- title;
716
- changeValue(e) {
717
- this.onChange.emit(e.value);
718
- }
719
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SelectButtonComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
720
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SelectButtonComponent, isStandalone: true, selector: "stc-select-button", inputs: { options: "options", title: "title" }, outputs: { onChange: "onChange" }, usesInheritance: true, ngImport: i0, template: "<div class=\"grid grid-cols-12 gap-x-4 gap-y-0 items-end\">\r\n <div class=\"col-span-12\">\r\n <div class=\"text-[14px] font-bold mb-1\">{{ title }}</div>\r\n <div class=\"grid w-100 bg-gray-100 rounded drop-shadow-basic\">\r\n <p-selectButton [disabled]=\"disabled\"\r\n [options]=\"options\"\r\n [formControl]=\"control\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n class=\"rounded\"\r\n [styleClass]=\"'full-width'\"\r\n (onChange)=\"changeValue($event)\">\r\n <ng-template let-item class=\"flex w-100\">\r\n <div class=\"col-span-4\">\r\n <span>{{ item.value }}</span>\r\n </div>\r\n </ng-template>\r\n </p-selectButton>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: SelectButtonModule }, { kind: "component", type: i2$2.SelectButton, selector: "p-selectButton, p-selectbutton, p-select-button", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "styleClass", "ariaLabelledBy", "dataKey", "autofocus", "size", "fluid"], outputs: ["onOptionClick", "onChange"] }, { kind: "ngmodule", type: FormsModule }] });
721
- }
722
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SelectButtonComponent, decorators: [{
723
- type: Component,
724
- args: [{ selector: "stc-select-button", standalone: true, imports: [ReactiveFormsModule, SelectButtonModule, FormsModule], template: "<div class=\"grid grid-cols-12 gap-x-4 gap-y-0 items-end\">\r\n <div class=\"col-span-12\">\r\n <div class=\"text-[14px] font-bold mb-1\">{{ title }}</div>\r\n <div class=\"grid w-100 bg-gray-100 rounded drop-shadow-basic\">\r\n <p-selectButton [disabled]=\"disabled\"\r\n [options]=\"options\"\r\n [formControl]=\"control\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n class=\"rounded\"\r\n [styleClass]=\"'full-width'\"\r\n (onChange)=\"changeValue($event)\">\r\n <ng-template let-item class=\"flex w-100\">\r\n <div class=\"col-span-4\">\r\n <span>{{ item.value }}</span>\r\n </div>\r\n </ng-template>\r\n </p-selectButton>\r\n </div>\r\n </div>\r\n</div>\r\n" }]
725
- }], propDecorators: { onChange: [{
726
- type: Output
727
- }], options: [{
728
- type: Input
729
- }], title: [{
730
- type: Input
731
- }] } });
732
-
733
- class SelectComponent extends BaseInputComponent {
734
- selectedItemTemplate = null;
735
- optionTemplate = null;
736
- options = [];
737
- optionLabel;
738
- optionValue;
739
- emptyMessage;
740
- checkmark = true;
741
- showClear = false;
742
- editable = false;
743
- filter = false;
744
- multiple = false;
745
- filterBy;
746
- selectAllLabel;
747
- dataKey;
748
- size = 'small';
749
- selectedItemsLabel;
750
- basicInput;
751
- variant = 'over';
752
- // eslint-disable-next-line @angular-eslint/no-output-native
753
- change = new EventEmitter();
754
- defaultColor = '#DFE0E6';
755
- allSelectd = false;
756
- constructor() {
757
- super();
758
- }
759
- toggleAll(event) {
760
- if (!event.checked) {
761
- this.control.setValue([]);
762
- return;
763
- }
764
- const values = this.optionValue
765
- ? this.options.map((o) => o[this.optionValue])
766
- : this.options;
767
- this.control.setValue([...values]);
768
- }
769
- onMultiSelectClear() {
770
- this.allSelectd = false;
771
- }
772
- onChange(e) {
773
- this.change.emit(e);
774
- }
775
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
776
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: SelectComponent, isStandalone: true, selector: "stc-select", inputs: { selectedItemTemplate: "selectedItemTemplate", optionTemplate: "optionTemplate", options: "options", optionLabel: "optionLabel", optionValue: "optionValue", emptyMessage: "emptyMessage", checkmark: "checkmark", showClear: "showClear", editable: "editable", filter: "filter", multiple: "multiple", filterBy: "filterBy", selectAllLabel: "selectAllLabel", dataKey: "dataKey", size: "size", selectedItemsLabel: "selectedItemsLabel", basicInput: "basicInput", variant: "variant", defaultColor: "defaultColor" }, outputs: { change: "change" }, usesInheritance: true, ngImport: i0, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n\r\n @if(multiple) {\r\n <p-floatLabel [variant]=\"variant\">\r\n\r\n <p-multiselect\r\n [disabled]=\"disabled\"\r\n [filterBy]=\"filterBy\"\r\n [filter]=\"filter\"\r\n [formControl]=\"control\"\r\n [id]=\"inputId\"\r\n [name]=\"name\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid }\"\r\n [optionLabel]=\"optionLabel\"\r\n [optionValue]=\"optionValue\"\r\n [options]=\"options\"\r\n [showToggleAll]=\"false\"\r\n [placeholder]=\"placeholder\"\r\n [emptyMessage]=\"emptyMessage || ('shared.no_results_found'|translate)\"\r\n [readonly]=\"readonly\"\r\n [showClear]=\"showClear\"\r\n (onClear)=\"onMultiSelectClear()\"\r\n class=\"w-full\"\r\n [size]=\"size\"\r\n [selectedItemsLabel]=\"selectedItemsLabel || ('shared.Items_Selected'| translate: {count: '{0}'})\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \"\r\n (onChange)=\"onChange($event)\"\r\n [ngClass]=\"{ 'basic-style': basicInput }\"\r\n >\r\n\r\n @if (selectAllLabel) {\r\n <ng-template #filter>\r\n <p-checkbox\r\n binary=\"true\"\r\n [(ngModel)]=\"allSelectd\"\r\n (onChange)=\"toggleAll($event)\"\r\n inputId=\"toggleAll\">\r\n </p-checkbox>\r\n <span>{{selectAllLabel}}</span>\r\n </ng-template>\r\n }\r\n\r\n @if(optionTemplate){\r\n <ng-template let-item #item>\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"optionTemplate\" />\r\n </ng-template>\r\n }\r\n\r\n\r\n\r\n\r\n\r\n </p-multiselect>\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n\r\n </p-floatLabel>\r\n\r\n } @else {\r\n <p-floatLabel [variant]=\"variant\">\r\n <p-select\r\n [dataKey]=\"dataKey\"\r\n [checkmark]=\"checkmark\"\r\n [disabled]=\"disabled\"\r\n [editable]=\"editable\"\r\n [filterBy]=\"filterBy\"\r\n [filter]=\"filter\"\r\n [formControl]=\"control\"\r\n [id]=\"inputId\"\r\n [name]=\"name\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid }\"\r\n [emptyMessage]=\"emptyMessage || ('shared.no_results_found'|translate)\"\r\n [optionLabel]=\"optionLabel\"\r\n [optionValue]=\"optionValue\"\r\n [options]=\"options\"\r\n [placeholder]=\"placeholder\"\r\n [readonly]=\"readonly\"\r\n [showClear]=\"showClear\"\r\n [size]=\"size\"\r\n class=\"w-full\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \"\r\n (onChange)=\"onChange($event)\"\r\n [ngClass]=\"{ 'basic-style': basicInput }\"\r\n >\r\n\r\n @if (optionTemplate) {\r\n <ng-template let-item pTemplate=\"item\">\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"optionTemplate\" />\r\n </ng-template>\r\n }\r\n @if (selectedItemTemplate) {\r\n <ng-template let-item pTemplate=\"selectedItem\">\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"selectedItemTemplate\" />\r\n </ng-template>\r\n }\r\n </p-select>\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatLabel>\r\n }\r\n\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n } @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br />\r\n }\r\n </small>\r\n }\r\n</div>\r\n", styles: ["textarea,.p-select{border-radius:0;border-color:#dfe0e6}textarea:enabled:hover,.p-select:enabled:hover{border-color:#dfe0e6}textarea:not(.p-disabled).p-focus,textarea:not(.p-disabled).p-focus:hover,textarea:focus,.p-select:not(.p-disabled).p-focus,.p-select:not(.p-disabled).p-focus:hover,.p-select:focus{outline:#DFE0E6;border-color:#dfe0e6}.p-floatlabel:has(input:focus) label,.p-floatlabel:has(input:-webkit-autofill) label,.p-floatlabel:has(textarea:focus) label,.p-floatlabel:has(.p-inputwrapper-focus) label{color:#687078}.p-inputtext:enabled:focus{border-color:#dfe0e6}.p-select .p-select-label{padding-block-end:1rem!important;padding-block-start:1rem!important}.text-required{color:red}.p-error{color:#dc2626}.edit-search .p-select-label{padding:1rem 1rem 1rem 2.2rem!important}.edit-search .p-floatlabel>label{padding-inline-start:25px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i2$3.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i3$1.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "pipe", type: ValidationErrorsPipe, name: "validationErrors" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None });
777
- }
778
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SelectComponent, decorators: [{
779
- type: Component,
780
- args: [{ selector: 'stc-select', standalone: true, imports: [
781
- FormsModule,
782
- Select,
783
- ReactiveFormsModule,
784
- NgClass,
785
- NgTemplateOutlet,
786
- PrimeTemplate,
787
- ValidationErrorsPipe,
788
- MultiSelectModule,
789
- FloatLabelModule,
790
- TranslatePipe,
791
- CheckboxModule,
792
- ], encapsulation: ViewEncapsulation.None, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n\r\n @if(multiple) {\r\n <p-floatLabel [variant]=\"variant\">\r\n\r\n <p-multiselect\r\n [disabled]=\"disabled\"\r\n [filterBy]=\"filterBy\"\r\n [filter]=\"filter\"\r\n [formControl]=\"control\"\r\n [id]=\"inputId\"\r\n [name]=\"name\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid }\"\r\n [optionLabel]=\"optionLabel\"\r\n [optionValue]=\"optionValue\"\r\n [options]=\"options\"\r\n [showToggleAll]=\"false\"\r\n [placeholder]=\"placeholder\"\r\n [emptyMessage]=\"emptyMessage || ('shared.no_results_found'|translate)\"\r\n [readonly]=\"readonly\"\r\n [showClear]=\"showClear\"\r\n (onClear)=\"onMultiSelectClear()\"\r\n class=\"w-full\"\r\n [size]=\"size\"\r\n [selectedItemsLabel]=\"selectedItemsLabel || ('shared.Items_Selected'| translate: {count: '{0}'})\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \"\r\n (onChange)=\"onChange($event)\"\r\n [ngClass]=\"{ 'basic-style': basicInput }\"\r\n >\r\n\r\n @if (selectAllLabel) {\r\n <ng-template #filter>\r\n <p-checkbox\r\n binary=\"true\"\r\n [(ngModel)]=\"allSelectd\"\r\n (onChange)=\"toggleAll($event)\"\r\n inputId=\"toggleAll\">\r\n </p-checkbox>\r\n <span>{{selectAllLabel}}</span>\r\n </ng-template>\r\n }\r\n\r\n @if(optionTemplate){\r\n <ng-template let-item #item>\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"optionTemplate\" />\r\n </ng-template>\r\n }\r\n\r\n\r\n\r\n\r\n\r\n </p-multiselect>\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n\r\n </p-floatLabel>\r\n\r\n } @else {\r\n <p-floatLabel [variant]=\"variant\">\r\n <p-select\r\n [dataKey]=\"dataKey\"\r\n [checkmark]=\"checkmark\"\r\n [disabled]=\"disabled\"\r\n [editable]=\"editable\"\r\n [filterBy]=\"filterBy\"\r\n [filter]=\"filter\"\r\n [formControl]=\"control\"\r\n [id]=\"inputId\"\r\n [name]=\"name\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid }\"\r\n [emptyMessage]=\"emptyMessage || ('shared.no_results_found'|translate)\"\r\n [optionLabel]=\"optionLabel\"\r\n [optionValue]=\"optionValue\"\r\n [options]=\"options\"\r\n [placeholder]=\"placeholder\"\r\n [readonly]=\"readonly\"\r\n [showClear]=\"showClear\"\r\n [size]=\"size\"\r\n class=\"w-full\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \"\r\n (onChange)=\"onChange($event)\"\r\n [ngClass]=\"{ 'basic-style': basicInput }\"\r\n >\r\n\r\n @if (optionTemplate) {\r\n <ng-template let-item pTemplate=\"item\">\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"optionTemplate\" />\r\n </ng-template>\r\n }\r\n @if (selectedItemTemplate) {\r\n <ng-template let-item pTemplate=\"selectedItem\">\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"selectedItemTemplate\" />\r\n </ng-template>\r\n }\r\n </p-select>\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatLabel>\r\n }\r\n\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n } @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br />\r\n }\r\n </small>\r\n }\r\n</div>\r\n", styles: ["textarea,.p-select{border-radius:0;border-color:#dfe0e6}textarea:enabled:hover,.p-select:enabled:hover{border-color:#dfe0e6}textarea:not(.p-disabled).p-focus,textarea:not(.p-disabled).p-focus:hover,textarea:focus,.p-select:not(.p-disabled).p-focus,.p-select:not(.p-disabled).p-focus:hover,.p-select:focus{outline:#DFE0E6;border-color:#dfe0e6}.p-floatlabel:has(input:focus) label,.p-floatlabel:has(input:-webkit-autofill) label,.p-floatlabel:has(textarea:focus) label,.p-floatlabel:has(.p-inputwrapper-focus) label{color:#687078}.p-inputtext:enabled:focus{border-color:#dfe0e6}.p-select .p-select-label{padding-block-end:1rem!important;padding-block-start:1rem!important}.text-required{color:red}.p-error{color:#dc2626}.edit-search .p-select-label{padding:1rem 1rem 1rem 2.2rem!important}.edit-search .p-floatlabel>label{padding-inline-start:25px}\n"] }]
793
- }], ctorParameters: () => [], propDecorators: { selectedItemTemplate: [{
794
- type: Input
795
- }], optionTemplate: [{
796
- type: Input
797
- }], options: [{
798
- type: Input
799
- }], optionLabel: [{
800
- type: Input
801
- }], optionValue: [{
802
- type: Input
803
- }], emptyMessage: [{
804
- type: Input
805
- }], checkmark: [{
806
- type: Input
807
- }], showClear: [{
808
- type: Input
809
- }], editable: [{
810
- type: Input
811
- }], filter: [{
812
- type: Input
813
- }], multiple: [{
814
- type: Input
815
- }], filterBy: [{
816
- type: Input
817
- }], selectAllLabel: [{
818
- type: Input
819
- }], dataKey: [{
820
- type: Input
821
- }], size: [{
822
- type: Input
823
- }], selectedItemsLabel: [{
824
- type: Input
825
- }], basicInput: [{
826
- type: Input
827
- }], variant: [{
828
- type: Input
829
- }], change: [{
830
- type: Output
831
- }], defaultColor: [{
832
- type: Input
833
- }] } });
834
-
835
- class SwitchComponent {
836
- label;
837
- key;
838
- checked = false;
839
- onChange = new EventEmitter();
840
- // checked: boolean = false;
841
- sendUpdatedValue(value) {
842
- if (value) {
843
- this.onChange.emit(value.checked);
844
- }
845
- }
846
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
847
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SwitchComponent, isStandalone: true, selector: "stc-switch", inputs: { label: "label", key: "key", checked: "checked" }, outputs: { onChange: "onChange" }, ngImport: i0, template: "<div class=\"flex items-center mr-2\">\r\n <p-toggleswitch [(ngModel)]=\"checked\" [inputId]=\"key\" (onChange)=\"sendUpdatedValue($event)\" class=\"flex\">\r\n </p-toggleswitch>\r\n <label [for]=\"key\" class=\"text-[12px] mx-2\">{{label}}</label>\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i1$5.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
848
- }
849
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SwitchComponent, decorators: [{
850
- type: Component,
851
- args: [{ selector: "stc-switch", standalone: true, imports: [CommonModule, ToggleSwitchModule, FormsModule], template: "<div class=\"flex items-center mr-2\">\r\n <p-toggleswitch [(ngModel)]=\"checked\" [inputId]=\"key\" (onChange)=\"sendUpdatedValue($event)\" class=\"flex\">\r\n </p-toggleswitch>\r\n <label [for]=\"key\" class=\"text-[12px] mx-2\">{{label}}</label>\r\n</div>" }]
852
- }], propDecorators: { label: [{
853
- type: Input
854
- }], key: [{
855
- type: Input
856
- }], checked: [{
857
- type: Input
858
- }], onChange: [{
859
- type: Output
860
- }] } });
861
-
862
- var FormFieldTypeEnum;
863
- (function (FormFieldTypeEnum) {
864
- FormFieldTypeEnum["DATE_PICKER"] = "date-picker";
865
- FormFieldTypeEnum["SELECT_BUTTON"] = "select-button";
866
- FormFieldTypeEnum["INPUT"] = "input";
867
- FormFieldTypeEnum["SELECT"] = "select";
868
- FormFieldTypeEnum["SWITCH"] = "switch";
869
- FormFieldTypeEnum["AUTO_COMPLETE"] = "auto-complete";
870
- FormFieldTypeEnum["HIJRI_DATE_PICKER"] = "hijri-date";
871
- FormFieldTypeEnum["UPLOAD_FILE"] = "upload-file";
872
- })(FormFieldTypeEnum || (FormFieldTypeEnum = {}));
873
-
874
- const WEEKDAYS = {
875
- ar: ['ن', 'ث', 'ر', 'خ', 'ج', 'س', 'ح'],
876
- en: ['M', 'T', 'W', 'T', 'F', 'S', 'S']
877
- };
878
- const MONTHS_GREGORIAN = {
879
- ar: [
880
- 'يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو',
881
- 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'
882
- ],
883
- en: [
884
- 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
885
- 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
886
- ]
887
- };
888
- const MONTHS_HIJRI = {
889
- ar: [
890
- 'محرم',
891
- 'صفر',
892
- 'ربيع الأول',
893
- 'ربيع الآخر',
894
- 'جمادى الأولى',
895
- 'جمادى الآخرة',
896
- 'رجب',
897
- 'شعبان',
898
- 'رمضان',
899
- 'شوال',
900
- 'ذو القعدة',
901
- 'ذو الحجة'
902
- ],
903
- en: [
904
- 'Muharram',
905
- 'Safar',
906
- 'Rabi Al-Awwal',
907
- 'Rabi Al-Thani',
908
- 'Jumada Al-Awwal',
909
- 'Jumada Al-Thani',
910
- 'Rajab',
911
- 'Shaaban',
912
- 'Ramadan',
913
- 'Shawwal',
914
- 'Dhul-Qi’dah',
915
- 'Dhul-Hijjah'
916
- ]
917
- };
918
- function getGregorianMonthName(lang, month) {
919
- return MONTHS_GREGORIAN[lang][month - 1] || '';
920
- }
921
- function getHijriMonthName(lang, month) {
922
- return MONTHS_HIJRI[lang][month - 1] || '';
923
- }
924
- function getWeekdayName(lang, weekday) {
925
- return WEEKDAYS[lang][weekday - 1];
926
- }
927
-
928
- class IslamicI18n extends NgbDatepickerI18n {
929
- getMonthShortName(month) {
930
- return MONTHS_HIJRI.ar[month - 1];
931
- }
932
- getMonthFullName(month) {
933
- return MONTHS_HIJRI.ar[month - 1];
934
- }
935
- getWeekdayLabel(weekday) {
936
- return WEEKDAYS.ar[weekday - 1];
937
- }
938
- getWeekdayShortName(weekday) {
939
- return WEEKDAYS.ar[weekday - 1];
940
- }
941
- getDayAriaLabel(date) {
942
- return `${date.day}-${date.month}-${date.year}`;
943
- }
944
- getYearNumerals(year) {
945
- return String(year);
946
- }
947
- getWeekNumerals(weekNumber) {
948
- return String(weekNumber);
949
- }
950
- getDayNumerals(date) {
951
- return String(date.day);
952
- }
953
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: IslamicI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
954
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: IslamicI18n });
955
- }
956
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: IslamicI18n, decorators: [{
957
- type: Injectable
958
- }] });
959
- class HijriEnglishI18n extends NgbDatepickerI18n {
960
- getMonthShortName(month) {
961
- return MONTHS_HIJRI.en[month - 1].substring(0, 3);
962
- }
963
- getMonthFullName(month) {
964
- return MONTHS_HIJRI.en[month - 1];
965
- }
966
- getWeekdayLabel(weekday) {
967
- return WEEKDAYS.en[weekday - 1];
968
- }
969
- getWeekdayShortName(weekday) {
970
- return WEEKDAYS.en[weekday - 1];
971
- }
972
- getDayAriaLabel(date) {
973
- return `${date.day}-${date.month}-${date.year}`;
455
+ class FileManagementComponent extends BaseInputComponent {
456
+ // Inputs
457
+ existingFiles = input([], ...(ngDevMode ? [{ debugName: "existingFiles" }] : []));
458
+ acceptedTypes = input('*', ...(ngDevMode ? [{ debugName: "acceptedTypes" }] : []));
459
+ maxFileSize = input(10485760, ...(ngDevMode ? [{ debugName: "maxFileSize" }] : [])); //250 MB
460
+ maxConcurrentUploads = input(3, ...(ngDevMode ? [{ debugName: "maxConcurrentUploads" }] : []));
461
+ showTable = input(true, ...(ngDevMode ? [{ debugName: "showTable" }] : []));
462
+ showDropZone = input(true, ...(ngDevMode ? [{ debugName: "showDropZone" }] : []));
463
+ allowPreview = input(true, ...(ngDevMode ? [{ debugName: "allowPreview" }] : []));
464
+ permissonKey = input('', ...(ngDevMode ? [{ debugName: "permissonKey" }] : []));
465
+ allowedActions = input([], ...(ngDevMode ? [{ debugName: "allowedActions" }] : []));
466
+ uploadedFile = signal([], ...(ngDevMode ? [{ debugName: "uploadedFile" }] : []));
467
+ // Outputs
468
+ filesUploaded = new EventEmitter();
469
+ fileDeleted = new EventEmitter();
470
+ filePreview = new EventEmitter();
471
+ fileDownload = new EventEmitter();
472
+ uploadError = new EventEmitter();
473
+ newFilesChange = new EventEmitter();
474
+ fileInput;
475
+ // State - separate new uploads from existing files
476
+ isDragOver = signal(false, ...(ngDevMode ? [{ debugName: "isDragOver" }] : []));
477
+ newFiles = signal([], ...(ngDevMode ? [{ debugName: "newFiles" }] : [])); // Files being uploaded or newly uploaded
478
+ uploadedResponses = [];
479
+ // Combined files list for the table (existing + new)
480
+ allFiles = computed(() => {
481
+ const existing = this.existingFiles().map((f) => ({
482
+ ...f,
483
+ status: undefined, // Don't show status for existing files
484
+ isNew: false,
485
+ }));
486
+ const newOnes = this.newFiles();
487
+ return [...newOnes, ...existing];
488
+ }, ...(ngDevMode ? [{ debugName: "allFiles" }] : []));
489
+ // Get only successfully uploaded new file IDs
490
+ uploadedNewFileIds = computed(() => {
491
+ return this.newFiles()
492
+ .filter((f) => f.status === UploadStatus.SUCCESS && f.id && !f.id.startsWith('temp-'))
493
+ .map((f) => f.id);
494
+ }, ...(ngDevMode ? [{ debugName: "uploadedNewFileIds" }] : []));
495
+ // Formatted accepted file types for display
496
+ formattedAcceptedTypes = computed(() => {
497
+ const accepted = this.acceptedTypes();
498
+ if (accepted === '*' || accepted === '*/*')
499
+ return '';
500
+ return accepted
501
+ .split(',')
502
+ .map((type) => type.trim().replace('.', '').toUpperCase())
503
+ .join(', ');
504
+ }, ...(ngDevMode ? [{ debugName: "formattedAcceptedTypes" }] : []));
505
+ // Table configuration
506
+ // Drag & Drop handlers
507
+ onDragOver(event) {
508
+ event.preventDefault();
509
+ event.stopPropagation();
510
+ this.isDragOver.set(true);
974
511
  }
975
- getYearNumerals(year) {
976
- return String(year);
512
+ onDragLeave(event) {
513
+ event.preventDefault();
514
+ event.stopPropagation();
515
+ this.isDragOver.set(false);
977
516
  }
978
- getWeekNumerals(weekNumber) {
979
- return String(weekNumber);
517
+ onDrop(event) {
518
+ event.preventDefault();
519
+ event.stopPropagation();
520
+ this.isDragOver.set(false);
521
+ const droppedFiles = event.dataTransfer?.files;
522
+ if (droppedFiles) {
523
+ this.handleFiles(Array.from(droppedFiles));
524
+ }
980
525
  }
981
- getDayNumerals(date) {
982
- return String(date.day);
526
+ // Browse button handler
527
+ onBrowseClick() {
528
+ this.fileInput.nativeElement.click();
983
529
  }
984
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriEnglishI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
985
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriEnglishI18n });
986
- }
987
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriEnglishI18n, decorators: [{
988
- type: Injectable
989
- }] });
990
- class DynamicHijriI18n extends NgbDatepickerI18n {
991
- currentLang = 'ar';
992
- arabicI18n = new IslamicI18n();
993
- englishI18n = new HijriEnglishI18n();
994
- setLanguage(lang) {
995
- this.currentLang = lang;
530
+ onFileInputChange(event) {
531
+ const input = event.target;
532
+ if (input.files) {
533
+ this.handleFiles(Array.from(input.files));
534
+ // Reset input to allow selecting the same file again
535
+ input.value = '';
536
+ }
996
537
  }
997
- get activeI18n() {
998
- return this.currentLang === 'ar' ? this.arabicI18n : this.englishI18n;
538
+ // Public method to trigger file selection from parent
539
+ triggerFileInput() {
540
+ this.fileInput?.nativeElement?.click();
999
541
  }
1000
- getMonthShortName(month) {
1001
- return this.activeI18n.getMonthShortName(month);
542
+ // Public method to append file selection from parent
543
+ appendFileFromParent(file) {
544
+ this.handleFiles([file]);
1002
545
  }
1003
- getMonthFullName(month) {
1004
- return this.activeI18n.getMonthFullName(month);
546
+ // Public method to upload files programmatically from parent
547
+ uploadFilesFromParent(files) {
548
+ this.handleFiles(files);
1005
549
  }
1006
- getWeekdayLabel(weekday) {
1007
- return this.activeI18n.getWeekdayLabel(weekday);
550
+ // Public method to get new uploaded file IDs
551
+ getUploadedFileIds() {
552
+ return this.uploadedNewFileIds();
1008
553
  }
1009
- getWeekdayShortName(weekday) {
1010
- return this.activeI18n.getWeekdayShortName(weekday);
554
+ // Public method to clear new files (after save)
555
+ clearNewFiles() {
556
+ this.newFiles.set([]);
557
+ this.uploadedResponses = [];
1011
558
  }
1012
- getDayAriaLabel(date) {
1013
- return this.activeI18n.getDayAriaLabel(date);
559
+ // Public method to remove a new file by ID
560
+ removeNewFile(fileId) {
561
+ this.newFiles.update((files) => files.filter((f) => f.id !== fileId));
1014
562
  }
1015
- getYearNumerals(year) {
1016
- return this.activeI18n.getYearNumerals(year);
563
+ // Check if there are pending/uploading files
564
+ // File handling
565
+ handleFiles(filesToProcess) {
566
+ const validFiles = [];
567
+ for (const file of filesToProcess) {
568
+ // Validate file size
569
+ if (file.size > this.maxFileSize()) {
570
+ this.uploadError.emit({
571
+ file,
572
+ error: `File ${file.name} exceeds maximum size of ${this.formatFileSize(this.maxFileSize())}`,
573
+ });
574
+ continue;
575
+ }
576
+ // Validate file type
577
+ // if (!this.isValidFileType(file)) {
578
+ // this.uploadError.emit({
579
+ // file,
580
+ // error: `File type not allowed: ${file.type}`,
581
+ // });
582
+ // continue;
583
+ // }
584
+ validFiles.push(file);
585
+ }
586
+ if (validFiles.length > 0) {
587
+ // this.uploadFiles(validFiles);
588
+ this.uploadedFile.set(validFiles);
589
+ this.filesUploaded.emit(validFiles);
590
+ console.log('uploadedFile', this.uploadedFile());
591
+ }
1017
592
  }
1018
- getWeekNumerals(weekNumber) {
1019
- return this.activeI18n.getWeekNumerals(weekNumber);
593
+ deleteFile() {
594
+ this.uploadedFile.set([]);
595
+ this.filesUploaded.emit([]);
1020
596
  }
1021
- getDayNumerals(date) {
1022
- return this.activeI18n.getDayNumerals(date);
597
+ isValidFileType(file) {
598
+ const accepted = this.acceptedTypes();
599
+ if (accepted === '*' || accepted === '*/*')
600
+ return true;
601
+ const acceptedTypes = accepted.split(',').map((t) => t.trim().toLowerCase());
602
+ const fileType = file.type.toLowerCase();
603
+ const fileExt = '.' + file.name.split('.').pop()?.toLowerCase();
604
+ return acceptedTypes.some((type) => {
605
+ if (type.startsWith('.')) {
606
+ return fileExt === type;
607
+ }
608
+ if (type.endsWith('/*')) {
609
+ return fileType.startsWith(type.replace('/*', '/'));
610
+ }
611
+ return fileType === type;
612
+ });
1023
613
  }
1024
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicHijriI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1025
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicHijriI18n });
1026
- }
1027
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicHijriI18n, decorators: [{
1028
- type: Injectable
1029
- }] });
1030
-
1031
- class HijriCalendarComponent {
1032
- i18n;
1033
- cdr;
1034
- model;
1035
- dateSelected = new EventEmitter();
1036
- language = 'en';
1037
- renderer = inject(Renderer2);
1038
- startDate;
1039
- calendar = new NgbCalendarIslamicUmalqura();
1040
- constructor(i18n, cdr) {
1041
- this.i18n = i18n;
1042
- this.cdr = cdr;
614
+ updateFileFromAttachment(attachment) {
615
+ this.newFiles.update((currentFiles) => {
616
+ return currentFiles.map((file) => {
617
+ // Match by file name and size
618
+ if (file.fileName === attachment.nameFile && file.size === attachment.size) {
619
+ const updatedFile = {
620
+ ...file,
621
+ progress: attachment.status?.percentage ?? 0,
622
+ error: attachment.errorMessage,
623
+ };
624
+ // If upload succeeded, update with response data from serverResponse
625
+ if (attachment.uploadStatus === UploadStatus.SUCCESS && attachment.serverResponse) {
626
+ const serverData = attachment.serverResponse;
627
+ const responseFile = {
628
+ id: attachment.id || serverData?.id || file.id,
629
+ fileName: serverData?.fileName || attachment.nameFile,
630
+ size: serverData?.size || attachment.size,
631
+ mimeType: serverData?.mimeType || file.mimeType,
632
+ };
633
+ this.uploadedResponses.push(responseFile);
634
+ return {
635
+ ...updatedFile,
636
+ id: responseFile.id,
637
+ };
638
+ }
639
+ return updatedFile;
640
+ }
641
+ return file;
642
+ });
643
+ });
1043
644
  }
1044
- ngOnChanges(changes) {
1045
- if (changes['model'] && changes['model'].currentValue) {
1046
- this.startDate = { ...changes['model'].currentValue };
1047
- console.log('Hijri navigating to:', this.startDate);
1048
- }
1049
- if (changes['language'] && this.i18n instanceof DynamicHijriI18n) {
1050
- this.i18n.setLanguage(this.language);
1051
- this.cdr.detectChanges(); // Force re-render to update labels
645
+ // Actions
646
+ onDeleteFile(file) {
647
+ const isNewFile = file.isNew;
648
+ this.fileDeleted.emit({ fileId: file.id, isNew: !!isNewFile });
649
+ if (isNewFile) {
650
+ // Remove from newFiles list immediately for new uploads
651
+ this.newFiles.update((files) => files.filter((f) => f.id !== file.id));
1052
652
  }
1053
653
  }
1054
- ngAfterViewInit() {
1055
- const buttons = document.querySelectorAll('.ngb-dp-arrow-btn');
1056
- buttons.forEach(btn => {
1057
- this.renderer.removeAttribute(btn, 'title');
1058
- });
654
+ onPreviewFile(file) {
655
+ this.filePreview.emit(file);
1059
656
  }
1060
- onDateChange(date) {
1061
- this.model = date;
1062
- this.startDate = { ...date };
657
+ removeFileFromList(fileId) {
658
+ this.newFiles.update((current) => current.filter((f) => f.id !== fileId));
1063
659
  }
1064
- isToday(date) {
1065
- const today = this.calendar.getToday();
1066
- return date.year === today.year &&
1067
- date.month === today.month &&
1068
- date.day === today.day;
660
+ generateTempId(file) {
661
+ return `temp-${file.name}-${file.size}-${Date.now()}`;
1069
662
  }
1070
- isDisabled = () => false;
1071
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriCalendarComponent, deps: [{ token: i1$6.NgbDatepickerI18n }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1072
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: HijriCalendarComponent, isStandalone: true, selector: "app-hijri-calendar", inputs: { model: "model", language: "language" }, outputs: { dateSelected: "dateSelected" }, providers: [
1073
- { provide: NgbCalendar, useClass: NgbCalendarIslamicUmalqura },
1074
- { provide: NgbDatepickerI18n, useClass: DynamicHijriI18n }
1075
- ], usesOnChanges: true, ngImport: i0, template: "<ngb-datepicker #dp [class.rtl]=\"language === 'ar'\" [class.ltr]=\"language === 'en'\" [ngModel]=\"model\"\r\n [startDate]=\"startDate\" (ngModelChange)=\"onDateChange($event)\" (dateSelect)=\"dateSelected.emit($event)\"\r\n [dayTemplate]=\"dayTemplate\" [markDisabled]=\"isDisabled\">\r\n</ngb-datepicker>\r\n<ng-template #dayTemplate let-date let-currentMonth=\"currentMonth\" let-selected=\"selected\" let-disabled=\"disabled\">\r\n <span class=\"custom-day\" [class.today]=\"isToday(date)\" [class.selected]=\"selected\"\r\n [class.outside]=\"date.month !== currentMonth\" [class.disabled]=\"disabled\">\r\n {{ date.day }}\r\n </span>\r\n</ng-template>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: NgbDatepickerModule }, { kind: "component", type: i1$6.NgbDatepicker, selector: "ngb-datepicker", inputs: ["contentTemplate", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "maxDate", "minDate", "navigation", "outsideDays", "showWeekNumbers", "startDate", "weekdays"], outputs: ["navigate", "dateSelect"], exportAs: ["ngbDatepicker"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
663
+ formatFileSize(bytes) {
664
+ if (bytes === 0)
665
+ return '0 B';
666
+ const k = 1024;
667
+ const sizes = ['B', 'KB', 'MB', 'GB'];
668
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
669
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
670
+ }
671
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FileManagementComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
672
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: FileManagementComponent, isStandalone: true, selector: "app-file-management", inputs: { existingFiles: { classPropertyName: "existingFiles", publicName: "existingFiles", isSignal: true, isRequired: false, transformFunction: null }, acceptedTypes: { classPropertyName: "acceptedTypes", publicName: "acceptedTypes", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, maxConcurrentUploads: { classPropertyName: "maxConcurrentUploads", publicName: "maxConcurrentUploads", isSignal: true, isRequired: false, transformFunction: null }, showTable: { classPropertyName: "showTable", publicName: "showTable", isSignal: true, isRequired: false, transformFunction: null }, showDropZone: { classPropertyName: "showDropZone", publicName: "showDropZone", isSignal: true, isRequired: false, transformFunction: null }, allowPreview: { classPropertyName: "allowPreview", publicName: "allowPreview", isSignal: true, isRequired: false, transformFunction: null }, permissonKey: { classPropertyName: "permissonKey", publicName: "permissonKey", isSignal: true, isRequired: false, transformFunction: null }, allowedActions: { classPropertyName: "allowedActions", publicName: "allowedActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filesUploaded: "filesUploaded", fileDeleted: "fileDeleted", filePreview: "filePreview", fileDownload: "fileDownload", uploadError: "uploadError", newFilesChange: "newFilesChange" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"file-management\">\r\n <!-- Drop Zone -->\r\n @if (showDropZone()) {\r\n <div\r\n class=\"drop-zone upload-container\"\r\n [class.drag-over]=\"isDragOver()\"\r\n (dragover)=\"onDragOver($event)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event)\"\r\n >\r\n <div class=\"drop-zone-content\">\r\n <p class=\"drop-text\">{{ 'file.drag_drop_files' | translate }}</p>\r\n <p-button\r\n [label]=\"'file.browse' | translate\"\r\n severity=\"danger\"\r\n [outlined]=\"true\"\r\n (onClick)=\"onBrowseClick()\"\r\n />\r\n <p class=\"drop-hint text-xs text-gray-500 mt-2\">\r\n {{ 'file.max_size_hint' | translate }}: {{ maxFileSize() | fileSize: 2 : 'MB' }}\r\n </p>\r\n @if (formattedAcceptedTypes()) {\r\n <p class=\"accepted-types text-xs text-gray-400\">\r\n {{ 'file.accepted_types' | translate }}: {{ formattedAcceptedTypes() }}\r\n </p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Hidden file input (always present for programmatic access) -->\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n [accept]=\"acceptedTypes()\"\r\n multiple\r\n hidden\r\n (change)=\"onFileInputChange($event)\"\r\n />\r\n\r\n @if(uploadedFile().length) {\r\n @for(file of uploadedFile() ; track file) {\r\n <div class=\"uploaded-files \" >\r\n <p>{{file.name}}</p>\r\n <i class=\"pi pi-trash\" style=\"font-size: 1.5rem; color: #f00\" (click)=\"deleteFile()\"></i>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Files Table -->\r\n\r\n</div>\r\n", styles: [".file-management{width:100%}.drop-zone{@apply cursor-pointer rounded-l border-2 border-dashed border-gray-300 p-8 bg-purple-light3 text-center transition-all duration-200 ease-in-out;}.drop-zone.drag-over{@apply border-purple-200 bg-purple-light;}.drop-zone-content{@apply flex flex-col items-center gap-2;}.drop-icon{font-size:3rem;color:var(--gray-400, #9ca3af);margin-bottom:.5rem}.drop-text{font-size:1rem;color:var(--gray-700, #374151);margin:0}.drop-or{font-size:.875rem;color:var(--gray-500, #6b7280);margin:.25rem 0}.drop-hint{margin-top:.75rem}.files-table{border:1px solid var(--gray-200, #e5e7eb);border-radius:8px;overflow:hidden}:host-context([dir=rtl]) .drop-zone-content{direction:rtl}.uploaded-files{background-color:#f3f3f7;border:1px solid #DFE0E6;display:flex;justify-content:space-between;align-items:center;padding:15px;margin-bottom:10px}.uploaded-files .pi-trash{cursor:pointer}.uploaded-files p{margin-block-start:0;margin-block-end:0}.upload-container{background-color:#f3f3f7;padding:15px;border:1px dashed #DFE0E6;margin-bottom:15px;display:flex;justify-content:center;align-items:center;border-radius:2px}.upload-container .drop-zone-content{display:flex;align-items:center;flex-direction:column}.upload-container .drop-zone-content .drop-text{margin-bottom:10px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FileSizePipe, name: "fileSize" }] });
1076
673
  }
1077
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriCalendarComponent, decorators: [{
674
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FileManagementComponent, decorators: [{
1078
675
  type: Component,
1079
- args: [{ selector: "app-hijri-calendar", standalone: true, imports: [NgbDatepickerModule, FormsModule], providers: [
1080
- { provide: NgbCalendar, useClass: NgbCalendarIslamicUmalqura },
1081
- { provide: NgbDatepickerI18n, useClass: DynamicHijriI18n }
1082
- ], template: "<ngb-datepicker #dp [class.rtl]=\"language === 'ar'\" [class.ltr]=\"language === 'en'\" [ngModel]=\"model\"\r\n [startDate]=\"startDate\" (ngModelChange)=\"onDateChange($event)\" (dateSelect)=\"dateSelected.emit($event)\"\r\n [dayTemplate]=\"dayTemplate\" [markDisabled]=\"isDisabled\">\r\n</ngb-datepicker>\r\n<ng-template #dayTemplate let-date let-currentMonth=\"currentMonth\" let-selected=\"selected\" let-disabled=\"disabled\">\r\n <span class=\"custom-day\" [class.today]=\"isToday(date)\" [class.selected]=\"selected\"\r\n [class.outside]=\"date.month !== currentMonth\" [class.disabled]=\"disabled\">\r\n {{ date.day }}\r\n </span>\r\n</ng-template>\r\n" }]
1083
- }], ctorParameters: () => [{ type: i1$6.NgbDatepickerI18n }, { type: i0.ChangeDetectorRef }], propDecorators: { model: [{
1084
- type: Input
1085
- }], dateSelected: [{
676
+ args: [{ selector: 'app-file-management', imports: [CommonModule, TranslatePipe, ButtonModule, TooltipModule, FileSizePipe], template: "<div class=\"file-management\">\r\n <!-- Drop Zone -->\r\n @if (showDropZone()) {\r\n <div\r\n class=\"drop-zone upload-container\"\r\n [class.drag-over]=\"isDragOver()\"\r\n (dragover)=\"onDragOver($event)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event)\"\r\n >\r\n <div class=\"drop-zone-content\">\r\n <p class=\"drop-text\">{{ 'file.drag_drop_files' | translate }}</p>\r\n <p-button\r\n [label]=\"'file.browse' | translate\"\r\n severity=\"danger\"\r\n [outlined]=\"true\"\r\n (onClick)=\"onBrowseClick()\"\r\n />\r\n <p class=\"drop-hint text-xs text-gray-500 mt-2\">\r\n {{ 'file.max_size_hint' | translate }}: {{ maxFileSize() | fileSize: 2 : 'MB' }}\r\n </p>\r\n @if (formattedAcceptedTypes()) {\r\n <p class=\"accepted-types text-xs text-gray-400\">\r\n {{ 'file.accepted_types' | translate }}: {{ formattedAcceptedTypes() }}\r\n </p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Hidden file input (always present for programmatic access) -->\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n [accept]=\"acceptedTypes()\"\r\n multiple\r\n hidden\r\n (change)=\"onFileInputChange($event)\"\r\n />\r\n\r\n @if(uploadedFile().length) {\r\n @for(file of uploadedFile() ; track file) {\r\n <div class=\"uploaded-files \" >\r\n <p>{{file.name}}</p>\r\n <i class=\"pi pi-trash\" style=\"font-size: 1.5rem; color: #f00\" (click)=\"deleteFile()\"></i>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Files Table -->\r\n\r\n</div>\r\n", styles: [".file-management{width:100%}.drop-zone{@apply cursor-pointer rounded-l border-2 border-dashed border-gray-300 p-8 bg-purple-light3 text-center transition-all duration-200 ease-in-out;}.drop-zone.drag-over{@apply border-purple-200 bg-purple-light;}.drop-zone-content{@apply flex flex-col items-center gap-2;}.drop-icon{font-size:3rem;color:var(--gray-400, #9ca3af);margin-bottom:.5rem}.drop-text{font-size:1rem;color:var(--gray-700, #374151);margin:0}.drop-or{font-size:.875rem;color:var(--gray-500, #6b7280);margin:.25rem 0}.drop-hint{margin-top:.75rem}.files-table{border:1px solid var(--gray-200, #e5e7eb);border-radius:8px;overflow:hidden}:host-context([dir=rtl]) .drop-zone-content{direction:rtl}.uploaded-files{background-color:#f3f3f7;border:1px solid #DFE0E6;display:flex;justify-content:space-between;align-items:center;padding:15px;margin-bottom:10px}.uploaded-files .pi-trash{cursor:pointer}.uploaded-files p{margin-block-start:0;margin-block-end:0}.upload-container{background-color:#f3f3f7;padding:15px;border:1px dashed #DFE0E6;margin-bottom:15px;display:flex;justify-content:center;align-items:center;border-radius:2px}.upload-container .drop-zone-content{display:flex;align-items:center;flex-direction:column}.upload-container .drop-zone-content .drop-text{margin-bottom:10px}\n"] }]
677
+ }], propDecorators: { existingFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "existingFiles", required: false }] }], acceptedTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "acceptedTypes", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], maxConcurrentUploads: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxConcurrentUploads", required: false }] }], showTable: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTable", required: false }] }], showDropZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDropZone", required: false }] }], allowPreview: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowPreview", required: false }] }], permissonKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "permissonKey", required: false }] }], allowedActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowedActions", required: false }] }], filesUploaded: [{
1086
678
  type: Output
1087
- }], language: [{
1088
- type: Input
679
+ }], fileDeleted: [{
680
+ type: Output
681
+ }], filePreview: [{
682
+ type: Output
683
+ }], fileDownload: [{
684
+ type: Output
685
+ }], uploadError: [{
686
+ type: Output
687
+ }], newFilesChange: [{
688
+ type: Output
689
+ }], fileInput: [{
690
+ type: ViewChild,
691
+ args: ['fileInput']
1089
692
  }] } });
1090
693
 
1091
- class GregorianArabicI18n extends NgbDatepickerI18n {
1092
- getMonthShortName(month) {
1093
- return MONTHS_GREGORIAN.ar[month - 1];
1094
- }
1095
- getMonthFullName(month) {
1096
- return MONTHS_GREGORIAN.ar[month - 1];
1097
- }
1098
- getWeekdayLabel(weekday) {
1099
- return WEEKDAYS.ar[weekday - 1];
694
+ class FormUtils {
695
+ static getFormControl(controlName, form) {
696
+ if (!form)
697
+ throw new Error(`Form is not initialized.`);
698
+ const formControl = form.get(controlName);
699
+ if (!formControl)
700
+ throw new Error(`There's no form control with given name. '${controlName}'`);
701
+ return formControl;
1100
702
  }
1101
- getWeekdayShortName(weekday) {
1102
- return WEEKDAYS.ar[weekday - 1];
703
+ }
704
+
705
+ var BasicErrorKeysEnum;
706
+ (function (BasicErrorKeysEnum) {
707
+ BasicErrorKeysEnum["required"] = "REQUIRED";
708
+ BasicErrorKeysEnum["email"] = "EMAIL";
709
+ BasicErrorKeysEnum["pattern"] = "PATTERN";
710
+ BasicErrorKeysEnum["invalidArFormat"] = "INVALID_AR_FORMAT";
711
+ BasicErrorKeysEnum["invalidLink"] = "INVALID_LINK";
712
+ BasicErrorKeysEnum["endDateBeforeStartDate"] = "END_DATE_BEFORE_START_DATE";
713
+ BasicErrorKeysEnum["startDateEqualsEndDate"] = "START_DATE_EQUALS_END_DATE";
714
+ BasicErrorKeysEnum["endTimeBeforeStartTime"] = "END_TIME_BEFORE_START_TIME";
715
+ BasicErrorKeysEnum["startTimeEqualsEndTime"] = "START_TIME_EQUALS_END_TIME";
716
+ BasicErrorKeysEnum["integer"] = "INTEGER";
717
+ BasicErrorKeysEnum["positiveNumber"] = "POSITIVE_NUMBER";
718
+ BasicErrorKeysEnum["fileSelected"] = "FILE_SELECTED";
719
+ BasicErrorKeysEnum["default"] = "DEFAULT";
720
+ BasicErrorKeysEnum["numbersOnly"] = "NUMBERS_ONLY";
721
+ })(BasicErrorKeysEnum || (BasicErrorKeysEnum = {}));
722
+ var ErrorsWithValuesKeysEnum;
723
+ (function (ErrorsWithValuesKeysEnum) {
724
+ ErrorsWithValuesKeysEnum["minlength"] = "MIN_LENGTH";
725
+ ErrorsWithValuesKeysEnum["maxlength"] = "MAX_LENGTH";
726
+ ErrorsWithValuesKeysEnum["min"] = "MIN";
727
+ ErrorsWithValuesKeysEnum["max"] = "MAX";
728
+ ErrorsWithValuesKeysEnum["maxSize"] = "MAX_SIZE";
729
+ ErrorsWithValuesKeysEnum["maxFiles"] = "MAX_FILES";
730
+ ErrorsWithValuesKeysEnum["allowedTypes"] = "ALLOWED_TYPES";
731
+ })(ErrorsWithValuesKeysEnum || (ErrorsWithValuesKeysEnum = {}));
732
+
733
+ class FormValidationService {
734
+ translate = inject(TranslateService);
735
+ getTranslation(key, interpolateParams) {
736
+ return this.translate.instant(`VALIDATION.${key}`, interpolateParams);
1103
737
  }
1104
- getDayAriaLabel(date) {
1105
- return `${date.day}-${date.month}-${date.year}`;
738
+ getErrorMessage(errorKey, errorValue) {
739
+ if (this.isBasicErrorKey(errorKey)) {
740
+ return this.getTranslation(BasicErrorKeysEnum[errorKey]);
741
+ }
742
+ if (this.isErrorWithValueKey(errorKey)) {
743
+ return this.getErrorWithValueMessage(errorKey, errorValue);
744
+ }
745
+ return this.getTranslation(BasicErrorKeysEnum.default);
1106
746
  }
1107
- getYearNumerals(year) {
1108
- return String(year);
747
+ // Basic error keys are the keys that don't have any values to interpolate. like required, email, etc.
748
+ isBasicErrorKey(key) {
749
+ return Object.keys(BasicErrorKeysEnum).includes(key);
1109
750
  }
1110
- getWeekNumerals(weekNumber) {
1111
- return String(weekNumber);
751
+ // Error keys with values are the keys that have values to interpolate. like minlength, maxlength, etc.
752
+ isErrorWithValueKey(key) {
753
+ return Object.keys(ErrorsWithValuesKeysEnum).includes(key);
1112
754
  }
1113
- getDayNumerals(date) {
1114
- return String(date.day);
755
+ getErrorWithValueMessage(errorKey, errorValue) {
756
+ const messages = {
757
+ minlength: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.minlength, {
758
+ requiredLength: val?.requiredLength,
759
+ actualLength: val?.actualLength,
760
+ }),
761
+ maxlength: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.maxlength, {
762
+ requiredLength: val?.requiredLength,
763
+ actualLength: val?.actualLength,
764
+ }),
765
+ min: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.min, { min: val?.min }),
766
+ max: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.max, { max: val?.max }),
767
+ maxSize: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.maxSize, { size: val?.requiredLength }),
768
+ maxFiles: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.maxFiles, { size: val?.requiredLength }),
769
+ allowedTypes: (val) => this.getTranslation(ErrorsWithValuesKeysEnum.allowedTypes, { types: val?.join(', ') }),
770
+ };
771
+ return messages[errorKey](errorValue);
1115
772
  }
1116
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianArabicI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1117
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianArabicI18n });
773
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormValidationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
774
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormValidationService, providedIn: 'root' });
1118
775
  }
1119
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianArabicI18n, decorators: [{
1120
- type: Injectable
776
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FormValidationService, decorators: [{
777
+ type: Injectable,
778
+ args: [{
779
+ providedIn: 'root',
780
+ }]
1121
781
  }] });
1122
- class GregorianEnglishI18n extends NgbDatepickerI18n {
1123
- getMonthShortName(month) {
1124
- return MONTHS_GREGORIAN.en[month - 1].substring(0, 3);
1125
- }
1126
- getMonthFullName(month) {
1127
- return MONTHS_GREGORIAN.en[month - 1];
1128
- }
1129
- getWeekdayLabel(weekday) {
1130
- return WEEKDAYS.en[weekday - 1];
1131
- }
1132
- getWeekdayShortName(weekday) {
1133
- return WEEKDAYS.en[weekday - 1];
1134
- }
1135
- getDayAriaLabel(date) {
1136
- return `${date.day}-${date.month}-${date.year}`;
782
+
783
+ class ValidationErrorsPipe {
784
+ formValidationService = inject(FormValidationService);
785
+ // allowed keys here to handle errors in case of cross-validators like startDate and endDate validators,
786
+ // we pass this custom key to handle the error messages only for the allowed keys
787
+ transform(errors, allowedKeys) {
788
+ if (!errors)
789
+ return [];
790
+ return Object.keys(errors)
791
+ .filter((errorKey) => !allowedKeys || allowedKeys.includes(errorKey)) // Filter errors if allowedKeys are provided
792
+ .map((errorKey) => {
793
+ return this.formValidationService.getErrorMessage(errorKey, errors[errorKey]);
794
+ });
1137
795
  }
1138
- getYearNumerals(year) {
1139
- return String(year);
796
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ValidationErrorsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
797
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: ValidationErrorsPipe, isStandalone: true, name: "validationErrors" });
798
+ }
799
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ValidationErrorsPipe, decorators: [{
800
+ type: Pipe,
801
+ args: [{
802
+ name: "validationErrors",
803
+ standalone: true,
804
+ pure: true
805
+ }]
806
+ }] });
807
+
808
+ function numbersOnlyValidator(control) {
809
+ const value = control.value;
810
+ if (value === null || value === undefined || value === '') {
811
+ return null;
1140
812
  }
1141
- getWeekNumerals(weekNumber) {
1142
- return String(weekNumber);
813
+ const isNumbersOnly = /^[0-9]+$/.test(value);
814
+ return isNumbersOnly ? null : { numbersOnly: true };
815
+ }
816
+
817
+ class AutoCompleteComponent extends BaseInputComponent {
818
+ selectedItemTemplate = null;
819
+ // eslint-disable-next-line @angular-eslint/no-output-on-prefix
820
+ onSearch = new EventEmitter();
821
+ selectOption = new EventEmitter();
822
+ items = [];
823
+ minLengthToSearch = 3;
824
+ delay = 300; // default value
825
+ basicInput;
826
+ typeAhead = false;
827
+ variant = 'over';
828
+ constructor() {
829
+ super();
1143
830
  }
1144
- getDayNumerals(date) {
1145
- return String(date.day);
831
+ search(event) {
832
+ this.onSearch.emit(event.query);
1146
833
  }
1147
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianEnglishI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1148
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianEnglishI18n });
1149
- }
1150
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianEnglishI18n, decorators: [{
1151
- type: Injectable
1152
- }] });
1153
- // ============ Dynamic I18N Factory ============
1154
- class DynamicGregorianI18n extends NgbDatepickerI18n {
1155
- currentLang = 'en';
1156
- arabicI18n = new GregorianArabicI18n();
1157
- englishI18n = new GregorianEnglishI18n();
1158
- setLanguage(lang) {
1159
- this.currentLang = lang;
834
+ onSelect(event) {
835
+ this.selectOption.emit(event);
1160
836
  }
1161
- get activeI18n() {
1162
- return this.currentLang === 'ar' ? this.arabicI18n : this.englishI18n;
837
+ onKeyDown(event) {
838
+ if (!['Enter', 'Tab', ' '].includes(event.key))
839
+ return;
840
+ event.preventDefault();
841
+ const input = event.target;
842
+ this.addValueFromInput(input);
1163
843
  }
1164
- getMonthShortName(month) {
1165
- return this.activeI18n.getMonthShortName(month);
844
+ onBlur(event) {
845
+ const input = event.target;
846
+ this.addValueFromInput(input);
1166
847
  }
1167
- getMonthFullName(month) {
1168
- return this.activeI18n.getMonthFullName(month);
848
+ addValueFromInput(input) {
849
+ const value = input.value?.trim();
850
+ if (!value)
851
+ return;
852
+ const current = this.control.value ?? [];
853
+ if (!current.includes(value)) {
854
+ this.control.setValue([...current, value]);
855
+ this.control.markAsDirty();
856
+ }
857
+ input.value = '';
1169
858
  }
1170
- getWeekdayLabel(weekday) {
1171
- return this.activeI18n.getWeekdayLabel(weekday);
859
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AutoCompleteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
860
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: AutoCompleteComponent, isStandalone: true, selector: "stc-auto-complete", inputs: { selectedItemTemplate: "selectedItemTemplate", items: "items", minLengthToSearch: "minLengthToSearch", delay: "delay", basicInput: "basicInput", typeAhead: "typeAhead", variant: "variant" }, outputs: { onSearch: "onSearch", selectOption: "selectOption" }, usesInheritance: true, ngImport: i0, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n @if (!required) {\r\n <span class=\"absolute top-[6px] left-0 text-[10px] text-gray-400\">{{'forms.config.optional' | translate}}</span>\r\n }\r\n <p-floatlabel [variant]=\"variant\" class=\"autoComplete\">\r\n <p-auto-complete (keydown)=\"onKeyDown($event)\" (onBlur)=\"onBlur($event)\" (completeMethod)=\"search($event)\" (onSelect)=\"onSelect($event)\" [delay]=\"delay\"\r\n [disabled]=\"disabled\" [formControl]=\"control\" [id]=\"inputId\" fluid [typeahead]=\"typeAhead\"\r\n [inputStyleClass]=\"'reset-default-styles w-full' + (basicInput ? ' basic-style': ' ')\"\r\n [minLength]=\"minLengthToSearch\" [name]=\"name\" [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid}\"\r\n [placeholder]=\"placeholder\" [styleClass]=\"'w-full'\" multiple [suggestions]=\"items\">\r\n <ng-template let-item pTemplate=\"item\">\r\n @if (selectedItemTemplate) {\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"selectedItemTemplate\" />\r\n }\r\n </ng-template>\r\n </p-auto-complete>\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"isInvalid\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n\r\n</div>\r\n", styles: [".text-required{color:red}.p-error{color:#dc2626}.autoComplete .p-floatlabel-in{height:auto!important}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "directive", type: PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "pipe", type: ValidationErrorsPipe, name: "validationErrors" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None });
861
+ }
862
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: AutoCompleteComponent, decorators: [{
863
+ type: Component,
864
+ args: [{ selector: 'stc-auto-complete', standalone: true, imports: [
865
+ ReactiveFormsModule,
866
+ AutoComplete,
867
+ PrimeTemplate,
868
+ NgIf,
869
+ NgTemplateOutlet,
870
+ NgClass,
871
+ JsonPipe,
872
+ ValidationErrorsPipe,
873
+ TranslatePipe,
874
+ FloatLabel,
875
+ ], encapsulation: ViewEncapsulation.None, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n @if (!required) {\r\n <span class=\"absolute top-[6px] left-0 text-[10px] text-gray-400\">{{'forms.config.optional' | translate}}</span>\r\n }\r\n <p-floatlabel [variant]=\"variant\" class=\"autoComplete\">\r\n <p-auto-complete (keydown)=\"onKeyDown($event)\" (onBlur)=\"onBlur($event)\" (completeMethod)=\"search($event)\" (onSelect)=\"onSelect($event)\" [delay]=\"delay\"\r\n [disabled]=\"disabled\" [formControl]=\"control\" [id]=\"inputId\" fluid [typeahead]=\"typeAhead\"\r\n [inputStyleClass]=\"'reset-default-styles w-full' + (basicInput ? ' basic-style': ' ')\"\r\n [minLength]=\"minLengthToSearch\" [name]=\"name\" [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid}\"\r\n [placeholder]=\"placeholder\" [styleClass]=\"'w-full'\" multiple [suggestions]=\"items\">\r\n <ng-template let-item pTemplate=\"item\">\r\n @if (selectedItemTemplate) {\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"selectedItemTemplate\" />\r\n }\r\n </ng-template>\r\n </p-auto-complete>\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"isInvalid\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n\r\n</div>\r\n", styles: [".text-required{color:red}.p-error{color:#dc2626}.autoComplete .p-floatlabel-in{height:auto!important}\n"] }]
876
+ }], ctorParameters: () => [], propDecorators: { selectedItemTemplate: [{
877
+ type: Input
878
+ }], onSearch: [{
879
+ type: Output
880
+ }], selectOption: [{
881
+ type: Output
882
+ }], items: [{
883
+ type: Input
884
+ }], minLengthToSearch: [{
885
+ type: Input
886
+ }], delay: [{
887
+ type: Input
888
+ }], basicInput: [{
889
+ type: Input
890
+ }], typeAhead: [{
891
+ type: Input
892
+ }], variant: [{
893
+ type: Input
894
+ }] } });
895
+
896
+ class DatePickerComponent extends BaseInputComponent {
897
+ showIcon = false;
898
+ showClear = false;
899
+ basicInput;
900
+ isTimeOnly = false;
901
+ minDate;
902
+ maxDate;
903
+ hourFormat = '12';
904
+ nowTime = new Date();
905
+ selectionMode = 'single';
906
+ onAfterClearDate = new EventEmitter();
907
+ variant = 'over';
908
+ withoutTime = false;
909
+ innerControl = new FormControl(null);
910
+ constructor() {
911
+ super();
1172
912
  }
1173
- getWeekdayShortName(weekday) {
1174
- return this.activeI18n.getWeekdayShortName(weekday);
913
+ ngOnInit() {
914
+ if (typeof this.control?.value === 'string') {
915
+ const date = new Date(this.control.value);
916
+ if (date) {
917
+ this.innerControl.setValue(date, { emitEvent: false });
918
+ }
919
+ }
920
+ this.control.valueChanges.subscribe((value) => {
921
+ if (!value)
922
+ this.innerControl.reset();
923
+ });
1175
924
  }
1176
- getDayAriaLabel(date) {
1177
- return this.activeI18n.getDayAriaLabel(date);
925
+ selectCurrentTime(e) {
926
+ if (this.withoutTime) {
927
+ const d = new Date();
928
+ this.control.setValue(d.toISOString().split('T')[0]);
929
+ return;
930
+ }
931
+ this.control.setValue(this.nowTime);
1178
932
  }
1179
- getYearNumerals(year) {
1180
- return this.activeI18n.getYearNumerals(year);
933
+ clearButtonClick(e) {
934
+ this.control.setValue(null);
1181
935
  }
1182
- getWeekNumerals(weekNumber) {
1183
- return this.activeI18n.getWeekNumerals(weekNumber);
936
+ afterClearDate() {
937
+ this.control.reset();
938
+ this.onAfterClearDate.emit();
1184
939
  }
1185
- getDayNumerals(date) {
1186
- return this.activeI18n.getDayNumerals(date);
940
+ onDateChange(value) {
941
+ const dateOnly = value instanceof Date ? formatDate(value, 'yyyy-MM-dd', 'en-US') : value;
942
+ this.control.setValue(dateOnly, { emitEvent: true });
1187
943
  }
1188
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicGregorianI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1189
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicGregorianI18n });
944
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
945
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DatePickerComponent, isStandalone: true, selector: "stc-date-picker", inputs: { showIcon: "showIcon", showClear: "showClear", basicInput: "basicInput", isTimeOnly: "isTimeOnly", minDate: "minDate", maxDate: "maxDate", hourFormat: "hourFormat", selectionMode: "selectionMode", variant: "variant", withoutTime: "withoutTime" }, outputs: { onAfterClearDate: "onAfterClearDate" }, usesInheritance: true, ngImport: i0, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n <p-floatlabel [variant]=\"variant\">\r\n <p-datepicker [selectionMode]=\"selectionMode\" [disabled]=\"disabled\" [formControl]=\"innerControl\"\r\n (onSelect)=\"onDateChange($event)\" [iconDisplay]=\"'input'\" [showClear]=\"showClear\" (onClear)=\"afterClearDate()\"\r\n [inputId]=\"inputId\" [inputStyleClass]=\"'reset-default-styles ' + (basicInput ? 'basic-style' : '')\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid }\" [placeholder]=\"placeholder\" [showIcon]=\"showIcon\"\r\n [class]=\"'w-full'\" appendTo=\"body\" [timeOnly]=\"isTimeOnly\" [hourFormat]=\"hourFormat\" [minDate]=\"minDate\"\r\n [maxDate]=\"maxDate\">\r\n @if (isTimeOnly) {\r\n <ng-template #inputicon let-clickCallBack=\"clickCallBack\">\r\n <i class=\"text-[18px] font-icon-time-clock\" (click)=\"clickCallBack($event)\"></i>\r\n </ng-template>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"p-datepicker-buttonbar\">\r\n <button pButton type=\"button\" class=\"p-button-text\" (click)=\"selectCurrentTime($event)\">\u0627\u0644\u0627\u0646\r\n </button>\r\n <button pButton type=\"button\" class=\"p-button-text\" (click)=\"clearButtonClick($event)\"> \u0627\u0644\u063A\u0627\u0621</button>\r\n </div>\r\n </ng-template>\r\n }\r\n </p-datepicker>\r\n\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n</div>\r\n", styles: [".p-datepicker{@apply relative;}.p-datepicker-clear-icon{@apply cursor-pointer absolute top-[50%] left-[13px] text-[var(--p-datepicker-input-icon-color)] ml-[calc(var(--p-icon-size))] leading-none;}.text-required{color:red}.p-error{color:#dc2626}stc-date-picker.w-full,stc-date-picker.w-full .field,stc-date-picker.w-full .p-floatlabel,stc-date-picker.w-full .p-datepicker,stc-date-picker.w-full .p-inputtext{@apply w-full;}stc-date-picker input{width:100%}stc-date-picker.w-full .p-datepicker{@apply block;}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "component", type: DatePicker, selector: "p-datePicker, p-datepicker, p-date-picker", inputs: ["iconDisplay", "styleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "readonlyInput", "shortYearCutoff", "hourFormat", "timeOnly", "stepHour", "stepMinute", "stepSecond", "showSeconds", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "minDate", "maxDate", "disabledDates", "disabledDays", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "view", "defaultDate", "appendTo"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: DatePickerModule }, { kind: "directive", type: i2$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i3$1.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "pipe", type: ValidationErrorsPipe, name: "validationErrors" }], encapsulation: i0.ViewEncapsulation.None });
1190
946
  }
1191
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicGregorianI18n, decorators: [{
1192
- type: Injectable
1193
- }] });
947
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatePickerComponent, decorators: [{
948
+ type: Component,
949
+ args: [{ selector: 'stc-date-picker', standalone: true, imports: [
950
+ FormsModule,
951
+ DatePicker,
952
+ ReactiveFormsModule,
953
+ NgClass,
954
+ DatePickerModule,
955
+ ValidationErrorsPipe,
956
+ FloatLabelModule,
957
+ ], encapsulation: ViewEncapsulation.None, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n <p-floatlabel [variant]=\"variant\">\r\n <p-datepicker [selectionMode]=\"selectionMode\" [disabled]=\"disabled\" [formControl]=\"innerControl\"\r\n (onSelect)=\"onDateChange($event)\" [iconDisplay]=\"'input'\" [showClear]=\"showClear\" (onClear)=\"afterClearDate()\"\r\n [inputId]=\"inputId\" [inputStyleClass]=\"'reset-default-styles ' + (basicInput ? 'basic-style' : '')\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid }\" [placeholder]=\"placeholder\" [showIcon]=\"showIcon\"\r\n [class]=\"'w-full'\" appendTo=\"body\" [timeOnly]=\"isTimeOnly\" [hourFormat]=\"hourFormat\" [minDate]=\"minDate\"\r\n [maxDate]=\"maxDate\">\r\n @if (isTimeOnly) {\r\n <ng-template #inputicon let-clickCallBack=\"clickCallBack\">\r\n <i class=\"text-[18px] font-icon-time-clock\" (click)=\"clickCallBack($event)\"></i>\r\n </ng-template>\r\n <ng-template pTemplate=\"footer\">\r\n <div class=\"p-datepicker-buttonbar\">\r\n <button pButton type=\"button\" class=\"p-button-text\" (click)=\"selectCurrentTime($event)\">\u0627\u0644\u0627\u0646\r\n </button>\r\n <button pButton type=\"button\" class=\"p-button-text\" (click)=\"clearButtonClick($event)\"> \u0627\u0644\u063A\u0627\u0621</button>\r\n </div>\r\n </ng-template>\r\n }\r\n </p-datepicker>\r\n\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n</div>\r\n", styles: [".p-datepicker{@apply relative;}.p-datepicker-clear-icon{@apply cursor-pointer absolute top-[50%] left-[13px] text-[var(--p-datepicker-input-icon-color)] ml-[calc(var(--p-icon-size))] leading-none;}.text-required{color:red}.p-error{color:#dc2626}stc-date-picker.w-full,stc-date-picker.w-full .field,stc-date-picker.w-full .p-floatlabel,stc-date-picker.w-full .p-datepicker,stc-date-picker.w-full .p-inputtext{@apply w-full;}stc-date-picker input{width:100%}stc-date-picker.w-full .p-datepicker{@apply block;}\n"] }]
958
+ }], ctorParameters: () => [], propDecorators: { showIcon: [{
959
+ type: Input
960
+ }], showClear: [{
961
+ type: Input
962
+ }], basicInput: [{
963
+ type: Input
964
+ }], isTimeOnly: [{
965
+ type: Input
966
+ }], minDate: [{
967
+ type: Input
968
+ }], maxDate: [{
969
+ type: Input
970
+ }], hourFormat: [{
971
+ type: Input
972
+ }], selectionMode: [{
973
+ type: Input
974
+ }], onAfterClearDate: [{
975
+ type: Output
976
+ }], variant: [{
977
+ type: Input
978
+ }], withoutTime: [{
979
+ type: Input
980
+ }] } });
1194
981
 
1195
- class GregorianCalendarComponent {
1196
- model;
1197
- dateSelected = new EventEmitter();
1198
- renderer = inject(Renderer2);
1199
- language = 'en';
1200
- startDate;
1201
- calendar = new NgbCalendarGregorian();
1202
- i18n = inject(NgbDatepickerI18n);
1203
- cdr = inject(ChangeDetectorRef);
1204
- calendarKey = 0;
1205
- ngOnChanges(changes) {
1206
- if (changes['model'] && changes['model'].currentValue) {
1207
- this.startDate = { ...changes['model'].currentValue };
1208
- }
1209
- if (changes['language'] && this.i18n instanceof DynamicGregorianI18n) {
1210
- this.i18n.setLanguage(this.language);
1211
- this.calendarKey++; // Increment to force recreation
1212
- }
1213
- }
1214
- ngAfterViewInit() {
1215
- const buttons = document.querySelectorAll('.ngb-dp-arrow-btn');
1216
- buttons.forEach(btn => {
1217
- this.renderer.removeAttribute(btn, 'title');
1218
- });
982
+ class InputComponent extends BaseInputComponent {
983
+ type = 'text';
984
+ contentType = 'text';
985
+ size = "small";
986
+ prefix;
987
+ rows = 2;
988
+ cols = 20;
989
+ autoResize = false;
990
+ basicInput;
991
+ noStyle;
992
+ canClear;
993
+ hideOptionalLabel;
994
+ inputDirection = 'inherit';
995
+ variant = 'over';
996
+ defaultColor = '#DFE0E6';
997
+ iconClass;
998
+ iconPosition = 'left';
999
+ constructor() {
1000
+ super();
1219
1001
  }
1220
- onDateChange(date) {
1221
- this.model = date;
1222
- this.startDate = { ...date };
1002
+ clearInput() {
1003
+ this.control.reset();
1223
1004
  }
1224
- isToday(date) {
1225
- const today = this.calendar.getToday();
1226
- return date.year === today.year &&
1227
- date.month === today.month &&
1228
- date.day === today.day;
1005
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1006
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: InputComponent, isStandalone: true, selector: "stc-input", inputs: { type: "type", contentType: "contentType", size: "size", prefix: "prefix", rows: "rows", cols: "cols", autoResize: "autoResize", basicInput: "basicInput", noStyle: "noStyle", canClear: "canClear", hideOptionalLabel: "hideOptionalLabel", inputDirection: "inputDirection", variant: "variant", defaultColor: "defaultColor", iconClass: "iconClass", iconPosition: "iconPosition" }, usesInheritance: true, ngImport: i0, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n\r\n <!-- input text align will be handled according to lang when implemented -->\r\n\r\n @switch (type) {\r\n @case ('textarea') {\r\n @if (label) {\r\n <div class=\"flex items-center justify-between gap-2\">\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n <!-- @else if (!hideOptionalLabel) {\r\n <span span class=\"optional-label\">{{'forms.config.optional' | translate}}</span>\r\n } -->\r\n </label>\r\n <ng-content></ng-content>\r\n </div>\r\n }\r\n <textarea [name]=\"name\" [id]=\"inputId\" [formControl]=\"control\" [placeholder]=\"placeholder\" [readonly]=\"readonly\"\r\n [disabled]=\"disabled\" pTextarea [rows]=\"rows\" [cols]=\"cols\" [autoResize]=\"autoResize\" [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \"\r\n [ngClass]=\"{'ng-invalid ng-dirty': control.invalid && (control.dirty || control.touched), 'basic-style': basicInput, 'no-style':noStyle}\">\r\n </textarea>\r\n }\r\n @case ('withIcon') {\r\n <p-iconfield class=\"filter-input\">\r\n <p-inputicon>\r\n <i [class]=\"iconClass\"></i>\r\n </p-inputicon>\r\n <input pInputText [id]=\"inputId\" type=\"text\" [placeholder]=\"placeholder\" [formControl]=\"control\" [readonly]=\"readonly\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid, 'basic-style': basicInput, 'no-style':noStyle}\" />\r\n @if (canClear && control.value) {\r\n <p-inputIcon (click)=\"clearInput()\">\r\n <i class=\"pi pi-times cursor-pointer text-sm text-gray-400 hover:text-gray-600\"></i>\r\n </p-inputIcon>\r\n }\r\n\r\n </p-iconfield>\r\n }\r\n @default {\r\n <p-floatlabel [variant]=\"variant\">\r\n <!-- <input pInputText id=\"value2\" [(ngModel)]=\"value2\" [invalid]=\"!value2\" autocomplete=\"off\" /> -->\r\n <input [id]=\"inputId\" [type]=\"'text-float-label'\" [formControl]=\"control\" [readonly]=\"readonly\" [pSize]=\"size\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \" [disabled]=\"disabled\" [name]=\"name\" pInputText [ngStyle]=\"{'direction': inputDirection || 'inherit'}\"\r\n class=\"w-full\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid, 'basic-style': basicInput, 'no-style':noStyle}\" />\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (prefix) {\r\n <span class=\"absolute top-[40px] font-bold text-[16px] left-[25px]\">\r\n {{ prefix }}\r\n </span>\r\n }\r\n\r\n\r\n }\r\n }\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n</div>", styles: ["textarea{@apply h-auto min-h-[50px] overflow-auto;}textarea,.p-select,input{border-radius:0;border-color:#dfe0e6}textarea:enabled:hover,.p-select:enabled:hover,input:enabled:hover{border-color:#dfe0e6}textarea:not(.p-disabled).p-focus,textarea:not(.p-disabled).p-focus:hover,textarea:focus,.p-select:not(.p-disabled).p-focus,.p-select:not(.p-disabled).p-focus:hover,.p-select:focus,input:not(.p-disabled).p-focus,input:not(.p-disabled).p-focus:hover,input:focus{outline:#DFE0E6;border-color:#dfe0e6}.p-floatlabel:has(input:focus) label,.p-floatlabel:has(input:-webkit-autofill) label,.p-floatlabel:has(textarea:focus) label,.p-floatlabel:has(.p-inputwrapper-focus) label{color:#687078}.p-inputtext:enabled:focus{border-color:#dfe0e6}.text-required{color:red}.p-error{color:#dc2626}.optional-label{@apply text-[10px] text-gray-400;margin-inline-start:4px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "directive", type: Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i3$1.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "component", type: InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["hostName", "styleClass"] }, { kind: "component", type: IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["hostName", "iconPosition", "styleClass"] }, { kind: "pipe", type: ValidationErrorsPipe, name: "validationErrors" }] });
1007
+ }
1008
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InputComponent, decorators: [{
1009
+ type: Component,
1010
+ args: [{ selector: 'stc-input', standalone: true, imports: [
1011
+ ReactiveFormsModule,
1012
+ InputText,
1013
+ Textarea,
1014
+ ValidationErrorsPipe,
1015
+ NgClass,
1016
+ NgStyle,
1017
+ TranslatePipe,
1018
+ FloatLabelModule,
1019
+ InputIcon,
1020
+ IconField,
1021
+ ], template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n\r\n <!-- input text align will be handled according to lang when implemented -->\r\n\r\n @switch (type) {\r\n @case ('textarea') {\r\n @if (label) {\r\n <div class=\"flex items-center justify-between gap-2\">\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n <!-- @else if (!hideOptionalLabel) {\r\n <span span class=\"optional-label\">{{'forms.config.optional' | translate}}</span>\r\n } -->\r\n </label>\r\n <ng-content></ng-content>\r\n </div>\r\n }\r\n <textarea [name]=\"name\" [id]=\"inputId\" [formControl]=\"control\" [placeholder]=\"placeholder\" [readonly]=\"readonly\"\r\n [disabled]=\"disabled\" pTextarea [rows]=\"rows\" [cols]=\"cols\" [autoResize]=\"autoResize\" [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \"\r\n [ngClass]=\"{'ng-invalid ng-dirty': control.invalid && (control.dirty || control.touched), 'basic-style': basicInput, 'no-style':noStyle}\">\r\n </textarea>\r\n }\r\n @case ('withIcon') {\r\n <p-iconfield class=\"filter-input\">\r\n <p-inputicon>\r\n <i [class]=\"iconClass\"></i>\r\n </p-inputicon>\r\n <input pInputText [id]=\"inputId\" type=\"text\" [placeholder]=\"placeholder\" [formControl]=\"control\" [readonly]=\"readonly\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid, 'basic-style': basicInput, 'no-style':noStyle}\" />\r\n @if (canClear && control.value) {\r\n <p-inputIcon (click)=\"clearInput()\">\r\n <i class=\"pi pi-times cursor-pointer text-sm text-gray-400 hover:text-gray-600\"></i>\r\n </p-inputIcon>\r\n }\r\n\r\n </p-iconfield>\r\n }\r\n @default {\r\n <p-floatlabel [variant]=\"variant\">\r\n <!-- <input pInputText id=\"value2\" [(ngModel)]=\"value2\" [invalid]=\"!value2\" autocomplete=\"off\" /> -->\r\n <input [id]=\"inputId\" [type]=\"'text-float-label'\" [formControl]=\"control\" [readonly]=\"readonly\" [pSize]=\"size\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \" [disabled]=\"disabled\" [name]=\"name\" pInputText [ngStyle]=\"{'direction': inputDirection || 'inherit'}\"\r\n class=\"w-full\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid, 'basic-style': basicInput, 'no-style':noStyle}\" />\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (prefix) {\r\n <span class=\"absolute top-[40px] font-bold text-[16px] left-[25px]\">\r\n {{ prefix }}\r\n </span>\r\n }\r\n\r\n\r\n }\r\n }\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n</div>", styles: ["textarea{@apply h-auto min-h-[50px] overflow-auto;}textarea,.p-select,input{border-radius:0;border-color:#dfe0e6}textarea:enabled:hover,.p-select:enabled:hover,input:enabled:hover{border-color:#dfe0e6}textarea:not(.p-disabled).p-focus,textarea:not(.p-disabled).p-focus:hover,textarea:focus,.p-select:not(.p-disabled).p-focus,.p-select:not(.p-disabled).p-focus:hover,.p-select:focus,input:not(.p-disabled).p-focus,input:not(.p-disabled).p-focus:hover,input:focus{outline:#DFE0E6;border-color:#dfe0e6}.p-floatlabel:has(input:focus) label,.p-floatlabel:has(input:-webkit-autofill) label,.p-floatlabel:has(textarea:focus) label,.p-floatlabel:has(.p-inputwrapper-focus) label{color:#687078}.p-inputtext:enabled:focus{border-color:#dfe0e6}.text-required{color:red}.p-error{color:#dc2626}.optional-label{@apply text-[10px] text-gray-400;margin-inline-start:4px}\n"] }]
1022
+ }], ctorParameters: () => [], propDecorators: { type: [{
1023
+ type: Input
1024
+ }], contentType: [{
1025
+ type: Input
1026
+ }], size: [{
1027
+ type: Input
1028
+ }], prefix: [{
1029
+ type: Input
1030
+ }], rows: [{
1031
+ type: Input
1032
+ }], cols: [{
1033
+ type: Input
1034
+ }], autoResize: [{
1035
+ type: Input
1036
+ }], basicInput: [{
1037
+ type: Input
1038
+ }], noStyle: [{
1039
+ type: Input
1040
+ }], canClear: [{
1041
+ type: Input
1042
+ }], hideOptionalLabel: [{
1043
+ type: Input
1044
+ }], inputDirection: [{
1045
+ type: Input
1046
+ }], variant: [{
1047
+ type: Input
1048
+ }], defaultColor: [{
1049
+ type: Input
1050
+ }], iconClass: [{
1051
+ type: Input
1052
+ }], iconPosition: [{
1053
+ type: Input
1054
+ }] } });
1055
+
1056
+ class SelectButtonComponent extends BaseInputComponent {
1057
+ onChange = new EventEmitter();
1058
+ options;
1059
+ title;
1060
+ changeValue(e) {
1061
+ this.onChange.emit(e.value);
1229
1062
  }
1230
- isDisabled = () => false;
1231
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1232
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: GregorianCalendarComponent, isStandalone: true, selector: "app-gregorian-calendar", inputs: { model: "model", language: "language" }, outputs: { dateSelected: "dateSelected" }, providers: [
1233
- { provide: NgbCalendar, useClass: NgbCalendarGregorian },
1234
- { provide: NgbDatepickerI18n, useClass: DynamicGregorianI18n }
1235
- ], usesOnChanges: true, ngImport: i0, template: "@for(item of [calendarKey]; track item) {\r\n <ngb-datepicker #dp\r\n [class.rtl]=\"language === 'ar'\"\r\n [class.ltr]=\"language === 'en'\"\r\n [ngModel]=\"model\"\r\n [startDate]=\"startDate\"\r\n (ngModelChange)=\"onDateChange($event)\"\r\n (dateSelect)=\"dateSelected.emit($event)\"\r\n [dayTemplate]=\"dayTemplate\"\r\n [markDisabled]=\"isDisabled\">\r\n </ngb-datepicker>\r\n <ng-template #dayTemplate let-date let-currentMonth=\"currentMonth\" let-selected=\"selected\" let-disabled=\"disabled\">\r\n <span class=\"custom-day\"\r\n [class.today]=\"isToday(date)\"\r\n [class.selected]=\"selected\"\r\n [class.outside]=\"date.month !== currentMonth\"\r\n [class.disabled]=\"disabled\">\r\n {{ date.day }}\r\n </span>\r\n </ng-template>\r\n}\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: NgbDatepickerModule }, { kind: "component", type: i1$6.NgbDatepicker, selector: "ngb-datepicker", inputs: ["contentTemplate", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "maxDate", "minDate", "navigation", "outsideDays", "showWeekNumbers", "startDate", "weekdays"], outputs: ["navigate", "dateSelect"], exportAs: ["ngbDatepicker"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], encapsulation: i0.ViewEncapsulation.None });
1063
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SelectButtonComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1064
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SelectButtonComponent, isStandalone: true, selector: "stc-select-button", inputs: { options: "options", title: "title" }, outputs: { onChange: "onChange" }, usesInheritance: true, ngImport: i0, template: "<div class=\"grid grid-cols-12 gap-x-4 gap-y-0 items-end\">\r\n <div class=\"col-span-12\">\r\n <div class=\"text-[14px] font-bold mb-1\">{{ title }}</div>\r\n <div class=\"grid w-100 bg-gray-100 rounded drop-shadow-basic\">\r\n <p-selectButton [disabled]=\"disabled\"\r\n [options]=\"options\"\r\n [formControl]=\"control\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n class=\"rounded\"\r\n [styleClass]=\"'full-width'\"\r\n (onChange)=\"changeValue($event)\">\r\n <ng-template let-item class=\"flex w-100\">\r\n <div class=\"col-span-4\">\r\n <span>{{ item.value }}</span>\r\n </div>\r\n </ng-template>\r\n </p-selectButton>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: SelectButtonModule }, { kind: "component", type: i2$2.SelectButton, selector: "p-selectButton, p-selectbutton, p-select-button", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "unselectable", "tabindex", "multiple", "allowEmpty", "styleClass", "ariaLabelledBy", "dataKey", "autofocus", "size", "fluid"], outputs: ["onOptionClick", "onChange"] }, { kind: "ngmodule", type: FormsModule }] });
1236
1065
  }
1237
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianCalendarComponent, decorators: [{
1066
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SelectButtonComponent, decorators: [{
1238
1067
  type: Component,
1239
- args: [{ selector: "app-gregorian-calendar", standalone: true, imports: [NgbDatepickerModule, FormsModule], providers: [
1240
- { provide: NgbCalendar, useClass: NgbCalendarGregorian },
1241
- { provide: NgbDatepickerI18n, useClass: DynamicGregorianI18n }
1242
- ], encapsulation: ViewEncapsulation.None, template: "@for(item of [calendarKey]; track item) {\r\n <ngb-datepicker #dp\r\n [class.rtl]=\"language === 'ar'\"\r\n [class.ltr]=\"language === 'en'\"\r\n [ngModel]=\"model\"\r\n [startDate]=\"startDate\"\r\n (ngModelChange)=\"onDateChange($event)\"\r\n (dateSelect)=\"dateSelected.emit($event)\"\r\n [dayTemplate]=\"dayTemplate\"\r\n [markDisabled]=\"isDisabled\">\r\n </ngb-datepicker>\r\n <ng-template #dayTemplate let-date let-currentMonth=\"currentMonth\" let-selected=\"selected\" let-disabled=\"disabled\">\r\n <span class=\"custom-day\"\r\n [class.today]=\"isToday(date)\"\r\n [class.selected]=\"selected\"\r\n [class.outside]=\"date.month !== currentMonth\"\r\n [class.disabled]=\"disabled\">\r\n {{ date.day }}\r\n </span>\r\n </ng-template>\r\n}\r\n" }]
1243
- }], propDecorators: { model: [{
1244
- type: Input
1245
- }], dateSelected: [{
1068
+ args: [{ selector: "stc-select-button", standalone: true, imports: [ReactiveFormsModule, SelectButtonModule, FormsModule], template: "<div class=\"grid grid-cols-12 gap-x-4 gap-y-0 items-end\">\r\n <div class=\"col-span-12\">\r\n <div class=\"text-[14px] font-bold mb-1\">{{ title }}</div>\r\n <div class=\"grid w-100 bg-gray-100 rounded drop-shadow-basic\">\r\n <p-selectButton [disabled]=\"disabled\"\r\n [options]=\"options\"\r\n [formControl]=\"control\"\r\n optionLabel=\"label\"\r\n optionValue=\"value\"\r\n class=\"rounded\"\r\n [styleClass]=\"'full-width'\"\r\n (onChange)=\"changeValue($event)\">\r\n <ng-template let-item class=\"flex w-100\">\r\n <div class=\"col-span-4\">\r\n <span>{{ item.value }}</span>\r\n </div>\r\n </ng-template>\r\n </p-selectButton>\r\n </div>\r\n </div>\r\n</div>\r\n" }]
1069
+ }], propDecorators: { onChange: [{
1246
1070
  type: Output
1247
- }], language: [{
1071
+ }], options: [{
1072
+ type: Input
1073
+ }], title: [{
1248
1074
  type: Input
1249
1075
  }] } });
1250
1076
 
1251
- class DatePickerSwitcherComponent extends BaseInputComponent {
1252
- type = 'text';
1253
- contentType = 'text';
1254
- size = "small";
1255
- prefix;
1256
- rows = 2;
1257
- cols = 20;
1258
- autoResize = true;
1077
+ class SelectComponent extends BaseInputComponent {
1078
+ selectedItemTemplate = null;
1079
+ optionTemplate = null;
1080
+ options = [];
1081
+ optionLabel;
1082
+ optionValue;
1083
+ emptyMessage;
1084
+ checkmark = true;
1085
+ showClear = false;
1086
+ editable = false;
1087
+ filter = false;
1088
+ multiple = false;
1089
+ filterBy;
1090
+ selectAllLabel;
1091
+ dataKey;
1092
+ size = 'small';
1093
+ selectedItemsLabel;
1259
1094
  basicInput;
1260
- noStyle;
1261
- hideOptionalLabel;
1262
- inputDirection = 'inherit';
1263
1095
  variant = 'over';
1096
+ // eslint-disable-next-line @angular-eslint/no-output-native
1097
+ change = new EventEmitter();
1098
+ clicked = new EventEmitter();
1264
1099
  defaultColor = '#DFE0E6';
1265
- formattedDate = '';
1266
- openCalender = new EventEmitter();
1100
+ allSelectd = false;
1267
1101
  constructor() {
1268
1102
  super();
1269
1103
  }
1270
- ngOnChanges(changes) {
1271
- if (changes['formattedDate'] && changes['formattedDate'].currentValue) {
1272
- // Update the FormControl value if parent changes the formattedDate
1273
- this.control.setValue(changes['formattedDate'].currentValue, { emitEvent: false });
1104
+ toggleAll(event) {
1105
+ if (!event.checked) {
1106
+ this.control.setValue([]);
1107
+ return;
1274
1108
  }
1109
+ const values = this.optionValue
1110
+ ? this.options.map((o) => o[this.optionValue])
1111
+ : this.options;
1112
+ this.control.setValue([...values]);
1275
1113
  }
1276
- ngOnInit() {
1277
- this.control.setValue(this.formattedDate);
1114
+ onMultiSelectClear() {
1115
+ this.allSelectd = false;
1278
1116
  }
1279
- clearButtonClick(e) {
1280
- this.control.setValue(null);
1117
+ onChange(e) {
1118
+ this.change.emit(e);
1281
1119
  }
1282
- openCalendar(isOpen) {
1283
- this.openCalender.emit(isOpen);
1120
+ onClick(event) {
1121
+ this.clicked.emit(event);
1284
1122
  }
1285
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatePickerSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1286
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DatePickerSwitcherComponent, isStandalone: true, selector: "stc-date-picker-switcher", inputs: { type: "type", contentType: "contentType", size: "size", prefix: "prefix", rows: "rows", cols: "cols", autoResize: "autoResize", basicInput: "basicInput", noStyle: "noStyle", hideOptionalLabel: "hideOptionalLabel", inputDirection: "inputDirection", variant: "variant", defaultColor: "defaultColor", formattedDate: "formattedDate" }, outputs: { openCalender: "openCalender" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n <p-floatlabel [variant]=\"variant\">\r\n <input [id]=\"inputId\" [type]=\"'text-float-label'\" [formControl]=\"control\" [readonly]=\"true\" (focus)=\"openCalendar(true)\"\r\n (click)=\"openCalendar(true)\" [pSize]=\"'small'\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \" [disabled]=\"disabled\" [name]=\"name\" pInputText\r\n class=\"w-full\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid, 'basic-style': basicInput, 'no-style':noStyle}\" />\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n</div>\r\n", styles: [".p-datepicker-clear-icon{@apply cursor-pointer absolute top-[50%] left-[13px] -translate-y-1/2 text-[var(--p-datepicker-input-icon-color)] ml-[calc(var(--p-icon-size))] leading-none;}.my-custom-datepicker-panel{display:none!important}.d-ltr{direction:ltr}.text-required{color:red}.p-error{color:#dc2626}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: DatePickerModule }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i3$1.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "pipe", type: ValidationErrorsPipe, name: "validationErrors" }], encapsulation: i0.ViewEncapsulation.None });
1123
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1124
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: SelectComponent, isStandalone: true, selector: "stc-select", inputs: { selectedItemTemplate: "selectedItemTemplate", optionTemplate: "optionTemplate", options: "options", optionLabel: "optionLabel", optionValue: "optionValue", emptyMessage: "emptyMessage", checkmark: "checkmark", showClear: "showClear", editable: "editable", filter: "filter", multiple: "multiple", filterBy: "filterBy", selectAllLabel: "selectAllLabel", dataKey: "dataKey", size: "size", selectedItemsLabel: "selectedItemsLabel", basicInput: "basicInput", variant: "variant", defaultColor: "defaultColor" }, outputs: { change: "change", clicked: "clicked" }, usesInheritance: true, ngImport: i0, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n\r\n @if(multiple) {\r\n <p-floatLabel [variant]=\"variant\">\r\n\r\n <p-multiselect [disabled]=\"disabled\" [filterBy]=\"filterBy\" [filter]=\"filter\" [formControl]=\"control\" [id]=\"inputId\"\r\n [name]=\"name\" [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid }\" [optionLabel]=\"optionLabel\"\r\n [optionValue]=\"optionValue\" [options]=\"options\" [showToggleAll]=\"false\" [placeholder]=\"placeholder\"\r\n [emptyMessage]=\"emptyMessage || ('shared.no_results_found'|translate)\" [readonly]=\"readonly\"\r\n [showClear]=\"showClear\" (onClear)=\"onMultiSelectClear()\" class=\"w-full\" [size]=\"size\"\r\n [selectedItemsLabel]=\"selectedItemsLabel || ('shared.Items_Selected'| translate: {count: '{0}'})\" [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \" (onChange)=\"onChange($event)\" [ngClass]=\"{ 'basic-style': basicInput }\">\r\n\r\n @if (selectAllLabel) {\r\n <ng-template #filter>\r\n <p-checkbox binary=\"true\" [(ngModel)]=\"allSelectd\" (onChange)=\"toggleAll($event)\" inputId=\"toggleAll\">\r\n </p-checkbox>\r\n <span>{{selectAllLabel}}</span>\r\n </ng-template>\r\n }\r\n\r\n @if(optionTemplate){\r\n <ng-template let-item #item>\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"optionTemplate\" />\r\n </ng-template>\r\n }\r\n\r\n\r\n\r\n\r\n\r\n </p-multiselect>\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n\r\n </p-floatLabel>\r\n\r\n } @else {\r\n <p-floatLabel [variant]=\"variant\">\r\n <p-select [dataKey]=\"dataKey\" [checkmark]=\"checkmark\" [disabled]=\"disabled\" [editable]=\"editable\"\r\n [filterBy]=\"filterBy\" [filter]=\"filter\" [formControl]=\"control\" [id]=\"inputId\" [name]=\"name\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid }\"\r\n [emptyMessage]=\"emptyMessage || ('shared.no_results_found'|translate)\" [optionLabel]=\"optionLabel\"\r\n [optionValue]=\"optionValue\" [options]=\"options\" [placeholder]=\"placeholder\" [readonly]=\"readonly\"\r\n [showClear]=\"showClear\" [size]=\"size\" class=\"w-full\" [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \" (onChange)=\"onChange($event)\" (click)=\"clicked.emit($event)\" [ngClass]=\"{ 'basic-style': basicInput }\">\r\n\r\n @if (optionTemplate) {\r\n <ng-template let-item pTemplate=\"item\">\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"optionTemplate\" />\r\n </ng-template>\r\n }\r\n @if (selectedItemTemplate) {\r\n <ng-template let-item pTemplate=\"selectedItem\">\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"selectedItemTemplate\" />\r\n </ng-template>\r\n }\r\n </p-select>\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatLabel>\r\n }\r\n\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n } @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br />\r\n }\r\n </small>\r\n }\r\n</div>", styles: ["textarea,.p-select{border-radius:0;border-color:#dfe0e6}textarea:enabled:hover,.p-select:enabled:hover{border-color:#dfe0e6}textarea:not(.p-disabled).p-focus,textarea:not(.p-disabled).p-focus:hover,textarea:focus,.p-select:not(.p-disabled).p-focus,.p-select:not(.p-disabled).p-focus:hover,.p-select:focus{outline:#DFE0E6;border-color:#dfe0e6}.p-floatlabel:has(input:focus) label,.p-floatlabel:has(input:-webkit-autofill) label,.p-floatlabel:has(textarea:focus) label,.p-floatlabel:has(.p-inputwrapper-focus) label{color:#687078}.p-inputtext:enabled:focus{border-color:#dfe0e6}.p-select .p-select-label{padding-block-end:1rem!important;padding-block-start:1rem!important}.text-required{color:red}.p-error{color:#dc2626}.edit-search .p-select-label{padding:1rem 1rem 1rem 2.2rem!important}.edit-search .p-floatlabel>label{padding-inline-start:25px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: MultiSelectModule }, { kind: "component", type: i2$3.MultiSelect, selector: "p-multiSelect, p-multiselect, p-multi-select", inputs: ["id", "ariaLabel", "styleClass", "panelStyle", "panelStyleClass", "inputId", "readonly", "group", "filter", "filterPlaceHolder", "filterLocale", "overlayVisible", "tabindex", "dataKey", "ariaLabelledBy", "displaySelectedLabel", "maxSelectedLabels", "selectionLimit", "selectedItemsLabel", "showToggleAll", "emptyFilterMessage", "emptyMessage", "resetFilterOnHide", "dropdownIcon", "chipIcon", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "showHeader", "filterBy", "scrollHeight", "lazy", "virtualScroll", "loading", "virtualScrollItemSize", "loadingIcon", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "autofocusFilter", "display", "autocomplete", "showClear", "autofocus", "placeholder", "options", "filterValue", "selectAll", "focusOnHover", "filterFields", "selectOnFocus", "autoOptionFocus", "highlightOnSelect", "size", "variant", "fluid", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onClear", "onPanelShow", "onPanelHide", "onLazyLoad", "onRemove", "onSelectAllChange"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i3$1.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "pipe", type: ValidationErrorsPipe, name: "validationErrors" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None });
1287
1125
  }
1288
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatePickerSwitcherComponent, decorators: [{
1126
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SelectComponent, decorators: [{
1289
1127
  type: Component,
1290
- args: [{ selector: 'stc-date-picker-switcher', standalone: true, imports: [
1128
+ args: [{ selector: 'stc-select', standalone: true, imports: [
1291
1129
  FormsModule,
1130
+ Select,
1292
1131
  ReactiveFormsModule,
1293
1132
  NgClass,
1294
- InputText,
1295
- DatePickerModule,
1133
+ NgTemplateOutlet,
1134
+ PrimeTemplate,
1296
1135
  ValidationErrorsPipe,
1297
- TranslatePipe,
1136
+ MultiSelectModule,
1298
1137
  FloatLabelModule,
1299
- ], encapsulation: ViewEncapsulation.None, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n <p-floatlabel [variant]=\"variant\">\r\n <input [id]=\"inputId\" [type]=\"'text-float-label'\" [formControl]=\"control\" [readonly]=\"true\" (focus)=\"openCalendar(true)\"\r\n (click)=\"openCalendar(true)\" [pSize]=\"'small'\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \" [disabled]=\"disabled\" [name]=\"name\" pInputText\r\n class=\"w-full\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid, 'basic-style': basicInput, 'no-style':noStyle}\" />\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n</div>\r\n", styles: [".p-datepicker-clear-icon{@apply cursor-pointer absolute top-[50%] left-[13px] -translate-y-1/2 text-[var(--p-datepicker-input-icon-color)] ml-[calc(var(--p-icon-size))] leading-none;}.my-custom-datepicker-panel{display:none!important}.d-ltr{direction:ltr}.text-required{color:red}.p-error{color:#dc2626}\n"] }]
1300
- }], ctorParameters: () => [], propDecorators: { type: [{
1138
+ TranslatePipe,
1139
+ CheckboxModule,
1140
+ ], encapsulation: ViewEncapsulation.None, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n\r\n @if(multiple) {\r\n <p-floatLabel [variant]=\"variant\">\r\n\r\n <p-multiselect [disabled]=\"disabled\" [filterBy]=\"filterBy\" [filter]=\"filter\" [formControl]=\"control\" [id]=\"inputId\"\r\n [name]=\"name\" [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid }\" [optionLabel]=\"optionLabel\"\r\n [optionValue]=\"optionValue\" [options]=\"options\" [showToggleAll]=\"false\" [placeholder]=\"placeholder\"\r\n [emptyMessage]=\"emptyMessage || ('shared.no_results_found'|translate)\" [readonly]=\"readonly\"\r\n [showClear]=\"showClear\" (onClear)=\"onMultiSelectClear()\" class=\"w-full\" [size]=\"size\"\r\n [selectedItemsLabel]=\"selectedItemsLabel || ('shared.Items_Selected'| translate: {count: '{0}'})\" [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \" (onChange)=\"onChange($event)\" [ngClass]=\"{ 'basic-style': basicInput }\">\r\n\r\n @if (selectAllLabel) {\r\n <ng-template #filter>\r\n <p-checkbox binary=\"true\" [(ngModel)]=\"allSelectd\" (onChange)=\"toggleAll($event)\" inputId=\"toggleAll\">\r\n </p-checkbox>\r\n <span>{{selectAllLabel}}</span>\r\n </ng-template>\r\n }\r\n\r\n @if(optionTemplate){\r\n <ng-template let-item #item>\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"optionTemplate\" />\r\n </ng-template>\r\n }\r\n\r\n\r\n\r\n\r\n\r\n </p-multiselect>\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n\r\n </p-floatLabel>\r\n\r\n } @else {\r\n <p-floatLabel [variant]=\"variant\">\r\n <p-select [dataKey]=\"dataKey\" [checkmark]=\"checkmark\" [disabled]=\"disabled\" [editable]=\"editable\"\r\n [filterBy]=\"filterBy\" [filter]=\"filter\" [formControl]=\"control\" [id]=\"inputId\" [name]=\"name\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid }\"\r\n [emptyMessage]=\"emptyMessage || ('shared.no_results_found'|translate)\" [optionLabel]=\"optionLabel\"\r\n [optionValue]=\"optionValue\" [options]=\"options\" [placeholder]=\"placeholder\" [readonly]=\"readonly\"\r\n [showClear]=\"showClear\" [size]=\"size\" class=\"w-full\" [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \" (onChange)=\"onChange($event)\" (click)=\"clicked.emit($event)\" [ngClass]=\"{ 'basic-style': basicInput }\">\r\n\r\n @if (optionTemplate) {\r\n <ng-template let-item pTemplate=\"item\">\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"optionTemplate\" />\r\n </ng-template>\r\n }\r\n @if (selectedItemTemplate) {\r\n <ng-template let-item pTemplate=\"selectedItem\">\r\n <ng-container [ngTemplateOutletContext]=\"{ $implicit: item }\" [ngTemplateOutlet]=\"selectedItemTemplate\" />\r\n </ng-template>\r\n }\r\n </p-select>\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatLabel>\r\n }\r\n\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n } @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br />\r\n }\r\n </small>\r\n }\r\n</div>", styles: ["textarea,.p-select{border-radius:0;border-color:#dfe0e6}textarea:enabled:hover,.p-select:enabled:hover{border-color:#dfe0e6}textarea:not(.p-disabled).p-focus,textarea:not(.p-disabled).p-focus:hover,textarea:focus,.p-select:not(.p-disabled).p-focus,.p-select:not(.p-disabled).p-focus:hover,.p-select:focus{outline:#DFE0E6;border-color:#dfe0e6}.p-floatlabel:has(input:focus) label,.p-floatlabel:has(input:-webkit-autofill) label,.p-floatlabel:has(textarea:focus) label,.p-floatlabel:has(.p-inputwrapper-focus) label{color:#687078}.p-inputtext:enabled:focus{border-color:#dfe0e6}.p-select .p-select-label{padding-block-end:1rem!important;padding-block-start:1rem!important}.text-required{color:red}.p-error{color:#dc2626}.edit-search .p-select-label{padding:1rem 1rem 1rem 2.2rem!important}.edit-search .p-floatlabel>label{padding-inline-start:25px}\n"] }]
1141
+ }], ctorParameters: () => [], propDecorators: { selectedItemTemplate: [{
1301
1142
  type: Input
1302
- }], contentType: [{
1143
+ }], optionTemplate: [{
1303
1144
  type: Input
1304
- }], size: [{
1145
+ }], options: [{
1305
1146
  type: Input
1306
- }], prefix: [{
1147
+ }], optionLabel: [{
1307
1148
  type: Input
1308
- }], rows: [{
1149
+ }], optionValue: [{
1309
1150
  type: Input
1310
- }], cols: [{
1151
+ }], emptyMessage: [{
1311
1152
  type: Input
1312
- }], autoResize: [{
1153
+ }], checkmark: [{
1313
1154
  type: Input
1314
- }], basicInput: [{
1155
+ }], showClear: [{
1315
1156
  type: Input
1316
- }], noStyle: [{
1157
+ }], editable: [{
1317
1158
  type: Input
1318
- }], hideOptionalLabel: [{
1159
+ }], filter: [{
1319
1160
  type: Input
1320
- }], inputDirection: [{
1161
+ }], multiple: [{
1162
+ type: Input
1163
+ }], filterBy: [{
1164
+ type: Input
1165
+ }], selectAllLabel: [{
1166
+ type: Input
1167
+ }], dataKey: [{
1168
+ type: Input
1169
+ }], size: [{
1170
+ type: Input
1171
+ }], selectedItemsLabel: [{
1172
+ type: Input
1173
+ }], basicInput: [{
1321
1174
  type: Input
1322
1175
  }], variant: [{
1323
1176
  type: Input
1177
+ }], change: [{
1178
+ type: Output
1179
+ }], clicked: [{
1180
+ type: Output
1324
1181
  }], defaultColor: [{
1325
1182
  type: Input
1326
- }], formattedDate: [{
1183
+ }] } });
1184
+
1185
+ class SwitchComponent {
1186
+ label;
1187
+ key;
1188
+ checked = false;
1189
+ onChange = new EventEmitter();
1190
+ // checked: boolean = false;
1191
+ sendUpdatedValue(value) {
1192
+ if (value) {
1193
+ this.onChange.emit(value.checked);
1194
+ }
1195
+ }
1196
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1197
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: SwitchComponent, isStandalone: true, selector: "stc-switch", inputs: { label: "label", key: "key", checked: "checked" }, outputs: { onChange: "onChange" }, ngImport: i0, template: "<div class=\"flex items-center mr-2\">\r\n <p-toggleswitch [(ngModel)]=\"checked\" [inputId]=\"key\" (onChange)=\"sendUpdatedValue($event)\" class=\"flex\">\r\n </p-toggleswitch>\r\n <label [for]=\"key\" class=\"text-[12px] mx-2\">{{label}}</label>\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i1$5.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
1198
+ }
1199
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SwitchComponent, decorators: [{
1200
+ type: Component,
1201
+ args: [{ selector: "stc-switch", standalone: true, imports: [CommonModule, ToggleSwitchModule, FormsModule], template: "<div class=\"flex items-center mr-2\">\r\n <p-toggleswitch [(ngModel)]=\"checked\" [inputId]=\"key\" (onChange)=\"sendUpdatedValue($event)\" class=\"flex\">\r\n </p-toggleswitch>\r\n <label [for]=\"key\" class=\"text-[12px] mx-2\">{{label}}</label>\r\n</div>" }]
1202
+ }], propDecorators: { label: [{
1327
1203
  type: Input
1328
- }], openCalender: [{
1204
+ }], key: [{
1205
+ type: Input
1206
+ }], checked: [{
1207
+ type: Input
1208
+ }], onChange: [{
1329
1209
  type: Output
1330
1210
  }] } });
1331
1211
 
1332
- var DateFormats;
1333
- (function (DateFormats) {
1334
- DateFormats["DATE_ONLY"] = "yyyy-MM-dd";
1335
- DateFormats["DATE_UTC"] = "yyyy-MM-dd'T'HH:mm:ss'Z'";
1336
- DateFormats["DATE_TIME_FULL"] = "dd MMMM yyyy - hh:mm a";
1337
- DateFormats["DATE_TIME_SEMI"] = "yyyy/MM/dd - hh:mm a";
1338
- DateFormats["DATE"] = "dd MMMM yyyy";
1339
- DateFormats["DATE_TWO"] = "yyyy/MM/dd";
1340
- DateFormats["DAY_ONLY"] = "cccc";
1341
- DateFormats["TIME_ONLY"] = "hh:mm";
1342
- DateFormats["AM_PM"] = "a";
1343
- DateFormats["TIME"] = "hh:mm a";
1344
- DateFormats["YEAR"] = "yyyy";
1345
- DateFormats["MONTH"] = "MM";
1346
- DateFormats["DAY"] = "dd";
1347
- })(DateFormats || (DateFormats = {}));
1348
- var TimeFormats;
1349
- (function (TimeFormats) {
1350
- TimeFormats["HOURS12Format"] = "hh";
1351
- TimeFormats["HOURS24Format"] = "HH";
1352
- TimeFormats["MINUTES"] = "mm";
1353
- TimeFormats["SECONDS"] = "ss";
1354
- })(TimeFormats || (TimeFormats = {}));
1355
-
1356
- class DualCalendarComponent {
1357
- selectedDate = '';
1358
- control = new FormControl({ value: null, disabled: false }, []);
1359
- label = '';
1360
- name = '';
1361
- withTime = true;
1362
- isDatePickerShow = true;
1363
- mode = 'gregorian';
1364
- gregorianModel;
1365
- hijriModel;
1366
- currentLang = signal('ar', ...(ngDevMode ? [{ debugName: "currentLang" }] : []));
1367
- gregorianUTC = new EventEmitter();
1368
- onClose = new EventEmitter();
1369
- gregorianUTCValue = '';
1370
- isShown = false;
1371
- calendarContainer;
1372
- hijriCal = new NgbCalendarIslamicUmalqura();
1373
- constructor() {
1374
- effect(() => {
1375
- this.currentLang(); // 👈 track signal
1376
- this.setDate(this.gregorianUTCValue);
1377
- });
1212
+ const WEEKDAYS = {
1213
+ ar: ['ن', 'ث', 'ر', 'خ', 'ج', 'س', 'ح'],
1214
+ en: ['M', 'T', 'W', 'T', 'F', 'S', 'S']
1215
+ };
1216
+ const MONTHS_GREGORIAN = {
1217
+ ar: [
1218
+ 'يناير', 'فبراير', 'مارس', 'أبريل', 'مايو', 'يونيو',
1219
+ 'يوليو', 'أغسطس', 'سبتمبر', 'أكتوبر', 'نوفمبر', 'ديسمبر'
1220
+ ],
1221
+ en: [
1222
+ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
1223
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
1224
+ ]
1225
+ };
1226
+ const MONTHS_HIJRI = {
1227
+ ar: [
1228
+ 'محرم',
1229
+ 'صفر',
1230
+ 'ربيع الأول',
1231
+ 'ربيع الآخر',
1232
+ 'جمادى الأولى',
1233
+ 'جمادى الآخرة',
1234
+ 'رجب',
1235
+ 'شعبان',
1236
+ 'رمضان',
1237
+ 'شوال',
1238
+ 'ذو القعدة',
1239
+ 'ذو الحجة'
1240
+ ],
1241
+ en: [
1242
+ 'Muharram',
1243
+ 'Safar',
1244
+ 'Rabi Al-Awwal',
1245
+ 'Rabi Al-Thani',
1246
+ 'Jumada Al-Awwal',
1247
+ 'Jumada Al-Thani',
1248
+ 'Rajab',
1249
+ 'Shaaban',
1250
+ 'Ramadan',
1251
+ 'Shawwal',
1252
+ 'Dhul-Qi’dah',
1253
+ 'Dhul-Hijjah'
1254
+ ]
1255
+ };
1256
+ function getGregorianMonthName(lang, month) {
1257
+ return MONTHS_GREGORIAN[lang][month - 1] || '';
1258
+ }
1259
+ function getHijriMonthName(lang, month) {
1260
+ return MONTHS_HIJRI[lang][month - 1] || '';
1261
+ }
1262
+ function getWeekdayName(lang, weekday) {
1263
+ return WEEKDAYS[lang][weekday - 1];
1264
+ }
1265
+
1266
+ class IslamicI18n extends NgbDatepickerI18n {
1267
+ getMonthShortName(month) {
1268
+ return MONTHS_HIJRI.ar[month - 1];
1378
1269
  }
1379
- ngOnInit() {
1380
- this.setDate(this.control?.value);
1270
+ getMonthFullName(month) {
1271
+ return MONTHS_HIJRI.ar[month - 1];
1381
1272
  }
1382
- setDate(value) {
1383
- if (!value)
1384
- return;
1385
- const jsDate = new Date(value);
1386
- if (isNaN(jsDate.getTime()))
1387
- return;
1388
- const ngbDate = {
1389
- year: jsDate.getFullYear(),
1390
- month: jsDate.getMonth() + 1,
1391
- day: jsDate.getDate()
1392
- };
1393
- // 🔥 Reuse existing logic
1394
- this.onSelectGregorian(ngbDate);
1273
+ getWeekdayLabel(weekday) {
1274
+ return WEEKDAYS.ar[weekday - 1];
1395
1275
  }
1396
- onDocumentClick(event) {
1397
- event.stopPropagation();
1398
- if (!this.calendarContainer)
1399
- return;
1400
- const clickedInside = this.calendarContainer.nativeElement.contains(event.target);
1401
- this.onClose.emit(!clickedInside);
1402
- if (!clickedInside) {
1403
- this.isShown = false;
1404
- }
1276
+ getWeekdayShortName(weekday) {
1277
+ return WEEKDAYS.ar[weekday - 1];
1405
1278
  }
1406
- structToNgbDate(d) {
1407
- return new NgbDate(d.year, d.month, d.day);
1279
+ getDayAriaLabel(date) {
1280
+ return `${date.day}-${date.month}-${date.year}`;
1408
1281
  }
1409
- onSelectGregorian(date) {
1410
- this.gregorianModel = date;
1411
- // Convert to NgbDate
1412
- const jsDate = new Date(date.year, date.month - 1, date.day);
1413
- // fromGregorian expects NgbDate or JS Date (depending on version)
1414
- const hijri = this.hijriCal.fromGregorian(jsDate);
1415
- const isoUTC = jsDate.toISOString();
1416
- this.gregorianUTCValue = this.withTime ? isoUTC : formatDate(jsDate, DateFormats.DATE_ONLY, 'en');
1417
- this.gregorianUTC.emit(this.gregorianUTCValue);
1418
- this.hijriModel = {
1419
- year: hijri.year,
1420
- month: hijri.month,
1421
- day: hijri.day
1422
- }; // datepicker
1423
- this.selectedDate = this.formatHijri(this.structToNgbDate(this.hijriModel)); //input
1424
- this.isShown = false;
1282
+ getYearNumerals(year) {
1283
+ return String(year);
1425
1284
  }
1426
- onSelectHijri(date) {
1427
- this.hijriModel = date;
1428
- const ngbDate = this.structToNgbDate(date);
1429
- const greg = this.hijriCal.toGregorian(ngbDate);
1430
- const isoUTC = greg.toISOString();
1431
- this.gregorianModel = {
1432
- year: greg.getFullYear(),
1433
- month: greg.getMonth() + 1,
1434
- day: greg.getDate()
1435
- };
1436
- const jsDate = new Date(this.gregorianModel.year, this.gregorianModel.month - 1, this.gregorianModel.day);
1437
- this.gregorianUTCValue = this.withTime ? isoUTC : formatDate(jsDate, DateFormats.DATE_ONLY, 'en');
1438
- this.gregorianUTC.emit(this.gregorianUTCValue);
1439
- this.selectedDate = this.formatHijri(ngbDate);
1440
- this.isShown = false;
1285
+ getWeekNumerals(weekNumber) {
1286
+ return String(weekNumber);
1441
1287
  }
1442
- showCalender(isOpen) {
1443
- this.isShown = isOpen;
1288
+ getDayNumerals(date) {
1289
+ return String(date.day);
1444
1290
  }
1445
- formatHijri(h) {
1446
- const hijriDay = h.day;
1447
- const hijriMonth = getHijriMonthName(this.currentLang(), h.month);
1448
- const hijriYear = h.year;
1449
- const greg = this.hijriCal.toGregorian(h);
1450
- const gregorianDay = greg.getDate();
1451
- const gregorianMonth = getGregorianMonthName(this.currentLang(), greg.getMonth() + 1);
1452
- const gregorianYear = greg.getFullYear();
1453
- return `${gregorianDay} ${gregorianMonth} ${gregorianYear} - ${hijriDay} ${hijriMonth} ${hijriYear}`;
1291
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: IslamicI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1292
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: IslamicI18n });
1293
+ }
1294
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: IslamicI18n, decorators: [{
1295
+ type: Injectable
1296
+ }] });
1297
+ class HijriEnglishI18n extends NgbDatepickerI18n {
1298
+ getMonthShortName(month) {
1299
+ return MONTHS_HIJRI.en[month - 1].substring(0, 3);
1454
1300
  }
1455
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DualCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1456
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DualCalendarComponent, isStandalone: true, selector: "app-dual-calendar", inputs: { control: "control", label: "label", name: "name", withTime: "withTime", isDatePickerShow: "isDatePickerShow", currentLang: "currentLang", isShown: "isShown" }, outputs: { gregorianUTC: "gregorianUTC", onClose: "onClose" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, providers: [
1457
- { provide: NgbCalendar, useClass: NgbCalendarIslamicUmalqura }
1458
- ], viewQueries: [{ propertyName: "calendarContainer", first: true, predicate: ["calendarContainer"], descendants: true }], ngImport: i0, template: "<div class=\"calender-content\" #calendarContainer>\r\n @if(isDatePickerShow) {\r\n <stc-date-picker-switcher [variant]=\"'in'\" [label]=\"label\" id=\"dateId\" (openCalender)=\"showCalender($event)\"\r\n [control]=\"control\" [formattedDate]='selectedDate' >\r\n </stc-date-picker-switcher>\r\n }\r\n\r\n <!-- calender.html -->\r\n <div [dir]=\"currentLang() === 'ar' ? 'rtl' : 'ltr'\" class=\"p-2 calendar-wrapper \" [@slideDown]=\"isShown ? 'open' : 'closed'\" >\r\n <div class=\"header-tabs\">\r\n <div class=\"header-label\">{{'calender.calender_type' | translate}}</div>\r\n <div class=\"tabs\">\r\n <button class=\"tab-button\" [class.active]=\"mode === 'gregorian'\" type=\"button\" (click)=\" mode='gregorian'\">\r\n {{'calender.gregorian' | translate}}\r\n </button>\r\n <button class=\"tab-button\" [class.active]=\"mode === 'hijri'\" type=\"button\" (click)=\" mode='hijri'\">\r\n {{'calender.hijri' | translate}}\r\n </button>\r\n </div>\r\n </div>\r\n @if(mode === 'gregorian') {\r\n <app-gregorian-calendar [model]=\"gregorianModel\" [language]=\"currentLang()\"\r\n (dateSelected)=\"onSelectGregorian($event)\">\r\n </app-gregorian-calendar>\r\n }\r\n\r\n @if(mode === 'hijri') {\r\n <app-hijri-calendar [model]=\"hijriModel\" [language]=\"currentLang()\" (dateSelected)=\"onSelectHijri($event)\">\r\n </app-hijri-calendar>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".calendar-wrapper{max-width:375px;padding:15px}.calendar-wrapper .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{margin:0 10px;max-width:20px}.calendar-wrapper .rtl .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{inset-inline-end:-6px;transform:rotate(180deg);margin:0 10px;max-width:20px}.calendar-wrapper .rtl .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-prev{inset-inline-end:22px;transform:rotate(180deg)}.calendar-wrapper .ltr .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{inset-inline-end:-4px}.calendar-wrapper .ltr .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-prev{inset-inline-end:11px}.header-tabs{display:flex;justify-content:space-between;align-items:center;gap:10px;margin-bottom:10px}.tabs{background:#f0f0f5;padding:3px;border-radius:2px}.tab-button{flex:1;padding:6px 10px;font-size:14px;background:#f0f0f5;border:none;border-radius:6px;cursor:pointer;transition:.3s}.tab-button.active{background:#dcd6f8;color:#4a3fb4;font-weight:600}.custom-datepicker{width:100%;background:#fff;border:1px solid #e5e5e5;border-radius:8px;padding:12px}.custom-datepicker .ngb-dp-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;max-width:375px}.custom-datepicker .ngb-dp-arrow-btn{background:none;border:none;cursor:pointer;padding:4px}.custom-datepicker .ngb-dp-weekdays{margin-bottom:6px}.custom-datepicker .ngb-dp-weekday{color:#9b9b9b;font-weight:600;text-align:center}.custom-day.today{border:1px solid #6a41d8;border-radius:8px}.custom-day.outside{opacity:.3}.custom-day.disabled{opacity:.2;pointer-events:none}.calender-content{position:relative}.calendar-wrapper{position:absolute;top:100%;left:0;z-index:50;box-shadow:0 2px 8px #00000026;background-color:#fff;border-radius:4px;overflow:hidden}.ngb-datepicker{width:100%}.custom-day{display:inline-flex;justify-content:center;align-items:center;margin:2px;border-radius:50%;cursor:pointer;font-weight:500}.custom-day.today{color:#4f008d;border:0!important}.ngb-dp-day:has(.selected){background-color:#ede6f4!important;border:0!important;color:#4f008d!important;border-radius:2px}.custom-day.outside{color:#ccc!important}.custom-day.disabled{color:#aaa!important;pointer-events:none!important}.ngb-dp-day,.ngb-dp-weekday,.ngb-dp-week-number{width:38px!important;height:44px!important;display:flex;margin:5px;justify-content:center;align-items:center}.ngb-dp-month:first-child .ngb-dp-week{padding:0!important}.ngb-dp-month:last-child .ngb-dp-week{padding:0!important}.ngb-dp-arrow-btn{margin-inline-end:0!important;outline:0!important;padding:0!important;margin:0!important}.ngb-dp-header{position:relative}.ngb-dp-header .ngb-dp-arrow{position:absolute}.ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-prev{inset-inline-end:0}.ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{inset-inline-end:15px}.ngb-dp-header .ngb-dp-arrow:focus-visible,.ngb-dp-header .ngb-dp-arrow .btn:focus-visible{outline:0!important}.ngb-dp-header .visually-hidden{display:none}.ngb-dp-navigation-select{max-width:140px}.ngb-dp-navigation-select select{border:0}.ngb-dp-navigation-select select:focus-visible{outline:0}.ngb-datepicker-navigation-select>.form-select{font-size:14px;font-weight:700}.ngb-dp-navigation-select,.form-select:first-child{appearance:none!important;-webkit-appearance:none;-moz-appearance:none}.ngb-dp-navigation-chevron{font-size:18px;border-width:.1em .1em 0 0!important;border-color:#000}\n"], dependencies: [{ kind: "ngmodule", type: NgbDatepickerModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: DatePickerModule }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: HijriCalendarComponent, selector: "app-hijri-calendar", inputs: ["model", "language"], outputs: ["dateSelected"] }, { kind: "component", type: DatePickerSwitcherComponent, selector: "stc-date-picker-switcher", inputs: ["type", "contentType", "size", "prefix", "rows", "cols", "autoResize", "basicInput", "noStyle", "hideOptionalLabel", "inputDirection", "variant", "defaultColor", "formattedDate"], outputs: ["openCalender"] }, { kind: "component", type: GregorianCalendarComponent, selector: "app-gregorian-calendar", inputs: ["model", "language"], outputs: ["dateSelected"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], animations: [
1459
- trigger('slideDown', [
1460
- state('closed', style({
1461
- height: '0px',
1462
- opacity: 0,
1463
- overflow: 'hidden'
1464
- })),
1465
- state('open', style({
1466
- height: '*',
1467
- opacity: 1,
1468
- overflow: 'hidden'
1469
- })),
1470
- transition('closed <=> open', [
1471
- animate('300ms ease')
1472
- ])
1473
- ])
1474
- ], encapsulation: i0.ViewEncapsulation.None });
1301
+ getMonthFullName(month) {
1302
+ return MONTHS_HIJRI.en[month - 1];
1303
+ }
1304
+ getWeekdayLabel(weekday) {
1305
+ return WEEKDAYS.en[weekday - 1];
1306
+ }
1307
+ getWeekdayShortName(weekday) {
1308
+ return WEEKDAYS.en[weekday - 1];
1309
+ }
1310
+ getDayAriaLabel(date) {
1311
+ return `${date.day}-${date.month}-${date.year}`;
1312
+ }
1313
+ getYearNumerals(year) {
1314
+ return String(year);
1315
+ }
1316
+ getWeekNumerals(weekNumber) {
1317
+ return String(weekNumber);
1318
+ }
1319
+ getDayNumerals(date) {
1320
+ return String(date.day);
1321
+ }
1322
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriEnglishI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1323
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriEnglishI18n });
1475
1324
  }
1476
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DualCalendarComponent, decorators: [{
1477
- type: Component,
1478
- args: [{ selector: 'app-dual-calendar', animations: [
1479
- trigger('slideDown', [
1480
- state('closed', style({
1481
- height: '0px',
1482
- opacity: 0,
1483
- overflow: 'hidden'
1484
- })),
1485
- state('open', style({
1486
- height: '*',
1487
- opacity: 1,
1488
- overflow: 'hidden'
1489
- })),
1490
- transition('closed <=> open', [
1491
- animate('300ms ease')
1492
- ])
1493
- ])
1494
- ], imports: [
1495
- NgbDatepickerModule,
1496
- FormsModule,
1497
- FormsModule,
1498
- ReactiveFormsModule,
1499
- DatePickerModule,
1500
- FloatLabelModule,
1501
- HijriCalendarComponent,
1502
- DatePickerSwitcherComponent,
1503
- TranslatePipe,
1504
- GregorianCalendarComponent
1505
- ], providers: [
1506
- { provide: NgbCalendar, useClass: NgbCalendarIslamicUmalqura }
1507
- ], encapsulation: ViewEncapsulation.None, template: "<div class=\"calender-content\" #calendarContainer>\r\n @if(isDatePickerShow) {\r\n <stc-date-picker-switcher [variant]=\"'in'\" [label]=\"label\" id=\"dateId\" (openCalender)=\"showCalender($event)\"\r\n [control]=\"control\" [formattedDate]='selectedDate' >\r\n </stc-date-picker-switcher>\r\n }\r\n\r\n <!-- calender.html -->\r\n <div [dir]=\"currentLang() === 'ar' ? 'rtl' : 'ltr'\" class=\"p-2 calendar-wrapper \" [@slideDown]=\"isShown ? 'open' : 'closed'\" >\r\n <div class=\"header-tabs\">\r\n <div class=\"header-label\">{{'calender.calender_type' | translate}}</div>\r\n <div class=\"tabs\">\r\n <button class=\"tab-button\" [class.active]=\"mode === 'gregorian'\" type=\"button\" (click)=\" mode='gregorian'\">\r\n {{'calender.gregorian' | translate}}\r\n </button>\r\n <button class=\"tab-button\" [class.active]=\"mode === 'hijri'\" type=\"button\" (click)=\" mode='hijri'\">\r\n {{'calender.hijri' | translate}}\r\n </button>\r\n </div>\r\n </div>\r\n @if(mode === 'gregorian') {\r\n <app-gregorian-calendar [model]=\"gregorianModel\" [language]=\"currentLang()\"\r\n (dateSelected)=\"onSelectGregorian($event)\">\r\n </app-gregorian-calendar>\r\n }\r\n\r\n @if(mode === 'hijri') {\r\n <app-hijri-calendar [model]=\"hijriModel\" [language]=\"currentLang()\" (dateSelected)=\"onSelectHijri($event)\">\r\n </app-hijri-calendar>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".calendar-wrapper{max-width:375px;padding:15px}.calendar-wrapper .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{margin:0 10px;max-width:20px}.calendar-wrapper .rtl .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{inset-inline-end:-6px;transform:rotate(180deg);margin:0 10px;max-width:20px}.calendar-wrapper .rtl .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-prev{inset-inline-end:22px;transform:rotate(180deg)}.calendar-wrapper .ltr .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{inset-inline-end:-4px}.calendar-wrapper .ltr .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-prev{inset-inline-end:11px}.header-tabs{display:flex;justify-content:space-between;align-items:center;gap:10px;margin-bottom:10px}.tabs{background:#f0f0f5;padding:3px;border-radius:2px}.tab-button{flex:1;padding:6px 10px;font-size:14px;background:#f0f0f5;border:none;border-radius:6px;cursor:pointer;transition:.3s}.tab-button.active{background:#dcd6f8;color:#4a3fb4;font-weight:600}.custom-datepicker{width:100%;background:#fff;border:1px solid #e5e5e5;border-radius:8px;padding:12px}.custom-datepicker .ngb-dp-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;max-width:375px}.custom-datepicker .ngb-dp-arrow-btn{background:none;border:none;cursor:pointer;padding:4px}.custom-datepicker .ngb-dp-weekdays{margin-bottom:6px}.custom-datepicker .ngb-dp-weekday{color:#9b9b9b;font-weight:600;text-align:center}.custom-day.today{border:1px solid #6a41d8;border-radius:8px}.custom-day.outside{opacity:.3}.custom-day.disabled{opacity:.2;pointer-events:none}.calender-content{position:relative}.calendar-wrapper{position:absolute;top:100%;left:0;z-index:50;box-shadow:0 2px 8px #00000026;background-color:#fff;border-radius:4px;overflow:hidden}.ngb-datepicker{width:100%}.custom-day{display:inline-flex;justify-content:center;align-items:center;margin:2px;border-radius:50%;cursor:pointer;font-weight:500}.custom-day.today{color:#4f008d;border:0!important}.ngb-dp-day:has(.selected){background-color:#ede6f4!important;border:0!important;color:#4f008d!important;border-radius:2px}.custom-day.outside{color:#ccc!important}.custom-day.disabled{color:#aaa!important;pointer-events:none!important}.ngb-dp-day,.ngb-dp-weekday,.ngb-dp-week-number{width:38px!important;height:44px!important;display:flex;margin:5px;justify-content:center;align-items:center}.ngb-dp-month:first-child .ngb-dp-week{padding:0!important}.ngb-dp-month:last-child .ngb-dp-week{padding:0!important}.ngb-dp-arrow-btn{margin-inline-end:0!important;outline:0!important;padding:0!important;margin:0!important}.ngb-dp-header{position:relative}.ngb-dp-header .ngb-dp-arrow{position:absolute}.ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-prev{inset-inline-end:0}.ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{inset-inline-end:15px}.ngb-dp-header .ngb-dp-arrow:focus-visible,.ngb-dp-header .ngb-dp-arrow .btn:focus-visible{outline:0!important}.ngb-dp-header .visually-hidden{display:none}.ngb-dp-navigation-select{max-width:140px}.ngb-dp-navigation-select select{border:0}.ngb-dp-navigation-select select:focus-visible{outline:0}.ngb-datepicker-navigation-select>.form-select{font-size:14px;font-weight:700}.ngb-dp-navigation-select,.form-select:first-child{appearance:none!important;-webkit-appearance:none;-moz-appearance:none}.ngb-dp-navigation-chevron{font-size:18px;border-width:.1em .1em 0 0!important;border-color:#000}\n"] }]
1508
- }], ctorParameters: () => [], propDecorators: { control: [{
1509
- type: Input
1510
- }], label: [{
1511
- type: Input
1512
- }], name: [{
1513
- type: Input
1514
- }], withTime: [{
1515
- type: Input
1516
- }], isDatePickerShow: [{
1517
- type: Input
1518
- }], currentLang: [{
1325
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriEnglishI18n, decorators: [{
1326
+ type: Injectable
1327
+ }] });
1328
+ class DynamicHijriI18n extends NgbDatepickerI18n {
1329
+ currentLang = 'ar';
1330
+ arabicI18n = new IslamicI18n();
1331
+ englishI18n = new HijriEnglishI18n();
1332
+ setLanguage(lang) {
1333
+ this.currentLang = lang;
1334
+ }
1335
+ get activeI18n() {
1336
+ return this.currentLang === 'ar' ? this.arabicI18n : this.englishI18n;
1337
+ }
1338
+ getMonthShortName(month) {
1339
+ return this.activeI18n.getMonthShortName(month);
1340
+ }
1341
+ getMonthFullName(month) {
1342
+ return this.activeI18n.getMonthFullName(month);
1343
+ }
1344
+ getWeekdayLabel(weekday) {
1345
+ return this.activeI18n.getWeekdayLabel(weekday);
1346
+ }
1347
+ getWeekdayShortName(weekday) {
1348
+ return this.activeI18n.getWeekdayShortName(weekday);
1349
+ }
1350
+ getDayAriaLabel(date) {
1351
+ return this.activeI18n.getDayAriaLabel(date);
1352
+ }
1353
+ getYearNumerals(year) {
1354
+ return this.activeI18n.getYearNumerals(year);
1355
+ }
1356
+ getWeekNumerals(weekNumber) {
1357
+ return this.activeI18n.getWeekNumerals(weekNumber);
1358
+ }
1359
+ getDayNumerals(date) {
1360
+ return this.activeI18n.getDayNumerals(date);
1361
+ }
1362
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicHijriI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1363
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicHijriI18n });
1364
+ }
1365
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicHijriI18n, decorators: [{
1366
+ type: Injectable
1367
+ }] });
1368
+
1369
+ class HijriCalendarComponent {
1370
+ i18n;
1371
+ cdr;
1372
+ model;
1373
+ dateSelected = new EventEmitter();
1374
+ language = 'en';
1375
+ renderer = inject(Renderer2);
1376
+ startDate;
1377
+ calendar = new NgbCalendarIslamicUmalqura();
1378
+ constructor(i18n, cdr) {
1379
+ this.i18n = i18n;
1380
+ this.cdr = cdr;
1381
+ }
1382
+ ngOnChanges(changes) {
1383
+ if (changes['model'] && changes['model'].currentValue) {
1384
+ this.startDate = { ...changes['model'].currentValue };
1385
+ console.log('Hijri navigating to:', this.startDate);
1386
+ }
1387
+ if (changes['language'] && this.i18n instanceof DynamicHijriI18n) {
1388
+ this.i18n.setLanguage(this.language);
1389
+ this.cdr.detectChanges(); // Force re-render to update labels
1390
+ }
1391
+ }
1392
+ ngAfterViewInit() {
1393
+ const buttons = document.querySelectorAll('.ngb-dp-arrow-btn');
1394
+ buttons.forEach(btn => {
1395
+ this.renderer.removeAttribute(btn, 'title');
1396
+ });
1397
+ }
1398
+ onDateChange(date) {
1399
+ this.model = date;
1400
+ this.startDate = { ...date };
1401
+ }
1402
+ isToday(date) {
1403
+ const today = this.calendar.getToday();
1404
+ return date.year === today.year &&
1405
+ date.month === today.month &&
1406
+ date.day === today.day;
1407
+ }
1408
+ isDisabled = () => false;
1409
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriCalendarComponent, deps: [{ token: i1$6.NgbDatepickerI18n }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1410
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: HijriCalendarComponent, isStandalone: true, selector: "app-hijri-calendar", inputs: { model: "model", language: "language" }, outputs: { dateSelected: "dateSelected" }, providers: [
1411
+ { provide: NgbCalendar, useClass: NgbCalendarIslamicUmalqura },
1412
+ { provide: NgbDatepickerI18n, useClass: DynamicHijriI18n }
1413
+ ], usesOnChanges: true, ngImport: i0, template: "<ngb-datepicker #dp [class.rtl]=\"language === 'ar'\" [class.ltr]=\"language === 'en'\" [ngModel]=\"model\"\r\n [startDate]=\"startDate\" (ngModelChange)=\"onDateChange($event)\" (dateSelect)=\"dateSelected.emit($event)\"\r\n [dayTemplate]=\"dayTemplate\" [markDisabled]=\"isDisabled\">\r\n</ngb-datepicker>\r\n<ng-template #dayTemplate let-date let-currentMonth=\"currentMonth\" let-selected=\"selected\" let-disabled=\"disabled\">\r\n <span class=\"custom-day\" [class.today]=\"isToday(date)\" [class.selected]=\"selected\"\r\n [class.outside]=\"date.month !== currentMonth\" [class.disabled]=\"disabled\">\r\n {{ date.day }}\r\n </span>\r\n</ng-template>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: NgbDatepickerModule }, { kind: "component", type: i1$6.NgbDatepicker, selector: "ngb-datepicker", inputs: ["contentTemplate", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "maxDate", "minDate", "navigation", "outsideDays", "showWeekNumbers", "startDate", "weekdays"], outputs: ["navigate", "dateSelect"], exportAs: ["ngbDatepicker"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
1414
+ }
1415
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriCalendarComponent, decorators: [{
1416
+ type: Component,
1417
+ args: [{ selector: "app-hijri-calendar", standalone: true, imports: [NgbDatepickerModule, FormsModule], providers: [
1418
+ { provide: NgbCalendar, useClass: NgbCalendarIslamicUmalqura },
1419
+ { provide: NgbDatepickerI18n, useClass: DynamicHijriI18n }
1420
+ ], template: "<ngb-datepicker #dp [class.rtl]=\"language === 'ar'\" [class.ltr]=\"language === 'en'\" [ngModel]=\"model\"\r\n [startDate]=\"startDate\" (ngModelChange)=\"onDateChange($event)\" (dateSelect)=\"dateSelected.emit($event)\"\r\n [dayTemplate]=\"dayTemplate\" [markDisabled]=\"isDisabled\">\r\n</ngb-datepicker>\r\n<ng-template #dayTemplate let-date let-currentMonth=\"currentMonth\" let-selected=\"selected\" let-disabled=\"disabled\">\r\n <span class=\"custom-day\" [class.today]=\"isToday(date)\" [class.selected]=\"selected\"\r\n [class.outside]=\"date.month !== currentMonth\" [class.disabled]=\"disabled\">\r\n {{ date.day }}\r\n </span>\r\n</ng-template>\r\n" }]
1421
+ }], ctorParameters: () => [{ type: i1$6.NgbDatepickerI18n }, { type: i0.ChangeDetectorRef }], propDecorators: { model: [{
1519
1422
  type: Input
1520
- }], gregorianUTC: [{
1521
- type: Output
1522
- }], onClose: [{
1423
+ }], dateSelected: [{
1523
1424
  type: Output
1524
- }], isShown: [{
1425
+ }], language: [{
1525
1426
  type: Input
1526
- }], calendarContainer: [{
1527
- type: ViewChild,
1528
- args: ['calendarContainer']
1529
- }], onDocumentClick: [{
1530
- type: HostListener,
1531
- args: ['document:click', ['$event']]
1532
1427
  }] } });
1533
1428
 
1534
- /**
1535
- * Transforms file size from bytes to readable format (B, KB, MB, GB, TB).
1536
- *
1537
- * Usage:
1538
- * {{ fileSize | fileSize }} // Default: auto unit, 2 decimals
1539
- * {{ fileSize | fileSize:0 }} // Auto unit, 0 decimals
1540
- * {{ fileSize | fileSize:2:'MB' }} // Force MB, 2 decimals
1541
- *
1542
- * @param value - File size in bytes
1543
- * @param decimals - Number of decimal places (default: 2)
1544
- * @param unit - Unit: 'B', 'KB', 'MB', 'GB', 'TB' (default: auto)
1545
- */
1546
- class FileSizePipe {
1547
- units = ['B', 'KB', 'MB', 'GB', 'TB'];
1548
- k = 1024;
1549
- transform(bytes, decimals = 2, unit) {
1550
- if (bytes === null || bytes === undefined || isNaN(bytes)) {
1551
- return '0 B';
1552
- }
1553
- if (bytes === 0) {
1554
- return '0 B';
1555
- }
1556
- // If a specific unit is requested
1557
- if (unit) {
1558
- const unitIndex = this.units.indexOf(unit);
1559
- if (unitIndex === -1) {
1560
- return this.autoFormat(bytes, decimals);
1561
- }
1562
- const divisor = Math.pow(this.k, unitIndex);
1563
- const value = bytes / divisor;
1564
- return `${this.formatNumber(value, decimals)} ${unit}`;
1565
- }
1566
- // Auto-detect the best unit
1567
- return this.autoFormat(bytes, decimals);
1429
+ class GregorianArabicI18n extends NgbDatepickerI18n {
1430
+ getMonthShortName(month) {
1431
+ return MONTHS_GREGORIAN.ar[month - 1];
1568
1432
  }
1569
- autoFormat(bytes, decimals) {
1570
- const i = Math.floor(Math.log(Math.abs(bytes)) / Math.log(this.k));
1571
- const unitIndex = Math.min(i, this.units.length - 1);
1572
- const value = bytes / Math.pow(this.k, unitIndex);
1573
- return `${this.formatNumber(value, decimals)} ${this.units[unitIndex]}`;
1433
+ getMonthFullName(month) {
1434
+ return MONTHS_GREGORIAN.ar[month - 1];
1574
1435
  }
1575
- formatNumber(value, decimals) {
1576
- return parseFloat(value.toFixed(decimals)).toString();
1436
+ getWeekdayLabel(weekday) {
1437
+ return WEEKDAYS.ar[weekday - 1];
1577
1438
  }
1578
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FileSizePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1579
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: FileSizePipe, isStandalone: true, name: "fileSize" });
1439
+ getWeekdayShortName(weekday) {
1440
+ return WEEKDAYS.ar[weekday - 1];
1441
+ }
1442
+ getDayAriaLabel(date) {
1443
+ return `${date.day}-${date.month}-${date.year}`;
1444
+ }
1445
+ getYearNumerals(year) {
1446
+ return String(year);
1447
+ }
1448
+ getWeekNumerals(weekNumber) {
1449
+ return String(weekNumber);
1450
+ }
1451
+ getDayNumerals(date) {
1452
+ return String(date.day);
1453
+ }
1454
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianArabicI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1455
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianArabicI18n });
1580
1456
  }
1581
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FileSizePipe, decorators: [{
1582
- type: Pipe,
1583
- args: [{
1584
- name: 'fileSize',
1585
- standalone: true,
1586
- }]
1457
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianArabicI18n, decorators: [{
1458
+ type: Injectable
1587
1459
  }] });
1588
-
1589
- var UploadStatus;
1590
- (function (UploadStatus) {
1591
- UploadStatus["PENDING"] = "pending";
1592
- UploadStatus["SUCCESS"] = "success";
1593
- UploadStatus["UPLOADING"] = "uploading";
1594
- UploadStatus["FAILED"] = "failed";
1595
- })(UploadStatus || (UploadStatus = {}));
1596
-
1597
- class FileManagementComponent extends BaseInputComponent {
1598
- // Inputs
1599
- existingFiles = input([], ...(ngDevMode ? [{ debugName: "existingFiles" }] : []));
1600
- acceptedTypes = input('*', ...(ngDevMode ? [{ debugName: "acceptedTypes" }] : []));
1601
- maxFileSize = input(10485760, ...(ngDevMode ? [{ debugName: "maxFileSize" }] : [])); //250 MB
1602
- maxConcurrentUploads = input(3, ...(ngDevMode ? [{ debugName: "maxConcurrentUploads" }] : []));
1603
- showTable = input(true, ...(ngDevMode ? [{ debugName: "showTable" }] : []));
1604
- showDropZone = input(true, ...(ngDevMode ? [{ debugName: "showDropZone" }] : []));
1605
- allowPreview = input(true, ...(ngDevMode ? [{ debugName: "allowPreview" }] : []));
1606
- permissonKey = input('', ...(ngDevMode ? [{ debugName: "permissonKey" }] : []));
1607
- allowedActions = input([], ...(ngDevMode ? [{ debugName: "allowedActions" }] : []));
1608
- uploadedFile = signal([], ...(ngDevMode ? [{ debugName: "uploadedFile" }] : []));
1609
- // Outputs
1610
- filesUploaded = new EventEmitter();
1611
- fileDeleted = new EventEmitter();
1612
- filePreview = new EventEmitter();
1613
- fileDownload = new EventEmitter();
1614
- uploadError = new EventEmitter();
1615
- newFilesChange = new EventEmitter();
1616
- fileInput;
1617
- // State - separate new uploads from existing files
1618
- isDragOver = signal(false, ...(ngDevMode ? [{ debugName: "isDragOver" }] : []));
1619
- newFiles = signal([], ...(ngDevMode ? [{ debugName: "newFiles" }] : [])); // Files being uploaded or newly uploaded
1620
- uploadedResponses = [];
1621
- // Combined files list for the table (existing + new)
1622
- allFiles = computed(() => {
1623
- const existing = this.existingFiles().map((f) => ({
1624
- ...f,
1625
- status: undefined, // Don't show status for existing files
1626
- isNew: false,
1627
- }));
1628
- const newOnes = this.newFiles();
1629
- return [...newOnes, ...existing];
1630
- }, ...(ngDevMode ? [{ debugName: "allFiles" }] : []));
1631
- // Get only successfully uploaded new file IDs
1632
- uploadedNewFileIds = computed(() => {
1633
- return this.newFiles()
1634
- .filter((f) => f.status === UploadStatus.SUCCESS && f.id && !f.id.startsWith('temp-'))
1635
- .map((f) => f.id);
1636
- }, ...(ngDevMode ? [{ debugName: "uploadedNewFileIds" }] : []));
1637
- // Formatted accepted file types for display
1638
- formattedAcceptedTypes = computed(() => {
1639
- const accepted = this.acceptedTypes();
1640
- if (accepted === '*' || accepted === '*/*')
1641
- return '';
1642
- return accepted
1643
- .split(',')
1644
- .map((type) => type.trim().replace('.', '').toUpperCase())
1645
- .join(', ');
1646
- }, ...(ngDevMode ? [{ debugName: "formattedAcceptedTypes" }] : []));
1647
- // Table configuration
1648
- // Drag & Drop handlers
1649
- onDragOver(event) {
1650
- event.preventDefault();
1651
- event.stopPropagation();
1652
- this.isDragOver.set(true);
1460
+ class GregorianEnglishI18n extends NgbDatepickerI18n {
1461
+ getMonthShortName(month) {
1462
+ return MONTHS_GREGORIAN.en[month - 1].substring(0, 3);
1653
1463
  }
1654
- onDragLeave(event) {
1655
- event.preventDefault();
1656
- event.stopPropagation();
1657
- this.isDragOver.set(false);
1464
+ getMonthFullName(month) {
1465
+ return MONTHS_GREGORIAN.en[month - 1];
1658
1466
  }
1659
- onDrop(event) {
1660
- event.preventDefault();
1661
- event.stopPropagation();
1662
- this.isDragOver.set(false);
1663
- const droppedFiles = event.dataTransfer?.files;
1664
- if (droppedFiles) {
1665
- this.handleFiles(Array.from(droppedFiles));
1666
- }
1467
+ getWeekdayLabel(weekday) {
1468
+ return WEEKDAYS.en[weekday - 1];
1667
1469
  }
1668
- // Browse button handler
1669
- onBrowseClick() {
1670
- this.fileInput.nativeElement.click();
1470
+ getWeekdayShortName(weekday) {
1471
+ return WEEKDAYS.en[weekday - 1];
1671
1472
  }
1672
- onFileInputChange(event) {
1673
- const input = event.target;
1674
- if (input.files) {
1675
- this.handleFiles(Array.from(input.files));
1676
- // Reset input to allow selecting the same file again
1677
- input.value = '';
1678
- }
1473
+ getDayAriaLabel(date) {
1474
+ return `${date.day}-${date.month}-${date.year}`;
1475
+ }
1476
+ getYearNumerals(year) {
1477
+ return String(year);
1478
+ }
1479
+ getWeekNumerals(weekNumber) {
1480
+ return String(weekNumber);
1481
+ }
1482
+ getDayNumerals(date) {
1483
+ return String(date.day);
1484
+ }
1485
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianEnglishI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1486
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianEnglishI18n });
1487
+ }
1488
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianEnglishI18n, decorators: [{
1489
+ type: Injectable
1490
+ }] });
1491
+ // ============ Dynamic I18N Factory ============
1492
+ class DynamicGregorianI18n extends NgbDatepickerI18n {
1493
+ currentLang = 'en';
1494
+ arabicI18n = new GregorianArabicI18n();
1495
+ englishI18n = new GregorianEnglishI18n();
1496
+ setLanguage(lang) {
1497
+ this.currentLang = lang;
1498
+ }
1499
+ get activeI18n() {
1500
+ return this.currentLang === 'ar' ? this.arabicI18n : this.englishI18n;
1501
+ }
1502
+ getMonthShortName(month) {
1503
+ return this.activeI18n.getMonthShortName(month);
1504
+ }
1505
+ getMonthFullName(month) {
1506
+ return this.activeI18n.getMonthFullName(month);
1507
+ }
1508
+ getWeekdayLabel(weekday) {
1509
+ return this.activeI18n.getWeekdayLabel(weekday);
1510
+ }
1511
+ getWeekdayShortName(weekday) {
1512
+ return this.activeI18n.getWeekdayShortName(weekday);
1513
+ }
1514
+ getDayAriaLabel(date) {
1515
+ return this.activeI18n.getDayAriaLabel(date);
1516
+ }
1517
+ getYearNumerals(year) {
1518
+ return this.activeI18n.getYearNumerals(year);
1679
1519
  }
1680
- // Public method to trigger file selection from parent
1681
- triggerFileInput() {
1682
- this.fileInput?.nativeElement?.click();
1520
+ getWeekNumerals(weekNumber) {
1521
+ return this.activeI18n.getWeekNumerals(weekNumber);
1683
1522
  }
1684
- // Public method to append file selection from parent
1685
- appendFileFromParent(file) {
1686
- this.handleFiles([file]);
1523
+ getDayNumerals(date) {
1524
+ return this.activeI18n.getDayNumerals(date);
1687
1525
  }
1688
- // Public method to upload files programmatically from parent
1689
- uploadFilesFromParent(files) {
1690
- this.handleFiles(files);
1526
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicGregorianI18n, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1527
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicGregorianI18n });
1528
+ }
1529
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicGregorianI18n, decorators: [{
1530
+ type: Injectable
1531
+ }] });
1532
+
1533
+ class GregorianCalendarComponent {
1534
+ model;
1535
+ dateSelected = new EventEmitter();
1536
+ renderer = inject(Renderer2);
1537
+ language = 'en';
1538
+ startDate;
1539
+ calendar = new NgbCalendarGregorian();
1540
+ i18n = inject(NgbDatepickerI18n);
1541
+ cdr = inject(ChangeDetectorRef);
1542
+ calendarKey = 0;
1543
+ ngOnChanges(changes) {
1544
+ if (changes['model'] && changes['model'].currentValue) {
1545
+ this.startDate = { ...changes['model'].currentValue };
1546
+ }
1547
+ if (changes['language'] && this.i18n instanceof DynamicGregorianI18n) {
1548
+ this.i18n.setLanguage(this.language);
1549
+ this.calendarKey++; // Increment to force recreation
1550
+ }
1691
1551
  }
1692
- // Public method to get new uploaded file IDs
1693
- getUploadedFileIds() {
1694
- return this.uploadedNewFileIds();
1552
+ ngAfterViewInit() {
1553
+ const buttons = document.querySelectorAll('.ngb-dp-arrow-btn');
1554
+ buttons.forEach(btn => {
1555
+ this.renderer.removeAttribute(btn, 'title');
1556
+ });
1695
1557
  }
1696
- // Public method to clear new files (after save)
1697
- clearNewFiles() {
1698
- this.newFiles.set([]);
1699
- this.uploadedResponses = [];
1558
+ onDateChange(date) {
1559
+ this.model = date;
1560
+ this.startDate = { ...date };
1700
1561
  }
1701
- // Public method to remove a new file by ID
1702
- removeNewFile(fileId) {
1703
- this.newFiles.update((files) => files.filter((f) => f.id !== fileId));
1562
+ isToday(date) {
1563
+ const today = this.calendar.getToday();
1564
+ return date.year === today.year &&
1565
+ date.month === today.month &&
1566
+ date.day === today.day;
1704
1567
  }
1705
- // Check if there are pending/uploading files
1706
- // File handling
1707
- handleFiles(filesToProcess) {
1708
- const validFiles = [];
1709
- for (const file of filesToProcess) {
1710
- // Validate file size
1711
- if (file.size > this.maxFileSize()) {
1712
- this.uploadError.emit({
1713
- file,
1714
- error: `File ${file.name} exceeds maximum size of ${this.formatFileSize(this.maxFileSize())}`,
1715
- });
1716
- continue;
1717
- }
1718
- // Validate file type
1719
- // if (!this.isValidFileType(file)) {
1720
- // this.uploadError.emit({
1721
- // file,
1722
- // error: `File type not allowed: ${file.type}`,
1723
- // });
1724
- // continue;
1725
- // }
1726
- validFiles.push(file);
1727
- }
1728
- if (validFiles.length > 0) {
1729
- // this.uploadFiles(validFiles);
1730
- this.uploadedFile.set(validFiles);
1731
- this.filesUploaded.emit(validFiles);
1732
- console.log('uploadedFile', this.uploadedFile());
1568
+ isDisabled = () => false;
1569
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1570
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: GregorianCalendarComponent, isStandalone: true, selector: "app-gregorian-calendar", inputs: { model: "model", language: "language" }, outputs: { dateSelected: "dateSelected" }, providers: [
1571
+ { provide: NgbCalendar, useClass: NgbCalendarGregorian },
1572
+ { provide: NgbDatepickerI18n, useClass: DynamicGregorianI18n }
1573
+ ], usesOnChanges: true, ngImport: i0, template: "@for(item of [calendarKey]; track item) {\r\n <ngb-datepicker #dp\r\n [class.rtl]=\"language === 'ar'\"\r\n [class.ltr]=\"language === 'en'\"\r\n [ngModel]=\"model\"\r\n [startDate]=\"startDate\"\r\n (ngModelChange)=\"onDateChange($event)\"\r\n (dateSelect)=\"dateSelected.emit($event)\"\r\n [dayTemplate]=\"dayTemplate\"\r\n [markDisabled]=\"isDisabled\">\r\n </ngb-datepicker>\r\n <ng-template #dayTemplate let-date let-currentMonth=\"currentMonth\" let-selected=\"selected\" let-disabled=\"disabled\">\r\n <span class=\"custom-day\"\r\n [class.today]=\"isToday(date)\"\r\n [class.selected]=\"selected\"\r\n [class.outside]=\"date.month !== currentMonth\"\r\n [class.disabled]=\"disabled\">\r\n {{ date.day }}\r\n </span>\r\n </ng-template>\r\n}\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: NgbDatepickerModule }, { kind: "component", type: i1$6.NgbDatepicker, selector: "ngb-datepicker", inputs: ["contentTemplate", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "maxDate", "minDate", "navigation", "outsideDays", "showWeekNumbers", "startDate", "weekdays"], outputs: ["navigate", "dateSelect"], exportAs: ["ngbDatepicker"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], encapsulation: i0.ViewEncapsulation.None });
1574
+ }
1575
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: GregorianCalendarComponent, decorators: [{
1576
+ type: Component,
1577
+ args: [{ selector: "app-gregorian-calendar", standalone: true, imports: [NgbDatepickerModule, FormsModule], providers: [
1578
+ { provide: NgbCalendar, useClass: NgbCalendarGregorian },
1579
+ { provide: NgbDatepickerI18n, useClass: DynamicGregorianI18n }
1580
+ ], encapsulation: ViewEncapsulation.None, template: "@for(item of [calendarKey]; track item) {\r\n <ngb-datepicker #dp\r\n [class.rtl]=\"language === 'ar'\"\r\n [class.ltr]=\"language === 'en'\"\r\n [ngModel]=\"model\"\r\n [startDate]=\"startDate\"\r\n (ngModelChange)=\"onDateChange($event)\"\r\n (dateSelect)=\"dateSelected.emit($event)\"\r\n [dayTemplate]=\"dayTemplate\"\r\n [markDisabled]=\"isDisabled\">\r\n </ngb-datepicker>\r\n <ng-template #dayTemplate let-date let-currentMonth=\"currentMonth\" let-selected=\"selected\" let-disabled=\"disabled\">\r\n <span class=\"custom-day\"\r\n [class.today]=\"isToday(date)\"\r\n [class.selected]=\"selected\"\r\n [class.outside]=\"date.month !== currentMonth\"\r\n [class.disabled]=\"disabled\">\r\n {{ date.day }}\r\n </span>\r\n </ng-template>\r\n}\r\n" }]
1581
+ }], propDecorators: { model: [{
1582
+ type: Input
1583
+ }], dateSelected: [{
1584
+ type: Output
1585
+ }], language: [{
1586
+ type: Input
1587
+ }] } });
1588
+
1589
+ class DatePickerSwitcherComponent extends BaseInputComponent {
1590
+ type = 'text';
1591
+ contentType = 'text';
1592
+ size = "small";
1593
+ prefix;
1594
+ rows = 2;
1595
+ cols = 20;
1596
+ autoResize = true;
1597
+ basicInput;
1598
+ noStyle;
1599
+ hideOptionalLabel;
1600
+ inputDirection = 'inherit';
1601
+ variant = 'over';
1602
+ defaultColor = '#DFE0E6';
1603
+ formattedDate = '';
1604
+ openCalender = new EventEmitter();
1605
+ constructor() {
1606
+ super();
1607
+ }
1608
+ ngOnChanges(changes) {
1609
+ if (changes['formattedDate'] && changes['formattedDate'].currentValue) {
1610
+ // Update the FormControl value if parent changes the formattedDate
1611
+ this.control.setValue(changes['formattedDate'].currentValue, { emitEvent: false });
1733
1612
  }
1734
1613
  }
1735
- deleteFile() {
1736
- this.uploadedFile.set([]);
1737
- this.filesUploaded.emit([]);
1614
+ ngOnInit() {
1615
+ this.control.setValue(this.formattedDate);
1738
1616
  }
1739
- isValidFileType(file) {
1740
- const accepted = this.acceptedTypes();
1741
- if (accepted === '*' || accepted === '*/*')
1742
- return true;
1743
- const acceptedTypes = accepted.split(',').map((t) => t.trim().toLowerCase());
1744
- const fileType = file.type.toLowerCase();
1745
- const fileExt = '.' + file.name.split('.').pop()?.toLowerCase();
1746
- return acceptedTypes.some((type) => {
1747
- if (type.startsWith('.')) {
1748
- return fileExt === type;
1749
- }
1750
- if (type.endsWith('/*')) {
1751
- return fileType.startsWith(type.replace('/*', '/'));
1752
- }
1753
- return fileType === type;
1754
- });
1617
+ clearButtonClick(e) {
1618
+ this.control.setValue(null);
1755
1619
  }
1756
- updateFileFromAttachment(attachment) {
1757
- this.newFiles.update((currentFiles) => {
1758
- return currentFiles.map((file) => {
1759
- // Match by file name and size
1760
- if (file.fileName === attachment.nameFile && file.size === attachment.size) {
1761
- const updatedFile = {
1762
- ...file,
1763
- progress: attachment.status?.percentage ?? 0,
1764
- error: attachment.errorMessage,
1765
- };
1766
- // If upload succeeded, update with response data from serverResponse
1767
- if (attachment.uploadStatus === UploadStatus.SUCCESS && attachment.serverResponse) {
1768
- const serverData = attachment.serverResponse;
1769
- const responseFile = {
1770
- id: attachment.id || serverData?.id || file.id,
1771
- fileName: serverData?.fileName || attachment.nameFile,
1772
- size: serverData?.size || attachment.size,
1773
- mimeType: serverData?.mimeType || file.mimeType,
1774
- };
1775
- this.uploadedResponses.push(responseFile);
1776
- return {
1777
- ...updatedFile,
1778
- id: responseFile.id,
1779
- };
1780
- }
1781
- return updatedFile;
1782
- }
1783
- return file;
1784
- });
1620
+ openCalendar(isOpen) {
1621
+ this.openCalender.emit(isOpen);
1622
+ }
1623
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatePickerSwitcherComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1624
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DatePickerSwitcherComponent, isStandalone: true, selector: "stc-date-picker-switcher", inputs: { type: "type", contentType: "contentType", size: "size", prefix: "prefix", rows: "rows", cols: "cols", autoResize: "autoResize", basicInput: "basicInput", noStyle: "noStyle", hideOptionalLabel: "hideOptionalLabel", inputDirection: "inputDirection", variant: "variant", defaultColor: "defaultColor", formattedDate: "formattedDate" }, outputs: { openCalender: "openCalender" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n <p-floatlabel [variant]=\"variant\">\r\n <input [id]=\"inputId\" [type]=\"'text-float-label'\" [formControl]=\"control\" [readonly]=\"true\" (focus)=\"openCalendar(true)\"\r\n (click)=\"openCalendar(true)\" [pSize]=\"'small'\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \" [disabled]=\"disabled\" [name]=\"name\" pInputText\r\n class=\"w-full\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid, 'basic-style': basicInput, 'no-style':noStyle}\" />\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n</div>\r\n", styles: [".p-datepicker-clear-icon{@apply cursor-pointer absolute top-[50%] left-[13px] -translate-y-1/2 text-[var(--p-datepicker-input-icon-color)] ml-[calc(var(--p-icon-size))] leading-none;}.my-custom-datepicker-panel{display:none!important}.d-ltr{direction:ltr}.text-required{color:red}.p-error{color:#dc2626}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: DatePickerModule }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i3$1.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "pipe", type: ValidationErrorsPipe, name: "validationErrors" }], encapsulation: i0.ViewEncapsulation.None });
1625
+ }
1626
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DatePickerSwitcherComponent, decorators: [{
1627
+ type: Component,
1628
+ args: [{ selector: 'stc-date-picker-switcher', standalone: true, imports: [
1629
+ FormsModule,
1630
+ ReactiveFormsModule,
1631
+ NgClass,
1632
+ InputText,
1633
+ DatePickerModule,
1634
+ ValidationErrorsPipe,
1635
+ TranslatePipe,
1636
+ FloatLabelModule,
1637
+ ], encapsulation: ViewEncapsulation.None, template: "<div class=\"field flex flex-col gap-2 my-3 relative\">\r\n <p-floatlabel [variant]=\"variant\">\r\n <input [id]=\"inputId\" [type]=\"'text-float-label'\" [formControl]=\"control\" [readonly]=\"true\" (focus)=\"openCalendar(true)\"\r\n (click)=\"openCalendar(true)\" [pSize]=\"'small'\"\r\n [class]=\"\r\n 'w-full border border-[' + defaultColor + '] rounded-none focus:outline-[' + defaultColor + '] focus:border-[' + defaultColor + '] hover:border-[' + defaultColor + '] disabled:opacity-50'\r\n \" [disabled]=\"disabled\" [name]=\"name\" pInputText\r\n class=\"w-full\"\r\n [ngClass]=\"{ 'p-invalid ng-dirty ng-invalid': isInvalid, 'basic-style': basicInput, 'no-style':noStyle}\" />\r\n <label [for]=\"inputId\">\r\n {{ label }}\r\n @if (required) {\r\n <span [class.text-required]=\"required\">*</span>\r\n }\r\n </label>\r\n </p-floatlabel>\r\n @if (hint) {\r\n <small class=\"p-mt-1\">{{ hint }}</small>\r\n }\r\n @if (isInvalid && (control.dirty || control.touched)) {\r\n <small class=\"p-error\">\r\n @for (error of control.errors | validationErrors; track error) {\r\n {{ error }}<br>\r\n }\r\n </small>\r\n }\r\n</div>\r\n", styles: [".p-datepicker-clear-icon{@apply cursor-pointer absolute top-[50%] left-[13px] -translate-y-1/2 text-[var(--p-datepicker-input-icon-color)] ml-[calc(var(--p-icon-size))] leading-none;}.my-custom-datepicker-panel{display:none!important}.d-ltr{direction:ltr}.text-required{color:red}.p-error{color:#dc2626}\n"] }]
1638
+ }], ctorParameters: () => [], propDecorators: { type: [{
1639
+ type: Input
1640
+ }], contentType: [{
1641
+ type: Input
1642
+ }], size: [{
1643
+ type: Input
1644
+ }], prefix: [{
1645
+ type: Input
1646
+ }], rows: [{
1647
+ type: Input
1648
+ }], cols: [{
1649
+ type: Input
1650
+ }], autoResize: [{
1651
+ type: Input
1652
+ }], basicInput: [{
1653
+ type: Input
1654
+ }], noStyle: [{
1655
+ type: Input
1656
+ }], hideOptionalLabel: [{
1657
+ type: Input
1658
+ }], inputDirection: [{
1659
+ type: Input
1660
+ }], variant: [{
1661
+ type: Input
1662
+ }], defaultColor: [{
1663
+ type: Input
1664
+ }], formattedDate: [{
1665
+ type: Input
1666
+ }], openCalender: [{
1667
+ type: Output
1668
+ }] } });
1669
+
1670
+ var DateFormats;
1671
+ (function (DateFormats) {
1672
+ DateFormats["DATE_ONLY"] = "yyyy-MM-dd";
1673
+ DateFormats["DATE_UTC"] = "yyyy-MM-dd'T'HH:mm:ss'Z'";
1674
+ DateFormats["DATE_TIME_FULL"] = "dd MMMM yyyy - hh:mm a";
1675
+ DateFormats["DATE_TIME_SEMI"] = "yyyy/MM/dd - hh:mm a";
1676
+ DateFormats["DATE"] = "dd MMMM yyyy";
1677
+ DateFormats["DATE_TWO"] = "yyyy/MM/dd";
1678
+ DateFormats["DAY_ONLY"] = "cccc";
1679
+ DateFormats["TIME_ONLY"] = "hh:mm";
1680
+ DateFormats["AM_PM"] = "a";
1681
+ DateFormats["TIME"] = "hh:mm a";
1682
+ DateFormats["YEAR"] = "yyyy";
1683
+ DateFormats["MONTH"] = "MM";
1684
+ DateFormats["DAY"] = "dd";
1685
+ })(DateFormats || (DateFormats = {}));
1686
+ var TimeFormats;
1687
+ (function (TimeFormats) {
1688
+ TimeFormats["HOURS12Format"] = "hh";
1689
+ TimeFormats["HOURS24Format"] = "HH";
1690
+ TimeFormats["MINUTES"] = "mm";
1691
+ TimeFormats["SECONDS"] = "ss";
1692
+ })(TimeFormats || (TimeFormats = {}));
1693
+
1694
+ class DualCalendarComponent {
1695
+ selectedDate = '';
1696
+ control = new FormControl({ value: null, disabled: false }, []);
1697
+ label = '';
1698
+ name = '';
1699
+ withTime = true;
1700
+ isDatePickerShow = true;
1701
+ mode = 'gregorian';
1702
+ gregorianModel;
1703
+ hijriModel;
1704
+ currentLang = signal('ar', ...(ngDevMode ? [{ debugName: "currentLang" }] : []));
1705
+ gregorianUTC = new EventEmitter();
1706
+ onClose = new EventEmitter();
1707
+ gregorianUTCValue = '';
1708
+ isShown = false;
1709
+ calendarContainer;
1710
+ hijriCal = new NgbCalendarIslamicUmalqura();
1711
+ constructor() {
1712
+ effect(() => {
1713
+ this.currentLang(); // 👈 track signal
1714
+ this.setDate(this.gregorianUTCValue);
1785
1715
  });
1786
1716
  }
1787
- // Actions
1788
- onDeleteFile(file) {
1789
- const isNewFile = file.isNew;
1790
- this.fileDeleted.emit({ fileId: file.id, isNew: !!isNewFile });
1791
- if (isNewFile) {
1792
- // Remove from newFiles list immediately for new uploads
1793
- this.newFiles.update((files) => files.filter((f) => f.id !== file.id));
1717
+ ngOnInit() {
1718
+ this.setDate(this.control?.value);
1719
+ }
1720
+ setDate(value) {
1721
+ if (!value)
1722
+ return;
1723
+ const jsDate = new Date(value);
1724
+ if (isNaN(jsDate.getTime()))
1725
+ return;
1726
+ const ngbDate = {
1727
+ year: jsDate.getFullYear(),
1728
+ month: jsDate.getMonth() + 1,
1729
+ day: jsDate.getDate()
1730
+ };
1731
+ // 🔥 Reuse existing logic
1732
+ this.onSelectGregorian(ngbDate);
1733
+ }
1734
+ onDocumentClick(event) {
1735
+ event.stopPropagation();
1736
+ if (!this.calendarContainer)
1737
+ return;
1738
+ const clickedInside = this.calendarContainer.nativeElement.contains(event.target);
1739
+ this.onClose.emit(!clickedInside);
1740
+ if (!clickedInside) {
1741
+ this.isShown = false;
1794
1742
  }
1795
1743
  }
1796
- onPreviewFile(file) {
1797
- this.filePreview.emit(file);
1744
+ structToNgbDate(d) {
1745
+ return new NgbDate(d.year, d.month, d.day);
1798
1746
  }
1799
- removeFileFromList(fileId) {
1800
- this.newFiles.update((current) => current.filter((f) => f.id !== fileId));
1747
+ onSelectGregorian(date) {
1748
+ this.gregorianModel = date;
1749
+ // Convert to NgbDate
1750
+ const jsDate = new Date(date.year, date.month - 1, date.day);
1751
+ // fromGregorian expects NgbDate or JS Date (depending on version)
1752
+ const hijri = this.hijriCal.fromGregorian(jsDate);
1753
+ const isoUTC = jsDate.toISOString();
1754
+ this.gregorianUTCValue = this.withTime ? isoUTC : formatDate(jsDate, DateFormats.DATE_ONLY, 'en');
1755
+ this.gregorianUTC.emit(this.gregorianUTCValue);
1756
+ this.hijriModel = {
1757
+ year: hijri.year,
1758
+ month: hijri.month,
1759
+ day: hijri.day
1760
+ }; // datepicker
1761
+ this.selectedDate = this.formatHijri(this.structToNgbDate(this.hijriModel)); //input
1762
+ this.isShown = false;
1801
1763
  }
1802
- generateTempId(file) {
1803
- return `temp-${file.name}-${file.size}-${Date.now()}`;
1764
+ onSelectHijri(date) {
1765
+ this.hijriModel = date;
1766
+ const ngbDate = this.structToNgbDate(date);
1767
+ const greg = this.hijriCal.toGregorian(ngbDate);
1768
+ const isoUTC = greg.toISOString();
1769
+ this.gregorianModel = {
1770
+ year: greg.getFullYear(),
1771
+ month: greg.getMonth() + 1,
1772
+ day: greg.getDate()
1773
+ };
1774
+ const jsDate = new Date(this.gregorianModel.year, this.gregorianModel.month - 1, this.gregorianModel.day);
1775
+ this.gregorianUTCValue = this.withTime ? isoUTC : formatDate(jsDate, DateFormats.DATE_ONLY, 'en');
1776
+ this.gregorianUTC.emit(this.gregorianUTCValue);
1777
+ this.selectedDate = this.formatHijri(ngbDate);
1778
+ this.isShown = false;
1804
1779
  }
1805
- formatFileSize(bytes) {
1806
- if (bytes === 0)
1807
- return '0 B';
1808
- const k = 1024;
1809
- const sizes = ['B', 'KB', 'MB', 'GB'];
1810
- const i = Math.floor(Math.log(bytes) / Math.log(k));
1811
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
1780
+ showCalender(isOpen) {
1781
+ this.isShown = isOpen;
1812
1782
  }
1813
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FileManagementComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1814
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: FileManagementComponent, isStandalone: true, selector: "app-file-management", inputs: { existingFiles: { classPropertyName: "existingFiles", publicName: "existingFiles", isSignal: true, isRequired: false, transformFunction: null }, acceptedTypes: { classPropertyName: "acceptedTypes", publicName: "acceptedTypes", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, maxConcurrentUploads: { classPropertyName: "maxConcurrentUploads", publicName: "maxConcurrentUploads", isSignal: true, isRequired: false, transformFunction: null }, showTable: { classPropertyName: "showTable", publicName: "showTable", isSignal: true, isRequired: false, transformFunction: null }, showDropZone: { classPropertyName: "showDropZone", publicName: "showDropZone", isSignal: true, isRequired: false, transformFunction: null }, allowPreview: { classPropertyName: "allowPreview", publicName: "allowPreview", isSignal: true, isRequired: false, transformFunction: null }, permissonKey: { classPropertyName: "permissonKey", publicName: "permissonKey", isSignal: true, isRequired: false, transformFunction: null }, allowedActions: { classPropertyName: "allowedActions", publicName: "allowedActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { filesUploaded: "filesUploaded", fileDeleted: "fileDeleted", filePreview: "filePreview", fileDownload: "fileDownload", uploadError: "uploadError", newFilesChange: "newFilesChange" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"file-management\">\r\n <!-- Drop Zone -->\r\n @if (showDropZone()) {\r\n <div\r\n class=\"drop-zone upload-container\"\r\n [class.drag-over]=\"isDragOver()\"\r\n (dragover)=\"onDragOver($event)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event)\"\r\n >\r\n <div class=\"drop-zone-content\">\r\n <p class=\"drop-text\">{{ 'file.drag_drop_files' | translate }}</p>\r\n <p-button\r\n [label]=\"'file.browse' | translate\"\r\n severity=\"danger\"\r\n [outlined]=\"true\"\r\n (onClick)=\"onBrowseClick()\"\r\n />\r\n <p class=\"drop-hint text-xs text-gray-500 mt-2\">\r\n {{ 'file.max_size_hint' | translate }}: {{ maxFileSize() | fileSize: 2 : 'MB' }}\r\n </p>\r\n @if (formattedAcceptedTypes()) {\r\n <p class=\"accepted-types text-xs text-gray-400\">\r\n {{ 'file.accepted_types' | translate }}: {{ formattedAcceptedTypes() }}\r\n </p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Hidden file input (always present for programmatic access) -->\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n [accept]=\"acceptedTypes()\"\r\n multiple\r\n hidden\r\n (change)=\"onFileInputChange($event)\"\r\n />\r\n\r\n @if(uploadedFile().length) {\r\n @for(file of uploadedFile() ; track file) {\r\n <div class=\"uploaded-files \" >\r\n <p>{{file.name}}</p>\r\n <i class=\"pi pi-trash\" style=\"font-size: 1.5rem; color: #f00\" (click)=\"deleteFile()\"></i>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Files Table -->\r\n\r\n</div>\r\n", styles: [".file-management{width:100%}.drop-zone{@apply cursor-pointer rounded-l border-2 border-dashed border-gray-300 p-8 bg-purple-light3 text-center transition-all duration-200 ease-in-out;}.drop-zone.drag-over{@apply border-purple-200 bg-purple-light;}.drop-zone-content{@apply flex flex-col items-center gap-2;}.drop-icon{font-size:3rem;color:var(--gray-400, #9ca3af);margin-bottom:.5rem}.drop-text{font-size:1rem;color:var(--gray-700, #374151);margin:0}.drop-or{font-size:.875rem;color:var(--gray-500, #6b7280);margin:.25rem 0}.drop-hint{margin-top:.75rem}.files-table{border:1px solid var(--gray-200, #e5e7eb);border-radius:8px;overflow:hidden}:host-context([dir=rtl]) .drop-zone-content{direction:rtl}.uploaded-files{background-color:#f3f3f7;border:1px solid #DFE0E6;display:flex;justify-content:space-between;align-items:center;padding:15px;margin-bottom:10px}.uploaded-files .pi-trash{cursor:pointer}.uploaded-files p{margin-block-start:0;margin-block-end:0}.upload-container{background-color:#f3f3f7;padding:15px;border:1px dashed #DFE0E6;margin-bottom:15px;display:flex;justify-content:center;align-items:center;border-radius:2px}.upload-container .drop-zone-content{display:flex;align-items:center;flex-direction:column}.upload-container .drop-zone-content .drop-text{margin-bottom:10px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: FileSizePipe, name: "fileSize" }] });
1783
+ formatHijri(h) {
1784
+ const hijriDay = h.day;
1785
+ const hijriMonth = getHijriMonthName(this.currentLang(), h.month);
1786
+ const hijriYear = h.year;
1787
+ const greg = this.hijriCal.toGregorian(h);
1788
+ const gregorianDay = greg.getDate();
1789
+ const gregorianMonth = getGregorianMonthName(this.currentLang(), greg.getMonth() + 1);
1790
+ const gregorianYear = greg.getFullYear();
1791
+ return `${gregorianDay} ${gregorianMonth} ${gregorianYear} - ${hijriDay} ${hijriMonth} ${hijriYear}`;
1792
+ }
1793
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DualCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1794
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DualCalendarComponent, isStandalone: true, selector: "app-dual-calendar", inputs: { control: "control", label: "label", name: "name", withTime: "withTime", isDatePickerShow: "isDatePickerShow", currentLang: "currentLang", isShown: "isShown" }, outputs: { gregorianUTC: "gregorianUTC", onClose: "onClose" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, providers: [
1795
+ { provide: NgbCalendar, useClass: NgbCalendarIslamicUmalqura }
1796
+ ], viewQueries: [{ propertyName: "calendarContainer", first: true, predicate: ["calendarContainer"], descendants: true }], ngImport: i0, template: "<div class=\"calender-content\" #calendarContainer>\r\n @if(isDatePickerShow) {\r\n <stc-date-picker-switcher [variant]=\"'in'\" [label]=\"label\" id=\"dateId\" (openCalender)=\"showCalender($event)\"\r\n [control]=\"control\" [formattedDate]='selectedDate' >\r\n </stc-date-picker-switcher>\r\n }\r\n\r\n <!-- calender.html -->\r\n <div [dir]=\"currentLang() === 'ar' ? 'rtl' : 'ltr'\" class=\"p-2 calendar-wrapper \" [@slideDown]=\"isShown ? 'open' : 'closed'\" >\r\n <div class=\"header-tabs\">\r\n <div class=\"header-label\">{{'calender.calender_type' | translate}}</div>\r\n <div class=\"tabs\">\r\n <button class=\"tab-button\" [class.active]=\"mode === 'gregorian'\" type=\"button\" (click)=\" mode='gregorian'\">\r\n {{'calender.gregorian' | translate}}\r\n </button>\r\n <button class=\"tab-button\" [class.active]=\"mode === 'hijri'\" type=\"button\" (click)=\" mode='hijri'\">\r\n {{'calender.hijri' | translate}}\r\n </button>\r\n </div>\r\n </div>\r\n @if(mode === 'gregorian') {\r\n <app-gregorian-calendar [model]=\"gregorianModel\" [language]=\"currentLang()\"\r\n (dateSelected)=\"onSelectGregorian($event)\">\r\n </app-gregorian-calendar>\r\n }\r\n\r\n @if(mode === 'hijri') {\r\n <app-hijri-calendar [model]=\"hijriModel\" [language]=\"currentLang()\" (dateSelected)=\"onSelectHijri($event)\">\r\n </app-hijri-calendar>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".calendar-wrapper{max-width:375px;padding:15px}.calendar-wrapper .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{margin:0 10px;max-width:20px}.calendar-wrapper .rtl .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{inset-inline-end:-6px;transform:rotate(180deg);margin:0 10px;max-width:20px}.calendar-wrapper .rtl .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-prev{inset-inline-end:22px;transform:rotate(180deg)}.calendar-wrapper .ltr .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{inset-inline-end:-4px}.calendar-wrapper .ltr .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-prev{inset-inline-end:11px}.header-tabs{display:flex;justify-content:space-between;align-items:center;gap:10px;margin-bottom:10px}.tabs{background:#f0f0f5;padding:3px;border-radius:2px}.tab-button{flex:1;padding:6px 10px;font-size:14px;background:#f0f0f5;border:none;border-radius:6px;cursor:pointer;transition:.3s}.tab-button.active{background:#dcd6f8;color:#4a3fb4;font-weight:600}.custom-datepicker{width:100%;background:#fff;border:1px solid #e5e5e5;border-radius:8px;padding:12px}.custom-datepicker .ngb-dp-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;max-width:375px}.custom-datepicker .ngb-dp-arrow-btn{background:none;border:none;cursor:pointer;padding:4px}.custom-datepicker .ngb-dp-weekdays{margin-bottom:6px}.custom-datepicker .ngb-dp-weekday{color:#9b9b9b;font-weight:600;text-align:center}.custom-day.today{border:1px solid #6a41d8;border-radius:8px}.custom-day.outside{opacity:.3}.custom-day.disabled{opacity:.2;pointer-events:none}.calender-content{position:relative}.calendar-wrapper{position:absolute;top:100%;left:0;z-index:50;box-shadow:0 2px 8px #00000026;background-color:#fff;border-radius:4px;overflow:hidden}.ngb-datepicker{width:100%}.custom-day{display:inline-flex;justify-content:center;align-items:center;margin:2px;border-radius:50%;cursor:pointer;font-weight:500}.custom-day.today{color:#4f008d;border:0!important}.ngb-dp-day:has(.selected){background-color:#ede6f4!important;border:0!important;color:#4f008d!important;border-radius:2px}.custom-day.outside{color:#ccc!important}.custom-day.disabled{color:#aaa!important;pointer-events:none!important}.ngb-dp-day,.ngb-dp-weekday,.ngb-dp-week-number{width:38px!important;height:44px!important;display:flex;margin:5px;justify-content:center;align-items:center}.ngb-dp-month:first-child .ngb-dp-week{padding:0!important}.ngb-dp-month:last-child .ngb-dp-week{padding:0!important}.ngb-dp-arrow-btn{margin-inline-end:0!important;outline:0!important;padding:0!important;margin:0!important}.ngb-dp-header{position:relative}.ngb-dp-header .ngb-dp-arrow{position:absolute}.ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-prev{inset-inline-end:0}.ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{inset-inline-end:15px}.ngb-dp-header .ngb-dp-arrow:focus-visible,.ngb-dp-header .ngb-dp-arrow .btn:focus-visible{outline:0!important}.ngb-dp-header .visually-hidden{display:none}.ngb-dp-navigation-select{max-width:140px}.ngb-dp-navigation-select select{border:0}.ngb-dp-navigation-select select:focus-visible{outline:0}.ngb-datepicker-navigation-select>.form-select{font-size:14px;font-weight:700}.ngb-dp-navigation-select,.form-select:first-child{appearance:none!important;-webkit-appearance:none;-moz-appearance:none}.ngb-dp-navigation-chevron{font-size:18px;border-width:.1em .1em 0 0!important;border-color:#000}\n"], dependencies: [{ kind: "ngmodule", type: NgbDatepickerModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: DatePickerModule }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: HijriCalendarComponent, selector: "app-hijri-calendar", inputs: ["model", "language"], outputs: ["dateSelected"] }, { kind: "component", type: DatePickerSwitcherComponent, selector: "stc-date-picker-switcher", inputs: ["type", "contentType", "size", "prefix", "rows", "cols", "autoResize", "basicInput", "noStyle", "hideOptionalLabel", "inputDirection", "variant", "defaultColor", "formattedDate"], outputs: ["openCalender"] }, { kind: "component", type: GregorianCalendarComponent, selector: "app-gregorian-calendar", inputs: ["model", "language"], outputs: ["dateSelected"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], animations: [
1797
+ trigger('slideDown', [
1798
+ state('closed', style({
1799
+ height: '0px',
1800
+ opacity: 0,
1801
+ overflow: 'hidden'
1802
+ })),
1803
+ state('open', style({
1804
+ height: '*',
1805
+ opacity: 1,
1806
+ overflow: 'hidden'
1807
+ })),
1808
+ transition('closed <=> open', [
1809
+ animate('300ms ease')
1810
+ ])
1811
+ ])
1812
+ ], encapsulation: i0.ViewEncapsulation.None });
1815
1813
  }
1816
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: FileManagementComponent, decorators: [{
1814
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DualCalendarComponent, decorators: [{
1817
1815
  type: Component,
1818
- args: [{ selector: 'app-file-management', imports: [CommonModule, TranslatePipe, ButtonModule, TooltipModule, FileSizePipe], template: "<div class=\"file-management\">\r\n <!-- Drop Zone -->\r\n @if (showDropZone()) {\r\n <div\r\n class=\"drop-zone upload-container\"\r\n [class.drag-over]=\"isDragOver()\"\r\n (dragover)=\"onDragOver($event)\"\r\n (dragleave)=\"onDragLeave($event)\"\r\n (drop)=\"onDrop($event)\"\r\n >\r\n <div class=\"drop-zone-content\">\r\n <p class=\"drop-text\">{{ 'file.drag_drop_files' | translate }}</p>\r\n <p-button\r\n [label]=\"'file.browse' | translate\"\r\n severity=\"danger\"\r\n [outlined]=\"true\"\r\n (onClick)=\"onBrowseClick()\"\r\n />\r\n <p class=\"drop-hint text-xs text-gray-500 mt-2\">\r\n {{ 'file.max_size_hint' | translate }}: {{ maxFileSize() | fileSize: 2 : 'MB' }}\r\n </p>\r\n @if (formattedAcceptedTypes()) {\r\n <p class=\"accepted-types text-xs text-gray-400\">\r\n {{ 'file.accepted_types' | translate }}: {{ formattedAcceptedTypes() }}\r\n </p>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Hidden file input (always present for programmatic access) -->\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n [accept]=\"acceptedTypes()\"\r\n multiple\r\n hidden\r\n (change)=\"onFileInputChange($event)\"\r\n />\r\n\r\n @if(uploadedFile().length) {\r\n @for(file of uploadedFile() ; track file) {\r\n <div class=\"uploaded-files \" >\r\n <p>{{file.name}}</p>\r\n <i class=\"pi pi-trash\" style=\"font-size: 1.5rem; color: #f00\" (click)=\"deleteFile()\"></i>\r\n </div>\r\n }\r\n }\r\n\r\n <!-- Files Table -->\r\n\r\n</div>\r\n", styles: [".file-management{width:100%}.drop-zone{@apply cursor-pointer rounded-l border-2 border-dashed border-gray-300 p-8 bg-purple-light3 text-center transition-all duration-200 ease-in-out;}.drop-zone.drag-over{@apply border-purple-200 bg-purple-light;}.drop-zone-content{@apply flex flex-col items-center gap-2;}.drop-icon{font-size:3rem;color:var(--gray-400, #9ca3af);margin-bottom:.5rem}.drop-text{font-size:1rem;color:var(--gray-700, #374151);margin:0}.drop-or{font-size:.875rem;color:var(--gray-500, #6b7280);margin:.25rem 0}.drop-hint{margin-top:.75rem}.files-table{border:1px solid var(--gray-200, #e5e7eb);border-radius:8px;overflow:hidden}:host-context([dir=rtl]) .drop-zone-content{direction:rtl}.uploaded-files{background-color:#f3f3f7;border:1px solid #DFE0E6;display:flex;justify-content:space-between;align-items:center;padding:15px;margin-bottom:10px}.uploaded-files .pi-trash{cursor:pointer}.uploaded-files p{margin-block-start:0;margin-block-end:0}.upload-container{background-color:#f3f3f7;padding:15px;border:1px dashed #DFE0E6;margin-bottom:15px;display:flex;justify-content:center;align-items:center;border-radius:2px}.upload-container .drop-zone-content{display:flex;align-items:center;flex-direction:column}.upload-container .drop-zone-content .drop-text{margin-bottom:10px}\n"] }]
1819
- }], propDecorators: { existingFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "existingFiles", required: false }] }], acceptedTypes: [{ type: i0.Input, args: [{ isSignal: true, alias: "acceptedTypes", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], maxConcurrentUploads: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxConcurrentUploads", required: false }] }], showTable: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTable", required: false }] }], showDropZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDropZone", required: false }] }], allowPreview: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowPreview", required: false }] }], permissonKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "permissonKey", required: false }] }], allowedActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowedActions", required: false }] }], filesUploaded: [{
1820
- type: Output
1821
- }], fileDeleted: [{
1822
- type: Output
1823
- }], filePreview: [{
1824
- type: Output
1825
- }], fileDownload: [{
1826
- type: Output
1827
- }], uploadError: [{
1816
+ args: [{ selector: 'app-dual-calendar', animations: [
1817
+ trigger('slideDown', [
1818
+ state('closed', style({
1819
+ height: '0px',
1820
+ opacity: 0,
1821
+ overflow: 'hidden'
1822
+ })),
1823
+ state('open', style({
1824
+ height: '*',
1825
+ opacity: 1,
1826
+ overflow: 'hidden'
1827
+ })),
1828
+ transition('closed <=> open', [
1829
+ animate('300ms ease')
1830
+ ])
1831
+ ])
1832
+ ], imports: [
1833
+ NgbDatepickerModule,
1834
+ FormsModule,
1835
+ FormsModule,
1836
+ ReactiveFormsModule,
1837
+ DatePickerModule,
1838
+ FloatLabelModule,
1839
+ HijriCalendarComponent,
1840
+ DatePickerSwitcherComponent,
1841
+ TranslatePipe,
1842
+ GregorianCalendarComponent
1843
+ ], providers: [
1844
+ { provide: NgbCalendar, useClass: NgbCalendarIslamicUmalqura }
1845
+ ], encapsulation: ViewEncapsulation.None, template: "<div class=\"calender-content\" #calendarContainer>\r\n @if(isDatePickerShow) {\r\n <stc-date-picker-switcher [variant]=\"'in'\" [label]=\"label\" id=\"dateId\" (openCalender)=\"showCalender($event)\"\r\n [control]=\"control\" [formattedDate]='selectedDate' >\r\n </stc-date-picker-switcher>\r\n }\r\n\r\n <!-- calender.html -->\r\n <div [dir]=\"currentLang() === 'ar' ? 'rtl' : 'ltr'\" class=\"p-2 calendar-wrapper \" [@slideDown]=\"isShown ? 'open' : 'closed'\" >\r\n <div class=\"header-tabs\">\r\n <div class=\"header-label\">{{'calender.calender_type' | translate}}</div>\r\n <div class=\"tabs\">\r\n <button class=\"tab-button\" [class.active]=\"mode === 'gregorian'\" type=\"button\" (click)=\" mode='gregorian'\">\r\n {{'calender.gregorian' | translate}}\r\n </button>\r\n <button class=\"tab-button\" [class.active]=\"mode === 'hijri'\" type=\"button\" (click)=\" mode='hijri'\">\r\n {{'calender.hijri' | translate}}\r\n </button>\r\n </div>\r\n </div>\r\n @if(mode === 'gregorian') {\r\n <app-gregorian-calendar [model]=\"gregorianModel\" [language]=\"currentLang()\"\r\n (dateSelected)=\"onSelectGregorian($event)\">\r\n </app-gregorian-calendar>\r\n }\r\n\r\n @if(mode === 'hijri') {\r\n <app-hijri-calendar [model]=\"hijriModel\" [language]=\"currentLang()\" (dateSelected)=\"onSelectHijri($event)\">\r\n </app-hijri-calendar>\r\n }\r\n </div>\r\n</div>\r\n", styles: [".calendar-wrapper{max-width:375px;padding:15px}.calendar-wrapper .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{margin:0 10px;max-width:20px}.calendar-wrapper .rtl .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{inset-inline-end:-6px;transform:rotate(180deg);margin:0 10px;max-width:20px}.calendar-wrapper .rtl .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-prev{inset-inline-end:22px;transform:rotate(180deg)}.calendar-wrapper .ltr .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{inset-inline-end:-4px}.calendar-wrapper .ltr .ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-prev{inset-inline-end:11px}.header-tabs{display:flex;justify-content:space-between;align-items:center;gap:10px;margin-bottom:10px}.tabs{background:#f0f0f5;padding:3px;border-radius:2px}.tab-button{flex:1;padding:6px 10px;font-size:14px;background:#f0f0f5;border:none;border-radius:6px;cursor:pointer;transition:.3s}.tab-button.active{background:#dcd6f8;color:#4a3fb4;font-weight:600}.custom-datepicker{width:100%;background:#fff;border:1px solid #e5e5e5;border-radius:8px;padding:12px}.custom-datepicker .ngb-dp-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;max-width:375px}.custom-datepicker .ngb-dp-arrow-btn{background:none;border:none;cursor:pointer;padding:4px}.custom-datepicker .ngb-dp-weekdays{margin-bottom:6px}.custom-datepicker .ngb-dp-weekday{color:#9b9b9b;font-weight:600;text-align:center}.custom-day.today{border:1px solid #6a41d8;border-radius:8px}.custom-day.outside{opacity:.3}.custom-day.disabled{opacity:.2;pointer-events:none}.calender-content{position:relative}.calendar-wrapper{position:absolute;top:100%;left:0;z-index:50;box-shadow:0 2px 8px #00000026;background-color:#fff;border-radius:4px;overflow:hidden}.ngb-datepicker{width:100%}.custom-day{display:inline-flex;justify-content:center;align-items:center;margin:2px;border-radius:50%;cursor:pointer;font-weight:500}.custom-day.today{color:#4f008d;border:0!important}.ngb-dp-day:has(.selected){background-color:#ede6f4!important;border:0!important;color:#4f008d!important;border-radius:2px}.custom-day.outside{color:#ccc!important}.custom-day.disabled{color:#aaa!important;pointer-events:none!important}.ngb-dp-day,.ngb-dp-weekday,.ngb-dp-week-number{width:38px!important;height:44px!important;display:flex;margin:5px;justify-content:center;align-items:center}.ngb-dp-month:first-child .ngb-dp-week{padding:0!important}.ngb-dp-month:last-child .ngb-dp-week{padding:0!important}.ngb-dp-arrow-btn{margin-inline-end:0!important;outline:0!important;padding:0!important;margin:0!important}.ngb-dp-header{position:relative}.ngb-dp-header .ngb-dp-arrow{position:absolute}.ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-prev{inset-inline-end:0}.ngb-dp-header .ngb-dp-arrow.ngb-dp-arrow-next{inset-inline-end:15px}.ngb-dp-header .ngb-dp-arrow:focus-visible,.ngb-dp-header .ngb-dp-arrow .btn:focus-visible{outline:0!important}.ngb-dp-header .visually-hidden{display:none}.ngb-dp-navigation-select{max-width:140px}.ngb-dp-navigation-select select{border:0}.ngb-dp-navigation-select select:focus-visible{outline:0}.ngb-datepicker-navigation-select>.form-select{font-size:14px;font-weight:700}.ngb-dp-navigation-select,.form-select:first-child{appearance:none!important;-webkit-appearance:none;-moz-appearance:none}.ngb-dp-navigation-chevron{font-size:18px;border-width:.1em .1em 0 0!important;border-color:#000}\n"] }]
1846
+ }], ctorParameters: () => [], propDecorators: { control: [{
1847
+ type: Input
1848
+ }], label: [{
1849
+ type: Input
1850
+ }], name: [{
1851
+ type: Input
1852
+ }], withTime: [{
1853
+ type: Input
1854
+ }], isDatePickerShow: [{
1855
+ type: Input
1856
+ }], currentLang: [{
1857
+ type: Input
1858
+ }], gregorianUTC: [{
1828
1859
  type: Output
1829
- }], newFilesChange: [{
1860
+ }], onClose: [{
1830
1861
  type: Output
1831
- }], fileInput: [{
1862
+ }], isShown: [{
1863
+ type: Input
1864
+ }], calendarContainer: [{
1832
1865
  type: ViewChild,
1833
- args: ['fileInput']
1866
+ args: ['calendarContainer']
1867
+ }], onDocumentClick: [{
1868
+ type: HostListener,
1869
+ args: ['document:click', ['$event']]
1834
1870
  }] } });
1835
1871
 
1836
- class LocalizedLabelPipe {
1837
- translateService = inject(TranslateService);
1838
- transform(label) {
1839
- if (!label)
1840
- return '';
1841
- const lang = this.translateService.getCurrentLang() || 'ar';
1842
- const suffix = lang.charAt(0).toUpperCase() + lang.slice(1);
1843
- const key = label + `${suffix}`;
1844
- return key;
1845
- }
1846
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: LocalizedLabelPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1847
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: LocalizedLabelPipe, isStandalone: true, name: "localizedLabel", pure: false });
1848
- }
1849
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: LocalizedLabelPipe, decorators: [{
1850
- type: Pipe,
1851
- args: [{
1852
- name: 'localizedLabel',
1853
- standalone: true,
1854
- pure: false,
1855
- }]
1856
- }] });
1857
-
1858
- const FileExtentions = [
1859
- 'jpeg',
1860
- 'pptx',
1861
- 'xlsx',
1862
- 'xls',
1863
- 'doc',
1864
- 'docx',
1865
- 'jpg',
1866
- 'png',
1867
- 'pdf',
1868
- 'txt',
1869
- 'csv',
1870
- 'msg',
1871
- 'zip',
1872
- 'win',
1873
- 'xlsb',
1874
- 'ppt',
1875
- 'rar',
1876
- ];
1872
+ var FormFieldTypeEnum;
1873
+ (function (FormFieldTypeEnum) {
1874
+ FormFieldTypeEnum["DATE_PICKER"] = "date-picker";
1875
+ FormFieldTypeEnum["SELECT_BUTTON"] = "select-button";
1876
+ FormFieldTypeEnum["INPUT"] = "input";
1877
+ FormFieldTypeEnum["SELECT"] = "select";
1878
+ FormFieldTypeEnum["SWITCH"] = "switch";
1879
+ FormFieldTypeEnum["AUTO_COMPLETE"] = "auto-complete";
1880
+ FormFieldTypeEnum["HIJRI_DATE_PICKER"] = "hijri-date";
1881
+ FormFieldTypeEnum["UPLOAD_FILE"] = "upload-file";
1882
+ })(FormFieldTypeEnum || (FormFieldTypeEnum = {}));
1877
1883
 
1878
1884
  class DynamicFormComponent {
1879
1885
  dynamicFormData;
1880
1886
  // Generic field change outputs (optional for consumers)
1881
1887
  selectButtonChange = new EventEmitter();
1882
1888
  selectChange = new EventEmitter();
1889
+ selectClicked = new EventEmitter();
1883
1890
  switchChange = new EventEmitter();
1884
1891
  autoCompleteSearch = new EventEmitter();
1885
1892
  autoCompleteSelect = new EventEmitter();
@@ -1905,7 +1912,7 @@ class DynamicFormComponent {
1905
1912
  this.fileDeleted.emit(file);
1906
1913
  }
1907
1914
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1908
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DynamicFormComponent, isStandalone: true, selector: "app-dynamic-form", inputs: { dynamicFormData: "dynamicFormData" }, outputs: { selectButtonChange: "selectButtonChange", selectChange: "selectChange", switchChange: "switchChange", autoCompleteSearch: "autoCompleteSearch", autoCompleteSelect: "autoCompleteSelect", popUpFilesUploaded: "popUpFilesUploaded", fileDeleted: "fileDeleted" }, ngImport: i0, template: "<form [formGroup]=\"formGroup\" class=\"dynamic-form\">\r\n <div class=\"grid grid-cols-12 gap-x-2 dynamic-form__content\">\r\n @for (inputName of inputsNames; track $index) {\r\n <div [ngClass]=\"inputsMap[inputName].rowSize\" >\r\n @switch (inputsMap[inputName].fieldType) {\r\n @case (fieldType.HIJRI_DATE_PICKER) {\r\n <app-dual-calendar [control]=\"getFormControl(inputName, formGroup)\"></app-dual-calendar>\r\n }\r\n\r\n @case (fieldType.DATE_PICKER) {\r\n <stc-date-picker [minDate]=\"inputsMap[inputName]?.dateRange?.min\" [maxDate]=\"inputsMap[inputName]?.dateRange?.max\"\r\n [id]=\"inputsMap[inputName].inputId\" [control]=\"getFormControl(inputName, formGroup)\" [name]=\"inputName\"\r\n [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [variant]=\"inputsMap[inputName].variant || 'over'\"\r\n [showIcon]=\"inputsMap[inputName].showIcon !== false\" [isTimeOnly]=\"inputsMap[inputName].isTimeOnly || false\" />\r\n }\r\n @case (fieldType.SELECT_BUTTON) {\r\n <stc-select-button [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\"\r\n [name]=\"inputName\" [label]=\"inputsMap[inputName].label\"\r\n [options]=\"inputsMap[inputName].selectButtonOptions || []\"\r\n (onChange)=\"selectButtonChange.emit({ name: inputName, value: $event })\" />\r\n }\r\n @case (fieldType.INPUT) {\r\n <stc-input [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\" [name]=\"inputName\"\r\n [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [type]=\"inputsMap[inputName].inputType || 'text'\"\r\n [contentType]=\"inputsMap[inputName].contentType || 'text'\" [rows]=\"inputsMap[inputName].rows || 2\"\r\n [cols]=\"inputsMap[inputName].cols || 20\" [autoResize]=\"inputsMap[inputName].autoResize ?? false\"\r\n [prefix]=\"inputsMap[inputName].prefix || ''\" [size]=\"inputsMap[inputName].size || 'small'\"\r\n [variant]=\"inputsMap[inputName].variant || 'over'\">\r\n @if(inputsMap[inputName].maxLength){\r\n <span class=\"text-xs text-gray-700\">\r\n {{ (getFormControl(inputName, formGroup).value?.length || 0) }}\r\n <span> / {{ inputsMap[inputName].maxLength}}</span>\r\n </span>\r\n }\r\n </stc-input>\r\n }\r\n @case (fieldType.SELECT) {\r\n <stc-select [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\"\r\n [name]=\"inputName\" [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [options]=\"inputsMap[inputName].selectOptions || []\"\r\n [optionLabel]=\"inputsMap[inputName]?.translatable\r\n ? ((inputsMap[inputName]?.optionLabel || 'label') | localizedLabel)\r\n : (inputsMap[inputName]?.optionLabel || 'label')\"\r\n [filter]=\"inputsMap[inputName].filter || false\"\r\n [multiple]=\"inputsMap[inputName].multiple || false\" [showClear]=\"inputsMap[inputName].showClear || false\"\r\n [checkmark]=\"inputsMap[inputName].checkmark ?? true\" [filterBy]=\"inputsMap[inputName].filterBy || ''\"\r\n [selectedItemsLabel]=\"inputsMap[inputName].selectedItemsLabel || ''\"\r\n [size]=\"inputsMap[inputName].size || 'small'\" [variant]=\"inputsMap[inputName].variant || 'over'\"\r\n (change)=\"selectChange.emit({ name: inputName, event: $event })\" />\r\n }\r\n @case (fieldType.SWITCH) {\r\n <stc-switch [label]=\"inputsMap[inputName].label\" [key]=\"inputName\"\r\n [checked]=\"getFormControl(inputName, formGroup).value\"\r\n (onChange)=\"getFormControl(inputName, formGroup).setValue(typeof $event === 'string' ? ($event === 'true') : $event); switchChange.emit({ name: inputName, value: (typeof $event === 'string' ? ($event === 'true') : $event) })\" />\r\n }\r\n @case (fieldType.AUTO_COMPLETE) {\r\n <stc-auto-complete [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\"\r\n [name]=\"inputName\" [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [items]=\"inputsMap[inputName].autoCompleteItems || []\"\r\n [minLengthToSearch]=\"inputsMap[inputName].minLengthToSearch || 2\" [delay]=\"inputsMap[inputName].delay || 300\"\r\n (onSearch)=\"autoCompleteSearch.emit({ name: inputName, query: $event })\"\r\n (selectOption)=\"autoCompleteSelect.emit({ name: inputName, event: $event })\"\r\n [variant]=\"inputsMap[inputName].variant || 'over'\" />\r\n }\r\n @case(fieldType.UPLOAD_FILE) {\r\n <app-file-management #fileManager #groupFileManager [maxFileSize]=\"262144000\" [maxConcurrentUploads]=\"1\"\r\n [allowPreview]=\"true\" [acceptedTypes]=\"getAcceptedTypes()\" (filesUploaded)=\"onFilesUploaded($event)\" [control]=\"getFormControl(inputName, formGroup)\" (fileDeleted)=\"onFileDeleted($event)\" />\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n\r\n\r\n </div>\r\n <div class=\"col-span-12\">\r\n <small class=\"p-error text-red-700\">\r\n @for (error of formGroup.errors | validationErrors: dynamicFormData.formValidationErrorsKeys;\r\n track error) {\r\n {{ error }}\r\n }\r\n </small>\r\n </div>\r\n</form>\r\n", styles: [".dynamic-form__content>div{margin-bottom:15px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: DatePickerComponent, selector: "stc-date-picker", inputs: ["showIcon", "showClear", "basicInput", "isTimeOnly", "minDate", "maxDate", "hourFormat", "selectionMode", "variant", "withoutTime"], outputs: ["onAfterClearDate"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: SelectButtonComponent, selector: "stc-select-button", inputs: ["options", "title"], outputs: ["onChange"] }, { kind: "component", type: DualCalendarComponent, selector: "app-dual-calendar", inputs: ["control", "label", "name", "withTime", "isDatePickerShow", "currentLang", "isShown"], outputs: ["gregorianUTC", "onClose"] }, { kind: "component", type: InputComponent, selector: "stc-input", inputs: ["type", "contentType", "size", "prefix", "rows", "cols", "autoResize", "basicInput", "noStyle", "canClear", "hideOptionalLabel", "inputDirection", "variant", "defaultColor", "iconClass", "iconPosition"] }, { kind: "component", type: FileManagementComponent, selector: "app-file-management", inputs: ["existingFiles", "acceptedTypes", "maxFileSize", "maxConcurrentUploads", "showTable", "showDropZone", "allowPreview", "permissonKey", "allowedActions"], outputs: ["filesUploaded", "fileDeleted", "filePreview", "fileDownload", "uploadError", "newFilesChange"] }, { kind: "component", type: SelectComponent, selector: "stc-select", inputs: ["selectedItemTemplate", "optionTemplate", "options", "optionLabel", "optionValue", "emptyMessage", "checkmark", "showClear", "editable", "filter", "multiple", "filterBy", "selectAllLabel", "dataKey", "size", "selectedItemsLabel", "basicInput", "variant", "defaultColor"], outputs: ["change"] }, { kind: "component", type: AutoCompleteComponent, selector: "stc-auto-complete", inputs: ["selectedItemTemplate", "items", "minLengthToSearch", "delay", "basicInput", "typeAhead", "variant"], outputs: ["onSearch", "selectOption"] }, { kind: "component", type: SwitchComponent, selector: "stc-switch", inputs: ["label", "key", "checked"], outputs: ["onChange"] }, { kind: "pipe", type: ValidationErrorsPipe, name: "validationErrors" }, { kind: "pipe", type: LocalizedLabelPipe, name: "localizedLabel" }] });
1915
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DynamicFormComponent, isStandalone: true, selector: "app-dynamic-form", inputs: { dynamicFormData: "dynamicFormData" }, outputs: { selectButtonChange: "selectButtonChange", selectChange: "selectChange", selectClicked: "selectClicked", switchChange: "switchChange", autoCompleteSearch: "autoCompleteSearch", autoCompleteSelect: "autoCompleteSelect", popUpFilesUploaded: "popUpFilesUploaded", fileDeleted: "fileDeleted" }, ngImport: i0, template: "<form [formGroup]=\"formGroup\" class=\"dynamic-form\">\r\n <div class=\"grid grid-cols-12 gap-x-2 dynamic-form__content\">\r\n @for (inputName of inputsNames; track $index) {\r\n <div [ngClass]=\"inputsMap[inputName].rowSize\">\r\n @switch (inputsMap[inputName].fieldType) {\r\n @case (fieldType.HIJRI_DATE_PICKER) {\r\n <app-dual-calendar [control]=\"getFormControl(inputName, formGroup)\"></app-dual-calendar>\r\n }\r\n\r\n @case (fieldType.DATE_PICKER) {\r\n <stc-date-picker [minDate]=\"inputsMap[inputName]?.dateRange?.min\" [maxDate]=\"inputsMap[inputName]?.dateRange?.max\"\r\n [id]=\"inputsMap[inputName].inputId\" [control]=\"getFormControl(inputName, formGroup)\" [name]=\"inputName\"\r\n [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [variant]=\"inputsMap[inputName].variant || 'over'\"\r\n [showIcon]=\"inputsMap[inputName].showIcon !== false\" [isTimeOnly]=\"inputsMap[inputName].isTimeOnly || false\" />\r\n }\r\n @case (fieldType.SELECT_BUTTON) {\r\n <stc-select-button [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\"\r\n [name]=\"inputName\" [label]=\"inputsMap[inputName].label\"\r\n [options]=\"inputsMap[inputName].selectButtonOptions || []\"\r\n (onChange)=\"selectButtonChange.emit({ name: inputName, value: $event })\" />\r\n }\r\n @case (fieldType.INPUT) {\r\n <stc-input [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\" [name]=\"inputName\"\r\n [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [type]=\"inputsMap[inputName].inputType || 'text'\"\r\n [contentType]=\"inputsMap[inputName].contentType || 'text'\" [rows]=\"inputsMap[inputName].rows || 2\"\r\n [cols]=\"inputsMap[inputName].cols || 20\" [autoResize]=\"inputsMap[inputName].autoResize ?? false\"\r\n [prefix]=\"inputsMap[inputName].prefix || ''\" [size]=\"inputsMap[inputName].size || 'small'\"\r\n [variant]=\"inputsMap[inputName].variant || 'over'\">\r\n @if(inputsMap[inputName].maxLength){\r\n <span class=\"text-xs text-gray-700\">\r\n {{ (getFormControl(inputName, formGroup).value?.length || 0) }}\r\n <span> / {{ inputsMap[inputName].maxLength}}</span>\r\n </span>\r\n }\r\n </stc-input>\r\n }\r\n @case (fieldType.SELECT) {\r\n <stc-select [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\"\r\n [name]=\"inputName\" [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [options]=\"inputsMap[inputName].selectOptions || []\"\r\n [optionLabel]=\"inputsMap[inputName]?.translatable\r\n ? ((inputsMap[inputName]?.optionLabel || 'label') | localizedLabel)\r\n : (inputsMap[inputName]?.optionLabel || 'label')\" [filter]=\"inputsMap[inputName].filter || false\"\r\n [multiple]=\"inputsMap[inputName].multiple || false\" [showClear]=\"inputsMap[inputName].showClear || false\"\r\n [checkmark]=\"inputsMap[inputName].checkmark ?? true\" [filterBy]=\"inputsMap[inputName].filterBy || ''\"\r\n [selectedItemsLabel]=\"inputsMap[inputName].selectedItemsLabel || ''\"\r\n [size]=\"inputsMap[inputName].size || 'small'\" [variant]=\"inputsMap[inputName].variant || 'over'\"\r\n (change)=\"selectChange.emit({ name: inputName, event: $event })\"\r\n (click)=\"selectClicked.emit({ name: inputName, event: $event })\" />\r\n }\r\n @case (fieldType.SWITCH) {\r\n <stc-switch [label]=\"inputsMap[inputName].label\" [key]=\"inputName\"\r\n [checked]=\"getFormControl(inputName, formGroup).value\"\r\n (onChange)=\"getFormControl(inputName, formGroup).setValue(typeof $event === 'string' ? ($event === 'true') : $event); switchChange.emit({ name: inputName, value: (typeof $event === 'string' ? ($event === 'true') : $event) })\" />\r\n }\r\n @case (fieldType.AUTO_COMPLETE) {\r\n <stc-auto-complete [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\"\r\n [name]=\"inputName\" [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [items]=\"inputsMap[inputName].autoCompleteItems || []\"\r\n [minLengthToSearch]=\"inputsMap[inputName].minLengthToSearch || 2\" [delay]=\"inputsMap[inputName].delay || 300\"\r\n (onSearch)=\"autoCompleteSearch.emit({ name: inputName, query: $event })\"\r\n (selectOption)=\"autoCompleteSelect.emit({ name: inputName, event: $event })\"\r\n [variant]=\"inputsMap[inputName].variant || 'over'\" />\r\n }\r\n @case(fieldType.UPLOAD_FILE) {\r\n <app-file-management #fileManager #groupFileManager [maxFileSize]=\"262144000\" [maxConcurrentUploads]=\"1\"\r\n [allowPreview]=\"true\" [acceptedTypes]=\"getAcceptedTypes()\" (filesUploaded)=\"onFilesUploaded($event)\"\r\n [control]=\"getFormControl(inputName, formGroup)\" (fileDeleted)=\"onFileDeleted($event)\" />\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n\r\n\r\n </div>\r\n <div class=\"col-span-12\">\r\n <small class=\"p-error text-red-700\">\r\n @for (error of formGroup.errors | validationErrors: dynamicFormData.formValidationErrorsKeys;\r\n track error) {\r\n {{ error }}\r\n }\r\n </small>\r\n </div>\r\n</form>", styles: [".dynamic-form__content>div{margin-bottom:15px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: DatePickerComponent, selector: "stc-date-picker", inputs: ["showIcon", "showClear", "basicInput", "isTimeOnly", "minDate", "maxDate", "hourFormat", "selectionMode", "variant", "withoutTime"], outputs: ["onAfterClearDate"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "component", type: SelectButtonComponent, selector: "stc-select-button", inputs: ["options", "title"], outputs: ["onChange"] }, { kind: "component", type: DualCalendarComponent, selector: "app-dual-calendar", inputs: ["control", "label", "name", "withTime", "isDatePickerShow", "currentLang", "isShown"], outputs: ["gregorianUTC", "onClose"] }, { kind: "component", type: InputComponent, selector: "stc-input", inputs: ["type", "contentType", "size", "prefix", "rows", "cols", "autoResize", "basicInput", "noStyle", "canClear", "hideOptionalLabel", "inputDirection", "variant", "defaultColor", "iconClass", "iconPosition"] }, { kind: "component", type: FileManagementComponent, selector: "app-file-management", inputs: ["existingFiles", "acceptedTypes", "maxFileSize", "maxConcurrentUploads", "showTable", "showDropZone", "allowPreview", "permissonKey", "allowedActions"], outputs: ["filesUploaded", "fileDeleted", "filePreview", "fileDownload", "uploadError", "newFilesChange"] }, { kind: "component", type: SelectComponent, selector: "stc-select", inputs: ["selectedItemTemplate", "optionTemplate", "options", "optionLabel", "optionValue", "emptyMessage", "checkmark", "showClear", "editable", "filter", "multiple", "filterBy", "selectAllLabel", "dataKey", "size", "selectedItemsLabel", "basicInput", "variant", "defaultColor"], outputs: ["change", "clicked"] }, { kind: "component", type: AutoCompleteComponent, selector: "stc-auto-complete", inputs: ["selectedItemTemplate", "items", "minLengthToSearch", "delay", "basicInput", "typeAhead", "variant"], outputs: ["onSearch", "selectOption"] }, { kind: "component", type: SwitchComponent, selector: "stc-switch", inputs: ["label", "key", "checked"], outputs: ["onChange"] }, { kind: "pipe", type: ValidationErrorsPipe, name: "validationErrors" }, { kind: "pipe", type: LocalizedLabelPipe, name: "localizedLabel" }] });
1909
1916
  }
1910
1917
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DynamicFormComponent, decorators: [{
1911
1918
  type: Component,
@@ -1922,8 +1929,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
1922
1929
  SelectComponent,
1923
1930
  AutoCompleteComponent,
1924
1931
  SwitchComponent,
1925
- LocalizedLabelPipe
1926
- ], template: "<form [formGroup]=\"formGroup\" class=\"dynamic-form\">\r\n <div class=\"grid grid-cols-12 gap-x-2 dynamic-form__content\">\r\n @for (inputName of inputsNames; track $index) {\r\n <div [ngClass]=\"inputsMap[inputName].rowSize\" >\r\n @switch (inputsMap[inputName].fieldType) {\r\n @case (fieldType.HIJRI_DATE_PICKER) {\r\n <app-dual-calendar [control]=\"getFormControl(inputName, formGroup)\"></app-dual-calendar>\r\n }\r\n\r\n @case (fieldType.DATE_PICKER) {\r\n <stc-date-picker [minDate]=\"inputsMap[inputName]?.dateRange?.min\" [maxDate]=\"inputsMap[inputName]?.dateRange?.max\"\r\n [id]=\"inputsMap[inputName].inputId\" [control]=\"getFormControl(inputName, formGroup)\" [name]=\"inputName\"\r\n [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [variant]=\"inputsMap[inputName].variant || 'over'\"\r\n [showIcon]=\"inputsMap[inputName].showIcon !== false\" [isTimeOnly]=\"inputsMap[inputName].isTimeOnly || false\" />\r\n }\r\n @case (fieldType.SELECT_BUTTON) {\r\n <stc-select-button [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\"\r\n [name]=\"inputName\" [label]=\"inputsMap[inputName].label\"\r\n [options]=\"inputsMap[inputName].selectButtonOptions || []\"\r\n (onChange)=\"selectButtonChange.emit({ name: inputName, value: $event })\" />\r\n }\r\n @case (fieldType.INPUT) {\r\n <stc-input [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\" [name]=\"inputName\"\r\n [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [type]=\"inputsMap[inputName].inputType || 'text'\"\r\n [contentType]=\"inputsMap[inputName].contentType || 'text'\" [rows]=\"inputsMap[inputName].rows || 2\"\r\n [cols]=\"inputsMap[inputName].cols || 20\" [autoResize]=\"inputsMap[inputName].autoResize ?? false\"\r\n [prefix]=\"inputsMap[inputName].prefix || ''\" [size]=\"inputsMap[inputName].size || 'small'\"\r\n [variant]=\"inputsMap[inputName].variant || 'over'\">\r\n @if(inputsMap[inputName].maxLength){\r\n <span class=\"text-xs text-gray-700\">\r\n {{ (getFormControl(inputName, formGroup).value?.length || 0) }}\r\n <span> / {{ inputsMap[inputName].maxLength}}</span>\r\n </span>\r\n }\r\n </stc-input>\r\n }\r\n @case (fieldType.SELECT) {\r\n <stc-select [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\"\r\n [name]=\"inputName\" [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [options]=\"inputsMap[inputName].selectOptions || []\"\r\n [optionLabel]=\"inputsMap[inputName]?.translatable\r\n ? ((inputsMap[inputName]?.optionLabel || 'label') | localizedLabel)\r\n : (inputsMap[inputName]?.optionLabel || 'label')\"\r\n [filter]=\"inputsMap[inputName].filter || false\"\r\n [multiple]=\"inputsMap[inputName].multiple || false\" [showClear]=\"inputsMap[inputName].showClear || false\"\r\n [checkmark]=\"inputsMap[inputName].checkmark ?? true\" [filterBy]=\"inputsMap[inputName].filterBy || ''\"\r\n [selectedItemsLabel]=\"inputsMap[inputName].selectedItemsLabel || ''\"\r\n [size]=\"inputsMap[inputName].size || 'small'\" [variant]=\"inputsMap[inputName].variant || 'over'\"\r\n (change)=\"selectChange.emit({ name: inputName, event: $event })\" />\r\n }\r\n @case (fieldType.SWITCH) {\r\n <stc-switch [label]=\"inputsMap[inputName].label\" [key]=\"inputName\"\r\n [checked]=\"getFormControl(inputName, formGroup).value\"\r\n (onChange)=\"getFormControl(inputName, formGroup).setValue(typeof $event === 'string' ? ($event === 'true') : $event); switchChange.emit({ name: inputName, value: (typeof $event === 'string' ? ($event === 'true') : $event) })\" />\r\n }\r\n @case (fieldType.AUTO_COMPLETE) {\r\n <stc-auto-complete [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\"\r\n [name]=\"inputName\" [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [items]=\"inputsMap[inputName].autoCompleteItems || []\"\r\n [minLengthToSearch]=\"inputsMap[inputName].minLengthToSearch || 2\" [delay]=\"inputsMap[inputName].delay || 300\"\r\n (onSearch)=\"autoCompleteSearch.emit({ name: inputName, query: $event })\"\r\n (selectOption)=\"autoCompleteSelect.emit({ name: inputName, event: $event })\"\r\n [variant]=\"inputsMap[inputName].variant || 'over'\" />\r\n }\r\n @case(fieldType.UPLOAD_FILE) {\r\n <app-file-management #fileManager #groupFileManager [maxFileSize]=\"262144000\" [maxConcurrentUploads]=\"1\"\r\n [allowPreview]=\"true\" [acceptedTypes]=\"getAcceptedTypes()\" (filesUploaded)=\"onFilesUploaded($event)\" [control]=\"getFormControl(inputName, formGroup)\" (fileDeleted)=\"onFileDeleted($event)\" />\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n\r\n\r\n </div>\r\n <div class=\"col-span-12\">\r\n <small class=\"p-error text-red-700\">\r\n @for (error of formGroup.errors | validationErrors: dynamicFormData.formValidationErrorsKeys;\r\n track error) {\r\n {{ error }}\r\n }\r\n </small>\r\n </div>\r\n</form>\r\n", styles: [".dynamic-form__content>div{margin-bottom:15px}\n"] }]
1932
+ LocalizedLabelPipe,
1933
+ ], template: "<form [formGroup]=\"formGroup\" class=\"dynamic-form\">\r\n <div class=\"grid grid-cols-12 gap-x-2 dynamic-form__content\">\r\n @for (inputName of inputsNames; track $index) {\r\n <div [ngClass]=\"inputsMap[inputName].rowSize\">\r\n @switch (inputsMap[inputName].fieldType) {\r\n @case (fieldType.HIJRI_DATE_PICKER) {\r\n <app-dual-calendar [control]=\"getFormControl(inputName, formGroup)\"></app-dual-calendar>\r\n }\r\n\r\n @case (fieldType.DATE_PICKER) {\r\n <stc-date-picker [minDate]=\"inputsMap[inputName]?.dateRange?.min\" [maxDate]=\"inputsMap[inputName]?.dateRange?.max\"\r\n [id]=\"inputsMap[inputName].inputId\" [control]=\"getFormControl(inputName, formGroup)\" [name]=\"inputName\"\r\n [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [variant]=\"inputsMap[inputName].variant || 'over'\"\r\n [showIcon]=\"inputsMap[inputName].showIcon !== false\" [isTimeOnly]=\"inputsMap[inputName].isTimeOnly || false\" />\r\n }\r\n @case (fieldType.SELECT_BUTTON) {\r\n <stc-select-button [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\"\r\n [name]=\"inputName\" [label]=\"inputsMap[inputName].label\"\r\n [options]=\"inputsMap[inputName].selectButtonOptions || []\"\r\n (onChange)=\"selectButtonChange.emit({ name: inputName, value: $event })\" />\r\n }\r\n @case (fieldType.INPUT) {\r\n <stc-input [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\" [name]=\"inputName\"\r\n [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [type]=\"inputsMap[inputName].inputType || 'text'\"\r\n [contentType]=\"inputsMap[inputName].contentType || 'text'\" [rows]=\"inputsMap[inputName].rows || 2\"\r\n [cols]=\"inputsMap[inputName].cols || 20\" [autoResize]=\"inputsMap[inputName].autoResize ?? false\"\r\n [prefix]=\"inputsMap[inputName].prefix || ''\" [size]=\"inputsMap[inputName].size || 'small'\"\r\n [variant]=\"inputsMap[inputName].variant || 'over'\">\r\n @if(inputsMap[inputName].maxLength){\r\n <span class=\"text-xs text-gray-700\">\r\n {{ (getFormControl(inputName, formGroup).value?.length || 0) }}\r\n <span> / {{ inputsMap[inputName].maxLength}}</span>\r\n </span>\r\n }\r\n </stc-input>\r\n }\r\n @case (fieldType.SELECT) {\r\n <stc-select [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\"\r\n [name]=\"inputName\" [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [options]=\"inputsMap[inputName].selectOptions || []\"\r\n [optionLabel]=\"inputsMap[inputName]?.translatable\r\n ? ((inputsMap[inputName]?.optionLabel || 'label') | localizedLabel)\r\n : (inputsMap[inputName]?.optionLabel || 'label')\" [filter]=\"inputsMap[inputName].filter || false\"\r\n [multiple]=\"inputsMap[inputName].multiple || false\" [showClear]=\"inputsMap[inputName].showClear || false\"\r\n [checkmark]=\"inputsMap[inputName].checkmark ?? true\" [filterBy]=\"inputsMap[inputName].filterBy || ''\"\r\n [selectedItemsLabel]=\"inputsMap[inputName].selectedItemsLabel || ''\"\r\n [size]=\"inputsMap[inputName].size || 'small'\" [variant]=\"inputsMap[inputName].variant || 'over'\"\r\n (change)=\"selectChange.emit({ name: inputName, event: $event })\"\r\n (click)=\"selectClicked.emit({ name: inputName, event: $event })\" />\r\n }\r\n @case (fieldType.SWITCH) {\r\n <stc-switch [label]=\"inputsMap[inputName].label\" [key]=\"inputName\"\r\n [checked]=\"getFormControl(inputName, formGroup).value\"\r\n (onChange)=\"getFormControl(inputName, formGroup).setValue(typeof $event === 'string' ? ($event === 'true') : $event); switchChange.emit({ name: inputName, value: (typeof $event === 'string' ? ($event === 'true') : $event) })\" />\r\n }\r\n @case (fieldType.AUTO_COMPLETE) {\r\n <stc-auto-complete [control]=\"getFormControl(inputName, formGroup)\" [id]=\"inputsMap[inputName].inputId\"\r\n [name]=\"inputName\" [label]=\"inputsMap[inputName].label\" [placeholder]=\"inputsMap[inputName].placeholder || ''\"\r\n [hint]=\"inputsMap[inputName].hint\"\r\n [readonly]=\"inputsMap[inputName].readonly || dynamicFormData.isReadOnlyForm || false\"\r\n [disabled]=\"inputsMap[inputName].disabled || false\" [items]=\"inputsMap[inputName].autoCompleteItems || []\"\r\n [minLengthToSearch]=\"inputsMap[inputName].minLengthToSearch || 2\" [delay]=\"inputsMap[inputName].delay || 300\"\r\n (onSearch)=\"autoCompleteSearch.emit({ name: inputName, query: $event })\"\r\n (selectOption)=\"autoCompleteSelect.emit({ name: inputName, event: $event })\"\r\n [variant]=\"inputsMap[inputName].variant || 'over'\" />\r\n }\r\n @case(fieldType.UPLOAD_FILE) {\r\n <app-file-management #fileManager #groupFileManager [maxFileSize]=\"262144000\" [maxConcurrentUploads]=\"1\"\r\n [allowPreview]=\"true\" [acceptedTypes]=\"getAcceptedTypes()\" (filesUploaded)=\"onFilesUploaded($event)\"\r\n [control]=\"getFormControl(inputName, formGroup)\" (fileDeleted)=\"onFileDeleted($event)\" />\r\n }\r\n }\r\n </div>\r\n }\r\n\r\n\r\n\r\n </div>\r\n <div class=\"col-span-12\">\r\n <small class=\"p-error text-red-700\">\r\n @for (error of formGroup.errors | validationErrors: dynamicFormData.formValidationErrorsKeys;\r\n track error) {\r\n {{ error }}\r\n }\r\n </small>\r\n </div>\r\n</form>", styles: [".dynamic-form__content>div{margin-bottom:15px}\n"] }]
1927
1934
  }], propDecorators: { dynamicFormData: [{
1928
1935
  type: Input,
1929
1936
  args: [{ required: true }]
@@ -1931,6 +1938,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
1931
1938
  type: Output
1932
1939
  }], selectChange: [{
1933
1940
  type: Output
1941
+ }], selectClicked: [{
1942
+ type: Output
1934
1943
  }], switchChange: [{
1935
1944
  type: Output
1936
1945
  }], autoCompleteSearch: [{
@@ -1983,7 +1992,7 @@ class ConfirmationDialogComponent extends DynamicDialogRef {
1983
1992
  onFileDeleted(file) {
1984
1993
  }
1985
1994
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfirmationDialogComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1986
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ConfirmationDialogComponent, isStandalone: true, selector: "app-confirm-dialog", providers: [DialogService, DynamicDialogStyle], usesInheritance: true, ngImport: i0, template: "@if (dynamicDialogConfig.data) {\r\n<div class=\"confirmation-dialog\">\r\n <div class=\"dialog-wrapper\">\r\n @if (dynamicDialogConfig.data) {\r\n <div class=\"confirmation-dialog__content my-4\">\r\n @if (dynamicDialogConfig.data.dialogIcon) {\r\n <em [class]=\"dynamicDialogConfig.data.dialogIcon\"></em>\r\n }\r\n <p class=\"confirmation-dialog__message text-xl mb-2\">\r\n {{ dynamicDialogConfig.data.message }}\r\n </p>\r\n @if (dynamicDialogConfig.data.hint) {\r\n <p class=\"confirmation-dialog__hint font-normal text-base\">\r\n {{ dynamicDialogConfig.data.hint }}\r\n </p>\r\n }\r\n @if (dynamicDialogConfig.data.inputForm) {\r\n <app-dynamic-form [dynamicFormData]=\"dialogFormData\" (popUpFilesUploaded)=\"onPopFilesUploaded($event)\" (fileDeleted)=\"onFileDeleted($event)\" ></app-dynamic-form>\r\n }\r\n </div>\r\n }\r\n <div class=\"confirmation-dialog__actions flex gap-2 mt-4\">\r\n <app-button [title]=\"dynamicDialogConfig.data?.confirmLabel || ('actions.confirm' | translate)\"\r\n [disabled]=\"!!(dialogFormData && dialogFormData.formGroup?.invalid)\" [severity]=\"'primary'\"\r\n [id]=\"dynamicDialogConfig.data.confirmBtnId\" [icon]=\"dynamicDialogConfig.data.confirmBtnIcon || ''\"\r\n [label]=\"dynamicDialogConfig.data.confirmBtnLabel\"\r\n [iconPos]=\"dynamicDialogConfig.data.confirmBtnPosition || 'left'\" [styleClass]=\"'confirmation-btn'\"\r\n (click)=\"submit()\" />\r\n <app-button [title]=\"dynamicDialogConfig.data?.closeLabel || ('actions.cancel' | translate)\"\r\n [severity]=\"'primary'\" variant=\"outlined\" [label]=\"dynamicDialogConfig.data.cancelBtnLabel\"\r\n [id]=\"dynamicDialogConfig.data.cancelBtnId\" [styleClass]=\"'cancel-btn confirmation-btn cancel-btn'\"\r\n (click)=\"close()\" />\r\n </div>\r\n </div>\r\n\r\n</div>\r\n}\r\n", styles: [""], dependencies: [{ kind: "component", type: AppButtonComponent, selector: "app-button" }, { kind: "ngmodule", type: AvatarModule }, { kind: "ngmodule", type: DynamicDialogModule }, { kind: "component", type: DynamicFormComponent, selector: "app-dynamic-form", inputs: ["dynamicFormData"], outputs: ["selectButtonChange", "selectChange", "switchChange", "autoCompleteSearch", "autoCompleteSelect", "popUpFilesUploaded", "fileDeleted"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None });
1995
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ConfirmationDialogComponent, isStandalone: true, selector: "app-confirm-dialog", providers: [DialogService, DynamicDialogStyle], usesInheritance: true, ngImport: i0, template: "@if (dynamicDialogConfig.data) {\r\n<div class=\"confirmation-dialog\">\r\n <div class=\"dialog-wrapper\">\r\n @if (dynamicDialogConfig.data) {\r\n <div class=\"confirmation-dialog__content my-4\">\r\n @if (dynamicDialogConfig.data.dialogIcon) {\r\n <em [class]=\"dynamicDialogConfig.data.dialogIcon\"></em>\r\n }\r\n <p class=\"confirmation-dialog__message text-xl mb-2\">\r\n {{ dynamicDialogConfig.data.message }}\r\n </p>\r\n @if (dynamicDialogConfig.data.hint) {\r\n <p class=\"confirmation-dialog__hint font-normal text-base\">\r\n {{ dynamicDialogConfig.data.hint }}\r\n </p>\r\n }\r\n @if (dynamicDialogConfig.data.inputForm) {\r\n <app-dynamic-form [dynamicFormData]=\"dialogFormData\" (popUpFilesUploaded)=\"onPopFilesUploaded($event)\" (fileDeleted)=\"onFileDeleted($event)\" ></app-dynamic-form>\r\n }\r\n </div>\r\n }\r\n <div class=\"confirmation-dialog__actions flex gap-2 mt-4\">\r\n <app-button [title]=\"dynamicDialogConfig.data?.confirmLabel || ('actions.confirm' | translate)\"\r\n [disabled]=\"!!(dialogFormData && dialogFormData.formGroup?.invalid)\" [severity]=\"'primary'\"\r\n [id]=\"dynamicDialogConfig.data.confirmBtnId\" [icon]=\"dynamicDialogConfig.data.confirmBtnIcon || ''\"\r\n [label]=\"dynamicDialogConfig.data.confirmBtnLabel\"\r\n [iconPos]=\"dynamicDialogConfig.data.confirmBtnPosition || 'left'\" [styleClass]=\"'confirmation-btn'\"\r\n (click)=\"submit()\" />\r\n <app-button [title]=\"dynamicDialogConfig.data?.closeLabel || ('actions.cancel' | translate)\"\r\n [severity]=\"'primary'\" variant=\"outlined\" [label]=\"dynamicDialogConfig.data.cancelBtnLabel\"\r\n [id]=\"dynamicDialogConfig.data.cancelBtnId\" [styleClass]=\"'cancel-btn confirmation-btn cancel-btn'\"\r\n (click)=\"close()\" />\r\n </div>\r\n </div>\r\n\r\n</div>\r\n}\r\n", styles: [""], dependencies: [{ kind: "component", type: AppButtonComponent, selector: "app-button" }, { kind: "ngmodule", type: AvatarModule }, { kind: "ngmodule", type: DynamicDialogModule }, { kind: "component", type: DynamicFormComponent, selector: "app-dynamic-form", inputs: ["dynamicFormData"], outputs: ["selectButtonChange", "selectChange", "selectClicked", "switchChange", "autoCompleteSearch", "autoCompleteSelect", "popUpFilesUploaded", "fileDeleted"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None });
1987
1996
  }
1988
1997
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ConfirmationDialogComponent, decorators: [{
1989
1998
  type: Component,