@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,280 @@
|
|
|
1
|
+
import { t as useClienteInternoStore } from "./cliente-interno.store-De39VsEE.js";
|
|
2
|
+
import { t as RUTAS_PORTAL } from "./tipos-D93bLfFC.js";
|
|
3
|
+
import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper-BOaGB7Aw.js";
|
|
4
|
+
import { a as duracion, i as chatService, r as MOTIVOS_ESCALAMIENTO } from "./chat.service-C7ZQf4w3.js";
|
|
5
|
+
import { t as mensajeError } from "./apiError-BHGbwz97.js";
|
|
6
|
+
import { Fragment, computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, onMounted, openBlock, ref, renderList, toDisplayString, unref, vModelText, watch, withCtx, withDirectives, withModifiers } from "vue";
|
|
7
|
+
import { RouterLink } from "vue-router";
|
|
8
|
+
//#region src/views/chat/ChatInformeView.vue?vue&type=script&setup=true&lang.ts
|
|
9
|
+
var _hoisted_1 = { class: "page-shell" };
|
|
10
|
+
var _hoisted_2 = { class: "page-subtitle" };
|
|
11
|
+
var _hoisted_3 = ["disabled"];
|
|
12
|
+
var _hoisted_4 = {
|
|
13
|
+
key: 0,
|
|
14
|
+
class: "panel-error",
|
|
15
|
+
role: "alert"
|
|
16
|
+
};
|
|
17
|
+
var _hoisted_5 = {
|
|
18
|
+
key: 1,
|
|
19
|
+
class: "panel-muted"
|
|
20
|
+
};
|
|
21
|
+
var _hoisted_6 = { class: "cifras" };
|
|
22
|
+
var _hoisted_7 = { class: "cifra-titulo" };
|
|
23
|
+
var _hoisted_8 = { class: "cifra-valor" };
|
|
24
|
+
var _hoisted_9 = { class: "panel-muted" };
|
|
25
|
+
var _hoisted_10 = {
|
|
26
|
+
key: 0,
|
|
27
|
+
class: "panel-error",
|
|
28
|
+
role: "alert"
|
|
29
|
+
};
|
|
30
|
+
var _hoisted_11 = { class: "columnas" };
|
|
31
|
+
var _hoisted_12 = { class: "panel" };
|
|
32
|
+
var _hoisted_13 = { class: "data-table" };
|
|
33
|
+
var _hoisted_14 = { class: "panel" };
|
|
34
|
+
var _hoisted_15 = {
|
|
35
|
+
key: 0,
|
|
36
|
+
class: "panel-muted"
|
|
37
|
+
};
|
|
38
|
+
var _hoisted_16 = {
|
|
39
|
+
key: 1,
|
|
40
|
+
class: "data-table"
|
|
41
|
+
};
|
|
42
|
+
var _hoisted_17 = { scope: "row" };
|
|
43
|
+
var _hoisted_18 = { class: "num" };
|
|
44
|
+
var _hoisted_19 = { class: "num" };
|
|
45
|
+
var _hoisted_20 = { class: "panel" };
|
|
46
|
+
var _hoisted_21 = { class: "table-wrap" };
|
|
47
|
+
var _hoisted_22 = { class: "data-table" };
|
|
48
|
+
var _hoisted_23 = { scope: "row" };
|
|
49
|
+
var _hoisted_24 = { class: "num" };
|
|
50
|
+
var _hoisted_25 = { class: "num" };
|
|
51
|
+
var _hoisted_26 = { class: "num" };
|
|
52
|
+
var _hoisted_27 = { class: "num" };
|
|
53
|
+
var _hoisted_28 = { key: 0 };
|
|
54
|
+
var _hoisted_29 = {
|
|
55
|
+
key: 1,
|
|
56
|
+
class: "panel"
|
|
57
|
+
};
|
|
58
|
+
var _hoisted_30 = { class: "table-wrap" };
|
|
59
|
+
var _hoisted_31 = { class: "data-table" };
|
|
60
|
+
var _hoisted_32 = { scope: "row" };
|
|
61
|
+
var _hoisted_33 = { class: "num" };
|
|
62
|
+
var _hoisted_34 = { class: "num" };
|
|
63
|
+
var _hoisted_35 = { class: "num" };
|
|
64
|
+
var _hoisted_36 = { class: "num" };
|
|
65
|
+
var _hoisted_37 = { key: 0 };
|
|
66
|
+
var _hoisted_38 = { class: "columnas" };
|
|
67
|
+
var _hoisted_39 = { class: "panel" };
|
|
68
|
+
var _hoisted_40 = { class: "data-table" };
|
|
69
|
+
var _hoisted_41 = { scope: "row" };
|
|
70
|
+
var _hoisted_42 = { class: "num" };
|
|
71
|
+
var _hoisted_43 = { class: "num" };
|
|
72
|
+
var _hoisted_44 = { class: "panel" };
|
|
73
|
+
var _hoisted_45 = { class: "data-table" };
|
|
74
|
+
var _hoisted_46 = { class: "num" };
|
|
75
|
+
var _hoisted_47 = { class: "num" };
|
|
76
|
+
var _hoisted_48 = { class: "num" };
|
|
77
|
+
var _hoisted_49 = { class: "num" };
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/views/chat/ChatInformeView.vue
|
|
80
|
+
var ChatInformeView_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
|
|
81
|
+
__name: "ChatInformeView",
|
|
82
|
+
setup(__props) {
|
|
83
|
+
const clientesInternos = useClienteInternoStore();
|
|
84
|
+
const hoy = /* @__PURE__ */ new Date();
|
|
85
|
+
const iso = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
86
|
+
const hasta = ref(iso(hoy));
|
|
87
|
+
const desde = ref(iso(new Date(hoy.getFullYear(), hoy.getMonth(), hoy.getDate() - 29)));
|
|
88
|
+
const informe = ref(null);
|
|
89
|
+
const cargando = ref(true);
|
|
90
|
+
const error = ref(null);
|
|
91
|
+
const pct = (n, total) => total ? `${Math.round(n * 100 / total)} %` : "—";
|
|
92
|
+
const nota = (n) => n === null ? "—" : n.toLocaleString("es-CO", { maximumFractionDigits: 2 });
|
|
93
|
+
const tarjetas = computed(() => {
|
|
94
|
+
const i = informe.value;
|
|
95
|
+
if (!i) return [];
|
|
96
|
+
return [
|
|
97
|
+
{
|
|
98
|
+
titulo: "Conversaciones",
|
|
99
|
+
valor: String(i.total),
|
|
100
|
+
detalle: `${i.escaladas} pasaron a RRHH`
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
titulo: "Resueltas por el asistente",
|
|
104
|
+
valor: String(i.resueltas_por_ia),
|
|
105
|
+
detalle: pct(i.resueltas_por_ia, i.total) + " del total"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
titulo: "Primera respuesta (mediana)",
|
|
109
|
+
valor: duracion(i.primera_respuesta.mediana),
|
|
110
|
+
detalle: i.primera_respuesta.dentro_del_plazo === null ? "sin respuestas en el rango" : `${i.primera_respuesta.dentro_del_plazo} % dentro del plazo`
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
titulo: "Calificación",
|
|
114
|
+
valor: i.calificacion.promedio === null ? "—" : `${nota(i.calificacion.promedio)} / 5`,
|
|
115
|
+
detalle: `${i.calificacion.respuestas} ${i.calificacion.respuestas === 1 ? "respuesta" : "respuestas"}`
|
|
116
|
+
}
|
|
117
|
+
];
|
|
118
|
+
});
|
|
119
|
+
async function cargar() {
|
|
120
|
+
cargando.value = true;
|
|
121
|
+
error.value = null;
|
|
122
|
+
try {
|
|
123
|
+
informe.value = await chatService.informe(desde.value, hasta.value, clientesInternos.seleccionado);
|
|
124
|
+
} catch (e) {
|
|
125
|
+
error.value = mensajeError(e, "No se pudo calcular el informe.");
|
|
126
|
+
} finally {
|
|
127
|
+
cargando.value = false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
watch(() => clientesInternos.seleccionado, () => void cargar());
|
|
131
|
+
onMounted(() => void cargar());
|
|
132
|
+
return (_ctx, _cache) => {
|
|
133
|
+
return openBlock(), createElementBlock("section", _hoisted_1, [
|
|
134
|
+
createVNode(unref(RouterLink), {
|
|
135
|
+
to: { name: unref(RUTAS_PORTAL).chat },
|
|
136
|
+
class: "volver"
|
|
137
|
+
}, {
|
|
138
|
+
default: withCtx(() => [..._cache[2] || (_cache[2] = [createTextVNode("← Bandeja", -1)])]),
|
|
139
|
+
_: 1
|
|
140
|
+
}, 8, ["to"]),
|
|
141
|
+
createElementVNode("header", null, [_cache[5] || (_cache[5] = createElementVNode("h1", { class: "page-title" }, "Informe del chat", -1)), createElementVNode("p", _hoisted_2, [
|
|
142
|
+
_cache[3] || (_cache[3] = createTextVNode(" Conversaciones creadas en el rango, de los temas que usted ve", -1)),
|
|
143
|
+
unref(clientesInternos).seleccionado !== null ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(" y de los empleados de " + toDisplayString(unref(clientesInternos).nombre(unref(clientesInternos).seleccionado)), 1)], 64)) : createCommentVNode("", true),
|
|
144
|
+
_cache[4] || (_cache[4] = createTextVNode(". Los tiempos se cuentan en horas hábiles, con el horario de atención y sin festivos. ", -1))
|
|
145
|
+
])]),
|
|
146
|
+
createElementVNode("form", {
|
|
147
|
+
class: "toolbar",
|
|
148
|
+
onSubmit: withModifiers(cargar, ["prevent"])
|
|
149
|
+
}, [
|
|
150
|
+
_cache[6] || (_cache[6] = createElementVNode("label", {
|
|
151
|
+
for: "inf-desde",
|
|
152
|
+
class: "label"
|
|
153
|
+
}, "Desde", -1)),
|
|
154
|
+
withDirectives(createElementVNode("input", {
|
|
155
|
+
id: "inf-desde",
|
|
156
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => desde.value = $event),
|
|
157
|
+
type: "date",
|
|
158
|
+
class: "input"
|
|
159
|
+
}, null, 512), [[vModelText, desde.value]]),
|
|
160
|
+
_cache[7] || (_cache[7] = createElementVNode("label", {
|
|
161
|
+
for: "inf-hasta",
|
|
162
|
+
class: "label"
|
|
163
|
+
}, "hasta", -1)),
|
|
164
|
+
withDirectives(createElementVNode("input", {
|
|
165
|
+
id: "inf-hasta",
|
|
166
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => hasta.value = $event),
|
|
167
|
+
type: "date",
|
|
168
|
+
class: "input"
|
|
169
|
+
}, null, 512), [[vModelText, hasta.value]]),
|
|
170
|
+
createElementVNode("button", {
|
|
171
|
+
type: "submit",
|
|
172
|
+
class: "btn-primary",
|
|
173
|
+
disabled: cargando.value
|
|
174
|
+
}, "Calcular", 8, _hoisted_3)
|
|
175
|
+
], 32),
|
|
176
|
+
error.value ? (openBlock(), createElementBlock("p", _hoisted_4, toDisplayString(error.value), 1)) : cargando.value ? (openBlock(), createElementBlock("p", _hoisted_5, "Calculando…")) : informe.value ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [
|
|
177
|
+
createElementVNode("div", _hoisted_6, [(openBlock(true), createElementBlock(Fragment, null, renderList(tarjetas.value, (t) => {
|
|
178
|
+
return openBlock(), createElementBlock("div", {
|
|
179
|
+
key: t.titulo,
|
|
180
|
+
class: "panel cifra"
|
|
181
|
+
}, [
|
|
182
|
+
createElementVNode("p", _hoisted_7, toDisplayString(t.titulo), 1),
|
|
183
|
+
createElementVNode("p", _hoisted_8, toDisplayString(t.valor), 1),
|
|
184
|
+
createElementVNode("p", _hoisted_9, toDisplayString(t.detalle), 1)
|
|
185
|
+
]);
|
|
186
|
+
}), 128))]),
|
|
187
|
+
informe.value.sin_respuesta_vencidas > 0 ? (openBlock(), createElementBlock("p", _hoisted_10, " ⚠ " + toDisplayString(informe.value.sin_respuesta_vencidas) + " " + toDisplayString(informe.value.sin_respuesta_vencidas === 1 ? "conversación sigue" : "conversaciones siguen") + " sin primera respuesta con el plazo vencido. ", 1)) : createCommentVNode("", true),
|
|
188
|
+
createElementVNode("div", _hoisted_11, [createElementVNode("div", _hoisted_12, [_cache[13] || (_cache[13] = createElementVNode("p", { class: "panel-title" }, "Tiempos de RRHH", -1)), createElementVNode("table", _hoisted_13, [_cache[12] || (_cache[12] = createElementVNode("thead", null, [createElementVNode("tr", null, [
|
|
189
|
+
createElementVNode("th"),
|
|
190
|
+
createElementVNode("th", null, "Primera respuesta"),
|
|
191
|
+
createElementVNode("th", null, "Resolución")
|
|
192
|
+
])], -1)), createElementVNode("tbody", null, [
|
|
193
|
+
createElementVNode("tr", null, [
|
|
194
|
+
_cache[8] || (_cache[8] = createElementVNode("th", { scope: "row" }, "Mediana", -1)),
|
|
195
|
+
createElementVNode("td", null, toDisplayString(unref(duracion)(informe.value.primera_respuesta.mediana)), 1),
|
|
196
|
+
createElementVNode("td", null, toDisplayString(unref(duracion)(informe.value.resolucion.mediana)), 1)
|
|
197
|
+
]),
|
|
198
|
+
createElementVNode("tr", null, [
|
|
199
|
+
_cache[9] || (_cache[9] = createElementVNode("th", { scope: "row" }, "Promedio", -1)),
|
|
200
|
+
createElementVNode("td", null, toDisplayString(unref(duracion)(informe.value.primera_respuesta.promedio)), 1),
|
|
201
|
+
createElementVNode("td", null, toDisplayString(unref(duracion)(informe.value.resolucion.promedio)), 1)
|
|
202
|
+
]),
|
|
203
|
+
createElementVNode("tr", null, [
|
|
204
|
+
_cache[10] || (_cache[10] = createElementVNode("th", { scope: "row" }, "Dentro del plazo", -1)),
|
|
205
|
+
createElementVNode("td", null, [createTextVNode(toDisplayString(informe.value.primera_respuesta.dentro_del_plazo ?? "—"), 1), informe.value.primera_respuesta.dentro_del_plazo !== null ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(" %")], 64)) : createCommentVNode("", true)]),
|
|
206
|
+
createElementVNode("td", null, [createTextVNode(toDisplayString(informe.value.resolucion.dentro_del_plazo ?? "—"), 1), informe.value.resolucion.dentro_del_plazo !== null ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(" %")], 64)) : createCommentVNode("", true)])
|
|
207
|
+
]),
|
|
208
|
+
createElementVNode("tr", null, [
|
|
209
|
+
_cache[11] || (_cache[11] = createElementVNode("th", { scope: "row" }, "Medidas", -1)),
|
|
210
|
+
createElementVNode("td", null, toDisplayString(informe.value.primera_respuesta.medidas), 1),
|
|
211
|
+
createElementVNode("td", null, toDisplayString(informe.value.resolucion.medidas), 1)
|
|
212
|
+
])
|
|
213
|
+
])])]), createElementVNode("div", _hoisted_14, [_cache[14] || (_cache[14] = createElementVNode("p", { class: "panel-title" }, "Por qué pasaron a RRHH", -1)), !informe.value.escaladas ? (openBlock(), createElementBlock("p", _hoisted_15, "Ninguna pasó a RRHH en el rango.")) : (openBlock(), createElementBlock("table", _hoisted_16, [createElementVNode("tbody", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(informe.value.por_motivo, (n, motivo) => {
|
|
214
|
+
return openBlock(), createElementBlock("tr", { key: motivo }, [
|
|
215
|
+
createElementVNode("th", _hoisted_17, toDisplayString(unref(MOTIVOS_ESCALAMIENTO)[motivo] ?? motivo), 1),
|
|
216
|
+
createElementVNode("td", _hoisted_18, toDisplayString(n), 1),
|
|
217
|
+
createElementVNode("td", _hoisted_19, toDisplayString(pct(n, informe.value.escaladas)), 1)
|
|
218
|
+
]);
|
|
219
|
+
}), 128))])]))])]),
|
|
220
|
+
createElementVNode("div", _hoisted_20, [_cache[17] || (_cache[17] = createElementVNode("p", { class: "panel-title" }, "Por tema", -1)), createElementVNode("div", _hoisted_21, [createElementVNode("table", _hoisted_22, [_cache[16] || (_cache[16] = createElementVNode("thead", null, [createElementVNode("tr", null, [
|
|
221
|
+
createElementVNode("th", null, "Tema"),
|
|
222
|
+
createElementVNode("th", { class: "num" }, "Conversaciones"),
|
|
223
|
+
createElementVNode("th", { class: "num" }, "Pasaron a RRHH"),
|
|
224
|
+
createElementVNode("th", { class: "num" }, "Primera respuesta (prom.)"),
|
|
225
|
+
createElementVNode("th", { class: "num" }, "Calificación")
|
|
226
|
+
])], -1)), createElementVNode("tbody", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(informe.value.por_tema, (t) => {
|
|
227
|
+
return openBlock(), createElementBlock("tr", { key: t.tema }, [
|
|
228
|
+
createElementVNode("th", _hoisted_23, toDisplayString(t.tema), 1),
|
|
229
|
+
createElementVNode("td", _hoisted_24, toDisplayString(t.total), 1),
|
|
230
|
+
createElementVNode("td", _hoisted_25, toDisplayString(t.escaladas), 1),
|
|
231
|
+
createElementVNode("td", _hoisted_26, toDisplayString(unref(duracion)(t.primera_respuesta_promedio)), 1),
|
|
232
|
+
createElementVNode("td", _hoisted_27, toDisplayString(nota(t.calificacion_promedio)), 1)
|
|
233
|
+
]);
|
|
234
|
+
}), 128)), !informe.value.por_tema.length ? (openBlock(), createElementBlock("tr", _hoisted_28, [..._cache[15] || (_cache[15] = [createElementVNode("td", {
|
|
235
|
+
colspan: "5",
|
|
236
|
+
class: "panel-muted"
|
|
237
|
+
}, "Sin conversaciones en el rango.", -1)])])) : createCommentVNode("", true)])])])]),
|
|
238
|
+
informe.value.por_persona ? (openBlock(), createElementBlock("div", _hoisted_29, [_cache[20] || (_cache[20] = createElementVNode("p", { class: "panel-title" }, "Por persona", -1)), createElementVNode("div", _hoisted_30, [createElementVNode("table", _hoisted_31, [_cache[19] || (_cache[19] = createElementVNode("thead", null, [createElementVNode("tr", null, [
|
|
239
|
+
createElementVNode("th", null, "Persona"),
|
|
240
|
+
createElementVNode("th", { class: "num" }, "Atendidas"),
|
|
241
|
+
createElementVNode("th", { class: "num" }, "Resueltas"),
|
|
242
|
+
createElementVNode("th", { class: "num" }, "Primera respuesta (prom.)"),
|
|
243
|
+
createElementVNode("th", { class: "num" }, "Calificación")
|
|
244
|
+
])], -1)), createElementVNode("tbody", null, [(openBlock(true), createElementBlock(Fragment, null, renderList(informe.value.por_persona, (p) => {
|
|
245
|
+
return openBlock(), createElementBlock("tr", { key: p.usuario }, [
|
|
246
|
+
createElementVNode("th", _hoisted_32, toDisplayString(p.usuario), 1),
|
|
247
|
+
createElementVNode("td", _hoisted_33, toDisplayString(p.atendidas), 1),
|
|
248
|
+
createElementVNode("td", _hoisted_34, toDisplayString(p.resueltas), 1),
|
|
249
|
+
createElementVNode("td", _hoisted_35, toDisplayString(unref(duracion)(p.primera_respuesta_promedio)), 1),
|
|
250
|
+
createElementVNode("td", _hoisted_36, toDisplayString(nota(p.calificacion_promedio)), 1)
|
|
251
|
+
]);
|
|
252
|
+
}), 128)), !informe.value.por_persona.length ? (openBlock(), createElementBlock("tr", _hoisted_37, [..._cache[18] || (_cache[18] = [createElementVNode("td", {
|
|
253
|
+
colspan: "5",
|
|
254
|
+
class: "panel-muted"
|
|
255
|
+
}, "Nadie atendió conversaciones en el rango.", -1)])])) : createCommentVNode("", true)])])])])) : createCommentVNode("", true),
|
|
256
|
+
createElementVNode("div", _hoisted_38, [createElementVNode("div", _hoisted_39, [_cache[21] || (_cache[21] = createElementVNode("p", { class: "panel-title" }, "Calificaciones (1 a 5)", -1)), createElementVNode("table", _hoisted_40, [createElementVNode("tbody", null, [(openBlock(), createElementBlock(Fragment, null, renderList([
|
|
257
|
+
5,
|
|
258
|
+
4,
|
|
259
|
+
3,
|
|
260
|
+
2,
|
|
261
|
+
1
|
|
262
|
+
], (n) => {
|
|
263
|
+
return createElementVNode("tr", { key: n }, [
|
|
264
|
+
createElementVNode("th", _hoisted_41, toDisplayString(n), 1),
|
|
265
|
+
createElementVNode("td", _hoisted_42, toDisplayString(informe.value.calificacion.distribucion[n] ?? 0), 1),
|
|
266
|
+
createElementVNode("td", _hoisted_43, toDisplayString(pct(informe.value.calificacion.distribucion[n] ?? 0, informe.value.calificacion.respuestas)), 1)
|
|
267
|
+
]);
|
|
268
|
+
}), 64))])])]), createElementVNode("div", _hoisted_44, [_cache[26] || (_cache[26] = createElementVNode("p", { class: "panel-title" }, "Uso del asistente", -1)), createElementVNode("table", _hoisted_45, [createElementVNode("tbody", null, [
|
|
269
|
+
createElementVNode("tr", null, [_cache[22] || (_cache[22] = createElementVNode("th", { scope: "row" }, "Respuestas", -1)), createElementVNode("td", _hoisted_46, toDisplayString(informe.value.uso_ia.mensajes.toLocaleString("es-CO")), 1)]),
|
|
270
|
+
createElementVNode("tr", null, [_cache[23] || (_cache[23] = createElementVNode("th", { scope: "row" }, "Consultas al proveedor", -1)), createElementVNode("td", _hoisted_47, toDisplayString(informe.value.uso_ia.llamadas.toLocaleString("es-CO")), 1)]),
|
|
271
|
+
createElementVNode("tr", null, [_cache[24] || (_cache[24] = createElementVNode("th", { scope: "row" }, "Tokens de entrada", -1)), createElementVNode("td", _hoisted_48, toDisplayString(informe.value.uso_ia.tokens_entrada.toLocaleString("es-CO")), 1)]),
|
|
272
|
+
createElementVNode("tr", null, [_cache[25] || (_cache[25] = createElementVNode("th", { scope: "row" }, "Tokens de salida", -1)), createElementVNode("td", _hoisted_49, toDisplayString(informe.value.uso_ia.tokens_salida.toLocaleString("es-CO")), 1)])
|
|
273
|
+
])])])])
|
|
274
|
+
], 64)) : createCommentVNode("", true)
|
|
275
|
+
]);
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}), [["__scopeId", "data-v-fa114240"]]);
|
|
279
|
+
//#endregion
|
|
280
|
+
export { ChatInformeView_default as default };
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { t as RUTAS_PORTAL } from "./tipos-D93bLfFC.js";
|
|
2
|
+
import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper-BOaGB7Aw.js";
|
|
3
|
+
import { i as chatService } from "./chat.service-C7ZQf4w3.js";
|
|
4
|
+
import { t as mensajeError } from "./apiError-BHGbwz97.js";
|
|
5
|
+
import { Fragment, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, onMounted, openBlock, ref, renderList, toDisplayString, unref, vModelSelect, vModelText, withCtx, withDirectives, withModifiers } from "vue";
|
|
6
|
+
import { RouterLink } from "vue-router";
|
|
7
|
+
//#region src/views/chat/ChatRespuestasView.vue?vue&type=script&setup=true&lang.ts
|
|
8
|
+
var _hoisted_1 = { class: "page-shell" };
|
|
9
|
+
var _hoisted_2 = { class: "page-header" };
|
|
10
|
+
var _hoisted_3 = {
|
|
11
|
+
key: 0,
|
|
12
|
+
class: "panel-error",
|
|
13
|
+
role: "alert"
|
|
14
|
+
};
|
|
15
|
+
var _hoisted_4 = {
|
|
16
|
+
key: 1,
|
|
17
|
+
class: "panel-muted"
|
|
18
|
+
};
|
|
19
|
+
var _hoisted_5 = { class: "campo" };
|
|
20
|
+
var _hoisted_6 = { class: "campo" };
|
|
21
|
+
var _hoisted_7 = { class: "toolbar" };
|
|
22
|
+
var _hoisted_8 = ["value"];
|
|
23
|
+
var _hoisted_9 = ["disabled"];
|
|
24
|
+
var _hoisted_10 = ["disabled"];
|
|
25
|
+
var _hoisted_11 = {
|
|
26
|
+
key: 0,
|
|
27
|
+
class: "panel-muted"
|
|
28
|
+
};
|
|
29
|
+
var _hoisted_12 = { class: "page-header" };
|
|
30
|
+
var _hoisted_13 = { class: "panel-title" };
|
|
31
|
+
var _hoisted_14 = { class: "panel-muted" };
|
|
32
|
+
var _hoisted_15 = {
|
|
33
|
+
key: 0,
|
|
34
|
+
class: "toolbar"
|
|
35
|
+
};
|
|
36
|
+
var _hoisted_16 = ["disabled", "onClick"];
|
|
37
|
+
var _hoisted_17 = ["disabled", "onClick"];
|
|
38
|
+
var _hoisted_18 = { class: "texto" };
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/views/chat/ChatRespuestasView.vue
|
|
41
|
+
var ChatRespuestasView_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
|
|
42
|
+
__name: "ChatRespuestasView",
|
|
43
|
+
setup(__props) {
|
|
44
|
+
const respuestas = ref([]);
|
|
45
|
+
const temas = ref([]);
|
|
46
|
+
const cargando = ref(true);
|
|
47
|
+
const ocupado = ref(false);
|
|
48
|
+
const error = ref(null);
|
|
49
|
+
const editando = ref(null);
|
|
50
|
+
const nombreTema = (id) => temas.value.find((t) => t.id === id)?.nombre ?? "Todos los temas";
|
|
51
|
+
async function cargar() {
|
|
52
|
+
cargando.value = true;
|
|
53
|
+
error.value = null;
|
|
54
|
+
try {
|
|
55
|
+
[respuestas.value, temas.value] = await Promise.all([chatService.respuestas(), chatService.temas()]);
|
|
56
|
+
} catch (e) {
|
|
57
|
+
error.value = mensajeError(e, "No se pudieron cargar las respuestas guardadas.");
|
|
58
|
+
} finally {
|
|
59
|
+
cargando.value = false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function guardar() {
|
|
63
|
+
if (!editando.value) return;
|
|
64
|
+
ocupado.value = true;
|
|
65
|
+
error.value = null;
|
|
66
|
+
try {
|
|
67
|
+
await chatService.guardarRespuesta(editando.value);
|
|
68
|
+
editando.value = null;
|
|
69
|
+
respuestas.value = await chatService.respuestas();
|
|
70
|
+
} catch (e) {
|
|
71
|
+
error.value = mensajeError(e, "No se pudo guardar la respuesta.");
|
|
72
|
+
} finally {
|
|
73
|
+
ocupado.value = false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function borrar(r) {
|
|
77
|
+
if (!window.confirm(`¿Borrar «${r.titulo}»?`)) return;
|
|
78
|
+
ocupado.value = true;
|
|
79
|
+
try {
|
|
80
|
+
await chatService.borrarRespuesta(r.id);
|
|
81
|
+
respuestas.value = respuestas.value.filter((x) => x.id !== r.id);
|
|
82
|
+
} catch (e) {
|
|
83
|
+
error.value = mensajeError(e, "No se pudo borrar la respuesta.");
|
|
84
|
+
} finally {
|
|
85
|
+
ocupado.value = false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
onMounted(() => void cargar());
|
|
89
|
+
return (_ctx, _cache) => {
|
|
90
|
+
return openBlock(), createElementBlock("section", _hoisted_1, [
|
|
91
|
+
createVNode(unref(RouterLink), {
|
|
92
|
+
to: { name: unref(RUTAS_PORTAL).chat },
|
|
93
|
+
class: "volver"
|
|
94
|
+
}, {
|
|
95
|
+
default: withCtx(() => [..._cache[5] || (_cache[5] = [createTextVNode("← Bandeja", -1)])]),
|
|
96
|
+
_: 1
|
|
97
|
+
}, 8, ["to"]),
|
|
98
|
+
createElementVNode("header", _hoisted_2, [_cache[6] || (_cache[6] = createElementVNode("div", null, [createElementVNode("h1", { class: "page-title" }, "Respuestas guardadas"), createElementVNode("p", { class: "page-subtitle" }, [
|
|
99
|
+
createTextVNode(" Textos que el equipo reusa al contestar. Escriba "),
|
|
100
|
+
createElementVNode("code", null, "{nombre}"),
|
|
101
|
+
createTextVNode(" donde vaya el primer nombre del empleado. ")
|
|
102
|
+
])], -1)), !editando.value ? (openBlock(), createElementBlock("button", {
|
|
103
|
+
key: 0,
|
|
104
|
+
type: "button",
|
|
105
|
+
class: "btn-primary",
|
|
106
|
+
onClick: _cache[0] || (_cache[0] = ($event) => editando.value = {
|
|
107
|
+
titulo: "",
|
|
108
|
+
cuerpo: "",
|
|
109
|
+
tema_id: null
|
|
110
|
+
})
|
|
111
|
+
}, " Nueva respuesta ")) : createCommentVNode("", true)]),
|
|
112
|
+
error.value ? (openBlock(), createElementBlock("p", _hoisted_3, toDisplayString(error.value), 1)) : createCommentVNode("", true),
|
|
113
|
+
cargando.value ? (openBlock(), createElementBlock("p", _hoisted_4, "Cargando…")) : createCommentVNode("", true),
|
|
114
|
+
editando.value ? (openBlock(), createElementBlock("form", {
|
|
115
|
+
key: 2,
|
|
116
|
+
class: "panel",
|
|
117
|
+
onSubmit: withModifiers(guardar, ["prevent"])
|
|
118
|
+
}, [
|
|
119
|
+
createElementVNode("label", _hoisted_5, [_cache[7] || (_cache[7] = createElementVNode("span", { class: "label" }, "Título (para encontrarla)", -1)), withDirectives(createElementVNode("input", {
|
|
120
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => editando.value.titulo = $event),
|
|
121
|
+
class: "input",
|
|
122
|
+
maxlength: "120",
|
|
123
|
+
required: "",
|
|
124
|
+
placeholder: "Fecha de pago de la prima"
|
|
125
|
+
}, null, 512), [[vModelText, editando.value.titulo]])]),
|
|
126
|
+
createElementVNode("label", _hoisted_6, [_cache[8] || (_cache[8] = createElementVNode("span", { class: "label" }, "Texto", -1)), withDirectives(createElementVNode("textarea", {
|
|
127
|
+
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => editando.value.cuerpo = $event),
|
|
128
|
+
class: "input",
|
|
129
|
+
rows: "5",
|
|
130
|
+
maxlength: "4000",
|
|
131
|
+
required: "",
|
|
132
|
+
placeholder: "Hola {nombre}, la prima se paga…"
|
|
133
|
+
}, null, 512), [[vModelText, editando.value.cuerpo]])]),
|
|
134
|
+
createElementVNode("div", _hoisted_7, [
|
|
135
|
+
_cache[10] || (_cache[10] = createElementVNode("label", {
|
|
136
|
+
for: "resp-tema",
|
|
137
|
+
class: "label"
|
|
138
|
+
}, "Tema", -1)),
|
|
139
|
+
withDirectives(createElementVNode("select", {
|
|
140
|
+
id: "resp-tema",
|
|
141
|
+
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => editando.value.tema_id = $event),
|
|
142
|
+
class: "input"
|
|
143
|
+
}, [_cache[9] || (_cache[9] = createElementVNode("option", { value: null }, "Todos los temas", -1)), (openBlock(true), createElementBlock(Fragment, null, renderList(temas.value, (t) => {
|
|
144
|
+
return openBlock(), createElementBlock("option", {
|
|
145
|
+
key: t.id,
|
|
146
|
+
value: t.id
|
|
147
|
+
}, toDisplayString(t.nombre), 9, _hoisted_8);
|
|
148
|
+
}), 128))], 512), [[vModelSelect, editando.value.tema_id]]),
|
|
149
|
+
createElementVNode("button", {
|
|
150
|
+
type: "submit",
|
|
151
|
+
class: "btn-primary",
|
|
152
|
+
disabled: ocupado.value
|
|
153
|
+
}, "Guardar", 8, _hoisted_9),
|
|
154
|
+
createElementVNode("button", {
|
|
155
|
+
type: "button",
|
|
156
|
+
class: "btn-secondary",
|
|
157
|
+
disabled: ocupado.value,
|
|
158
|
+
onClick: _cache[4] || (_cache[4] = ($event) => editando.value = null)
|
|
159
|
+
}, "Cancelar", 8, _hoisted_10)
|
|
160
|
+
])
|
|
161
|
+
], 32)) : createCommentVNode("", true),
|
|
162
|
+
!cargando.value ? (openBlock(), createElementBlock(Fragment, { key: 3 }, [!respuestas.value.length ? (openBlock(), createElementBlock("p", _hoisted_11, "Todavía no hay respuestas guardadas.")) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(respuestas.value, (r) => {
|
|
163
|
+
return openBlock(), createElementBlock("article", {
|
|
164
|
+
key: r.id,
|
|
165
|
+
class: "panel"
|
|
166
|
+
}, [createElementVNode("div", _hoisted_12, [createElementVNode("div", null, [createElementVNode("p", _hoisted_13, toDisplayString(r.titulo), 1), createElementVNode("p", _hoisted_14, [createTextVNode(toDisplayString(nombreTema(r.tema_id)), 1), r.propia ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [createTextVNode(" · Suya")], 64)) : createCommentVNode("", true)])]), r.editable ? (openBlock(), createElementBlock("div", _hoisted_15, [createElementVNode("button", {
|
|
167
|
+
type: "button",
|
|
168
|
+
class: "btn-secondary",
|
|
169
|
+
disabled: ocupado.value,
|
|
170
|
+
onClick: ($event) => editando.value = { ...r }
|
|
171
|
+
}, "Editar", 8, _hoisted_16), createElementVNode("button", {
|
|
172
|
+
type: "button",
|
|
173
|
+
class: "btn-danger",
|
|
174
|
+
disabled: ocupado.value,
|
|
175
|
+
onClick: ($event) => borrar(r)
|
|
176
|
+
}, "Borrar", 8, _hoisted_17)])) : createCommentVNode("", true)]), createElementVNode("p", _hoisted_18, toDisplayString(r.cuerpo), 1)]);
|
|
177
|
+
}), 128))], 64)) : createCommentVNode("", true)
|
|
178
|
+
]);
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}), [["__scopeId", "data-v-d7451ca3"]]);
|
|
182
|
+
//#endregion
|
|
183
|
+
export { ChatRespuestasView_default as default };
|