# Repeater Bone
# Introducción
Componente lógico.
# Código fuente
<script>
import { separateValidPositions } from '../../../mixins/comportamientoPositionCheck'
const validPositions = ['append', 'prepend']
const props = {
hint: {type: String},
item: {type: Array, required: true},
label: {
type: String,
default: ''
},
readonly: {type: Boolean, default: false},
items: {type: Array, default: () => ([])},
required: {type: Boolean, default: false},
max: {type: Number, default: -1},
min: {type: Number, default: 1},
duplicate: {type: Boolean, default: false},
// logic_delete: {type: Boolean, default: false }, //funcionalidad parcialmente desarrollada (Borrado lógico de filas)
items_fcn: {type: String},
comportamientos:{type: Array, required: false},
args_items_fcn: {
type: Array,
default: () => ([])
},
id_resolver:{
type: String
},
props: {
type: Object,
required: true
}
}
import { normalizeProps, assignCamelToSnake } from '../../../helpers/propsGenerator';
const mergedProps = normalizeProps(props)
import { endpointIcl, repeaterComponentName } from '../../../constants'
export default {
name: repeaterComponentName + 'Bone',
props: mergedProps,
data() {
return {
itemsBoneModified: [],
loading: false,
itemsBoneModifiedAux: [],
usedPosition:[],
structureError: false
}
},
computed: {
columnasControl(){
let mayor = 1
for (let i in this.item){
if(this.item[i].props.width > mayor)
mayor = this.item[i].props.width
}
return mayor
},
},
watch: {
itemsBoneModified: {
deep: true,
handler(isItems) {
this.props.items = isItems
}
},
readonly(isReadonly) {
if (this.itemsBoneModifiedAux.length === 0 && this.itemsBoneModified.length !== 0)
this.itemsBoneModifiedAux = JSON.parse(JSON.stringify(this.itemsBoneModified))
if (isReadonly) {
this.itemsBoneModified.forEach(campo => {
campo.forEach(c => {
c.props.readonly = true
})
})
} else {
if (this.itemsBoneModifiedAux.length !== 0)
this.itemsBoneModified = JSON.parse(JSON.stringify(this.itemsBoneModifiedAux))
}
}
},
methods: {
moveItem(index, item, moveUp = true) {
let move = moveUp ? -1 : 1
this.itemsBoneModified.splice(index, 1)
this.itemsBoneModified.splice(index + move, 0, item)
},
addItem() {
if(this.readonly)
return
if (this.max !== -1 && this.itemsBoneModified.length < this.max || this.max === -1)
this.add()
},
add() {
let obj = JSON.parse(JSON.stringify(this.item))
// if(this.logic_delete){ //funcionalidad parcialmente desarrollada (Borrado lógico de filas)
// let campoIndex = this.itemsBoneModified.findIndex(item => item.label === 'Index')
// if(campoIndex != -1){
// let indmax = 0
// this.itemsBoneModified.forEach(item => {
// item[campoIndex].value > indmax ? indmax = item[campoIndex].value : ''
// });
// obj[campoIndex].value = indmax + 1
// }
// }
obj[0].key = (Math.floor(Math.random() * 999) + this.itemsBoneModified.length)
this.itemsBoneModified.push(obj)
},
duplicateItem(item) {
let itemAux = Object.assign(item)
this.itemsBoneModified.push(itemAux)
},
deleteItem(i) {
if (this.readonly)
return
// if(!this.logic_delete){
if (this.itemsBoneModified.length > this.min) {
this.itemsBoneModified.splice(i, 1)
}
// }
// else{ //funcionalidad parcialmente desarrollada (Borrado lógico de filas)
// let statusField = this.itemsBoneModified[i].find(campo=> { //TODO To do: revisar funcionalidad
// return campo.label === 'Status'
// });
// statusField.value = false
// }
},
addMinItems() {
while (this.itemsBoneModified.length < this.min && !this.readonly)
this.addItem()
},
getItems() {
return this.$iclAxios.post(endpointIcl + this.items_fcn, [
JSON.stringify({args: this.args_items_fcn, id_usuario: this.$iclstore.state.id_usuario})
]).then((res) => {
res.forEach((item)=>{
this.$detectResponseStructErrors(item, this.items_fcn, ['props', 'type'], repeaterComponentName, '{props: Object, type: String}', 'https://icl.iridiumrobotics.com.ar/components/ir-repeater.html#uso')
})
return res
}
).catch((err) =>{
console.log(err)
this.$iclstore.commit('updateSnack', {active: true, text: 'Error al consultar los datos' + (!!this.label ? ' de ' + this.label : ''), color: 'error'})
}
).finally(() =>
this.loading = false
)
},
async manageItems() {
this.itemsBoneModified = [...this.items]
if (typeof this.items_fcn === 'undefined')
this.addMinItems()
else {
this.loading = true
let res = await this.getItems()
if (!!res && Array.isArray(res)) {
res.forEach((itemRes) => {
itemRes.forEach((rowField, i) => {
let itemObj = Object.assign(this.item[i])
if (!itemObj || Object.keys(rowField).toString() !== Object.keys(itemObj).toString()) { // se chequea que los items recibidos en la consulta tengan la misma estructura que this.item
this.$logErrorComponent(repeaterComponentName, 'Error en la estructura "items_fcn" en IrRepeater, la respuesta no coincide con los campos predefinidos del IrRepeater (propiedad "item") - ' + this.label)
this.$iclstore.commit('updateSnack', {active: true, text: 'Error al consultar los datos' + (!!this.label ? ' de ' + this.label : ''), color: 'error'})
return
}
})
})
this.itemsBoneModified = res
}
}
},
manageReadonly() {
if (this.readonly) {
this.itemsBoneModified.forEach((fila) => {
fila.forEach((campoFila) => {
campoFila.props.readonly = true
})
})
}
},
async createdFunctions() {
await this.manageItems()
this.manageReadonly()
}
},
mounted(){
this.structureError = this.$propError(props, this.$props, repeaterComponentName)
if(this.structureError){
this.$iclstore.commit('updateSnack', {text: 'Ha ocurrido un error al cargar algunos campos del formulario', active: true, color:'warning'})
}
this.usedPosition = separateValidPositions(this.comportamientos, validPositions, repeaterComponentName,
this.$iclRouter.currentRoute.path, this.$logError) // Valida las posiciones válidas para comportamientos
},
created() {
assignCamelToSnake(mergedProps, this)
this.createdFunctions()
},
render() {
if(this.structureError){
return
}
return this.$scopedSlots.default({
hint: this.hint,
item: this.item,
items: this.itemsBoneModified,
readonly: this.readonly,
loading: this.loading,
addButtonEvent: this.addItem,
deleteItem: this.deleteItem,
columnNumber: this.columnasControl,
moveItem: this.moveItem,
duplicateItem: this.duplicateItem,
duplicate: this.duplicate,
required: this.required,
label: this.label,
comportamientos: this.comportamientos,
comportamientosPositions: this.usedPosition,
valueType: props.items.type.name.toLowerCase(),
id_resolver: this.id_resolver,
comportamientoEvents:{
changeFieldValue:(e) => {
this.itemsBoneModified = [...e]
},
'close-dialog': (e) => {
this.$emit('close-dialog', e)
},
refresh: () => {
this.$emit('refresh')
}
}
})
}
}
</script>