<template>
  <el-container v-if="isLoadPanel" label-position="top" style="height: inherit;">
    <el-main style="padding: 0px !important; overflow: hidden;">
      <el-container style="height: 100%;">
        <el-header :style="tableHeaderStyle">
          <el-collapse
            v-if="isParent && isAdvancedQuery"
            v-show="isAdvancedQuery"
            v-model="activeNames"
            v-shortkey="{f6: ['f6'], ctrlf: ['ctrl', 'f']}"
            @shortkey.native="actionAdvancedQuery()"
          >
            <el-collapse-item :title="$t('table.dataTable.advancedQuery')" name="1">
              <main-panel
                :container-uuid="containerUuid"
                :parent-uuid="parentUuid"
                :metadata="getterPanel"
                panel-type="table"
                is-advanced-query
                :class="isEmptyValue(activeName) ? 'collapse_item' : 'collapse_item_wrap'"
              />
            </el-collapse-item>
          </el-collapse>
          <div>
            <div v-if="!isMobile">
              <table-menu
                :container-uuid="containerUuid"
                :parent-uuid="parentUuid"
                :panel-type="panelType"
                :is-parent="isParent"
                :is-panel-window="isPanelWindow"
                :is-process-menu="getterContextMenu"
                :is-mobile="isMobile"
                :is-panel="getterPanel"
              />
              <el-button
                v-if="!isParent && isPanelWindow"
                type="text"
                :icon="(getterNewRecords <= 0) ? 'el-icon-circle-plus' : 'el-icon-remove'"
                style="float: right; padding-top: 8px; font-size: larger; padding-left: 6px; color: gray;"
                :disabled="getterNewRecords <= 0 ? isDisabledAddNew : false"
                @click="(getterNewRecords <= 0) ? addNewRow() : callOffNewRecord()"
              />
              <icon-element v-if="!isMobile" icon="el-icon-news">
                <fixed-columns
                  :container-uuid="containerUuid"
                  :panel-type="panelType"
                  class="header-search-input"
                />
              </icon-element>
              <filter-columns
                v-if="isOptional"
                :container-uuid="containerUuid"
                :panel-type="panelType"
                class="field-optional"
              />
              <div :class="{ 'show': showTableSearch }" class="table-search">
                <svg-icon class-name="search-icon" icon-class="search" @click.stop="click()" />
                <el-input
                  ref="headerSearchSelect"
                  v-model="searchTable"
                  size="mini"
                  :placeholder="$t('table.dataTable.search')"
                  class="header-search-select"
                />
              </div>
            </div>
            <div v-else>
              <div v-if="!isParent">
                <fixed-columns
                  :container-uuid="containerUuid"
                  :panel-type="panelType"
                  class="header-search-input"
                />
                <filter-columns
                  v-if="isOptional"
                  :container-uuid="containerUuid"
                  :panel-type="panelType"
                  class="field-optional"
                />
                <div :class="{ 'show' :showTableSearch }" class="table-search">
                  <svg-icon class-name="search-icon" icon-class="search" @click.stop="click()" />
                  <el-input
                    ref="headerSearchSelect"
                    v-model="searchTable"
                    size="mini"
                    :placeholder="$t('table.dataTable.search')"
                    class="header-search-select"
                    clearable
                  />
                </div>
              </div>
              <div v-else class="panel-expand">
                <div :class="{ 'show': showTableSearch }" class="table-search">
                  <svg-icon class-name="search-icon" icon-class="search" @click.stop="click()" />
                  <el-input
                    ref="headerSearchSelect"
                    v-model="searchTable"
                    size="mini"
                    :placeholder="$t('table.dataTable.search')"
                    class="header-search-select-mobile"
                    clearable
                  />
                </div>
                <el-button
                  v-show="isParent && isPanelWindow && isMobile && getDataSelection.length"
                  type="text"
                  icon="el-icon-delete"
                  style="color: black; font-size: 17px; font-weight: 605 !important;"
                  @click="deleteSelection()"
                />
                <icon-element icon="el-icon-news" style="padding-top: 0px;" @click="searchRecordNavegation()">
                  <fixed-columns
                    :container-uuid="containerUuid"
                    :panel-type="panelType"
                    class="header-search-input-mobile"
                  />
                </icon-element>
              </div>
            </div>
          </div>
        </el-header>
        <el-main style="padding: 0px !important; overflow: hidden;">
          <context-menu
            v-if="isParent"
            v-show="getShowContextMenuTable"
            :style="{left:left+'px',top:top+'px'}"
            class="contextmenu"
            :container-uuid="containerUuid"
            :parent-uuid="parentUuid"
            :panel-type="panelType"
            :is-option="isOption"
            :is-panel-window="isPanelWindow"
            :is-process-menu="getterContextMenu"
            :is-mobile="isMobile"
            :is-panel="getterPanel"
          />
          <context-menu
            v-if="!isParent"
            v-show="getShowContextMenuTabChildren"
            :style="{left:left+'px',top:top+'px'}"
            class="contextmenu"
            :container-uuid="containerUuid"
            :parent-uuid="parentUuid"
            :panel-type="panelType"
            :is-option="isOption"
            :is-panel-window="isPanelWindow"
            :is-process-menu="getterContextMenu"
            :is-mobile="isMobile"
            :is-panel="getterPanel"
          />
          <el-table
            ref="multipleTable"
            v-loading="$route.query.action !== 'create-new' && isLoaded"
            v-shortkey="{up: ['arrowup'], down: ['arrowdown'], left: ['arrowleft'], right: ['arrowright']}"
            :height="getHeigthTable"
            style="width: 100%"
            border
            :row-key="getterPanel.keyColumn"
            reserve-selection
            highlight-current-row
            :row-style="rowStyle"
            :data="showTableSearch ? filterResult() : getterDataRecords"
            :element-loading-text="$t('notifications.loading')"
            element-loading-background="rgba(255, 255, 255, 0.8)"
            element-loading-spinner="el-icon-loading"
            cell-class-name="datatable-max-cell-height"
            :show-summary="getterPanel.isShowedTotals"
            :summary-method="getSummaries"
            @shortkey.native="theAction"
            @row-click="handleRowClick"
            @row-dblclick="handleRowDblClick"
            @select="handleSelection"
            @select-all="handleSelectionAll"
            @row-contextmenu="rowMenu"
            @contextmenu.prevent.native="block"
          >
            <el-table-column
              v-if="isTableSelection"
              type="selection"
              :prop="getterPanel.keyColumn"
              fixed
              min-width="50"
            />
            <template v-for="(fieldAttributes, key) in fieldList">
              <el-table-column
                v-if="isDisplayed(fieldAttributes)"
                :key="key"
                :label="headerLabel(fieldAttributes)"
                :column-key="fieldAttributes.columnName"
                :prop="fieldAttributes.columnName"
                sortable
                :formatter="changeOrder"
                min-width="200"
                :class-name="cellClass(fieldAttributes)"
                :fixed="fieldAttributes.isFixedTableColumn"
              >
                <template slot-scope="scope">
                  <template v-if="rowCanBeEdited(scope.row, fieldAttributes)">
                    <field-definition
                      :is-data-table="true"
                      :is-show-label="false"
                      :in-table="true"
                      :metadata-field="{
                        ...fieldAttributes,
                        parentUuid: parentUuid,
                        displayColumn: scope.row['DisplayColumn_' + fieldAttributes.columnName],
                        tableIndex: scope.$index,
                        rowKey: scope.row[getterPanel.keyColumn],
                        keyColumn: getterPanel.keyColumn,
                        recordUuid: scope.row.UUID
                      }"
                      :record-data-fields="scope.row[fieldAttributes.columnName]"
                      size="mini"
                      @keyup.enter.native="confirmEdit(scope.row)"
                    />
                  </template>
                  <template
                    v-else
                  >
                    <el-tag
                      v-if="fieldAttributes.columnName === 'DocStatus' || (fieldAttributes.columnName === 'O_DocStatus')"
                      :style="getFieldDefinition(fieldAttributes.fieldDefinition, scope.row)"
                      :type="fieldAttributes.columnName === 'DocStatus' ? tagStatus(scope.row.DocStatus) : tagStatus(scope.row.O_DocStatus)"
                      disable-transitions
                    >
                      {{ displayedValue(scope.row, fieldAttributes) }}
                    </el-tag>
                    <span v-else :style="getFieldDefinition(fieldAttributes.fieldDefinition, scope.row)">
                      {{ displayedValue(scope.row, fieldAttributes) }}
                    </span>
                  </template>
                </template>
              </el-table-column>
            </template>
          </el-table>
        </el-main>
      </el-container>
    </el-main>
    <el-footer style="height: 30px;">
      <div>
        <div style="float: right;">
          <el-pagination
            small
            layout="slot, total, prev, pager, next"
            :current-page="currentPage"
            :page-size="defaultMaxPagination"
            :total="getterRecordCount"
            @current-change="handleChangePage"
          >
            <template v-slot>
              <span>{{ $t('table.dataTable.selected') }}: {{ getDataSelection.length }} / </span>
            </template>
          </el-pagination>
        </div>
      </div>
    </el-footer>
  </el-container>
</template>

<script>
import FieldDefinition from '@/components/ADempiere/Field'
import Sortable from 'sortablejs'
import FilterColumns from '@/components/ADempiere/DataTable/filterColumns'
import FixedColumns from '@/components/ADempiere/DataTable/fixedColumns'
import ContextMenu from '@/components/ADempiere/DataTable/menu/contextMenu'
import TableMenu from '@/components/ADempiere/DataTable/menu'
import IconElement from '@/components/ADempiere/IconElement'
import { formatDate } from '@/filters/ADempiere'
import MainPanel from '@/components/ADempiere/Panel'
import { sortFields } from '@/utils/ADempiere'
import { FIELD_READ_ONLY_FORM } from '@/components/ADempiere/Field/references'
import { fieldIsDisplayed } from '@/utils/ADempiere'
import { supportedTypes, exportFileFromJson } from '@/utils/ADempiere/exportUtil'
import evaluator from '@/utils/ADempiere/evaluator'

export default {
  name: 'DataTable',
  components: {
    FieldDefinition,
    FilterColumns,
    FixedColumns,
    ContextMenu,
    IconElement,
    MainPanel,
    TableMenu
  },
  props: {
    parentUuid: {
      type: String,
      default: undefined
    },
    containerUuid: {
      type: String,
      required: true
    },
    panelType: {
      type: String,
      default: 'window'
    },
    // is used in root view with primary records
    isParent: {
      type: Boolean,
      default: false
    },
    // Show input section from search in data
    isSearchable: {
      type: Boolean,
      default: false
    },
    // Show check from selection row
    isTableSelection: {
      type: Boolean,
      default: true
    },
    // Show check from selection row, send to panel form
    isShowedPanelRecord: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      top: 0,
      left: 0,
      isOption: {},
      activeNames: ['0'],
      focusTable: false,
      currentRow: null,
      currentTable: 0,
      visible: this.getShowContextMenuTable,
      searchTable: '', // text from search
      defaultMaxPagination: 100,
      option: supportedTypes,
      menuTable: '1',
      activeName: this.$route.query.action === 'advancedQuery' ? '1' : '',
      isOptional: false,
      isFixed: false,
      isLoadPanelFromServer: false,
      rowStyle: { height: '52px' },
      sortable: null,
      isExpand: false,
      currentPage: 1,
      uuidCurrentRecordSelected: '',
      showTableSearch: false,
      isAdvancedQuery: true
    }
  },
  computed: {
    getterContextMenu() {
      var process = this.$store.getters.getContextMenu(this.containerUuid).actions
      if (process) {
        return process.filter(menu => {
          if (menu.type === 'process') {
            return menu
          }
        })
      }
      return false
    },
    getShowContextMenuTable() {
      return this.$store.getters.getShowContextMenuTable
    },
    getShowContextMenuTabChildren() {
      return this.$store.getters.getShowContextMenuTabChildren
    },
    getterFieldList() {
      return this.$store.getters.getFieldsListFromPanel(this.containerUuid)
    },
    getterFieldListHeader() {
      return this.getterFieldList.filter(fieldItem => {
        const isDisplayed = fieldItem.isDisplayed || fieldItem.isDisplayedFromLogic
        if (fieldItem.isActive && isDisplayed && !fieldItem.isKey) {
          return fieldItem.name
        }
      }).map(fieldItem => {
        return fieldItem.name
      })
    },
    getterFieldListValue() {
      var value = this.getterFieldList.filter(fieldItem => {
        const isDisplayed = fieldItem.isDisplayed || fieldItem.isDisplayedFromLogic
        if (fieldItem.isActive && isDisplayed && !fieldItem.isKey) {
          return fieldItem
        }
      })
      return value.map(fieldItem => {
        if (fieldItem.componentPath === 'FieldSelect') {
          return 'DisplayColumn_' + fieldItem.columnName
        } else {
          return fieldItem.columnName
        }
      })
    },
    isMobile() {
      return this.$store.state.app.device === 'mobile'
    },
    classTableMenu() {
      if (this.isMobile) {
        return 'menu-table-mobile'
      } else if (this.$store.state.app.sidebar.opened) {
        return 'menu-table'
      }
      return 'menu-table'
    },
    getterPanel() {
      return this.$store.getters.getPanel(this.containerUuid)
    },
    getterDataRecordsAndSelection() {
      return this.$store.getters.getDataRecordAndSelection(this.containerUuid)
    },
    getterRecordCount() {
      return this.getterDataRecordsAndSelection.recordCount
    },
    getterDataRecords() {
      return this.getterDataRecordsAndSelection.record
    },
    getterNewRecords() {
      if (this.isPanelWindow && !this.isParent) {
        var newRecordTable = this.getterDataRecordsAndSelection.record.filter(recordItem => {
          return recordItem.isNew
        })
        return newRecordTable.length
      }
      return 0
    },
    getPageNumber() {
      return this.getterDataRecordsAndSelection.pageNumber
    },
    isLoaded() {
      return !this.getterDataRecordsAndSelection.isLoaded
    },
    getDataSelection() {
      return this.getterDataRecordsAndSelection.selection
    },
    getterFieldIsDisplayed() {
      return this.$store.getters.getFieldsIsDisplayed(this.containerUuid)
    },
    getterIsShowedCriteria() {
      var browser = this.$store.getters.getBrowser(this.containerUuid)
      if (browser) {
        return browser.isShowedCriteria
      }
      return false
    },
    getHeightPanelBottom() {
      return this.$store.getters.getSplitHeight - 25
    },
    getterHeight() {
      return this.$store.getters.getHeigth
    },
    tableHeaderStyle() {
      if (this.isAdvancedQuery) {
        if (!this.isEmptyValue(this.activeName)) {
          return {
            height: '55%',
            overflow: 'auto'
          }
        }
        return {
          height: '17%',
          overflow: 'hidden'
        }
      }
      return {
        height: '5%'
      }
    },
    getHeigthTable() {
      if (this.isPanelWindow) {
        // table record navigation
        if (this.isParent) {
          if (this.isAdvancedQuery) {
            if (this.isEmptyValue(this.activeName)) {
              return this.getterHeight - 220
            } else {
              return this.getterHeight - 420
            }
          } else {
            return this.getterHeight - 180
          }
        }
        if (!this.isExpand) {
          return this.getHeightPanelBottom + 'vh'
        }
        return this.getterHeight - 220
      } else if (this.panelType === 'browser') {
        // open browser criteria
        if (this.getterIsShowedCriteria) {
          // showed some field query criteria
          if (this.getterFieldIsDisplayed.isDisplayed) {
            return this.getterHeight - 495
          }
          return this.getterHeight - 415
        }
        return this.getterHeight - 290
      }
      return this.getterHeight - 300
    },
    fieldList() {
      if (this.getterPanel && this.getterPanel.fieldList) {
        return this.sortFields(
          this.getterPanel.fieldList,
          this.panelType !== 'browser' ? 'seqNoGrid' : 'sequence'
        )
      }
      return []
    },
    isLoadPanel() {
      if (this.getterPanel && this.getterPanel.fieldList) {
        return true
      }
      return false
    },
    windowFields() {
      if (this.isAdvancedQuery) {
        return this.$store.getters.getPanelParameters(this.containerUuid, false, [], this.isAdvancedQuery).params
      }
      return undefined
    },
    isPanelWindow() {
      return Boolean(this.panelType === 'window')
    },
    getterContextClientId() {
      if (this.isPanelWindow) {
        return parseInt(this.$store.getters.getContextClientId, 10)
      }
      return undefined
    },
    isReadOnlyParent() {
      if (this.isPanelWindow) {
        if (this.$store.getters.getContextIsActive(this.parentUuid) === false) {
          return true
        }
        if (this.$store.getters.getContextProcessing(this.parentUuid) === true ||
          this.$store.getters.getContextProcessing(this.parentUuid) === 'Y') {
          return true
        }
        if (this.$store.getters.getContextProcessed(this.parentUuid)) {
          return true
        }
      }
      return false
    },
    isDisabledAddNew() {
      if (this.isParent) {
        return true
      }
      if (this.$route.query.action === 'create-new') {
        return true
      }
      if (!this.getterPanel.isInsertRecord) {
        return true
      }
      if (this.isReadOnlyParent) {
        return true
      }
      if (this.getterNewRecords) {
        return true
      }
      return false
    },
    permissionRoutes() {
      return this.$store.getters.permission_routes
    }
  },
  watch: {
    visible(value) {
      if (value) {
        document.body.addEventListener('click', this.closeMenu)
      } else {
        document.body.removeEventListener('click', this.closeMenu)
      }
    }
  },
  created() {
    this.getPanel()
  },
  beforeMount() {
    this.currentPage = this.getPageNumber
  },
  mounted() {
    if (this.isTableSelection) {
      this.toggleSelection(this.getDataSelection)
    }
  },
  methods: {
    actionAdvancedQuery() {
      if (this.activeNames < 1) {
        this.activeNames = '1'
      } else {
        this.activeNames = '0'
      }
    },
    setCurrent(row) {
      this.$refs.multipleTable.setCurrentRow(row)
    },
    setCurrentParent(row) {
      this.$refs.Parent.setCurrentRow(row)
    },
    theAction(event) {
      switch (event.srcKey) {
        case 'up':
          this.currentTable = this.currentTable - 1
          break
        case 'down':
          this.currentTable = this.currentTable + 1
          break
      }
      this.handleRowClick(this.getterDataRecords[this.currentTable])
      return this.setCurrent(this.getterDataRecords[this.currentTable])
    },
    sortTab(actionSequence) {
      // TODO: Refactor and remove redundant dispatchs
      this.$store.dispatch('setShowDialog', {
        type: 'window',
        action: actionSequence,
        parentRecordUuid: this.$route.query.action
      })
    },
    closeMenu() {
      this.$store.dispatch('showMenuTable', {
        isShowedTable: false
      })
      this.$store.dispatch('showMenuTabChildren', {
        isShowedTabChildren: false
      })
    },
    block() {
      return false
    },
    rowMenu(row, column, event) {
      const menuMinWidth = 105
      const offsetLeft = this.$el.getBoundingClientRect().left // container margin left
      const offsetWidth = this.$el.offsetWidth // container width
      const maxLeft = offsetWidth - menuMinWidth // left boundary
      const left = event.clientX - offsetLeft + 15 // 15: margin right

      if (left > maxLeft) {
        this.left = maxLeft
      } else {
        this.left = left
      }
      if (this.isParent) {
        this.top = event.clientY - 100
        this.isOption = row
        this.visible = true
        this.$store.dispatch('showMenuTable', {
          isShowedTable: true
        })
        this.$store.dispatch('showMenuTabChildren', {
          isShowedTabChildren: false
        })
      } else {
        this.top = event.clientY - event.screenY
        this.isOption = row
        this.visible = true
        this.$store.dispatch('showMenuTabChildren', {
          isShowedTabChildren: true
        })
        this.$store.dispatch('showMenuTable', {
          isShowedTable: false
        })
      }
    },
    typeFormat(key, keyPath) {
      Object.keys(supportedTypes).forEach(type => {
        if (type === key) {
          this.exporRecordTable(key)
        }
      })
    },
    exporRecordTable(key) {
      const Header = this.getterFieldListHeader
      const filterVal = this.getterFieldListValue
      const list = this.getDataSelection
      const data = this.formatJson(filterVal, list)
      exportFileFromJson({
        header: Header,
        data,
        filename: '',
        exportType: key
      })
    },
    formatJson(filterVal, jsonData) {
      return jsonData.map(v => filterVal.map(j => v[j]))
    },
    sortFields,
    handleChange(val) {
      val = !val
    },
    showTotals() {
      this.$store.dispatch('showedTotals', this.containerUuid)
    },
    showOnlyMandatoryColumns() {
      this.$store.dispatch('showOnlyMandatoryColumns', {
        containerUuid: this.containerUuid
      })
    },
    showAllAvailableColumns() {
      this.$store.dispatch('showAllAvailableColumns', {
        containerUuid: this.containerUuid
      })
    },
    headerLabel(field) {
      if (field.isMandatory || field.isMandatoryFromLogic) {
        return '* ' + field.name
      }
      return field.name
    },
    /**
     * add a tab depending on the status of the document
     * @param {string} tag, document status key
     */
    tagStatus(tag) {
      var type
      switch (tag) {
        case 'VO':
          type = 'danger'
          break
        case 'AP':
          type = 'success'
          break
        case 'DR':
          type = 'info'
          break
        case 'CL':
          type = 'primary'
          break
        case 'CO':
          type = 'success'
          break
        case '??':
          type = 'info'
          break
        case 'IP':
          type = 'warning'
          break
        case 'WC':
          type = 'warning'
          break
        case 'WP':
          type = 'warning'
          break
        case 'NA':
          type = 'danger'
          break
        case 'IN':
          type = 'danger'
          break
        case 'RE':
          type = 'danger'
          break
      }
      return type
    },
    /**
     * @param {object} row, row data
     * @param {object} field, field with attributes
     */
    displayedValue(row, field) {
      if (typeof row[field.columnName] === 'boolean') {
        // replace boolean true-false value for 'Yes' or 'Not'
        return row[field.columnName] ? this.$t('components.switchActiveText') : this.$t('components.switchInactiveText')
      } else if (field.componentPath === 'FieldDate' || field.componentPath === 'FieldTime') {
        let cell = row[field.columnName]
        if (Object.prototype.toString.call(cell) === '[object Date]') {
          cell = cell.getTime()
        }
        // replace number timestamp value for date
        return formatDate(cell, field.referenceType)
      } else if (field.componentPath === 'FieldNumber') {
        if (this.isEmptyValue(row[field.columnName])) {
          return undefined
        }
        return this.formatNumber({ referenceType: field.referenceType, number: row[field.columnName] })
      }
      return row['DisplayColumn_' + field.columnName] || row[field.columnName]
    },
    rowCanBeEdited(record, fieldAttributes) {
      if (!this.isParent) {
        if (this.isPanelWindow) {
          // getter with context
          if (this.isReadOnlyParent) {
            return false
          }
          // if is IsActive, Processed, Processing
          if (this.isReadOnlyRow(record, fieldAttributes)) {
            return false
          }
        }
        // if isReadOnly, isReadOnlyFromLogic
        if (this.isReadOnlyCell(record, fieldAttributes)) {
          return false
        }
        if (record.isEdit) {
          return true
        }
      }
      return false
    },
    isReadOnlyRow(row, field) {
      // evaluate context
      if (this.getterContextClientId !== parseInt(row.AD_Client_ID, 10)) {
        return true
      }
      if (fieldIsDisplayed(field)) {
        // const fieldReadOnlyAllForm = FIELD_READ_ONLY_FORM.filter(item => {
        //   return row.hasOwnProperty(item.columnName) && item.isChangedAllForm
        // })
        // // columnName: Processed, Processing
        // if (fieldReadOnlyAllForm.length) {
        //   var isReadOnlyAllRow = Boolean(fieldReadOnlyAllForm.find(item => row[item.columnName] === item.valueIsReadOnlyForm))
        //   return isReadOnlyAllRow
        // }

        // columnName: IsActive
        const fieldReadOnlyForm = FIELD_READ_ONLY_FORM.find(item => {
          return row.hasOwnProperty(item.columnName) && !item.isChangedAllForm
        })
        if (fieldReadOnlyForm) {
          var isReadOnlyRow = row[fieldReadOnlyForm.columnName] === fieldReadOnlyForm.valueIsReadOnlyForm && field.columnName !== fieldReadOnlyForm.columnName
          return isReadOnlyRow
        }
      }
      return false
    },
    isReadOnlyCell(row, field) {
      // TODO: Add support to its type fields
      if (field.componentPath === 'FieldImage' || field.componentPath === 'FieldBinary') {
        return true
      }

      const isUpdateableAllFields = field.isReadOnly || field.isReadOnlyFromLogic
      if (this.isPanelWindow) {
        if (field.columnName === this.getterPanel.linkColumnName ||
          field.columnName === this.getterPanel.fieldLinkColumnName) {
          return true
        }
        // edit mode is diferent to create new
        const editMode = !this.isEmptyValue(row.UUID)
        return (!field.isUpdateable && editMode) || (isUpdateableAllFields || field.isReadOnlyFromForm)
      } else if (this.panelType === 'browser') {
        // browser result
        return field.isReadOnly
      }
      // other type of panels (process/reports)
      return isUpdateableAllFields
    },
    deleteSelection() {
      this.$store.dispatch('deleteSelectionDataList', {
        parentUuid: this.parentUuid,
        containerUuid: this.containerUuid
      })
      this.$store.dispatch('setRecordSelection', {
        parentUuid: this.parentUuid,
        containerUuid: this.containerUuid,
        panelType: this.panelType
      })
    },
    callOffNewRecord() {
      this.getterDataRecords.shift()
    },
    addNewRow() {
      if (this.getterNewRecords <= 0) {
        this.$store.dispatch('addNewRow', {
          parentUuid: this.parentUuid,
          containerUuid: this.containerUuid,
          fieldList: this.fieldList,
          isEdit: true,
          isSendServer: false
        })
      } else {
        const fieldsEmpty = this.$store.getters.getFieldListEmptyMandatory({ containerUuid: this.containerUuid })
        this.$message({
          message: this.$t('notifications.mandatoryFieldMissing') + fieldsEmpty,
          type: 'info'
        })
      }
    },
    optionalPanel() {
      this.showTableSearch = false
      this.isOptional = !this.isOptional
    },
    fixedPanel() {
      this.showTableSearch = false
      this.isFixed = !this.isFixed
    },
    expandPanel() {
      this.isExpand = !this.isExpand
    },
    async getList() {
      this.oldgetDataDetail = this.getterDataRecords.map(v => v.id)
      this.newgetDataDetail = this.oldgetDataDetail.slice()
      this.$nextTick(() => {
        this.setSort()
      })
    },
    setSort() {
      if (!this.isMobile) {
        const el = this.$refs.multipleTable.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
        this.sortable = Sortable.create(el, {
          ghostClass: 'sortable-ghost', // Class name for the drop placeholder,
          setData: function(dataTransfer) {
            // to avoid Firefox bug
            // Detail see : https://github.com/RubaXa/Sortable/issues/1012
            dataTransfer.setData('Text', '')
          },
          onEnd: evt => {
            const targetRow = this.getterDataRecords.splice(evt.oldIndex, 1)[0]
            this.getterDataRecords.splice(evt.newIndex, 0, targetRow)

            // for show the changes, you can delete in you code
            const tempIndex = this.newgetDataDetail.splice(evt.oldIndex, 1)[0]
            this.newgetDataDetail.splice(evt.newIndex, 0, tempIndex)
          }
        })
      }
    },
    changeOrder() {
      var reversed = this.getterDataRecords.reverse()
      return reversed
    },
    /**
     * @param {object} field
     */
    cellClass(field) {
      var classReturn = ''
      if (field.isReadOnly) {
        classReturn += 'cell-no-edit'
      }
      if (field.componentPath === 'FieldNumber') {
        classReturn += 'cell-align-right'
      }
      // return 'cell-edit'
      return classReturn
    },
    /**
     * Select or unselect rows
     * USE ONLY MOUNTED
     */
    toggleSelection(rows) {
      if (rows) {
        rows.forEach(row => {
          this.$refs.multipleTable.toggleRowSelection(row)
        })
      } else {
        this.$refs.multipleTable.clearSelection()
      }
    },
    confirmEdit(row) {
      const fieldsEmpty = this.$store.getters.getFieldListEmptyMandatory({
        containerUuid: this.containerUuid,
        row: row
      })

      if (row.isNew) {
        row.isEdit = true
        this.$message({
          message: this.$t('notifications.mandatoryFieldMissing') + fieldsEmpty,
          type: 'info'
        })
        return
      }

      if (row.isEdit && fieldsEmpty) {
        row.isEdit = false
        this.$message({
          message: this.$t('notifications.mandatoryFieldMissing') + fieldsEmpty,
          type: 'info'
        })
        return
      }
      row.isEdit = false
    },
    handleRowClick(row, column, event) {
      this.currentTable = this.getterDataRecords.findIndex(item => item.UUID === row.UUID)
      if (this.isShowedPanelRecord && this.isParent) {
        if (this.uuidCurrentRecordSelected !== row.UUID) {
          this.uuidCurrentRecordSelected = row.UUID
          // disabled rollback when change route
          this.$store.dispatch('setDataLog', {})
        }
        this.$router.push({
          query: {
            ...this.$route.query,
            action: row.UUID
          },
          params: {
            tableName: this.getterPanel.tableName,
            recordId: row[`${this.getterPanel.tableName}_ID`]
          }
        })
      } else {
        if (!row.isEdit) {
          row.isEdit = true
          /*
          var inSelection = this.getDataSelection.some(item => {
            return JSON.stringify(item) === JSON.stringify(row)
          })
          if (inSelection) {
            row.isEdit = true
          }
          */
        }
      }
    },
    handleRowDblClick(row, column, event) {
      if (!this.isShowedPanelRecord) {
        this.confirmEdit(row)
      }
    },
    handleSelection(rowsSelection, rowSelected) {
      this.$store.dispatch('setSelection', {
        containerUuid: this.containerUuid,
        selection: rowsSelection
      })
    },
    isAllSelected(selection = 0) {
      if (selection > 0) {
        var data = this.getterDataRecords
        return data.length === selection
      }
      return false
    },
    handleSelectionAll(rowsSelection) {
      // var selectAll = false
      // if (this.isAllSelected(rowsSelection.length)) {
      //   selectAll = true
      // }
      this.$store.dispatch('setSelection', {
        containerUuid: this.containerUuid,
        selection: rowsSelection
      })
      // rowsSelection.forEach(row => {
      //   row.isEdit = selectAll
      // })
    },
    filterResult() {
      var data = []
      data = this.getterDataRecords.filter(rowItem => {
        if (this.searchTable.trim().length) {
          let find = false
          Object.keys(rowItem).forEach(key => {
            if (String(rowItem[key]).toLowerCase().includes(String(this.searchTable).toLowerCase())) {
              find = true
              return find
            }
          })
          return find
        }
        return true
      })
      return data
    },
    /**
     * Verify is displayed field in column table
     */
    isDisplayed(field) {
      var isDisplayed = field.isDisplayed && field.isDisplayedFromLogic && field.isShowedTableFromUser && !field.isKey
      //  Verify for displayed and is active
      return field.isActive && isDisplayed
    },
    /**
     * Get the tab object with all its attributes as well as the fields it contains
     */
    getPanel() {
      // get panel from server only window and tab children
      if (this.isPanelWindow && !this.isParent && !this.getterPanel) {
        this.$store.dispatch('getPanelAndFields', {
          containerUuid: this.containerUuid,
          parentUuid: this.parentUuid,
          panelType: this.panelType
        }).then(response => {
          this.isLoadPanelFromServer = true
        }).catch(error => {
          console.warn('FieldList Load Error ' + error.code + ': ' + error.message)
        })
      }
    },
    /**
     * @param columns
     * @param data
     */
    getSummaries(parameters) {
      const { columns } = parameters
      const sums = []
      if (!this.getterPanel.isShowedTotals) {
        return
      }

      columns.forEach((column, index) => {
        if (index === 0) {
          sums[index] = 'Σ'
          return
        }
        const field = this.fieldList.find(field => field.columnName === column.property)
        if (field.componentPath !== 'FieldNumber') {
          sums[index] = ''
          return
        }
        const values = this.getDataSelection.map(item => Number(item[column.property]))
        if (values.every(value => isNaN(value))) {
          sums[index] = ''
        } else {
          const total = values.reduce((prev, curr) => {
            const value = Number(curr)
            if (!isNaN(value)) {
              return prev + curr
            }
            return prev
          }, 0)
          sums[index] = this.formatNumber({ referenceType: field.referenceType, number: total })
        }
      })

      return sums
    },
    formatNumber({ referenceType, number }) {
      let fixed = 0
      if (['Amount', 'Costs+Prices', 'Number'].includes(referenceType)) {
        fixed = 2
      }
      return new Intl.NumberFormat().format(number.toFixed(fixed))
    },
    handleChangePage(newPage) {
      this.$store.dispatch('setPageNumber', {
        parentUuid: this.parentUuid,
        containerUuid: this.containerUuid,
        pageNumber: newPage,
        panelType: this.panelType
      })
    },
    click() {
      this.isOptional = false
      this.showTableSearch = !this.showTableSearch
      if (this.showTableSearch) {
        this.$refs.headerSearchSelect && this.$refs.headerSearchSelect.focus()
      }
    },
    activeAdvancedQuery(value) {
      this.isAdvancedQuery = value
      if (value) {
        this.$store.dispatch('setOldAction', this.$route.query.action)
        this.$router.push({
          query: {
            ...this.$route.query,
            action: 'advancedQuery'
          }
        })
      }
      if (!value) {
        var oldAction = this.$store.getters.getOldAction
        this.$router.push({
          query: {
            ...this.$route.query,
            action: oldAction
          }
        })
      }
    },
    getFieldDefinition(fieldDefinition, row) {
      var styleSheet = ''
      if (fieldDefinition && (fieldDefinition.id !== null || fieldDefinition.conditionsList.length)) {
        fieldDefinition.conditionsList.forEach(condition => {
          var columns = evaluator.parseDepends(condition.condition)
          var conditionLogic = condition.condition
          columns.forEach(column => {
            conditionLogic = conditionLogic.replace(/@/g, '')
            conditionLogic = conditionLogic.replace(column, row[column])
            conditionLogic = evaluator.evaluateLogic({
              logic: conditionLogic
            })
          })
          if (conditionLogic && condition.isActive) {
            styleSheet = condition.styleSheet
          }
        })
      }
      return styleSheet
    },
    zoomRecord() {
      const browserMetadata = this.$store.getters.getBrowser(this.$route.meta.uuid)
      const elementName = browserMetadata.fieldList.find(field => field.columnName === browserMetadata.keyColumn).elementName
      const records = []
      this.getDataSelection.forEach(record => {
        if (!isNaN(record[browserMetadata.keyColumn])) {
          records.push(Number(record[browserMetadata.keyColumn]))
        } else {
          records.push(record[browserMetadata.keyColumn])
        }
      })

      this.$store.dispatch('getWindowByUuid', { routes: this.permissionRoutes, windowUuid: browserMetadata.window.uuid })
      var windowRoute = this.$store.getters.getWindowRoute(browserMetadata.window.uuid)
      this.$router.push({
        name: windowRoute.name,
        query: {
          action: 'advancedQuery',
          [elementName]: records
        }
      })
    }
  }
}
</script>

<style lang="scss">
 .contextmenu {
    margin: 0;
    background: #fff;
    z-index: 3000;
    position: absolute;
    list-style-type: none;
    padding: 5px 0;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 400;
    color: #333;
    box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
    li {
      margin: 0;
      padding: 7px 16px;
      cursor: pointer;
      &:hover {
        background: #eee;
      }
    }
  }
  .el-table-row {
    .hover-row {
      background-color: black;
    }
    .current-row {
      .hover-row {
        background-color: initial !important;
      }
    }
  }
</style>
<style>
  .el-table > .cell {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    overflow: hidden;
    max-height: 41px;
    text-overflow: ellipsis;
    white-space: nowrap;
    word-break: break-all;
    line-height: 23px;
    padding-left: 10px;
    padding-right: 10px;
  }
  .el-table .cell {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    overflow: hidden;
    max-height: 50px;
    text-overflow: ellipsis;
    white-space: nowrap;
    word-break: break-all;
    line-height: 23px;
    padding-left: 10px;
    padding-right: 10px;
  }

  .tr.current-row > td {
    background-color: initial !important;
    /* background-color: #e8f4ff; */
  }
  .hover-row > tr {
    background-color: initial !important;
  }
  .hover-row > td {
    background-color: initial !important;
  }
  .header-table-records {
    height: 45px !important;
    padding: 0 !important;
  }
  .icon-mobile {
    padding-right: 5%;
  }
  .el-table th, .el-table td {
    padding: 12px 0;
    min-width: 0;
    height: 64px;
    max-height: 407px;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    text-overflow: ellipsis;
    vertical-align: middle;
    position: relative;
    text-align: left;
  }
  .el-menu.el-menu--horizontal {
    border-bottom: solid 0px transparent !important;
  }
  .menu-table {
    width: 75px;
    float: right;
    height: 39px !important;
  }
  .menu-table-mobile {
    height: 39px !important;
    width: 35px;
    float: right;
  }
  ul.menu-table > .el-submenu {
    height: 39px !important;
    line-height: 39px !important;
    padding: 0 10px;
  }
  ul.menu-table > .el-submenu > .el-submenu__title {
    line-height: 39px !important;
    height: 39px !important;
    padding: 0;
  }
  .el-submenu__title {
    border-bottom: 0px !important;
    color: #303133;
  }
  .panel-expand {
    float: right;
    padding-right: 40px;
    display: flex;
  }
  .field-optional {
    margin: 3px 10px;
    float: right;
  }

  /* used in cell type number */
  td.cell-align-right {
    text-align: right !important;
  }
  .el-collapse {
    border-top: 1px solid #e6ebf5;
    border-bottom: 1px solid #e6ebf5;
    overflow: hidden;
    width: 100%;
  }
</style>
<style lang="scss" scoped>
  .collapse_item_wrap {
    min-height: 180px;
    max-height: 180px;
    will-change: height;
    background-color: #fff;
    overflow: auto;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    border-bottom: 1px solid #e6ebf5;
  }
  .el-table__header-wrapper {
    .el-table__footer-wrapper {
      overflow: auto;
      /* background: black; */
    }
  }
  /* style in cursor if cell is no edit */
  .cell-no-edit {
    cursor: not-allowed !important;
  }
  .cell-edit {
    cursor: pointer !important;
  }

  .table-root {
    padding-right: 0px;
    .table-footer {
      bottom: 0px;
      float: right;
      text-align: right;
      padding: 10px;
    }
  }
  .table-search {
    font-size: 0 !important;
    float: right;
    color: #5a5e66;
    height: 39px !important;
    line-height: 39px !important;
      .search-icon {
        cursor: pointer;
        font-size: 18px;
        vertical-align: middle;
      }
    .header-search-select {
      transition: width 0.2s;
      width: 0 !important;
      overflow: hidden;
      background: transparent;
      border-radius: 0;
      display: inline-block;
      vertical-align: middle;

      /deep/ .el-input__inner {
        border-radius: 0;
        border: 0;
        padding-left: 0;
        padding-right: 0;
        box-shadow: none !important;
        border-bottom: 1px solid #d9d9d9;
        vertical-align: middle;
      }
    }
    &.show {
      .header-search-select {
        width: 190px !important;
        margin-left: 10px;
      }
    }
    .header-search-select-mobile {
      transition: width 0.2s;
      width: 0 !important;
      overflow: hidden;
      background: transparent;
      border-radius: 0;
      display: inline-block;
      vertical-align: middle;

      /deep/ .el-input__inner {
        border-radius: 0;
        border: 0;
        padding-left: 0;
        padding-right: 0;
        box-shadow: none !important;
        border-bottom: 1px solid #d9d9d9;
        vertical-align: middle;
      }
    }
    &.show{
      .header-search-select-mobile {
        width: 120px !important;
        margin-left: 5px;
      }
    }
  }
</style>
