grav-svelte 0.0.30 → 0.0.32
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/README.md +1 -0
- package/dist/CRUD/CrudFilters.css +21 -0
- package/dist/CRUD/CrudFilters.svelte +50 -22
- package/dist/CRUD/CrudTable.svelte +66 -3
- package/dist/CRUD/CrudTableButtons.svelte +2 -1
- package/dist/CRUD/CrudTableButtons.svelte.d.ts +1 -0
- package/dist/CRUD/CrudWrapper.svelte +3 -1
- package/dist/CRUD/ImageModal.svelte +16 -0
- package/dist/CRUD/ImageModal.svelte.d.ts +16 -0
- package/dist/CRUD/index.d.ts +1 -0
- package/dist/CRUD/index.js +1 -0
- package/dist/CRUD/interfaces.d.ts +12 -3
- package/dist/Inputs/InputFormSelect.svelte +2 -2
- package/dist/Inputs/InputFormSelect.svelte.d.ts +3 -3
- package/dist/Inputs/InputFormTextArea.svelte +96 -17
- package/dist/Inputs/InputFormTextArea.svelte.d.ts +1 -0
- package/dist/Sidebar/SidebarWrapper.svelte +19 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -177,4 +177,25 @@
|
|
|
177
177
|
|
|
178
178
|
.filter-item-bool {
|
|
179
179
|
margin: auto 0;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.loading-spinner {
|
|
183
|
+
display: flex;
|
|
184
|
+
justify-content: center;
|
|
185
|
+
align-items: center;
|
|
186
|
+
min-height: 38px;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
.spinner {
|
|
190
|
+
width: 20px;
|
|
191
|
+
height: 20px;
|
|
192
|
+
border: 2px solid #f3f3f3;
|
|
193
|
+
border-top: 2px solid #3498db;
|
|
194
|
+
border-radius: 50%;
|
|
195
|
+
animation: spin 1s linear infinite;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
@keyframes spin {
|
|
199
|
+
0% { transform: rotate(0deg); }
|
|
200
|
+
100% { transform: rotate(360deg); }
|
|
180
201
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { slide } from "svelte/transition";
|
|
9
9
|
import "./CrudFilters.css";
|
|
10
10
|
|
|
11
|
-
import { createEventDispatcher } from "svelte";
|
|
11
|
+
import { createEventDispatcher, onMount } from "svelte";
|
|
12
12
|
import type { FiltrosI } from "./interfaces.js";
|
|
13
13
|
const dispatch = createEventDispatcher();
|
|
14
14
|
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
let localPageSize = 50;
|
|
18
18
|
let localPageSizeStr = "50";
|
|
19
19
|
let showFilters = false;
|
|
20
|
+
let isLoading = false;
|
|
20
21
|
|
|
21
22
|
export let Filtros: FiltrosI[];
|
|
22
23
|
export let showAddButton: boolean = true;
|
|
@@ -74,6 +75,29 @@
|
|
|
74
75
|
localPageSizeStr = input.value;
|
|
75
76
|
}
|
|
76
77
|
}
|
|
78
|
+
|
|
79
|
+
let dataFetched: { value: any; label: string }[][] = [];
|
|
80
|
+
onMount(async () => {
|
|
81
|
+
console.log("Filtros", Filtros);
|
|
82
|
+
if (Filtros.length > 0) {
|
|
83
|
+
isLoading = true;
|
|
84
|
+
try {
|
|
85
|
+
const promises = Filtros.map(async (filtro) => {
|
|
86
|
+
console.log("filtro", filtro);
|
|
87
|
+
if (filtro.service) {
|
|
88
|
+
const data = await filtro.service();
|
|
89
|
+
return data;
|
|
90
|
+
}
|
|
91
|
+
return [];
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
dataFetched = await Promise.all(promises);
|
|
95
|
+
console.log("dataFetched", dataFetched);
|
|
96
|
+
} finally {
|
|
97
|
+
isLoading = false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
77
101
|
</script>
|
|
78
102
|
|
|
79
103
|
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
@@ -94,9 +118,7 @@
|
|
|
94
118
|
<div>
|
|
95
119
|
<div class="tooltip-container">
|
|
96
120
|
{#if showTooltip == "Agregar"}
|
|
97
|
-
<div class="tooltip">
|
|
98
|
-
Agregar
|
|
99
|
-
</div>
|
|
121
|
+
<div class="tooltip">Agregar</div>
|
|
100
122
|
{/if}
|
|
101
123
|
</div>
|
|
102
124
|
<!-- svelte-ignore a11y_consider_explicit_label -->
|
|
@@ -128,9 +150,7 @@
|
|
|
128
150
|
<div>
|
|
129
151
|
<div class="tooltip-container">
|
|
130
152
|
{#if showTooltip == "Importar"}
|
|
131
|
-
<div class="tooltip">
|
|
132
|
-
Importar Excel
|
|
133
|
-
</div>
|
|
153
|
+
<div class="tooltip">Importar Excel</div>
|
|
134
154
|
{/if}
|
|
135
155
|
</div>
|
|
136
156
|
<!-- svelte-ignore a11y_consider_explicit_label -->
|
|
@@ -219,9 +239,7 @@
|
|
|
219
239
|
<!-- Btn de limpiar filtros -->
|
|
220
240
|
<div class="tooltip-container">
|
|
221
241
|
{#if showTooltip == "Borrar"}
|
|
222
|
-
<div class="tooltip">
|
|
223
|
-
Borrar filtro
|
|
224
|
-
</div>
|
|
242
|
+
<div class="tooltip">Borrar filtro</div>
|
|
225
243
|
{/if}
|
|
226
244
|
</div>
|
|
227
245
|
<!-- svelte-ignore a11y_consider_explicit_label -->
|
|
@@ -266,9 +284,7 @@
|
|
|
266
284
|
<div class="filter-group" role="group">
|
|
267
285
|
<div class="tooltip-container">
|
|
268
286
|
{#if showTooltip == "Aplicar"}
|
|
269
|
-
<div class="tooltip">
|
|
270
|
-
Aplicar filtro
|
|
271
|
-
</div>
|
|
287
|
+
<div class="tooltip">Aplicar filtro</div>
|
|
272
288
|
{/if}
|
|
273
289
|
</div>
|
|
274
290
|
<button
|
|
@@ -276,8 +292,7 @@
|
|
|
276
292
|
on:click={() => actualizarFiltro()}
|
|
277
293
|
on:mouseenter={() => (showTooltip = "Aplicar")}
|
|
278
294
|
on:mouseleave={() => (showTooltip = "nada")}
|
|
279
|
-
class="apply-filter-button"
|
|
280
|
-
>Filtrar</button
|
|
295
|
+
class="apply-filter-button">Filtrar</button
|
|
281
296
|
>
|
|
282
297
|
</div>
|
|
283
298
|
<!-- /Btn de aplicar filtro -->
|
|
@@ -287,9 +302,8 @@
|
|
|
287
302
|
{#if showFilters}
|
|
288
303
|
<div
|
|
289
304
|
class="filters-grid"
|
|
290
|
-
transition:slide|local={{ duration: 300, delay: 100 }}
|
|
291
305
|
>
|
|
292
|
-
{#each Filtros as { tipo, label, options }, i}
|
|
306
|
+
{#each Filtros as { tipo, label, options, service }, i}
|
|
293
307
|
{#if tipo == "text"}
|
|
294
308
|
<div class="filter-item">
|
|
295
309
|
<InputFormText
|
|
@@ -320,11 +334,25 @@
|
|
|
320
334
|
</div>
|
|
321
335
|
{:else if tipo == "select"}
|
|
322
336
|
<div class="filter-item filter-item-select">
|
|
323
|
-
|
|
324
|
-
{
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
337
|
+
{#if service}
|
|
338
|
+
{#if isLoading}
|
|
339
|
+
<div class="loading-spinner">
|
|
340
|
+
<div class="spinner"></div>
|
|
341
|
+
</div>
|
|
342
|
+
{:else}
|
|
343
|
+
<InputFormSelect
|
|
344
|
+
{label}
|
|
345
|
+
res={dataFetched[i]}
|
|
346
|
+
bind:justValue={Filtros[i].value}
|
|
347
|
+
/>
|
|
348
|
+
{/if}
|
|
349
|
+
{:else}
|
|
350
|
+
<InputFormSelect
|
|
351
|
+
{label}
|
|
352
|
+
res={options}
|
|
353
|
+
bind:justValue={Filtros[i].value}
|
|
354
|
+
/>
|
|
355
|
+
{/if}
|
|
328
356
|
</div>
|
|
329
357
|
{:else if tipo == "bool"}
|
|
330
358
|
<div class="filter-item filter-item-bool">
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
2
|
+
import CrudTableButtons from "./CrudTableButtons.svelte";
|
|
3
|
+
import { openModal, closeModal } from "../Modals/index.js";
|
|
4
|
+
import ImageModal from "./ImageModal.svelte";
|
|
3
5
|
|
|
4
6
|
// COMPONENTES imports
|
|
5
7
|
|
|
@@ -36,6 +38,11 @@
|
|
|
36
38
|
selectedAsc: selectedAscOrDesc,
|
|
37
39
|
});
|
|
38
40
|
}
|
|
41
|
+
|
|
42
|
+
function openImageModal(src: string) {
|
|
43
|
+
closeModal("crud-image-modal");
|
|
44
|
+
openModal("crud-image-modal", ImageModal, { src });
|
|
45
|
+
}
|
|
39
46
|
</script>
|
|
40
47
|
|
|
41
48
|
<div class="table-container">
|
|
@@ -49,6 +56,7 @@
|
|
|
49
56
|
class="table-header-cell {index == 0
|
|
50
57
|
? 'borderleft'
|
|
51
58
|
: ''} non-sortable"
|
|
59
|
+
style="text-align: {tableHeader.align ?? 'center'}"
|
|
52
60
|
>
|
|
53
61
|
{tableHeader.titulo}
|
|
54
62
|
</th>
|
|
@@ -58,6 +66,7 @@
|
|
|
58
66
|
class="table-header-cell {index == 0
|
|
59
67
|
? 'borderleft'
|
|
60
68
|
: ''} sortable"
|
|
69
|
+
style="text-align: {tableHeader.align ?? 'left'}"
|
|
61
70
|
>
|
|
62
71
|
<h1>{tableHeader.titulo}</h1>
|
|
63
72
|
{#if selectedSort == tableHeader.campo}
|
|
@@ -127,6 +136,7 @@
|
|
|
127
136
|
class="cell-content {tableBodyItem.biBold
|
|
128
137
|
? 'bold'
|
|
129
138
|
: ''}"
|
|
139
|
+
style="text-align: {tableBodyItem.align ?? 'left'}"
|
|
130
140
|
>
|
|
131
141
|
{item[tableBodyItem.campo] ?? ""}
|
|
132
142
|
</p>
|
|
@@ -141,15 +151,49 @@
|
|
|
141
151
|
class="cell-content {tableBodyItem.biBold
|
|
142
152
|
? 'bold'
|
|
143
153
|
: ''}"
|
|
154
|
+
style="text-align: {tableBodyItem.align ?? 'left'}"
|
|
144
155
|
>
|
|
145
156
|
{item[tableBodyItem.campo] ?? ""}
|
|
146
157
|
</p>
|
|
147
158
|
</td>
|
|
159
|
+
{:else if tableBodyItem.tipo == "Bool"}
|
|
160
|
+
<td
|
|
161
|
+
class="table-cell {i == 0
|
|
162
|
+
? 'sticky-cell'
|
|
163
|
+
: ''}"
|
|
164
|
+
>
|
|
165
|
+
<p
|
|
166
|
+
class="cell-content {tableBodyItem.biBold
|
|
167
|
+
? 'bold'
|
|
168
|
+
: ''}"
|
|
169
|
+
style="text-align: {tableBodyItem.align ?? 'left'}"
|
|
170
|
+
>
|
|
171
|
+
{#if item[tableBodyItem.campo] === true}
|
|
172
|
+
<i class="fas fa-check"></i>
|
|
173
|
+
{:else}
|
|
174
|
+
-
|
|
175
|
+
{/if}
|
|
176
|
+
</p>
|
|
177
|
+
</td>
|
|
178
|
+
{:else if tableBodyItem.tipo == "Image"}
|
|
179
|
+
<td
|
|
180
|
+
class="table-cell {i == 0
|
|
181
|
+
? 'sticky-cell'
|
|
182
|
+
: ''}"
|
|
183
|
+
>
|
|
184
|
+
<img
|
|
185
|
+
class="crud-image cursor-pointer"
|
|
186
|
+
src={item[tableBodyItem.campo] ?? ''}
|
|
187
|
+
alt="image"
|
|
188
|
+
on:click={() => openImageModal(item[tableBodyItem.campo])}
|
|
189
|
+
/>
|
|
190
|
+
</td>
|
|
148
191
|
{:else if tableBodyItem.tipo == "Buttons"}
|
|
149
192
|
<CrudTableButtons
|
|
150
193
|
id={item[tableBodyItem.campo]}
|
|
151
194
|
buttonsConfig={tableBodyItem.buttonsConfig ??
|
|
152
195
|
[]}
|
|
196
|
+
align={tableBodyItem.align ?? 'center'}
|
|
153
197
|
/>
|
|
154
198
|
{/if}
|
|
155
199
|
{/each}
|
|
@@ -275,10 +319,20 @@
|
|
|
275
319
|
background-color: #f5f5f5;
|
|
276
320
|
}
|
|
277
321
|
|
|
322
|
+
/* ensure sticky cells follow row hover */
|
|
323
|
+
.table-row:hover .sticky-cell {
|
|
324
|
+
background-color: #f5f5f5;
|
|
325
|
+
}
|
|
326
|
+
|
|
278
327
|
.table-row.selected {
|
|
279
328
|
background-color: #e8e8e8;
|
|
280
329
|
}
|
|
281
330
|
|
|
331
|
+
/* keep first column selected state consistent */
|
|
332
|
+
.table-row.selected .sticky-cell {
|
|
333
|
+
background-color: #e8e8e8;
|
|
334
|
+
}
|
|
335
|
+
|
|
282
336
|
.table-cell {
|
|
283
337
|
border-top: 0;
|
|
284
338
|
border-left: 0;
|
|
@@ -319,6 +373,8 @@
|
|
|
319
373
|
|
|
320
374
|
.loading-animation {
|
|
321
375
|
display: flex;
|
|
376
|
+
flex-direction: column;
|
|
377
|
+
width: 100%;
|
|
322
378
|
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
323
379
|
}
|
|
324
380
|
|
|
@@ -328,8 +384,8 @@
|
|
|
328
384
|
background-color: #e0e0e0;
|
|
329
385
|
margin-bottom: 0.5rem;
|
|
330
386
|
width: 100%;
|
|
331
|
-
|
|
332
|
-
|
|
387
|
+
margin: 0 0 0.5rem 0;
|
|
388
|
+
flex: none;
|
|
333
389
|
}
|
|
334
390
|
|
|
335
391
|
@keyframes pulse {
|
|
@@ -347,4 +403,11 @@
|
|
|
347
403
|
font-size: 1rem;
|
|
348
404
|
}
|
|
349
405
|
}
|
|
406
|
+
|
|
407
|
+
.crud-image {
|
|
408
|
+
max-width: 4rem;
|
|
409
|
+
max-height: 4rem;
|
|
410
|
+
object-fit: contain;
|
|
411
|
+
margin: auto;
|
|
412
|
+
}
|
|
350
413
|
</style>
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
export let id = 1;
|
|
5
5
|
export let buttonsConfig: ButtonConfig[];
|
|
6
|
+
export let align: 'left' | 'right' | 'center' = 'center';
|
|
6
7
|
let showTooltip = "";
|
|
7
8
|
</script>
|
|
8
9
|
|
|
9
|
-
<td class="table-cell">
|
|
10
|
+
<td class="table-cell" style="text-align: {align}">
|
|
10
11
|
<div class="button-group" role="group">
|
|
11
12
|
{#each buttonsConfig as button, i}
|
|
12
13
|
<div class="tooltip-container">
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import CrudFilters from "./CrudFilters.svelte";
|
|
4
4
|
import CrudTable from "./CrudTable.svelte";
|
|
5
5
|
import type { FiltrosI, TableHeader, CrudWrapperProps } from "./interfaces.js";
|
|
6
|
-
|
|
6
|
+
import PaginationCrud from "./PaginationCRUD.svelte";
|
|
7
|
+
import { ModalContainer } from "../Modals/index.js";
|
|
7
8
|
|
|
8
9
|
export let Filtros: FiltrosI[];
|
|
9
10
|
export let todosLosObjetos: any[];
|
|
@@ -105,6 +106,7 @@
|
|
|
105
106
|
<i class="far fa-file-pdf pr-3"> </i>PDF
|
|
106
107
|
</button>
|
|
107
108
|
</div>
|
|
109
|
+
<ModalContainer />
|
|
108
110
|
</div>
|
|
109
111
|
|
|
110
112
|
<style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Grav_Modal, closeModal } from '../Modals/index.js';
|
|
3
|
+
export let src: string;
|
|
4
|
+
const MODAL_ID = 'crud-image-modal';
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<Grav_Modal
|
|
8
|
+
title="Imagen"
|
|
9
|
+
size="md"
|
|
10
|
+
isVista={true}
|
|
11
|
+
onClose={() => closeModal(MODAL_ID)}
|
|
12
|
+
>
|
|
13
|
+
<div class="flex items-center justify-center p-4">
|
|
14
|
+
<img src={src} alt="image" class="max-w-full max-h-[80vh]" />
|
|
15
|
+
</div>
|
|
16
|
+
</Grav_Modal>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
declare const __propDef: {
|
|
3
|
+
props: {
|
|
4
|
+
src: string;
|
|
5
|
+
};
|
|
6
|
+
events: {
|
|
7
|
+
[evt: string]: CustomEvent<any>;
|
|
8
|
+
};
|
|
9
|
+
slots: {};
|
|
10
|
+
};
|
|
11
|
+
export type ImageModalProps = typeof __propDef.props;
|
|
12
|
+
export type ImageModalEvents = typeof __propDef.events;
|
|
13
|
+
export type ImageModalSlots = typeof __propDef.slots;
|
|
14
|
+
export default class ImageModal extends SvelteComponentTyped<ImageModalProps, ImageModalEvents, ImageModalSlots> {
|
|
15
|
+
}
|
|
16
|
+
export {};
|
package/dist/CRUD/index.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ export { default as CrudTable } from './CrudTable.svelte';
|
|
|
3
3
|
export { default as CrudFilters } from './CrudFilters.svelte';
|
|
4
4
|
export { default as PaginationCrud } from './PaginationCRUD.svelte';
|
|
5
5
|
export { default as CrudTableButtons } from './CrudTableButtons.svelte';
|
|
6
|
+
export { default as ImageModal } from './ImageModal.svelte';
|
|
6
7
|
export type { ButtonConfig, TableHeader, FiltrosI, CrudWrapperProps } from './interfaces.js';
|
package/dist/CRUD/index.js
CHANGED
|
@@ -3,3 +3,4 @@ export { default as CrudTable } from './CrudTable.svelte';
|
|
|
3
3
|
export { default as CrudFilters } from './CrudFilters.svelte';
|
|
4
4
|
export { default as PaginationCrud } from './PaginationCRUD.svelte';
|
|
5
5
|
export { default as CrudTableButtons } from './CrudTableButtons.svelte';
|
|
6
|
+
export { default as ImageModal } from './ImageModal.svelte';
|
|
@@ -7,8 +7,13 @@ export interface ButtonConfig {
|
|
|
7
7
|
export interface TableHeader {
|
|
8
8
|
titulo: string;
|
|
9
9
|
biSort: boolean;
|
|
10
|
-
tipo: 'Text' | 'Number' | 'Buttons';
|
|
10
|
+
tipo: 'Text' | 'Number' | 'Buttons' | 'Bool' | 'Image';
|
|
11
11
|
biBold: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Alignment for the content of the cells belonging to this header.
|
|
14
|
+
* Defaults to 'left' when not provided.
|
|
15
|
+
*/
|
|
16
|
+
align?: 'left' | 'right' | 'center';
|
|
12
17
|
campo: string;
|
|
13
18
|
buttonsConfig: ButtonConfig[] | null;
|
|
14
19
|
}
|
|
@@ -16,10 +21,14 @@ export interface FiltrosI {
|
|
|
16
21
|
tipo: 'number' | 'text' | 'date' | 'datetime' | 'select' | 'bool';
|
|
17
22
|
label: string;
|
|
18
23
|
value: any;
|
|
19
|
-
options
|
|
20
|
-
value:
|
|
24
|
+
options?: {
|
|
25
|
+
value: any;
|
|
21
26
|
label: string;
|
|
22
27
|
}[];
|
|
28
|
+
service?: () => Promise<{
|
|
29
|
+
value: any;
|
|
30
|
+
label: string;
|
|
31
|
+
}[]>;
|
|
23
32
|
}
|
|
24
33
|
export interface CrudWrapperProps {
|
|
25
34
|
Filtros: FiltrosI[];
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import Select from "svelte-select";
|
|
3
3
|
|
|
4
4
|
interface SelectValue {
|
|
5
|
-
value:
|
|
5
|
+
value: any;
|
|
6
6
|
label: string;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export let value: SelectValue | null = null;
|
|
10
|
-
export let justValue:
|
|
10
|
+
export let justValue: any | null = null;
|
|
11
11
|
export let res: any[] = [];
|
|
12
12
|
export let changeFunction: (
|
|
13
13
|
e: CustomEvent<SelectValue | null>
|
|
@@ -2,13 +2,13 @@ import { SvelteComponentTyped } from "svelte";
|
|
|
2
2
|
declare const __propDef: {
|
|
3
3
|
props: {
|
|
4
4
|
value?: {
|
|
5
|
-
value:
|
|
5
|
+
value: any;
|
|
6
6
|
label: string;
|
|
7
7
|
} | null;
|
|
8
|
-
justValue?:
|
|
8
|
+
justValue?: any | null;
|
|
9
9
|
res?: any[];
|
|
10
10
|
changeFunction?: (e: CustomEvent<{
|
|
11
|
-
value:
|
|
11
|
+
value: any;
|
|
12
12
|
label: string;
|
|
13
13
|
} | null>) => void;
|
|
14
14
|
onClear?: () => void;
|
|
@@ -4,23 +4,102 @@
|
|
|
4
4
|
export let disabled = false;
|
|
5
5
|
export let obligatory = false;
|
|
6
6
|
export let rows: number = 3;
|
|
7
|
+
export let icon: string | null = null;
|
|
7
8
|
</script>
|
|
8
9
|
|
|
9
|
-
<div class="
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
10
|
+
<div class="input-container">
|
|
11
|
+
{#if icon}
|
|
12
|
+
<div class="icon-wrapper">
|
|
13
|
+
<i class="{icon} icon"></i>
|
|
14
|
+
</div>
|
|
15
|
+
{/if}
|
|
16
|
+
<div class="input-wrapper">
|
|
17
|
+
<textarea
|
|
18
|
+
{disabled}
|
|
19
|
+
id={valueVar}
|
|
20
|
+
bind:value={valueVar}
|
|
21
|
+
name={valueVar}
|
|
22
|
+
{rows}
|
|
23
|
+
placeholder=""
|
|
24
|
+
class="input-field"
|
|
25
|
+
/>
|
|
26
|
+
<label for={valueVar} class="input-label"
|
|
27
|
+
>{label}
|
|
28
|
+
{#if obligatory}
|
|
29
|
+
<span class="required-mark"> *</span>
|
|
30
|
+
{/if}</label
|
|
31
|
+
>
|
|
32
|
+
</div>
|
|
26
33
|
</div>
|
|
34
|
+
|
|
35
|
+
<style>
|
|
36
|
+
.input-container {
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
margin-top: 0.75rem;
|
|
40
|
+
border: 0;
|
|
41
|
+
border-bottom: 2px solid #9ca3af;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.icon-wrapper {
|
|
45
|
+
width: 1rem;
|
|
46
|
+
position: relative;
|
|
47
|
+
margin-right: 0.5rem;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.icon {
|
|
51
|
+
position: absolute;
|
|
52
|
+
top: -0.25rem;
|
|
53
|
+
left: 0.25rem;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.input-wrapper {
|
|
57
|
+
position: relative;
|
|
58
|
+
z-index: 0;
|
|
59
|
+
width: 100%;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.input-field {
|
|
63
|
+
display: block;
|
|
64
|
+
padding-top: 0.625rem;
|
|
65
|
+
padding-left: 0;
|
|
66
|
+
padding-right: 0;
|
|
67
|
+
width: 100%;
|
|
68
|
+
font-size: 1rem;
|
|
69
|
+
color: #111827;
|
|
70
|
+
background: transparent;
|
|
71
|
+
appearance: none;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.input-field:focus {
|
|
75
|
+
outline: none;
|
|
76
|
+
border-color: black;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.input-label {
|
|
80
|
+
position: absolute;
|
|
81
|
+
font-size: 1rem;
|
|
82
|
+
text-align: left;
|
|
83
|
+
color: black;
|
|
84
|
+
transition: all 0.3s;
|
|
85
|
+
top: 0.625rem;
|
|
86
|
+
z-index: -10;
|
|
87
|
+
transform-origin: left;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.input-field:focus + .input-label,
|
|
91
|
+
.input-field:not(:placeholder-shown) + .input-label {
|
|
92
|
+
left: 0;
|
|
93
|
+
color: #4b5563;
|
|
94
|
+
translate: 0rem -1.25rem;
|
|
95
|
+
scale: 0.75;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.input-field:placeholder-shown + .input-label {
|
|
99
|
+
transform: translateY(0) scale(1);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.required-mark {
|
|
103
|
+
color: #dc2626;
|
|
104
|
+
}
|
|
105
|
+
</style>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { SidebarSection } from "./sidebarConfig.js";
|
|
3
3
|
import SidebarItem from "./SidebarItem.svelte";
|
|
4
4
|
import "./SidebarWrapper.css";
|
|
5
|
+
import { Confirmacion_Alert } from "../index.js";
|
|
5
6
|
import { onMount } from 'svelte';
|
|
6
7
|
// Props
|
|
7
8
|
export let sections: SidebarSection[];
|
|
@@ -26,6 +27,17 @@
|
|
|
26
27
|
console.log("toggleCollapseShow");
|
|
27
28
|
collapseShow = !collapseShow;
|
|
28
29
|
}
|
|
30
|
+
|
|
31
|
+
function handleLogout(event: MouseEvent) {
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
Confirmacion_Alert(
|
|
34
|
+
"Confirmar cierre de sesión",
|
|
35
|
+
"¿Desea cerrar sesión?",
|
|
36
|
+
() => {
|
|
37
|
+
window.location.href = logoutLink;
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
}
|
|
29
41
|
</script>
|
|
30
42
|
|
|
31
43
|
<nav class="sidebar {customClass}">
|
|
@@ -107,8 +119,13 @@
|
|
|
107
119
|
|
|
108
120
|
{#if showLogout}
|
|
109
121
|
<li class="logout-item">
|
|
110
|
-
<a
|
|
111
|
-
|
|
122
|
+
<a
|
|
123
|
+
class="logout-link"
|
|
124
|
+
href={logoutLink}
|
|
125
|
+
on:click|preventDefault={handleLogout}
|
|
126
|
+
>
|
|
127
|
+
Log Out
|
|
128
|
+
<i class="fas fa-sign-out-alt ml-2"></i>
|
|
112
129
|
</a>
|
|
113
130
|
</li>
|
|
114
131
|
{/if}
|