v-sistec-features 1.31.11 → 1.31.13
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/v-sistec-features.css +1 -1
- package/dist/vDataAgenda.d.ts +595 -18
- package/dist/vDataAgenda.js +3638 -2753
- package/package.json +1 -1
- package/src/DataAgenda/VDataAgenda.vue +167 -182
- package/src/DataAgenda/components/AgendaMatrix.vue +30 -19
- package/src/DataAgenda/components/AgendaMatrixBase.vue +392 -264
- package/src/DataAgenda/components/AgendaMatrixUnico.vue +21 -29
- package/src/DataAgenda/components/AgendaTabelaHorario.vue +506 -0
- package/src/DataAgenda/components/AgendaVueCal.vue +118 -199
- package/src/DataAgenda/components/BlocoArrastavel.vue +62 -0
- package/src/DataAgenda/components/HeaderTabela.vue +13 -4
- package/src/DataAgenda/components/ModalReserva.vue +268 -133
- package/src/DataAgenda/composables/useAgenda.ts +13 -0
- package/src/DataAgenda/composables/useCoresAgenda.ts +40 -0
- package/src/DataAgenda/composables/useGradeCompartilhada.ts +216 -0
- package/src/DataAgenda/composables/useSelecaoArrasto.ts +167 -0
- package/src/DataAgenda/components/AgendaMatrixAntigo.vue +0 -403
package/package.json
CHANGED
|
@@ -1,75 +1,151 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
========
|
|
3
3
|
O layout raiz que orquestra a interface com cabeçalhos modulares separados.
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
Suporta os modos 'calendario', 'tabela' (matriz horizontal) e 'tabela-horario' (grade vertical de horários por turno).
|
|
5
|
+
Repassa as configurações de usuário, layout, recurso único opcional, blocos por agenda e o cliente HTTP para os filhos,
|
|
6
|
+
além de destacar a semana operacional ativa, bloquear dias inativos no minicalendário lateral e expor a lista de
|
|
7
|
+
recursos atualmente em exibição no modelo ativo.
|
|
6
8
|
========
|
|
7
9
|
-->
|
|
8
10
|
<script setup lang="ts">
|
|
9
|
-
import { ref, onMounted, provide } from 'vue';
|
|
11
|
+
import { ref, computed, onMounted, provide } from 'vue';
|
|
10
12
|
import { VueCal } from 'vue-cal';
|
|
11
13
|
import 'vue-cal/style.css';
|
|
12
|
-
import { useAgenda } from './composables/useAgenda
|
|
14
|
+
import { useAgenda } from './composables/useAgenda';
|
|
15
|
+
import { calcularDataInicioSemana, formatarDataIso } from './composables/useGradeCompartilhada';
|
|
13
16
|
import AgendaVueCal from './components/AgendaVueCal.vue';
|
|
14
17
|
import AgendaMatrix from './components/AgendaMatrix.vue';
|
|
15
18
|
import AgendaMatrixUnico from './components/AgendaMatrixUnico.vue';
|
|
19
|
+
import AgendaTabelaHorario from './components/AgendaTabelaHorario.vue';
|
|
16
20
|
import HeaderCalendario from './components/HeaderCalendario.vue';
|
|
17
21
|
import HeaderTabela from './components/HeaderTabela.vue';
|
|
18
22
|
|
|
19
23
|
const props = withDefaults(defineProps<{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
modoLayout?: 'calendario' | 'tabela' | 'tabela-horario',
|
|
25
|
+
idRecursoUnico?: number | string | null,
|
|
26
|
+
usaInterceptador?: boolean,
|
|
27
|
+
usuarioLogado?: string,
|
|
28
|
+
tituloPadrao?: string,
|
|
29
|
+
ocultarTituloModal?: boolean,
|
|
30
|
+
configuracaoBlocos?: any,
|
|
31
|
+
fetch: any,
|
|
27
32
|
}>(), {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
modoLayout: 'calendario',
|
|
34
|
+
idRecursoUnico: null,
|
|
35
|
+
usaInterceptador: false,
|
|
36
|
+
usuarioLogado: '',
|
|
37
|
+
tituloPadrao: '',
|
|
38
|
+
ocultarTituloModal: false,
|
|
39
|
+
configuracaoBlocos: null
|
|
34
40
|
});
|
|
35
41
|
|
|
36
42
|
provide('api-instance-agenda', props.fetch);
|
|
43
|
+
defineEmits(['before-save']);
|
|
37
44
|
|
|
38
|
-
const
|
|
45
|
+
const {
|
|
46
|
+
dataSelecionada,
|
|
47
|
+
dataVisao,
|
|
48
|
+
agendasDisponiveis,
|
|
49
|
+
agendaSelecionada,
|
|
50
|
+
datasDesabilitadas,
|
|
51
|
+
carregarRecursosEAgendas
|
|
52
|
+
} = useAgenda(props.fetch);
|
|
39
53
|
|
|
40
|
-
// Armazena as referências e funções do composable de agenda para manipulação global.
|
|
41
|
-
const { dataSelecionada, dataVisao, carregarRecursosEAgendas } = useAgenda(props.fetch);
|
|
42
|
-
|
|
43
|
-
// Controla o estado de abertura da barra lateral (menu) contendo o minicalendário.
|
|
44
54
|
const menuAberto = ref(true);
|
|
45
|
-
|
|
46
|
-
// Armazena a referência da instância do componente vue-cal em sua versão miniatura.
|
|
47
55
|
const calendarioMiniRef = ref<any>(null);
|
|
56
|
+
const modeloAtivoRef = ref<any>(null);
|
|
57
|
+
|
|
58
|
+
const componenteModeloAtivo = computed(() => {
|
|
59
|
+
if (props.modoLayout === 'calendario') return AgendaVueCal;
|
|
60
|
+
if (props.modoLayout === 'tabela-horario') return AgendaTabelaHorario;
|
|
61
|
+
if (props.modoLayout === 'tabela' && props.idRecursoUnico) return AgendaMatrixUnico;
|
|
62
|
+
return AgendaMatrix;
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const propriedadesModeloAtivo = computed(() => {
|
|
66
|
+
const base = {
|
|
67
|
+
usaInterceptador: props.usaInterceptador,
|
|
68
|
+
tituloPadrao: props.tituloPadrao,
|
|
69
|
+
ocultarTituloModal: props.ocultarTituloModal
|
|
70
|
+
};
|
|
48
71
|
|
|
49
|
-
|
|
50
|
-
|
|
72
|
+
if (props.modoLayout === 'calendario') {
|
|
73
|
+
return { ...base, usuarioLogado: props.usuarioLogado };
|
|
74
|
+
}
|
|
75
|
+
if (props.modoLayout === 'tabela-horario') {
|
|
76
|
+
return { ...base, idRecursoUnico: props.idRecursoUnico, configuracaoBlocos: props.configuracaoBlocos };
|
|
77
|
+
}
|
|
78
|
+
if (props.modoLayout === 'tabela' && props.idRecursoUnico) {
|
|
79
|
+
return { ...base, idRecurso: props.idRecursoUnico, configuracaoBlocos: props.configuracaoBlocos };
|
|
80
|
+
}
|
|
81
|
+
return { ...base, configuracaoBlocos: props.configuracaoBlocos };
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const recursosEmExibicao = computed(() => modeloAtivoRef.value?.recursosEmExibicao ?? []);
|
|
85
|
+
|
|
86
|
+
defineExpose({ recursosEmExibicao });
|
|
51
87
|
|
|
52
|
-
// Executa o carregamento inicial de recursos ao montar o componente na tela.
|
|
53
88
|
onMounted(() => { carregarRecursosEAgendas(); });
|
|
54
89
|
|
|
55
|
-
|
|
56
|
-
|
|
90
|
+
const obterDataDaCelula = (cell: any): Date | null => {
|
|
91
|
+
if (!cell) return null;
|
|
92
|
+
if (cell instanceof Date) return cell;
|
|
93
|
+
if (cell.start) return new Date(cell.start);
|
|
94
|
+
return null;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const conjuntoDatasDesabilitadas = computed(() => new Set<string>(datasDesabilitadas.value));
|
|
98
|
+
|
|
99
|
+
const datasVisiveisNaSemana = computed(() => {
|
|
100
|
+
const visiveis = new Set<string>();
|
|
101
|
+
if (props.modoLayout !== 'tabela-horario' || !dataSelecionada.value || !agendaSelecionada.value) {
|
|
102
|
+
return visiveis;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const agendaObj = agendasDisponiveis.value.find(
|
|
106
|
+
(a: any) => Number(a.id_agenda) === Number(agendaSelecionada.value)
|
|
107
|
+
);
|
|
108
|
+
if (!agendaObj?.detalhes) return visiveis;
|
|
109
|
+
|
|
110
|
+
const inicioSemana = calcularDataInicioSemana(
|
|
111
|
+
dataSelecionada.value,
|
|
112
|
+
Number(agendaObj.detalhes.dia_inicio_semana_agenda ?? 0)
|
|
113
|
+
);
|
|
114
|
+
const diasVisiveis = Number(agendaObj.detalhes.dias_visiveis_agenda ?? 6);
|
|
115
|
+
|
|
116
|
+
for (let i = 0; i < diasVisiveis; i++) {
|
|
117
|
+
const diaCorrente = new Date(inicioSemana);
|
|
118
|
+
diaCorrente.setDate(inicioSemana.getDate() + i);
|
|
119
|
+
visiveis.add(formatarDataIso(diaCorrente));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return visiveis;
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const ehDiaBloqueadoNoMini = (cell: any): boolean => {
|
|
126
|
+
const data = obterDataDaCelula(cell);
|
|
127
|
+
if (!data || props.modoLayout !== 'tabela-horario') return false;
|
|
128
|
+
return conjuntoDatasDesabilitadas.value.has(formatarDataIso(data));
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const ehDiaVisivelNaGrade = (cell: any): boolean => {
|
|
132
|
+
const data = obterDataDaCelula(cell);
|
|
133
|
+
if (!data || props.modoLayout !== 'tabela-horario') return false;
|
|
134
|
+
return datasVisiveisNaSemana.value.has(formatarDataIso(data));
|
|
135
|
+
};
|
|
136
|
+
|
|
57
137
|
const alternarMenu = () => { menuAberto.value = !menuAberto.value; };
|
|
58
138
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (props.modoLayout === 'calendario') agendaVueCalRef.value?.irParaHoje();
|
|
66
|
-
if (calendarioMiniRef.value) calendarioMiniRef.value.view.goToToday();
|
|
139
|
+
const irParaHoje = () => {
|
|
140
|
+
const hoje = new Date();
|
|
141
|
+
dataSelecionada.value = hoje;
|
|
142
|
+
dataVisao.value = hoje;
|
|
143
|
+
if (props.modoLayout === 'calendario') modeloAtivoRef.value?.irParaHoje?.();
|
|
144
|
+
if (calendarioMiniRef.value) calendarioMiniRef.value.view.goToToday();
|
|
67
145
|
};
|
|
68
146
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const mudarVisao = (novaVisao: string) => {
|
|
72
|
-
agendaVueCalRef.value?.mudarVisao(novaVisao);
|
|
147
|
+
const mudarVisao = (novaVisao: string) => {
|
|
148
|
+
modeloAtivoRef.value?.mudarVisao?.(novaVisao);
|
|
73
149
|
};
|
|
74
150
|
</script>
|
|
75
151
|
|
|
@@ -99,6 +175,7 @@ const mudarVisao = (novaVisao: string) => {
|
|
|
99
175
|
<vue-cal
|
|
100
176
|
ref="calendarioMiniRef"
|
|
101
177
|
class="calendario-mini vuecal--blue-theme"
|
|
178
|
+
:class="{ 'modo-mini-tabela-horario': props.modoLayout === 'tabela-horario' }"
|
|
102
179
|
small
|
|
103
180
|
active-view="month"
|
|
104
181
|
:views="['month']"
|
|
@@ -106,180 +183,88 @@ const mudarVisao = (novaVisao: string) => {
|
|
|
106
183
|
hide-view-selector
|
|
107
184
|
:click-to-navigate="false"
|
|
108
185
|
locale="pt-br"
|
|
186
|
+
:disable-days="props.modoLayout === 'tabela-horario' ? datasDesabilitadas : []"
|
|
109
187
|
v-model:selected-date="dataSelecionada"
|
|
110
188
|
:view-date="dataVisao"
|
|
111
189
|
@update:selected-date="dataVisao = $event"
|
|
112
190
|
>
|
|
113
191
|
<template #views-bar></template>
|
|
114
192
|
<template #today-button></template>
|
|
193
|
+
|
|
194
|
+
<template #cell-content="{ cell }">
|
|
195
|
+
<div
|
|
196
|
+
class="vuecal__cell-date"
|
|
197
|
+
:class="{
|
|
198
|
+
'dia-semana-visivel': ehDiaVisivelNaGrade(cell),
|
|
199
|
+
'dia-coluna-inativa': ehDiaBloqueadoNoMini(cell)
|
|
200
|
+
}"
|
|
201
|
+
@mousedown.stop="
|
|
202
|
+
(ehDiaVisivelNaGrade(cell) || ehDiaBloqueadoNoMini(cell))
|
|
203
|
+
? $event.preventDefault()
|
|
204
|
+
: null
|
|
205
|
+
"
|
|
206
|
+
@click.stop="
|
|
207
|
+
(!ehDiaVisivelNaGrade(cell) && !ehDiaBloqueadoNoMini(cell))
|
|
208
|
+
? (dataSelecionada = obterDataDaCelula(cell) || dataSelecionada, dataVisao = obterDataDaCelula(cell) || dataVisao)
|
|
209
|
+
: null
|
|
210
|
+
"
|
|
211
|
+
>
|
|
212
|
+
{{ cell.content }}
|
|
213
|
+
</div>
|
|
214
|
+
</template>
|
|
115
215
|
</vue-cal>
|
|
116
216
|
</div>
|
|
117
217
|
</div>
|
|
118
218
|
</aside>
|
|
119
219
|
|
|
120
220
|
<main class="area-calendario">
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
ref="
|
|
124
|
-
|
|
125
|
-
:usuario-logado="props.usuarioLogado"
|
|
126
|
-
:titulo-padrao="props.tituloPadrao"
|
|
127
|
-
:ocultar-titulo-modal="props.ocultarTituloModal"
|
|
128
|
-
@before-save="$emit('before-save', $event)"
|
|
129
|
-
>
|
|
130
|
-
<template #campos-extras>
|
|
131
|
-
<slot name="campos-extras"></slot>
|
|
132
|
-
</template>
|
|
133
|
-
</AgendaVueCal>
|
|
134
|
-
|
|
135
|
-
<AgendaMatrixUnico
|
|
136
|
-
v-else-if="props.modoLayout === 'tabela' && props.idRecursoUnico"
|
|
137
|
-
:id-recurso="props.idRecursoUnico"
|
|
138
|
-
:usa-interceptador="props.usaInterceptador"
|
|
139
|
-
:titulo-padrao="props.tituloPadrao"
|
|
140
|
-
:ocultar-titulo-modal="props.ocultarTituloModal"
|
|
141
|
-
@before-save="$emit('before-save', $event)"
|
|
142
|
-
>
|
|
143
|
-
<template #campos-extras>
|
|
144
|
-
<slot name="campos-extras"></slot>
|
|
145
|
-
</template>
|
|
146
|
-
</AgendaMatrixUnico>
|
|
147
|
-
|
|
148
|
-
<AgendaMatrix
|
|
149
|
-
v-else-if="props.modoLayout === 'tabela'"
|
|
150
|
-
:usa-interceptador="props.usaInterceptador"
|
|
151
|
-
:titulo-padrao="props.tituloPadrao"
|
|
152
|
-
:ocultar-titulo-modal="props.ocultarTituloModal"
|
|
221
|
+
<component
|
|
222
|
+
:is="componenteModeloAtivo"
|
|
223
|
+
ref="modeloAtivoRef"
|
|
224
|
+
v-bind="propriedadesModeloAtivo"
|
|
153
225
|
@before-save="$emit('before-save', $event)"
|
|
154
226
|
>
|
|
155
|
-
<template #
|
|
156
|
-
<slot name="
|
|
227
|
+
<template v-for="(_, nomeSlot) in $slots" :key="nomeSlot" #[nomeSlot]="slotProps">
|
|
228
|
+
<slot :name="nomeSlot" v-bind="slotProps ?? {}"></slot>
|
|
157
229
|
</template>
|
|
158
|
-
</
|
|
230
|
+
</component>
|
|
159
231
|
</main>
|
|
160
232
|
</div>
|
|
161
233
|
</div>
|
|
162
234
|
</div>
|
|
163
235
|
</template>
|
|
236
|
+
|
|
164
237
|
<style lang="scss">
|
|
165
|
-
// importa o main.scss
|
|
166
238
|
@use '../assets/scss/main.scss';
|
|
167
239
|
</style>
|
|
168
240
|
|
|
169
241
|
<style scoped>
|
|
170
|
-
.painel-agenda-unificado {
|
|
171
|
-
|
|
172
|
-
border-radius: 16px;
|
|
173
|
-
box-shadow: var(--shadow-float);
|
|
174
|
-
border: 1px solid var(--border-light);
|
|
175
|
-
flex-grow: 1;
|
|
176
|
-
display: flex;
|
|
177
|
-
flex-direction: column;
|
|
178
|
-
overflow: hidden;
|
|
179
|
-
}
|
|
180
|
-
.painel-header-topo {
|
|
181
|
-
height: 60px;
|
|
182
|
-
background-color: var(--bg-primary);
|
|
183
|
-
border-bottom: 1px solid var(--border-light);
|
|
184
|
-
display: flex;
|
|
185
|
-
align-items: center;
|
|
186
|
-
justify-content: space-between;
|
|
187
|
-
padding: 0 20px;
|
|
188
|
-
flex-shrink: 0;
|
|
189
|
-
}
|
|
242
|
+
.painel-agenda-unificado { background: var(--bg-primary); border-radius: 16px; box-shadow: var(--shadow-float); border: 1px solid var(--border-light); flex-grow: 1; display: flex; flex-direction: column; overflow: hidden; }
|
|
243
|
+
.painel-header-topo { height: 60px; background-color: var(--bg-primary); border-bottom: 1px solid var(--border-light); display: flex; align-items: center; justify-content: space-between; padding: 0 20px; flex-shrink: 0; }
|
|
190
244
|
.corpo-principal { display: flex; flex-grow: 1; overflow: hidden; }
|
|
191
|
-
.barra-lateral {
|
|
192
|
-
width: 300px;
|
|
193
|
-
background-color: var(--bg-primary);
|
|
194
|
-
border-right: 1px solid var(--border-light);
|
|
195
|
-
transition: width 0.3s cubic-bezier(0.25, 1, 0.5, 1), opacity 0.2s;
|
|
196
|
-
overflow: hidden;
|
|
197
|
-
flex-shrink: 0;
|
|
198
|
-
}
|
|
245
|
+
.barra-lateral { width: 300px; background-color: var(--bg-primary); border-right: 1px solid var(--border-light); transition: width 0.3s cubic-bezier(0.25, 1, 0.5, 1), opacity 0.2s; overflow: hidden; flex-shrink: 0; }
|
|
199
246
|
.barra-lateral.oculta { width: 0; border-right: none; opacity: 0; }
|
|
200
247
|
.conteudo-lateral-fixo { width: 300px; padding: 15px; }
|
|
201
248
|
.secao-mini-cal { width: 100%; }
|
|
202
|
-
.area-calendario {
|
|
203
|
-
flex-grow: 1;
|
|
204
|
-
overflow: hidden;
|
|
205
|
-
background-color: var(--bg-primary);
|
|
206
|
-
display: flex;
|
|
207
|
-
flex-direction: column;
|
|
208
|
-
}
|
|
209
|
-
|
|
249
|
+
.area-calendario { flex-grow: 1; overflow: hidden; background-color: var(--bg-primary); display: flex; flex-direction: column; }
|
|
210
250
|
.calendario-mini { border: none !important; box-shadow: none !important; background-color: transparent !important; }
|
|
211
|
-
:deep(.calendario-mini .vuecal__header), :deep(.calendario-mini .vuecal__title-bar) { background-color:
|
|
212
|
-
:deep(.calendario-mini .vuecal__title), :deep(.calendario-mini .vuecal__arrow) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
color: var(--color-brand) !important;
|
|
216
|
-
background: transparent !important;
|
|
217
|
-
}
|
|
218
|
-
:deep(.calendario-mini .vuecal__heading) { border: none !important; background-color: transparent !important; font-weight: 600; color: var(--text-secondary); padding-bottom: 4px; }
|
|
251
|
+
:deep(.calendario-mini .vuecal__header), :deep(.calendario-mini .vuecal__title-bar) { background-color: var(--bg-primary) !important; border: none !important; padding-bottom: 5px; }
|
|
252
|
+
:deep(.calendario-mini .vuecal__title), :deep(.calendario-mini .vuecal__arrow) { font-size: 1rem; font-weight: 600; color: var(--color-brand) !important; background: transparent !important; }
|
|
253
|
+
:deep(.calendario-mini .vuecal__weekdays-headings) { background-color: var(--bg-primary) !important; border-bottom: 1px solid var(--border-light) !important; }
|
|
254
|
+
:deep(.calendario-mini .vuecal__heading), :deep(.calendario-mini .vuecal__weekday), :deep(.calendario-mini .vuecal__weekday-name), :deep(.calendario-mini .vuecal__heading *) { background-color: var(--bg-primary) !important; color: var(--text-secondary) !important; font-weight: 600 !important; border: none !important; padding-bottom: 4px; }
|
|
219
255
|
:deep(.calendario-mini .vuecal__cell) { border: none !important; background-color: transparent !important; height: 32px !important; min-height: 32px !important; aspect-ratio: auto !important; }
|
|
220
256
|
:deep(.calendario-mini .vuecal__cell::before) { display: none !important; content: none !important; }
|
|
221
|
-
:deep(.calendario-mini .vuecal__cell-content) { height: 32px !important; min-height: 32px !important; padding: 0 !important; margin: 0 !important; justify-content: center !important; align-items: center !important; }
|
|
222
|
-
:deep(.calendario-mini .vuecal__cell-date) { width:
|
|
223
|
-
:deep(.calendario-mini .vuecal__cell--selected) { background-color: transparent !important; }
|
|
224
|
-
:deep(.calendario-mini .vuecal__cell--selected .vuecal__cell-date) {
|
|
225
|
-
|
|
226
|
-
color: var(--text-inverse) !important;
|
|
227
|
-
border-color: var(--color-brand) !important;
|
|
228
|
-
}
|
|
257
|
+
:deep(.calendario-mini .vuecal__cell-content) { height: 32px !important; min-height: 32px !important; padding: 0 !important; margin: 0 !important; justify-content: center !important; align-items: center !important; width: 100% !important; }
|
|
258
|
+
:deep(.calendario-mini .vuecal__cell-date) { width: 26px !important; height: 26px !important; font-size: 12px !important; line-height: 26px !important; padding: 0 !important; display: flex !important; align-items: center !important; justify-content: center !important; margin: 0 auto !important; border-radius: 50% !important; border: 2px solid transparent !important; box-sizing: border-box !important; transition: all 0.2s ease; cursor: pointer; background-color: transparent !important; color: var(--text-primary); }
|
|
259
|
+
:deep(.calendario-mini .vuecal__cell--selected), :deep(.calendario-mini .vuecal__cell--today) { background-color: transparent !important; }
|
|
260
|
+
:deep(.calendario-mini:not(.modo-mini-tabela-horario) .vuecal__cell--selected .vuecal__cell-date) { background-color: var(--color-brand) !important; color: var(--text-inverse) !important; border-color: var(--color-brand) !important; }
|
|
261
|
+
:deep(.calendario-mini .vuecal__cell--today:not(.vuecal__cell--selected) .vuecal__cell-date:not(.dia-semana-visivel)) { background-color: var(--color-brand-light) !important; border-color: transparent !important; color: var(--color-brand) !important; }
|
|
229
262
|
:deep(.vuecal__body) { padding: 0; gap: 0; margin: 0; }
|
|
230
|
-
:deep(.calendario-mini .vuecal__cell--today) { background-color: transparent !important; }
|
|
231
|
-
:deep(.calendario-mini .vuecal__cell-date){ background-color: transparent !important; color: var(--text-primary); }
|
|
232
|
-
:deep(.calendario-mini .vuecal__cell--today:not(.vuecal__cell--selected) .vuecal__cell-date) {
|
|
233
|
-
background-color: var(--color-brand-light) !important;
|
|
234
|
-
border-color: transparent !important;
|
|
235
|
-
color: var(--color-brand) !important;
|
|
236
|
-
}
|
|
237
263
|
:deep(.calendario-mini .vuecal__views-bar) { display: none !important; }
|
|
238
264
|
:deep(.calendario-mini .vuecal__nav--next), :deep(.calendario-mini .vuecal__nav--prev) { color: var(--text-primary) !important; }
|
|
239
|
-
:deep(.calendario-mini .vuecal__body){ height: 0
|
|
240
|
-
:deep(.calendario-mini .vuecal__scrollable-wrap){ background-color: transparent!important; }
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
:deep(.calendario-mini .
|
|
244
|
-
:deep(.calendario-mini .vuecal__weekday) {
|
|
245
|
-
background-color: transparent !important;
|
|
246
|
-
border: none !important;
|
|
247
|
-
color: var(--text-secondary) !important;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
:deep(.calendario-mini .vuecal__weekdays-headings) {
|
|
251
|
-
background: transparent !important;
|
|
252
|
-
background-color: transparent !important;
|
|
253
|
-
border-bottom: 1px solid var(--border-light) !important;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/* Aplica o fundo transparente e a cor correta a cada dia individualmente e seus filhos */
|
|
257
|
-
:deep(.calendario-mini .vuecal__heading),
|
|
258
|
-
:deep(.calendario-mini .vuecal__weekday),
|
|
259
|
-
:deep(.calendario-mini .vuecal__heading *) {
|
|
260
|
-
background: transparent !important;
|
|
261
|
-
background-color: transparent !important;
|
|
262
|
-
color: var(--text-secondary) !important;
|
|
263
|
-
font-weight: 600 !important;
|
|
264
|
-
border: none !important;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
:deep(.calendario-mini .vuecal__header),
|
|
268
|
-
:deep(.calendario-mini .vuecal__weekdays-headings) {
|
|
269
|
-
background: var(--bg-primary) !important;
|
|
270
|
-
background-color: var(--bg-primary) !important;
|
|
271
|
-
border-bottom: 1px solid var(--border-light) !important;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/* Garante que os itens individuais e o texto adotem o fundo escuro e texto legível */
|
|
275
|
-
:deep(.calendario-mini .vuecal__heading),
|
|
276
|
-
:deep(.calendario-mini .vuecal__weekday),
|
|
277
|
-
:deep(.calendario-mini .vuecal__weekday-name),
|
|
278
|
-
:deep(.calendario-mini .vuecal__heading *) {
|
|
279
|
-
background: var(--bg-primary) !important;
|
|
280
|
-
background-color: var(--bg-primary) !important;
|
|
281
|
-
color: var(--text-secondary) !important;
|
|
282
|
-
font-weight: 600 !important;
|
|
283
|
-
border: none !important;
|
|
284
|
-
}
|
|
265
|
+
:deep(.calendario-mini .vuecal__body) { height: 0% !important; }
|
|
266
|
+
:deep(.calendario-mini .vuecal__scrollable-wrap) { background-color: transparent !important; }
|
|
267
|
+
:deep(.calendario-mini.modo-mini-tabela-horario .vuecal__cell--disabled) { pointer-events: none !important; cursor: not-allowed !important; }
|
|
268
|
+
:deep(.calendario-mini.modo-mini-tabela-horario .vuecal__cell-date.dia-coluna-inativa) { opacity: 0.22 !important; color: var(--text-secondary) !important; background-color: transparent !important; border-color: transparent !important; cursor: not-allowed !important; pointer-events: none !important; text-decoration: line-through; }
|
|
269
|
+
:deep(.calendario-mini.modo-mini-tabela-horario .vuecal__cell-date.dia-semana-visivel) { background-color: var(--color-brand) !important; color: var(--text-inverse) !important; border-color: var(--color-brand) !important; font-weight: 700 !important; width: 92% !important; border-radius: 6px !important; cursor: default !important; box-shadow: var(--shadow-sm); }
|
|
285
270
|
</style>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
========
|
|
3
3
|
Este arquivo representa a visualização em matriz para múltiplos recursos com suporte a filtragem.
|
|
4
|
-
Ele utiliza o AgendaMatrixBase para renderizar a grade
|
|
5
|
-
preservando os filtros ativos
|
|
4
|
+
Ele utiliza o AgendaMatrixBase para renderizar a grade, repassa a configuração de blocos da agenda,
|
|
5
|
+
gerencia o dropdown de seleção de salas preservando os filtros ativos ao mudar a data e expõe a lista
|
|
6
|
+
de recursos atualmente em exibição (já filtrada).
|
|
6
7
|
========
|
|
7
8
|
-->
|
|
8
9
|
<script setup lang="ts">
|
|
@@ -13,30 +14,23 @@ import AgendaMatrixBase from './AgendaMatrixBase.vue';
|
|
|
13
14
|
const props = defineProps({
|
|
14
15
|
usaInterceptador: { type: Boolean, default: false },
|
|
15
16
|
tituloPadrao: { type: String, default: '' },
|
|
16
|
-
ocultarTituloModal: { type: Boolean, default: false }
|
|
17
|
+
ocultarTituloModal: { type: Boolean, default: false },
|
|
18
|
+
configuracaoBlocos: { type: [Array, Object], default: null }
|
|
17
19
|
});
|
|
18
20
|
|
|
19
21
|
const api = inject('api-instance-agenda') as any;
|
|
20
|
-
|
|
22
|
+
defineEmits(['before-save']);
|
|
21
23
|
|
|
22
|
-
const { dadosMatrix, agendaSelecionada } = useAgenda(api);
|
|
24
|
+
const { dadosMatrix, agendaSelecionada, recursosDisponiveis } = useAgenda(api);
|
|
23
25
|
|
|
24
|
-
// Armazena os IDs (em string) dos recursos visíveis selecionados no filtro.
|
|
25
26
|
const recursosVisiveisIds = ref<string[]>([]);
|
|
26
|
-
|
|
27
|
-
// Armazena o ID da última agenda cujo filtro foi inicializado para evitar reset ao mudar apenas a data.
|
|
28
27
|
const idAgendaFiltroInicializado = ref<number | null>(null);
|
|
29
|
-
|
|
30
|
-
// Controla a abertura do menu dropdown de filtro de salas.
|
|
31
28
|
const menuFiltroAberto = ref(false);
|
|
32
29
|
|
|
33
|
-
// Extrai a lista de recursos presentes no primeiro dia retornado na matriz.
|
|
34
30
|
const recursosPermitidosNaMatriz = computed(() => {
|
|
35
|
-
|
|
36
|
-
return dadosMatrix.value.datas_matriz[0].recursos_slot;
|
|
31
|
+
return dadosMatrix.value?.datas_matriz?.[0]?.recursos_slot || [];
|
|
37
32
|
});
|
|
38
33
|
|
|
39
|
-
// Observa os recursos da matriz e inicializa o filtro apenas quando a agenda muda ou na primeira carga.
|
|
40
34
|
watch(recursosPermitidosNaMatriz, (novosRecursos) => {
|
|
41
35
|
if (novosRecursos.length === 0) {
|
|
42
36
|
recursosVisiveisIds.value = [];
|
|
@@ -53,15 +47,31 @@ watch(recursosPermitidosNaMatriz, (novosRecursos) => {
|
|
|
53
47
|
}
|
|
54
48
|
}, { immediate: true });
|
|
55
49
|
|
|
56
|
-
|
|
50
|
+
const recursosEmExibicao = computed(() => {
|
|
51
|
+
if (recursosVisiveisIds.value.length === 0) return [];
|
|
52
|
+
|
|
53
|
+
return recursosPermitidosNaMatriz.value
|
|
54
|
+
.filter((recMatriz: any) => recursosVisiveisIds.value.includes(String(recMatriz.id_recurso)))
|
|
55
|
+
.map((recMatriz: any) => {
|
|
56
|
+
return recursosDisponiveis.value.find(
|
|
57
|
+
(r: any) => Number(r.id_recurso) === Number(recMatriz.id_recurso)
|
|
58
|
+
) || {
|
|
59
|
+
id_recurso: recMatriz.id_recurso,
|
|
60
|
+
nome_recurso: recMatriz.nome_recurso,
|
|
61
|
+
id_agenda: agendaSelecionada.value
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
57
66
|
const selecionarTodos = () => {
|
|
58
67
|
recursosVisiveisIds.value = recursosPermitidosNaMatriz.value.map((r: any) => String(r.id_recurso));
|
|
59
68
|
};
|
|
60
69
|
|
|
61
|
-
// Desmarca todos os recursos no filtro de salas.
|
|
62
70
|
const limparFiltros = () => {
|
|
63
71
|
recursosVisiveisIds.value = [];
|
|
64
72
|
};
|
|
73
|
+
|
|
74
|
+
defineExpose({ recursosEmExibicao });
|
|
65
75
|
</script>
|
|
66
76
|
|
|
67
77
|
<template>
|
|
@@ -70,8 +80,9 @@ const limparFiltros = () => {
|
|
|
70
80
|
:usa-interceptador="props.usaInterceptador"
|
|
71
81
|
:titulo-padrao="props.tituloPadrao"
|
|
72
82
|
:ocultar-titulo-modal="props.ocultarTituloModal"
|
|
83
|
+
:configuracao-blocos="props.configuracaoBlocos"
|
|
73
84
|
mensagem-vazio="Nenhuma sala selecionada."
|
|
74
|
-
@before-save="$emit('before-save'
|
|
85
|
+
@before-save="$emit('before-save',$event)"
|
|
75
86
|
>
|
|
76
87
|
<template #topo>
|
|
77
88
|
<div class="barra-filtros" v-if="recursosPermitidosNaMatriz.length > 0">
|
|
@@ -123,8 +134,8 @@ const limparFiltros = () => {
|
|
|
123
134
|
</div>
|
|
124
135
|
</template>
|
|
125
136
|
|
|
126
|
-
<template #
|
|
127
|
-
<slot name="
|
|
137
|
+
<template v-for="(_, nomeSlot) in $slots" :key="nomeSlot" #[nomeSlot]="slotProps">
|
|
138
|
+
<slot :name="nomeSlot" v-bind="slotProps ?? {}"></slot>
|
|
128
139
|
</template>
|
|
129
140
|
</AgendaMatrixBase>
|
|
130
141
|
</template>
|