<commit_before>import Head from './mixins/head'
import Body from './mixins/body'
import Foot from './mixins/foot'

export default {
  name: 'datatable',

  mixins: [Head, Body, Foot],

  data () {
    return {
      desc: null,
      page: 1,
      sorting: null,
      all: false
    }
  },

  props: {
    headers: {
      type: Array,
      default: () => []
    },
    headerText: {
      type: String,
      default: 'text'
    },
    hideActions: Boolean,
    items: {
      type: Array,
      default: () => []
    },
    itemValue: {
      default: 'value'
    },
    noDataText: {
      type: String,
      default: 'No data available in table'
    },
    noResultsText: {
      type: String,
      default: 'No matching records found'
    },
    rowsPerPage: {
      type: [Number, String],
      default: 5
    },
    rowsPerPageItems: {
      type: Array,
      default () {
        return [
          5,
          10,
          25,
          { text: 'All', value: -1 }
        ]
      }
    },
    rowsPerPageText: {
      type: String,
      default: 'Rows per page:'
    },
    selectAll: Boolean,
    search: {
      required: false
    },
    filter: {
      type: Function,
      default: (val, search) => {
        return val !== null &&
          ['undefined', 'boolean'].indexOf(typeof val) === -1 &&
          val.toString().toLowerCase().indexOf(search) !== -1
      }
    },
    value: {
      type: Array,
      default: () => []
    }
  },

  computed: {
    indeterminate () {
      return this.selectAll && this.someItems && !this.everyItem
    },
    everyItem () {
      return this.value.every(i => i[this.itemValue])
    },
    someItems () {
      return this.value.some(i => i[this.itemValue])
    },
    pageStart () {
      const page = this.rowsPerPage === Object(this.rowsPerPage)
        ? this.rowsPerPage.value
        : this.rowsPerPage
      return page === -1 ? 0 : (this.page - 1) * page
    },
    pageStop () {
      const page = this.rowsPerPage === Object(this.rowsPerPage)
        ? this.rowsPerPage.value
        : this.rowsPerPage
      return page === -1 ? this.value.length : this.page * page
    },
    filteredItems () {
      let items = this.value.slice()
      const hasSearch = typeof this.search !== 'undefined' && this.search !== null

      if (hasSearch) {
        const search = this.search.toString().toLowerCase()

        items = items.filter(i => Object.keys(i).some(j => this.filter(i[j], search)))
      }

      items = items.sort((a, b) => {
        this.sorting = !this.sorting ? this.headers.find(h => !('sortable' in h) || h.sortable).value : this.sorting
        const sortA = a[this.sorting]
        const sortB = b[this.sorting]

        if (this.desc) {
          if (sortA < sortB) return 1
          if (sortA > sortB) return -1
          return 0
        } else {
          if (sortA < sortB) return -1
          if (sortA > sortB) return 1
          return 0
        }
      })

      return this.hideActions ? items : items.slice(this.pageStart, this.pageStop)
    }
  },

  watch: {
    rowsPerPage () {
      this.page = 1
    },
    indeterminate (val) {
      if (val) this.all = true
    },
    someItems (val) {
      if (!val) this.all = false
    },
    search () {
      this.page = 1
    }
  },

  methods: {
    sort (index) {
      if (this.sorting === null) {
        this.sorting = index
        this.desc = true
      } else if (this.sorting === index && this.desc) {
        this.desc = false
      } else if (this.sorting !== index) {
        this.sorting = index
        this.desc = true
      } else {
        this.sorting = null
        this.desc = null
      }
    },
    genTR (children, data = {}) {
      return this.$createElement('tr', data, children)
    },
    toggle (val) {
      this.all = val

      this.$emit('input', this.value.map(i => {
        i[this.itemValue] = this.filteredItems.includes(i) ? val : false

        return i
      }))
    }
  },

  render (h) {
    return h('v-table-overflow', {}, [
      h('table', {
        'class': {
          'datatable table': true,
          'datatable--select-all': this.selectAll
        }
      }, [
        this.genTHead(),
        this.genTBody(),
        this.hideActions ? null : this.genTFoot()
      ])
    ])
  }
}<commit_msg>fixed auto sort bug (#434)<commit_after>import Head from './mixins/head'
import Body from './mixins/body'
import Foot from './mixins/foot'

export default {
  name: 'datatable',

  mixins: [Head, Body, Foot],

  data () {
    return {
      desc: null,
      page: 1,
      sorting: null,
      all: false
    }
  },

  props: {
    headers: {
      type: Array,
      default: () => []
    },
    headerText: {
      type: String,
      default: 'text'
    },
    hideActions: Boolean,
    items: {
      type: Array,
      default: () => []
    },
    itemValue: {
      default: 'value'
    },
    noDataText: {
      type: String,
      default: 'No data available in table'
    },
    noResultsText: {
      type: String,
      default: 'No matching records found'
    },
    rowsPerPage: {
      type: [Number, String],
      default: 5
    },
    rowsPerPageItems: {
      type: Array,
      default () {
        return [
          5,
          10,
          25,
          { text: 'All', value: -1 }
        ]
      }
    },
    rowsPerPageText: {
      type: String,
      default: 'Rows per page:'
    },
    selectAll: Boolean,
    search: {
      required: false
    },
    filter: {
      type: Function,
      default: (val, search) => {
        return val !== null &&
          ['undefined', 'boolean'].indexOf(typeof val) === -1 &&
          val.toString().toLowerCase().indexOf(search) !== -1
      }
    },
    value: {
      type: Array,
      default: () => []
    }
  },

  computed: {
    indeterminate () {
      return this.selectAll && this.someItems && !this.everyItem
    },
    everyItem () {
      return this.value.every(i => i[this.itemValue])
    },
    someItems () {
      return this.value.some(i => i[this.itemValue])
    },
    pageStart () {
      const page = this.rowsPerPage === Object(this.rowsPerPage)
        ? this.rowsPerPage.value
        : this.rowsPerPage
      return page === -1 ? 0 : (this.page - 1) * page
    },
    pageStop () {
      const page = this.rowsPerPage === Object(this.rowsPerPage)
        ? this.rowsPerPage.value
        : this.rowsPerPage
      return page === -1 ? this.value.length : this.page * page
    },
    filteredItems () {
      let items = this.value.slice()
      const hasSearch = typeof this.search !== 'undefined' && this.search !== null

      if (hasSearch) {
        const search = this.search.toString().toLowerCase()

        items = items.filter(i => Object.keys(i).some(j => this.filter(i[j], search)))
      }

      items = items.sort((a, b) => {
        const sortA = a[this.sorting]
        const sortB = b[this.sorting]

        if (this.desc) {
          if (sortA < sortB) return 1
          if (sortA > sortB) return -1
          return 0
        } else {
          if (sortA < sortB) return -1
          if (sortA > sortB) return 1
          return 0
        }
      })

      return this.hideActions ? items : items.slice(this.pageStart, this.pageStop)
    }
  },

  watch: {
    rowsPerPage () {
      this.page = 1
    },
    indeterminate (val) {
      if (val) this.all = true
    },
    someItems (val) {
      if (!val) this.all = false
    },
    search () {
      this.page = 1
    }
  },

  methods: {
    sort (index) {
      if (this.sorting === null) {
        this.sorting = index
        this.desc = true
      } else if (this.sorting === index && this.desc) {
        this.desc = false
      } else if (this.sorting !== index) {
        this.sorting = index
        this.desc = true
      } else {
        this.sorting = null
        this.desc = null
      }
    },
    genTR (children, data = {}) {
      return this.$createElement('tr', data, children)
    },
    toggle (val) {
      this.all = val

      this.$emit('input', this.value.map(i => {
        i[this.itemValue] = this.filteredItems.includes(i) ? val : false

        return i
      }))
    }
  },

  mounted () {
    this.sorting = !this.sorting ? this.headers.find(h => !('sortable' in h) || h.sortable).value : this.sorting
  },

  render (h) {
    return h('v-table-overflow', {}, [
      h('table', {
        'class': {
          'datatable table': true,
          'datatable--select-all': this.selectAll
        }
      }, [
        this.genTHead(),
        this.genTBody(),
        this.hideActions ? null : this.genTFoot()
      ])
    ])
  }
}
{'fraction_non_alphanumeric': 0.1489115331171839, 'fraction_numerical': 0.005442334414080593, 'mean_word_length': 1.700750469043152, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5648832', 'n_tokens_mistral': 2807, 'n_tokens_neox': 2752, 'n_words': 625}