# Radio Group Bone

# Introducción

Componente lógico. Este componente comparte Bone de IrSelect

# Código fuente

<script>
/*IMPORTANTE: ESTE BONE ES EXTENDIDO POR IR-RADIO-GROUP-BONE. TENER EN CUENTA A LA HORA DE MODIFICAR VERIFICAR EL FUNCIONAMIENTO EN AMBOS COMPONENTES */

import { separateValidPositions } from '../../../mixins/comportamientoPositionCheck'
const validPositions = [
  'append',
  'append-outer',
  'append',
  'item',
  'label',
  'no-data',
  'prepend',
  'prepend-inner',
  'prepend-item',
  'selection',
  'counter'
]

const props = {
  required: {
    type: Boolean,
    default: false
  },
  readonly: {
    type: Boolean,
    default: false
  },
  placeholder: {
    type: String,
    default: ''
  },
  items_fcn: {
    type: String,
    default: ''
  },
  args_items_fcn: {
    type: Array,
    default: () => []
  },
  items: {
    type: Array
  },
  label: {
    type: String,
    default: ''
  },
  id_resolver: {
    type: String
  },
  returnObject: {
    type: Boolean,
    default: false
  },
  hideDetails: {
    type: undefined,
    default: 'auto'
  },
  linked: {
    type: undefined,
    validator: (value) => ['update', false, true, 'replace'].includes(value),
    default: false
  },
  comportamientos: {
    type: Array,
    required: false
  },
  itemText: {
    type: String,
    default: 'text'
  },
  searchable: {
    type: Boolean,
    default: true
  }
}
import {
  normalizeProps,
  assignCamelToSnake
} from '../../../helpers/propsGenerator'
const mergedProps = normalizeProps(props)
import {
  selectComponentName,
  externalDBEndpoint,
  endpointIcl,
  externalApi
} from '../../../constants'
export default {
  name: selectComponentName + 'Bone',
  props: mergedProps,
  data() {
    return {
      itemsLocal: [],
      usedPosition: [],
      structureError: false,
      rspReplacedProps: {},
      searchText: '',
      selectComponentName: selectComponentName
    }
  },
  computed: {
    generatedIdResolver() {
      return this.id_resolver
        ? this.id_resolver
        : this.$iclRouter.currentRoute.path
    },
    /**
     * Filtra los items según el texto de búsqueda proporcionado.
     * @computed
     * @name itemsLocalFiltered
     * @returns {Array} - Una nueva matriz de elementos filtrados.
     */
    itemsLocalFiltered() {
      return this.itemsLocal.filter((item) => {
        let filterText = (itemText) =>
          itemText.toLowerCase().includes(this.searchText.toLowerCase())
        let filterNumber = (itemTextNumber) =>
          itemTextNumber.toString().includes(this.searchText)
        let itemType = typeof item
        // Item = 'hola'
        if (itemType === 'string') return filterText(item)
        // Item = 7
        if (itemType === 'number') return filterNumber(item)
        if (itemType === 'object') {
          let text = item[this.itemText]
          let textType = typeof text
          // Item = { text: 'hola', value: 'valor' }
          if (textType === 'string') return filterText(text)
          // Item = { text: 7, value: '7' }
          if (textType === 'number') return filterNumber(text)
        }
        console.log(
          'El item ' +
            item +
            ' tiene una estructura inválida. No se va a comparar.'
        )
        return false
      })
    },
    localProps() {
      return { ...this.$props, ...this.rspReplacedProps }
    }
  },
  created() {
    assignCamelToSnake(mergedProps, this)
  },
  mounted() {
    this.structureError = this.$propError(
      props,
      this.localProps,
      this.selectComponentName
    )
    if (this.structureError) {
      this.$iclstore.commit('updateSnack', {
        text: 'Ha ocurrido un error al cargar algunos campos del formulario',
        active: true,
        color: 'error'
      })
    }
    this.usedPosition = separateValidPositions(
      this.comportamientos,
      validPositions,
      this.selectComponentName,
      this.id_resolver,
      this.$logError
    ) // Valida las posiciones válidas para comportamientos
    if (this.items_fcn !== '' && this.items_fcn !== null) this.getItems()
    else this.itemsLocal = this.items
  },
  methods: {
    async getItems() {
      this.$emit('update-loading', true)
      this.$iclAxios
        .post(externalDBEndpoint + this.items_fcn, [
          JSON.stringify({
            args: this.args_items_fcn,
            id_usuario: this.$iclstore.state.id_usuario,
            id_resolver: this.id_resolver
          })
        ])
        .then((rsp) => {
          if (Array.isArray(rsp))
            // Si es un arreglo entonces se considera un arreglo de "items"
            this.$detectResponseStructErrors(
              rsp,
              this.items_fcn,
              ['text', 'value'],
              this.selectComponentName,
              '{text: String, value: Any}',
              'https://icl.iridiumrobotics.com.ar/components/ir-select.html#propiedades'
            )
          else
            this.structureError = this.$propError(
              props,
              { ...this.localProps, ...rsp },
              this.selectComponentName
            )
          this.manageResponse(rsp)
        })
        .catch((error) => {
          console.log(error)
        })
        .finally(() => {
          this.$emit('update-loading', false)
        })
    },
    /**
     * Realiza una consulta asincrónica utilizando Axios.
     *
     * @param {Object} args - Los argumentos para la consulta.
     * @param {Object} args.pre_api - Configuración previa a la consulta.
     * @param {Object} args.post_api - Configuración posterior a la consulta.
     * @returns {Promise<void>} - Una promesa que resuelve cuando la consulta se completa con éxito o falla.
     * @throws {Error} - Lanza un error si la consulta falla.
     */
    async makeQuery(args, value) {
      this.$emit('toggle-loading')
      let { pre_api, post_api } = args
      if (pre_api && pre_api.config && pre_api.config.loading_message) {
        this.$iclstore.dispatch('cancelSnack')
        this.$iclstore.commit('updateSnack', {
          text: pre_api.config.loading_message,
          active: true,
          color: 'success',
          time: 999999,
          is_closing_allowed: false
        })
      }
      if (post_api && post_api.config && post_api.config.loading_message) {
        this.$iclstore.dispatch('cancelSnack')
        this.$iclstore.commit('updateSnack', {
          text: post_api.config.loading_message,
          active: true,
          color: 'success',
          time: 999999,
          is_closing_allowed: false
        })
      }
      let localArgs = [
        JSON.stringify({
          ...args,
          id_usuario: this.$iclstore.state.id_usuario,
          id_resolver: this.generatedIdResolver,
          value
        })
      ]
      this.$iclAxios
        .post(endpointIcl + externalApi, localArgs)
        .then((rsp) => {
          this.$emit('toggle-loading')
          this.$emit('change-linked-value', {
            action: this.localProps.linked,
            campo: {
              type: this.selectComponentName,
              props: { ...this.localProps, value, items: this.itemsLocal }
            }
          })
        })
        .catch((error) => {
          this.$emit('toggle-loading')
          console.log(error)
        })
        .finally(() => {
          if (
            (pre_api && pre_api.config && pre_api.config.loading_message) ||
            (post_api && post_api.config && post_api.config.loading_message)
          )
            this.$iclstore.dispatch('showNextSnack')
        })
    },
    manageResponse(response) {
      if (Array.isArray(response)) this.itemsLocal = response
      else {
        this.rspReplacedProps = { ...this.localProps, ...response }
        this.itemsLocal = this.rspReplacedProps.items
          ? [...this.rspReplacedProps.items]
          : []
        if (response.value) this.$emit('updateValue', response.value)
      }
    }
  },
  render() {
    if (this.structureError) {
      return
    }
    let {
      readonly,
      required,
      label,
      placeholder,
      returnObject,
      hideDetails,
      linked,
      comportamientos,
      id_resolver
    } = this.localProps
    return this.$scopedSlots.default({
      selectItems: this.itemsLocalFiltered,
      originalItems: this.itemsLocal,
      readonly,
      required,
      label,
      placeholder,
      returnObject,
      hideDetails,
      rules: this.$rulesGenerator(this.required),
      linked,
      comportamientos,
      comportamientosPositions: this.usedPosition,
      id_resolver,
      makeQuery: this.makeQuery,
      search: (newSearchText) => {
        if (newSearchText === null) newSearchText = ''
        this.searchText = newSearchText
      },
      isFilterVisible: this.searchable || linked
    })
  }
}
</script>
Last Updated: 4/5/2024, 4:52:19 PM