# Conversation Bone
# Introducción
Éste componente no está encargado de renderizar, es de uso interno del IrConversation. Guía de uso parte lógica
# Código fuente
<script>
const propsLocal = {
messages: {
type: Array,
default: () => []
},
messages_fcn: {
type: String,
required: false
},
refreshTimer: {
type: Object,
default: () => ({
repeat_time: 5000,
loops: -1
})
},
args_messages_fcn: {
type: Array,
default: () => []
},
cache_messages: {
type: Boolean,
default: true
},
id_resolver: {
type: String,
required: false
}
}
import {
normalizeProps,
assignCamelToSnake
} from '../../helpers/propsGenerator'
import Vue, { ref, h, onBeforeUnmount } from 'vue'
const mergedProps = normalizeProps(propsLocal)
import { IrConversationName, externalDBEndpoint } from '../../constants'
export default {
name: IrConversationName + 'Bone',
props: mergedProps,
setup(props, { slots, emit, expose }) {
const iclAxios = Vue.prototype.$iclAxios
const iclstore = Vue.prototype.$iclstore
const iclRouter = Vue.prototype.$iclRouter
const detectResponseStructErrors = Vue.prototype.$detectResponseStructErrors
const loading = ref(false)
const refreshed = ref(false)
const loopInterval = ref(null)
const firstTime = ref(true)
/*** Separa los mensajes por fecha.
*
* @param {Array} mensajes - La lista de mensajes a ser procesados.
* @returns {Array} Un array de objetos con propiedades 'date' y 'messages'.
*/
const separatePerDate = (mensajes) => {
const mensajesPorDia = {}
mensajes.forEach((mensaje) => {
try {
const fecha = new Date(mensaje.date).toISOString().split('T')[0]
if (!mensajesPorDia[fecha]) mensajesPorDia[fecha] = []
mensajesPorDia[fecha].push(mensaje)
} catch (error) {
console.log('No se pudo conseguir la fecha del mensaje', mensaje)
console.log(error)
}
})
return Object.values(mensajesPorDia).map((messages, index) => {
return { date: Object.keys(mensajesPorDia)[index], messages }
})
}
/**
* Obtiene mensajes mediante una solicitud a un punto final externo.
*/
const getMessages = async () => {
loading.value = true
const params = {
args: props.args_messages_fcn,
id_usuario: iclstore.state.id_usuario,
id_resolver: props.id_resolver
? props.id_resolver
: iclRouter.currentRoute.path
}
try {
const rsp = await iclAxios.post(externalDBEndpoint + props.messages_fcn, [JSON.stringify(params)])
const paramsDetectErrors = [
props.messages_fcn,
[],
IrConversationName,
'{type: String, props: Object}',
'https://icl.iridiumrobotics.com.ar/components/ir-conversation.html#uso'
]
detectResponseStructErrors(rsp, ...paramsDetectErrors) //En caso de detección de errores en la respuesta NO interrumpe la ejecución del componente, solo loguea.
emit('uploaded-messages', rsp || [])
} catch (error) {
console.log(error)
emit('uploaded-messages', props.messages)
} finally {
loading.value = false
}
}
const manageRefreshRepeater = () => {
const { repeat_time, loops } = props.refreshTimer
const isInfiniteLoop = loops === -1
let countingDown = loops
if (repeat_time && (countingDown > 0 || isInfiniteLoop)) {
refreshed.value = true
loopInterval.value = setInterval(async () => {
if (!isInfiniteLoop) countingDown -= 1
await getMessages()
if (!isInfiniteLoop && countingDown <= 0) clearInterval(loopInterval.value)
}, repeat_time)
}
}
/**
* Asynchronously manages messages retrieval.
* @async
* @function manageMessagesGetter
*/
const manageMessagesGetter = async () => {
if (props.messages_fcn && iclAxios) {
const params = {
args: props.args_messages_fcn,
id_usuario: iclstore.state.id_usuario,
id_resolver: props.id_resolver
? props.id_resolver
: iclRouter.currentRoute.path
}
const datosSitio = iclstore.getters.getDatosSitios({
sitio: iclRouter.app._route.path,
query: props.messages_fcn,
method: 'post',
params: [JSON.stringify(params)]
})
if (datosSitio && props.cache_messages && datosSitio.response) {
// los busca en el store, si los encuentra los guarda en itemsLocal hasta que se termine de hacer la consulta por los items
emit('uploaded-messages', [...datosSitio.response])
}
await getMessages()
} else {
// si no se envía messages_fcn se envía al FE la propiedad messages
emit('uploaded-messages', props.messages)
}
if (firstTime.value && props.refreshTimer && props.messages_fcn) {
firstTime.value = false
manageRefreshRepeater()
}
}
assignCamelToSnake(mergedProps, props)
manageMessagesGetter()
onBeforeUnmount(() => {
if (loopInterval.value) {
clearInterval(loopInterval.value)
}
})
expose({
separatePerDate
})
return () => {
return h(
'div', // Contenedor como nodo raíz
[
slots.default({
separatePerDate: separatePerDate,
loading: loading.value
})
]
)
}
}
}
</script>
← Componente Componente →