@softdin/portal-admin 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +95 -2
  2. package/dist-lib/chunks/AppLayout-COCPfLWo.js +303 -0
  3. package/dist-lib/chunks/AuditoriaView-Bcf_kOqI.js +643 -0
  4. package/dist-lib/chunks/CarnetView-BsdUtYeu.js +450 -0
  5. package/dist-lib/chunks/CarteleraView-CRnVjt-S.js +996 -0
  6. package/dist-lib/chunks/CertificadosView-DvHDflcN.js +549 -0
  7. package/dist-lib/chunks/ChatBandejaView-HqhdSw7G.js +274 -0
  8. package/dist-lib/chunks/ChatConfiguracionView-BdH5gDdR.js +716 -0
  9. package/dist-lib/chunks/ChatConocimientoView-nKTAKxFa.js +263 -0
  10. package/dist-lib/chunks/ChatConversacionView-Do74V09l.js +477 -0
  11. package/dist-lib/chunks/ChatInformeView-BIiAH9L_.js +280 -0
  12. package/dist-lib/chunks/ChatRespuestasView-QFXbyg8U.js +183 -0
  13. package/dist-lib/chunks/EmpleadosView-BtqrO5-8.js +311 -0
  14. package/dist-lib/chunks/HomologacionView-UCZk4u6R.js +949 -0
  15. package/dist-lib/chunks/IngresoSsoView-BKkcnrYO.js +98 -0
  16. package/dist-lib/chunks/SolicitudesView-CYPD2A1s.js +900 -0
  17. package/dist-lib/chunks/TiposSolicitudView-CrWTVizl.js +168 -0
  18. package/dist-lib/chunks/ToggleSwitch-BYrIyheq.js +55 -0
  19. package/dist-lib/chunks/_plugin-vue_export-helper-BOaGB7Aw.js +8 -0
  20. package/dist-lib/chunks/api-M7D1c3IT.js +97 -0
  21. package/dist-lib/chunks/apiError-BHGbwz97.js +15 -0
  22. package/dist-lib/chunks/auth.store-BrGKZg-7.js +220 -0
  23. package/dist-lib/chunks/chat.service-C7ZQf4w3.js +241 -0
  24. package/dist-lib/chunks/cliente-interno.store-De39VsEE.js +203 -0
  25. package/dist-lib/chunks/homologacion-CoeHD7cB.js +131 -0
  26. package/dist-lib/chunks/portal-empleado-6KQrnsQJ.js +120 -0
  27. package/dist-lib/chunks/tipos-D93bLfFC.js +22 -0
  28. package/dist-lib/portal-admin.js +196 -0
  29. package/dist-lib/style.css +4813 -0
  30. package/dist-lib/types/App.vue.d.ts +3 -0
  31. package/dist-lib/types/components/AppLayout.vue.d.ts +3 -0
  32. package/dist-lib/types/components/CarnetClientesInternos.vue.d.ts +11 -0
  33. package/dist-lib/types/components/InvitacionPortalModal.vue.d.ts +20 -0
  34. package/dist-lib/types/components/MenuUsuario.vue.d.ts +3 -0
  35. package/dist-lib/types/components/VistoBuenoPortalModal.vue.d.ts +23 -0
  36. package/dist-lib/types/components/auditoria/AuditoriaFila.vue.d.ts +16 -0
  37. package/dist-lib/types/components/auditoria/AuditoriaFiltros.vue.d.ts +30 -0
  38. package/dist-lib/types/components/auditoria/AuditoriaPaginador.vue.d.ts +14 -0
  39. package/dist-lib/types/components/cartelera/PaginaCarteleraImagen.vue.d.ts +14 -0
  40. package/dist-lib/types/components/cartelera/PublicacionFormModal.vue.d.ts +27 -0
  41. package/dist-lib/types/components/cartelera/VistaCelularCartelera.vue.d.ts +34 -0
  42. package/dist-lib/types/components/certificados/AtenderCertificadoModal.vue.d.ts +22 -0
  43. package/dist-lib/types/components/certificados/RechazarCertificadoModal.vue.d.ts +18 -0
  44. package/dist-lib/types/components/certificados/ResumenSolicitudCertificado.vue.d.ts +8 -0
  45. package/dist-lib/types/components/chat/ChatClientesInternos.vue.d.ts +21 -0
  46. package/dist-lib/types/components/chat/ChatHorarioCampos.vue.d.ts +21 -0
  47. package/dist-lib/types/components/forms/ExportExcelButton.vue.d.ts +30 -0
  48. package/dist-lib/types/components/forms/ToggleSwitch.vue.d.ts +17 -0
  49. package/dist-lib/types/components/homologacion/HomologacionFila.vue.d.ts +30 -0
  50. package/dist-lib/types/components/homologacion/TipoPermisoFormModal.vue.d.ts +26 -0
  51. package/dist-lib/types/components/homologacion/TipoSolicitudFormModal.vue.d.ts +27 -0
  52. package/dist-lib/types/lib/auditoria.d.ts +25 -0
  53. package/dist-lib/types/lib/cartelera-paginas.d.ts +26 -0
  54. package/dist-lib/types/lib/cartelera-vigencia.d.ts +3 -0
  55. package/dist-lib/types/lib/export-excel-csv.d.ts +4 -0
  56. package/dist-lib/types/lib/export-excel.d.ts +9 -0
  57. package/dist-lib/types/lib/exportar-listado.d.ts +68 -0
  58. package/dist-lib/types/lib/homologacion.d.ts +41 -0
  59. package/dist-lib/types/lib/portal-empleado.d.ts +32 -0
  60. package/dist-lib/types/modulo.d.ts +31 -0
  61. package/dist-lib/types/portal-admin/config.d.ts +17 -0
  62. package/dist-lib/types/portal-admin/rutas.d.ts +17 -0
  63. package/dist-lib/types/portal-admin/tipos.d.ts +68 -0
  64. package/dist-lib/types/router/index.d.ts +7 -0
  65. package/dist-lib/types/services/api.d.ts +29 -0
  66. package/dist-lib/types/services/auditoria.service.d.ts +63 -0
  67. package/dist-lib/types/services/auth.service.d.ts +61 -0
  68. package/dist-lib/types/services/carnet.service.d.ts +56 -0
  69. package/dist-lib/types/services/cartelera.service.d.ts +69 -0
  70. package/dist-lib/types/services/chat.service.d.ts +279 -0
  71. package/dist-lib/types/services/configuracion-cliente-interno.service.d.ts +23 -0
  72. package/dist-lib/types/services/homologacion.service.d.ts +105 -0
  73. package/dist-lib/types/services/portal-empleado.service.d.ts +112 -0
  74. package/dist-lib/types/services/solicitudes-certificado.service.d.ts +59 -0
  75. package/dist-lib/types/stores/auth.store.d.ts +125 -0
  76. package/dist-lib/types/stores/cliente-interno.store.d.ts +65 -0
  77. package/dist-lib/types/utils/apiError.d.ts +4 -0
  78. package/dist-lib/types/views/AuditoriaView.vue.d.ts +3 -0
  79. package/dist-lib/types/views/CarnetView.vue.d.ts +3 -0
  80. package/dist-lib/types/views/CarteleraView.vue.d.ts +3 -0
  81. package/dist-lib/types/views/CertificadosView.vue.d.ts +3 -0
  82. package/dist-lib/types/views/EmpleadosView.vue.d.ts +3 -0
  83. package/dist-lib/types/views/HomologacionView.vue.d.ts +4 -0
  84. package/dist-lib/types/views/IngresoSsoView.vue.d.ts +3 -0
  85. package/dist-lib/types/views/LoginView.vue.d.ts +3 -0
  86. package/dist-lib/types/views/OlvideView.vue.d.ts +3 -0
  87. package/dist-lib/types/views/RestablecerView.vue.d.ts +3 -0
  88. package/dist-lib/types/views/SolicitudesView.vue.d.ts +3 -0
  89. package/dist-lib/types/views/TiposSolicitudView.vue.d.ts +3 -0
  90. package/dist-lib/types/views/chat/ChatBandejaView.vue.d.ts +3 -0
  91. package/dist-lib/types/views/chat/ChatConfiguracionView.vue.d.ts +3 -0
  92. package/dist-lib/types/views/chat/ChatConocimientoView.vue.d.ts +3 -0
  93. package/dist-lib/types/views/chat/ChatConversacionView.vue.d.ts +11 -0
  94. package/dist-lib/types/views/chat/ChatInformeView.vue.d.ts +3 -0
  95. package/dist-lib/types/views/chat/ChatRespuestasView.vue.d.ts +3 -0
  96. package/package.json +66 -4
@@ -0,0 +1,716 @@
1
+ import { t as useClienteInternoStore } from "./cliente-interno.store-De39VsEE.js";
2
+ import { t as RUTAS_PORTAL } from "./tipos-D93bLfFC.js";
3
+ import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper-BOaGB7Aw.js";
4
+ import { c as textoHorario, i as chatService, t as DIAS_SEMANA } from "./chat.service-C7ZQf4w3.js";
5
+ import { t as mensajeError } from "./apiError-BHGbwz97.js";
6
+ import { t as ToggleSwitch_default } from "./ToggleSwitch-BYrIyheq.js";
7
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeModels, normalizeClass, onMounted, openBlock, ref, renderList, toDisplayString, unref, useModel, vModelCheckbox, vModelSelect, vModelText, withCtx, withDirectives, withModifiers } from "vue";
8
+ import { RouterLink } from "vue-router";
9
+ //#region src/components/chat/ChatHorarioCampos.vue?vue&type=script&setup=true&lang.ts
10
+ var _hoisted_1$2 = ["disabled"];
11
+ var _hoisted_2$2 = { class: "toolbar" };
12
+ var _hoisted_3$2 = ["aria-pressed", "onClick"];
13
+ var _hoisted_4$2 = { class: "toolbar" };
14
+ var _hoisted_5$2 = ["for"];
15
+ var _hoisted_6$2 = ["id"];
16
+ var _hoisted_7$2 = ["for"];
17
+ var _hoisted_8$2 = ["id"];
18
+ //#endregion
19
+ //#region src/components/chat/ChatHorarioCampos.vue
20
+ var ChatHorarioCampos_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
21
+ __name: "ChatHorarioCampos",
22
+ props: /*@__PURE__*/ mergeModels({
23
+ id: {},
24
+ disabled: { type: Boolean }
25
+ }, {
26
+ "modelValue": { required: true },
27
+ "modelModifiers": {}
28
+ }),
29
+ emits: ["update:modelValue"],
30
+ setup(__props) {
31
+ const horario = useModel(__props, "modelValue");
32
+ function alternarDia(n) {
33
+ const dias = horario.value.dias;
34
+ horario.value = {
35
+ ...horario.value,
36
+ dias: dias.includes(n) ? dias.filter((d) => d !== n) : [...dias, n].sort()
37
+ };
38
+ }
39
+ return (_ctx, _cache) => {
40
+ return openBlock(), createElementBlock("fieldset", {
41
+ class: "horario",
42
+ disabled: __props.disabled
43
+ }, [
44
+ _cache[2] || (_cache[2] = createElementVNode("legend", { class: "label" }, "Días de atención", -1)),
45
+ createElementVNode("div", _hoisted_2$2, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(DIAS_SEMANA), (d) => {
46
+ return openBlock(), createElementBlock("button", {
47
+ key: d.n,
48
+ type: "button",
49
+ class: normalizeClass(horario.value.dias.includes(d.n) ? "btn-primary" : "btn-secondary"),
50
+ "aria-pressed": horario.value.dias.includes(d.n),
51
+ onClick: ($event) => alternarDia(d.n)
52
+ }, toDisplayString(d.texto), 11, _hoisted_3$2);
53
+ }), 128))]),
54
+ createElementVNode("div", _hoisted_4$2, [
55
+ createElementVNode("label", {
56
+ class: "label",
57
+ for: `${__props.id}-desde`
58
+ }, "Desde", 8, _hoisted_5$2),
59
+ withDirectives(createElementVNode("input", {
60
+ id: `${__props.id}-desde`,
61
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => horario.value.desde = $event),
62
+ type: "time",
63
+ class: "input"
64
+ }, null, 8, _hoisted_6$2), [[vModelText, horario.value.desde]]),
65
+ createElementVNode("label", {
66
+ class: "label",
67
+ for: `${__props.id}-hasta`
68
+ }, "hasta", 8, _hoisted_7$2),
69
+ withDirectives(createElementVNode("input", {
70
+ id: `${__props.id}-hasta`,
71
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => horario.value.hasta = $event),
72
+ type: "time",
73
+ class: "input"
74
+ }, null, 8, _hoisted_8$2), [[vModelText, horario.value.hasta]])
75
+ ])
76
+ ], 8, _hoisted_1$2);
77
+ };
78
+ }
79
+ }), [["__scopeId", "data-v-772cd631"]]);
80
+ //#endregion
81
+ //#region src/components/chat/ChatClientesInternos.vue?vue&type=script&setup=true&lang.ts
82
+ var _hoisted_1$1 = {
83
+ key: 0,
84
+ class: "panel"
85
+ };
86
+ var _hoisted_2$1 = {
87
+ key: 0,
88
+ class: "panel-error",
89
+ role: "alert"
90
+ };
91
+ var _hoisted_3$1 = {
92
+ key: 1,
93
+ class: "panel-muted",
94
+ role: "status"
95
+ };
96
+ var _hoisted_4$1 = { class: "table-wrap" };
97
+ var _hoisted_5$1 = { class: "data-table" };
98
+ var _hoisted_6$1 = { key: 0 };
99
+ var _hoisted_7$1 = ["data-cliente"];
100
+ var _hoisted_8$1 = {
101
+ key: 0,
102
+ class: "sub"
103
+ };
104
+ var _hoisted_9$1 = { key: 0 };
105
+ var _hoisted_10$1 = { class: "toolbar acciones" };
106
+ var _hoisted_11$1 = ["disabled", "onClick"];
107
+ var _hoisted_12$1 = ["disabled", "onClick"];
108
+ var _hoisted_13$1 = { class: "panel-title" };
109
+ var _hoisted_14$1 = { class: "campo corto" };
110
+ var _hoisted_15$1 = { value: false };
111
+ var _hoisted_16$1 = {
112
+ key: 0,
113
+ class: "panel-muted"
114
+ };
115
+ var _hoisted_17$1 = { class: "label" };
116
+ var _hoisted_18$1 = {
117
+ key: 2,
118
+ class: "panel-muted"
119
+ };
120
+ var _hoisted_19$1 = { class: "label" };
121
+ var _hoisted_20$1 = {
122
+ key: 4,
123
+ class: "panel-muted"
124
+ };
125
+ var _hoisted_21$1 = { class: "toolbar" };
126
+ var _hoisted_22$1 = ["disabled"];
127
+ var _hoisted_23$1 = ["disabled"];
128
+ //#endregion
129
+ //#region src/components/chat/ChatClientesInternos.vue
130
+ var ChatClientesInternos_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
131
+ __name: "ChatClientesInternos",
132
+ props: {
133
+ general: {},
134
+ ajustes: {},
135
+ admin: { type: Boolean }
136
+ },
137
+ emits: ["actualizados"],
138
+ setup(__props, { emit: __emit }) {
139
+ const props = __props;
140
+ const emit = __emit;
141
+ const clientesInternos = useClienteInternoStore();
142
+ const clientes = computed(() => clientesInternos.seleccionado === null ? clientesInternos.lista : clientesInternos.lista.filter((c) => c.id === clientesInternos.seleccionado));
143
+ const editando = ref(null);
144
+ const ocupado = ref(false);
145
+ const error = ref(null);
146
+ const aviso = ref(null);
147
+ const porCliente = computed(() => new Map(props.ajustes.map((a) => [a.cliente_interno_id, a])));
148
+ /** Lo que de verdad aplica a un cliente y si es propio o heredado. */
149
+ function estado(c) {
150
+ const a = porCliente.value.get(c.id);
151
+ return {
152
+ ajustado: a !== void 0,
153
+ activo: props.general.activo && a?.activo !== false,
154
+ activoPropio: props.general.activo && a?.activo === false,
155
+ horario: a?.horario ?? props.general.horario,
156
+ horarioPropio: !!a?.horario,
157
+ mensaje: a?.mensaje_fuera_horario ?? props.general.mensaje_fuera_horario,
158
+ mensajePropio: a?.mensaje_fuera_horario != null
159
+ };
160
+ }
161
+ const copiaHorario = (h) => ({
162
+ ...h,
163
+ dias: [...h.dias]
164
+ });
165
+ function ajustar(c) {
166
+ const a = porCliente.value.get(c.id);
167
+ aviso.value = null;
168
+ editando.value = {
169
+ cliente: c,
170
+ apagado: a?.activo === false,
171
+ horarioPropio: !!a?.horario,
172
+ horario: copiaHorario(a?.horario ?? props.general.horario),
173
+ mensajePropio: a?.mensaje_fuera_horario != null,
174
+ mensaje: a?.mensaje_fuera_horario ?? props.general.mensaje_fuera_horario ?? ""
175
+ };
176
+ }
177
+ async function ejecutar(fn, ok) {
178
+ ocupado.value = true;
179
+ error.value = null;
180
+ aviso.value = null;
181
+ try {
182
+ const config = await fn();
183
+ emit("actualizados", config.clientes_internos ?? []);
184
+ editando.value = null;
185
+ aviso.value = ok;
186
+ } catch (e) {
187
+ error.value = mensajeError(e, "No se pudo guardar el ajuste del cliente.");
188
+ } finally {
189
+ ocupado.value = false;
190
+ }
191
+ }
192
+ function guardar() {
193
+ const e = editando.value;
194
+ if (!e) return;
195
+ const ajuste = {
196
+ activo: e.apagado ? false : null,
197
+ horario: e.horarioPropio ? e.horario : null,
198
+ mensaje_fuera_horario: e.mensajePropio && e.mensaje.trim() ? e.mensaje.trim() : null
199
+ };
200
+ if (ajuste.activo === null && ajuste.horario === null && ajuste.mensaje_fuera_horario === null) {
201
+ if (porCliente.value.has(e.cliente.id)) volverAlGeneral(e.cliente);
202
+ else editando.value = null;
203
+ return;
204
+ }
205
+ ejecutar(() => chatService.ajustarClienteInterno(e.cliente.id, ajuste), `${e.cliente.nombre}: ajuste guardado.`);
206
+ }
207
+ async function volverAlGeneral(c) {
208
+ await ejecutar(() => chatService.heredarClienteInterno(c.id), `${c.nombre}: vuelve a lo general.`);
209
+ }
210
+ return (_ctx, _cache) => {
211
+ return clientes.value.length ? (openBlock(), createElementBlock("div", _hoisted_1$1, [
212
+ _cache[14] || (_cache[14] = createElementVNode("div", null, [createElementVNode("p", { class: "panel-title" }, "Ajustes por cliente"), createElementVNode("p", { class: "panel-muted" }, " Cada cliente usa lo general, salvo lo que se le ajuste: eso prevalece para sus empleados. Se puede apagar el chat para un cliente, pero no encenderlo si el general está apagado. ")], -1)),
213
+ error.value ? (openBlock(), createElementBlock("p", _hoisted_2$1, toDisplayString(error.value), 1)) : createCommentVNode("", true),
214
+ aviso.value ? (openBlock(), createElementBlock("p", _hoisted_3$1, toDisplayString(aviso.value), 1)) : createCommentVNode("", true),
215
+ createElementVNode("div", _hoisted_4$1, [createElementVNode("table", _hoisted_5$1, [createElementVNode("thead", null, [createElementVNode("tr", null, [
216
+ _cache[6] || (_cache[6] = createElementVNode("th", null, "Cliente", -1)),
217
+ _cache[7] || (_cache[7] = createElementVNode("th", null, "Chat", -1)),
218
+ _cache[8] || (_cache[8] = createElementVNode("th", null, "Horario", -1)),
219
+ _cache[9] || (_cache[9] = createElementVNode("th", null, "Mensaje fuera de horario", -1)),
220
+ __props.admin ? (openBlock(), createElementBlock("th", _hoisted_6$1)) : createCommentVNode("", true)
221
+ ])]), createElementVNode("tbody", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(clientes.value, (c) => {
222
+ return openBlock(), createElementBlock("tr", {
223
+ key: c.id,
224
+ "data-cliente": c.id
225
+ }, [
226
+ createElementVNode("td", null, [
227
+ createTextVNode(toDisplayString(c.nombre) + " ", 1),
228
+ c.nit ? (openBlock(), createElementBlock("span", _hoisted_8$1, "NIT " + toDisplayString(c.nit), 1)) : createCommentVNode("", true),
229
+ createElementVNode("span", { class: normalizeClass(["estado", estado(c).ajustado ? "estado-info" : "estado-neutro"]) }, toDisplayString(estado(c).ajustado ? "Ajustado" : "Como el general"), 3)
230
+ ]),
231
+ createElementVNode("td", null, [createElementVNode("span", { class: normalizeClass(["estado", estado(c).activo ? "estado-ok" : "estado-neutro"]) }, toDisplayString(estado(c).activo ? "Encendido" : "Apagado"), 3), createElementVNode("span", { class: normalizeClass(["sub", { propio: estado(c).activoPropio }]) }, toDisplayString(estado(c).activoPropio ? "Propio" : "Del general"), 3)]),
232
+ createElementVNode("td", null, [createTextVNode(toDisplayString(unref(textoHorario)(estado(c).horario)) + " ", 1), createElementVNode("span", { class: normalizeClass(["sub", { propio: estado(c).horarioPropio }]) }, toDisplayString(estado(c).horarioPropio ? "Propio" : "Del general"), 3)]),
233
+ createElementVNode("td", null, [createTextVNode(toDisplayString(estado(c).mensaje ?? "—") + " ", 1), createElementVNode("span", { class: normalizeClass(["sub", { propio: estado(c).mensajePropio }]) }, toDisplayString(estado(c).mensajePropio ? "Propio" : "Del general"), 3)]),
234
+ __props.admin ? (openBlock(), createElementBlock("td", _hoisted_9$1, [createElementVNode("div", _hoisted_10$1, [createElementVNode("button", {
235
+ type: "button",
236
+ class: "btn-secondary",
237
+ disabled: ocupado.value,
238
+ onClick: ($event) => ajustar(c)
239
+ }, "Ajustar", 8, _hoisted_11$1), estado(c).ajustado ? (openBlock(), createElementBlock("button", {
240
+ key: 0,
241
+ type: "button",
242
+ class: "btn-secondary",
243
+ disabled: ocupado.value,
244
+ onClick: ($event) => volverAlGeneral(c)
245
+ }, " Volver al general ", 8, _hoisted_12$1)) : createCommentVNode("", true)])])) : createCommentVNode("", true)
246
+ ], 8, _hoisted_7$1);
247
+ }), 128))])])]),
248
+ __props.admin && editando.value ? (openBlock(), createElementBlock("form", {
249
+ key: 2,
250
+ class: "edicion",
251
+ onSubmit: withModifiers(guardar, ["prevent"])
252
+ }, [
253
+ createElementVNode("p", _hoisted_13$1, "Ajuste para " + toDisplayString(editando.value.cliente.nombre), 1),
254
+ createElementVNode("label", _hoisted_14$1, [_cache[11] || (_cache[11] = createElementVNode("span", { class: "label" }, "Chat", -1)), withDirectives(createElementVNode("select", {
255
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => editando.value.apagado = $event),
256
+ class: "input",
257
+ "aria-label": "Chat para este cliente"
258
+ }, [createElementVNode("option", _hoisted_15$1, "Como el general (" + toDisplayString(__props.general.activo ? "encendido" : "apagado") + ")", 1), _cache[10] || (_cache[10] = createElementVNode("option", { value: true }, "Apagado para este cliente", -1))], 512), [[vModelSelect, editando.value.apagado]])]),
259
+ !__props.general.activo ? (openBlock(), createElementBlock("p", _hoisted_16$1, "El chat general está apagado: este cliente tampoco lo tiene mientras siga así.")) : createCommentVNode("", true),
260
+ createElementVNode("label", _hoisted_17$1, [withDirectives(createElementVNode("input", {
261
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => editando.value.horarioPropio = $event),
262
+ type: "checkbox"
263
+ }, null, 512), [[vModelCheckbox, editando.value.horarioPropio]]), _cache[12] || (_cache[12] = createTextVNode(" Horario propio", -1))]),
264
+ editando.value.horarioPropio ? (openBlock(), createBlock(ChatHorarioCampos_default, {
265
+ key: 1,
266
+ modelValue: editando.value.horario,
267
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => editando.value.horario = $event),
268
+ id: `chat-ci-${editando.value.cliente.id}`
269
+ }, null, 8, ["modelValue", "id"])) : (openBlock(), createElementBlock("p", _hoisted_18$1, "Usa el general: " + toDisplayString(unref(textoHorario)(__props.general.horario)) + ".", 1)),
270
+ createElementVNode("label", _hoisted_19$1, [withDirectives(createElementVNode("input", {
271
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => editando.value.mensajePropio = $event),
272
+ type: "checkbox"
273
+ }, null, 512), [[vModelCheckbox, editando.value.mensajePropio]]), _cache[13] || (_cache[13] = createTextVNode(" Mensaje fuera de horario propio", -1))]),
274
+ editando.value.mensajePropio ? withDirectives((openBlock(), createElementBlock("input", {
275
+ key: 3,
276
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => editando.value.mensaje = $event),
277
+ class: "input",
278
+ maxlength: "500",
279
+ "aria-label": "Mensaje fuera de horario del cliente",
280
+ placeholder: "Te responderemos el siguiente día hábil."
281
+ }, null, 512)), [[vModelText, editando.value.mensaje]]) : (openBlock(), createElementBlock("p", _hoisted_20$1, "Usa el general: " + toDisplayString(__props.general.mensaje_fuera_horario ?? "sin mensaje") + ".", 1)),
282
+ createElementVNode("div", _hoisted_21$1, [createElementVNode("button", {
283
+ type: "submit",
284
+ class: "btn-primary",
285
+ disabled: ocupado.value || editando.value.horarioPropio && editando.value.horario.dias.length === 0
286
+ }, " Guardar ", 8, _hoisted_22$1), createElementVNode("button", {
287
+ type: "button",
288
+ class: "btn-secondary",
289
+ disabled: ocupado.value,
290
+ onClick: _cache[5] || (_cache[5] = ($event) => editando.value = null)
291
+ }, "Cancelar", 8, _hoisted_23$1)])
292
+ ], 32)) : createCommentVNode("", true)
293
+ ])) : createCommentVNode("", true);
294
+ };
295
+ }
296
+ }), [["__scopeId", "data-v-fdeaf51a"]]);
297
+ //#endregion
298
+ //#region src/views/chat/ChatConfiguracionView.vue?vue&type=script&setup=true&lang.ts
299
+ var _hoisted_1 = { class: "page-shell" };
300
+ var _hoisted_2 = {
301
+ key: 0,
302
+ class: "panel-error",
303
+ role: "alert"
304
+ };
305
+ var _hoisted_3 = {
306
+ key: 1,
307
+ class: "panel-muted",
308
+ role: "status"
309
+ };
310
+ var _hoisted_4 = {
311
+ key: 2,
312
+ class: "panel-muted"
313
+ };
314
+ var _hoisted_5 = {
315
+ key: 0,
316
+ class: "panel-muted"
317
+ };
318
+ var _hoisted_6 = { class: "fila" };
319
+ var _hoisted_7 = { class: "campo" };
320
+ var _hoisted_8 = ["disabled"];
321
+ var _hoisted_9 = { class: "campo corto" };
322
+ var _hoisted_10 = ["disabled"];
323
+ var _hoisted_11 = { class: "fila ia" };
324
+ var _hoisted_12 = { class: "panel-muted" };
325
+ var _hoisted_13 = {
326
+ key: 0,
327
+ class: "panel-error"
328
+ };
329
+ var _hoisted_14 = {
330
+ key: 1,
331
+ class: "panel-muted"
332
+ };
333
+ var _hoisted_15 = { class: "campo corto" };
334
+ var _hoisted_16 = ["disabled"];
335
+ var _hoisted_17 = { key: 0 };
336
+ var _hoisted_18 = ["disabled"];
337
+ var _hoisted_19 = { class: "panel" };
338
+ var _hoisted_20 = {
339
+ key: 0,
340
+ class: "panel-muted"
341
+ };
342
+ var _hoisted_21 = {
343
+ key: 1,
344
+ class: "table-wrap"
345
+ };
346
+ var _hoisted_22 = { class: "data-table" };
347
+ var _hoisted_23 = { key: 0 };
348
+ var _hoisted_24 = ["onUpdate:modelValue", "disabled"];
349
+ var _hoisted_25 = ["onUpdate:modelValue", "disabled"];
350
+ var _hoisted_26 = ["onUpdate:modelValue", "disabled"];
351
+ var _hoisted_27 = [
352
+ "value",
353
+ "disabled",
354
+ "onChange"
355
+ ];
356
+ var _hoisted_28 = [
357
+ "value",
358
+ "disabled",
359
+ "onChange"
360
+ ];
361
+ var _hoisted_29 = ["onUpdate:modelValue", "disabled"];
362
+ var _hoisted_30 = { key: 0 };
363
+ var _hoisted_31 = ["disabled", "onClick"];
364
+ var _hoisted_32 = ["disabled"];
365
+ var _hoisted_33 = { class: "panel" };
366
+ var _hoisted_34 = { class: "table-wrap" };
367
+ var _hoisted_35 = { class: "data-table" };
368
+ var _hoisted_36 = { key: 0 };
369
+ var _hoisted_37 = { class: "sub" };
370
+ var _hoisted_38 = [
371
+ "onUpdate:modelValue",
372
+ "disabled",
373
+ "aria-label"
374
+ ];
375
+ var _hoisted_39 = [
376
+ "onUpdate:modelValue",
377
+ "disabled",
378
+ "aria-label"
379
+ ];
380
+ var _hoisted_40 = { class: "temas-persona" };
381
+ var _hoisted_41 = [
382
+ "checked",
383
+ "disabled",
384
+ "onChange"
385
+ ];
386
+ var _hoisted_42 = { key: 0 };
387
+ var _hoisted_43 = ["disabled", "onClick"];
388
+ //#endregion
389
+ //#region src/views/chat/ChatConfiguracionView.vue
390
+ var ChatConfiguracionView_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
391
+ __name: "ChatConfiguracionView",
392
+ setup(__props) {
393
+ const resumen = ref(null);
394
+ const config = ref(null);
395
+ /** Lo general tal como está guardado: es lo que heredan los clientes internos sin ajuste. */
396
+ const guardada = ref(null);
397
+ const temas = ref([]);
398
+ const personas = ref([]);
399
+ const cargando = ref(true);
400
+ const ocupado = ref(false);
401
+ const error = ref(null);
402
+ const aviso = ref(null);
403
+ const nuevoTema = ref("");
404
+ const admin = computed(() => resumen.value?.es_admin === true);
405
+ async function cargar() {
406
+ cargando.value = true;
407
+ error.value = null;
408
+ try {
409
+ [resumen.value, config.value, temas.value, personas.value] = await Promise.all([
410
+ chatService.resumen(),
411
+ chatService.configuracion(),
412
+ chatService.temas(),
413
+ chatService.personas()
414
+ ]);
415
+ recordarGuardada();
416
+ } catch (e) {
417
+ error.value = mensajeError(e, "No se pudo cargar la configuración del chat.");
418
+ } finally {
419
+ cargando.value = false;
420
+ }
421
+ }
422
+ async function guardar(fn, ok, falla) {
423
+ ocupado.value = true;
424
+ error.value = null;
425
+ aviso.value = null;
426
+ try {
427
+ await fn();
428
+ aviso.value = ok;
429
+ } catch (e) {
430
+ error.value = mensajeError(e, falla);
431
+ } finally {
432
+ ocupado.value = false;
433
+ }
434
+ }
435
+ function recordarGuardada() {
436
+ guardada.value = config.value ? JSON.parse(JSON.stringify(config.value)) : null;
437
+ }
438
+ /** Los ajustes por cliente se guardan aparte: solo se reemplazan ellos, sin pisar lo general sin guardar. */
439
+ function ajustesActualizados(ajustes) {
440
+ if (config.value) config.value.clientes_internos = ajustes;
441
+ }
442
+ const guardarConfig = () => guardar(async () => {
443
+ config.value = await chatService.guardarConfiguracion(config.value);
444
+ recordarGuardada();
445
+ temas.value = await chatService.temas();
446
+ }, "Configuración guardada.", "No se pudo guardar la configuración.");
447
+ const guardarTema = (t) => guardar(async () => {
448
+ const r = await chatService.actualizarTema(t.id, {
449
+ nombre: t.nombre,
450
+ descripcion: t.descripcion,
451
+ confidencial: t.confidencial,
452
+ asignacion_automatica: t.asignacion_automatica,
453
+ minutos_primera_respuesta: t.minutos_primera_respuesta,
454
+ minutos_resolucion: t.minutos_resolucion,
455
+ activo: t.activo
456
+ });
457
+ Object.assign(t, r);
458
+ }, `Tema «${t.nombre}» guardado.`, "No se pudo guardar el tema.");
459
+ const crearTema = () => guardar(async () => {
460
+ temas.value.push(await chatService.crearTema({
461
+ nombre: nuevoTema.value.trim(),
462
+ orden: temas.value.length
463
+ }));
464
+ nuevoTema.value = "";
465
+ }, "Tema creado.", "No se pudo crear el tema.");
466
+ function alternarTemaDePersona(p, temaId) {
467
+ p.temas = p.temas.includes(temaId) ? p.temas.filter((t) => t !== temaId) : [...p.temas, temaId];
468
+ }
469
+ const guardarPersona = (p) => guardar(async () => {
470
+ personas.value = await chatService.actualizarPersona(p.id, {
471
+ atiende_chat: p.atiende_chat,
472
+ disponible: p.disponible,
473
+ temas: p.atiende_chat ? p.temas : []
474
+ });
475
+ temas.value = await chatService.temas();
476
+ }, `${p.nombre}: guardado.`, "No se pudo guardar la persona.");
477
+ /** Minutos hábiles ↔ horas, para editar en horas. */
478
+ const horas = (min) => Math.round(min / 60 * 10) / 10;
479
+ const aMinutos = (h) => Math.max(15, Math.round(Number(h) * 60));
480
+ onMounted(() => void cargar());
481
+ return (_ctx, _cache) => {
482
+ return openBlock(), createElementBlock("section", _hoisted_1, [
483
+ createVNode(unref(RouterLink), {
484
+ to: { name: unref(RUTAS_PORTAL).chat },
485
+ class: "volver"
486
+ }, {
487
+ default: withCtx(() => [..._cache[7] || (_cache[7] = [createTextVNode("← Bandeja", -1)])]),
488
+ _: 1
489
+ }, 8, ["to"]),
490
+ _cache[31] || (_cache[31] = createElementVNode("header", null, [createElementVNode("h1", { class: "page-title" }, "Configuración del chat"), createElementVNode("p", { class: "page-subtitle" }, " Los empleados escriben desde su Portal de autogestión y les responde una persona de RRHH. Los plazos se cuentan en horas hábiles: dentro del horario de atención y sin festivos. ")], -1)),
491
+ error.value ? (openBlock(), createElementBlock("p", _hoisted_2, toDisplayString(error.value), 1)) : createCommentVNode("", true),
492
+ aviso.value ? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString(aviso.value), 1)) : createCommentVNode("", true),
493
+ cargando.value ? (openBlock(), createElementBlock("p", _hoisted_4, "Cargando…")) : config.value ? (openBlock(), createElementBlock(Fragment, { key: 3 }, [
494
+ !admin.value ? (openBlock(), createElementBlock("p", _hoisted_5, "Solo un administrador del cliente puede cambiar esta configuración.")) : createCommentVNode("", true),
495
+ createElementVNode("form", {
496
+ class: "panel",
497
+ onSubmit: withModifiers(guardarConfig, ["prevent"])
498
+ }, [
499
+ createElementVNode("div", _hoisted_6, [_cache[8] || (_cache[8] = createElementVNode("div", null, [createElementVNode("p", { class: "panel-title" }, "Chat activo para los empleados"), createElementVNode("p", { class: "panel-muted" }, "Apagado, los empleados no pueden escribir; lo ya abierto se sigue atendiendo aquí.")], -1)), createVNode(ToggleSwitch_default, {
500
+ modelValue: config.value.activo,
501
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => config.value.activo = $event),
502
+ disabled: !admin.value || ocupado.value,
503
+ "aria-label": "Chat activo"
504
+ }, null, 8, ["modelValue", "disabled"])]),
505
+ createVNode(ChatHorarioCampos_default, {
506
+ modelValue: config.value.horario,
507
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => config.value.horario = $event),
508
+ id: "chat",
509
+ disabled: !admin.value
510
+ }, null, 8, ["modelValue", "disabled"]),
511
+ createElementVNode("label", _hoisted_7, [_cache[9] || (_cache[9] = createElementVNode("span", { class: "label" }, "Mensaje fuera de horario (opcional)", -1)), withDirectives(createElementVNode("input", {
512
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => config.value.mensaje_fuera_horario = $event),
513
+ class: "input",
514
+ maxlength: "500",
515
+ disabled: !admin.value,
516
+ placeholder: "Te responderemos el siguiente día hábil."
517
+ }, null, 8, _hoisted_8), [[vModelText, config.value.mensaje_fuera_horario]])]),
518
+ createElementVNode("label", _hoisted_9, [_cache[10] || (_cache[10] = createElementVNode("span", { class: "label" }, "Conservar las conversaciones (días desde el cierre)", -1)), withDirectives(createElementVNode("input", {
519
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => config.value.dias_conservacion = $event),
520
+ type: "number",
521
+ min: "30",
522
+ max: "3650",
523
+ class: "input",
524
+ disabled: !admin.value
525
+ }, null, 8, _hoisted_10), [[
526
+ vModelText,
527
+ config.value.dias_conservacion,
528
+ void 0,
529
+ { number: true }
530
+ ]])]),
531
+ createElementVNode("div", _hoisted_11, [createElementVNode("div", null, [
532
+ _cache[14] || (_cache[14] = createElementVNode("p", { class: "panel-title" }, "Asistente de IA", -1)),
533
+ createElementVNode("p", _hoisted_12, [
534
+ _cache[12] || (_cache[12] = createTextVNode(" Responde primero a los empleados que acepten su aviso de privacidad, con sus datos publicados y la ", -1)),
535
+ createVNode(unref(RouterLink), {
536
+ to: { name: unref(RUTAS_PORTAL).chatConocimiento },
537
+ class: "enlace"
538
+ }, {
539
+ default: withCtx(() => [..._cache[11] || (_cache[11] = [createTextVNode("base de conocimiento", -1)])]),
540
+ _: 1
541
+ }, 8, ["to"]),
542
+ _cache[13] || (_cache[13] = createTextVNode(". Los temas sensibles nunca le llegan: pasan directo a una persona. ", -1))
543
+ ]),
544
+ config.value.ia_en_servidor === false ? (openBlock(), createElementBlock("p", _hoisted_13, " El servidor del portal aún no tiene el asistente habilitado: encenderlo aquí no tiene efecto hasta que se configure. ")) : createCommentVNode("", true),
545
+ config.value.uso_ia_hoy ? (openBlock(), createElementBlock("p", _hoisted_14, " Hoy: " + toDisplayString(config.value.uso_ia_hoy.mensajes) + " respuestas del asistente (" + toDisplayString(config.value.uso_ia_hoy.llamadas) + " consultas al proveedor). ", 1)) : createCommentVNode("", true)
546
+ ]), createVNode(ToggleSwitch_default, {
547
+ modelValue: config.value.ia_activa,
548
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => config.value.ia_activa = $event),
549
+ disabled: !admin.value || ocupado.value,
550
+ "aria-label": "Asistente de IA activo"
551
+ }, null, 8, ["modelValue", "disabled"])]),
552
+ createElementVNode("label", _hoisted_15, [_cache[15] || (_cache[15] = createElementVNode("span", { class: "label" }, "Máximo de respuestas del asistente por día (después responde una persona)", -1)), withDirectives(createElementVNode("input", {
553
+ "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => config.value.tope_mensajes_ia_dia = $event),
554
+ type: "number",
555
+ min: "0",
556
+ max: "100000",
557
+ class: "input",
558
+ disabled: !admin.value
559
+ }, null, 8, _hoisted_16), [[
560
+ vModelText,
561
+ config.value.tope_mensajes_ia_dia,
562
+ void 0,
563
+ { number: true }
564
+ ]])]),
565
+ admin.value ? (openBlock(), createElementBlock("div", _hoisted_17, [createElementVNode("button", {
566
+ type: "submit",
567
+ class: "btn-primary",
568
+ disabled: ocupado.value || config.value.horario.dias.length === 0
569
+ }, "Guardar", 8, _hoisted_18)])) : createCommentVNode("", true)
570
+ ], 32),
571
+ guardada.value ? (openBlock(), createBlock(ChatClientesInternos_default, {
572
+ key: 1,
573
+ general: guardada.value,
574
+ ajustes: config.value.clientes_internos ?? [],
575
+ admin: admin.value,
576
+ onActualizados: ajustesActualizados
577
+ }, null, 8, [
578
+ "general",
579
+ "ajustes",
580
+ "admin"
581
+ ])) : createCommentVNode("", true),
582
+ createElementVNode("div", _hoisted_19, [
583
+ _cache[23] || (_cache[23] = createElementVNode("p", { class: "panel-title" }, "Temas", -1)),
584
+ _cache[24] || (_cache[24] = createElementVNode("p", { class: "panel-muted" }, " El empleado elige uno al escribir. Un tema confidencial solo lo leen sus personas asignadas (nunca el soporte de SoftDIN) y no se le ofrece al empleado mientras no tenga a nadie. ", -1)),
585
+ temas.value.length === 0 ? (openBlock(), createElementBlock("p", _hoisted_20, "Se crean al activar el chat.")) : (openBlock(), createElementBlock("div", _hoisted_21, [createElementVNode("table", _hoisted_22, [createElementVNode("thead", null, [createElementVNode("tr", null, [
586
+ _cache[16] || (_cache[16] = createElementVNode("th", null, "Nombre", -1)),
587
+ _cache[17] || (_cache[17] = createElementVNode("th", null, "Confidencial", -1)),
588
+ _cache[18] || (_cache[18] = createElementVNode("th", { title: "Lo que queda sin asignar va solo a la persona disponible con menos carga" }, "Asignación automática", -1)),
589
+ _cache[19] || (_cache[19] = createElementVNode("th", null, "Primera respuesta (h)", -1)),
590
+ _cache[20] || (_cache[20] = createElementVNode("th", null, "Resolución (h)", -1)),
591
+ _cache[21] || (_cache[21] = createElementVNode("th", null, "Personas", -1)),
592
+ _cache[22] || (_cache[22] = createElementVNode("th", null, "Activo", -1)),
593
+ admin.value ? (openBlock(), createElementBlock("th", _hoisted_23)) : createCommentVNode("", true)
594
+ ])]), createElementVNode("tbody", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(temas.value, (t) => {
595
+ return openBlock(), createElementBlock("tr", { key: t.id }, [
596
+ createElementVNode("td", null, [withDirectives(createElementVNode("input", {
597
+ "onUpdate:modelValue": ($event) => t.nombre = $event,
598
+ class: "input",
599
+ maxlength: "100",
600
+ disabled: !admin.value,
601
+ "aria-label": "Nombre del tema"
602
+ }, null, 8, _hoisted_24), [[vModelText, t.nombre]])]),
603
+ createElementVNode("td", null, [withDirectives(createElementVNode("input", {
604
+ "onUpdate:modelValue": ($event) => t.confidencial = $event,
605
+ type: "checkbox",
606
+ disabled: !admin.value,
607
+ "aria-label": "Confidencial"
608
+ }, null, 8, _hoisted_25), [[vModelCheckbox, t.confidencial]])]),
609
+ createElementVNode("td", null, [withDirectives(createElementVNode("input", {
610
+ "onUpdate:modelValue": ($event) => t.asignacion_automatica = $event,
611
+ type: "checkbox",
612
+ disabled: !admin.value,
613
+ "aria-label": "Asignación automática"
614
+ }, null, 8, _hoisted_26), [[vModelCheckbox, t.asignacion_automatica]])]),
615
+ createElementVNode("td", null, [createElementVNode("input", {
616
+ value: horas(t.minutos_primera_respuesta),
617
+ type: "number",
618
+ min: "0.25",
619
+ step: "0.25",
620
+ class: "input numero",
621
+ disabled: !admin.value,
622
+ "aria-label": "Horas para la primera respuesta",
623
+ onChange: ($event) => t.minutos_primera_respuesta = aMinutos($event.target.value)
624
+ }, null, 40, _hoisted_27)]),
625
+ createElementVNode("td", null, [createElementVNode("input", {
626
+ value: horas(t.minutos_resolucion),
627
+ type: "number",
628
+ min: "0.25",
629
+ step: "0.25",
630
+ class: "input numero",
631
+ disabled: !admin.value,
632
+ "aria-label": "Horas para resolver",
633
+ onChange: ($event) => t.minutos_resolucion = aMinutos($event.target.value)
634
+ }, null, 40, _hoisted_28)]),
635
+ createElementVNode("td", null, toDisplayString(t.personas.length ? personas.value.filter((p) => t.personas.includes(p.id)).map((p) => p.nombre).join(", ") : t.confidencial ? "Nadie (no se ofrece)" : "Cualquiera que atienda"), 1),
636
+ createElementVNode("td", null, [withDirectives(createElementVNode("input", {
637
+ "onUpdate:modelValue": ($event) => t.activo = $event,
638
+ type: "checkbox",
639
+ disabled: !admin.value,
640
+ "aria-label": "Activo"
641
+ }, null, 8, _hoisted_29), [[vModelCheckbox, t.activo]])]),
642
+ admin.value ? (openBlock(), createElementBlock("td", _hoisted_30, [createElementVNode("button", {
643
+ type: "button",
644
+ class: "btn-secondary",
645
+ disabled: ocupado.value,
646
+ onClick: ($event) => guardarTema(t)
647
+ }, "Guardar", 8, _hoisted_31)])) : createCommentVNode("", true)
648
+ ]);
649
+ }), 128))])])])),
650
+ admin.value ? (openBlock(), createElementBlock("form", {
651
+ key: 2,
652
+ class: "toolbar",
653
+ onSubmit: withModifiers(crearTema, ["prevent"])
654
+ }, [withDirectives(createElementVNode("input", {
655
+ "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => nuevoTema.value = $event),
656
+ class: "input",
657
+ maxlength: "100",
658
+ placeholder: "Nuevo tema",
659
+ "aria-label": "Nombre del nuevo tema"
660
+ }, null, 512), [[vModelText, nuevoTema.value]]), createElementVNode("button", {
661
+ type: "submit",
662
+ class: "btn-secondary",
663
+ disabled: ocupado.value || !nuevoTema.value.trim()
664
+ }, "Agregar tema", 8, _hoisted_32)], 32)) : createCommentVNode("", true)
665
+ ]),
666
+ createElementVNode("div", _hoisted_33, [
667
+ _cache[29] || (_cache[29] = createElementVNode("p", { class: "panel-title" }, "Personas que atienden", -1)),
668
+ _cache[30] || (_cache[30] = createElementVNode("p", { class: "panel-muted" }, " Usuarios de RRHH de este cliente. Quien atiende el chat ve las conversaciones de sus temas y las de los temas sin personas asignadas. Si deja de atender, lo que tenía vuelve a «sin asignar». ", -1)),
669
+ createElementVNode("div", _hoisted_34, [createElementVNode("table", _hoisted_35, [createElementVNode("thead", null, [createElementVNode("tr", null, [
670
+ _cache[25] || (_cache[25] = createElementVNode("th", null, "Usuario", -1)),
671
+ _cache[26] || (_cache[26] = createElementVNode("th", null, "Atiende el chat", -1)),
672
+ _cache[27] || (_cache[27] = createElementVNode("th", { title: "Recibe conversaciones de la asignación automática" }, "Disponible", -1)),
673
+ _cache[28] || (_cache[28] = createElementVNode("th", null, "Temas", -1)),
674
+ admin.value ? (openBlock(), createElementBlock("th", _hoisted_36)) : createCommentVNode("", true)
675
+ ])]), createElementVNode("tbody", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(personas.value, (p) => {
676
+ return openBlock(), createElementBlock("tr", { key: p.id }, [
677
+ createElementVNode("td", null, [createTextVNode(toDisplayString(p.nombre) + " ", 1), createElementVNode("span", _hoisted_37, [createTextVNode(toDisplayString(p.email) + " · " + toDisplayString(p.rol === "admin" ? "Administrador" : "RRHH"), 1), p.es_superadmin ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(" · soporte SoftDIN")], 64)) : createCommentVNode("", true)])]),
678
+ createElementVNode("td", null, [withDirectives(createElementVNode("input", {
679
+ "onUpdate:modelValue": ($event) => p.atiende_chat = $event,
680
+ type: "checkbox",
681
+ disabled: !admin.value,
682
+ "aria-label": `${p.nombre} atiende el chat`
683
+ }, null, 8, _hoisted_38), [[vModelCheckbox, p.atiende_chat]])]),
684
+ createElementVNode("td", null, [withDirectives(createElementVNode("input", {
685
+ "onUpdate:modelValue": ($event) => p.disponible = $event,
686
+ type: "checkbox",
687
+ disabled: !admin.value || !p.atiende_chat,
688
+ "aria-label": `${p.nombre} disponible`
689
+ }, null, 8, _hoisted_39), [[vModelCheckbox, p.disponible]])]),
690
+ createElementVNode("td", null, [createElementVNode("div", _hoisted_40, [(openBlock(true), createElementBlock(Fragment, null, renderList(temas.value, (t) => {
691
+ return openBlock(), createElementBlock("label", {
692
+ key: t.id,
693
+ class: "opcion"
694
+ }, [createElementVNode("input", {
695
+ type: "checkbox",
696
+ checked: p.temas.includes(t.id),
697
+ disabled: !admin.value || !p.atiende_chat || t.confidencial && p.es_superadmin,
698
+ onChange: ($event) => alternarTemaDePersona(p, t.id)
699
+ }, null, 40, _hoisted_41), createTextVNode(" " + toDisplayString(t.nombre), 1)]);
700
+ }), 128))])]),
701
+ admin.value ? (openBlock(), createElementBlock("td", _hoisted_42, [createElementVNode("button", {
702
+ type: "button",
703
+ class: "btn-secondary",
704
+ disabled: ocupado.value,
705
+ onClick: ($event) => guardarPersona(p)
706
+ }, "Guardar", 8, _hoisted_43)])) : createCommentVNode("", true)
707
+ ]);
708
+ }), 128))])])])
709
+ ])
710
+ ], 64)) : createCommentVNode("", true)
711
+ ]);
712
+ };
713
+ }
714
+ }), [["__scopeId", "data-v-6a4fed44"]]);
715
+ //#endregion
716
+ export { ChatConfiguracionView_default as default };