grav-svelte 0.0.4 → 0.0.6
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.
- package/dist/CRUD/CrudFilters.svelte +272 -0
- package/dist/CRUD/CrudFilters.svelte.d.ts +23 -0
- package/dist/CRUD/CrudTable.svelte +226 -0
- package/dist/CRUD/CrudTable.svelte.d.ts +22 -0
- package/dist/CRUD/CrudTableButtons.svelte +38 -0
- package/dist/CRUD/CrudTableButtons.svelte.d.ts +18 -0
- package/dist/CRUD/CrudWrapper.svelte +95 -0
- package/dist/CRUD/CrudWrapper.svelte.d.ts +29 -0
- package/dist/CRUD/PaginationCRUD.svelte +100 -0
- package/dist/CRUD/PaginationCRUD.svelte.d.ts +33 -0
- package/dist/CRUD/index.d.ts +2 -0
- package/dist/CRUD/index.js +1 -0
- package/dist/CRUD/interfaces.d.ts +23 -0
- package/dist/CRUD/interfaces.js +2 -0
- package/dist/Inputs/InputFormBool.svelte +24 -0
- package/dist/Inputs/InputFormBool.svelte.d.ts +27 -0
- package/dist/Inputs/InputFormCascade.svelte +102 -0
- package/dist/Inputs/InputFormCascade.svelte.d.ts +27 -0
- package/dist/Inputs/InputFormColor.svelte +25 -0
- package/dist/Inputs/InputFormColor.svelte.d.ts +19 -0
- package/dist/Inputs/InputFormDate.svelte +22 -0
- package/dist/Inputs/InputFormDate.svelte.d.ts +19 -0
- package/dist/Inputs/InputFormDateAndHours.svelte +25 -0
- package/dist/Inputs/InputFormDateAndHours.svelte.d.ts +19 -0
- package/dist/Inputs/InputFormImage.svelte +129 -0
- package/dist/Inputs/InputFormImage.svelte.d.ts +17 -0
- package/dist/Inputs/InputFormNumber.svelte +25 -0
- package/dist/Inputs/InputFormNumber.svelte.d.ts +19 -0
- package/dist/Inputs/InputFormSelect.svelte +36 -0
- package/dist/Inputs/InputFormSelect.svelte.d.ts +28 -0
- package/dist/Inputs/InputFormText.svelte +25 -0
- package/dist/Inputs/InputFormText.svelte.d.ts +19 -0
- package/dist/Inputs/InputFormTextArea.svelte +26 -0
- package/dist/Inputs/InputFormTextArea.svelte.d.ts +20 -0
- package/dist/Inputs/InputFormTextWithSlide.svelte +37 -0
- package/dist/Inputs/InputFormTextWithSlide.svelte.d.ts +20 -0
- package/dist/Inputs/index.d.ts +11 -0
- package/dist/Inputs/index.js +11 -0
- package/dist/Modals/Grav_Modal.svelte +176 -0
- package/dist/Modals/Grav_Modal.svelte.d.ts +26 -0
- package/dist/Modals/index.d.ts +1 -0
- package/dist/Modals/index.js +1 -0
- package/dist/generics.d.ts +2 -0
- package/dist/generics.js +66 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -2
- package/package.json +18 -5
- package/dist/Button/Button.svelte +0 -49
- package/dist/Button/Button.svelte.d.ts +0 -23
- package/dist/Button/index.d.ts +0 -1
- package/dist/Button/index.js +0 -1
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import InputFormText from "./../Inputs/InputFormText.svelte";
|
|
3
|
+
import InputFormBool from "../Inputs/InputFormBool.svelte";
|
|
4
|
+
import InputFormSelect from "../Inputs/InputFormSelect.svelte";
|
|
5
|
+
import InputFormNumber from "../Inputs/InputFormNumber.svelte";
|
|
6
|
+
import InputFormDateAndHours from "../Inputs/InputFormDateAndHours.svelte";
|
|
7
|
+
import InputFormDate from "../Inputs/InputFormDate.svelte";
|
|
8
|
+
import { slide } from "svelte/transition";
|
|
9
|
+
|
|
10
|
+
import { createEventDispatcher } from "svelte";
|
|
11
|
+
import type { FiltrosI } from "./interfaces.js";
|
|
12
|
+
const dispatch = createEventDispatcher();
|
|
13
|
+
|
|
14
|
+
let showTooltip = "";
|
|
15
|
+
export let PageSize = 50;
|
|
16
|
+
let localPageSize = 50;
|
|
17
|
+
let showFilters = false;
|
|
18
|
+
|
|
19
|
+
export let Filtros: FiltrosI[];
|
|
20
|
+
export let showAddButton: boolean = true;
|
|
21
|
+
export let showImportButton: boolean = true;
|
|
22
|
+
|
|
23
|
+
// Ensure localPageSize is never 0
|
|
24
|
+
$: if (localPageSize == 0) {
|
|
25
|
+
localPageSize = 1;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function clearFilters() {
|
|
29
|
+
console.log("clearFilters");
|
|
30
|
+
|
|
31
|
+
Filtros = Filtros.map((filtro) => ({
|
|
32
|
+
...filtro,
|
|
33
|
+
value: filtro.tipo === "bool" ? false : "",
|
|
34
|
+
}));
|
|
35
|
+
console.log(Filtros);
|
|
36
|
+
dispatch("filtrar", { filtros: Filtros }); // puedes pasar los filtros actualizados
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function actualizarFiltro() {
|
|
40
|
+
console.log(Filtros);
|
|
41
|
+
PageSize = localPageSize;
|
|
42
|
+
dispatch("filtrar", { filtros: Filtros }); // puedes pasar los filtros actualizados
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Handle keydown event
|
|
46
|
+
function handleKeydown(event) {
|
|
47
|
+
// Check if the event target is a textarea or input
|
|
48
|
+
// const isInputElement = event.target.tagName === 'TEXTAREA' || event.target.tagName === 'INPUT';
|
|
49
|
+
const isInputElement = event.target.tagName === "TEXTAREA";
|
|
50
|
+
|
|
51
|
+
if (event.key === "Enter") {
|
|
52
|
+
event.preventDefault();
|
|
53
|
+
event.stopPropagation();
|
|
54
|
+
actualizarFiltro();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Handle click to focus the modal
|
|
59
|
+
function handleClick(event) {
|
|
60
|
+
// Only focus if clicking directly on the modal container
|
|
61
|
+
if (event.target === event.currentTarget) {
|
|
62
|
+
event.target.focus();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
68
|
+
<div
|
|
69
|
+
class="sm:mb-0 sm:mt-1 p-2"
|
|
70
|
+
on:keydown={handleKeydown}
|
|
71
|
+
on:click={handleClick}
|
|
72
|
+
tabindex="0"
|
|
73
|
+
>
|
|
74
|
+
<!-- Filtros CORE -->
|
|
75
|
+
<!--------------------------------------------------------------------->
|
|
76
|
+
<div class="sm:flex sm:space-x-3 w-full">
|
|
77
|
+
<div class=" flex items-center space-x-3">
|
|
78
|
+
<h1 class=" font-bold text-2xl">Transacciones</h1>
|
|
79
|
+
<div class="flex justify-start items-center space-x-3 w-full">
|
|
80
|
+
{#if showAddButton}
|
|
81
|
+
<div>
|
|
82
|
+
<div class="relative">
|
|
83
|
+
{#if showTooltip == "Agregar"}
|
|
84
|
+
<div
|
|
85
|
+
class="absolute z-[10000] p-1 text-white text-xs bg-gray-500 rounded shadow -top-5 -left-10"
|
|
86
|
+
>
|
|
87
|
+
Agregar
|
|
88
|
+
</div>
|
|
89
|
+
{/if}
|
|
90
|
+
</div>
|
|
91
|
+
<button
|
|
92
|
+
class=" flex justify-center items-center border border-black w-12 h-12 rounded-lg shadow-md"
|
|
93
|
+
type="button"
|
|
94
|
+
on:mouseenter={() => (showTooltip = "Agregar")}
|
|
95
|
+
on:mouseleave={() => (showTooltip = "")}
|
|
96
|
+
on:click={() => dispatch("add")}
|
|
97
|
+
>
|
|
98
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
99
|
+
<line x1="12" y1="5" x2="12" y2="19"></line>
|
|
100
|
+
<line x1="5" y1="12" x2="19" y2="12"></line>
|
|
101
|
+
</svg>
|
|
102
|
+
</button>
|
|
103
|
+
</div>
|
|
104
|
+
{/if}
|
|
105
|
+
{#if showImportButton}
|
|
106
|
+
<div>
|
|
107
|
+
<div class="relative">
|
|
108
|
+
{#if showTooltip == "Importar"}
|
|
109
|
+
<div
|
|
110
|
+
class="absolute z-[10000] p-1 text-white text-xs bg-gray-500 rounded shadow -top-5 -left-10"
|
|
111
|
+
>
|
|
112
|
+
Importar Excel
|
|
113
|
+
</div>
|
|
114
|
+
{/if}
|
|
115
|
+
</div>
|
|
116
|
+
<button
|
|
117
|
+
class=" flex justify-center items-center border border-black w-12 h-12 rounded-lg shadow-md"
|
|
118
|
+
type="button"
|
|
119
|
+
on:mouseenter={() => (showTooltip = "Importar")}
|
|
120
|
+
on:mouseleave={() => (showTooltip = "")}
|
|
121
|
+
>
|
|
122
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
123
|
+
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
|
|
124
|
+
<polyline points="7 10 12 15 17 10"></polyline>
|
|
125
|
+
<line x1="12" y1="15" x2="12" y2="3"></line>
|
|
126
|
+
</svg>
|
|
127
|
+
</button>
|
|
128
|
+
</div>
|
|
129
|
+
{/if}
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
<div class=" flex items-center space-x-3 mt-2 sm:mt-0">
|
|
133
|
+
<!-- Show Filters Button -->
|
|
134
|
+
<div class="inline-flex shadow-sm" role="group">
|
|
135
|
+
{#if Filtros && Filtros.length > 0}
|
|
136
|
+
{#if showFilters}
|
|
137
|
+
<button
|
|
138
|
+
type="button"
|
|
139
|
+
on:click={() => (showFilters = !showFilters)}
|
|
140
|
+
class="inline-flex items-center h-12 sm:px-4 sm:py-3 px-3 py-2 sm:text-sm text-xs font-medium border border-black text-black rounded-l-lg"
|
|
141
|
+
>
|
|
142
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-1">
|
|
143
|
+
<polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"></polygon>
|
|
144
|
+
</svg>
|
|
145
|
+
{showFilters ? '▲' : '▼'}
|
|
146
|
+
</button>
|
|
147
|
+
{:else}
|
|
148
|
+
<button
|
|
149
|
+
type="button"
|
|
150
|
+
on:click={() => (showFilters = !showFilters)}
|
|
151
|
+
class="inline-flex items-center h-12 sm:px-4 sm:py-3 px-3 py-2 sm:text-sm text-xs font-medium border border-black text-black rounded-l-lg"
|
|
152
|
+
>
|
|
153
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-1">
|
|
154
|
+
<polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"></polygon>
|
|
155
|
+
</svg>
|
|
156
|
+
{showFilters ? '▲' : '▼'}
|
|
157
|
+
</button>
|
|
158
|
+
{/if}
|
|
159
|
+
|
|
160
|
+
<!-- Btn de limpiar filtros -->
|
|
161
|
+
|
|
162
|
+
<div class="relative">
|
|
163
|
+
{#if showTooltip == "Borrar"}
|
|
164
|
+
<div
|
|
165
|
+
class="absolute z-[10000] p-1 text-white text-xs bg-gray-500 rounded shadow -top-5 -left-10"
|
|
166
|
+
>
|
|
167
|
+
Borrar filtro
|
|
168
|
+
</div>
|
|
169
|
+
{/if}
|
|
170
|
+
</div>
|
|
171
|
+
<button
|
|
172
|
+
type="button"
|
|
173
|
+
on:click={() => clearFilters()}
|
|
174
|
+
on:mouseenter={() => (showTooltip = "Borrar")}
|
|
175
|
+
on:mouseleave={() => (showTooltip = "nada")}
|
|
176
|
+
class="inline-flex items-center sm:px-4 sm:py-3 px-3 py-2 sm:text-sm text-xs font-medium border border-black rounded-r-lg text-black"
|
|
177
|
+
>
|
|
178
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
179
|
+
<polyline points="3 6 5 6 21 6"></polyline>
|
|
180
|
+
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
|
|
181
|
+
</svg>
|
|
182
|
+
</button>
|
|
183
|
+
{/if}
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
<!-- Filtro 2 -->
|
|
187
|
+
<div class=" w-16">
|
|
188
|
+
<InputFormText
|
|
189
|
+
label="Mostrando:"
|
|
190
|
+
bind:valueVar={localPageSize}
|
|
191
|
+
/>
|
|
192
|
+
</div>
|
|
193
|
+
<!-- /Filtro 2 -->
|
|
194
|
+
|
|
195
|
+
<!-- Btn de aplicar filtro (siempre visible) -->
|
|
196
|
+
<div class="inline-flex rounded-md shadow-sm" role="group">
|
|
197
|
+
<div class="relative">
|
|
198
|
+
{#if showTooltip == "Aplicar"}
|
|
199
|
+
<div
|
|
200
|
+
class="absolute z-[10000] p-1 transition-all ease-in duration-200 text-white text-xs bg-gray-500 rounded shadow -top-5 -left-10"
|
|
201
|
+
>
|
|
202
|
+
Aplicar filtro
|
|
203
|
+
</div>
|
|
204
|
+
{/if}
|
|
205
|
+
</div>
|
|
206
|
+
<button
|
|
207
|
+
type="button"
|
|
208
|
+
on:click={() => actualizarFiltro()}
|
|
209
|
+
on:mouseenter={() => (showTooltip = "Aplicar")}
|
|
210
|
+
on:mouseleave={() => (showTooltip = "nada")}
|
|
211
|
+
class="inline-flex h-12 items-center shadow-md sm:px-4 sm:py-3 px-3 py-2 sm:text-sm text-xs font-medium border border-black text-black rounded-lg"
|
|
212
|
+
>Filtrar</button
|
|
213
|
+
>
|
|
214
|
+
</div>
|
|
215
|
+
<!-- /Btn de aplicar filtro -->
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
<!-- Filtros Dynamic -->
|
|
219
|
+
{#if showFilters}
|
|
220
|
+
<div
|
|
221
|
+
class="grid sm:grid-cols-5 grid-cols-1 gap-3 mt-4"
|
|
222
|
+
transition:slide|local={{ duration: 300, delay: 100 }}
|
|
223
|
+
>
|
|
224
|
+
{#each Filtros as { tipo, label, value, options }, i}
|
|
225
|
+
{#if tipo == "text"}
|
|
226
|
+
<div class="relative z-0 my-auto">
|
|
227
|
+
<InputFormText
|
|
228
|
+
{label}
|
|
229
|
+
bind:valueVar={Filtros[i].value}
|
|
230
|
+
/>
|
|
231
|
+
</div>
|
|
232
|
+
{:else if tipo == "number"}
|
|
233
|
+
<div class="z-50">
|
|
234
|
+
<InputFormNumber
|
|
235
|
+
{label}
|
|
236
|
+
bind:valueVar={Filtros[i].value}
|
|
237
|
+
/>
|
|
238
|
+
</div>
|
|
239
|
+
{:else if tipo == "datetime"}
|
|
240
|
+
<div class="z-50">
|
|
241
|
+
<InputFormDateAndHours
|
|
242
|
+
{label}
|
|
243
|
+
bind:valueVar={Filtros[i].value}
|
|
244
|
+
/>
|
|
245
|
+
</div>
|
|
246
|
+
{:else if tipo == "date"}
|
|
247
|
+
<div class="z-50">
|
|
248
|
+
<InputFormDate
|
|
249
|
+
{label}
|
|
250
|
+
bind:valueVar={Filtros[i].value}
|
|
251
|
+
/>
|
|
252
|
+
</div>
|
|
253
|
+
{:else if tipo == "select"}
|
|
254
|
+
<div class="z-50">
|
|
255
|
+
<InputFormSelect
|
|
256
|
+
{label}
|
|
257
|
+
res={options}
|
|
258
|
+
bind:justValue={Filtros[i].value}
|
|
259
|
+
/>
|
|
260
|
+
</div>
|
|
261
|
+
{:else if tipo == "bool"}
|
|
262
|
+
<div class="my-auto">
|
|
263
|
+
<InputFormBool
|
|
264
|
+
{label}
|
|
265
|
+
bind:valueVar={Filtros[i].value}
|
|
266
|
+
/>
|
|
267
|
+
</div>
|
|
268
|
+
{/if}
|
|
269
|
+
{/each}
|
|
270
|
+
</div>
|
|
271
|
+
{/if}
|
|
272
|
+
</div>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { FiltrosI } from "./interfaces.js";
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
PageSize?: number;
|
|
6
|
+
Filtros: FiltrosI[];
|
|
7
|
+
showAddButton?: boolean;
|
|
8
|
+
showImportButton?: boolean;
|
|
9
|
+
};
|
|
10
|
+
events: {
|
|
11
|
+
add: CustomEvent<any>;
|
|
12
|
+
filtrar: CustomEvent<any>;
|
|
13
|
+
} & {
|
|
14
|
+
[evt: string]: CustomEvent<any>;
|
|
15
|
+
};
|
|
16
|
+
slots: {};
|
|
17
|
+
};
|
|
18
|
+
export type CrudFiltersProps = typeof __propDef.props;
|
|
19
|
+
export type CrudFiltersEvents = typeof __propDef.events;
|
|
20
|
+
export type CrudFiltersSlots = typeof __propDef.slots;
|
|
21
|
+
export default class CrudFilters extends SvelteComponentTyped<CrudFiltersProps, CrudFiltersEvents, CrudFiltersSlots> {
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import CrudTableButtons from "./CrudTableButtons.svelte";
|
|
3
|
+
|
|
4
|
+
// COMPONENTES imports
|
|
5
|
+
|
|
6
|
+
import { createEventDispatcher } from "svelte";
|
|
7
|
+
import type { TableHeader } from "./interfaces.js";
|
|
8
|
+
|
|
9
|
+
const dispatch = createEventDispatcher();
|
|
10
|
+
|
|
11
|
+
// variable que captura la tabla para exportar a Excel o Pdf
|
|
12
|
+
let tablaExport;
|
|
13
|
+
|
|
14
|
+
export let todosLosRegistros: any[] = [];
|
|
15
|
+
export let tableHeaders: TableHeader[];
|
|
16
|
+
export let loading: boolean = false;
|
|
17
|
+
|
|
18
|
+
let selectedAscOrDesc = "asc";
|
|
19
|
+
let selectedSort = "";
|
|
20
|
+
let selectedRowId: string | number | null = null;
|
|
21
|
+
|
|
22
|
+
function handleRowClick(id: string | number) {
|
|
23
|
+
if (id === 0) return;
|
|
24
|
+
selectedRowId = selectedRowId === id ? null : id;
|
|
25
|
+
dispatch("rowClick", { id: selectedRowId });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function dispatchSort(selection: string) {
|
|
29
|
+
if (selectedAscOrDesc == "asc") {
|
|
30
|
+
selectedAscOrDesc = "desc";
|
|
31
|
+
} else {
|
|
32
|
+
selectedAscOrDesc = "asc";
|
|
33
|
+
}
|
|
34
|
+
selectedSort = selection;
|
|
35
|
+
dispatch("selectedSort", {
|
|
36
|
+
selectedSort: selection,
|
|
37
|
+
selectedAsc: selectedAscOrDesc,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<div
|
|
43
|
+
class="relative flex flex-col min-w-0 break-words z-30 w-full mb-3 shadow-lg rounded mt-3 p-1 bg-white"
|
|
44
|
+
>
|
|
45
|
+
<div class="not-prose relative bg-slate-50 rounded-xl overflow-hidden">
|
|
46
|
+
<div class="relative rounded-xl overflow-auto">
|
|
47
|
+
<div class=" bg-white shadow-xl overflow-hidden">
|
|
48
|
+
<div class="overflow-scroll grid max-h-[80vh]">
|
|
49
|
+
<table
|
|
50
|
+
class="items-center w-full bg-transparent border-collapse shadow-xs table-auto"
|
|
51
|
+
bind:this={tablaExport}
|
|
52
|
+
>
|
|
53
|
+
<thead class="shadow-lg sticky top-0 z-20 bg-white">
|
|
54
|
+
<tr class="relative">
|
|
55
|
+
{#each tableHeaders as tableHeader}
|
|
56
|
+
{#if tableHeader.biSort == false}
|
|
57
|
+
<th
|
|
58
|
+
class="px-3 align-middle cursor-not-allowed text-center border border-solid py-1 text-xs uppercase border-l-0 border-r whitespace-nowrap font-semibold bg-blueGray-50 text-blueGray-500 border-blueGray-100"
|
|
59
|
+
>
|
|
60
|
+
{tableHeader.titulo}
|
|
61
|
+
</th>
|
|
62
|
+
{:else}
|
|
63
|
+
<th
|
|
64
|
+
on:click={() =>
|
|
65
|
+
dispatchSort(tableHeader.campo)}
|
|
66
|
+
class="px-3 border-r cursor-pointer align-middle border border-solid py-1 text-xs uppercase border-l-0 whitespace-nowrap font-semibold text-left bg-blueGray-50 text-blueGray-500 border-blueGray-100"
|
|
67
|
+
>
|
|
68
|
+
<h1 class="relative">
|
|
69
|
+
{tableHeader.titulo}
|
|
70
|
+
</h1>
|
|
71
|
+
{#if selectedSort == tableHeader.campo}
|
|
72
|
+
{#if selectedAscOrDesc == "asc"}
|
|
73
|
+
<div
|
|
74
|
+
class="flex items-center justify-center"
|
|
75
|
+
>
|
|
76
|
+
<svg
|
|
77
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
78
|
+
width="16"
|
|
79
|
+
height="16"
|
|
80
|
+
viewBox="0 0 24 24"
|
|
81
|
+
fill="none"
|
|
82
|
+
stroke="currentColor"
|
|
83
|
+
stroke-width="2"
|
|
84
|
+
stroke-linecap="round"
|
|
85
|
+
stroke-linejoin="round"
|
|
86
|
+
class="ml-1"
|
|
87
|
+
>
|
|
88
|
+
<polyline
|
|
89
|
+
points="6 9 12 15 18 9"
|
|
90
|
+
></polyline>
|
|
91
|
+
</svg>
|
|
92
|
+
</div>
|
|
93
|
+
{:else}
|
|
94
|
+
<div
|
|
95
|
+
class="flex items-center justify-center"
|
|
96
|
+
>
|
|
97
|
+
<svg
|
|
98
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
99
|
+
width="16"
|
|
100
|
+
height="16"
|
|
101
|
+
viewBox="0 0 24 24"
|
|
102
|
+
fill="none"
|
|
103
|
+
stroke="currentColor"
|
|
104
|
+
stroke-width="2"
|
|
105
|
+
stroke-linecap="round"
|
|
106
|
+
stroke-linejoin="round"
|
|
107
|
+
class="ml-1"
|
|
108
|
+
>
|
|
109
|
+
<polyline
|
|
110
|
+
points="18 15 12 9 6 15"
|
|
111
|
+
></polyline>
|
|
112
|
+
</svg>
|
|
113
|
+
</div>
|
|
114
|
+
{/if}
|
|
115
|
+
{/if}
|
|
116
|
+
</th>
|
|
117
|
+
{/if}
|
|
118
|
+
{/each}
|
|
119
|
+
</tr>
|
|
120
|
+
</thead>
|
|
121
|
+
|
|
122
|
+
{#if todosLosRegistros && !loading}
|
|
123
|
+
<tbody>
|
|
124
|
+
{#each todosLosRegistros as item, index}
|
|
125
|
+
<tr
|
|
126
|
+
class="border-b-2 cursor-pointer transition-colors duration-200 {selectedRowId ===
|
|
127
|
+
index
|
|
128
|
+
? 'bg-gray-100'
|
|
129
|
+
: 'hover:bg-gray-50'}"
|
|
130
|
+
on:click={() => handleRowClick(index)}
|
|
131
|
+
>
|
|
132
|
+
{#each tableHeaders as tableBodyItem, i}
|
|
133
|
+
{#if tableBodyItem.tipo == "Text"}
|
|
134
|
+
<td
|
|
135
|
+
class="border-t-0 {i == 0
|
|
136
|
+
? 'sticky bg-white'
|
|
137
|
+
: ''} {selectedRowId ===
|
|
138
|
+
index
|
|
139
|
+
? 'bg-gray-100'
|
|
140
|
+
: 'hover:bg-gray-50'} z-10 left-0 align-middle border-l-0 border-r-0 whitespace-nowrap"
|
|
141
|
+
>
|
|
142
|
+
<p
|
|
143
|
+
class=" pl-1 whitespace-normal break-word sm:text-base text-xs {tableBodyItem.biBold
|
|
144
|
+
? 'font-bold'
|
|
145
|
+
: ''} text-blueGray-500"
|
|
146
|
+
>
|
|
147
|
+
{item[
|
|
148
|
+
tableBodyItem.campo
|
|
149
|
+
] ?? ""}
|
|
150
|
+
</p>
|
|
151
|
+
</td>
|
|
152
|
+
{:else if tableBodyItem.tipo == "Number"}
|
|
153
|
+
<td
|
|
154
|
+
class="border-t-0 {i == 0
|
|
155
|
+
? 'sticky bg-white'
|
|
156
|
+
: ''} {selectedRowId ===
|
|
157
|
+
index
|
|
158
|
+
? 'bg-gray-100'
|
|
159
|
+
: 'hover:bg-gray-50'} z-10 left-0 align-middle border-l-0 border-r-0 whitespace-nowrap"
|
|
160
|
+
>
|
|
161
|
+
<p
|
|
162
|
+
class=" pl-1 whitespace-normal break-word sm:text-base text-xs {tableBodyItem.biBold
|
|
163
|
+
? 'font-bold'
|
|
164
|
+
: ''} text-blueGray-500"
|
|
165
|
+
>
|
|
166
|
+
{item[
|
|
167
|
+
tableBodyItem.campo
|
|
168
|
+
] ?? ""}
|
|
169
|
+
</p>
|
|
170
|
+
</td>
|
|
171
|
+
{:else if tableBodyItem.tipo == "Buttons"}
|
|
172
|
+
<CrudTableButtons
|
|
173
|
+
id={item[
|
|
174
|
+
tableBodyItem.campo
|
|
175
|
+
]}
|
|
176
|
+
buttonsConfig={tableBodyItem.buttonsConfig ??
|
|
177
|
+
[]}
|
|
178
|
+
/>
|
|
179
|
+
{/if}
|
|
180
|
+
{/each}
|
|
181
|
+
</tr>
|
|
182
|
+
{/each}
|
|
183
|
+
</tbody>
|
|
184
|
+
{:else if !loading}
|
|
185
|
+
<tbody>
|
|
186
|
+
<tr>
|
|
187
|
+
<td
|
|
188
|
+
colspan={tableHeaders.length}
|
|
189
|
+
class="text-center py-4"
|
|
190
|
+
>
|
|
191
|
+
No hay datos disponibles
|
|
192
|
+
</td>
|
|
193
|
+
</tr>
|
|
194
|
+
</tbody>
|
|
195
|
+
{/if}
|
|
196
|
+
</table>
|
|
197
|
+
{#if loading}
|
|
198
|
+
<div class="mx-auto w-full rounded-md p-4">
|
|
199
|
+
<div class="flex animate-pulse space-x-4">
|
|
200
|
+
<div class="flex-1 space-y-6 py-1">
|
|
201
|
+
<div class="space-y-4">
|
|
202
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
203
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
204
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
205
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
206
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
207
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
208
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
209
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
210
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
211
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
212
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
213
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
214
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
215
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
216
|
+
<div class="h-4 rounded bg-gray-200" />
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
</div>
|
|
221
|
+
{/if}
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { TableHeader } from "./interfaces.js";
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
todosLosRegistros?: any[];
|
|
6
|
+
tableHeaders: TableHeader[];
|
|
7
|
+
loading?: boolean;
|
|
8
|
+
};
|
|
9
|
+
events: {
|
|
10
|
+
rowClick: CustomEvent<any>;
|
|
11
|
+
selectedSort: CustomEvent<any>;
|
|
12
|
+
} & {
|
|
13
|
+
[evt: string]: CustomEvent<any>;
|
|
14
|
+
};
|
|
15
|
+
slots: {};
|
|
16
|
+
};
|
|
17
|
+
export type CrudTableProps = typeof __propDef.props;
|
|
18
|
+
export type CrudTableEvents = typeof __propDef.events;
|
|
19
|
+
export type CrudTableSlots = typeof __propDef.slots;
|
|
20
|
+
export default class CrudTable extends SvelteComponentTyped<CrudTableProps, CrudTableEvents, CrudTableSlots> {
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ButtonConfig } from "./interfaces.js";
|
|
3
|
+
|
|
4
|
+
export let id = 1;
|
|
5
|
+
export let buttonsConfig: ButtonConfig[];
|
|
6
|
+
let showTooltip = "";
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<td class="text-xs text-center">
|
|
10
|
+
<div class="inline-flex rounded-md shadow-sm" role="group">
|
|
11
|
+
{#each buttonsConfig as button, i}
|
|
12
|
+
<div class="relative">
|
|
13
|
+
{#if showTooltip == button.tooltip}
|
|
14
|
+
<div
|
|
15
|
+
class="absolute z-[10000] p-1 text-white text-xs bg-gray-500 rounded shadow -top-6 -right-10"
|
|
16
|
+
>
|
|
17
|
+
{button.tooltip}
|
|
18
|
+
</div>
|
|
19
|
+
{/if}
|
|
20
|
+
</div>
|
|
21
|
+
<button
|
|
22
|
+
aria-label={button.tooltip}
|
|
23
|
+
on:click={() => button.action(id)}
|
|
24
|
+
on:mouseenter={() => (showTooltip = button.tooltip)}
|
|
25
|
+
on:mouseleave={() => (showTooltip = "")}
|
|
26
|
+
type="button"
|
|
27
|
+
class="inline-flex items-center sm:px-2 sm:py-1 px-3 py-2 min-h-6 min-w-5 sm:text-xs text-xs border border-gray-200 text-white {i ==
|
|
28
|
+
0
|
|
29
|
+
? 'rounded-l-lg'
|
|
30
|
+
: i == buttonsConfig.length - 1
|
|
31
|
+
? 'rounded-r-lg'
|
|
32
|
+
: ''} {button.color} "
|
|
33
|
+
>
|
|
34
|
+
<i class={button.icon}> </i>
|
|
35
|
+
</button>
|
|
36
|
+
{/each}
|
|
37
|
+
</div>
|
|
38
|
+
</td>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
import type { ButtonConfig } from "./interfaces.js";
|
|
3
|
+
declare const __propDef: {
|
|
4
|
+
props: {
|
|
5
|
+
id?: number;
|
|
6
|
+
buttonsConfig: ButtonConfig[];
|
|
7
|
+
};
|
|
8
|
+
events: {
|
|
9
|
+
[evt: string]: CustomEvent<any>;
|
|
10
|
+
};
|
|
11
|
+
slots: {};
|
|
12
|
+
};
|
|
13
|
+
export type CrudTableButtonsProps = typeof __propDef.props;
|
|
14
|
+
export type CrudTableButtonsEvents = typeof __propDef.events;
|
|
15
|
+
export type CrudTableButtonsSlots = typeof __propDef.slots;
|
|
16
|
+
export default class CrudTableButtons extends SvelteComponentTyped<CrudTableButtonsProps, CrudTableButtonsEvents, CrudTableButtonsSlots> {
|
|
17
|
+
}
|
|
18
|
+
export {};
|