@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,949 @@
1
+ import { t as api } from "./api-M7D1c3IT.js";
2
+ import { t as useAuthStore } from "./auth.store-BrGKZg-7.js";
3
+ import { i as portalTiposService, t as useClienteInternoStore } from "./cliente-interno.store-De39VsEE.js";
4
+ import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper-BOaGB7Aw.js";
5
+ import { t as mensajeError } from "./apiError-BHGbwz97.js";
6
+ import { a as avisoVariable, c as nombreVariable, d as tipoDeClave, i as UNIDADES_PERMISO, n as LINEAS_PARENTESCO, o as esPermisoDeLey, r as PERIODOS_TOPE, s as esTipoNuevo, t as GRUPOS_HOMOLOGACION, u as textoConcepto } from "./homologacion-CoeHD7cB.js";
7
+ import { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeModels, onMounted, openBlock, reactive, ref, renderList, toDisplayString, unref, useModel, vModelCheckbox, vModelSelect, vModelText, watch, withDirectives, withModifiers } from "vue";
8
+ import FormCloseButton from "@softdin/shared/components/forms/FormCloseButton.vue";
9
+ //#region src/components/homologacion/HomologacionFila.vue?vue&type=script&setup=true&lang.ts
10
+ var _hoisted_1$3 = ["data-clave"];
11
+ var _hoisted_2$3 = { "data-label": "Del portal" };
12
+ var _hoisted_3$3 = { class: "font-medium text-slate-900" };
13
+ var _hoisted_4$3 = {
14
+ key: 0,
15
+ class: "hm-sub"
16
+ };
17
+ var _hoisted_5$3 = { "data-label": "Variable esperada" };
18
+ var _hoisted_6$3 = { "data-label": "Concepto de novedad" };
19
+ var _hoisted_7$3 = ["for"];
20
+ var _hoisted_8$3 = ["id", "disabled"];
21
+ var _hoisted_9$3 = ["value"];
22
+ var _hoisted_10$3 = ["value"];
23
+ var _hoisted_11$3 = {
24
+ key: 0,
25
+ class: "hm-marca",
26
+ "data-prueba": "heredado"
27
+ };
28
+ var _hoisted_12$3 = {
29
+ key: 1,
30
+ class: "hm-sub",
31
+ "data-prueba": "sin-homologar"
32
+ };
33
+ var _hoisted_13$3 = {
34
+ key: 2,
35
+ class: "hm-aviso",
36
+ role: "status",
37
+ "data-prueba": "advertencia"
38
+ };
39
+ var _hoisted_14$3 = { "data-label": "Acciones" };
40
+ var _hoisted_15$2 = { class: "hm-acciones" };
41
+ var _hoisted_16$1 = ["disabled", "aria-label"];
42
+ var _hoisted_17$1 = ["disabled"];
43
+ var _hoisted_18$1 = ["disabled", "aria-label"];
44
+ //#endregion
45
+ //#region src/components/homologacion/HomologacionFila.vue
46
+ var HomologacionFila_default = /* @__PURE__ */ defineComponent({
47
+ __name: "HomologacionFila",
48
+ props: {
49
+ fila: {},
50
+ conceptos: {},
51
+ clienteInterno: {},
52
+ puedeEditar: { type: Boolean },
53
+ ocupado: { type: Boolean },
54
+ guardando: { type: Boolean },
55
+ editableTipo: { type: Boolean }
56
+ },
57
+ emits: [
58
+ "guardar",
59
+ "heredar",
60
+ "editar"
61
+ ],
62
+ setup(__props, { emit: __emit }) {
63
+ const props = __props;
64
+ const emit = __emit;
65
+ /** Lo elegido en el combo, antes de guardar. */
66
+ const elegido = ref(props.fila.idconceptonovedad);
67
+ watch(() => props.fila, (f) => {
68
+ elegido.value = f.idconceptonovedad;
69
+ });
70
+ const idCampo = computed(() => `hm-${props.fila.clave.replace(/[^a-zA-Z0-9_-]/g, "-")}`);
71
+ const cambiado = computed(() => elegido.value !== props.fila.idconceptonovedad);
72
+ const conceptoElegido = computed(() => props.conceptos.find((c) => c.id === elegido.value) ?? null);
73
+ /** El concepto guardado ya no está entre los de seguridad social del cliente: se conserva como opción. */
74
+ const fueraDeLista = computed(() => props.fila.idconceptonovedad !== null && !props.conceptos.some((c) => c.id === props.fila.idconceptonovedad));
75
+ const deshabilitado = computed(() => !props.puedeEditar || !props.fila.editable || props.ocupado);
76
+ /** Antes de guardar, el aviso es el de lo elegido; ya guardado, el que dejó SoftDIN. */
77
+ const aviso = computed(() => cambiado.value ? avisoVariable(props.fila, conceptoElegido.value, props.conceptos) : props.fila.advertencia);
78
+ const conCliente = computed(() => props.clienteInterno !== null);
79
+ const sinHomologar = computed(() => props.fila.idconceptonovedad === null && !cambiado.value);
80
+ return (_ctx, _cache) => {
81
+ return openBlock(), createElementBlock("tr", { "data-clave": __props.fila.clave }, [
82
+ createElementVNode("td", _hoisted_2$3, [createElementVNode("span", _hoisted_3$3, toDisplayString(__props.fila.nombre), 1), __props.fila.detalle ? (openBlock(), createElementBlock("span", _hoisted_4$3, toDisplayString(__props.fila.detalle), 1)) : createCommentVNode("", true)]),
83
+ createElementVNode("td", _hoisted_5$3, toDisplayString(unref(nombreVariable)(__props.fila.variable_esperada, __props.conceptos)), 1),
84
+ createElementVNode("td", _hoisted_6$3, [
85
+ createElementVNode("label", {
86
+ for: idCampo.value,
87
+ class: "sr-only"
88
+ }, "Concepto de novedad para " + toDisplayString(__props.fila.nombre), 9, _hoisted_7$3),
89
+ withDirectives(createElementVNode("select", {
90
+ id: idCampo.value,
91
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => elegido.value = $event),
92
+ class: "hm-select",
93
+ disabled: deshabilitado.value
94
+ }, [
95
+ _cache[4] || (_cache[4] = createElementVNode("option", { value: null }, "— Sin homologar —", -1)),
96
+ fueraDeLista.value ? (openBlock(), createElementBlock("option", {
97
+ key: 0,
98
+ value: __props.fila.idconceptonovedad
99
+ }, "Concepto " + toDisplayString(__props.fila.idconceptonovedad) + " (ya no está disponible)", 9, _hoisted_9$3)) : createCommentVNode("", true),
100
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.conceptos, (c) => {
101
+ return openBlock(), createElementBlock("option", {
102
+ key: c.id,
103
+ value: c.id
104
+ }, toDisplayString(unref(textoConcepto)(c, __props.conceptos)), 9, _hoisted_10$3);
105
+ }), 128))
106
+ ], 8, _hoisted_8$3), [[vModelSelect, elegido.value]]),
107
+ conCliente.value && __props.fila.heredado && !cambiado.value ? (openBlock(), createElementBlock("span", _hoisted_11$3, "Heredado de todo el tenant")) : createCommentVNode("", true),
108
+ sinHomologar.value ? (openBlock(), createElementBlock("span", _hoisted_12$3, [__props.fila.grupo === "tipo" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode("Sin homologar: el empleado no podrá radicarlo.")], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode("Sin homologar: SoftDIN usa el concepto de la variable, como hasta ahora.")], 64))])) : createCommentVNode("", true),
109
+ aviso.value ? (openBlock(), createElementBlock("p", _hoisted_13$3, toDisplayString(aviso.value), 1)) : createCommentVNode("", true)
110
+ ]),
111
+ createElementVNode("td", _hoisted_14$3, [createElementVNode("div", _hoisted_15$2, [
112
+ __props.puedeEditar && __props.fila.editable ? (openBlock(), createElementBlock("button", {
113
+ key: 0,
114
+ type: "button",
115
+ class: "hm-btn-primario",
116
+ disabled: !cambiado.value || __props.ocupado,
117
+ "aria-label": `Guardar la homologación de ${__props.fila.nombre}`,
118
+ onClick: _cache[1] || (_cache[1] = ($event) => emit("guardar", elegido.value))
119
+ }, toDisplayString(__props.guardando ? "Guardando…" : "Guardar"), 9, _hoisted_16$1)) : createCommentVNode("", true),
120
+ __props.puedeEditar && __props.fila.editable && conCliente.value && !__props.fila.heredado ? (openBlock(), createElementBlock("button", {
121
+ key: 1,
122
+ type: "button",
123
+ class: "hm-link",
124
+ disabled: __props.ocupado,
125
+ onClick: _cache[2] || (_cache[2] = ($event) => emit("heredar"))
126
+ }, " Usar el de todo el tenant ", 8, _hoisted_17$1)) : createCommentVNode("", true),
127
+ __props.puedeEditar && __props.editableTipo ? (openBlock(), createElementBlock("button", {
128
+ key: 2,
129
+ type: "button",
130
+ class: "hm-link",
131
+ disabled: __props.ocupado,
132
+ "aria-label": `Editar ${__props.fila.nombre}`,
133
+ onClick: _cache[3] || (_cache[3] = ($event) => emit("editar"))
134
+ }, " Editar ", 8, _hoisted_18$1)) : createCommentVNode("", true)
135
+ ])])
136
+ ], 8, _hoisted_1$3);
137
+ };
138
+ }
139
+ });
140
+ //#endregion
141
+ //#region src/services/homologacion.service.ts
142
+ var homologacionService = {
143
+ async obtener(clienteInterno) {
144
+ const params = clienteInterno === null ? {} : { cliente_interno_id: clienteInterno };
145
+ const { data } = await api.get("/homologacion", { params });
146
+ return {
147
+ conceptos: data.data?.conceptos ?? [],
148
+ filas: data.data?.filas ?? []
149
+ };
150
+ },
151
+ /** `idconceptonovedad` null: quita la homologación (con un cliente elegido, vuelve a la de todo el tenant). */
152
+ async guardar(clave, idconceptonovedad, clienteInterno) {
153
+ const { data } = await api.put("/homologacion", {
154
+ cliente_interno_id: clienteInterno,
155
+ clave,
156
+ idconceptonovedad
157
+ });
158
+ return data.data;
159
+ },
160
+ /** Primero se crea en SoftDIN y después en el portal: si SoftDIN falla, no se crea nada. */
161
+ async crearTipoSolicitud(datos, clienteInterno) {
162
+ const { data } = await api.post("/tipos-solicitud", {
163
+ ...datos,
164
+ cliente_interno_id: clienteInterno
165
+ });
166
+ return data.data;
167
+ },
168
+ /** `id`: el del tipo del tenant (como en Tipos de solicitud). */
169
+ async editarTipoSolicitud(id, datos, clienteInterno) {
170
+ const cuerpo = clienteInterno === null ? datos : {
171
+ ...datos,
172
+ cliente_interno_id: clienteInterno
173
+ };
174
+ const { data } = await api.patch(`/tipos-solicitud/${id}`, cuerpo);
175
+ return data.data;
176
+ },
177
+ async crearPermiso(datos, clienteInterno) {
178
+ const { data } = await api.post("/tipos-permiso", {
179
+ ...datos,
180
+ cliente_interno_id: clienteInterno
181
+ });
182
+ return data.data;
183
+ },
184
+ async editarPermiso(codigo, datos, clienteInterno) {
185
+ const { data } = await api.patch(`/tipos-permiso/${encodeURIComponent(codigo)}`, {
186
+ ...datos,
187
+ cliente_interno_id: clienteInterno
188
+ });
189
+ return data.data;
190
+ }
191
+ };
192
+ //#endregion
193
+ //#region src/components/homologacion/TipoPermisoFormModal.vue?vue&type=script&setup=true&lang.ts
194
+ var _hoisted_1$2 = {
195
+ key: 0,
196
+ class: "hm-modal-fondo"
197
+ };
198
+ var _hoisted_2$2 = {
199
+ class: "hm-modal",
200
+ role: "dialog",
201
+ "aria-modal": "true",
202
+ "aria-labelledby": "permiso-titulo"
203
+ };
204
+ var _hoisted_3$2 = { class: "hm-modal-cabecera" };
205
+ var _hoisted_4$2 = {
206
+ id: "permiso-titulo",
207
+ class: "hm-modal-titulo"
208
+ };
209
+ var _hoisted_5$2 = { class: "hm-info" };
210
+ var _hoisted_6$2 = { class: "hm-campos" };
211
+ var _hoisted_7$2 = ["disabled"];
212
+ var _hoisted_8$2 = ["value"];
213
+ var _hoisted_9$2 = ["disabled"];
214
+ var _hoisted_10$2 = {
215
+ for: "permiso-tope",
216
+ class: "hm-label"
217
+ };
218
+ var _hoisted_11$2 = ["min"];
219
+ var _hoisted_12$2 = {
220
+ id: "permiso-tope-ayuda",
221
+ class: "hm-sub"
222
+ };
223
+ var _hoisted_13$2 = ["disabled"];
224
+ var _hoisted_14$2 = ["value"];
225
+ var _hoisted_15$1 = { class: "hm-fieldset" };
226
+ var _hoisted_16 = { class: "hm-check" };
227
+ var _hoisted_17 = { key: 0 };
228
+ var _hoisted_18 = { class: "hm-fieldset" };
229
+ var _hoisted_19 = { class: "hm-check" };
230
+ var _hoisted_20 = ["disabled"];
231
+ var _hoisted_21 = {
232
+ key: 0,
233
+ class: "hm-campos"
234
+ };
235
+ var _hoisted_22 = ["for"];
236
+ var _hoisted_23 = [
237
+ "id",
238
+ "onUpdate:modelValue",
239
+ "disabled"
240
+ ];
241
+ var _hoisted_24 = ["value"];
242
+ var _hoisted_25 = { class: "hm-check" };
243
+ var _hoisted_26 = ["disabled"];
244
+ var _hoisted_27 = {
245
+ key: 0,
246
+ class: "hm-error",
247
+ role: "alert"
248
+ };
249
+ var _hoisted_28 = { class: "hm-modal-pie" };
250
+ var _hoisted_29 = ["disabled"];
251
+ var _hoisted_30 = ["disabled"];
252
+ //#endregion
253
+ //#region src/components/homologacion/TipoPermisoFormModal.vue
254
+ var TipoPermisoFormModal_default = /* @__PURE__ */ defineComponent({
255
+ __name: "TipoPermisoFormModal",
256
+ props: /*@__PURE__*/ mergeModels({
257
+ permiso: {},
258
+ clienteInterno: {},
259
+ nombreCliente: {}
260
+ }, {
261
+ "open": {
262
+ type: Boolean,
263
+ required: true
264
+ },
265
+ "openModifiers": {}
266
+ }),
267
+ emits: /*@__PURE__*/ mergeModels(["guardado"], ["update:open"]),
268
+ setup(__props, { emit: __emit }) {
269
+ const open = useModel(__props, "open");
270
+ const props = __props;
271
+ const emit = __emit;
272
+ const form = reactive({
273
+ nombre: "",
274
+ unidad: "dias_habiles",
275
+ tope: "",
276
+ tope_periodo: "evento",
277
+ remunerado: true,
278
+ soporte_requerido: false,
279
+ plazo_soporte_dias: "",
280
+ pide_parentesco: false,
281
+ parentesco: {
282
+ consanguinidad: 0,
283
+ afinidad: 0,
284
+ civil: 0
285
+ },
286
+ activo: true
287
+ });
288
+ const guardando = ref(false);
289
+ const error = ref(null);
290
+ const editando = computed(() => props.permiso !== null);
291
+ /** De la plantilla de la ley: solo se ajusta lo que la mejora. */
292
+ const deLey = computed(() => props.permiso !== null && esPermisoDeLey(props.permiso));
293
+ const topeLegal = computed(() => deLey.value ? props.permiso?.tope_legal ?? null : null);
294
+ const obligatorio = computed(() => deLey.value && props.permiso?.obligatorio === true);
295
+ const unidadTexto = computed(() => UNIDADES_PERMISO.find((u) => u.valor === form.unidad)?.texto.toLowerCase() ?? "");
296
+ watch(open, (abierto) => {
297
+ if (!abierto) return;
298
+ const p = props.permiso;
299
+ const parentesco = p?.parentesco ?? null;
300
+ Object.assign(form, {
301
+ nombre: p?.nombre ?? "",
302
+ unidad: p?.unidad ?? "dias_habiles",
303
+ tope: p?.tope ?? "",
304
+ tope_periodo: p?.tope_periodo ?? "evento",
305
+ remunerado: p?.remunerado ?? true,
306
+ soporte_requerido: p?.soporte_requerido ?? false,
307
+ plazo_soporte_dias: p?.plazo_soporte_dias ?? "",
308
+ pide_parentesco: parentesco !== null && parentesco !== void 0,
309
+ parentesco: {
310
+ consanguinidad: parentesco?.consanguinidad ?? 0,
311
+ afinidad: parentesco?.afinidad ?? 0,
312
+ civil: parentesco?.civil ?? 0
313
+ },
314
+ activo: p?.activo ?? true
315
+ });
316
+ error.value = null;
317
+ }, { immediate: true });
318
+ function numero(v) {
319
+ return v === "" || v === null ? null : Number(v);
320
+ }
321
+ function validar() {
322
+ const nombre = form.nombre.trim();
323
+ if (nombre.length < 3) return "Escriba el nombre del permiso (al menos 3 caracteres).";
324
+ if (nombre.length > 120) return "El nombre admite hasta 120 caracteres.";
325
+ const tope = numero(form.tope);
326
+ if (tope !== null && !(Number.isFinite(tope) && tope > 0)) return "El tope debe ser un número mayor que cero, o vacío para no tener tope.";
327
+ if (topeLegal.value !== null && (tope === null ? false : tope < topeLegal.value)) return `La ley da ${topeLegal.value} ${unidadTexto.value}${props.permiso?.norma ? ` (${props.permiso.norma})` : ""}: se puede ampliar el tope, no bajarlo.`;
328
+ if (form.soporte_requerido && form.plazo_soporte_dias !== "") {
329
+ const plazo = Number(form.plazo_soporte_dias);
330
+ if (!Number.isInteger(plazo) || plazo < 1 || plazo > 365) return "El plazo del soporte va de 1 a 365 días (vacío: al pedirlo).";
331
+ }
332
+ if (obligatorio.value && !form.activo) return "Este permiso lo exige la ley: no se puede desactivar.";
333
+ if (!deLey.value && form.pide_parentesco && LINEAS_PARENTESCO.every((l) => !form.parentesco[l.linea])) return "Indique hasta qué grado de parentesco da derecho, o quite «Pide parentesco».";
334
+ return null;
335
+ }
336
+ function datosAjuste() {
337
+ return {
338
+ nombre: form.nombre.trim(),
339
+ tope: numero(form.tope),
340
+ soporte_requerido: form.soporte_requerido,
341
+ plazo_soporte_dias: form.soporte_requerido ? numero(form.plazo_soporte_dias) : null,
342
+ activo: form.activo
343
+ };
344
+ }
345
+ function datosPropio() {
346
+ const parentesco = form.pide_parentesco ? Object.fromEntries(LINEAS_PARENTESCO.filter((l) => form.parentesco[l.linea] > 0).map((l) => [l.linea, Number(form.parentesco[l.linea])])) : null;
347
+ return {
348
+ ...datosAjuste(),
349
+ unidad: form.unidad,
350
+ tope_periodo: form.tope_periodo,
351
+ remunerado: form.remunerado,
352
+ parentesco
353
+ };
354
+ }
355
+ async function guardar() {
356
+ error.value = validar();
357
+ if (error.value) return;
358
+ guardando.value = true;
359
+ try {
360
+ const p = props.permiso ? await homologacionService.editarPermiso(props.permiso.codigo, deLey.value ? datosAjuste() : datosPropio(), props.clienteInterno) : await homologacionService.crearPermiso(datosPropio(), props.clienteInterno);
361
+ emit("guardado", p);
362
+ open.value = false;
363
+ } catch (e) {
364
+ error.value = mensajeError(e, "No se pudo guardar el permiso.");
365
+ } finally {
366
+ guardando.value = false;
367
+ }
368
+ }
369
+ return (_ctx, _cache) => {
370
+ return openBlock(), createBlock(Teleport, { to: "body" }, [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$2, [createElementVNode("div", _hoisted_2$2, [createElementVNode("header", _hoisted_3$2, [createElementVNode("h2", _hoisted_4$2, toDisplayString(editando.value ? "Editar permiso" : "Nuevo permiso"), 1), createVNode(FormCloseButton, {
371
+ disabled: guardando.value,
372
+ onClick: _cache[0] || (_cache[0] = ($event) => open.value = false)
373
+ }, null, 8, ["disabled"])]), createElementVNode("form", {
374
+ class: "hm-modal-cuerpo",
375
+ novalidate: "",
376
+ onSubmit: withModifiers(guardar, ["prevent"])
377
+ }, [
378
+ createElementVNode("p", _hoisted_5$2, [
379
+ _cache[13] || (_cache[13] = createTextVNode(" Para ", -1)),
380
+ createElementVNode("strong", null, toDisplayString(__props.nombreCliente), 1),
381
+ _cache[14] || (_cache[14] = createTextVNode(". ", -1)),
382
+ deLey.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
383
+ _cache[11] || (_cache[11] = createTextVNode(" Es un permiso de la ley", -1)),
384
+ __props.permiso?.norma ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(" (" + toDisplayString(__props.permiso.norma) + ")", 1)], 64)) : createCommentVNode("", true),
385
+ _cache[12] || (_cache[12] = createTextVNode(": se puede mejorar (nombre, tope más alto, soporte), no empeorar. La unidad, si es remunerado y el parentesco los fija la ley. ", -1))
386
+ ], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(" Lo verá el empleado al pedir un permiso. Remunerado se liquida como licencia remunerada (LRM); no remunerado, como licencia no remunerada (SLN). ")], 64))
387
+ ]),
388
+ createElementVNode("div", null, [_cache[15] || (_cache[15] = createElementVNode("label", {
389
+ for: "permiso-nombre",
390
+ class: "hm-label"
391
+ }, "Nombre", -1)), withDirectives(createElementVNode("input", {
392
+ id: "permiso-nombre",
393
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => form.nombre = $event),
394
+ class: "hm-input",
395
+ maxlength: "120",
396
+ autocomplete: "off",
397
+ placeholder: "Ej.: Día de la familia"
398
+ }, null, 512), [[vModelText, form.nombre]])]),
399
+ createElementVNode("div", _hoisted_6$2, [
400
+ createElementVNode("div", null, [_cache[16] || (_cache[16] = createElementVNode("label", {
401
+ for: "permiso-unidad",
402
+ class: "hm-label"
403
+ }, "Unidad", -1)), withDirectives(createElementVNode("select", {
404
+ id: "permiso-unidad",
405
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => form.unidad = $event),
406
+ class: "hm-select",
407
+ disabled: deLey.value
408
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(UNIDADES_PERMISO), (u) => {
409
+ return openBlock(), createElementBlock("option", {
410
+ key: u.valor,
411
+ value: u.valor
412
+ }, toDisplayString(u.texto), 9, _hoisted_8$2);
413
+ }), 128))], 8, _hoisted_7$2), [[vModelSelect, form.unidad]])]),
414
+ createElementVNode("div", null, [_cache[18] || (_cache[18] = createElementVNode("label", {
415
+ for: "permiso-remunerado",
416
+ class: "hm-label"
417
+ }, "Pago", -1)), withDirectives(createElementVNode("select", {
418
+ id: "permiso-remunerado",
419
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => form.remunerado = $event),
420
+ class: "hm-select",
421
+ disabled: deLey.value
422
+ }, [..._cache[17] || (_cache[17] = [createElementVNode("option", { value: true }, "Remunerado", -1), createElementVNode("option", { value: false }, "No remunerado", -1)])], 8, _hoisted_9$2), [[vModelSelect, form.remunerado]])]),
423
+ createElementVNode("div", null, [
424
+ createElementVNode("label", _hoisted_10$2, "Tope (" + toDisplayString(unidadTexto.value) + ")", 1),
425
+ withDirectives(createElementVNode("input", {
426
+ id: "permiso-tope",
427
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => form.tope = $event),
428
+ class: "hm-input",
429
+ type: "number",
430
+ step: "0.5",
431
+ min: topeLegal.value ?? .5,
432
+ inputmode: "decimal",
433
+ "aria-describedby": "permiso-tope-ayuda"
434
+ }, null, 8, _hoisted_11$2), [[vModelText, form.tope]]),
435
+ createElementVNode("span", _hoisted_12$2, [topeLegal.value !== null ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode("Mínimo de ley: " + toDisplayString(topeLegal.value) + ". ", 1)], 64)) : createCommentVNode("", true), _cache[19] || (_cache[19] = createTextVNode("Vacío: sin tope. ", -1))])
436
+ ]),
437
+ createElementVNode("div", null, [_cache[20] || (_cache[20] = createElementVNode("label", {
438
+ for: "permiso-periodo",
439
+ class: "hm-label"
440
+ }, "Periodo del tope", -1)), withDirectives(createElementVNode("select", {
441
+ id: "permiso-periodo",
442
+ "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => form.tope_periodo = $event),
443
+ class: "hm-select",
444
+ disabled: deLey.value
445
+ }, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(PERIODOS_TOPE), (p) => {
446
+ return openBlock(), createElementBlock("option", {
447
+ key: p.valor,
448
+ value: p.valor
449
+ }, toDisplayString(p.texto), 9, _hoisted_14$2);
450
+ }), 128))], 8, _hoisted_13$2), [[vModelSelect, form.tope_periodo]])])
451
+ ]),
452
+ createElementVNode("fieldset", _hoisted_15$1, [
453
+ _cache[24] || (_cache[24] = createElementVNode("legend", null, "Soporte", -1)),
454
+ createElementVNode("label", _hoisted_16, [withDirectives(createElementVNode("input", {
455
+ "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => form.soporte_requerido = $event),
456
+ type: "checkbox"
457
+ }, null, 512), [[vModelCheckbox, form.soporte_requerido]]), _cache[21] || (_cache[21] = createElementVNode("span", null, "Pide soporte", -1))]),
458
+ form.soporte_requerido ? (openBlock(), createElementBlock("div", _hoisted_17, [
459
+ _cache[22] || (_cache[22] = createElementVNode("label", {
460
+ for: "permiso-plazo",
461
+ class: "hm-label"
462
+ }, "Plazo para entregarlo (días)", -1)),
463
+ withDirectives(createElementVNode("input", {
464
+ id: "permiso-plazo",
465
+ "onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => form.plazo_soporte_dias = $event),
466
+ class: "hm-input",
467
+ type: "number",
468
+ min: "1",
469
+ max: "365",
470
+ inputmode: "numeric",
471
+ "aria-describedby": "permiso-plazo-ayuda"
472
+ }, null, 512), [[vModelText, form.plazo_soporte_dias]]),
473
+ _cache[23] || (_cache[23] = createElementVNode("span", {
474
+ id: "permiso-plazo-ayuda",
475
+ class: "hm-sub"
476
+ }, "Vacío: obligatorio al pedirlo.", -1))
477
+ ])) : createCommentVNode("", true)
478
+ ]),
479
+ createElementVNode("fieldset", _hoisted_18, [
480
+ _cache[27] || (_cache[27] = createElementVNode("legend", null, "Parentesco", -1)),
481
+ createElementVNode("label", _hoisted_19, [withDirectives(createElementVNode("input", {
482
+ "onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => form.pide_parentesco = $event),
483
+ type: "checkbox",
484
+ disabled: deLey.value
485
+ }, null, 8, _hoisted_20), [[vModelCheckbox, form.pide_parentesco]]), _cache[25] || (_cache[25] = createElementVNode("span", null, "Pide parentesco (el cónyuge o compañero(a) permanente siempre da derecho)", -1))]),
486
+ form.pide_parentesco ? (openBlock(), createElementBlock("div", _hoisted_21, [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(LINEAS_PARENTESCO), (l) => {
487
+ return openBlock(), createElementBlock("div", { key: l.linea }, [createElementVNode("label", {
488
+ for: `permiso-parentesco-${l.linea}`,
489
+ class: "hm-label"
490
+ }, toDisplayString(l.texto) + ": hasta el grado", 9, _hoisted_22), withDirectives(createElementVNode("select", {
491
+ id: `permiso-parentesco-${l.linea}`,
492
+ "onUpdate:modelValue": ($event) => form.parentesco[l.linea] = $event,
493
+ class: "hm-select",
494
+ disabled: deLey.value
495
+ }, [_cache[26] || (_cache[26] = createElementVNode("option", { value: 0 }, "Ninguno", -1)), (openBlock(true), createElementBlock(Fragment, null, renderList(l.maximo, (g) => {
496
+ return openBlock(), createElementBlock("option", {
497
+ key: g,
498
+ value: g
499
+ }, toDisplayString(g) + ".º", 9, _hoisted_24);
500
+ }), 128))], 8, _hoisted_23), [[
501
+ vModelSelect,
502
+ form.parentesco[l.linea],
503
+ void 0,
504
+ { number: true }
505
+ ]])]);
506
+ }), 128))])) : createCommentVNode("", true)
507
+ ]),
508
+ createElementVNode("label", _hoisted_25, [withDirectives(createElementVNode("input", {
509
+ "onUpdate:modelValue": _cache[9] || (_cache[9] = ($event) => form.activo = $event),
510
+ type: "checkbox",
511
+ disabled: obligatorio.value
512
+ }, null, 8, _hoisted_26), [[vModelCheckbox, form.activo]]), createElementVNode("span", null, [_cache[28] || (_cache[28] = createTextVNode(" Disponible para pedirlo", -1)), obligatorio.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(" (lo exige la ley: no se puede desactivar)")], 64)) : createCommentVNode("", true)])]),
513
+ error.value ? (openBlock(), createElementBlock("p", _hoisted_27, toDisplayString(error.value), 1)) : createCommentVNode("", true),
514
+ createElementVNode("footer", _hoisted_28, [createElementVNode("button", {
515
+ type: "button",
516
+ class: "hm-btn",
517
+ disabled: guardando.value,
518
+ onClick: _cache[10] || (_cache[10] = ($event) => open.value = false)
519
+ }, "Cancelar", 8, _hoisted_29), createElementVNode("button", {
520
+ type: "submit",
521
+ class: "hm-btn-primario",
522
+ disabled: guardando.value
523
+ }, toDisplayString(guardando.value ? "Guardando…" : editando.value ? "Guardar cambios" : "Crear permiso"), 9, _hoisted_30)])
524
+ ], 32)])])) : createCommentVNode("", true)]);
525
+ };
526
+ }
527
+ });
528
+ //#endregion
529
+ //#region src/components/homologacion/TipoSolicitudFormModal.vue?vue&type=script&setup=true&lang.ts
530
+ var _hoisted_1$1 = {
531
+ key: 0,
532
+ class: "hm-modal-fondo"
533
+ };
534
+ var _hoisted_2$1 = {
535
+ class: "hm-modal",
536
+ role: "dialog",
537
+ "aria-modal": "true",
538
+ "aria-labelledby": "tipo-solicitud-titulo"
539
+ };
540
+ var _hoisted_3$1 = { class: "hm-modal-cabecera" };
541
+ var _hoisted_4$1 = {
542
+ id: "tipo-solicitud-titulo",
543
+ class: "hm-modal-titulo"
544
+ };
545
+ var _hoisted_5$1 = { class: "hm-info" };
546
+ var _hoisted_6$1 = { class: "hm-check" };
547
+ var _hoisted_7$1 = { class: "hm-check" };
548
+ var _hoisted_8$1 = { class: "hm-fieldset" };
549
+ var _hoisted_9$1 = { class: "hm-check" };
550
+ var _hoisted_10$1 = { key: 0 };
551
+ var _hoisted_11$1 = {
552
+ key: 0,
553
+ class: "hm-error",
554
+ role: "alert"
555
+ };
556
+ var _hoisted_12$1 = { class: "hm-modal-pie" };
557
+ var _hoisted_13$1 = ["disabled"];
558
+ var _hoisted_14$1 = ["disabled"];
559
+ //#endregion
560
+ //#region src/components/homologacion/TipoSolicitudFormModal.vue
561
+ var TipoSolicitudFormModal_default = /* @__PURE__ */ defineComponent({
562
+ __name: "TipoSolicitudFormModal",
563
+ props: /*@__PURE__*/ mergeModels({
564
+ tipo: {},
565
+ clienteInterno: {},
566
+ nombreCliente: {}
567
+ }, {
568
+ "open": {
569
+ type: Boolean,
570
+ required: true
571
+ },
572
+ "openModifiers": {}
573
+ }),
574
+ emits: /*@__PURE__*/ mergeModels(["guardado"], ["update:open"]),
575
+ setup(__props, { emit: __emit }) {
576
+ const open = useModel(__props, "open");
577
+ const props = __props;
578
+ const emit = __emit;
579
+ const form = reactive({
580
+ nombre: "",
581
+ activo: true,
582
+ requiere_visto_bueno_nomina: true,
583
+ requiere_soporte: false,
584
+ plazo_soporte_dias: ""
585
+ });
586
+ const guardando = ref(false);
587
+ const error = ref(null);
588
+ const editando = computed(() => props.tipo !== null);
589
+ watch(open, (abierto) => {
590
+ if (!abierto) return;
591
+ const t = props.tipo;
592
+ Object.assign(form, {
593
+ nombre: t?.nombre ?? "",
594
+ activo: t?.activo ?? true,
595
+ requiere_visto_bueno_nomina: t?.requiere_visto_bueno_nomina ?? true,
596
+ requiere_soporte: t?.requiere_soporte ?? false,
597
+ plazo_soporte_dias: t?.plazo_soporte_dias ?? ""
598
+ });
599
+ error.value = null;
600
+ }, { immediate: true });
601
+ function validar() {
602
+ const nombre = form.nombre.trim();
603
+ if (nombre.length < 3) return "Escriba el nombre del tipo de solicitud (al menos 3 caracteres).";
604
+ if (nombre.length > 80) return "El nombre admite hasta 80 caracteres.";
605
+ if (form.requiere_soporte && form.plazo_soporte_dias !== "") {
606
+ const plazo = Number(form.plazo_soporte_dias);
607
+ if (!Number.isInteger(plazo) || plazo < 1 || plazo > 365) return "El plazo del soporte va de 1 a 365 días (vacío: al radicar).";
608
+ }
609
+ return null;
610
+ }
611
+ async function guardar() {
612
+ error.value = validar();
613
+ if (error.value) return;
614
+ const datos = {
615
+ nombre: form.nombre.trim(),
616
+ activo: form.activo,
617
+ requiere_visto_bueno_nomina: form.requiere_visto_bueno_nomina,
618
+ requiere_soporte: form.requiere_soporte,
619
+ plazo_soporte_dias: form.requiere_soporte && form.plazo_soporte_dias !== "" ? Number(form.plazo_soporte_dias) : null
620
+ };
621
+ guardando.value = true;
622
+ try {
623
+ const t = props.tipo ? await homologacionService.editarTipoSolicitud(props.tipo.id, datos, props.clienteInterno) : await homologacionService.crearTipoSolicitud(datos, props.clienteInterno);
624
+ emit("guardado", t);
625
+ open.value = false;
626
+ } catch (e) {
627
+ error.value = mensajeError(e, "No se pudo guardar el tipo de solicitud.");
628
+ } finally {
629
+ guardando.value = false;
630
+ }
631
+ }
632
+ return (_ctx, _cache) => {
633
+ return openBlock(), createBlock(Teleport, { to: "body" }, [open.value ? (openBlock(), createElementBlock("div", _hoisted_1$1, [createElementVNode("div", _hoisted_2$1, [createElementVNode("header", _hoisted_3$1, [createElementVNode("h2", _hoisted_4$1, toDisplayString(editando.value ? "Editar tipo de solicitud" : "Nuevo tipo de solicitud"), 1), createVNode(FormCloseButton, {
634
+ disabled: guardando.value,
635
+ onClick: _cache[0] || (_cache[0] = ($event) => open.value = false)
636
+ }, null, 8, ["disabled"])]), createElementVNode("form", {
637
+ class: "hm-modal-cuerpo",
638
+ novalidate: "",
639
+ onSubmit: withModifiers(guardar, ["prevent"])
640
+ }, [
641
+ createElementVNode("p", _hoisted_5$1, [
642
+ _cache[7] || (_cache[7] = createTextVNode(" Para ", -1)),
643
+ createElementVNode("strong", null, toDisplayString(__props.nombreCliente), 1),
644
+ _cache[8] || (_cache[8] = createTextVNode(". El empleado lo radica con fechas y motivo; pasa por los niveles de aprobación y, al aprobarse, SoftDIN crea la novedad con el concepto que le homologue en esta pantalla. Sin homologación, el portal no lo deja radicar. ", -1))
645
+ ]),
646
+ createElementVNode("div", null, [_cache[9] || (_cache[9] = createElementVNode("label", {
647
+ for: "tipo-solicitud-nombre",
648
+ class: "hm-label"
649
+ }, "Nombre", -1)), withDirectives(createElementVNode("input", {
650
+ id: "tipo-solicitud-nombre",
651
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => form.nombre = $event),
652
+ class: "hm-input",
653
+ maxlength: "80",
654
+ autocomplete: "off",
655
+ placeholder: "Ej.: Permiso sindical"
656
+ }, null, 512), [[vModelText, form.nombre]])]),
657
+ createElementVNode("label", _hoisted_6$1, [withDirectives(createElementVNode("input", {
658
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => form.activo = $event),
659
+ type: "checkbox"
660
+ }, null, 512), [[vModelCheckbox, form.activo]]), _cache[10] || (_cache[10] = createElementVNode("span", null, "Disponible en el portal", -1))]),
661
+ createElementVNode("label", _hoisted_7$1, [withDirectives(createElementVNode("input", {
662
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => form.requiere_visto_bueno_nomina = $event),
663
+ type: "checkbox"
664
+ }, null, 512), [[vModelCheckbox, form.requiere_visto_bueno_nomina]]), _cache[11] || (_cache[11] = createElementVNode("span", null, "Visto bueno de nómina: la novedad nace inactiva hasta que nómina la active", -1))]),
665
+ createElementVNode("fieldset", _hoisted_8$1, [
666
+ _cache[15] || (_cache[15] = createElementVNode("legend", null, "Soporte", -1)),
667
+ createElementVNode("label", _hoisted_9$1, [withDirectives(createElementVNode("input", {
668
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => form.requiere_soporte = $event),
669
+ type: "checkbox"
670
+ }, null, 512), [[vModelCheckbox, form.requiere_soporte]]), _cache[12] || (_cache[12] = createElementVNode("span", null, "El empleado adjunta un soporte", -1))]),
671
+ form.requiere_soporte ? (openBlock(), createElementBlock("div", _hoisted_10$1, [
672
+ _cache[13] || (_cache[13] = createElementVNode("label", {
673
+ for: "tipo-solicitud-plazo",
674
+ class: "hm-label"
675
+ }, "Plazo para entregarlo (días)", -1)),
676
+ withDirectives(createElementVNode("input", {
677
+ id: "tipo-solicitud-plazo",
678
+ "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => form.plazo_soporte_dias = $event),
679
+ class: "hm-input",
680
+ type: "number",
681
+ min: "1",
682
+ max: "365",
683
+ inputmode: "numeric",
684
+ "aria-describedby": "tipo-solicitud-plazo-ayuda"
685
+ }, null, 512), [[vModelText, form.plazo_soporte_dias]]),
686
+ _cache[14] || (_cache[14] = createElementVNode("span", {
687
+ id: "tipo-solicitud-plazo-ayuda",
688
+ class: "hm-sub"
689
+ }, "Vacío: obligatorio al radicar.", -1))
690
+ ])) : createCommentVNode("", true)
691
+ ]),
692
+ error.value ? (openBlock(), createElementBlock("p", _hoisted_11$1, toDisplayString(error.value), 1)) : createCommentVNode("", true),
693
+ createElementVNode("footer", _hoisted_12$1, [createElementVNode("button", {
694
+ type: "button",
695
+ class: "hm-btn",
696
+ disabled: guardando.value,
697
+ onClick: _cache[6] || (_cache[6] = ($event) => open.value = false)
698
+ }, "Cancelar", 8, _hoisted_13$1), createElementVNode("button", {
699
+ type: "submit",
700
+ class: "hm-btn-primario",
701
+ disabled: guardando.value
702
+ }, toDisplayString(guardando.value ? "Guardando…" : editando.value ? "Guardar cambios" : "Crear tipo"), 9, _hoisted_14$1)])
703
+ ], 32)])])) : createCommentVNode("", true)]);
704
+ };
705
+ }
706
+ });
707
+ //#endregion
708
+ //#region src/views/HomologacionView.vue?vue&type=script&setup=true&lang.ts
709
+ var _hoisted_1 = { class: "hm-pagina" };
710
+ var _hoisted_2 = { class: "hm-cabecera" };
711
+ var _hoisted_3 = {
712
+ key: 0,
713
+ class: "hm-acciones"
714
+ };
715
+ var _hoisted_4 = {
716
+ class: "hm-selector",
717
+ "data-prueba": "configurando"
718
+ };
719
+ var _hoisted_5 = {
720
+ key: 0,
721
+ class: "hm-muted"
722
+ };
723
+ var _hoisted_6 = {
724
+ key: 0,
725
+ class: "hm-info",
726
+ "data-prueba": "solo-consulta"
727
+ };
728
+ var _hoisted_7 = {
729
+ key: 1,
730
+ class: "hm-error",
731
+ role: "alert"
732
+ };
733
+ var _hoisted_8 = {
734
+ class: "sr-only",
735
+ "aria-live": "polite"
736
+ };
737
+ var _hoisted_9 = {
738
+ key: 2,
739
+ class: "hm-ok",
740
+ "data-prueba": "aviso"
741
+ };
742
+ var _hoisted_10 = {
743
+ key: 3,
744
+ class: "hm-muted"
745
+ };
746
+ var _hoisted_11 = ["aria-labelledby"];
747
+ var _hoisted_12 = ["id"];
748
+ var _hoisted_13 = {
749
+ key: 0,
750
+ class: "hm-muted",
751
+ "data-prueba": "sin-tipos-nuevos"
752
+ };
753
+ var _hoisted_14 = {
754
+ key: 1,
755
+ class: "hm-tabla-wrap"
756
+ };
757
+ var _hoisted_15 = { class: "hm-tabla" };
758
+ //#endregion
759
+ //#region src/views/HomologacionView.vue
760
+ var HomologacionView_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
761
+ __name: "HomologacionView",
762
+ setup(__props) {
763
+ const auth = useAuthStore();
764
+ const clientesInternos = useClienteInternoStore();
765
+ const clienteInterno = computed(() => clientesInternos.seleccionado);
766
+ const puedeEditar = computed(() => auth.esAdmin);
767
+ const conceptos = ref([]);
768
+ const filas = ref([]);
769
+ const tipos = ref([]);
770
+ const loading = ref(false);
771
+ const error = ref(null);
772
+ const aviso = ref(null);
773
+ const guardando = ref(null);
774
+ const modalTipo = ref(false);
775
+ const tipoEditado = ref(null);
776
+ const modalPermiso = ref(false);
777
+ const permisoEditado = ref(null);
778
+ const grupos = computed(() => GRUPOS_HOMOLOGACION.map((g) => ({
779
+ ...g,
780
+ filas: filas.value.filter((f) => f.grupo === g.grupo)
781
+ })).filter((g) => g.filas.length > 0 || g.grupo === "tipo"));
782
+ /** Los tipos de solicitud nuevos (`t_…`), con su id del tenant para editarlos. */
783
+ function tipoDeFila(f) {
784
+ const clave = tipoDeClave(f.clave);
785
+ return clave !== null && esTipoNuevo(clave) ? tipos.value.find((t) => t.tipo === clave) ?? null : null;
786
+ }
787
+ function editableTipo(f) {
788
+ if (f.grupo === "permiso") return !!f.tipo_permiso;
789
+ if (f.grupo === "tipo") return tipoDeFila(f) !== null;
790
+ return false;
791
+ }
792
+ let consulta = 0;
793
+ async function cargar() {
794
+ const esta = ++consulta;
795
+ loading.value = true;
796
+ error.value = null;
797
+ try {
798
+ const [h, t] = await Promise.all([homologacionService.obtener(clienteInterno.value), portalTiposService.listar(clienteInterno.value).catch(() => [])]);
799
+ if (esta !== consulta) return;
800
+ conceptos.value = h.conceptos;
801
+ filas.value = h.filas;
802
+ tipos.value = t;
803
+ } catch (e) {
804
+ if (esta !== consulta) return;
805
+ filas.value = [];
806
+ error.value = mensajeError(e, "No se pudo cargar la homologación.");
807
+ } finally {
808
+ if (esta === consulta) loading.value = false;
809
+ }
810
+ }
811
+ async function guardar(f, idconceptonovedad) {
812
+ error.value = null;
813
+ aviso.value = null;
814
+ guardando.value = f.clave;
815
+ try {
816
+ const actualizada = await homologacionService.guardar(f.clave, idconceptonovedad, clienteInterno.value);
817
+ filas.value = filas.value.map((x) => x.clave === f.clave ? {
818
+ ...x,
819
+ ...actualizada
820
+ } : x);
821
+ aviso.value = `Se guardó la homologación de «${f.nombre}».`;
822
+ } catch (e) {
823
+ error.value = mensajeError(e, "No se pudo guardar la homologación.");
824
+ } finally {
825
+ guardando.value = null;
826
+ }
827
+ }
828
+ function nuevoTipo() {
829
+ tipoEditado.value = null;
830
+ modalTipo.value = true;
831
+ }
832
+ function nuevoPermiso() {
833
+ permisoEditado.value = null;
834
+ modalPermiso.value = true;
835
+ }
836
+ function editar(f) {
837
+ if (f.grupo === "permiso" && f.tipo_permiso) {
838
+ permisoEditado.value = f.tipo_permiso;
839
+ modalPermiso.value = true;
840
+ } else if (f.grupo === "tipo") {
841
+ const t = tipoDeFila(f);
842
+ if (!t) return;
843
+ tipoEditado.value = t;
844
+ modalTipo.value = true;
845
+ }
846
+ }
847
+ /** Un tipo o permiso creado o cambiado: su fila (nueva o con otro nombre) sale de SoftDIN. */
848
+ async function alGuardarTipo(nombre) {
849
+ await cargar();
850
+ if (!error.value) aviso.value = `Se guardó «${nombre}». Homológuelo con su concepto de novedad.`;
851
+ }
852
+ watch(clienteInterno, () => {
853
+ aviso.value = null;
854
+ cargar();
855
+ });
856
+ onMounted(() => void cargar());
857
+ return (_ctx, _cache) => {
858
+ return openBlock(), createElementBlock("section", _hoisted_1, [
859
+ createElementVNode("header", _hoisted_2, [_cache[4] || (_cache[4] = createElementVNode("div", null, [createElementVNode("h1", { class: "hm-titulo" }, "Homologación"), createElementVNode("p", { class: "hm-muted" }, " Qué concepto de novedad de seguridad social de SoftDIN usa cada cosa que radica el empleado en su Portal de autogestión. Los conceptos se crean en SoftDIN; aquí solo se eligen. Si el concepto no liquida con la variable que exige la PILA, la pantalla avisa y SoftDIN guarda la advertencia. ")], -1)), puedeEditar.value ? (openBlock(), createElementBlock("div", _hoisted_3, [createElementVNode("button", {
860
+ type: "button",
861
+ class: "hm-btn",
862
+ onClick: nuevoTipo
863
+ }, "Nuevo tipo de solicitud"), createElementVNode("button", {
864
+ type: "button",
865
+ class: "hm-btn",
866
+ onClick: nuevoPermiso
867
+ }, "Nuevo permiso")])) : createCommentVNode("", true)]),
868
+ createElementVNode("p", _hoisted_4, [createElementVNode("span", null, [
869
+ _cache[5] || (_cache[5] = createTextVNode(" Configurando para ", -1)),
870
+ createElementVNode("strong", null, toDisplayString(unref(clientesInternos).nombre(clienteInterno.value)), 1),
871
+ _cache[6] || (_cache[6] = createElementVNode("span", { class: "hm-muted" }, "(se cambia en «Cliente», arriba)", -1))
872
+ ]), clienteInterno.value !== null ? (openBlock(), createElementBlock("span", _hoisted_5, " Lo que guarde aquí aplica solo a los empleados de este cliente y prevalece sobre lo de todo el tenant. ")) : createCommentVNode("", true)]),
873
+ !puedeEditar.value ? (openBlock(), createElementBlock("p", _hoisted_6, " Solo consulta: la homologación la cambia un administrador del portal. ")) : createCommentVNode("", true),
874
+ error.value ? (openBlock(), createElementBlock("p", _hoisted_7, toDisplayString(error.value), 1)) : createCommentVNode("", true),
875
+ createElementVNode("p", _hoisted_8, toDisplayString(aviso.value), 1),
876
+ aviso.value && !error.value ? (openBlock(), createElementBlock("p", _hoisted_9, toDisplayString(aviso.value), 1)) : createCommentVNode("", true),
877
+ loading.value ? (openBlock(), createElementBlock("p", _hoisted_10, "Cargando…")) : createCommentVNode("", true),
878
+ filas.value.length || !loading.value && !error.value ? (openBlock(true), createElementBlock(Fragment, { key: 4 }, renderList(grupos.value, (g) => {
879
+ return openBlock(), createElementBlock("section", {
880
+ key: g.grupo,
881
+ class: "hm-grupo",
882
+ "aria-labelledby": `hm-grupo-${g.grupo}`
883
+ }, [createElementVNode("h2", {
884
+ id: `hm-grupo-${g.grupo}`,
885
+ class: "hm-grupo-titulo"
886
+ }, toDisplayString(g.titulo), 9, _hoisted_12), !g.filas.length ? (openBlock(), createElementBlock("p", _hoisted_13, [_cache[7] || (_cache[7] = createTextVNode(" Aún no hay tipos de solicitud nuevos.", -1)), puedeEditar.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(" Créelos con «Nuevo tipo de solicitud».")], 64)) : createCommentVNode("", true)])) : (openBlock(), createElementBlock("div", _hoisted_14, [createElementVNode("table", _hoisted_15, [_cache[8] || (_cache[8] = createElementVNode("thead", null, [createElementVNode("tr", null, [
887
+ createElementVNode("th", { scope: "col" }, "Del portal"),
888
+ createElementVNode("th", { scope: "col" }, "Variable esperada"),
889
+ createElementVNode("th", { scope: "col" }, "Concepto de novedad"),
890
+ createElementVNode("th", { scope: "col" }, [createElementVNode("span", { class: "sr-only" }, "Acciones")])
891
+ ])], -1)), createElementVNode("tbody", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(g.filas, (f) => {
892
+ return openBlock(), createBlock(HomologacionFila_default, {
893
+ key: f.clave,
894
+ fila: f,
895
+ conceptos: conceptos.value,
896
+ "cliente-interno": clienteInterno.value,
897
+ "puede-editar": puedeEditar.value,
898
+ ocupado: guardando.value !== null,
899
+ guardando: guardando.value === f.clave,
900
+ "editable-tipo": editableTipo(f),
901
+ onGuardar: ($event) => guardar(f, $event),
902
+ onHeredar: ($event) => guardar(f, null),
903
+ onEditar: ($event) => editar(f)
904
+ }, null, 8, [
905
+ "fila",
906
+ "conceptos",
907
+ "cliente-interno",
908
+ "puede-editar",
909
+ "ocupado",
910
+ "guardando",
911
+ "editable-tipo",
912
+ "onGuardar",
913
+ "onHeredar",
914
+ "onEditar"
915
+ ]);
916
+ }), 128))])])]))], 8, _hoisted_11);
917
+ }), 128)) : createCommentVNode("", true),
918
+ createVNode(TipoSolicitudFormModal_default, {
919
+ open: modalTipo.value,
920
+ "onUpdate:open": _cache[0] || (_cache[0] = ($event) => modalTipo.value = $event),
921
+ tipo: tipoEditado.value,
922
+ "cliente-interno": clienteInterno.value,
923
+ "nombre-cliente": unref(clientesInternos).nombre(clienteInterno.value),
924
+ onGuardado: _cache[1] || (_cache[1] = ($event) => alGuardarTipo($event.nombre))
925
+ }, null, 8, [
926
+ "open",
927
+ "tipo",
928
+ "cliente-interno",
929
+ "nombre-cliente"
930
+ ]),
931
+ createVNode(TipoPermisoFormModal_default, {
932
+ open: modalPermiso.value,
933
+ "onUpdate:open": _cache[2] || (_cache[2] = ($event) => modalPermiso.value = $event),
934
+ permiso: permisoEditado.value,
935
+ "cliente-interno": clienteInterno.value,
936
+ "nombre-cliente": unref(clientesInternos).nombre(clienteInterno.value),
937
+ onGuardado: _cache[3] || (_cache[3] = ($event) => alGuardarTipo($event.nombre))
938
+ }, null, 8, [
939
+ "open",
940
+ "permiso",
941
+ "cliente-interno",
942
+ "nombre-cliente"
943
+ ])
944
+ ]);
945
+ };
946
+ }
947
+ }), [["__scopeId", "data-v-e9c01cc9"]]);
948
+ //#endregion
949
+ export { HomologacionView_default as default };