tailjng 0.0.60 → 0.0.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/cli/settings/components-list.js +7 -3
  2. package/cli/settings/header-generator.js +1 -1
  3. package/package.json +1 -1
  4. package/src/lib/components/card/card-complete/complete-card.component.html +1 -1
  5. package/src/lib/components/card/card-crud-complete/complete-crud-card.component.html +1 -1
  6. package/src/lib/components/filter/filter-complete/complete-filter.component.html +6 -1
  7. package/src/lib/components/filter/filter-complete/complete-filter.component.ts +3 -1
  8. package/src/lib/components/form/form-sidebar/sidebar-form.component.html +130 -97
  9. package/src/lib/components/form/form-sidebar/sidebar-form.component.ts +3 -2
  10. package/src/lib/components/input/input/input.component.css +35 -0
  11. package/src/lib/components/input/input/input.component.html +37 -27
  12. package/src/lib/components/input/input/input.component.ts +1 -0
  13. package/src/lib/components/menu/options-coach-menu/options-coach-menu.component.html +53 -0
  14. package/src/lib/components/menu/options-coach-menu/options-coach-menu.component.scss +0 -0
  15. package/src/lib/components/menu/options-coach-menu/options-coach-menu.component.ts +41 -0
  16. package/src/lib/components/paginator/paginator-complete/complete-paginator.component.html +8 -1
  17. package/src/lib/components/paginator/paginator-complete/complete-paginator.component.ts +2 -1
  18. package/src/lib/components/select/select-dropdown/dropdown-select.component.html +155 -83
  19. package/src/lib/components/select/select-dropdown/dropdown-select.component.ts +14 -2
  20. package/src/lib/components/select/select-multi-table/multi-table-select.component.html +2 -0
  21. package/src/lib/components/select/select-multi-table/multi-table-select.component.ts +12 -0
  22. package/src/lib/components/table/table-complete/complete-table.component.html +1 -1
  23. package/src/lib/components/table/table-complete/complete-table.component.scss +0 -5
  24. package/src/lib/components/table/table-crud-complete/complete-crud-table.component.html +9 -6
  25. package/src/lib/components/table/table-crud-complete/complete-crud-table.component.ts +3 -2
@@ -108,7 +108,7 @@ function getComponentList() {
108
108
  },
109
109
  'form-sidebar': {
110
110
  path: "src/lib/components/form/form-sidebar",
111
- dependencies: ["tooltip", "button", "checkbox-switch"],
111
+ dependencies: ["tooltip", "button", "checkbox-switch", "coach-mark"],
112
112
  },
113
113
  'paginator-complete': {
114
114
  path: "src/lib/components/paginator/paginator-complete",
@@ -130,17 +130,21 @@ function getComponentList() {
130
130
  path: "src/lib/components/menu/menu-options-table",
131
131
  dependencies: ["button"],
132
132
  },
133
+ 'options-coach-menu': {
134
+ path: "src/lib/components/menu/options-coach-menu",
135
+ dependencies: ["button", "coach-mark"],
136
+ },
133
137
 
134
138
 
135
139
 
136
140
 
137
141
  'table-crud-complete': {
138
142
  path: "src/lib/components/table/table-crud-complete",
139
- dependencies: ["button", "paginator-complete", "filter-complete", "checkbox-input", "menu-options-table", "dialog", "viewer-image", "select-dropdown", "input"],
143
+ dependencies: ["button", "paginator-complete", "filter-complete", "checkbox-input", "options-coach-menu", "dialog", "viewer-image", "select-dropdown", "input"],
140
144
  },
141
145
  'table-complete': {
142
146
  path: "src/lib/components/table/table-complete",
143
- dependencies: ["button", "paginator-complete", "filter-complete", "checkbox-input", "menu-options-table", "dialog", "viewer-image", "select-dropdown", "input"],
147
+ dependencies: ["button", "paginator-complete", "filter-complete", "checkbox-input", "options-coach-menu", "dialog", "viewer-image", "select-dropdown", "input"],
144
148
  },
145
149
  'theme-generator': {
146
150
  path: "src/lib/components/theme-generator",
@@ -27,7 +27,7 @@ Authors:
27
27
  License:
28
28
  This project is licensed under the BSD 3-Clause - see the LICENSE file for more details.
29
29
 
30
- Version: 0.0.59
30
+ Version: 0.0.62
31
31
  Creation Date: 2025-01-04
32
32
  ===============================================`
33
33
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tailjng",
3
- "version": "0.0.60",
3
+ "version": "0.0.62",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^19.2.0",
6
6
  "@angular/core": "^19.2.0",
@@ -53,7 +53,7 @@
53
53
  } @else if (displayData.length > 0) {
54
54
 
55
55
  @if (itemTemplate) {
56
- <div class="grid grid-cols-4 items-start max-[1300px]:grid-cols-3 max-[1150px]:grid-cols-2 max-[800px]:grid-cols-1 gap-4 my-4">
56
+ <div class="grid grid-cols-4 max-[1200px]:grid-cols-3 max-[950px]:grid-cols-2 max-[650px]:grid-cols-1 items-start gap-4 my-4">
57
57
  @for (item of displayData; track trackById($index, item)) {
58
58
  <div class="flex flex-col gap-3 rounded-xl border border-border dark:border-dark-border bg-white dark:bg-foreground shadow-sm hover:shadow-lg hover:border-primary/50 hover:dark:border-primary transition-all duration-300">
59
59
  <ng-container
@@ -53,7 +53,7 @@
53
53
  } @else if (displayData.length > 0) {
54
54
 
55
55
  @if (itemTemplate) {
56
- <div class="grid grid-cols-4 items-start max-[1300px]:grid-cols-3 max-[1150px]:grid-cols-2 max-[800px]:grid-cols-1 gap-4 my-4">
56
+ <div class="grid grid-cols-4 max-[1200px]:grid-cols-3 max-[950px]:grid-cols-2 max-[650px]:grid-cols-1 items-start gap-4 my-4">
57
57
  @for (item of displayData; track trackById($index, item)) {
58
58
  <div class="flex flex-col rounded-xl border border-border dark:border-dark-border bg-white dark:bg-foreground shadow-sm hover:shadow-lg hover:border-primary/50 hover:dark:border-primary transition-all duration-300">
59
59
  <ng-container
@@ -9,7 +9,10 @@
9
9
  type="text"
10
10
  [(ngModel)]="searchQuery"
11
11
  [placeholder]="searchPlaceholder"
12
- class="input w-full w-full min-[400px]:min-w-[275px] h-[40px] max-[400px]:h-[35px] text-[12px] bg-background dark:bg-dark-background border border-border dark:border-dark-border text-black dark:text-white placeholder:text-muted-foreground/70 dark:placeholder:text-dark-muted-foreground/70 rounded px-3 py-2 pr-12 max-[400px]:pr-10 focus:outline-none focus:ring-2 focus:ring-primary dark:focus:ring-dark-primary transition duration-200 resize-y disabled:opacity-60 disabled:cursor-not-allowed"
12
+ class="input w-[250px] max-[768px]:w-full! h-[40px] max-[400px]:h-[35px] text-[12px] bg-background dark:bg-dark-background border border-border dark:border-dark-border text-black dark:text-white placeholder:text-muted-foreground/70 dark:placeholder:text-dark-muted-foreground/70 rounded px-3 py-2 pr-12 max-[400px]:pr-10 focus:outline-none focus:ring-2 focus:ring-primary dark:focus:ring-dark-primary transition duration-200 resize-y disabled:opacity-60 disabled:cursor-not-allowed"
13
+ [ngClass]="{
14
+ 'bg-white dark:bg-foreground': !isbackground
15
+ }"
13
16
  />
14
17
 
15
18
  <div
@@ -57,6 +60,7 @@
57
60
  placeholder="Mostrar"
58
61
  title="Mostrar elementos"
59
62
  [options]="itemsPerPageOptions"
63
+ [ngClasses]="{ '!bg-white dark:!bg-foreground': !isbackground }"
60
64
  />
61
65
  </div>
62
66
  }
@@ -68,6 +72,7 @@
68
72
  type="multi-table"
69
73
  title="Seleccionar columnas"
70
74
  [columns]="visibleColumns"
75
+ [ngClasses]="{ '!bg-white dark:!bg-foreground': !isbackground }"
71
76
  />
72
77
  </div>
73
78
  }
@@ -1,4 +1,5 @@
1
1
  import { Component, EventEmitter, Input, Output, OnDestroy, OnInit, ViewChild, ElementRef } from '@angular/core';
2
+ import { NgClass } from '@angular/common';
2
3
  import { FormsModule } from '@angular/forms';
3
4
  import { LucideAngularModule } from 'lucide-angular';
4
5
  import { Subject, Subscription, debounceTime, filter, forkJoin } from 'rxjs';
@@ -12,7 +13,7 @@ import { JButtonComponent } from '../../button/button.component';
12
13
  @Component({
13
14
  selector: 'JFilter',
14
15
  standalone: true,
15
- imports: [LucideAngularModule, JDropdownSelectComponent, JMultiTableSelectComponent, JButtonComponent, JDialogComponent, FormsModule, JSwitchCheckboxComponent],
16
+ imports: [LucideAngularModule, JDropdownSelectComponent, JMultiTableSelectComponent, JButtonComponent, JDialogComponent, FormsModule, JSwitchCheckboxComponent, NgClass],
16
17
  templateUrl: './complete-filter.component.html',
17
18
  styleUrls: ['./complete-filter.component.scss'],
18
19
  providers: [JDialogComponent]
@@ -35,6 +36,7 @@ export class JCompleteFilterComponent implements OnInit, OnDestroy {
35
36
  @Input() isShowColumns: boolean = true;
36
37
  @Input() mainEndpoint!: string;
37
38
  @Input() data: any[] = [];
39
+ @Input() isbackground: boolean = false;
38
40
 
39
41
  @Input() isItemsPerPage: boolean = true;
40
42
  @Input() itemsPerPageOptions: number[] = [];
@@ -1,101 +1,134 @@
1
1
  <section class="content_form">
2
-
3
- <!-- Overlay -->
4
- @if (openForm) {
5
- <div onKeyPress class="fixed top-0 left-0 w-full h-full bg-black/50 z-[998] transition duration-300" (click)="canCloseOverlay ? onClose() : null"></div>
6
- }
7
-
8
- <!-- Sidebar personalizado -->
9
- @if (openForm) {
10
- <div @sidebarTransition
11
- class="fixed top-0 right-0 h-full max-w-full border border-border dark:border-dark-border rounded-tl-[15px] rounded-bl-[15px] text-white shadow-lg z-[999] flex flex-col"
12
- [style]="style"
13
- [ngClass]="bgColor"
14
- [class.w-[22em]]="size==='small'"
15
- [class.w-[30em]]="size==='medium'"
16
- [class.w-[47em]]="size==='large'"
17
- [class.w-[65em]]="size==='xlarge'"
2
+ <!-- Overlay -->
3
+ @if (openForm) {
4
+ <div
5
+ onKeyPress
6
+ class="fixed top-0 left-0 w-full h-full bg-black/50 z-[999] transition duration-300"
7
+ (click)="canCloseOverlay ? onClose() : null"
8
+ ></div>
9
+ }
10
+
11
+ <!-- Sidebar personalizado -->
12
+ @if (openForm) {
13
+ <div
14
+ @sidebarTransition
15
+ class="fixed top-0 right-0 h-full max-w-full border border-border dark:border-dark-border rounded-tl-[15px] rounded-bl-[15px] text-white shadow-lg z-[999] flex flex-col"
16
+ [style]="style"
17
+ [ngClass]="bgColor"
18
+ [class.w-[22em]]="size === 'small'"
19
+ [class.w-[30em]]="size === 'medium'"
20
+ [class.w-[47em]]="size === 'large'"
21
+ [class.w-[65em]]="size === 'xlarge'"
22
+ >
23
+ <!-- Header -->
24
+ <div
25
+ class="flex p-2 pl-4 pr-4 justify-between items-center bg-primary dark:bg-dark-primary border-b border-border dark:border-dark-border rounded-tl-[15px] font-semibold text-2sm"
26
+ >
27
+ <div class="flex items-center gap-2">
28
+ <span>
29
+ {{
30
+ typeForm !== "none"
31
+ ? typeForm === "create"
32
+ ? "AGREGAR"
33
+ : "ACTUALIZAR"
34
+ : "REGISTROS"
35
+ }}
36
+ {{ typeForm !== "none" ? titleForm : "" }}
37
+ </span>
38
+
39
+ <JButton
40
+ jTooltip="Información"
41
+ jTooltipPosition="bottom"
42
+ jCoachMark
43
+ [coachContent]="coachContentChangePassword"
44
+ coachPosition="bottom"
45
+ coachTrigger="click"
46
+ [icon]="iconsService.icons.info"
47
+ classes="border-none shadow-none p-0 m-0 h-5 w-5 text-white"
48
+ />
49
+ </div>
50
+
51
+ <ng-template #coachContentChangePassword>
52
+ <div class="text-[12px] leading-[15px]">
53
+ <span>
54
+ Las etiquetas con <span class="text-[10px]">✱</span> indican
55
+ campos requeridos.
56
+ </span>
57
+ <br />
58
+ <span>
59
+ <span class="text-red-600 dark:text-red-300">✱</span>
60
+ Obligatorio
61
+ </span>
62
+ <br />
63
+ <span>
64
+ <span class="text-blue-600 dark:text-blue-300">✱</span>
65
+ Condicionado
66
+ </span>
67
+ <br />
68
+ <span>
69
+ <span class="text-purple-600 dark:text-purple-300">✱</span>
70
+ Automático
71
+ </span>
72
+ </div>
73
+ </ng-template>
74
+
75
+ <div class="flex gap-2">
76
+ @for (cb of checkboxes; track $index) {
77
+ @if (cb.isVisible) {
78
+ <JSwitchCheckbox
79
+ onKeyPress
80
+ [title]="cb.title"
81
+ [isChecked]="cb.isChecked"
82
+ [isLoading]="cb.isLoading"
83
+ (click)="cb.onClick(!cb.isChecked, $index)"
84
+ />
85
+ }
86
+ }
87
+ </div>
88
+
89
+ <button
90
+ type="button"
91
+ (click)="onClose()"
92
+ class="p-2 rounded-full border border-border dark:border-dark-border text-white hover:bg-dark-background focus:outline-none cursor-pointer"
18
93
  >
19
- <!-- Header -->
20
- <div class="flex p-2 pl-4 pr-4 justify-between items-center bg-primary dark:bg-dark-primary border-b border-border dark:border-dark-border rounded-tl-[15px] font-semibold text-2sm">
21
- <div class="flex items-center gap-2">
22
- <span>
23
- {{ typeForm !== 'none' ? typeForm === 'create' ? 'AGREGAR' : 'ACTUALIZAR' : 'REGISTROS' }} {{ typeForm !== 'none' ? titleForm : '' }}
24
- </span>
25
-
26
- <div class="cursor-pointer"
27
- [jTooltip]="tooltipContentChangePassword"
28
- [jTooltipPosition]="'bottom'"
29
- [jTooltipOffsetX]="25"
30
- [jTooltipOffsetY]="-20"
31
- >
32
- <lucide-icon [name]="iconsService.icons.info" [size]="15"></lucide-icon>
33
- </div>
34
- </div>
35
-
36
-
37
- <ng-template #tooltipContentChangePassword>
38
- <div class="text-[12px] leading-[15px]">
39
- <span>Las etiquetas con ✱ indican campos requeridos.</span> <br>
40
- <span><span class="text-red-600 dark:text-red-300">✱</span> Obligatorio</span> <br>
41
- <span><span class="text-blue-600 dark:text-blue-300">✱</span> Condicionado</span> <br>
42
- <span><span class="text-purple-600 dark:text-purple-300">✱</span> Automático</span> <br>
43
- </div>
44
- </ng-template>
45
-
46
-
47
- <div class="flex gap-2">
48
- @for (cb of checkboxes; track $index) {
49
- @if (cb.isVisible) {
50
- <JSwitchCheckbox onKeyPress
51
- [title]="cb.title"
52
- [isChecked]="cb.isChecked"
53
- [isLoading]="cb.isLoading"
54
- (click)="cb.onClick(!cb.isChecked, $index)"
55
- />
56
- }
57
- }
58
- </div>
59
-
60
- <button type="button" (click)="onClose()" class="p-2 rounded-full border border-border dark:border-dark-border text-white hover:bg-dark-background focus:outline-none cursor-pointer">
61
- <lucide-icon [name]="iconsService.icons.close" size="16"></lucide-icon>
62
- </button>
63
- </div>
64
-
65
-
66
- <!-- Content -->
67
- <div class="p-4 flex-1 overflow-x-hidden overflow-y-auto scroll-element">
68
- @if (formTemplate) {
69
- <ng-container [ngTemplateOutlet]="formTemplate"></ng-container>
70
- }
71
- </div>
72
-
73
-
74
- <!-- Footer -->
75
- @if (typeForm !== 'none') {
76
- <div class="p-4 border-t border-border dark:border-dark-border rounded-bl-[15px] flex justify-center gap-3">
77
-
78
- <JButton
79
- type="submit"
80
- (clicked)="onSubmit()"
81
- classes="primary"
82
- [icon]="iconsService.icons.save"
83
- [isLoading]="isLoading"
84
- >
85
- {{typeForm === 'create' ? 'AGREGAR' : 'ACTUALIZAR'}}
86
- </JButton>
87
-
88
- <JButton
89
- type="button"
90
- (clicked)="onClose()"
91
- classes="secondary"
92
- [icon]="iconsService.icons.error"
93
- text="CANCELAR"
94
- />
95
-
96
- </div>
94
+ <lucide-icon
95
+ [name]="iconsService.icons.close"
96
+ size="16"
97
+ ></lucide-icon>
98
+ </button>
99
+ </div>
100
+
101
+ <!-- Content -->
102
+ <div class="p-4 flex-1 overflow-x-hidden overflow-y-auto scroll-element">
103
+ @if (formTemplate) {
104
+ <ng-container [ngTemplateOutlet]="formTemplate"></ng-container>
97
105
  }
98
- </div>
99
- }
106
+ </div>
100
107
 
101
- </section>
108
+ <!-- Footer -->
109
+ @if (typeForm !== "none") {
110
+ <div
111
+ class="p-4 border-t border-border dark:border-dark-border rounded-bl-[15px] flex justify-center gap-3"
112
+ >
113
+ <JButton
114
+ type="submit"
115
+ (clicked)="onSubmit()"
116
+ classes="primary"
117
+ [icon]="iconsService.icons.save"
118
+ [isLoading]="isLoading"
119
+ >
120
+ {{ typeForm === "create" ? "AGREGAR" : "ACTUALIZAR" }}
121
+ </JButton>
122
+
123
+ <JButton
124
+ type="button"
125
+ (clicked)="onClose()"
126
+ classes="secondary"
127
+ [icon]="iconsService.icons.error"
128
+ text="CANCELAR"
129
+ />
130
+ </div>
131
+ }
132
+ </div>
133
+ }
134
+ </section>
@@ -7,11 +7,12 @@ import { DynamicCheckbox, FormType, JIconsService } from 'tailjng';
7
7
  import { JTooltipDirective } from '../../tooltip/tooltip.directive';
8
8
  import { JButtonComponent } from '../../button/button.component';
9
9
  import { JSwitchCheckboxComponent } from '../../checkbox/checkbox-switch/switch-checkbox.component';
10
+ import { JCoachMarkDirective } from '../../coach-mark/coach-mark.directive';
10
11
 
11
12
  @Component({
12
13
  selector: 'JSidebarForm',
13
14
  standalone: true,
14
- imports: [LucideAngularModule, JButtonComponent, JTooltipDirective, ReactiveFormsModule, FormsModule, CommonModule, JSwitchCheckboxComponent],
15
+ imports: [LucideAngularModule, JButtonComponent, JTooltipDirective, ReactiveFormsModule, FormsModule, CommonModule, JSwitchCheckboxComponent, JCoachMarkDirective],
15
16
  templateUrl: './sidebar-form.component.html',
16
17
  styleUrl: './sidebar-form.component.scss',
17
18
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
@@ -61,4 +62,4 @@ export class JSidebarFormComponent {
61
62
  this.onClose();
62
63
  }
63
64
  }
64
- }
65
+ }
@@ -0,0 +1,35 @@
1
+ @media (max-width: 400px) {
2
+ .input-container {
3
+ width: 100%;
4
+ }
5
+
6
+ input[type="date"] {
7
+ appearance: none !important;
8
+ -webkit-appearance: none !important;
9
+ }
10
+
11
+ input[type="date"]::-webkit-calendar-picker-indicator {
12
+ opacity: 0 !important;
13
+ display: none !important;
14
+ -webkit-appearance: none !important;
15
+ }
16
+
17
+ input[type="date"]:not(:valid) {
18
+ color: transparent !important;
19
+ }
20
+
21
+ input[type="date"]:not(:valid)::before {
22
+ content: attr(placeholder) !important;
23
+ color: rgb(148 163 184) !important;
24
+ }
25
+ }
26
+
27
+ .date-fake-placeholder {
28
+ display: none;
29
+ }
30
+
31
+ @media (pointer: coarse) {
32
+ .date-fake-placeholder {
33
+ display: block;
34
+ }
35
+ }
@@ -1,29 +1,39 @@
1
1
  <div class="relative w-full">
2
- <input
3
- [type]="type"
4
- [id]="id"
5
- [name]="name ?? ''"
6
- [placeholder]="placeholder"
7
- [value]="value"
8
- (input)="onInput($event)"
9
- [required]="required"
10
- [disabled]="isDisabled"
11
- (blur)="onTouched()"
12
- [ngClass]="combinedNgClass"
13
- [class]="classes"
14
- class="input w-full h-[40px] max-[400px]:h-[35px] text-[12px] bg-background dark:bg-dark-background border border-border dark:border-dark-border text-black dark:text-white placeholder:text-muted-foreground/70 dark:placeholder:text-dark-muted-foreground/70 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary dark:focus:ring-dark-primary transition duration-200 resize-y disabled:opacity-60 disabled:cursor-not-allowed"
15
- />
2
+ @if (type === 'date' && !value && placeholder) {
3
+ <span
4
+ class="date-fake-placeholder pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-[12px] text-muted-foreground/70 dark:text-dark-muted-foreground/70 z-[1]"
5
+ >
6
+ {{ placeholder }}
7
+ </span>
8
+ }
16
9
 
17
- @if (value && clearButton) {
18
- <button type="button"
19
- class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 text-gray-400 hover:text-gray-500 pr-1 mr-1 text-gray-400 hover:text-gray-600 focus:outline-none cursor-pointer"
20
- (click)="clearInput()"
21
- [disabled]="isDisabled"
22
- [ngClass]="{
23
- 'cursor-not-allowed opacity-50': isDisabled
24
- }"
25
- >
26
- <lucide-icon [name]="iconsService.icons.close" class="w-4 h-4" />
27
- </button>
28
- }
29
- </div>
10
+ <input
11
+ [type]="type"
12
+ [id]="id"
13
+ [name]="name ?? ''"
14
+ [placeholder]="placeholder"
15
+ [value]="value"
16
+ (input)="onInput($event)"
17
+ [required]="required"
18
+ [disabled]="isDisabled"
19
+ [readonly]="isReadonly"
20
+ (blur)="onTouched()"
21
+ [ngClass]="combinedNgClass"
22
+ [class]="classes"
23
+ class="input w-full h-[40px] max-[400px]:h-[35px] text-[12px] bg-background dark:bg-dark-background border border-border dark:border-dark-border text-black dark:text-white placeholder:text-muted-foreground/70 dark:placeholder:text-dark-muted-foreground/70 rounded px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary dark:focus:ring-dark-primary transition duration-200 resize-y disabled:opacity-60 disabled:cursor-not-allowed"
24
+ />
25
+
26
+ @if (value && clearButton) {
27
+ <button
28
+ type="button"
29
+ class="absolute right-2 top-1/2 -translate-y-1/2 text-gray-400 text-gray-400 hover:text-gray-500 pr-1 mr-1 text-gray-400 hover:text-gray-600 focus:outline-none cursor-pointer"
30
+ (click)="clearInput()"
31
+ [disabled]="isDisabled"
32
+ [ngClass]="{
33
+ 'cursor-not-allowed opacity-50': isDisabled,
34
+ }"
35
+ >
36
+ <lucide-icon [name]="iconsService.icons.close" class="w-4 h-4" />
37
+ </button>
38
+ }
39
+ </div>
@@ -26,6 +26,7 @@ export class JInputComponent implements ControlValueAccessor {
26
26
  @Input() placeholder: string = '';
27
27
 
28
28
  @Input() isDisabled: boolean = false;
29
+ @Input() isReadonly: boolean = false;
29
30
  @Input() required: boolean = false;
30
31
  @Input() clearButton: boolean = false;
31
32
 
@@ -0,0 +1,53 @@
1
+ <div class="relative isolate">
2
+ <JButton
3
+ onKeyPress
4
+ jCoachMark
5
+ [contentTemplate]="customTemplateActions"
6
+ [isDescriptionFormatted]="true"
7
+ coachPosition="bottom-left"
8
+ coachTrigger="click"
9
+ [coachMaxWidth]="'170px'"
10
+ [coachSpotlight]="false"
11
+ [icon]="iconsService.icons.ellipsisVertical"
12
+ [iconSize]="20"
13
+ classes="secondary w-[35px] h-[35px] rounded-full"
14
+ (clicked)="handleClickGeneral()"
15
+ />
16
+
17
+ <ng-template #customTemplateActions>
18
+ <div class="flex flex-col gap-2">
19
+ @if (optionsTable.length > 0) {
20
+ @for (option of optionsTable; track $index) {
21
+ @if (getIsVisible(option, group)) {
22
+ <div
23
+ class="w-full hover:bg-primary/10 dark:hover:bg-dark-primary/10 text-[10px]"
24
+ >
25
+ <JButton
26
+ onKeyPress
27
+ [icon]="getIcon(option.icon, group)"
28
+ [iconSize]="20"
29
+ (clicked)="handleClick(option, group)"
30
+ [tooltip]="getTooltip(option.tooltip ?? '', group)"
31
+ [tooltipPosition]="option.tooltipPosition ?? 'top'"
32
+ [disabled]="getDisabled(option, group)"
33
+ [isLoading]="false"
34
+ [classes]="
35
+ 'w-full text-left justify-start ' + (option.classes ?? '')
36
+ "
37
+ [ngClasses]="mergeNgClasses(option.ngClass, group)"
38
+ >
39
+ {{ getTooltip(option.text ?? "", group) }}
40
+ </JButton>
41
+ </div>
42
+ }
43
+ }
44
+ } @else {
45
+ <div
46
+ class="text-center text-gray-500 dark:text-dark-text-secondary text-xs"
47
+ >
48
+ No hay opciones disponibles
49
+ </div>
50
+ }
51
+ </div>
52
+ </ng-template>
53
+ </div>
@@ -0,0 +1,41 @@
1
+ import { Component, Input, Output, EventEmitter, ElementRef, OnDestroy, ViewChild, AfterViewInit, Renderer2 } from '@angular/core';
2
+ import { LucideAngularModule } from 'lucide-angular';
3
+ import { JButtonComponent } from '../../button/button.component';
4
+ import { JIconsService } from 'tailjng';
5
+ import { JCoachMarkDirective } from '../../coach-mark/coach-mark.directive';
6
+
7
+ @Component({
8
+ selector: 'JOptionsCoachMenu',
9
+ imports: [LucideAngularModule, JButtonComponent, JCoachMarkDirective],
10
+ templateUrl: './options-coach-menu.component.html',
11
+ styleUrl: './options-coach-menu.component.scss'
12
+ })
13
+ export class JOptionsCoachMenuComponent {
14
+
15
+ @Input() optionsTable: any[] = [];
16
+ @Input() group: any;
17
+ @Input() rowId: string | number | null = null;
18
+
19
+ @Input() getIcon: (icon: any, group: any) => any = () => null;
20
+ @Input() getTooltip: (tooltip: string, group: any) => string = () => '';
21
+ @Input() getDisabled: (option: any, group: any) => boolean = () => false;
22
+ @Input() getIsVisible: (option: any, group: any) => boolean = () => true;
23
+ @Input() mergeNgClasses: (ngClass: any, group: any) => any = () => '';
24
+ @Input() isAditionalButtonLoading: (type: string, id: any) => boolean = () => false;
25
+
26
+ @Output() clicked = new EventEmitter<{ option: any; group: any }>();
27
+
28
+
29
+ constructor(
30
+ public readonly iconsService: JIconsService,
31
+ ) { }
32
+
33
+ handleClick(option: any, group: any): void {
34
+ this.clicked.emit({ option, group });
35
+ this.handleClickGeneral();
36
+ }
37
+
38
+ handleClickGeneral(): void {
39
+ document.body.click();
40
+ }
41
+ }
@@ -17,6 +17,7 @@
17
17
  [isLoadingText]="false"
18
18
  classes="secondary h-[35px]"
19
19
  [class.disabled]="currentPage === 1 || isLoading"
20
+ [ngClasses]="{ '!bg-white dark:!bg-foreground': !isbackground }"
20
21
  />
21
22
 
22
23
  <!-- Previous page -->
@@ -29,6 +30,7 @@
29
30
  [isLoading]="isButtonLoading('prev')"
30
31
  [isLoadingText]="false"
31
32
  [class.disabled]="currentPage === 1 || isLoading"
33
+ [ngClasses]="{ '!bg-white dark:!bg-foreground': !isbackground }"
32
34
  />
33
35
 
34
36
  <!-- Page numbers -->
@@ -41,7 +43,10 @@
41
43
  [disabled]="currentPage === page || isLoading"
42
44
  [isLoading]="isButtonLoading(page)"
43
45
  [isLoadingText]="false"
44
- [ngClasses]="{ 'primary' : currentPage === page }"
46
+ [ngClasses]="{
47
+ 'primary' : currentPage === page,
48
+ '!bg-white dark:!bg-foreground': !isbackground && currentPage !== page,
49
+ }"
45
50
  />
46
51
  }
47
52
 
@@ -55,6 +60,7 @@
55
60
  [isLoading]="isButtonLoading('next')"
56
61
  [isLoadingText]="false"
57
62
  [class.disabled]="currentPage === totalPages || isLoading"
63
+ [ngClasses]="{ '!bg-white dark:!bg-foreground': !isbackground }"
58
64
  />
59
65
 
60
66
  <!-- Last page -->
@@ -67,6 +73,7 @@
67
73
  [isLoading]="isButtonLoading('last')"
68
74
  [isLoadingText]="false"
69
75
  [class.disabled]="currentPage === totalPages || isLoading"
76
+ [ngClasses]="{ '!bg-white dark:!bg-foreground': !isbackground }"
70
77
  />
71
78
 
72
79
  </div>
@@ -24,6 +24,7 @@ export class JCompletePaginatorComponent {
24
24
  @Input() itemsPerPage = this.itemsPerPageOptions[0];
25
25
  @Input() totalItems = 0;
26
26
 
27
+ @Input() isbackground = false;
27
28
 
28
29
  @Input() isLoading = false;
29
30
 
@@ -112,5 +113,5 @@ export class JCompletePaginatorComponent {
112
113
  isButtonLoading(button: 'first' | 'prev' | 'next' | 'last' | number): boolean {
113
114
  return this.isLoading && this.loadingButton === button;
114
115
  }
115
-
116
+
116
117
  }
@@ -1,94 +1,166 @@
1
1
  <div class="relative w-full h-full">
2
- <div #selectButton class="w-auto">
3
- <button
4
- type="button"
5
- [disabled]="isDisabled || isLoading"
6
- (click)="toggleColumnSelector()"
7
- [class]="'flex w-full h-[40px] max-[400px]:h-[35px] text-[12px] items-center justify-between px-3 py-2 text-sm bg-background dark:bg-dark-background border border-border dark:border-dark-border rounded focus:outline-none focus:ring-2 focus:ring-primary select-none' + ' ' + classes"
8
- [ngClass]="{
9
- 'opacity-50 cursor-not-allowed pointer-events-none': isDisabled || isLoading,
10
- ngClass: true
11
- }"
12
- >
13
- <span class="truncate text-black dark:text-white" [ngClass]="{'opacity-70 text-muted-foreground dark:text-dark-muted-foreground' : selectedValue === null}">{{selectedLabel}}</span>
14
-
15
- <div class="flex items-center">
16
- @if (showClear && selectedValue !== null) {
17
- <button type="button"
18
- (click)="clearSelection($event)"
19
- class="pr-1 mr-1 text-gray-400 hover:text-gray-600 focus:outline-none cursor-pointer">
20
- <lucide-icon [name]="iconsService.icons.close" size="14"></lucide-icon>
21
- </button>
22
- }
23
- @if (!isLoading) {
24
- <lucide-icon [name]="iconsService.icons.chevronDown" size="16" class="transition duration-300 ease-in-out text-gray-400" [ngClass]="{'rotate-180': isColumnSelectorOpen}"></lucide-icon>
25
- } @else {
26
- <lucide-icon [name]="iconsService.icons.loading" size="16" class="text-gray-400 animate-spin"></lucide-icon>
27
- }
28
- </div>
29
- </button>
30
- </div>
2
+ <div #selectButton class="w-auto">
3
+ <button
4
+ type="button"
5
+ [disabled]="isDisabled || isLoading"
6
+ (click)="toggleColumnSelector()"
7
+ [class]="
8
+ 'flex w-full h-[40px] max-[400px]:h-[35px] text-[12px] items-center justify-between px-3 py-2 text-sm bg-background dark:bg-dark-background border border-border dark:border-dark-border rounded focus:outline-none focus:ring-2 focus:ring-primary select-none' +
9
+ ' ' +
10
+ classes
11
+ "
12
+ [ngClass]="getButtonNgClass()"
13
+ >
14
+ <span
15
+ class="truncate text-black dark:text-white"
16
+ [ngClass]="{
17
+ 'opacity-70 text-muted-foreground dark:text-dark-muted-foreground':
18
+ selectedValue === null,
19
+ }"
20
+ >{{ selectedLabel }}</span
21
+ >
22
+
23
+ <div class="flex items-center">
24
+ @if (showClear && selectedValue !== null) {
25
+ <button
26
+ type="button"
27
+ (click)="clearSelection($event)"
28
+ class="pr-1 mr-1 text-gray-400 hover:text-gray-600 focus:outline-none cursor-pointer"
29
+ >
30
+ <lucide-icon
31
+ [name]="iconsService.icons.close"
32
+ size="14"
33
+ ></lucide-icon>
34
+ </button>
35
+ }
36
+ @if (!isLoading) {
37
+ <lucide-icon
38
+ [name]="iconsService.icons.chevronDown"
39
+ size="16"
40
+ class="transition duration-300 ease-in-out text-gray-400"
41
+ [ngClass]="{ 'rotate-180': isColumnSelectorOpen }"
42
+ ></lucide-icon>
43
+ } @else {
44
+ <lucide-icon
45
+ [name]="iconsService.icons.loading"
46
+ size="16"
47
+ class="text-gray-400 animate-spin"
48
+ ></lucide-icon>
49
+ }
50
+ </div>
51
+ </button>
52
+ </div>
31
53
  </div>
32
54
 
33
55
  <!-- Dropdown positioned outside the flow -->
34
56
  @if (isColumnSelectorOpen) {
35
- <div @modalTransition
36
- [class]="'absolute z-[100] min-w-[250px] mt-1 bg-background dark:bg-dark-background rounded-lg shadow-lg border border-border border-dark-border' + ' ' + classes"
37
- [style.width.px]="dropdownWidth"
38
- [style.top.px]="dropdownTop"
39
- [style.left.px]="dropdownLeft"
40
- >
41
- <div class="pt-1 pl-3 pr-3 pb-3">
42
- <div class="text-[10px] font-medium text-gray-500 dark:text-gray-500 mb-1">{{title}}</div>
43
-
44
- <!-- Search -->
45
- @if (type === 'searchable' && isSearch) {
46
- <div class="mb-2 relative">
47
- <input type="text"
48
- [(ngModel)]="searchTerm"
49
- (input)="onSearchInput()"
50
- placeholder="Buscar..."
51
- class="input bg-dark-foreground dark:bg-foreground text-black dark:text-white w-full px-3 py-2 text-sm max-[400px]:h-[35px] max-[400px]:text-[12px] border border-border dark:border-dark-border rounded focus:outline-none focus:ring-2 focus:ring-primary"
57
+ <div
58
+ @modalTransition
59
+ [class]="
60
+ 'absolute z-[100] min-w-[250px] mt-1 bg-background dark:bg-dark-background rounded-lg shadow-lg border border-border border-dark-border' +
61
+ ' ' +
62
+ classes
63
+ "
64
+ [style.width.px]="dropdownWidth"
65
+ [style.top.px]="dropdownTop"
66
+ [style.left.px]="dropdownLeft"
67
+ [ngClass]="getButtonNgClass()"
68
+ >
69
+ <div class="pt-1 pl-3 pr-3 pb-3">
70
+ <div
71
+ class="text-[10px] font-medium text-gray-500 dark:text-gray-500 mb-1"
72
+ >
73
+ {{ title }}
74
+ </div>
75
+
76
+ <!-- Search -->
77
+ @if (type === "searchable" && isSearch) {
78
+ <div class="mb-2 relative">
79
+ <input
80
+ type="text"
81
+ [(ngModel)]="searchTerm"
82
+ (input)="onSearchInput()"
83
+ placeholder="Buscar..."
84
+ class="input bg-dark-foreground dark:bg-foreground text-black dark:text-white w-full px-3 py-2 text-sm max-[400px]:h-[35px] max-[400px]:text-[12px] border border-border dark:border-dark-border rounded focus:outline-none focus:ring-2 focus:ring-primary"
85
+ />
86
+
87
+ <div class="absolute flex right-3 top-1/2 transform -translate-y-1/2">
88
+ @if (searchTerm) {
89
+ <button
90
+ type="button"
91
+ (click)="clearSearchTerm()"
92
+ class="pr-1 mr-1 text-gray-400 hover:text-gray-600 focus:outline-none cursor-pointer"
93
+ >
94
+ <lucide-icon
95
+ [name]="iconsService.icons.close"
96
+ size="16"
97
+ ></lucide-icon>
98
+ </button>
99
+ }
100
+ <lucide-icon
101
+ [name]="iconsService.icons.search"
102
+ size="16"
103
+ class="text-gray-400"
104
+ ></lucide-icon>
105
+ </div>
106
+ </div>
107
+ }
108
+
109
+ <!-- Dropdown -->
110
+ <div
111
+ class="max-h-45 max-[400px]:max-h-38 overflow-x-hidden overflow-y-auto flex flex-col gap-1 scroll-element"
112
+ >
113
+ @if (isLoading) {
114
+ <div
115
+ class="flex gap-3 text-black/50 dark:text-white/50 items-center justify-center py-4"
116
+ >
117
+ <lucide-icon
118
+ [name]="iconsService.icons.loading"
119
+ size="20"
120
+ class="animate-spin"
121
+ ></lucide-icon>
122
+ Cargando...
123
+ </div>
124
+ } @else {
125
+ @for (option of filteredOptions; track option.value) {
126
+ <div
127
+ onKeyDown
128
+ (click)="selectOption(option)"
129
+ class="flex gap-2 items-center border border-accent dark:border-dark-accent/50 px-3 py-2 rounded text-sm max-[400px]:h-[35px] max-[400px]:text-[12px] cursor-pointer text-black! dark:text-white! hover:bg-accent/50 hover:dark:bg-dark-accent/40"
130
+ [ngClass]="{
131
+ 'bg-accent! dark:bg-dark-accent/80!':
132
+ selectedValue === option.value,
133
+ 'text-black': selectedValue === option.value,
134
+ }"
135
+ >
136
+ @if (selectedValue === option.value) {
137
+ <lucide-icon
138
+ [name]="iconsService.icons.check"
139
+ size="15"
140
+ class="transition text-black dark:text-white"
52
141
  />
142
+ } @else {
143
+ <lucide-icon
144
+ [name]="iconsService.icons.squareDashedMousePointer"
145
+ size="15"
146
+ class="transition text-black dark:text-white opacity-40"
147
+ />
148
+ }
53
149
 
54
- <div class="absolute flex right-3 top-1/2 transform -translate-y-1/2 ">
55
- @if (searchTerm) {
56
- <button
57
- type="button"
58
- (click)="clearSearchTerm()"
59
- class="pr-1 mr-1 text-gray-400 hover:text-gray-600 focus:outline-none cursor-pointer"
60
- >
61
- <lucide-icon [name]="iconsService.icons.close" size="16"></lucide-icon>
62
- </button>
63
- }
64
- <lucide-icon [name]="iconsService.icons.search" size="16" class="text-gray-400"></lucide-icon>
65
- </div>
150
+ <div
151
+ class="flex items-center break-words whitespace-normal overflow-hidden"
152
+ >
153
+ {{ option.text }}
154
+ </div>
66
155
  </div>
67
- }
68
-
69
- <!-- Dropdown -->
70
- <div class="max-h-40 max-[400px]:max-h-38 overflow-x-hidden overflow-y-auto flex flex-col gap-1 scroll-element">
71
- @if (isLoading) {
72
- <div class="flex gap-3 text-black/50 dark:text-white/50 items-center justify-center py-4">
73
- <lucide-icon [name]="iconsService.icons.loading" size="20" class="animate-spin"></lucide-icon>
74
- Cargando...
75
- </div>
76
- } @else {
77
- @for (option of filteredOptions; track option.value) {
78
- <div onKeyDown
79
- (click)="selectOption(option)"
80
- class="px-3 py-2 rounded text-sm max-[400px]:h-[35px] max-[400px]:text-[12px] cursor-pointer text-black! dark:text-white! hover:bg-accent/50 hover:dark:bg-dark-accent/40"
81
- [ngClass]="{'bg-accent! dark:bg-dark-accent/80!': selectedValue === option.value, 'text-black': selectedValue === option.value}">
82
- <div class="flex items-center break-words whitespace-normal overflow-hidden">
83
- {{option.text}}
84
- </div>
85
- </div>
86
- }
87
- @if (filteredOptions.length === 0) {
88
- <div class="px-3 py-2 text-sm text-gray-500">No hay opciones disponibles</div>
89
- }
90
- }
156
+ }
157
+ @if (filteredOptions.length === 0) {
158
+ <div class="px-3 py-2 text-sm text-gray-500">
159
+ No hay opciones disponibles
91
160
  </div>
92
- </div>
161
+ }
162
+ }
163
+ </div>
93
164
  </div>
165
+ </div>
94
166
  }
@@ -1,3 +1,4 @@
1
+
1
2
  import { Component, Input, Output, EventEmitter, ElementRef, ViewChild, OnDestroy, ChangeDetectorRef, AfterViewInit, OnInit, SimpleChanges, OnChanges, } from "@angular/core"
2
3
  import { FormsModule, ControlValueAccessor, ReactiveFormsModule, NG_VALUE_ACCESSOR } from "@angular/forms"
3
4
  import { CommonModule } from "@angular/common"
@@ -55,9 +56,9 @@ export class JDropdownSelectComponent implements ControlValueAccessor, AfterView
55
56
 
56
57
  @Input() isSearch = true;
57
58
  @Input() isFilterSelect = false;
58
-
59
+
59
60
  @Input() classes: string = '';
60
- @Input() ngClass: { [key: string]: boolean } = {};
61
+ @Input() ngClasses: { [key: string]: boolean } = {};
61
62
 
62
63
  @Output() selectionChange = new EventEmitter<any>();
63
64
  @Output() fullData = new EventEmitter<any[]>();
@@ -662,4 +663,15 @@ export class JDropdownSelectComponent implements ControlValueAccessor, AfterView
662
663
  const isInitialState = this.selectedValue === null
663
664
  return isSearchActive || isInitialState
664
665
  }
666
+
667
+ /**
668
+ * Get the ngClass for the button based on disabled and loading state
669
+ * @returns
670
+ */
671
+ getButtonNgClass(): { [key: string]: boolean } {
672
+ return {
673
+ 'opacity-50 cursor-not-allowed pointer-events-none': this.isDisabled || this.isLoading,
674
+ ...this.ngClasses,
675
+ };
676
+ }
665
677
  }
@@ -5,6 +5,7 @@
5
5
  classes="secondary"
6
6
  [icon]="btnIcon"
7
7
  [disabled]="isDisabled"
8
+ [ngClasses]="getButtonNgClass()"
8
9
  >
9
10
  {{btnText}}
10
11
  </JButton>
@@ -18,6 +19,7 @@
18
19
  [style.width.px]="dropdownWidth"
19
20
  [style.top.px]="dropdownTop"
20
21
  [style.left.px]="dropdownLeft"
22
+ [ngClass]="getButtonNgClass()"
21
23
  >
22
24
  <div class="pt-1 pl-3 pr-3 pb-3">
23
25
  <div class="text-[10px] font-medium text-gray-500 dark:text-gray-500 mb-1">{{title}}</div>
@@ -31,6 +31,7 @@ export class JMultiTableSelectComponent implements AfterViewInit, OnInit, OnChan
31
31
  @Input() showActions = true;
32
32
  @Input() isFilterSelect = false;
33
33
 
34
+ @Input() ngClasses: { [key: string]: boolean } = {};
34
35
 
35
36
  @Output() columnToggle = new EventEmitter<{ column: TableColumn<any>; visible: boolean }>();
36
37
  @Input() columns: TableColumn<any>[] = [];
@@ -413,4 +414,15 @@ export class JMultiTableSelectComponent implements AfterViewInit, OnInit, OnChan
413
414
  const column = this.columns.find((col) => col.key === key);
414
415
  return column?.visible ?? false;
415
416
  }
417
+
418
+ /**
419
+ * Get the ngClass for the button based on disabled and loading state
420
+ * @returns
421
+ */
422
+ getButtonNgClass(): { [key: string]: boolean } {
423
+ return {
424
+ 'opacity-50 cursor-not-allowed pointer-events-none': this.isDisabled,
425
+ ...this.ngClasses,
426
+ };
427
+ }
416
428
  }
@@ -41,7 +41,7 @@
41
41
  </div>
42
42
  </div>
43
43
 
44
- <div class="j-table relative border border-border dark:border-dark-border rounded">
44
+ <div class="relative border border-border dark:border-dark-border rounded">
45
45
  <div class="overflow-x-auto rounded scroll-element pr-0!" style="overflow-y: hidden;">
46
46
  <table class="min-w-full bg-white dark:bg-dark-background rounded">
47
47
  <thead class="bg-primary dark:bg-dark-primary text-white dark:text-white select-none h-[50px]">
@@ -1,5 +0,0 @@
1
- .j-table {
2
- @media (max-width: 470px) {
3
- width: 485px !important;
4
- }
5
- }
@@ -10,6 +10,7 @@
10
10
  [isSearch]="isSearch"
11
11
  [isShowColumns]="isEyeColumn"
12
12
  (search)="onSearch()"
13
+ [isbackground]="isbackground"
13
14
  [searchPlaceholder]="searchPlaceholder"
14
15
  [isItemsPerPage]="isItemsPerPage"
15
16
  [(itemsPerPage)]="itemsPerPage"
@@ -41,13 +42,14 @@
41
42
  [pages]="pages"
42
43
  (pageChange)="handlePageChange($event)"
43
44
  [isLoading]="isLoading('pagination')"
45
+ [isbackground]="isbackground"
44
46
  />
45
47
  </div>
46
48
  }
47
49
 
48
50
  <!-- Table -->
49
51
  <div
50
- class="relative block max-[400px]:hidden border border-border dark:border-dark-border rounded"
52
+ class="relative block max-[768px]:hidden border border-border dark:border-dark-border rounded"
51
53
  >
52
54
  <div
53
55
  class="overflow-x-auto rounded scroll-element pr-0!"
@@ -491,7 +493,7 @@
491
493
  >
492
494
  <div class="flex justify-center items-center">
493
495
  @if (optionsType === "dropdown") {
494
- <JOptionsTableMenu
496
+ <JOptionsCoachMenu
495
497
  [optionsTable]="optionsTable"
496
498
  [group]="item"
497
499
  [rowId]="'group_' + item.id || 'group_' + $index"
@@ -798,7 +800,7 @@
798
800
  class="relative overflow-visible flex justify-center items-center space-x-2 min-w-[50px] px-4 py-2 h-[50px]"
799
801
  >
800
802
  @if (optionsType === "dropdown") {
801
- <JOptionsTableMenu
803
+ <JOptionsCoachMenu
802
804
  [optionsTable]="optionsTable"
803
805
  [group]="group"
804
806
  [rowId]="
@@ -954,7 +956,7 @@
954
956
  </div>
955
957
 
956
958
  <!-- TABLE MOVILE -->
957
- <div class="hidden max-[400px]:block">
959
+ <div class="hidden max-[768px]:block">
958
960
  <div class="flex flex-col gap-3">
959
961
  @if (isLoading("initialLoad") && displayData.length === 0) {
960
962
  <div
@@ -990,14 +992,14 @@
990
992
 
991
993
  <div class="flex-1 min-w-0 max-w-full overflow-hidden">
992
994
  <div
993
- class="font-bold text-[12px] leading-tight block overflow-hidden text-ellipsis whitespace-nowrap max-w-[200px]"
995
+ class="font-bold text-[12px] leading-tight block overflow-hidden text-ellipsis whitespace-nowrap max-[400px]:max-w-[200px] max-[768px]:max-w-[500px]"
994
996
  >
995
997
  {{ getMobileMainTitle(item) }}
996
998
  </div>
997
999
 
998
1000
  @if (getMobileMainDescription(item)) {
999
1001
  <div
1000
- class="text-[12px] leading-snug break-words whitespace-normal max-w-[200px]"
1002
+ class="text-[12px] leading-snug break-words whitespace-normal max-[400px]:max-w-[200px] max-[768px]:max-w-[500px]"
1001
1003
  >
1002
1004
  {{ getMobileMainDescription(item) }}
1003
1005
  </div>
@@ -1367,6 +1369,7 @@
1367
1369
  [pages]="pages"
1368
1370
  (pageChange)="handlePageChange($event)"
1369
1371
  [isLoading]="isLoading('pagination')"
1372
+ [isbackground]="isbackground"
1370
1373
  />
1371
1374
  </div>
1372
1375
  }
@@ -13,16 +13,16 @@ import { JCompletePaginatorComponent } from '../../paginator/paginator-complete/
13
13
  import { JCompleteFilterComponent } from '../../filter/filter-complete/complete-filter.component';
14
14
  import { JButtonComponent } from '../../button/button.component';
15
15
  import { JInputCheckboxComponent } from '../../checkbox/checkbox-input/input-checkbox.component';
16
- import { JOptionsTableMenuComponent } from '../../menu/menu-options-table/options-table-menu.component';
17
16
  import { JDialogComponent } from '../../dialog/dialog.component';
18
17
  import { JDropdownSelectComponent } from '../../select/select-dropdown/dropdown-select.component';
19
18
  import { JInputComponent } from '../../input/input/input.component';
20
19
  import { JImageViewerComponent } from '../../viewer/viewer-image/image-viewer.component';
20
+ import { JOptionsCoachMenuComponent } from '../../menu/options-coach-menu/options-coach-menu.component';
21
21
 
22
22
  @Component({
23
23
  selector: 'JCompleteCrudTable',
24
24
  standalone: true,
25
- imports: [CommonModule, FormsModule, JCompletePaginatorComponent, JCompleteFilterComponent, LucideAngularModule, JButtonComponent, JInputCheckboxComponent, JOptionsTableMenuComponent, JDialogComponent, JImageViewerComponent, JDropdownSelectComponent, JInputComponent],
25
+ imports: [CommonModule, FormsModule, JCompletePaginatorComponent, JCompleteFilterComponent, LucideAngularModule, JButtonComponent, JInputCheckboxComponent, JDialogComponent, JImageViewerComponent, JDropdownSelectComponent, JInputComponent, JOptionsCoachMenuComponent],
26
26
  templateUrl: './complete-crud-table.component.html',
27
27
  styleUrl: './complete-crud-table.component.scss',
28
28
  animations: [
@@ -66,6 +66,7 @@ export class JCompleteCrudTableComponent implements OnInit {
66
66
  @Input() defaultFilters: { [key: string]: any } = {};
67
67
  @Input() isPaginator = true;
68
68
  @Input() isFilter = true;
69
+ @Input() isbackground = false;
69
70
  @Input() isSearch = true;
70
71
  @Input() isEyeColumn = true;
71
72
  @Input() hideRowCondition?: (row: any) => boolean