@golstats/gsc-reports 1.0.76 → 1.0.78
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 +2 -2
- package/dist/{FilterConditions-55d68355-DMqzcKBO-LoDZzMFx-BnRBGncA.js → FilterConditions-55d68355-DMqzcKBO-D2kXmeoL-DEviWylE.js} +5 -5
- package/dist/{FilterField-59a73e38-CNaE03Ge-CQDCuDcF-D41LgF38.js → FilterField-59a73e38-CNaE03Ge-B0XkVQzG-V94Z81Vi.js} +1 -1
- package/dist/{FilterSubcategories-a9b32cc9-_h5FCZ4r-B4SJzQzA-DXEQISeO.js → FilterSubcategories-a9b32cc9-_h5FCZ4r-Df-aYrQw-VYuSaZOV.js} +4 -4
- package/dist/css/fonts.css +83 -83
- package/dist/gsc-reports.css +1 -1
- package/dist/gsc-reports.es.js +1 -1
- package/dist/gsc-reports.umd.js +236 -236
- package/dist/images/cancha-horizontal.jpg +0 -0
- package/dist/images/canchaRPH.svg +30 -0
- package/dist/{index-DWidkeeO.js → index-Ddsk52G7.js} +48677 -48614
- package/package.json +2 -2
- package/src/components/elementsTemplates/ModalConfigurarContenido.vue +1250 -1250
- package/src/components/elementsTemplates/ModalDeleteTemplate.vue +249 -249
- package/src/components/elementsTemplates/ModalSoloEscritorio.vue +83 -83
- package/src/components/elementsTemplates/ModalduplicateTemplate.vue +300 -300
- package/src/components/elementsTemplates/TooltipReportOptions.vue +97 -97
- package/src/components/elementsTemplates/TooltipTemplateOptions.vue +168 -168
- package/src/components/filters.vue +935 -935
- package/src/components/template-report-maker/CoverSelector.vue +165 -165
- package/src/components/template-report-maker/ReportView.vue +66 -66
- package/src/components/thumbnails-reports/AnalisisPostMatchType1.vue +741 -741
- package/src/components/thumbnails-reports/AnalisisPostMatchType2.vue +743 -743
- package/src/components/thumbnails-reports/AnalisisPrematchType3.vue +173 -173
- package/src/components/thumbnails-reports/AnalisisPrematchType4.vue +173 -173
- package/src/index.js +4 -4
- package/src/types.d.ts +45 -45
- package/src/utils/dateUtils.js +52 -52
|
@@ -1,935 +1,935 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="floating-bar">
|
|
3
|
-
<button class="tab active">Nueva vista</button>
|
|
4
|
-
<!-- Primer selector: opciones principales -->
|
|
5
|
-
<div class="custom-select" @click="toggleFieldMenu">
|
|
6
|
-
<div class="select-display">
|
|
7
|
-
<span class="select-icon">
|
|
8
|
-
<img v-if="selectedMain" :src="selectedMain.url" alt="icono" class="option-img" />
|
|
9
|
-
</span>
|
|
10
|
-
<span v-if="!selectedMain" class="select-placeholder select-label">Tipo de vista</span>
|
|
11
|
-
<span v-else class="select-label">{{ getFieldLabel() }}</span>
|
|
12
|
-
<span class="arrow" :class="{ open: showFieldMenu }">
|
|
13
|
-
<svg width="16" height="14" viewBox="0 0 16 14" fill="none">
|
|
14
|
-
<path
|
|
15
|
-
d="M3 5L8 10L13 5"
|
|
16
|
-
stroke="#AAB4BE"
|
|
17
|
-
stroke-width="2"
|
|
18
|
-
stroke-linecap="round"
|
|
19
|
-
stroke-linejoin="round"
|
|
20
|
-
/>
|
|
21
|
-
</svg>
|
|
22
|
-
</span>
|
|
23
|
-
</div>
|
|
24
|
-
<div v-if="showFieldMenu" class="dropdown-menu field-menu">
|
|
25
|
-
<div
|
|
26
|
-
v-for="(option, idx) in mainOptions"
|
|
27
|
-
:key="option.id"
|
|
28
|
-
class="option-card"
|
|
29
|
-
:class="{ active: selectedMainIndex === idx }"
|
|
30
|
-
@click.stop="selectMain(idx)"
|
|
31
|
-
>
|
|
32
|
-
<div class="option-icon">
|
|
33
|
-
<img :src="option.url" alt="icono" class="option-img" />
|
|
34
|
-
</div>
|
|
35
|
-
<div class="option-content">
|
|
36
|
-
<div class="option-title">{{ option.name }}</div>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
<!-- Segundo selector: views hijos -->
|
|
42
|
-
<div class="custom-select" @click="toggleTypeMenu">
|
|
43
|
-
<div class="select-display">
|
|
44
|
-
<span class="select-icon">
|
|
45
|
-
<img v-if="selectedSecond" :src="selectedSecond.url" alt="icono" class="option-img" />
|
|
46
|
-
</span>
|
|
47
|
-
<span class="select-label">{{ getTypeLabel() }}</span>
|
|
48
|
-
<span class="arrow" :class="{ open: showTypeMenu }">
|
|
49
|
-
<svg width="16" height="14" viewBox="0 0 16 14" fill="none">
|
|
50
|
-
<path
|
|
51
|
-
d="M3 5L8 10L13 5"
|
|
52
|
-
stroke="#AAB4BE"
|
|
53
|
-
stroke-width="2"
|
|
54
|
-
stroke-linecap="round"
|
|
55
|
-
stroke-linejoin="round"
|
|
56
|
-
/>
|
|
57
|
-
</svg>
|
|
58
|
-
</span>
|
|
59
|
-
</div>
|
|
60
|
-
<div v-if="showTypeMenu && selectedMain" class="dropdown-menu type-menu type-menu-grid">
|
|
61
|
-
<div class="option-grid">
|
|
62
|
-
<div
|
|
63
|
-
v-for="option in secondOptions"
|
|
64
|
-
:key="option.id"
|
|
65
|
-
class="option-card-grid"
|
|
66
|
-
:class="{ active: selectedSecondId === option.id }"
|
|
67
|
-
@click.stop="selectSecond(option)"
|
|
68
|
-
>
|
|
69
|
-
<div class="option-grid-title">{{ option.name || option.title }}</div>
|
|
70
|
-
<div class="option-grid-icon">
|
|
71
|
-
<img :src="option.url" alt="icono" class="option-img-grid" />
|
|
72
|
-
</div>
|
|
73
|
-
</div>
|
|
74
|
-
</div>
|
|
75
|
-
</div>
|
|
76
|
-
</div>
|
|
77
|
-
<!-- Separador después del segundo selector -->
|
|
78
|
-
<div class="filter-separator"></div>
|
|
79
|
-
<!-- Filtros dinámicos -->
|
|
80
|
-
<div
|
|
81
|
-
v-if="selectedSecond && selectedSecond.filters"
|
|
82
|
-
:class="['dynamic-filters', { 'dynamic-filters-wide': selectedSecond.filters.length >= 2 }]"
|
|
83
|
-
>
|
|
84
|
-
<template v-for="(filter, idx) in selectedSecond.filters" :key="idx">
|
|
85
|
-
<div
|
|
86
|
-
v-if="filter.type === 'select'"
|
|
87
|
-
class="custom-select dynamic-select filter-inline"
|
|
88
|
-
@click.stop="toggleDynamicSelect(idx)"
|
|
89
|
-
>
|
|
90
|
-
<div class="select-display">
|
|
91
|
-
<span class="select-icon">
|
|
92
|
-
<img v-if="filter.icon" :src="filter.icon" alt="icono" class="option-img" />
|
|
93
|
-
</span>
|
|
94
|
-
<span class="select-label">
|
|
95
|
-
{{ getMultiSelectLabel(idx) || filter.label || 'Selecciona opciones' }}
|
|
96
|
-
</span>
|
|
97
|
-
<span class="arrow" :class="{ open: dynamicSelectOpen === idx }">
|
|
98
|
-
<svg width="16" height="14" viewBox="0 0 16 14" fill="none">
|
|
99
|
-
<path
|
|
100
|
-
d="M3 5L8 10L13 5"
|
|
101
|
-
stroke="#AAB4BE"
|
|
102
|
-
stroke-width="2"
|
|
103
|
-
stroke-linecap="round"
|
|
104
|
-
stroke-linejoin="round"
|
|
105
|
-
/>
|
|
106
|
-
</svg>
|
|
107
|
-
</span>
|
|
108
|
-
</div>
|
|
109
|
-
<div v-if="dynamicSelectOpen === idx" class="dropdown-menu type-menu multi-select-menu">
|
|
110
|
-
<div class="multi-select-header" @click.stop>
|
|
111
|
-
<label class="select-all-checkbox">
|
|
112
|
-
<input
|
|
113
|
-
type="checkbox"
|
|
114
|
-
:checked="areAllSelected(idx)"
|
|
115
|
-
:indeterminate="isIndeterminate(idx)"
|
|
116
|
-
@change.stop="toggleSelectAll(idx)"
|
|
117
|
-
@click.stop
|
|
118
|
-
/>
|
|
119
|
-
<span class="select-all-label">Agregar todas</span>
|
|
120
|
-
</label>
|
|
121
|
-
</div>
|
|
122
|
-
<div
|
|
123
|
-
v-for="option in filter.options"
|
|
124
|
-
:key="option.value"
|
|
125
|
-
class="option-card multi-select-option"
|
|
126
|
-
:class="{ active: isOptionSelected(idx, option.value) }"
|
|
127
|
-
@click.stop="toggleMultiSelectOption(idx, option.value)"
|
|
128
|
-
>
|
|
129
|
-
<div class="option-checkbox">
|
|
130
|
-
<input
|
|
131
|
-
type="checkbox"
|
|
132
|
-
:checked="isOptionSelected(idx, option.value)"
|
|
133
|
-
@change.stop="toggleMultiSelectOption(idx, option.value)"
|
|
134
|
-
/>
|
|
135
|
-
</div>
|
|
136
|
-
<div class="option-icon">
|
|
137
|
-
<img v-if="option.icon" :src="option.icon" alt="icono" class="option-img" />
|
|
138
|
-
</div>
|
|
139
|
-
<div class="option-content">
|
|
140
|
-
<div class="option-title">{{ option.label }}</div>
|
|
141
|
-
</div>
|
|
142
|
-
</div>
|
|
143
|
-
</div>
|
|
144
|
-
</div>
|
|
145
|
-
<div v-else-if="filter.type === 'radio-button'" class="custom-radio-group filter-inline">
|
|
146
|
-
<div class="radio-label">{{ filter.label }}</div>
|
|
147
|
-
<div class="radio-options">
|
|
148
|
-
<label
|
|
149
|
-
v-for="option in filter.options"
|
|
150
|
-
:key="option.value"
|
|
151
|
-
class="radio-option-card"
|
|
152
|
-
:class="{ active: dynamicFilters[idx] === option.value }"
|
|
153
|
-
>
|
|
154
|
-
<input
|
|
155
|
-
type="radio"
|
|
156
|
-
:name="'dynamic-radio-' + idx"
|
|
157
|
-
:value="option.value"
|
|
158
|
-
v-model="dynamicFilters[idx]"
|
|
159
|
-
@change="emitChange"
|
|
160
|
-
/>
|
|
161
|
-
<span>{{ option.label }}</span>
|
|
162
|
-
</label>
|
|
163
|
-
</div>
|
|
164
|
-
</div>
|
|
165
|
-
<div v-else-if="filter.type === 'check'" class="check-group filter-inline">
|
|
166
|
-
<label>
|
|
167
|
-
<input type="checkbox" v-model="dynamicFilters[idx]" @change="emitChange" />
|
|
168
|
-
{{ filter.label }}
|
|
169
|
-
</label>
|
|
170
|
-
</div>
|
|
171
|
-
<div v-if="idx === 1 && selectedSecond.filters.length > 2" class="filter-separator"></div>
|
|
172
|
-
</template>
|
|
173
|
-
</div>
|
|
174
|
-
|
|
175
|
-
<button class="close-btn" @click="emitClose">✕</button>
|
|
176
|
-
</div>
|
|
177
|
-
</template>
|
|
178
|
-
|
|
179
|
-
<script setup>
|
|
180
|
-
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
|
|
181
|
-
|
|
182
|
-
defineOptions({
|
|
183
|
-
name: 'FloatingFiltersBar',
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
const props = defineProps({
|
|
187
|
-
token: {
|
|
188
|
-
type: String,
|
|
189
|
-
required: true,
|
|
190
|
-
},
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
const emit = defineEmits(['filters-changed', 'close'])
|
|
194
|
-
|
|
195
|
-
// Estado para los datos de la API
|
|
196
|
-
const apiData = ref([])
|
|
197
|
-
|
|
198
|
-
// Opciones del primer selector: solo el primer nivel
|
|
199
|
-
const mainOptions = computed(() => apiData.value)
|
|
200
|
-
const selectedMainIndex = ref(null)
|
|
201
|
-
const selectedMain = computed(() => mainOptions.value[selectedMainIndex.value] || null)
|
|
202
|
-
|
|
203
|
-
// Opciones del segundo selector: los views hijos del seleccionado
|
|
204
|
-
const secondOptions = computed(() => selectedMain.value?.views || [])
|
|
205
|
-
const selectedSecondId = ref(null)
|
|
206
|
-
const selectedSecond = computed(
|
|
207
|
-
() => secondOptions.value.find((v) => v.id === selectedSecondId.value) || null,
|
|
208
|
-
)
|
|
209
|
-
|
|
210
|
-
// Filtros dinámicos para el view seleccionado
|
|
211
|
-
const dynamicFilters = ref([])
|
|
212
|
-
|
|
213
|
-
// Sincroniza los filtros dinámicos cuando cambia el view seleccionado
|
|
214
|
-
watch(selectedSecond, (newVal) => {
|
|
215
|
-
if (!newVal || !Array.isArray(newVal.filters)) {
|
|
216
|
-
dynamicFilters.value = []
|
|
217
|
-
return
|
|
218
|
-
}
|
|
219
|
-
// Inicializa los valores según el tipo de filtro
|
|
220
|
-
dynamicFilters.value = newVal.filters.map((f) => {
|
|
221
|
-
if (f.type === 'select') {
|
|
222
|
-
return [] // Array vacío para selección múltiple
|
|
223
|
-
} else if (f.type === 'radio-button') {
|
|
224
|
-
return f.options?.[0]?.value ?? null
|
|
225
|
-
} else if (f.type === 'check') {
|
|
226
|
-
return f.value ?? false
|
|
227
|
-
}
|
|
228
|
-
return null
|
|
229
|
-
})
|
|
230
|
-
})
|
|
231
|
-
|
|
232
|
-
// Funciones para manejo de selección múltiple
|
|
233
|
-
function isOptionSelected(filterIdx, optionValue) {
|
|
234
|
-
const selectedValues = dynamicFilters.value[filterIdx]
|
|
235
|
-
return Array.isArray(selectedValues) && selectedValues.includes(optionValue)
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function toggleMultiSelectOption(filterIdx, optionValue) {
|
|
239
|
-
if (!Array.isArray(dynamicFilters.value[filterIdx])) {
|
|
240
|
-
dynamicFilters.value[filterIdx] = []
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const selectedValues = dynamicFilters.value[filterIdx]
|
|
244
|
-
const index = selectedValues.indexOf(optionValue)
|
|
245
|
-
|
|
246
|
-
if (index > -1) {
|
|
247
|
-
selectedValues.splice(index, 1)
|
|
248
|
-
} else {
|
|
249
|
-
selectedValues.push(optionValue)
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
emitChange()
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function getMultiSelectLabel(filterIdx) {
|
|
256
|
-
const selectedValues = dynamicFilters.value[filterIdx]
|
|
257
|
-
if (!Array.isArray(selectedValues) || selectedValues.length === 0) {
|
|
258
|
-
return 'Selecciona opciones'
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const filter = selectedSecond.value?.filters?.[filterIdx]
|
|
262
|
-
if (!filter || !filter.options) return 'Opciones seleccionadas'
|
|
263
|
-
|
|
264
|
-
const selectedLabels = selectedValues
|
|
265
|
-
.map((value) => filter.options.find((opt) => opt.value === value)?.label)
|
|
266
|
-
.filter(Boolean)
|
|
267
|
-
|
|
268
|
-
if (selectedLabels.length === 1) {
|
|
269
|
-
return selectedLabels[0]
|
|
270
|
-
} else if (selectedLabels.length <= 3) {
|
|
271
|
-
return selectedLabels.join(', ')
|
|
272
|
-
} else {
|
|
273
|
-
return `${selectedLabels.length} opciones seleccionadas`
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
function areAllSelected(filterIdx) {
|
|
278
|
-
const selectedValues = dynamicFilters.value[filterIdx]
|
|
279
|
-
const filter = selectedSecond.value?.filters?.[filterIdx]
|
|
280
|
-
if (!filter || !filter.options || !Array.isArray(selectedValues)) return false
|
|
281
|
-
|
|
282
|
-
return selectedValues.length === filter.options.length
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
function isIndeterminate(filterIdx) {
|
|
286
|
-
const selectedValues = dynamicFilters.value[filterIdx]
|
|
287
|
-
const filter = selectedSecond.value?.filters?.[filterIdx]
|
|
288
|
-
if (!filter || !filter.options || !Array.isArray(selectedValues)) return false
|
|
289
|
-
|
|
290
|
-
return selectedValues.length > 0 && selectedValues.length < filter.options.length
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
function toggleSelectAll(filterIdx) {
|
|
294
|
-
const filter = selectedSecond.value?.filters?.[filterIdx]
|
|
295
|
-
if (!filter || !filter.options) return
|
|
296
|
-
|
|
297
|
-
const allValues = filter.options.map((opt) => opt.value)
|
|
298
|
-
|
|
299
|
-
// Asegurar que dynamicFilters[filterIdx] sea un array
|
|
300
|
-
if (!Array.isArray(dynamicFilters.value[filterIdx])) {
|
|
301
|
-
dynamicFilters.value[filterIdx] = []
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
if (areAllSelected(filterIdx)) {
|
|
305
|
-
// Si todas están seleccionadas, deseleccionar todas
|
|
306
|
-
dynamicFilters.value[filterIdx] = []
|
|
307
|
-
} else {
|
|
308
|
-
// Si no todas están seleccionadas, seleccionar todas
|
|
309
|
-
dynamicFilters.value[filterIdx] = [...allValues]
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
// Mantener el menú abierto
|
|
313
|
-
dynamicSelectOpen.value = filterIdx
|
|
314
|
-
|
|
315
|
-
emitChange()
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
const selectedTeam = ref('ambos')
|
|
319
|
-
const showFieldMenu = ref(false)
|
|
320
|
-
const showTypeMenu = ref(false)
|
|
321
|
-
const dynamicSelectOpen = ref(null)
|
|
322
|
-
|
|
323
|
-
function getFieldLabel() {
|
|
324
|
-
if (!selectedMain.value) return 'Tipo de vista'
|
|
325
|
-
return selectedMain.value.name
|
|
326
|
-
}
|
|
327
|
-
function getTypeLabel() {
|
|
328
|
-
if (!selectedSecond.value) return 'Selecciona una opción'
|
|
329
|
-
return selectedSecond.value.name || selectedSecond.value.title
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
function toggleFieldMenu() {
|
|
333
|
-
showFieldMenu.value = !showFieldMenu.value
|
|
334
|
-
if (showFieldMenu.value) {
|
|
335
|
-
showTypeMenu.value = false
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
function toggleTypeMenu() {
|
|
339
|
-
if (!selectedMain.value) return // No abrir si no hay selección
|
|
340
|
-
showTypeMenu.value = !showTypeMenu.value
|
|
341
|
-
if (showTypeMenu.value) {
|
|
342
|
-
showFieldMenu.value = false
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
function selectMain(index) {
|
|
346
|
-
selectedMainIndex.value = index
|
|
347
|
-
showFieldMenu.value = false
|
|
348
|
-
// Limpiar selección dependiente
|
|
349
|
-
selectedSecondId.value = null
|
|
350
|
-
emitChange()
|
|
351
|
-
}
|
|
352
|
-
function selectSecond(option) {
|
|
353
|
-
selectedSecondId.value = option.id
|
|
354
|
-
showTypeMenu.value = false
|
|
355
|
-
emitChange()
|
|
356
|
-
}
|
|
357
|
-
function toggleDynamicSelect(idx) {
|
|
358
|
-
dynamicSelectOpen.value = dynamicSelectOpen.value === idx ? null : idx
|
|
359
|
-
}
|
|
360
|
-
function handleClickOutside(event) {
|
|
361
|
-
if (!event.target.closest('.custom-select')) {
|
|
362
|
-
showFieldMenu.value = false
|
|
363
|
-
showTypeMenu.value = false
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
function emitChange() {
|
|
367
|
-
emit('filters-changed', {
|
|
368
|
-
main: selectedMain.value,
|
|
369
|
-
view: selectedSecond.value,
|
|
370
|
-
team: selectedTeam.value,
|
|
371
|
-
dynamicFilters: dynamicFilters.value,
|
|
372
|
-
})
|
|
373
|
-
}
|
|
374
|
-
function resetFilters() {
|
|
375
|
-
selectedMainIndex.value = null
|
|
376
|
-
selectedSecondId.value = null
|
|
377
|
-
selectedTeam.value = 'ambos'
|
|
378
|
-
dynamicFilters.value = []
|
|
379
|
-
showFieldMenu.value = false
|
|
380
|
-
showTypeMenu.value = false
|
|
381
|
-
dynamicSelectOpen.value = null
|
|
382
|
-
}
|
|
383
|
-
function emitClose() {
|
|
384
|
-
resetFilters()
|
|
385
|
-
emit('close')
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
onMounted(async () => {
|
|
389
|
-
document.addEventListener('click', handleClickOutside)
|
|
390
|
-
try {
|
|
391
|
-
const response = await fetch(
|
|
392
|
-
'https://m9qip57rsh.execute-api.us-east-2.amazonaws.com/prod/views',
|
|
393
|
-
{
|
|
394
|
-
headers: {
|
|
395
|
-
Authorization: `${props.token}`,
|
|
396
|
-
},
|
|
397
|
-
},
|
|
398
|
-
)
|
|
399
|
-
const data = await response.json()
|
|
400
|
-
apiData.value = data.data || []
|
|
401
|
-
} catch (error) {
|
|
402
|
-
console.error('Error al obtener datos:', error)
|
|
403
|
-
}
|
|
404
|
-
})
|
|
405
|
-
onUnmounted(() => {
|
|
406
|
-
document.removeEventListener('click', handleClickOutside)
|
|
407
|
-
})
|
|
408
|
-
</script>
|
|
409
|
-
|
|
410
|
-
<style scoped>
|
|
411
|
-
.floating-bar {
|
|
412
|
-
position: absolute;
|
|
413
|
-
top: 67px;
|
|
414
|
-
left: 50%;
|
|
415
|
-
background: #2a3843;
|
|
416
|
-
border-radius: 8px;
|
|
417
|
-
display: flex;
|
|
418
|
-
align-items: center;
|
|
419
|
-
padding: 8px 32px;
|
|
420
|
-
z-index: 100;
|
|
421
|
-
gap: 12px;
|
|
422
|
-
height: 62px;
|
|
423
|
-
width: auto;
|
|
424
|
-
min-width: 600px;
|
|
425
|
-
max-width: 100vw;
|
|
426
|
-
box-sizing: border-box;
|
|
427
|
-
transform: translateX(-50%);
|
|
428
|
-
}
|
|
429
|
-
.dynamic-select,
|
|
430
|
-
.radio-group,
|
|
431
|
-
.check-group {
|
|
432
|
-
display: inline-flex;
|
|
433
|
-
margin-bottom: 0 !important;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
.tab {
|
|
437
|
-
background: none;
|
|
438
|
-
color: #fafafb;
|
|
439
|
-
border: none;
|
|
440
|
-
border-radius: 6px 6px 0 0;
|
|
441
|
-
padding: 8px 18px;
|
|
442
|
-
font-weight: bold;
|
|
443
|
-
font-size: 16px;
|
|
444
|
-
margin-right: 8px;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
.tab.active {
|
|
448
|
-
color: #fff;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
.custom-select {
|
|
452
|
-
position: relative;
|
|
453
|
-
cursor: pointer;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
.select-display {
|
|
457
|
-
background: #3f4c56;
|
|
458
|
-
color: #fafafb;
|
|
459
|
-
border: 1px solid #e9ecee;
|
|
460
|
-
border-radius: 6px;
|
|
461
|
-
padding: 0px 32px 0px 12px;
|
|
462
|
-
font-size: 15px;
|
|
463
|
-
display: flex;
|
|
464
|
-
align-items: center;
|
|
465
|
-
justify-content: space-between;
|
|
466
|
-
min-width: 140px;
|
|
467
|
-
height: 40px;
|
|
468
|
-
transition: border-color 0.2s;
|
|
469
|
-
}
|
|
470
|
-
.select-icon {
|
|
471
|
-
display: flex;
|
|
472
|
-
align-items: center;
|
|
473
|
-
margin-right: 8px;
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
.select-display:hover {
|
|
477
|
-
border-color: #cbee6b;
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
.arrow {
|
|
481
|
-
display: flex;
|
|
482
|
-
align-items: center;
|
|
483
|
-
transition: transform 0.2s;
|
|
484
|
-
}
|
|
485
|
-
.arrow svg {
|
|
486
|
-
display: block;
|
|
487
|
-
}
|
|
488
|
-
.arrow.open {
|
|
489
|
-
transform: rotate(180deg);
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
.custom-select:hover .arrow {
|
|
493
|
-
transform: rotate(180deg);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
.dropdown-menu {
|
|
497
|
-
position: absolute;
|
|
498
|
-
top: 100%;
|
|
499
|
-
left: 0;
|
|
500
|
-
background: #2a3843;
|
|
501
|
-
border: 1px solid #3d4a54;
|
|
502
|
-
border-radius: 8px;
|
|
503
|
-
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
|
504
|
-
padding: 8px;
|
|
505
|
-
margin-top: 4px;
|
|
506
|
-
min-width: 200px;
|
|
507
|
-
z-index: 1000;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
.option-card {
|
|
511
|
-
display: flex;
|
|
512
|
-
align-items: center;
|
|
513
|
-
padding: 12px;
|
|
514
|
-
border-radius: 6px;
|
|
515
|
-
cursor: pointer;
|
|
516
|
-
transition: background-color 0.2s;
|
|
517
|
-
margin-bottom: 4px;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
.option-card:last-child {
|
|
521
|
-
margin-bottom: 0;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
.option-card:hover {
|
|
525
|
-
background: #3d4a54;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
.option-card.active {
|
|
529
|
-
background: #cbee6b;
|
|
530
|
-
color: #1a2a36;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
.option-icon {
|
|
534
|
-
font-size: 20px;
|
|
535
|
-
margin-right: 12px;
|
|
536
|
-
width: 24px;
|
|
537
|
-
text-align: center;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
.option-content {
|
|
541
|
-
flex: 1;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
.option-title {
|
|
545
|
-
font-weight: 600;
|
|
546
|
-
font-size: 14px;
|
|
547
|
-
margin-bottom: 2px;
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
.option-description {
|
|
551
|
-
font-size: 12px;
|
|
552
|
-
opacity: 0.8;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
.radio-group {
|
|
556
|
-
display: flex;
|
|
557
|
-
align-items: center;
|
|
558
|
-
gap: 10px;
|
|
559
|
-
margin-left: 16px;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
.radio-group label {
|
|
563
|
-
color: #fafafb;
|
|
564
|
-
font-size: 15px;
|
|
565
|
-
display: flex;
|
|
566
|
-
align-items: center;
|
|
567
|
-
gap: 4px;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
input[type='radio'] {
|
|
571
|
-
appearance: none;
|
|
572
|
-
-webkit-appearance: none;
|
|
573
|
-
background: #2a3843;
|
|
574
|
-
border: 2px solid #e9ecee;
|
|
575
|
-
width: 20px;
|
|
576
|
-
height: 20px;
|
|
577
|
-
border-radius: 50%;
|
|
578
|
-
margin-right: 6px;
|
|
579
|
-
margin-top: 0px;
|
|
580
|
-
position: relative;
|
|
581
|
-
cursor: pointer;
|
|
582
|
-
outline: none;
|
|
583
|
-
transition: border-color 0.2s;
|
|
584
|
-
}
|
|
585
|
-
input[type='radio']:checked::before {
|
|
586
|
-
content: '';
|
|
587
|
-
display: block;
|
|
588
|
-
width: 12px;
|
|
589
|
-
height: 12px;
|
|
590
|
-
background: #cbee6b;
|
|
591
|
-
border-radius: 50%;
|
|
592
|
-
position: absolute;
|
|
593
|
-
top: 2px;
|
|
594
|
-
left: 2px;
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
.check-group {
|
|
598
|
-
display: flex;
|
|
599
|
-
align-items: center;
|
|
600
|
-
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
601
|
-
font-size: 14px;
|
|
602
|
-
color: #fff;
|
|
603
|
-
background: none;
|
|
604
|
-
border: none;
|
|
605
|
-
border-radius: 0;
|
|
606
|
-
padding: 0 8px;
|
|
607
|
-
min-height: 40px;
|
|
608
|
-
margin-right: 8px;
|
|
609
|
-
}
|
|
610
|
-
.check-group input[type='checkbox'] {
|
|
611
|
-
accent-color: #cbee6b;
|
|
612
|
-
margin-right: 8px;
|
|
613
|
-
width: 18px;
|
|
614
|
-
height: 18px;
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
.close-btn {
|
|
618
|
-
background: none;
|
|
619
|
-
border: none;
|
|
620
|
-
color: #fafafb;
|
|
621
|
-
font-size: 22px;
|
|
622
|
-
margin-left: auto;
|
|
623
|
-
cursor: pointer;
|
|
624
|
-
transition: color 0.2s;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
.close-btn:hover {
|
|
628
|
-
color: #cbee6b;
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
.select-label {
|
|
632
|
-
flex-grow: 0;
|
|
633
|
-
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
634
|
-
font-size: 14px;
|
|
635
|
-
font-weight: 500;
|
|
636
|
-
font-stretch: normal;
|
|
637
|
-
font-style: normal;
|
|
638
|
-
margin-left: -10px;
|
|
639
|
-
line-height: normal;
|
|
640
|
-
letter-spacing: normal;
|
|
641
|
-
text-align: left;
|
|
642
|
-
color: #d9d9d9;
|
|
643
|
-
}
|
|
644
|
-
.option-title {
|
|
645
|
-
flex-grow: 0;
|
|
646
|
-
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
647
|
-
font-size: 14px;
|
|
648
|
-
font-weight: 500;
|
|
649
|
-
font-stretch: normal;
|
|
650
|
-
font-style: normal;
|
|
651
|
-
line-height: normal;
|
|
652
|
-
letter-spacing: normal;
|
|
653
|
-
text-align: left;
|
|
654
|
-
color: #fff;
|
|
655
|
-
}
|
|
656
|
-
.select-placeholder {
|
|
657
|
-
font-family: 'Poppins-Regular', 'Poppins', Arial, sans-serif !important;
|
|
658
|
-
font-size: 14px;
|
|
659
|
-
margin-left: -8px;
|
|
660
|
-
color: #d9d9d9;
|
|
661
|
-
}
|
|
662
|
-
.option-img {
|
|
663
|
-
width: 24px;
|
|
664
|
-
height: 24px;
|
|
665
|
-
object-fit: cover;
|
|
666
|
-
border-radius: 4px;
|
|
667
|
-
background: #222;
|
|
668
|
-
}
|
|
669
|
-
.custom-radio-group {
|
|
670
|
-
display: flex;
|
|
671
|
-
flex-direction: row;
|
|
672
|
-
align-items: center;
|
|
673
|
-
border-radius: 6px;
|
|
674
|
-
padding: 0px 16px;
|
|
675
|
-
min-height: 40px;
|
|
676
|
-
justify-content: center;
|
|
677
|
-
margin-right: 8px;
|
|
678
|
-
}
|
|
679
|
-
.radio-label {
|
|
680
|
-
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
681
|
-
font-size: 13px;
|
|
682
|
-
color: #d9d9d9;
|
|
683
|
-
margin-bottom: 0;
|
|
684
|
-
margin-right: 8px;
|
|
685
|
-
}
|
|
686
|
-
.radio-options {
|
|
687
|
-
display: flex;
|
|
688
|
-
flex-direction: row;
|
|
689
|
-
gap: 8px;
|
|
690
|
-
flex-wrap: nowrap;
|
|
691
|
-
}
|
|
692
|
-
.radio-option-card {
|
|
693
|
-
display: flex;
|
|
694
|
-
align-items: center;
|
|
695
|
-
background: transparent;
|
|
696
|
-
border: none;
|
|
697
|
-
border-radius: 4px;
|
|
698
|
-
padding: 6px 10px;
|
|
699
|
-
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
700
|
-
font-size: 14px;
|
|
701
|
-
color: #fff;
|
|
702
|
-
cursor: pointer;
|
|
703
|
-
transition:
|
|
704
|
-
background 0.2s,
|
|
705
|
-
color 0.2s;
|
|
706
|
-
white-space: nowrap;
|
|
707
|
-
min-width: 0;
|
|
708
|
-
max-width: 120px;
|
|
709
|
-
justify-content: center;
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
.filter-separator {
|
|
713
|
-
width: 1px;
|
|
714
|
-
height: 32px;
|
|
715
|
-
border-left: 2px dashed #d9d9d9;
|
|
716
|
-
margin: 0 16px;
|
|
717
|
-
align-self: center;
|
|
718
|
-
}
|
|
719
|
-
.filter-inline {
|
|
720
|
-
display: inline-flex;
|
|
721
|
-
align-items: center;
|
|
722
|
-
vertical-align: middle;
|
|
723
|
-
margin-bottom: 0 !important;
|
|
724
|
-
min-width: 140px;
|
|
725
|
-
}
|
|
726
|
-
.select-label,
|
|
727
|
-
.option-title,
|
|
728
|
-
.radio-label,
|
|
729
|
-
.radio-option-card span,
|
|
730
|
-
.check-group label {
|
|
731
|
-
white-space: nowrap;
|
|
732
|
-
overflow: hidden;
|
|
733
|
-
text-overflow: ellipsis;
|
|
734
|
-
max-width: 180px;
|
|
735
|
-
display: inline-block;
|
|
736
|
-
vertical-align: middle;
|
|
737
|
-
}
|
|
738
|
-
.dynamic-filters {
|
|
739
|
-
display: flex;
|
|
740
|
-
align-items: center;
|
|
741
|
-
transition:
|
|
742
|
-
min-width 0.2s,
|
|
743
|
-
padding 0.2s;
|
|
744
|
-
}
|
|
745
|
-
.dynamic-filters-wide {
|
|
746
|
-
min-width: 400px;
|
|
747
|
-
padding-right: 24px;
|
|
748
|
-
padding-left: 24px;
|
|
749
|
-
}
|
|
750
|
-
.dynamic-filters-wide > .filter-inline:not(:last-child) {
|
|
751
|
-
margin-right: 16px;
|
|
752
|
-
}
|
|
753
|
-
.type-menu-grid {
|
|
754
|
-
min-width: 360px;
|
|
755
|
-
max-width: 420px;
|
|
756
|
-
}
|
|
757
|
-
.option-grid {
|
|
758
|
-
display: grid;
|
|
759
|
-
grid-template-columns: repeat(3, 1fr);
|
|
760
|
-
gap: 16px;
|
|
761
|
-
padding: 8px 0;
|
|
762
|
-
}
|
|
763
|
-
.option-card-grid {
|
|
764
|
-
display: flex;
|
|
765
|
-
flex-direction: column;
|
|
766
|
-
align-items: center;
|
|
767
|
-
justify-content: flex-start;
|
|
768
|
-
background: #3f4c56;
|
|
769
|
-
border: 2px solid transparent;
|
|
770
|
-
border-radius: 10px;
|
|
771
|
-
padding: 12px 8px 10px 8px;
|
|
772
|
-
cursor: pointer;
|
|
773
|
-
transition:
|
|
774
|
-
border-color 0.2s,
|
|
775
|
-
background 0.2s;
|
|
776
|
-
min-width: 90px;
|
|
777
|
-
min-height: 110px;
|
|
778
|
-
box-sizing: border-box;
|
|
779
|
-
}
|
|
780
|
-
.option-card-grid.active,
|
|
781
|
-
.option-card-grid:hover {
|
|
782
|
-
border-color: #cbee6b;
|
|
783
|
-
background: #22334a;
|
|
784
|
-
}
|
|
785
|
-
.option-grid-title {
|
|
786
|
-
font-size: 11px;
|
|
787
|
-
color: #d9d9d9;
|
|
788
|
-
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
789
|
-
margin-bottom: 8px;
|
|
790
|
-
text-align: center;
|
|
791
|
-
white-space: nowrap;
|
|
792
|
-
overflow: hidden;
|
|
793
|
-
text-overflow: ellipsis;
|
|
794
|
-
width: 100%;
|
|
795
|
-
}
|
|
796
|
-
.option-grid-icon {
|
|
797
|
-
display: flex;
|
|
798
|
-
align-items: center;
|
|
799
|
-
justify-content: center;
|
|
800
|
-
flex: 1;
|
|
801
|
-
}
|
|
802
|
-
.option-img-grid {
|
|
803
|
-
width: 40px;
|
|
804
|
-
height: 40px;
|
|
805
|
-
object-fit: cover;
|
|
806
|
-
border-radius: 6px;
|
|
807
|
-
background: #222;
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
/* Estilos para selector múltiple */
|
|
811
|
-
.multi-select-menu {
|
|
812
|
-
min-width: 280px;
|
|
813
|
-
max-width: 400px;
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
.multi-select-header {
|
|
817
|
-
display: flex;
|
|
818
|
-
justify-content: space-between;
|
|
819
|
-
align-items: center;
|
|
820
|
-
padding: 8px 12px;
|
|
821
|
-
border-bottom: 1px solid #3d4a54;
|
|
822
|
-
margin-bottom: 8px;
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
.select-all-checkbox {
|
|
826
|
-
display: flex;
|
|
827
|
-
align-items: center;
|
|
828
|
-
cursor: pointer;
|
|
829
|
-
gap: 8px;
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
.select-all-checkbox input[type='checkbox'] {
|
|
833
|
-
appearance: none;
|
|
834
|
-
-webkit-appearance: none;
|
|
835
|
-
width: 18px;
|
|
836
|
-
height: 18px;
|
|
837
|
-
border: 2px solid #e9ecee;
|
|
838
|
-
border-radius: 3px;
|
|
839
|
-
background: #2a3843;
|
|
840
|
-
cursor: pointer;
|
|
841
|
-
position: relative;
|
|
842
|
-
transition: all 0.2s;
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
.select-all-checkbox input[type='checkbox']:checked {
|
|
846
|
-
background: #cbee6b;
|
|
847
|
-
border-color: #cbee6b;
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
.select-all-checkbox input[type='checkbox']:checked::before {
|
|
851
|
-
content: '✓';
|
|
852
|
-
position: absolute;
|
|
853
|
-
top: 50%;
|
|
854
|
-
left: 50%;
|
|
855
|
-
transform: translate(-50%, -50%);
|
|
856
|
-
color: #1a2a36;
|
|
857
|
-
font-size: 12px;
|
|
858
|
-
font-weight: bold;
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
.select-all-checkbox input[type='checkbox']:indeterminate::before {
|
|
862
|
-
content: '−';
|
|
863
|
-
position: absolute;
|
|
864
|
-
top: 50%;
|
|
865
|
-
left: 50%;
|
|
866
|
-
transform: translate(-50%, -50%);
|
|
867
|
-
color: #1a2a36;
|
|
868
|
-
font-size: 14px;
|
|
869
|
-
font-weight: bold;
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
.select-all-checkbox input[type='checkbox']:hover {
|
|
873
|
-
border-color: #cbee6b;
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
.select-all-label {
|
|
877
|
-
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
878
|
-
font-size: 14px;
|
|
879
|
-
color: #d9d9d9;
|
|
880
|
-
font-weight: 500;
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
.multi-select-option {
|
|
884
|
-
padding: 8px 12px;
|
|
885
|
-
margin-bottom: 2px;
|
|
886
|
-
}
|
|
887
|
-
|
|
888
|
-
.multi-select-option:hover {
|
|
889
|
-
background: #3d4a54;
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
.multi-select-option.active {
|
|
893
|
-
background: rgba(203, 238, 107, 0.1);
|
|
894
|
-
border: 1px solid #cbee6b;
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
.option-checkbox {
|
|
898
|
-
display: flex;
|
|
899
|
-
align-items: center;
|
|
900
|
-
margin-right: 8px;
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
.option-checkbox input[type='checkbox'] {
|
|
904
|
-
appearance: none;
|
|
905
|
-
-webkit-appearance: none;
|
|
906
|
-
width: 18px;
|
|
907
|
-
height: 18px;
|
|
908
|
-
border: 2px solid #e9ecee;
|
|
909
|
-
border-radius: 3px;
|
|
910
|
-
background: #2a3843;
|
|
911
|
-
cursor: pointer;
|
|
912
|
-
position: relative;
|
|
913
|
-
transition: all 0.2s;
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
.option-checkbox input[type='checkbox']:checked {
|
|
917
|
-
background: #cbee6b;
|
|
918
|
-
border-color: #cbee6b;
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
.option-checkbox input[type='checkbox']:checked::before {
|
|
922
|
-
content: '✓';
|
|
923
|
-
position: absolute;
|
|
924
|
-
top: 50%;
|
|
925
|
-
left: 50%;
|
|
926
|
-
transform: translate(-50%, -50%);
|
|
927
|
-
color: #1a2a36;
|
|
928
|
-
font-size: 12px;
|
|
929
|
-
font-weight: bold;
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
.option-checkbox input[type='checkbox']:hover {
|
|
933
|
-
border-color: #cbee6b;
|
|
934
|
-
}
|
|
935
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<div class="floating-bar">
|
|
3
|
+
<button class="tab active">Nueva vista</button>
|
|
4
|
+
<!-- Primer selector: opciones principales -->
|
|
5
|
+
<div class="custom-select" @click="toggleFieldMenu">
|
|
6
|
+
<div class="select-display">
|
|
7
|
+
<span class="select-icon">
|
|
8
|
+
<img v-if="selectedMain" :src="selectedMain.url" alt="icono" class="option-img" />
|
|
9
|
+
</span>
|
|
10
|
+
<span v-if="!selectedMain" class="select-placeholder select-label">Tipo de vista</span>
|
|
11
|
+
<span v-else class="select-label">{{ getFieldLabel() }}</span>
|
|
12
|
+
<span class="arrow" :class="{ open: showFieldMenu }">
|
|
13
|
+
<svg width="16" height="14" viewBox="0 0 16 14" fill="none">
|
|
14
|
+
<path
|
|
15
|
+
d="M3 5L8 10L13 5"
|
|
16
|
+
stroke="#AAB4BE"
|
|
17
|
+
stroke-width="2"
|
|
18
|
+
stroke-linecap="round"
|
|
19
|
+
stroke-linejoin="round"
|
|
20
|
+
/>
|
|
21
|
+
</svg>
|
|
22
|
+
</span>
|
|
23
|
+
</div>
|
|
24
|
+
<div v-if="showFieldMenu" class="dropdown-menu field-menu">
|
|
25
|
+
<div
|
|
26
|
+
v-for="(option, idx) in mainOptions"
|
|
27
|
+
:key="option.id"
|
|
28
|
+
class="option-card"
|
|
29
|
+
:class="{ active: selectedMainIndex === idx }"
|
|
30
|
+
@click.stop="selectMain(idx)"
|
|
31
|
+
>
|
|
32
|
+
<div class="option-icon">
|
|
33
|
+
<img :src="option.url" alt="icono" class="option-img" />
|
|
34
|
+
</div>
|
|
35
|
+
<div class="option-content">
|
|
36
|
+
<div class="option-title">{{ option.name }}</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
<!-- Segundo selector: views hijos -->
|
|
42
|
+
<div class="custom-select" @click="toggleTypeMenu">
|
|
43
|
+
<div class="select-display">
|
|
44
|
+
<span class="select-icon">
|
|
45
|
+
<img v-if="selectedSecond" :src="selectedSecond.url" alt="icono" class="option-img" />
|
|
46
|
+
</span>
|
|
47
|
+
<span class="select-label">{{ getTypeLabel() }}</span>
|
|
48
|
+
<span class="arrow" :class="{ open: showTypeMenu }">
|
|
49
|
+
<svg width="16" height="14" viewBox="0 0 16 14" fill="none">
|
|
50
|
+
<path
|
|
51
|
+
d="M3 5L8 10L13 5"
|
|
52
|
+
stroke="#AAB4BE"
|
|
53
|
+
stroke-width="2"
|
|
54
|
+
stroke-linecap="round"
|
|
55
|
+
stroke-linejoin="round"
|
|
56
|
+
/>
|
|
57
|
+
</svg>
|
|
58
|
+
</span>
|
|
59
|
+
</div>
|
|
60
|
+
<div v-if="showTypeMenu && selectedMain" class="dropdown-menu type-menu type-menu-grid">
|
|
61
|
+
<div class="option-grid">
|
|
62
|
+
<div
|
|
63
|
+
v-for="option in secondOptions"
|
|
64
|
+
:key="option.id"
|
|
65
|
+
class="option-card-grid"
|
|
66
|
+
:class="{ active: selectedSecondId === option.id }"
|
|
67
|
+
@click.stop="selectSecond(option)"
|
|
68
|
+
>
|
|
69
|
+
<div class="option-grid-title">{{ option.name || option.title }}</div>
|
|
70
|
+
<div class="option-grid-icon">
|
|
71
|
+
<img :src="option.url" alt="icono" class="option-img-grid" />
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
<!-- Separador después del segundo selector -->
|
|
78
|
+
<div class="filter-separator"></div>
|
|
79
|
+
<!-- Filtros dinámicos -->
|
|
80
|
+
<div
|
|
81
|
+
v-if="selectedSecond && selectedSecond.filters"
|
|
82
|
+
:class="['dynamic-filters', { 'dynamic-filters-wide': selectedSecond.filters.length >= 2 }]"
|
|
83
|
+
>
|
|
84
|
+
<template v-for="(filter, idx) in selectedSecond.filters" :key="idx">
|
|
85
|
+
<div
|
|
86
|
+
v-if="filter.type === 'select'"
|
|
87
|
+
class="custom-select dynamic-select filter-inline"
|
|
88
|
+
@click.stop="toggleDynamicSelect(idx)"
|
|
89
|
+
>
|
|
90
|
+
<div class="select-display">
|
|
91
|
+
<span class="select-icon">
|
|
92
|
+
<img v-if="filter.icon" :src="filter.icon" alt="icono" class="option-img" />
|
|
93
|
+
</span>
|
|
94
|
+
<span class="select-label">
|
|
95
|
+
{{ getMultiSelectLabel(idx) || filter.label || 'Selecciona opciones' }}
|
|
96
|
+
</span>
|
|
97
|
+
<span class="arrow" :class="{ open: dynamicSelectOpen === idx }">
|
|
98
|
+
<svg width="16" height="14" viewBox="0 0 16 14" fill="none">
|
|
99
|
+
<path
|
|
100
|
+
d="M3 5L8 10L13 5"
|
|
101
|
+
stroke="#AAB4BE"
|
|
102
|
+
stroke-width="2"
|
|
103
|
+
stroke-linecap="round"
|
|
104
|
+
stroke-linejoin="round"
|
|
105
|
+
/>
|
|
106
|
+
</svg>
|
|
107
|
+
</span>
|
|
108
|
+
</div>
|
|
109
|
+
<div v-if="dynamicSelectOpen === idx" class="dropdown-menu type-menu multi-select-menu">
|
|
110
|
+
<div class="multi-select-header" @click.stop>
|
|
111
|
+
<label class="select-all-checkbox">
|
|
112
|
+
<input
|
|
113
|
+
type="checkbox"
|
|
114
|
+
:checked="areAllSelected(idx)"
|
|
115
|
+
:indeterminate="isIndeterminate(idx)"
|
|
116
|
+
@change.stop="toggleSelectAll(idx)"
|
|
117
|
+
@click.stop
|
|
118
|
+
/>
|
|
119
|
+
<span class="select-all-label">Agregar todas</span>
|
|
120
|
+
</label>
|
|
121
|
+
</div>
|
|
122
|
+
<div
|
|
123
|
+
v-for="option in filter.options"
|
|
124
|
+
:key="option.value"
|
|
125
|
+
class="option-card multi-select-option"
|
|
126
|
+
:class="{ active: isOptionSelected(idx, option.value) }"
|
|
127
|
+
@click.stop="toggleMultiSelectOption(idx, option.value)"
|
|
128
|
+
>
|
|
129
|
+
<div class="option-checkbox">
|
|
130
|
+
<input
|
|
131
|
+
type="checkbox"
|
|
132
|
+
:checked="isOptionSelected(idx, option.value)"
|
|
133
|
+
@change.stop="toggleMultiSelectOption(idx, option.value)"
|
|
134
|
+
/>
|
|
135
|
+
</div>
|
|
136
|
+
<div class="option-icon">
|
|
137
|
+
<img v-if="option.icon" :src="option.icon" alt="icono" class="option-img" />
|
|
138
|
+
</div>
|
|
139
|
+
<div class="option-content">
|
|
140
|
+
<div class="option-title">{{ option.label }}</div>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
<div v-else-if="filter.type === 'radio-button'" class="custom-radio-group filter-inline">
|
|
146
|
+
<div class="radio-label">{{ filter.label }}</div>
|
|
147
|
+
<div class="radio-options">
|
|
148
|
+
<label
|
|
149
|
+
v-for="option in filter.options"
|
|
150
|
+
:key="option.value"
|
|
151
|
+
class="radio-option-card"
|
|
152
|
+
:class="{ active: dynamicFilters[idx] === option.value }"
|
|
153
|
+
>
|
|
154
|
+
<input
|
|
155
|
+
type="radio"
|
|
156
|
+
:name="'dynamic-radio-' + idx"
|
|
157
|
+
:value="option.value"
|
|
158
|
+
v-model="dynamicFilters[idx]"
|
|
159
|
+
@change="emitChange"
|
|
160
|
+
/>
|
|
161
|
+
<span>{{ option.label }}</span>
|
|
162
|
+
</label>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
<div v-else-if="filter.type === 'check'" class="check-group filter-inline">
|
|
166
|
+
<label>
|
|
167
|
+
<input type="checkbox" v-model="dynamicFilters[idx]" @change="emitChange" />
|
|
168
|
+
{{ filter.label }}
|
|
169
|
+
</label>
|
|
170
|
+
</div>
|
|
171
|
+
<div v-if="idx === 1 && selectedSecond.filters.length > 2" class="filter-separator"></div>
|
|
172
|
+
</template>
|
|
173
|
+
</div>
|
|
174
|
+
|
|
175
|
+
<button class="close-btn" @click="emitClose">✕</button>
|
|
176
|
+
</div>
|
|
177
|
+
</template>
|
|
178
|
+
|
|
179
|
+
<script setup>
|
|
180
|
+
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
|
|
181
|
+
|
|
182
|
+
defineOptions({
|
|
183
|
+
name: 'FloatingFiltersBar',
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
const props = defineProps({
|
|
187
|
+
token: {
|
|
188
|
+
type: String,
|
|
189
|
+
required: true,
|
|
190
|
+
},
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
const emit = defineEmits(['filters-changed', 'close'])
|
|
194
|
+
|
|
195
|
+
// Estado para los datos de la API
|
|
196
|
+
const apiData = ref([])
|
|
197
|
+
|
|
198
|
+
// Opciones del primer selector: solo el primer nivel
|
|
199
|
+
const mainOptions = computed(() => apiData.value)
|
|
200
|
+
const selectedMainIndex = ref(null)
|
|
201
|
+
const selectedMain = computed(() => mainOptions.value[selectedMainIndex.value] || null)
|
|
202
|
+
|
|
203
|
+
// Opciones del segundo selector: los views hijos del seleccionado
|
|
204
|
+
const secondOptions = computed(() => selectedMain.value?.views || [])
|
|
205
|
+
const selectedSecondId = ref(null)
|
|
206
|
+
const selectedSecond = computed(
|
|
207
|
+
() => secondOptions.value.find((v) => v.id === selectedSecondId.value) || null,
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
// Filtros dinámicos para el view seleccionado
|
|
211
|
+
const dynamicFilters = ref([])
|
|
212
|
+
|
|
213
|
+
// Sincroniza los filtros dinámicos cuando cambia el view seleccionado
|
|
214
|
+
watch(selectedSecond, (newVal) => {
|
|
215
|
+
if (!newVal || !Array.isArray(newVal.filters)) {
|
|
216
|
+
dynamicFilters.value = []
|
|
217
|
+
return
|
|
218
|
+
}
|
|
219
|
+
// Inicializa los valores según el tipo de filtro
|
|
220
|
+
dynamicFilters.value = newVal.filters.map((f) => {
|
|
221
|
+
if (f.type === 'select') {
|
|
222
|
+
return [] // Array vacío para selección múltiple
|
|
223
|
+
} else if (f.type === 'radio-button') {
|
|
224
|
+
return f.options?.[0]?.value ?? null
|
|
225
|
+
} else if (f.type === 'check') {
|
|
226
|
+
return f.value ?? false
|
|
227
|
+
}
|
|
228
|
+
return null
|
|
229
|
+
})
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
// Funciones para manejo de selección múltiple
|
|
233
|
+
function isOptionSelected(filterIdx, optionValue) {
|
|
234
|
+
const selectedValues = dynamicFilters.value[filterIdx]
|
|
235
|
+
return Array.isArray(selectedValues) && selectedValues.includes(optionValue)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function toggleMultiSelectOption(filterIdx, optionValue) {
|
|
239
|
+
if (!Array.isArray(dynamicFilters.value[filterIdx])) {
|
|
240
|
+
dynamicFilters.value[filterIdx] = []
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const selectedValues = dynamicFilters.value[filterIdx]
|
|
244
|
+
const index = selectedValues.indexOf(optionValue)
|
|
245
|
+
|
|
246
|
+
if (index > -1) {
|
|
247
|
+
selectedValues.splice(index, 1)
|
|
248
|
+
} else {
|
|
249
|
+
selectedValues.push(optionValue)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
emitChange()
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function getMultiSelectLabel(filterIdx) {
|
|
256
|
+
const selectedValues = dynamicFilters.value[filterIdx]
|
|
257
|
+
if (!Array.isArray(selectedValues) || selectedValues.length === 0) {
|
|
258
|
+
return 'Selecciona opciones'
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const filter = selectedSecond.value?.filters?.[filterIdx]
|
|
262
|
+
if (!filter || !filter.options) return 'Opciones seleccionadas'
|
|
263
|
+
|
|
264
|
+
const selectedLabels = selectedValues
|
|
265
|
+
.map((value) => filter.options.find((opt) => opt.value === value)?.label)
|
|
266
|
+
.filter(Boolean)
|
|
267
|
+
|
|
268
|
+
if (selectedLabels.length === 1) {
|
|
269
|
+
return selectedLabels[0]
|
|
270
|
+
} else if (selectedLabels.length <= 3) {
|
|
271
|
+
return selectedLabels.join(', ')
|
|
272
|
+
} else {
|
|
273
|
+
return `${selectedLabels.length} opciones seleccionadas`
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function areAllSelected(filterIdx) {
|
|
278
|
+
const selectedValues = dynamicFilters.value[filterIdx]
|
|
279
|
+
const filter = selectedSecond.value?.filters?.[filterIdx]
|
|
280
|
+
if (!filter || !filter.options || !Array.isArray(selectedValues)) return false
|
|
281
|
+
|
|
282
|
+
return selectedValues.length === filter.options.length
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function isIndeterminate(filterIdx) {
|
|
286
|
+
const selectedValues = dynamicFilters.value[filterIdx]
|
|
287
|
+
const filter = selectedSecond.value?.filters?.[filterIdx]
|
|
288
|
+
if (!filter || !filter.options || !Array.isArray(selectedValues)) return false
|
|
289
|
+
|
|
290
|
+
return selectedValues.length > 0 && selectedValues.length < filter.options.length
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function toggleSelectAll(filterIdx) {
|
|
294
|
+
const filter = selectedSecond.value?.filters?.[filterIdx]
|
|
295
|
+
if (!filter || !filter.options) return
|
|
296
|
+
|
|
297
|
+
const allValues = filter.options.map((opt) => opt.value)
|
|
298
|
+
|
|
299
|
+
// Asegurar que dynamicFilters[filterIdx] sea un array
|
|
300
|
+
if (!Array.isArray(dynamicFilters.value[filterIdx])) {
|
|
301
|
+
dynamicFilters.value[filterIdx] = []
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (areAllSelected(filterIdx)) {
|
|
305
|
+
// Si todas están seleccionadas, deseleccionar todas
|
|
306
|
+
dynamicFilters.value[filterIdx] = []
|
|
307
|
+
} else {
|
|
308
|
+
// Si no todas están seleccionadas, seleccionar todas
|
|
309
|
+
dynamicFilters.value[filterIdx] = [...allValues]
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Mantener el menú abierto
|
|
313
|
+
dynamicSelectOpen.value = filterIdx
|
|
314
|
+
|
|
315
|
+
emitChange()
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const selectedTeam = ref('ambos')
|
|
319
|
+
const showFieldMenu = ref(false)
|
|
320
|
+
const showTypeMenu = ref(false)
|
|
321
|
+
const dynamicSelectOpen = ref(null)
|
|
322
|
+
|
|
323
|
+
function getFieldLabel() {
|
|
324
|
+
if (!selectedMain.value) return 'Tipo de vista'
|
|
325
|
+
return selectedMain.value.name
|
|
326
|
+
}
|
|
327
|
+
function getTypeLabel() {
|
|
328
|
+
if (!selectedSecond.value) return 'Selecciona una opción'
|
|
329
|
+
return selectedSecond.value.name || selectedSecond.value.title
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function toggleFieldMenu() {
|
|
333
|
+
showFieldMenu.value = !showFieldMenu.value
|
|
334
|
+
if (showFieldMenu.value) {
|
|
335
|
+
showTypeMenu.value = false
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
function toggleTypeMenu() {
|
|
339
|
+
if (!selectedMain.value) return // No abrir si no hay selección
|
|
340
|
+
showTypeMenu.value = !showTypeMenu.value
|
|
341
|
+
if (showTypeMenu.value) {
|
|
342
|
+
showFieldMenu.value = false
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function selectMain(index) {
|
|
346
|
+
selectedMainIndex.value = index
|
|
347
|
+
showFieldMenu.value = false
|
|
348
|
+
// Limpiar selección dependiente
|
|
349
|
+
selectedSecondId.value = null
|
|
350
|
+
emitChange()
|
|
351
|
+
}
|
|
352
|
+
function selectSecond(option) {
|
|
353
|
+
selectedSecondId.value = option.id
|
|
354
|
+
showTypeMenu.value = false
|
|
355
|
+
emitChange()
|
|
356
|
+
}
|
|
357
|
+
function toggleDynamicSelect(idx) {
|
|
358
|
+
dynamicSelectOpen.value = dynamicSelectOpen.value === idx ? null : idx
|
|
359
|
+
}
|
|
360
|
+
function handleClickOutside(event) {
|
|
361
|
+
if (!event.target.closest('.custom-select')) {
|
|
362
|
+
showFieldMenu.value = false
|
|
363
|
+
showTypeMenu.value = false
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
function emitChange() {
|
|
367
|
+
emit('filters-changed', {
|
|
368
|
+
main: selectedMain.value,
|
|
369
|
+
view: selectedSecond.value,
|
|
370
|
+
team: selectedTeam.value,
|
|
371
|
+
dynamicFilters: dynamicFilters.value,
|
|
372
|
+
})
|
|
373
|
+
}
|
|
374
|
+
function resetFilters() {
|
|
375
|
+
selectedMainIndex.value = null
|
|
376
|
+
selectedSecondId.value = null
|
|
377
|
+
selectedTeam.value = 'ambos'
|
|
378
|
+
dynamicFilters.value = []
|
|
379
|
+
showFieldMenu.value = false
|
|
380
|
+
showTypeMenu.value = false
|
|
381
|
+
dynamicSelectOpen.value = null
|
|
382
|
+
}
|
|
383
|
+
function emitClose() {
|
|
384
|
+
resetFilters()
|
|
385
|
+
emit('close')
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
onMounted(async () => {
|
|
389
|
+
document.addEventListener('click', handleClickOutside)
|
|
390
|
+
try {
|
|
391
|
+
const response = await fetch(
|
|
392
|
+
'https://m9qip57rsh.execute-api.us-east-2.amazonaws.com/prod/views',
|
|
393
|
+
{
|
|
394
|
+
headers: {
|
|
395
|
+
Authorization: `${props.token}`,
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
)
|
|
399
|
+
const data = await response.json()
|
|
400
|
+
apiData.value = data.data || []
|
|
401
|
+
} catch (error) {
|
|
402
|
+
console.error('Error al obtener datos:', error)
|
|
403
|
+
}
|
|
404
|
+
})
|
|
405
|
+
onUnmounted(() => {
|
|
406
|
+
document.removeEventListener('click', handleClickOutside)
|
|
407
|
+
})
|
|
408
|
+
</script>
|
|
409
|
+
|
|
410
|
+
<style scoped>
|
|
411
|
+
.floating-bar {
|
|
412
|
+
position: absolute;
|
|
413
|
+
top: 67px;
|
|
414
|
+
left: 50%;
|
|
415
|
+
background: #2a3843;
|
|
416
|
+
border-radius: 8px;
|
|
417
|
+
display: flex;
|
|
418
|
+
align-items: center;
|
|
419
|
+
padding: 8px 32px;
|
|
420
|
+
z-index: 100;
|
|
421
|
+
gap: 12px;
|
|
422
|
+
height: 62px;
|
|
423
|
+
width: auto;
|
|
424
|
+
min-width: 600px;
|
|
425
|
+
max-width: 100vw;
|
|
426
|
+
box-sizing: border-box;
|
|
427
|
+
transform: translateX(-50%);
|
|
428
|
+
}
|
|
429
|
+
.dynamic-select,
|
|
430
|
+
.radio-group,
|
|
431
|
+
.check-group {
|
|
432
|
+
display: inline-flex;
|
|
433
|
+
margin-bottom: 0 !important;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.tab {
|
|
437
|
+
background: none;
|
|
438
|
+
color: #fafafb;
|
|
439
|
+
border: none;
|
|
440
|
+
border-radius: 6px 6px 0 0;
|
|
441
|
+
padding: 8px 18px;
|
|
442
|
+
font-weight: bold;
|
|
443
|
+
font-size: 16px;
|
|
444
|
+
margin-right: 8px;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
.tab.active {
|
|
448
|
+
color: #fff;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.custom-select {
|
|
452
|
+
position: relative;
|
|
453
|
+
cursor: pointer;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.select-display {
|
|
457
|
+
background: #3f4c56;
|
|
458
|
+
color: #fafafb;
|
|
459
|
+
border: 1px solid #e9ecee;
|
|
460
|
+
border-radius: 6px;
|
|
461
|
+
padding: 0px 32px 0px 12px;
|
|
462
|
+
font-size: 15px;
|
|
463
|
+
display: flex;
|
|
464
|
+
align-items: center;
|
|
465
|
+
justify-content: space-between;
|
|
466
|
+
min-width: 140px;
|
|
467
|
+
height: 40px;
|
|
468
|
+
transition: border-color 0.2s;
|
|
469
|
+
}
|
|
470
|
+
.select-icon {
|
|
471
|
+
display: flex;
|
|
472
|
+
align-items: center;
|
|
473
|
+
margin-right: 8px;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.select-display:hover {
|
|
477
|
+
border-color: #cbee6b;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
.arrow {
|
|
481
|
+
display: flex;
|
|
482
|
+
align-items: center;
|
|
483
|
+
transition: transform 0.2s;
|
|
484
|
+
}
|
|
485
|
+
.arrow svg {
|
|
486
|
+
display: block;
|
|
487
|
+
}
|
|
488
|
+
.arrow.open {
|
|
489
|
+
transform: rotate(180deg);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.custom-select:hover .arrow {
|
|
493
|
+
transform: rotate(180deg);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.dropdown-menu {
|
|
497
|
+
position: absolute;
|
|
498
|
+
top: 100%;
|
|
499
|
+
left: 0;
|
|
500
|
+
background: #2a3843;
|
|
501
|
+
border: 1px solid #3d4a54;
|
|
502
|
+
border-radius: 8px;
|
|
503
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
|
504
|
+
padding: 8px;
|
|
505
|
+
margin-top: 4px;
|
|
506
|
+
min-width: 200px;
|
|
507
|
+
z-index: 1000;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
.option-card {
|
|
511
|
+
display: flex;
|
|
512
|
+
align-items: center;
|
|
513
|
+
padding: 12px;
|
|
514
|
+
border-radius: 6px;
|
|
515
|
+
cursor: pointer;
|
|
516
|
+
transition: background-color 0.2s;
|
|
517
|
+
margin-bottom: 4px;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
.option-card:last-child {
|
|
521
|
+
margin-bottom: 0;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
.option-card:hover {
|
|
525
|
+
background: #3d4a54;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.option-card.active {
|
|
529
|
+
background: #cbee6b;
|
|
530
|
+
color: #1a2a36;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.option-icon {
|
|
534
|
+
font-size: 20px;
|
|
535
|
+
margin-right: 12px;
|
|
536
|
+
width: 24px;
|
|
537
|
+
text-align: center;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
.option-content {
|
|
541
|
+
flex: 1;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
.option-title {
|
|
545
|
+
font-weight: 600;
|
|
546
|
+
font-size: 14px;
|
|
547
|
+
margin-bottom: 2px;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
.option-description {
|
|
551
|
+
font-size: 12px;
|
|
552
|
+
opacity: 0.8;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
.radio-group {
|
|
556
|
+
display: flex;
|
|
557
|
+
align-items: center;
|
|
558
|
+
gap: 10px;
|
|
559
|
+
margin-left: 16px;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
.radio-group label {
|
|
563
|
+
color: #fafafb;
|
|
564
|
+
font-size: 15px;
|
|
565
|
+
display: flex;
|
|
566
|
+
align-items: center;
|
|
567
|
+
gap: 4px;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
input[type='radio'] {
|
|
571
|
+
appearance: none;
|
|
572
|
+
-webkit-appearance: none;
|
|
573
|
+
background: #2a3843;
|
|
574
|
+
border: 2px solid #e9ecee;
|
|
575
|
+
width: 20px;
|
|
576
|
+
height: 20px;
|
|
577
|
+
border-radius: 50%;
|
|
578
|
+
margin-right: 6px;
|
|
579
|
+
margin-top: 0px;
|
|
580
|
+
position: relative;
|
|
581
|
+
cursor: pointer;
|
|
582
|
+
outline: none;
|
|
583
|
+
transition: border-color 0.2s;
|
|
584
|
+
}
|
|
585
|
+
input[type='radio']:checked::before {
|
|
586
|
+
content: '';
|
|
587
|
+
display: block;
|
|
588
|
+
width: 12px;
|
|
589
|
+
height: 12px;
|
|
590
|
+
background: #cbee6b;
|
|
591
|
+
border-radius: 50%;
|
|
592
|
+
position: absolute;
|
|
593
|
+
top: 2px;
|
|
594
|
+
left: 2px;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.check-group {
|
|
598
|
+
display: flex;
|
|
599
|
+
align-items: center;
|
|
600
|
+
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
601
|
+
font-size: 14px;
|
|
602
|
+
color: #fff;
|
|
603
|
+
background: none;
|
|
604
|
+
border: none;
|
|
605
|
+
border-radius: 0;
|
|
606
|
+
padding: 0 8px;
|
|
607
|
+
min-height: 40px;
|
|
608
|
+
margin-right: 8px;
|
|
609
|
+
}
|
|
610
|
+
.check-group input[type='checkbox'] {
|
|
611
|
+
accent-color: #cbee6b;
|
|
612
|
+
margin-right: 8px;
|
|
613
|
+
width: 18px;
|
|
614
|
+
height: 18px;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
.close-btn {
|
|
618
|
+
background: none;
|
|
619
|
+
border: none;
|
|
620
|
+
color: #fafafb;
|
|
621
|
+
font-size: 22px;
|
|
622
|
+
margin-left: auto;
|
|
623
|
+
cursor: pointer;
|
|
624
|
+
transition: color 0.2s;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
.close-btn:hover {
|
|
628
|
+
color: #cbee6b;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
.select-label {
|
|
632
|
+
flex-grow: 0;
|
|
633
|
+
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
634
|
+
font-size: 14px;
|
|
635
|
+
font-weight: 500;
|
|
636
|
+
font-stretch: normal;
|
|
637
|
+
font-style: normal;
|
|
638
|
+
margin-left: -10px;
|
|
639
|
+
line-height: normal;
|
|
640
|
+
letter-spacing: normal;
|
|
641
|
+
text-align: left;
|
|
642
|
+
color: #d9d9d9;
|
|
643
|
+
}
|
|
644
|
+
.option-title {
|
|
645
|
+
flex-grow: 0;
|
|
646
|
+
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
647
|
+
font-size: 14px;
|
|
648
|
+
font-weight: 500;
|
|
649
|
+
font-stretch: normal;
|
|
650
|
+
font-style: normal;
|
|
651
|
+
line-height: normal;
|
|
652
|
+
letter-spacing: normal;
|
|
653
|
+
text-align: left;
|
|
654
|
+
color: #fff;
|
|
655
|
+
}
|
|
656
|
+
.select-placeholder {
|
|
657
|
+
font-family: 'Poppins-Regular', 'Poppins', Arial, sans-serif !important;
|
|
658
|
+
font-size: 14px;
|
|
659
|
+
margin-left: -8px;
|
|
660
|
+
color: #d9d9d9;
|
|
661
|
+
}
|
|
662
|
+
.option-img {
|
|
663
|
+
width: 24px;
|
|
664
|
+
height: 24px;
|
|
665
|
+
object-fit: cover;
|
|
666
|
+
border-radius: 4px;
|
|
667
|
+
background: #222;
|
|
668
|
+
}
|
|
669
|
+
.custom-radio-group {
|
|
670
|
+
display: flex;
|
|
671
|
+
flex-direction: row;
|
|
672
|
+
align-items: center;
|
|
673
|
+
border-radius: 6px;
|
|
674
|
+
padding: 0px 16px;
|
|
675
|
+
min-height: 40px;
|
|
676
|
+
justify-content: center;
|
|
677
|
+
margin-right: 8px;
|
|
678
|
+
}
|
|
679
|
+
.radio-label {
|
|
680
|
+
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
681
|
+
font-size: 13px;
|
|
682
|
+
color: #d9d9d9;
|
|
683
|
+
margin-bottom: 0;
|
|
684
|
+
margin-right: 8px;
|
|
685
|
+
}
|
|
686
|
+
.radio-options {
|
|
687
|
+
display: flex;
|
|
688
|
+
flex-direction: row;
|
|
689
|
+
gap: 8px;
|
|
690
|
+
flex-wrap: nowrap;
|
|
691
|
+
}
|
|
692
|
+
.radio-option-card {
|
|
693
|
+
display: flex;
|
|
694
|
+
align-items: center;
|
|
695
|
+
background: transparent;
|
|
696
|
+
border: none;
|
|
697
|
+
border-radius: 4px;
|
|
698
|
+
padding: 6px 10px;
|
|
699
|
+
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
700
|
+
font-size: 14px;
|
|
701
|
+
color: #fff;
|
|
702
|
+
cursor: pointer;
|
|
703
|
+
transition:
|
|
704
|
+
background 0.2s,
|
|
705
|
+
color 0.2s;
|
|
706
|
+
white-space: nowrap;
|
|
707
|
+
min-width: 0;
|
|
708
|
+
max-width: 120px;
|
|
709
|
+
justify-content: center;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
.filter-separator {
|
|
713
|
+
width: 1px;
|
|
714
|
+
height: 32px;
|
|
715
|
+
border-left: 2px dashed #d9d9d9;
|
|
716
|
+
margin: 0 16px;
|
|
717
|
+
align-self: center;
|
|
718
|
+
}
|
|
719
|
+
.filter-inline {
|
|
720
|
+
display: inline-flex;
|
|
721
|
+
align-items: center;
|
|
722
|
+
vertical-align: middle;
|
|
723
|
+
margin-bottom: 0 !important;
|
|
724
|
+
min-width: 140px;
|
|
725
|
+
}
|
|
726
|
+
.select-label,
|
|
727
|
+
.option-title,
|
|
728
|
+
.radio-label,
|
|
729
|
+
.radio-option-card span,
|
|
730
|
+
.check-group label {
|
|
731
|
+
white-space: nowrap;
|
|
732
|
+
overflow: hidden;
|
|
733
|
+
text-overflow: ellipsis;
|
|
734
|
+
max-width: 180px;
|
|
735
|
+
display: inline-block;
|
|
736
|
+
vertical-align: middle;
|
|
737
|
+
}
|
|
738
|
+
.dynamic-filters {
|
|
739
|
+
display: flex;
|
|
740
|
+
align-items: center;
|
|
741
|
+
transition:
|
|
742
|
+
min-width 0.2s,
|
|
743
|
+
padding 0.2s;
|
|
744
|
+
}
|
|
745
|
+
.dynamic-filters-wide {
|
|
746
|
+
min-width: 400px;
|
|
747
|
+
padding-right: 24px;
|
|
748
|
+
padding-left: 24px;
|
|
749
|
+
}
|
|
750
|
+
.dynamic-filters-wide > .filter-inline:not(:last-child) {
|
|
751
|
+
margin-right: 16px;
|
|
752
|
+
}
|
|
753
|
+
.type-menu-grid {
|
|
754
|
+
min-width: 360px;
|
|
755
|
+
max-width: 420px;
|
|
756
|
+
}
|
|
757
|
+
.option-grid {
|
|
758
|
+
display: grid;
|
|
759
|
+
grid-template-columns: repeat(3, 1fr);
|
|
760
|
+
gap: 16px;
|
|
761
|
+
padding: 8px 0;
|
|
762
|
+
}
|
|
763
|
+
.option-card-grid {
|
|
764
|
+
display: flex;
|
|
765
|
+
flex-direction: column;
|
|
766
|
+
align-items: center;
|
|
767
|
+
justify-content: flex-start;
|
|
768
|
+
background: #3f4c56;
|
|
769
|
+
border: 2px solid transparent;
|
|
770
|
+
border-radius: 10px;
|
|
771
|
+
padding: 12px 8px 10px 8px;
|
|
772
|
+
cursor: pointer;
|
|
773
|
+
transition:
|
|
774
|
+
border-color 0.2s,
|
|
775
|
+
background 0.2s;
|
|
776
|
+
min-width: 90px;
|
|
777
|
+
min-height: 110px;
|
|
778
|
+
box-sizing: border-box;
|
|
779
|
+
}
|
|
780
|
+
.option-card-grid.active,
|
|
781
|
+
.option-card-grid:hover {
|
|
782
|
+
border-color: #cbee6b;
|
|
783
|
+
background: #22334a;
|
|
784
|
+
}
|
|
785
|
+
.option-grid-title {
|
|
786
|
+
font-size: 11px;
|
|
787
|
+
color: #d9d9d9;
|
|
788
|
+
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
789
|
+
margin-bottom: 8px;
|
|
790
|
+
text-align: center;
|
|
791
|
+
white-space: nowrap;
|
|
792
|
+
overflow: hidden;
|
|
793
|
+
text-overflow: ellipsis;
|
|
794
|
+
width: 100%;
|
|
795
|
+
}
|
|
796
|
+
.option-grid-icon {
|
|
797
|
+
display: flex;
|
|
798
|
+
align-items: center;
|
|
799
|
+
justify-content: center;
|
|
800
|
+
flex: 1;
|
|
801
|
+
}
|
|
802
|
+
.option-img-grid {
|
|
803
|
+
width: 40px;
|
|
804
|
+
height: 40px;
|
|
805
|
+
object-fit: cover;
|
|
806
|
+
border-radius: 6px;
|
|
807
|
+
background: #222;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
/* Estilos para selector múltiple */
|
|
811
|
+
.multi-select-menu {
|
|
812
|
+
min-width: 280px;
|
|
813
|
+
max-width: 400px;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
.multi-select-header {
|
|
817
|
+
display: flex;
|
|
818
|
+
justify-content: space-between;
|
|
819
|
+
align-items: center;
|
|
820
|
+
padding: 8px 12px;
|
|
821
|
+
border-bottom: 1px solid #3d4a54;
|
|
822
|
+
margin-bottom: 8px;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
.select-all-checkbox {
|
|
826
|
+
display: flex;
|
|
827
|
+
align-items: center;
|
|
828
|
+
cursor: pointer;
|
|
829
|
+
gap: 8px;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
.select-all-checkbox input[type='checkbox'] {
|
|
833
|
+
appearance: none;
|
|
834
|
+
-webkit-appearance: none;
|
|
835
|
+
width: 18px;
|
|
836
|
+
height: 18px;
|
|
837
|
+
border: 2px solid #e9ecee;
|
|
838
|
+
border-radius: 3px;
|
|
839
|
+
background: #2a3843;
|
|
840
|
+
cursor: pointer;
|
|
841
|
+
position: relative;
|
|
842
|
+
transition: all 0.2s;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
.select-all-checkbox input[type='checkbox']:checked {
|
|
846
|
+
background: #cbee6b;
|
|
847
|
+
border-color: #cbee6b;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
.select-all-checkbox input[type='checkbox']:checked::before {
|
|
851
|
+
content: '✓';
|
|
852
|
+
position: absolute;
|
|
853
|
+
top: 50%;
|
|
854
|
+
left: 50%;
|
|
855
|
+
transform: translate(-50%, -50%);
|
|
856
|
+
color: #1a2a36;
|
|
857
|
+
font-size: 12px;
|
|
858
|
+
font-weight: bold;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
.select-all-checkbox input[type='checkbox']:indeterminate::before {
|
|
862
|
+
content: '−';
|
|
863
|
+
position: absolute;
|
|
864
|
+
top: 50%;
|
|
865
|
+
left: 50%;
|
|
866
|
+
transform: translate(-50%, -50%);
|
|
867
|
+
color: #1a2a36;
|
|
868
|
+
font-size: 14px;
|
|
869
|
+
font-weight: bold;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
.select-all-checkbox input[type='checkbox']:hover {
|
|
873
|
+
border-color: #cbee6b;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
.select-all-label {
|
|
877
|
+
font-family: 'Poppins-Medium', 'Poppins', Arial, sans-serif;
|
|
878
|
+
font-size: 14px;
|
|
879
|
+
color: #d9d9d9;
|
|
880
|
+
font-weight: 500;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
.multi-select-option {
|
|
884
|
+
padding: 8px 12px;
|
|
885
|
+
margin-bottom: 2px;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
.multi-select-option:hover {
|
|
889
|
+
background: #3d4a54;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
.multi-select-option.active {
|
|
893
|
+
background: rgba(203, 238, 107, 0.1);
|
|
894
|
+
border: 1px solid #cbee6b;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
.option-checkbox {
|
|
898
|
+
display: flex;
|
|
899
|
+
align-items: center;
|
|
900
|
+
margin-right: 8px;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
.option-checkbox input[type='checkbox'] {
|
|
904
|
+
appearance: none;
|
|
905
|
+
-webkit-appearance: none;
|
|
906
|
+
width: 18px;
|
|
907
|
+
height: 18px;
|
|
908
|
+
border: 2px solid #e9ecee;
|
|
909
|
+
border-radius: 3px;
|
|
910
|
+
background: #2a3843;
|
|
911
|
+
cursor: pointer;
|
|
912
|
+
position: relative;
|
|
913
|
+
transition: all 0.2s;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
.option-checkbox input[type='checkbox']:checked {
|
|
917
|
+
background: #cbee6b;
|
|
918
|
+
border-color: #cbee6b;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
.option-checkbox input[type='checkbox']:checked::before {
|
|
922
|
+
content: '✓';
|
|
923
|
+
position: absolute;
|
|
924
|
+
top: 50%;
|
|
925
|
+
left: 50%;
|
|
926
|
+
transform: translate(-50%, -50%);
|
|
927
|
+
color: #1a2a36;
|
|
928
|
+
font-size: 12px;
|
|
929
|
+
font-weight: bold;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
.option-checkbox input[type='checkbox']:hover {
|
|
933
|
+
border-color: #cbee6b;
|
|
934
|
+
}
|
|
935
|
+
</style>
|