@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.
- package/README.md +95 -2
- package/dist-lib/chunks/AppLayout-COCPfLWo.js +303 -0
- package/dist-lib/chunks/AuditoriaView-Bcf_kOqI.js +643 -0
- package/dist-lib/chunks/CarnetView-BsdUtYeu.js +450 -0
- package/dist-lib/chunks/CarteleraView-CRnVjt-S.js +996 -0
- package/dist-lib/chunks/CertificadosView-DvHDflcN.js +549 -0
- package/dist-lib/chunks/ChatBandejaView-HqhdSw7G.js +274 -0
- package/dist-lib/chunks/ChatConfiguracionView-BdH5gDdR.js +716 -0
- package/dist-lib/chunks/ChatConocimientoView-nKTAKxFa.js +263 -0
- package/dist-lib/chunks/ChatConversacionView-Do74V09l.js +477 -0
- package/dist-lib/chunks/ChatInformeView-BIiAH9L_.js +280 -0
- package/dist-lib/chunks/ChatRespuestasView-QFXbyg8U.js +183 -0
- package/dist-lib/chunks/EmpleadosView-BtqrO5-8.js +311 -0
- package/dist-lib/chunks/HomologacionView-UCZk4u6R.js +949 -0
- package/dist-lib/chunks/IngresoSsoView-BKkcnrYO.js +98 -0
- package/dist-lib/chunks/SolicitudesView-CYPD2A1s.js +900 -0
- package/dist-lib/chunks/TiposSolicitudView-CrWTVizl.js +168 -0
- package/dist-lib/chunks/ToggleSwitch-BYrIyheq.js +55 -0
- package/dist-lib/chunks/_plugin-vue_export-helper-BOaGB7Aw.js +8 -0
- package/dist-lib/chunks/api-M7D1c3IT.js +97 -0
- package/dist-lib/chunks/apiError-BHGbwz97.js +15 -0
- package/dist-lib/chunks/auth.store-BrGKZg-7.js +220 -0
- package/dist-lib/chunks/chat.service-C7ZQf4w3.js +241 -0
- package/dist-lib/chunks/cliente-interno.store-De39VsEE.js +203 -0
- package/dist-lib/chunks/homologacion-CoeHD7cB.js +131 -0
- package/dist-lib/chunks/portal-empleado-6KQrnsQJ.js +120 -0
- package/dist-lib/chunks/tipos-D93bLfFC.js +22 -0
- package/dist-lib/portal-admin.js +196 -0
- package/dist-lib/style.css +4813 -0
- package/dist-lib/types/App.vue.d.ts +3 -0
- package/dist-lib/types/components/AppLayout.vue.d.ts +3 -0
- package/dist-lib/types/components/CarnetClientesInternos.vue.d.ts +11 -0
- package/dist-lib/types/components/InvitacionPortalModal.vue.d.ts +20 -0
- package/dist-lib/types/components/MenuUsuario.vue.d.ts +3 -0
- package/dist-lib/types/components/VistoBuenoPortalModal.vue.d.ts +23 -0
- package/dist-lib/types/components/auditoria/AuditoriaFila.vue.d.ts +16 -0
- package/dist-lib/types/components/auditoria/AuditoriaFiltros.vue.d.ts +30 -0
- package/dist-lib/types/components/auditoria/AuditoriaPaginador.vue.d.ts +14 -0
- package/dist-lib/types/components/cartelera/PaginaCarteleraImagen.vue.d.ts +14 -0
- package/dist-lib/types/components/cartelera/PublicacionFormModal.vue.d.ts +27 -0
- package/dist-lib/types/components/cartelera/VistaCelularCartelera.vue.d.ts +34 -0
- package/dist-lib/types/components/certificados/AtenderCertificadoModal.vue.d.ts +22 -0
- package/dist-lib/types/components/certificados/RechazarCertificadoModal.vue.d.ts +18 -0
- package/dist-lib/types/components/certificados/ResumenSolicitudCertificado.vue.d.ts +8 -0
- package/dist-lib/types/components/chat/ChatClientesInternos.vue.d.ts +21 -0
- package/dist-lib/types/components/chat/ChatHorarioCampos.vue.d.ts +21 -0
- package/dist-lib/types/components/forms/ExportExcelButton.vue.d.ts +30 -0
- package/dist-lib/types/components/forms/ToggleSwitch.vue.d.ts +17 -0
- package/dist-lib/types/components/homologacion/HomologacionFila.vue.d.ts +30 -0
- package/dist-lib/types/components/homologacion/TipoPermisoFormModal.vue.d.ts +26 -0
- package/dist-lib/types/components/homologacion/TipoSolicitudFormModal.vue.d.ts +27 -0
- package/dist-lib/types/lib/auditoria.d.ts +25 -0
- package/dist-lib/types/lib/cartelera-paginas.d.ts +26 -0
- package/dist-lib/types/lib/cartelera-vigencia.d.ts +3 -0
- package/dist-lib/types/lib/export-excel-csv.d.ts +4 -0
- package/dist-lib/types/lib/export-excel.d.ts +9 -0
- package/dist-lib/types/lib/exportar-listado.d.ts +68 -0
- package/dist-lib/types/lib/homologacion.d.ts +41 -0
- package/dist-lib/types/lib/portal-empleado.d.ts +32 -0
- package/dist-lib/types/modulo.d.ts +31 -0
- package/dist-lib/types/portal-admin/config.d.ts +17 -0
- package/dist-lib/types/portal-admin/rutas.d.ts +17 -0
- package/dist-lib/types/portal-admin/tipos.d.ts +68 -0
- package/dist-lib/types/router/index.d.ts +7 -0
- package/dist-lib/types/services/api.d.ts +29 -0
- package/dist-lib/types/services/auditoria.service.d.ts +63 -0
- package/dist-lib/types/services/auth.service.d.ts +61 -0
- package/dist-lib/types/services/carnet.service.d.ts +56 -0
- package/dist-lib/types/services/cartelera.service.d.ts +69 -0
- package/dist-lib/types/services/chat.service.d.ts +279 -0
- package/dist-lib/types/services/configuracion-cliente-interno.service.d.ts +23 -0
- package/dist-lib/types/services/homologacion.service.d.ts +105 -0
- package/dist-lib/types/services/portal-empleado.service.d.ts +112 -0
- package/dist-lib/types/services/solicitudes-certificado.service.d.ts +59 -0
- package/dist-lib/types/stores/auth.store.d.ts +125 -0
- package/dist-lib/types/stores/cliente-interno.store.d.ts +65 -0
- package/dist-lib/types/utils/apiError.d.ts +4 -0
- package/dist-lib/types/views/AuditoriaView.vue.d.ts +3 -0
- package/dist-lib/types/views/CarnetView.vue.d.ts +3 -0
- package/dist-lib/types/views/CarteleraView.vue.d.ts +3 -0
- package/dist-lib/types/views/CertificadosView.vue.d.ts +3 -0
- package/dist-lib/types/views/EmpleadosView.vue.d.ts +3 -0
- package/dist-lib/types/views/HomologacionView.vue.d.ts +4 -0
- package/dist-lib/types/views/IngresoSsoView.vue.d.ts +3 -0
- package/dist-lib/types/views/LoginView.vue.d.ts +3 -0
- package/dist-lib/types/views/OlvideView.vue.d.ts +3 -0
- package/dist-lib/types/views/RestablecerView.vue.d.ts +3 -0
- package/dist-lib/types/views/SolicitudesView.vue.d.ts +3 -0
- package/dist-lib/types/views/TiposSolicitudView.vue.d.ts +3 -0
- package/dist-lib/types/views/chat/ChatBandejaView.vue.d.ts +3 -0
- package/dist-lib/types/views/chat/ChatConfiguracionView.vue.d.ts +3 -0
- package/dist-lib/types/views/chat/ChatConocimientoView.vue.d.ts +3 -0
- package/dist-lib/types/views/chat/ChatConversacionView.vue.d.ts +11 -0
- package/dist-lib/types/views/chat/ChatInformeView.vue.d.ts +3 -0
- package/dist-lib/types/views/chat/ChatRespuestasView.vue.d.ts +3 -0
- package/package.json +66 -4
|
@@ -0,0 +1,996 @@
|
|
|
1
|
+
import { t as api } from "./api-M7D1c3IT.js";
|
|
2
|
+
import { t as useAuthStore } from "./auth.store-BrGKZg-7.js";
|
|
3
|
+
import { 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 { Fragment, Teleport, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeModels, normalizeClass, onBeforeUnmount, onMounted, openBlock, reactive, ref, renderList, renderSlot, toDisplayString, unref, useModel, vModelCheckbox, vModelSelect, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
|
|
7
|
+
import FormCloseButton from "@softdin/shared/components/forms/FormCloseButton.vue";
|
|
8
|
+
//#region src/services/cartelera.service.ts
|
|
9
|
+
var MULTIPART = { headers: { "Content-Type": "multipart/form-data" } };
|
|
10
|
+
function extension(b) {
|
|
11
|
+
return b.type === "image/webp" ? "webp" : b.type === "image/png" ? "png" : "jpg";
|
|
12
|
+
}
|
|
13
|
+
function formularioPublicacion(p) {
|
|
14
|
+
const f = new FormData();
|
|
15
|
+
if (p.cliente_interno_id !== void 0) f.append("cliente_interno_id", p.cliente_interno_id == null ? "" : String(p.cliente_interno_id));
|
|
16
|
+
f.append("titulo", p.titulo);
|
|
17
|
+
f.append("resumen", p.resumen);
|
|
18
|
+
f.append("fecha_desde", p.fecha_desde);
|
|
19
|
+
if (p.fecha_hasta) f.append("fecha_hasta", p.fecha_hasta);
|
|
20
|
+
f.append("orden", String(p.orden));
|
|
21
|
+
f.append("destacada", p.destacada ? "1" : "0");
|
|
22
|
+
if (p.archivo && p.paginas) {
|
|
23
|
+
f.append("archivo", p.archivo);
|
|
24
|
+
p.paginas.forEach((pg, i) => f.append("paginas[]", pg, `pagina-${i + 1}.${extension(pg)}`));
|
|
25
|
+
}
|
|
26
|
+
return f;
|
|
27
|
+
}
|
|
28
|
+
var carteleraService = {
|
|
29
|
+
async listar(filtro = {}) {
|
|
30
|
+
const params = {};
|
|
31
|
+
if (filtro.estado) params.estado = filtro.estado;
|
|
32
|
+
if (filtro.cliente_interno_id != null) params.cliente_interno_id = filtro.cliente_interno_id;
|
|
33
|
+
const { data } = await api.get("/cartelera", { params });
|
|
34
|
+
return data.data;
|
|
35
|
+
},
|
|
36
|
+
async ver(id) {
|
|
37
|
+
const { data } = await api.get(`/cartelera/${id}`);
|
|
38
|
+
return data.data;
|
|
39
|
+
},
|
|
40
|
+
/** Nace en borrador. */
|
|
41
|
+
async crear(p) {
|
|
42
|
+
const { data } = await api.post("/cartelera", formularioPublicacion(p), MULTIPART);
|
|
43
|
+
return data.data;
|
|
44
|
+
},
|
|
45
|
+
/** Multipart: PHP no lo lee en un PATCH, así que va como POST con `_method=PATCH`. Sin archivo conserva las páginas. */
|
|
46
|
+
async actualizar(id, p) {
|
|
47
|
+
const f = formularioPublicacion(p);
|
|
48
|
+
f.append("_method", "PATCH");
|
|
49
|
+
const { data } = await api.post(`/cartelera/${id}`, f, MULTIPART);
|
|
50
|
+
return data.data;
|
|
51
|
+
},
|
|
52
|
+
async eliminar(id) {
|
|
53
|
+
await api.delete(`/cartelera/${id}`);
|
|
54
|
+
},
|
|
55
|
+
/** 422 si la vigencia ya terminó o no tiene páginas. */
|
|
56
|
+
async publicar(id) {
|
|
57
|
+
const { data } = await api.post(`/cartelera/${id}/publicar`);
|
|
58
|
+
return data.data;
|
|
59
|
+
},
|
|
60
|
+
async retirar(id) {
|
|
61
|
+
const { data } = await api.post(`/cartelera/${id}/retirar`);
|
|
62
|
+
return data.data;
|
|
63
|
+
},
|
|
64
|
+
/** Imagen de una página (`n` desde 1). Va con el token de la sesión: se pide como blob. */
|
|
65
|
+
async pagina(id, n) {
|
|
66
|
+
const { data } = await api.get(`/cartelera/${id}/paginas/${n}`, { responseType: "blob" });
|
|
67
|
+
return data;
|
|
68
|
+
},
|
|
69
|
+
/** Archivo original tal como se subió (404 si no lo tiene). */
|
|
70
|
+
async archivo(id) {
|
|
71
|
+
const { data } = await api.get(`/cartelera/${id}/archivo`, { responseType: "blob" });
|
|
72
|
+
return data;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/components/cartelera/PaginaCarteleraImagen.vue?vue&type=script&setup=true&lang.ts
|
|
77
|
+
var _hoisted_1$3 = ["src", "alt"];
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/components/cartelera/PaginaCarteleraImagen.vue
|
|
80
|
+
var PaginaCarteleraImagen_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
|
|
81
|
+
__name: "PaginaCarteleraImagen",
|
|
82
|
+
props: {
|
|
83
|
+
publicacionId: {},
|
|
84
|
+
n: {},
|
|
85
|
+
version: {},
|
|
86
|
+
alt: {}
|
|
87
|
+
},
|
|
88
|
+
setup(__props) {
|
|
89
|
+
const props = __props;
|
|
90
|
+
const url = ref(null);
|
|
91
|
+
const fallo = ref(false);
|
|
92
|
+
async function cargar() {
|
|
93
|
+
fallo.value = false;
|
|
94
|
+
try {
|
|
95
|
+
const blob = await carteleraService.pagina(props.publicacionId, props.n);
|
|
96
|
+
if (url.value) URL.revokeObjectURL(url.value);
|
|
97
|
+
url.value = URL.createObjectURL(blob);
|
|
98
|
+
} catch {
|
|
99
|
+
fallo.value = true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
watch(() => [
|
|
103
|
+
props.publicacionId,
|
|
104
|
+
props.n,
|
|
105
|
+
props.version
|
|
106
|
+
], cargar, { immediate: true });
|
|
107
|
+
onBeforeUnmount(() => {
|
|
108
|
+
if (url.value) URL.revokeObjectURL(url.value);
|
|
109
|
+
});
|
|
110
|
+
return (_ctx, _cache) => {
|
|
111
|
+
return url.value ? (openBlock(), createElementBlock("img", {
|
|
112
|
+
key: 0,
|
|
113
|
+
src: url.value,
|
|
114
|
+
alt: __props.alt,
|
|
115
|
+
class: "pagina-img",
|
|
116
|
+
loading: "lazy"
|
|
117
|
+
}, null, 8, _hoisted_1$3)) : (openBlock(), createElementBlock("div", {
|
|
118
|
+
key: 1,
|
|
119
|
+
class: normalizeClass(["pagina-img pagina-espera", { "pagina-fallo": fallo.value }])
|
|
120
|
+
}, toDisplayString(fallo.value ? "No se pudo cargar" : "Cargando…"), 3));
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}), [["__scopeId", "data-v-9ad8b0fc"]]);
|
|
124
|
+
//#endregion
|
|
125
|
+
//#region src/components/cartelera/VistaCelularCartelera.vue?vue&type=script&setup=true&lang.ts
|
|
126
|
+
var _hoisted_1$2 = {
|
|
127
|
+
class: "celular",
|
|
128
|
+
"aria-label": "Vista previa en el celular del empleado"
|
|
129
|
+
};
|
|
130
|
+
var _hoisted_2$2 = { class: "celular-pantalla" };
|
|
131
|
+
var _hoisted_3$2 = { class: "app-barra" };
|
|
132
|
+
var _hoisted_4$2 = { class: "app-empresa" };
|
|
133
|
+
var _hoisted_5$2 = { class: "app-contenido" };
|
|
134
|
+
var _hoisted_6$2 = {
|
|
135
|
+
key: 0,
|
|
136
|
+
class: "app-vacio"
|
|
137
|
+
};
|
|
138
|
+
var _hoisted_7$2 = {
|
|
139
|
+
key: 0,
|
|
140
|
+
class: "cinta"
|
|
141
|
+
};
|
|
142
|
+
var _hoisted_8$2 = { class: "tarjeta-titulo" };
|
|
143
|
+
var _hoisted_9$2 = {
|
|
144
|
+
key: 1,
|
|
145
|
+
class: "tarjeta-resumen"
|
|
146
|
+
};
|
|
147
|
+
var _hoisted_10$2 = { class: "tarjeta-paginas" };
|
|
148
|
+
var _hoisted_11$2 = { class: "tarjeta-vigencia" };
|
|
149
|
+
//#endregion
|
|
150
|
+
//#region src/components/cartelera/VistaCelularCartelera.vue
|
|
151
|
+
var VistaCelularCartelera_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
|
|
152
|
+
__name: "VistaCelularCartelera",
|
|
153
|
+
props: {
|
|
154
|
+
tarjetas: {},
|
|
155
|
+
empresa: {}
|
|
156
|
+
},
|
|
157
|
+
setup(__props) {
|
|
158
|
+
/**
|
|
159
|
+
* Vista previa de la cartelera tal como la ve el empleado en la app «Portal de
|
|
160
|
+
* autogestión»: un marco de celular con las publicaciones en tarjetas y sus páginas una
|
|
161
|
+
* debajo de otra. Cada página llega por el slot `pagina` (una imagen recién convertida
|
|
162
|
+
* o una ya guardada).
|
|
163
|
+
*/
|
|
164
|
+
return (_ctx, _cache) => {
|
|
165
|
+
return openBlock(), createElementBlock("div", _hoisted_1$2, [createElementVNode("div", _hoisted_2$2, [
|
|
166
|
+
createElementVNode("header", _hoisted_3$2, [createElementVNode("span", _hoisted_4$2, toDisplayString(__props.empresa || "Su empresa"), 1), _cache[0] || (_cache[0] = createElementVNode("span", { class: "app-seccion" }, "Cartelera", -1))]),
|
|
167
|
+
createElementVNode("div", _hoisted_5$2, [__props.tarjetas.length === 0 ? (openBlock(), createElementBlock("p", _hoisted_6$2, " Aquí aparecerán las publicaciones que el empleado verá al abrir la app. ")) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(__props.tarjetas, (t) => {
|
|
168
|
+
return openBlock(), createElementBlock("article", {
|
|
169
|
+
key: t.clave,
|
|
170
|
+
class: normalizeClass(["tarjeta", { destacada: t.destacada }])
|
|
171
|
+
}, [
|
|
172
|
+
t.destacada ? (openBlock(), createElementBlock("span", _hoisted_7$2, "Destacada")) : createCommentVNode("", true),
|
|
173
|
+
createElementVNode("h4", _hoisted_8$2, toDisplayString(t.titulo || "Título de la publicación"), 1),
|
|
174
|
+
t.resumen ? (openBlock(), createElementBlock("p", _hoisted_9$2, toDisplayString(t.resumen), 1)) : createCommentVNode("", true),
|
|
175
|
+
createElementVNode("div", _hoisted_10$2, [(openBlock(true), createElementBlock(Fragment, null, renderList(t.paginas, (n) => {
|
|
176
|
+
return openBlock(), createElementBlock("div", {
|
|
177
|
+
key: n,
|
|
178
|
+
class: "tarjeta-pagina"
|
|
179
|
+
}, [renderSlot(_ctx.$slots, "pagina", {
|
|
180
|
+
tarjeta: t,
|
|
181
|
+
n
|
|
182
|
+
}, void 0, true)]);
|
|
183
|
+
}), 128))]),
|
|
184
|
+
createElementVNode("p", _hoisted_11$2, toDisplayString(t.vigencia), 1)
|
|
185
|
+
], 2);
|
|
186
|
+
}), 128))]),
|
|
187
|
+
_cache[1] || (_cache[1] = createElementVNode("nav", {
|
|
188
|
+
class: "app-pestanas",
|
|
189
|
+
"aria-hidden": "true"
|
|
190
|
+
}, [
|
|
191
|
+
createElementVNode("span", { class: "activa" }, "Inicio"),
|
|
192
|
+
createElementVNode("span", null, "Volantes"),
|
|
193
|
+
createElementVNode("span", null, "Certificados"),
|
|
194
|
+
createElementVNode("span", null, "Solicitudes"),
|
|
195
|
+
createElementVNode("span", null, "Perfil")
|
|
196
|
+
], -1))
|
|
197
|
+
])]);
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}), [["__scopeId", "data-v-1d48ce6f"]]);
|
|
201
|
+
//#endregion
|
|
202
|
+
//#region src/lib/cartelera-paginas.ts
|
|
203
|
+
/** Ancho máximo de cada página publicada: se ve nítida en un celular y pesa poco. */
|
|
204
|
+
var ANCHO_MAXIMO = 1400;
|
|
205
|
+
var CALIDAD = .85;
|
|
206
|
+
function esPdf(archivo) {
|
|
207
|
+
return archivo.type === "application/pdf" || archivo.name.toLowerCase().endsWith(".pdf");
|
|
208
|
+
}
|
|
209
|
+
function esImagenAdmitida(archivo) {
|
|
210
|
+
return [
|
|
211
|
+
"image/jpeg",
|
|
212
|
+
"image/png",
|
|
213
|
+
"image/webp"
|
|
214
|
+
].includes(archivo.type);
|
|
215
|
+
}
|
|
216
|
+
/** Revisa peso y tipo antes de convertir: dice qué es o lanza el motivo del rechazo. */
|
|
217
|
+
function validarArchivo(archivo) {
|
|
218
|
+
if (archivo.size > 20971520) throw new Error(`El archivo pesa más de 20 MB.`);
|
|
219
|
+
if (esPdf(archivo)) return "pdf";
|
|
220
|
+
if (esImagenAdmitida(archivo)) return "imagen";
|
|
221
|
+
throw new Error("Solo se admiten PDF o imágenes JPG, PNG o WebP.");
|
|
222
|
+
}
|
|
223
|
+
/** Un PDF de más de `MAX_PAGINAS` páginas no se publica (el servidor tampoco lo acepta). */
|
|
224
|
+
function validarCantidadPaginas(paginas) {
|
|
225
|
+
if (paginas > 30) throw new Error(`El PDF tiene ${paginas} páginas; la cartelera admite hasta 30.`);
|
|
226
|
+
}
|
|
227
|
+
async function convertirArchivo(archivo, alAvanzar) {
|
|
228
|
+
return validarArchivo(archivo) === "pdf" ? convertirPdf(archivo, alAvanzar) : [await convertirImagen(archivo)];
|
|
229
|
+
}
|
|
230
|
+
function liberarPaginas(paginas) {
|
|
231
|
+
for (const p of paginas) URL.revokeObjectURL(p.url);
|
|
232
|
+
}
|
|
233
|
+
async function convertirPdf(archivo, alAvanzar) {
|
|
234
|
+
const pdfjs = await import("pdfjs-dist");
|
|
235
|
+
const { default: workerUrl } = await import("pdfjs-dist/build/pdf.worker.min.mjs?url");
|
|
236
|
+
pdfjs.GlobalWorkerOptions.workerSrc = workerUrl;
|
|
237
|
+
const doc = await pdfjs.getDocument({ data: new Uint8Array(await archivo.arrayBuffer()) }).promise;
|
|
238
|
+
try {
|
|
239
|
+
validarCantidadPaginas(doc.numPages);
|
|
240
|
+
const paginas = [];
|
|
241
|
+
for (let n = 1; n <= doc.numPages; n++) {
|
|
242
|
+
const pagina = await doc.getPage(n);
|
|
243
|
+
const base = pagina.getViewport({ scale: 1 });
|
|
244
|
+
const vista = pagina.getViewport({ scale: ANCHO_MAXIMO / base.width });
|
|
245
|
+
const lienzo = document.createElement("canvas");
|
|
246
|
+
lienzo.width = Math.round(vista.width);
|
|
247
|
+
lienzo.height = Math.round(vista.height);
|
|
248
|
+
const ctx = lienzo.getContext("2d");
|
|
249
|
+
if (!ctx) throw new Error("El navegador no permitió dibujar el PDF.");
|
|
250
|
+
ctx.fillStyle = "#ffffff";
|
|
251
|
+
ctx.fillRect(0, 0, lienzo.width, lienzo.height);
|
|
252
|
+
await pagina.render({
|
|
253
|
+
canvas: lienzo,
|
|
254
|
+
canvasContext: ctx,
|
|
255
|
+
viewport: vista
|
|
256
|
+
}).promise;
|
|
257
|
+
paginas.push(await desdeLienzo(lienzo));
|
|
258
|
+
pagina.cleanup();
|
|
259
|
+
alAvanzar?.(n, doc.numPages);
|
|
260
|
+
}
|
|
261
|
+
return paginas;
|
|
262
|
+
} finally {
|
|
263
|
+
await doc.destroy();
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async function convertirImagen(archivo) {
|
|
267
|
+
const bitmap = await createImageBitmap(archivo);
|
|
268
|
+
try {
|
|
269
|
+
const escala = Math.min(1, ANCHO_MAXIMO / bitmap.width);
|
|
270
|
+
if (escala === 1 && archivo.size <= 1572864) return {
|
|
271
|
+
blob: archivo,
|
|
272
|
+
ancho: bitmap.width,
|
|
273
|
+
alto: bitmap.height,
|
|
274
|
+
url: URL.createObjectURL(archivo)
|
|
275
|
+
};
|
|
276
|
+
const lienzo = document.createElement("canvas");
|
|
277
|
+
lienzo.width = Math.round(bitmap.width * escala);
|
|
278
|
+
lienzo.height = Math.round(bitmap.height * escala);
|
|
279
|
+
const ctx = lienzo.getContext("2d");
|
|
280
|
+
if (!ctx) throw new Error("El navegador no permitió procesar la imagen.");
|
|
281
|
+
ctx.fillStyle = "#ffffff";
|
|
282
|
+
ctx.fillRect(0, 0, lienzo.width, lienzo.height);
|
|
283
|
+
ctx.drawImage(bitmap, 0, 0, lienzo.width, lienzo.height);
|
|
284
|
+
return desdeLienzo(lienzo);
|
|
285
|
+
} finally {
|
|
286
|
+
bitmap.close();
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/** WebP si el navegador lo genera (Safari antiguo no): si no, JPG. */
|
|
290
|
+
async function desdeLienzo(lienzo) {
|
|
291
|
+
let blob = await aBlob(lienzo, "image/webp");
|
|
292
|
+
if (!blob || blob.type !== "image/webp") blob = await aBlob(lienzo, "image/jpeg");
|
|
293
|
+
if (!blob) throw new Error("No se pudo generar la imagen de la página.");
|
|
294
|
+
return {
|
|
295
|
+
blob,
|
|
296
|
+
ancho: lienzo.width,
|
|
297
|
+
alto: lienzo.height,
|
|
298
|
+
url: URL.createObjectURL(blob)
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
function aBlob(lienzo, tipo) {
|
|
302
|
+
return new Promise((resolve) => lienzo.toBlob(resolve, tipo, CALIDAD));
|
|
303
|
+
}
|
|
304
|
+
//#endregion
|
|
305
|
+
//#region src/lib/cartelera-vigencia.ts
|
|
306
|
+
/** Texto de vigencia de una publicación de la cartelera, p. ej. «Del 13 oct. al 31 oct. 2026». */
|
|
307
|
+
function corta(fecha) {
|
|
308
|
+
const [a = 0, m = 1, d = 1] = fecha.split("-").map(Number);
|
|
309
|
+
return new Date(a, m - 1, d).toLocaleDateString("es-CO", {
|
|
310
|
+
day: "numeric",
|
|
311
|
+
month: "short",
|
|
312
|
+
year: "numeric"
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
function textoVigencia(desde, hasta) {
|
|
316
|
+
if (!desde) return "";
|
|
317
|
+
return hasta ? `Del ${corta(desde)} al ${corta(hasta)}` : `Desde el ${corta(desde)}, sin vencimiento`;
|
|
318
|
+
}
|
|
319
|
+
function hoyIso() {
|
|
320
|
+
const h = /* @__PURE__ */ new Date();
|
|
321
|
+
return `${h.getFullYear()}-${String(h.getMonth() + 1).padStart(2, "0")}-${String(h.getDate()).padStart(2, "0")}`;
|
|
322
|
+
}
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region src/components/cartelera/PublicacionFormModal.vue?vue&type=script&setup=true&lang.ts
|
|
325
|
+
var _hoisted_1$1 = ["aria-label"];
|
|
326
|
+
var _hoisted_2$1 = { class: "modal-header" };
|
|
327
|
+
var _hoisted_3$1 = { class: "modal-title" };
|
|
328
|
+
var _hoisted_4$1 = {
|
|
329
|
+
key: 0,
|
|
330
|
+
class: "aviso-publicada"
|
|
331
|
+
};
|
|
332
|
+
var _hoisted_5$1 = { class: "modal-body" };
|
|
333
|
+
var _hoisted_6$1 = { class: "columna-form" };
|
|
334
|
+
var _hoisted_7$1 = { key: 0 };
|
|
335
|
+
var _hoisted_8$1 = { class: "zona-ayuda" };
|
|
336
|
+
var _hoisted_9$1 = { class: "toolbar" };
|
|
337
|
+
var _hoisted_10$1 = { key: 0 };
|
|
338
|
+
var _hoisted_11$1 = { key: 1 };
|
|
339
|
+
var _hoisted_12$1 = { class: "zona-ayuda" };
|
|
340
|
+
var _hoisted_13$1 = {
|
|
341
|
+
key: 2,
|
|
342
|
+
class: "zona-ayuda"
|
|
343
|
+
};
|
|
344
|
+
var _hoisted_14$1 = {
|
|
345
|
+
key: 3,
|
|
346
|
+
class: "zona-ayuda"
|
|
347
|
+
};
|
|
348
|
+
var _hoisted_15$1 = { class: "campo" };
|
|
349
|
+
var _hoisted_16$1 = ["value"];
|
|
350
|
+
var _hoisted_17$1 = ["value"];
|
|
351
|
+
var _hoisted_18$1 = { class: "campo" };
|
|
352
|
+
var _hoisted_19$1 = { class: "campo" };
|
|
353
|
+
var _hoisted_20$1 = { class: "dos" };
|
|
354
|
+
var _hoisted_21$1 = { class: "campo" };
|
|
355
|
+
var _hoisted_22$1 = { class: "campo" };
|
|
356
|
+
var _hoisted_23$1 = ["min"];
|
|
357
|
+
var _hoisted_24$1 = { class: "dos" };
|
|
358
|
+
var _hoisted_25$1 = { class: "campo" };
|
|
359
|
+
var _hoisted_26$1 = { class: "label casilla" };
|
|
360
|
+
var _hoisted_27$1 = {
|
|
361
|
+
key: 0,
|
|
362
|
+
class: "alert-error",
|
|
363
|
+
role: "alert"
|
|
364
|
+
};
|
|
365
|
+
var _hoisted_28$1 = { class: "columna-vista" };
|
|
366
|
+
var _hoisted_29$1 = ["src", "alt"];
|
|
367
|
+
var _hoisted_30$1 = { class: "modal-footer" };
|
|
368
|
+
var _hoisted_31$1 = ["disabled"];
|
|
369
|
+
var _hoisted_32 = ["disabled"];
|
|
370
|
+
//#endregion
|
|
371
|
+
//#region src/components/cartelera/PublicacionFormModal.vue
|
|
372
|
+
var PublicacionFormModal_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
|
|
373
|
+
__name: "PublicacionFormModal",
|
|
374
|
+
props: /*@__PURE__*/ mergeModels({
|
|
375
|
+
publicacion: {},
|
|
376
|
+
clientesInternos: {},
|
|
377
|
+
clienteInicial: {},
|
|
378
|
+
empresa: {}
|
|
379
|
+
}, {
|
|
380
|
+
"open": {
|
|
381
|
+
type: Boolean,
|
|
382
|
+
default: false
|
|
383
|
+
},
|
|
384
|
+
"openModifiers": {}
|
|
385
|
+
}),
|
|
386
|
+
emits: /*@__PURE__*/ mergeModels(["saved"], ["update:open"]),
|
|
387
|
+
setup(__props, { emit: __emit }) {
|
|
388
|
+
const open = useModel(__props, "open");
|
|
389
|
+
const props = __props;
|
|
390
|
+
const emit = __emit;
|
|
391
|
+
const form = reactive({
|
|
392
|
+
cliente_interno_id: null,
|
|
393
|
+
titulo: "",
|
|
394
|
+
resumen: "",
|
|
395
|
+
fecha_desde: hoyIso(),
|
|
396
|
+
fecha_hasta: "",
|
|
397
|
+
orden: 0,
|
|
398
|
+
destacada: false
|
|
399
|
+
});
|
|
400
|
+
const archivo = ref(null);
|
|
401
|
+
const paginas = ref([]);
|
|
402
|
+
const convirtiendo = ref(false);
|
|
403
|
+
const avance = ref("");
|
|
404
|
+
const arrastrando = ref(false);
|
|
405
|
+
const guardando = ref(false);
|
|
406
|
+
const error = ref(null);
|
|
407
|
+
const inputArchivo = ref(null);
|
|
408
|
+
const editando = computed(() => props.publicacion !== null);
|
|
409
|
+
const titulo = computed(() => editando.value ? "Editar publicación" : "Nueva publicación");
|
|
410
|
+
const cuantasPaginas = computed(() => archivo.value ? paginas.value.length : props.publicacion?.paginas.length ?? 0);
|
|
411
|
+
const puedeGuardar = computed(() => form.titulo.trim() !== "" && form.fecha_desde !== "" && !convirtiendo.value && cuantasPaginas.value > 0);
|
|
412
|
+
/** La publicación es de un cliente que ya no está en el catálogo: se conserva como opción para no perderlo. */
|
|
413
|
+
const clienteFueraDeLista = computed(() => form.cliente_interno_id != null && !props.clientesInternos.some((c) => c.id === form.cliente_interno_id));
|
|
414
|
+
const vistaPrevia = computed(() => [{
|
|
415
|
+
clave: "borrador",
|
|
416
|
+
titulo: form.titulo.trim(),
|
|
417
|
+
resumen: form.resumen.trim() || null,
|
|
418
|
+
destacada: form.destacada,
|
|
419
|
+
vigencia: textoVigencia(form.fecha_desde, form.fecha_hasta || null),
|
|
420
|
+
paginas: cuantasPaginas.value
|
|
421
|
+
}]);
|
|
422
|
+
watch(open, (abierto) => {
|
|
423
|
+
if (!abierto) {
|
|
424
|
+
quitarArchivo();
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
const p = props.publicacion;
|
|
428
|
+
Object.assign(form, {
|
|
429
|
+
cliente_interno_id: p ? p.cliente_interno_id : props.clienteInicial ?? null,
|
|
430
|
+
titulo: p?.titulo ?? "",
|
|
431
|
+
resumen: p?.resumen ?? "",
|
|
432
|
+
fecha_desde: p?.fecha_desde ?? hoyIso(),
|
|
433
|
+
fecha_hasta: p?.fecha_hasta ?? "",
|
|
434
|
+
orden: p?.orden ?? 0,
|
|
435
|
+
destacada: p?.destacada ?? false
|
|
436
|
+
});
|
|
437
|
+
error.value = null;
|
|
438
|
+
}, { immediate: true });
|
|
439
|
+
onBeforeUnmount(() => liberarPaginas(paginas.value));
|
|
440
|
+
function quitarArchivo() {
|
|
441
|
+
liberarPaginas(paginas.value);
|
|
442
|
+
paginas.value = [];
|
|
443
|
+
archivo.value = null;
|
|
444
|
+
avance.value = "";
|
|
445
|
+
if (inputArchivo.value) inputArchivo.value.value = "";
|
|
446
|
+
}
|
|
447
|
+
async function usarArchivo(f) {
|
|
448
|
+
if (!f) return;
|
|
449
|
+
error.value = null;
|
|
450
|
+
quitarArchivo();
|
|
451
|
+
convirtiendo.value = true;
|
|
452
|
+
avance.value = "Preparando…";
|
|
453
|
+
try {
|
|
454
|
+
const nuevas = await convertirArchivo(f, (hecho, total) => {
|
|
455
|
+
avance.value = `Convirtiendo página ${hecho} de ${total}…`;
|
|
456
|
+
});
|
|
457
|
+
archivo.value = f;
|
|
458
|
+
paginas.value = nuevas;
|
|
459
|
+
if (!form.titulo.trim()) form.titulo = f.name.replace(/\.[^.]+$/, "").replace(/[-_]+/g, " ").trim().slice(0, 200);
|
|
460
|
+
} catch (e) {
|
|
461
|
+
error.value = e instanceof Error ? e.message : "No se pudo leer el archivo.";
|
|
462
|
+
} finally {
|
|
463
|
+
convirtiendo.value = false;
|
|
464
|
+
avance.value = "";
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
function alSoltar(ev) {
|
|
468
|
+
arrastrando.value = false;
|
|
469
|
+
usarArchivo(ev.dataTransfer?.files?.[0]);
|
|
470
|
+
}
|
|
471
|
+
async function guardar() {
|
|
472
|
+
if (!puedeGuardar.value) return;
|
|
473
|
+
guardando.value = true;
|
|
474
|
+
error.value = null;
|
|
475
|
+
const payload = {
|
|
476
|
+
titulo: form.titulo.trim(),
|
|
477
|
+
resumen: form.resumen.trim(),
|
|
478
|
+
fecha_desde: form.fecha_desde,
|
|
479
|
+
fecha_hasta: form.fecha_hasta || null,
|
|
480
|
+
orden: Number(form.orden) || 0,
|
|
481
|
+
destacada: form.destacada,
|
|
482
|
+
...archivo.value ? {
|
|
483
|
+
archivo: archivo.value,
|
|
484
|
+
paginas: paginas.value.map((p) => p.blob)
|
|
485
|
+
} : {}
|
|
486
|
+
};
|
|
487
|
+
payload.cliente_interno_id = form.cliente_interno_id;
|
|
488
|
+
try {
|
|
489
|
+
const guardada = props.publicacion ? await carteleraService.actualizar(props.publicacion.id, payload) : await carteleraService.crear(payload);
|
|
490
|
+
emit("saved", guardada);
|
|
491
|
+
open.value = false;
|
|
492
|
+
} catch (e) {
|
|
493
|
+
error.value = mensajeError(e, "No se pudo guardar la publicación.");
|
|
494
|
+
} finally {
|
|
495
|
+
guardando.value = false;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
return (_ctx, _cache) => {
|
|
499
|
+
return openBlock(), createBlock(Teleport, { to: "body" }, [open.value ? (openBlock(), createElementBlock("div", {
|
|
500
|
+
key: 0,
|
|
501
|
+
class: "modal-backdrop",
|
|
502
|
+
onKeydown: _cache[14] || (_cache[14] = withKeys(($event) => open.value = false, ["esc"]))
|
|
503
|
+
}, [createElementVNode("form", {
|
|
504
|
+
class: "modal-panel",
|
|
505
|
+
role: "dialog",
|
|
506
|
+
"aria-modal": "true",
|
|
507
|
+
"aria-label": titulo.value,
|
|
508
|
+
onSubmit: withModifiers(guardar, ["prevent"])
|
|
509
|
+
}, [
|
|
510
|
+
createElementVNode("header", _hoisted_2$1, [createElementVNode("div", null, [createElementVNode("h2", _hoisted_3$1, toDisplayString(titulo.value), 1), __props.publicacion?.estado === "publicada" ? (openBlock(), createElementBlock("p", _hoisted_4$1, " Está publicada: al guardar, los empleados verán el cambio en la próxima sincronización. ")) : createCommentVNode("", true)]), createVNode(FormCloseButton, {
|
|
511
|
+
disabled: guardando.value,
|
|
512
|
+
onClick: _cache[0] || (_cache[0] = ($event) => open.value = false)
|
|
513
|
+
}, null, 8, ["disabled"])]),
|
|
514
|
+
createElementVNode("div", _hoisted_5$1, [createElementVNode("div", _hoisted_6$1, [
|
|
515
|
+
createElementVNode("div", {
|
|
516
|
+
class: normalizeClass(["zona-archivo", {
|
|
517
|
+
arrastrando: arrastrando.value,
|
|
518
|
+
ocupada: convirtiendo.value
|
|
519
|
+
}]),
|
|
520
|
+
onDragover: _cache[4] || (_cache[4] = withModifiers(($event) => arrastrando.value = true, ["prevent"])),
|
|
521
|
+
onDragleave: _cache[5] || (_cache[5] = withModifiers(($event) => arrastrando.value = false, ["prevent"])),
|
|
522
|
+
onDrop: withModifiers(alSoltar, ["prevent"])
|
|
523
|
+
}, [convirtiendo.value ? (openBlock(), createElementBlock("strong", _hoisted_7$1, toDisplayString(avance.value), 1)) : archivo.value ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
|
|
524
|
+
createElementVNode("strong", null, toDisplayString(archivo.value.name), 1),
|
|
525
|
+
createElementVNode("span", _hoisted_8$1, toDisplayString(paginas.value.length) + " " + toDisplayString(paginas.value.length === 1 ? "página lista" : "páginas listas") + " para publicar ", 1),
|
|
526
|
+
createElementVNode("span", _hoisted_9$1, [createElementVNode("button", {
|
|
527
|
+
type: "button",
|
|
528
|
+
class: "btn-link",
|
|
529
|
+
onClick: _cache[1] || (_cache[1] = ($event) => inputArchivo.value?.click())
|
|
530
|
+
}, "Cambiar archivo"), createElementVNode("button", {
|
|
531
|
+
type: "button",
|
|
532
|
+
class: "btn-link",
|
|
533
|
+
onClick: quitarArchivo
|
|
534
|
+
}, "Quitar")])
|
|
535
|
+
], 64)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [
|
|
536
|
+
editando.value ? (openBlock(), createElementBlock("strong", _hoisted_10$1, "Arrastre aquí otra imagen o PDF para reemplazar el actual")) : (openBlock(), createElementBlock("strong", _hoisted_11$1, "Arrastre aquí una imagen o un PDF")),
|
|
537
|
+
createElementVNode("span", _hoisted_12$1, " JPG, PNG, WebP o PDF de hasta " + toDisplayString(unref(20)) + " MB. Un PDF se muestra página por página (hasta " + toDisplayString(unref(30)) + "). ", 1),
|
|
538
|
+
createElementVNode("button", {
|
|
539
|
+
type: "button",
|
|
540
|
+
class: "btn-secondary",
|
|
541
|
+
onClick: _cache[2] || (_cache[2] = ($event) => inputArchivo.value?.click())
|
|
542
|
+
}, "Elegir archivo"),
|
|
543
|
+
__props.publicacion?.archivo_nombre ? (openBlock(), createElementBlock("span", _hoisted_13$1, "Actual: " + toDisplayString(__props.publicacion.archivo_nombre), 1)) : __props.publicacion?.desde_softdin ? (openBlock(), createElementBlock("span", _hoisted_14$1, " Actual: las páginas que llegaron de SoftDIN (sin archivo original). ")) : createCommentVNode("", true)
|
|
544
|
+
], 64)), createElementVNode("input", {
|
|
545
|
+
ref_key: "inputArchivo",
|
|
546
|
+
ref: inputArchivo,
|
|
547
|
+
type: "file",
|
|
548
|
+
class: "oculto",
|
|
549
|
+
"data-prueba": "archivo",
|
|
550
|
+
accept: ".pdf,.jpg,.jpeg,.png,.webp,application/pdf,image/jpeg,image/png,image/webp",
|
|
551
|
+
onChange: _cache[3] || (_cache[3] = ($event) => usarArchivo($event.target.files?.[0]))
|
|
552
|
+
}, null, 544)], 34),
|
|
553
|
+
createElementVNode("label", _hoisted_15$1, [
|
|
554
|
+
_cache[16] || (_cache[16] = createElementVNode("span", { class: "label" }, "Destinatarios", -1)),
|
|
555
|
+
withDirectives(createElementVNode("select", {
|
|
556
|
+
id: "cartelera-cliente",
|
|
557
|
+
"onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => form.cliente_interno_id = $event),
|
|
558
|
+
class: "input"
|
|
559
|
+
}, [
|
|
560
|
+
_cache[15] || (_cache[15] = createElementVNode("option", { value: null }, "Todo el tenant", -1)),
|
|
561
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.clientesInternos, (c) => {
|
|
562
|
+
return openBlock(), createElementBlock("option", {
|
|
563
|
+
key: c.id,
|
|
564
|
+
value: c.id
|
|
565
|
+
}, toDisplayString(c.nombre), 9, _hoisted_16$1);
|
|
566
|
+
}), 128)),
|
|
567
|
+
clienteFueraDeLista.value ? (openBlock(), createElementBlock("option", {
|
|
568
|
+
key: 0,
|
|
569
|
+
value: form.cliente_interno_id
|
|
570
|
+
}, "Cliente " + toDisplayString(form.cliente_interno_id), 9, _hoisted_17$1)) : createCommentVNode("", true)
|
|
571
|
+
], 512), [[vModelSelect, form.cliente_interno_id]]),
|
|
572
|
+
_cache[17] || (_cache[17] = createElementVNode("span", { class: "hint" }, "«Todo el tenant»: la ven todos los empleados. Con un cliente, solo los de ese cliente.", -1))
|
|
573
|
+
]),
|
|
574
|
+
createElementVNode("label", _hoisted_18$1, [_cache[18] || (_cache[18] = createElementVNode("span", { class: "label" }, "Título", -1)), withDirectives(createElementVNode("input", {
|
|
575
|
+
"onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => form.titulo = $event),
|
|
576
|
+
class: "input",
|
|
577
|
+
type: "text",
|
|
578
|
+
maxlength: "200",
|
|
579
|
+
required: "",
|
|
580
|
+
placeholder: "Ej.: Jornada de vacunación"
|
|
581
|
+
}, null, 512), [[vModelText, form.titulo]])]),
|
|
582
|
+
createElementVNode("label", _hoisted_19$1, [_cache[19] || (_cache[19] = createElementVNode("span", { class: "label" }, "Texto (opcional)", -1)), withDirectives(createElementVNode("textarea", {
|
|
583
|
+
"onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => form.resumen = $event),
|
|
584
|
+
class: "input",
|
|
585
|
+
rows: "3",
|
|
586
|
+
maxlength: "5000",
|
|
587
|
+
placeholder: "Lo que el empleado lee encima de la imagen."
|
|
588
|
+
}, null, 512), [[vModelText, form.resumen]])]),
|
|
589
|
+
createElementVNode("div", _hoisted_20$1, [createElementVNode("label", _hoisted_21$1, [_cache[20] || (_cache[20] = createElementVNode("span", { class: "label" }, "Visible desde", -1)), withDirectives(createElementVNode("input", {
|
|
590
|
+
"onUpdate:modelValue": _cache[9] || (_cache[9] = ($event) => form.fecha_desde = $event),
|
|
591
|
+
class: "input",
|
|
592
|
+
type: "date",
|
|
593
|
+
required: ""
|
|
594
|
+
}, null, 512), [[vModelText, form.fecha_desde]])]), createElementVNode("label", _hoisted_22$1, [_cache[21] || (_cache[21] = createElementVNode("span", { class: "label" }, "Hasta (opcional)", -1)), withDirectives(createElementVNode("input", {
|
|
595
|
+
"onUpdate:modelValue": _cache[10] || (_cache[10] = ($event) => form.fecha_hasta = $event),
|
|
596
|
+
class: "input",
|
|
597
|
+
type: "date",
|
|
598
|
+
min: form.fecha_desde
|
|
599
|
+
}, null, 8, _hoisted_23$1), [[vModelText, form.fecha_hasta]])])]),
|
|
600
|
+
createElementVNode("div", _hoisted_24$1, [createElementVNode("label", _hoisted_25$1, [
|
|
601
|
+
_cache[22] || (_cache[22] = createElementVNode("span", { class: "label" }, "Orden", -1)),
|
|
602
|
+
withDirectives(createElementVNode("input", {
|
|
603
|
+
"onUpdate:modelValue": _cache[11] || (_cache[11] = ($event) => form.orden = $event),
|
|
604
|
+
class: "input",
|
|
605
|
+
type: "number",
|
|
606
|
+
min: "0",
|
|
607
|
+
max: "65535"
|
|
608
|
+
}, null, 512), [[
|
|
609
|
+
vModelText,
|
|
610
|
+
form.orden,
|
|
611
|
+
void 0,
|
|
612
|
+
{ number: true }
|
|
613
|
+
]]),
|
|
614
|
+
_cache[23] || (_cache[23] = createElementVNode("span", { class: "hint" }, "Menor número, más arriba.", -1))
|
|
615
|
+
]), createElementVNode("label", _hoisted_26$1, [withDirectives(createElementVNode("input", {
|
|
616
|
+
"onUpdate:modelValue": _cache[12] || (_cache[12] = ($event) => form.destacada = $event),
|
|
617
|
+
type: "checkbox"
|
|
618
|
+
}, null, 512), [[vModelCheckbox, form.destacada]]), _cache[24] || (_cache[24] = createTextVNode(" Destacada (va de primera, resaltada) ", -1))])]),
|
|
619
|
+
error.value ? (openBlock(), createElementBlock("p", _hoisted_27$1, toDisplayString(error.value), 1)) : createCommentVNode("", true)
|
|
620
|
+
]), createElementVNode("aside", _hoisted_28$1, [_cache[25] || (_cache[25] = createElementVNode("p", { class: "vista-titulo" }, "Así la verá el empleado", -1)), createVNode(VistaCelularCartelera_default, {
|
|
621
|
+
tarjetas: vistaPrevia.value,
|
|
622
|
+
empresa: __props.empresa
|
|
623
|
+
}, {
|
|
624
|
+
pagina: withCtx(({ n }) => [archivo.value && paginas.value[n - 1] ? (openBlock(), createElementBlock("img", {
|
|
625
|
+
key: 0,
|
|
626
|
+
src: paginas.value[n - 1].url,
|
|
627
|
+
alt: `Página ${n}`,
|
|
628
|
+
class: "pagina"
|
|
629
|
+
}, null, 8, _hoisted_29$1)) : __props.publicacion ? (openBlock(), createBlock(PaginaCarteleraImagen_default, {
|
|
630
|
+
key: 1,
|
|
631
|
+
"publicacion-id": __props.publicacion.id,
|
|
632
|
+
n,
|
|
633
|
+
version: __props.publicacion.actualizada,
|
|
634
|
+
alt: `Página ${n}`
|
|
635
|
+
}, null, 8, [
|
|
636
|
+
"publicacion-id",
|
|
637
|
+
"n",
|
|
638
|
+
"version",
|
|
639
|
+
"alt"
|
|
640
|
+
])) : createCommentVNode("", true)]),
|
|
641
|
+
_: 1
|
|
642
|
+
}, 8, ["tarjetas", "empresa"])])]),
|
|
643
|
+
createElementVNode("footer", _hoisted_30$1, [createElementVNode("button", {
|
|
644
|
+
type: "button",
|
|
645
|
+
class: "btn-secondary",
|
|
646
|
+
disabled: guardando.value,
|
|
647
|
+
onClick: _cache[13] || (_cache[13] = ($event) => open.value = false)
|
|
648
|
+
}, "Cancelar", 8, _hoisted_31$1), createElementVNode("button", {
|
|
649
|
+
type: "submit",
|
|
650
|
+
class: "btn-primary",
|
|
651
|
+
disabled: guardando.value || !puedeGuardar.value
|
|
652
|
+
}, toDisplayString(guardando.value ? "Guardando…" : "Guardar"), 9, _hoisted_32)])
|
|
653
|
+
], 40, _hoisted_1$1)], 32)) : createCommentVNode("", true)]);
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
}), [["__scopeId", "data-v-aaaf3e43"]]);
|
|
657
|
+
//#endregion
|
|
658
|
+
//#region src/views/CarteleraView.vue?vue&type=script&setup=true&lang.ts
|
|
659
|
+
var _hoisted_1 = { class: "page-shell" };
|
|
660
|
+
var _hoisted_2 = { class: "page-header" };
|
|
661
|
+
var _hoisted_3 = { class: "toolbar" };
|
|
662
|
+
var _hoisted_4 = ["disabled"];
|
|
663
|
+
var _hoisted_5 = {
|
|
664
|
+
key: 0,
|
|
665
|
+
class: "panel-muted aviso",
|
|
666
|
+
role: "status"
|
|
667
|
+
};
|
|
668
|
+
var _hoisted_6 = {
|
|
669
|
+
key: 1,
|
|
670
|
+
class: "panel-error",
|
|
671
|
+
role: "alert"
|
|
672
|
+
};
|
|
673
|
+
var _hoisted_7 = { class: "toolbar" };
|
|
674
|
+
var _hoisted_8 = { class: "distribucion" };
|
|
675
|
+
var _hoisted_9 = { class: "listado" };
|
|
676
|
+
var _hoisted_10 = {
|
|
677
|
+
key: 0,
|
|
678
|
+
class: "panel-muted"
|
|
679
|
+
};
|
|
680
|
+
var _hoisted_11 = {
|
|
681
|
+
key: 1,
|
|
682
|
+
class: "vacio"
|
|
683
|
+
};
|
|
684
|
+
var _hoisted_12 = {
|
|
685
|
+
key: 2,
|
|
686
|
+
class: "panel-muted"
|
|
687
|
+
};
|
|
688
|
+
var _hoisted_13 = ["data-publicacion"];
|
|
689
|
+
var _hoisted_14 = { class: "pub-miniatura" };
|
|
690
|
+
var _hoisted_15 = {
|
|
691
|
+
key: 1,
|
|
692
|
+
class: "pub-paginas"
|
|
693
|
+
};
|
|
694
|
+
var _hoisted_16 = { class: "pub-cuerpo" };
|
|
695
|
+
var _hoisted_17 = { class: "toolbar" };
|
|
696
|
+
var _hoisted_18 = { class: "panel-title pub-titulo" };
|
|
697
|
+
var _hoisted_19 = {
|
|
698
|
+
key: 0,
|
|
699
|
+
class: "estado estado-destacada"
|
|
700
|
+
};
|
|
701
|
+
var _hoisted_20 = ["title"];
|
|
702
|
+
var _hoisted_21 = {
|
|
703
|
+
key: 1,
|
|
704
|
+
class: "estado estado-neutro",
|
|
705
|
+
title: "Se armó en SoftDIN antes de que la cartelera pasara al portal: no tiene archivo original"
|
|
706
|
+
};
|
|
707
|
+
var _hoisted_22 = {
|
|
708
|
+
key: 0,
|
|
709
|
+
class: "pub-resumen"
|
|
710
|
+
};
|
|
711
|
+
var _hoisted_23 = { class: "sub" };
|
|
712
|
+
var _hoisted_24 = { class: "toolbar" };
|
|
713
|
+
var _hoisted_25 = ["disabled", "onClick"];
|
|
714
|
+
var _hoisted_26 = ["disabled", "onClick"];
|
|
715
|
+
var _hoisted_27 = ["disabled", "onClick"];
|
|
716
|
+
var _hoisted_28 = ["disabled", "onClick"];
|
|
717
|
+
var _hoisted_29 = ["disabled", "onClick"];
|
|
718
|
+
var _hoisted_30 = { class: "lateral" };
|
|
719
|
+
var _hoisted_31 = { class: "sub lateral-nota" };
|
|
720
|
+
//#endregion
|
|
721
|
+
//#region src/views/CarteleraView.vue
|
|
722
|
+
var CarteleraView_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
|
|
723
|
+
__name: "CarteleraView",
|
|
724
|
+
setup(__props) {
|
|
725
|
+
const auth = useAuthStore();
|
|
726
|
+
const clientesInternos = useClienteInternoStore();
|
|
727
|
+
const publicaciones = ref([]);
|
|
728
|
+
const cargando = ref(false);
|
|
729
|
+
const error = ref(null);
|
|
730
|
+
const aviso = ref(null);
|
|
731
|
+
const accionEnCurso = ref(null);
|
|
732
|
+
const modalAbierto = ref(false);
|
|
733
|
+
const editando = ref(null);
|
|
734
|
+
/** Filtro de la lista: null, todos. */
|
|
735
|
+
const filtroEstado = ref(null);
|
|
736
|
+
const filtroCliente = computed(() => clientesInternos.seleccionado);
|
|
737
|
+
const empresa = computed(() => auth.cliente?.nombre ?? "");
|
|
738
|
+
const ETIQUETAS = {
|
|
739
|
+
borrador: "Borrador",
|
|
740
|
+
publicada: "Publicada",
|
|
741
|
+
retirada: "Retirada"
|
|
742
|
+
};
|
|
743
|
+
function vigente(p) {
|
|
744
|
+
const hoy = hoyIso();
|
|
745
|
+
return p.estado === "publicada" && p.fecha_desde <= hoy && (p.fecha_hasta === null || p.fecha_hasta >= hoy);
|
|
746
|
+
}
|
|
747
|
+
function etiquetaEstado(p) {
|
|
748
|
+
if (p.estado !== "publicada") return ETIQUETAS[p.estado];
|
|
749
|
+
if (p.fecha_desde > hoyIso()) return "Programada";
|
|
750
|
+
if (p.fecha_hasta !== null && p.fecha_hasta < hoyIso()) return "Vencida";
|
|
751
|
+
return "Publicada";
|
|
752
|
+
}
|
|
753
|
+
const CLASE_ESTADO = {
|
|
754
|
+
Publicada: "estado-ok",
|
|
755
|
+
Programada: "estado-info",
|
|
756
|
+
Borrador: "estado-alerta",
|
|
757
|
+
Vencida: "estado-neutro",
|
|
758
|
+
Retirada: "estado-neutro"
|
|
759
|
+
};
|
|
760
|
+
const nombreCliente = (id) => clientesInternos.nombre(id);
|
|
761
|
+
const PESO_ESTADO = {
|
|
762
|
+
publicada: 0,
|
|
763
|
+
borrador: 1,
|
|
764
|
+
retirada: 2
|
|
765
|
+
};
|
|
766
|
+
const comoLaApp = (a, b) => Number(b.destacada) - Number(a.destacada) || a.orden - b.orden || b.fecha_desde.localeCompare(a.fecha_desde) || b.id - a.id;
|
|
767
|
+
/** Publicadas, luego borradores y retiradas; dentro de cada grupo, como las ordena la app. */
|
|
768
|
+
const ordenadas = computed(() => publicaciones.value.filter((p) => filtroEstado.value === null || p.estado === filtroEstado.value).filter((p) => filtroCliente.value === null || p.cliente_interno_id === filtroCliente.value).sort((a, b) => PESO_ESTADO[a.estado] - PESO_ESTADO[b.estado] || comoLaApp(a, b)));
|
|
769
|
+
/** Lo que hoy ve el empleado, en el mismo orden que la app: con un cliente filtrado, las generales y las de ese cliente. */
|
|
770
|
+
const enCartelera = computed(() => publicaciones.value.filter(vigente).filter((p) => filtroCliente.value === null || p.cliente_interno_id === null || p.cliente_interno_id === filtroCliente.value).sort(comoLaApp));
|
|
771
|
+
const tarjetasCelular = computed(() => enCartelera.value.map((p) => ({
|
|
772
|
+
clave: p.id,
|
|
773
|
+
titulo: p.titulo,
|
|
774
|
+
resumen: p.resumen,
|
|
775
|
+
destacada: p.destacada,
|
|
776
|
+
vigencia: textoVigencia(p.fecha_desde, p.fecha_hasta),
|
|
777
|
+
paginas: p.paginas.length
|
|
778
|
+
})));
|
|
779
|
+
async function cargar() {
|
|
780
|
+
cargando.value = true;
|
|
781
|
+
error.value = null;
|
|
782
|
+
try {
|
|
783
|
+
publicaciones.value = await carteleraService.listar();
|
|
784
|
+
} catch (e) {
|
|
785
|
+
error.value = mensajeError(e, "No se pudo cargar la cartelera.");
|
|
786
|
+
} finally {
|
|
787
|
+
cargando.value = false;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
function nueva() {
|
|
791
|
+
editando.value = null;
|
|
792
|
+
modalAbierto.value = true;
|
|
793
|
+
}
|
|
794
|
+
function editar(p) {
|
|
795
|
+
editando.value = p;
|
|
796
|
+
modalAbierto.value = true;
|
|
797
|
+
}
|
|
798
|
+
function reemplazar(p) {
|
|
799
|
+
const i = publicaciones.value.findIndex((x) => x.id === p.id);
|
|
800
|
+
if (i >= 0) publicaciones.value.splice(i, 1, p);
|
|
801
|
+
else publicaciones.value.unshift(p);
|
|
802
|
+
}
|
|
803
|
+
function guardada(p) {
|
|
804
|
+
reemplazar(p);
|
|
805
|
+
error.value = null;
|
|
806
|
+
aviso.value = p.estado === "publicada" ? "Cambios guardados: los empleados los verán en la próxima sincronización de la app." : "Guardada como borrador. Publíquela para que la vean los empleados.";
|
|
807
|
+
}
|
|
808
|
+
async function ejecutar(p, accion, falla) {
|
|
809
|
+
accionEnCurso.value = p.id;
|
|
810
|
+
aviso.value = null;
|
|
811
|
+
error.value = null;
|
|
812
|
+
try {
|
|
813
|
+
await accion();
|
|
814
|
+
} catch (e) {
|
|
815
|
+
error.value = mensajeError(e, falla);
|
|
816
|
+
} finally {
|
|
817
|
+
accionEnCurso.value = null;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
function publicar(p) {
|
|
821
|
+
return ejecutar(p, async () => {
|
|
822
|
+
reemplazar(await carteleraService.publicar(p.id));
|
|
823
|
+
aviso.value = `«${p.titulo}» quedó publicada: los empleados la verán en la próxima sincronización de la app.`;
|
|
824
|
+
}, "No se pudo publicar.");
|
|
825
|
+
}
|
|
826
|
+
function retirar(p) {
|
|
827
|
+
if (!window.confirm(`¿Retirar «${p.titulo}» de la cartelera? Los empleados dejarán de verla.`)) return Promise.resolve();
|
|
828
|
+
return ejecutar(p, async () => {
|
|
829
|
+
reemplazar(await carteleraService.retirar(p.id));
|
|
830
|
+
aviso.value = `«${p.titulo}» se retiró de la cartelera.`;
|
|
831
|
+
}, "No se pudo retirar.");
|
|
832
|
+
}
|
|
833
|
+
function eliminar(p) {
|
|
834
|
+
const extra = p.estado === "publicada" ? " También se quita de la cartelera de los empleados." : "";
|
|
835
|
+
if (!window.confirm(`¿Eliminar «${p.titulo}»?${extra}`)) return Promise.resolve();
|
|
836
|
+
return ejecutar(p, async () => {
|
|
837
|
+
await carteleraService.eliminar(p.id);
|
|
838
|
+
publicaciones.value = publicaciones.value.filter((x) => x.id !== p.id);
|
|
839
|
+
aviso.value = `«${p.titulo}» se eliminó.`;
|
|
840
|
+
}, "No se pudo eliminar.");
|
|
841
|
+
}
|
|
842
|
+
function descargar(p) {
|
|
843
|
+
return ejecutar(p, async () => {
|
|
844
|
+
const url = URL.createObjectURL(await carteleraService.archivo(p.id));
|
|
845
|
+
const a = document.createElement("a");
|
|
846
|
+
a.href = url;
|
|
847
|
+
a.download = p.archivo_nombre ?? `cartelera-${p.id}`;
|
|
848
|
+
a.click();
|
|
849
|
+
URL.revokeObjectURL(url);
|
|
850
|
+
}, "No se pudo descargar el archivo.");
|
|
851
|
+
}
|
|
852
|
+
onMounted(() => void cargar());
|
|
853
|
+
return (_ctx, _cache) => {
|
|
854
|
+
return openBlock(), createElementBlock("section", _hoisted_1, [
|
|
855
|
+
createElementVNode("header", _hoisted_2, [_cache[2] || (_cache[2] = createElementVNode("div", null, [createElementVNode("h1", { class: "page-title" }, "Cartelera"), createElementVNode("p", { class: "page-subtitle" }, " Es la página de entrada de la app «Portal de autogestión»: lo que los empleados ven al abrirla. Suba una imagen o un PDF, elija si es para todo el tenant o para los empleados de un cliente, revise cómo se verá en el celular y publíquela. ")], -1)), createElementVNode("div", _hoisted_3, [createElementVNode("button", {
|
|
856
|
+
type: "button",
|
|
857
|
+
class: "btn-secondary",
|
|
858
|
+
disabled: cargando.value,
|
|
859
|
+
onClick: cargar
|
|
860
|
+
}, "Actualizar", 8, _hoisted_4), createElementVNode("button", {
|
|
861
|
+
type: "button",
|
|
862
|
+
class: "btn-primary",
|
|
863
|
+
onClick: nueva
|
|
864
|
+
}, "Nueva publicación")])]),
|
|
865
|
+
aviso.value ? (openBlock(), createElementBlock("p", _hoisted_5, toDisplayString(aviso.value), 1)) : createCommentVNode("", true),
|
|
866
|
+
error.value ? (openBlock(), createElementBlock("p", _hoisted_6, toDisplayString(error.value), 1)) : createCommentVNode("", true),
|
|
867
|
+
createElementVNode("div", _hoisted_7, [_cache[4] || (_cache[4] = createElementVNode("label", {
|
|
868
|
+
for: "cartelera-filtro-estado",
|
|
869
|
+
class: "label"
|
|
870
|
+
}, "Estado", -1)), withDirectives(createElementVNode("select", {
|
|
871
|
+
id: "cartelera-filtro-estado",
|
|
872
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => filtroEstado.value = $event),
|
|
873
|
+
class: "input"
|
|
874
|
+
}, [..._cache[3] || (_cache[3] = [
|
|
875
|
+
createElementVNode("option", { value: null }, "Todos", -1),
|
|
876
|
+
createElementVNode("option", { value: "publicada" }, "Publicadas", -1),
|
|
877
|
+
createElementVNode("option", { value: "borrador" }, "Borradores", -1),
|
|
878
|
+
createElementVNode("option", { value: "retirada" }, "Retiradas", -1)
|
|
879
|
+
])], 512), [[vModelSelect, filtroEstado.value]])]),
|
|
880
|
+
createElementVNode("div", _hoisted_8, [createElementVNode("div", _hoisted_9, [cargando.value && publicaciones.value.length === 0 ? (openBlock(), createElementBlock("p", _hoisted_10, "Cargando publicaciones…")) : publicaciones.value.length === 0 ? (openBlock(), createElementBlock("div", _hoisted_11, [
|
|
881
|
+
_cache[5] || (_cache[5] = createElementVNode("p", { class: "panel-title" }, "La cartelera está vacía", -1)),
|
|
882
|
+
_cache[6] || (_cache[6] = createElementVNode("p", { class: "panel-muted" }, "Cree la primera publicación: un afiche, un boletín en PDF, una invitación…", -1)),
|
|
883
|
+
createElementVNode("button", {
|
|
884
|
+
type: "button",
|
|
885
|
+
class: "btn-primary",
|
|
886
|
+
onClick: nueva
|
|
887
|
+
}, "Nueva publicación")
|
|
888
|
+
])) : ordenadas.value.length === 0 ? (openBlock(), createElementBlock("p", _hoisted_12, "Ninguna publicación coincide con el filtro.")) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(ordenadas.value, (p) => {
|
|
889
|
+
return openBlock(), createElementBlock("article", {
|
|
890
|
+
key: p.id,
|
|
891
|
+
class: normalizeClass(["panel pub", `pub-${p.estado}`]),
|
|
892
|
+
"data-publicacion": p.id
|
|
893
|
+
}, [createElementVNode("div", _hoisted_14, [p.paginas.length > 0 ? (openBlock(), createBlock(PaginaCarteleraImagen_default, {
|
|
894
|
+
key: 0,
|
|
895
|
+
"publicacion-id": p.id,
|
|
896
|
+
n: 1,
|
|
897
|
+
version: p.actualizada,
|
|
898
|
+
alt: p.titulo
|
|
899
|
+
}, null, 8, [
|
|
900
|
+
"publicacion-id",
|
|
901
|
+
"version",
|
|
902
|
+
"alt"
|
|
903
|
+
])) : createCommentVNode("", true), p.paginas.length > 1 ? (openBlock(), createElementBlock("span", _hoisted_15, toDisplayString(p.paginas.length) + " págs.", 1)) : createCommentVNode("", true)]), createElementVNode("div", _hoisted_16, [
|
|
904
|
+
createElementVNode("div", _hoisted_17, [
|
|
905
|
+
createElementVNode("h2", _hoisted_18, toDisplayString(p.titulo), 1),
|
|
906
|
+
createElementVNode("span", { class: normalizeClass(["estado", CLASE_ESTADO[etiquetaEstado(p)]]) }, toDisplayString(etiquetaEstado(p)), 3),
|
|
907
|
+
p.destacada ? (openBlock(), createElementBlock("span", _hoisted_19, "Destacada")) : createCommentVNode("", true),
|
|
908
|
+
createElementVNode("span", {
|
|
909
|
+
class: "estado estado-cliente",
|
|
910
|
+
title: p.cliente_interno_id ? "Solo la ven los empleados de este cliente" : "La ven todos los empleados"
|
|
911
|
+
}, toDisplayString(p.cliente_interno_id ? nombreCliente(p.cliente_interno_id) : "Todo el tenant"), 9, _hoisted_20),
|
|
912
|
+
p.desde_softdin && !p.tiene_original ? (openBlock(), createElementBlock("span", _hoisted_21, " Viene de SoftDIN ")) : createCommentVNode("", true)
|
|
913
|
+
]),
|
|
914
|
+
p.resumen ? (openBlock(), createElementBlock("p", _hoisted_22, toDisplayString(p.resumen), 1)) : createCommentVNode("", true),
|
|
915
|
+
createElementVNode("p", _hoisted_23, [
|
|
916
|
+
createTextVNode(toDisplayString(unref(textoVigencia)(p.fecha_desde, p.fecha_hasta)) + " ", 1),
|
|
917
|
+
p.tipo_archivo ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(" · " + toDisplayString(p.tipo_archivo === "pdf" ? "PDF" : "Imagen"), 1)], 64)) : createCommentVNode("", true),
|
|
918
|
+
createTextVNode(" · Orden " + toDisplayString(p.orden), 1)
|
|
919
|
+
]),
|
|
920
|
+
createElementVNode("div", _hoisted_24, [
|
|
921
|
+
p.estado !== "publicada" ? (openBlock(), createElementBlock("button", {
|
|
922
|
+
key: 0,
|
|
923
|
+
type: "button",
|
|
924
|
+
class: "btn-primary",
|
|
925
|
+
disabled: accionEnCurso.value === p.id,
|
|
926
|
+
onClick: ($event) => publicar(p)
|
|
927
|
+
}, " Publicar ", 8, _hoisted_25)) : (openBlock(), createElementBlock("button", {
|
|
928
|
+
key: 1,
|
|
929
|
+
type: "button",
|
|
930
|
+
class: "btn-secondary",
|
|
931
|
+
disabled: accionEnCurso.value === p.id,
|
|
932
|
+
onClick: ($event) => retirar(p)
|
|
933
|
+
}, " Retirar ", 8, _hoisted_26)),
|
|
934
|
+
createElementVNode("button", {
|
|
935
|
+
type: "button",
|
|
936
|
+
class: "btn-secondary",
|
|
937
|
+
disabled: accionEnCurso.value === p.id,
|
|
938
|
+
onClick: ($event) => editar(p)
|
|
939
|
+
}, "Editar", 8, _hoisted_27),
|
|
940
|
+
p.tiene_original ? (openBlock(), createElementBlock("button", {
|
|
941
|
+
key: 2,
|
|
942
|
+
type: "button",
|
|
943
|
+
class: "btn-secondary",
|
|
944
|
+
disabled: accionEnCurso.value === p.id,
|
|
945
|
+
onClick: ($event) => descargar(p)
|
|
946
|
+
}, " Descargar original ", 8, _hoisted_28)) : createCommentVNode("", true),
|
|
947
|
+
createElementVNode("button", {
|
|
948
|
+
type: "button",
|
|
949
|
+
class: "btn-danger",
|
|
950
|
+
disabled: accionEnCurso.value === p.id,
|
|
951
|
+
onClick: ($event) => eliminar(p)
|
|
952
|
+
}, "Eliminar", 8, _hoisted_29)
|
|
953
|
+
])
|
|
954
|
+
])], 10, _hoisted_13);
|
|
955
|
+
}), 128))]), createElementVNode("aside", _hoisted_30, [
|
|
956
|
+
_cache[8] || (_cache[8] = createElementVNode("p", { class: "panel-title lateral-titulo" }, "Hoy en la cartelera", -1)),
|
|
957
|
+
createVNode(VistaCelularCartelera_default, {
|
|
958
|
+
tarjetas: tarjetasCelular.value,
|
|
959
|
+
empresa: empresa.value
|
|
960
|
+
}, {
|
|
961
|
+
pagina: withCtx(({ tarjeta, n }) => [createVNode(PaginaCarteleraImagen_default, {
|
|
962
|
+
"publicacion-id": Number(tarjeta.clave),
|
|
963
|
+
n,
|
|
964
|
+
version: enCartelera.value.find((x) => x.id === tarjeta.clave)?.actualizada ?? null,
|
|
965
|
+
alt: `${tarjeta.titulo}, página ${n}`
|
|
966
|
+
}, null, 8, [
|
|
967
|
+
"publicacion-id",
|
|
968
|
+
"n",
|
|
969
|
+
"version",
|
|
970
|
+
"alt"
|
|
971
|
+
])]),
|
|
972
|
+
_: 1
|
|
973
|
+
}, 8, ["tarjetas", "empresa"]),
|
|
974
|
+
createElementVNode("p", _hoisted_31, [_cache[7] || (_cache[7] = createTextVNode(" Solo aparecen las publicadas y vigentes hoy, en el orden en que las ve el empleado. ", -1)), filtroCliente.value === null ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(" Aquí salen las de todos los clientes: cada empleado ve las de todo el tenant y las de su cliente. ")], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode("Es lo que ve un empleado de " + toDisplayString(nombreCliente(filtroCliente.value)) + ".", 1)], 64))])
|
|
975
|
+
])]),
|
|
976
|
+
createVNode(PublicacionFormModal_default, {
|
|
977
|
+
open: modalAbierto.value,
|
|
978
|
+
"onUpdate:open": _cache[1] || (_cache[1] = ($event) => modalAbierto.value = $event),
|
|
979
|
+
publicacion: editando.value,
|
|
980
|
+
"clientes-internos": unref(clientesInternos).lista,
|
|
981
|
+
"cliente-inicial": filtroCliente.value,
|
|
982
|
+
empresa: empresa.value,
|
|
983
|
+
onSaved: guardada
|
|
984
|
+
}, null, 8, [
|
|
985
|
+
"open",
|
|
986
|
+
"publicacion",
|
|
987
|
+
"clientes-internos",
|
|
988
|
+
"cliente-inicial",
|
|
989
|
+
"empresa"
|
|
990
|
+
])
|
|
991
|
+
]);
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
}), [["__scopeId", "data-v-40dc441b"]]);
|
|
995
|
+
//#endregion
|
|
996
|
+
export { CarteleraView_default as default };
|