import axios from 'axios'
import dataSetUtils from '../../../classes/dataSetUtils'
import constructors from '../../../classes/constructors'
import { uuid } from 'vue-uuid'
import Router from 'vue-router'


const storeUtils = { 
  router: null,
  pRouter: Promise.resolve()
}

export default {
  addLog: ({ commit }, payload) => {
    commit('ADD_LOG', payload)
  },
  setSessionId: ({ commit }, payload) => {
    commit('SET_SESSIONID', payload)
  },
  setRouter(_, { router }) {
    storeUtils.router = router
  },
  checkRouter({ dispatch }) {
    if (storeUtils.router instanceof Router)
      return true
    dispatch('setErrors', { errors: 'Błąd techniczny: brak routera.\nSkontaktuj się z administratorem aplikacji.' })
    return false
  },
  setLanguageSuffix: ({ commit }, payload) => {
    commit('SET_LANGUAGESUFFIX', payload)
  },
  setLookupDefVisible: ({ commit, getters }, payload) => {
    let lookupDef = getters.getDataSetLookupDef(
      payload.appWindowIdent,
      payload.dataSetIdent,
      payload.dataFieldIdent
    )
    let lookupVisible = payload.lookupVisible
    let appWindow = getters.getAppWindow(lookupDef.appWindowIdentLookup)
    commit('SET_LOOKUP_DEF_VISIBLE', { 
      lookupDef: lookupDef, 
      lookupVisible: lookupVisible, 
      dataSet: payload.dataSet, 
      row: payload.row, 
      appWindowUniqIdent: payload.appWindowIdent 
    })
    commit('SET_APPWINDOW_LOOKUP_DEF', { 
      lookupDef, 
      appWindow
    })
  },
  setLookupDefSelection: async ({ dispatch, commit, getters }, payload) => {
    let lookupDef = getters.getAppWindowLookupDef(payload.appWindowIdent)
    if (lookupDef !== null) {
      let lookupVisible = false
      let {row, sourceKind} = lookupDef
      await commit('SET_LOOKUP_DEF_VISIBLE', { 
        lookupDef: lookupDef, 
        lookupVisible: lookupVisible, 
        dataSet: payload.dataSet, 
        row: payload.row
      })
      await dispatch('deleteDataSetWhereListsItem', {
        appWindowIdent: lookupDef.appWindowUniqIdent,
        dataSetIdent: lookupDef.dataSetIdent,
        dataFieldIdent: lookupDef.dataFieldIdent,
        sourceKind: sourceKind,
        row: row
      })
      await dispatch('fillDataSetsFromSetters', {
        appWindowIdent: payload.appWindowIdent,
        lookupAppWindowIdent: lookupDef.appWindowUniqIdent,
        lookupDataSetIdent: lookupDef.dataSetIdent,
        lookupDataFieldIdent: lookupDef.dataFieldIdent,
        lookupIsMultiSelect: lookupDef.isMultiSelect,
        sourceKind: sourceKind,
        row: row
      })
    }
  },
  setErrors: ({getters, commit, dispatch}, payload) => {
    if (!payload)
      return
    let errors = payload.errors, row = payload.row, appWindowIdent = payload.appWindowIdent, 
      dataSetIdent = payload.dataSetIdent, id = payload.id, action = payload.action
    if (!errors) return
    if (!Array.isArray(errors)) {
      if (errors.code && errors.originalError && errors.originalError.info) {
        errors = [
          { messageText: errors.originalError.info.message }
        ]
      } else {
        errors = [{ messageText: errors }]
      }
    }
    errors.forEach(error => {
      error = { ...error, appWindowIdent: appWindowIdent, dataSetIdent: dataSetIdent, row: row, __uuid: id, isVisible: true }
      let autoCloseTimeout = error.autoCloseTimeout
      let showKind = error.showKind === null || error.showKind === undefined ? 0 : error.showKind
      if (
        appWindowIdent &&
        dataSetIdent &&
        error.errorFields
      ) {
        let messageType = error.messageType === null || error.messageType === undefined ? 1 : error.messageType
        error.errorFields.forEach(errorField => {
          let fieldsType = getters.getFieldsType(messageType)
          let autoCloseTimeoutId
          if (autoCloseTimeout) {
            autoCloseTimeoutId = setTimeout(() =>
              dispatch('removeError', {
                error: error
              }), autoCloseTimeout)
          }
          if (row) {
            let rowMessageField = getters.getRowMessageFields(row, fieldsType, errorField.errorField)
            if(rowMessageField != null && rowMessageField.autoCloseTimeoutIdToClear != null) {
              commit('MESSAGE_FIELD_CLEAR_TIMEOUT', {messageField: rowMessageField})
            }
            commit('ADD_ROW_MESSAGE_FIELD', {
              row: row,
              fieldsType: fieldsType,
              messageField: errorField.errorField,
              message: {
                messageText: error.messageText,
                messageType: messageType,
                showKind: showKind,
                autoCloseTimeoutId: autoCloseTimeoutId
              }
            })
          } else {
            let dataSet = getters.getDataSet(appWindowIdent, dataSetIdent)
            let dataSetMessageField = getters.getDataSetMessageField(dataSet, fieldsType, errorField.errorField)
            if(dataSetMessageField != null && dataSetMessageField.autoCloseTimeoutIdToClear != null) {
              commit('MESSAGE_FIELD_CLEAR_TIMEOUT', {messageField: dataSetMessageField})
            }
            commit('ADD_DATASET_MESSAGE_FIELD', {
              dataSet: dataSet,
              fieldsType: fieldsType,
              messageField: errorField.errorField,
              message: {
                messageText: error.messageText,
                messageType: messageType,
                showKind: showKind,
                autoCloseTimeoutId: autoCloseTimeoutId
              }
            })
          }
        })
      }
      if (showKind == 0) commit('ADD_ERROR', {error})
    })
    commit('SET_DATASET_ACTION_STATE', {row: row, action: action, state: -1})
  },
  fillDataSetWhere: async ({ dispatch, getters }, payload) => {
    let appWindowIdentFrom
    let dataSetIdentFrom
    let dataSetsFrom
    let dataSetsFromItem
    let dataSetFrom
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    let whereList
    if (dataSet) {
      dataSetsFrom = dataSet.dataSetsFrom
    }
    if (dataSetsFrom != null) {
      for (let i = 0; i < dataSetsFrom.length; i++) {
        dataSetsFromItem = dataSetsFrom[i]
        appWindowIdentFrom = dataSetsFromItem.appWindowIdentFrom
        dataSetIdentFrom = dataSetsFromItem.dataSetIdentFrom
        dataSetFrom = getters.getDataSet(appWindowIdentFrom, dataSetIdentFrom)
        whereList = dataSetFrom.whereLists ? dataSetFrom.whereLists[dataSetsFromItem.dataFieldIdentFrom] : null
        await dispatch('setDataSetFieldValue', {
          sourceKind: dataSetsFromItem.sourceKindTo,
          dataSet: dataSet,
          dataFieldIdent: dataSetsFromItem.dataFieldIdentTo,
          dataFieldValue: getters.getDataSetFieldValue(
            dataSetsFromItem.sourceKindFrom,
            dataSetFrom,
            dataSetsFromItem.dataFieldIdentFrom
          ),
        })
        if (dataSetsFromItem.sourceKindTo === 'where') {
          dispatch('setDataSetWhereListsFieldValue', {
            dataSet: dataSet,
            lookupDataFieldIdent: dataSetsFromItem.dataFieldIdentTo,
            whereListValue: null
          })
          if (whereList){
            await whereList.forEach(whereListItem =>{
              dispatch('setDataSetWhereListsFieldValue', {
                dataSet: dataSet,
                lookupDataFieldIdent: dataSetsFromItem.dataFieldIdentTo,
                whereListValue: whereListItem
              })
            })
          }
        }
      }
    }
    dispatch('updateUrlQuery', {dataSet})
  },
  fillDataSetsFromGetters: async ({ dispatch, getters }, payload) => {
    let lookupGetters = getters.getAppWindowLookupGetters(
      payload.appWindowIdent
    )
    let row = payload.row
    await lookupGetters.forEach(async lookupGetter => {
      if (
        payload.dataSetIdent === null ||
        payload.dataSetIdent === undefined ||
        lookupGetter.dataSetIdentTo === payload.dataSetIdent
      ) {
        let dataSetTo = getters.getDataSet(
          lookupGetter.appWindowIdentTo,
          lookupGetter.dataSetIdentTo
        )
        let dataSetFrom = getters.getDataSet(
          lookupGetter.appWindowIdentFrom,
          lookupGetter.dataSetIdentFrom
        )
        let value
        if (row != null && row._appWindowIdent === lookupGetter.appWindowIdentFrom &&
          row._dataSetIdent === lookupGetter.dataSetIdentFrom && row._sourceKind ===  lookupGetter.sourceKindFrom)
          value = row[lookupGetter.dataFieldIdentFrom]
        else
          value = getters.getDataSetFieldValue(
            lookupGetter.sourceKindFrom,
            dataSetFrom,
            lookupGetter.dataFieldIdentFrom
          )
          
        await dispatch('setDataSetFieldValue', {
          sourceKind: lookupGetter.sourceKindTo,
          dataSet: dataSetTo,
          dataFieldIdent: lookupGetter.dataFieldIdentTo,
          dataFieldValue: value
        })
        if (
          lookupGetter.sourceKindFrom === 'where' &&
          lookupGetter.sourceKindTo === 'where'
        ) {
          let whereListValue =
            dataSetFrom.whereLists[lookupGetter.dataFieldIdentFrom] || null
          if (whereListValue)
            await whereListValue.forEach(async whereListItem => {
              await dispatch('setDataSetWhereListsFieldValue', {
                dataSet: dataSetTo,
                lookupDataFieldIdent: lookupGetter.dataFieldIdentTo,
                whereListValue: whereListItem
              })
            })
          else {
            await dispatch('setDataSetWhereListsFieldValue', {
              dataSet: dataSetTo,
              lookupDataFieldIdent: lookupGetter.dataFieldIdentTo,
              whereListValue: null
            })
          }
        }
      }
    })
  },
  refreshDataOnFromQuery: async ({ dispatch }, payload) => {
    if (!payload.query) return
    await dispatch('fillDataSetsFromQuery', {
      appWindowIdent: payload.appWindowIdent,
      query: payload.query
    })
    await dispatch('setAppWindowData', {
      appWindowIdent: payload.appWindowIdent,
      serverSide: payload.serverSide,
      query: payload.query
    })
  },
  fillDataSetsFromQuery: async ({ dispatch, getters }, payload) => {
    let appwindow = getters.getAppWindow(payload.appWindowIdent)
    if (!appwindow) return
    let queryDataSetsTo = appwindow.queryDataSetsTo
    if (!queryDataSetsTo) return
    let query = payload.query
    if (query) {
      queryDataSetsTo.forEach(async item => {
        let dataSet = getters.getDataSet(
          payload.appWindowIdent,
          item.dataSetIdent
        )
        let where = dataSet.where || {}
        if (query[item.linkedParamName] !== undefined) {
          if (query[item.linkedParamName] === where[item.dataFieldIdent]) return
          await dispatch('setDataSetWhereFieldValue', {
            appWindowIdent: payload.appWindowIdent,
            dataSet: dataSet,
            dataFieldIdent: item.dataFieldIdent,
            dataFieldValue: query[item.linkedParamName]          
          })
        } 
        else {
          let whereFieldsIdent = getters.getDataSetWhereFieldsIdentsDataField(dataSet, item.dataFieldIdent)
          let whereFieldsIdentValue = whereFieldsIdent != null ? whereFieldsIdent.dataFieldValueDef : null
          if(item.linkedParamName != null && whereFieldsIdentValue !== where[item.dataFieldIdent]) {
            await dispatch('setDataSetWhereFieldValue', {
              appWindowIdent: payload.appWindowIdent,
              dataSet: dataSet,
              dataFieldIdent: item.dataFieldIdent,
              dataFieldValue: whereFieldsIdentValue
            })
          }
        }
      })
    }
    if (appwindow.dataSets != null)
    {
      for(const dsi in appwindow.dataSets) {
        const ds = appwindow.dataSets[dsi]
        if (getters.getDataSetFieldsIdentsDataField(ds, '_urlParamName') == null)
          continue
        dispatch('deleteAllSelectedRow', {dataSetIdent: dsi, appWindowIdent: payload.appWindowIdent, urlLock: 1})
        if (query == null)
          continue
        ds.rows.forEach(row =>{
          switch(row._urlParamKind){
          case 'list':
            if (row._urlParamValue == null)
              break
            if (query[row._urlParamName] instanceof Array
              && query[row._urlParamName].find(p => p == row._urlParamValue)
            ) {
              dispatch('addSelectedRow', {dataSetIdent: dsi, appWindowIdent: payload.appWindowIdent, row: row, urlLock: 1})
            }
            else if (query[row._urlParamName] == row._urlParamValue) {
              dispatch('addSelectedRow', {dataSetIdent: dsi, appWindowIdent: payload.appWindowIdent, row: row, urlLock: 1})
            }
          }
        })
      }
    }
  },
  fillDataSetsFromData: async ({ dispatch, getters }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    let data = payload.data
    let filter = payload.filter
    let row = filter ?
      getters.appWindowDataSetFindRow(
        payload.appWindowIdent,
        payload.dataSetIdent,
        filter
      ) : payload.row
    let sourceKindTo = payload.sourceKindTo || 'where'
    let onCFLock = payload.onCFLock
    if (!data) return
    data.forEach(async item => {
      if (item.dataFieldIdent) {
        await dispatch(
          sourceKindTo === 'where'
            ? 'setDataSetWhereFieldValue'
            : 'setDataSetRowsFieldValue',
          {
            appWindowIdent: payload.appWindowIdent,
            dataSet: dataSet,
            row: row,
            dataFieldIdent: item.dataFieldIdent,
            dataFieldValue: item.dataFieldValue,
            onCFLock: onCFLock
          }
        )
      }
    })
  },
  addRow: async ({ commit }, payload) => {
    let dataSet = payload.dataSet
    let appWindowIdent = payload.appWindowIdent
    let fieldsIdents = payload.fieldsIdents
    let row = payload.row
    await commit('ADD_ROW', { appWindowIdent, dataSet, fieldsIdents, row })
  },
  deleteRow: async ({ commit }, payload) => {
    let dataSet = payload.dataSet
    let row = payload.row
    await commit('DELETE_ROW', { dataSet, row })
  },
  addFile: async ({ commit }, payload) => {
    let dataSet = payload.dataSet
    let file = payload.file
    await commit('ADD_FILE', { dataSet, file })
  },
  deleteFile: async ({ commit }, payload) => {
    let dataSet = payload.dataSet
    let file = payload.file
    await commit('DELETE_FILE', { dataSet, file })
  },
  addSelectedRow: async ({ commit, getters, dispatch }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    if (!dataSet.keyFieldsIdents || dataSet.keyFieldsIdents.length === 0) {
      await dispatch('setErrors', {
        appWindowIdent: payload.appWindowIdent,
        dataSetIdent: payload.dataSetIdent,
        errors: 'Brak zdefiniowanych pól kluczowych dla źródła danych: ' + payload.dataSetIdent
      })
      return -1
    }
    let row = payload.row
    await commit('ADD_SELECTED_ROW', { dataSet, row })
    if (payload.urlLock !== 1)
      dispatch('updateUrlQuery', {dataSet:dataSet, selectedRowsAdd: [row]})
    dispatch('refreshDataSetDependence', {
      appWindowIdent: payload.appWindowIdent,
      parentDataSetIdent: dataSet.dataSetIdent,
      refreshAggregates: 1,
      sourceKindFrom: 'selectedRows'
    })
  },
  addAllSelectedRow: async ({ commit, getters, dispatch }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    if (!dataSet.keyFieldsIdents || dataSet.keyFieldsIdents.length === 0) {
      await dispatch('setErrors', {
        appWindowIdent: payload.appWindowIdent,
        dataSetIdent: payload.dataSetIdent,
        errors: 'Brak zdefiniowanych pól kluczowych dla źródła danych: ' + payload.dataSetIdent
      })
      return -1
    }
    if (dataSet && dataSet.rows) await dataSet.rows.forEach(row => {
      commit('ADD_SELECTED_ROW', { dataSet, row })
    })
    dispatch('updateUrlQuery', {dataSet:dataSet, selectedRowsAdd: dataSet.selectedRows})
    dispatch('refreshDataSetDependence', {
      appWindowIdent: payload.appWindowIdent,
      parentDataSetIdent: dataSet.dataSetIdent,
      refreshAggregates: 1,
      sourceKindFrom: 'selectedRows'
    })
  },
  deleteSelectedRow: async ({ commit, getters, dispatch }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    let row = payload.row
    if (!dataSet)
      return
    await commit('DELETE_SELECTED_ROW', { dataSet, row })
    dispatch('updateUrlQuery', {dataSet:dataSet, selectedRowsDel: [row]})
    dispatch('refreshDataSetDependence', {
      appWindowIdent: payload.appWindowIdent,
      parentDataSetIdent: dataSet.dataSetIdent,
      refreshAggregates: 1,
      sourceKindFrom: 'selectedRows'
    })
  },
  deleteAllSelectedRow: async ({ commit, getters, dispatch }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    if (!dataSet)
      return
    if (payload.urlLock !== 1)
      dispatch('updateUrlQuery', {dataSet:dataSet, selectedRowsDel: dataSet.selectedRows})
    commit('DELETE_ALL_SELECTED_ROW', { dataSet })
  },
  fillDataSetsFromSetters: async ({ dispatch, getters }, payload) => {
    let lookupSetters = getters.getAppWindowLookupSetters(
      payload.appWindowIdent
    )
    let {row, sourceKind} = payload
    let lookupAppWindowIdent = getters.getAppWindowIdent(payload.lookupAppWindowIdent)
    if (!payload.lookupIsMultiSelect)
      await lookupSetters.forEach(lookupSetter => {
        dispatch('setDataSetFieldValue', {
          sourceKind: lookupSetter.sourceKindTo,
          appWindowIdent: lookupSetter.appWindowIdentTo === lookupAppWindowIdent ? payload.lookupAppWindowIdent : lookupSetter.appWindowIdentTo,
          dataSet: getters.getDataSet(
            lookupSetter.appWindowIdentTo === lookupAppWindowIdent ? payload.lookupAppWindowIdent : lookupSetter.appWindowIdentTo,
            lookupSetter.dataSetIdentTo
          ),
          dataFieldIdent: lookupSetter.dataFieldIdentTo,
          dataFieldValue: getters.getDataSetFieldValue(
            lookupSetter.sourceKindFrom,
            getters.getDataSet(
              lookupSetter.appWindowIdentFrom,
              lookupSetter.dataSetIdentFrom
            ),
            lookupSetter.dataFieldIdentFrom
          )
        })
      })
    if (payload.lookupIsMultiSelect) {
      let whereLists = []
      await lookupSetters.forEach(lookupSetter => {
        let dataSetFrom = getters.getDataSet(
          lookupSetter.appWindowIdentFrom,
          lookupSetter.dataSetIdentFrom
        )
        if (
          lookupSetter.sourceKindFrom === 'rows' &&
          dataSetFrom.selectedRows.length > 0
        ) {
          dataSetFrom.selectedRows.forEach((row, index) => {
            if (whereLists[index] === undefined) {
              let _keyFieldsValues = getters.getDataSetRowsKeyFieldsValues(dataSetFrom, row)
              whereLists.push({
                [lookupSetter.dataFieldIdentTo]: row[lookupSetter.dataFieldIdentFrom],
                _keyFieldsValues: _keyFieldsValues || undefined
              })
            } else {
              whereLists[index][[lookupSetter.dataFieldIdentTo]] =
                row[lookupSetter.dataFieldIdentFrom]
            }
          })
        }
      })
      whereLists.forEach(whereListValue => {
        if (sourceKind === 'rows') {
          dispatch('setRowListsFieldValue', {
            dataSet: getters.getDataSet(
              payload.lookupAppWindowIdent,
              payload.lookupDataSetIdent
            ),
            lookupDataFieldIdent: payload.lookupDataFieldIdent,
            whereListValue: whereListValue,
            row: row._appWindowIdent === payload.lookupAppWindowIdent && row._dataSetIdent === payload.lookupDataSetIdent 
              ? row : null
          })
        }
        else {
          dispatch('setDataSetWhereListsFieldValue', {
            dataSet: getters.getDataSet(
              payload.lookupAppWindowIdent,
              payload.lookupDataSetIdent
            ),
            lookupDataFieldIdent: payload.lookupDataFieldIdent,
            whereListValue: whereListValue
          })
        }
      })
    }
  },
  clearDataSetsFromSetters: async ({ dispatch, getters }, payload) => {
    let lookupDef =
      getters.getDataSetLookupDef(
        payload.appWindowIdent,
        payload.dataSetIdent,
        payload.dataFieldIdent
      ) || {}
    let lookupSetters = lookupDef.lookupSetters || []
    await lookupSetters.forEach(lookupSetter => {
      dispatch(
        lookupSetter.sourceKindTo === 'where'
          ? 'setDataSetWhereFieldValue'
          : 'setDataSetRowsFieldValue',
        {
          appWindowIdent: payload.appWindowIdent,
          dataSet: getters.getDataSet(
            lookupSetter.appWindowIdentTo,
            lookupSetter.dataSetIdentTo
          ),
          dataFieldIdent: lookupSetter.dataFieldIdentTo,
          dataFieldValue: null
        }
      )
    })
  },
  clearLookupDataSetsSelection: async ({ dispatch, getters }, payload) => {
    let lookupDef =
      getters.getDataSetLookupDef(
        payload.appWindowIdent,
        payload.dataSetIdent,
        payload.dataFieldIdent
      ) || {}
    let lookupSettersRefresh = lookupDef.lookupSettersRefresh || []
    await lookupSettersRefresh.forEach(async item => {
      await dispatch('deleteAllSelectedRow', {
        appWindowIdent: item.appWindowIdentFrom,
        dataSetIdent: item.dataSetIdentFrom
      })
    })
  },
  refreshDataSetFromSetters: async ({ dispatch, getters }, payload) => {
    let lookupSettersRefresh = getters.getAppWindowLookupSettersRefresh(
      payload.appWindowIdent
    )
    for (let i = 0; i < lookupSettersRefresh.length; i++) {
      await dispatch('refreshDataSet', {
        appWindowIdent: lookupSettersRefresh[i].appWindowIdentFrom,
        dataSetIdent: lookupSettersRefresh[i].dataSetIdentFrom,
        refreshAggregates: 1
      })
    }
  },
  refreshDataSets: async ({ dispatch, getters }, payload) => {
    let appWindowsIdents = []
    if (payload.dataSetIdents !== null) {
      for (let i = 0; i < payload.dataSetIdents.length; i++) {
        if(payload.dataSetIdents[i].appWindowIdent != null) {
          if (!appWindowsIdents.find(item => item === payload.dataSetIdents[i].appWindowIdent)) {
            appWindowsIdents.push(payload.dataSetIdents[i].appWindowIdent)
          }          
          await dispatch('setDataSetRefReq', {
            appWindowIdent: payload.dataSetIdents[i].appWindowIdent,
            dataSetIdent: payload.dataSetIdents[i].dataSetIdent,
            refreshAggregates: payload.refreshAggregates
          })
        }
      }
    }
    for (let i = 0; i < appWindowsIdents.length; i++) {
      dispatch('setAppWindowData', {
        appWindowIdent: appWindowsIdents[i],
        query: getters.getRoute.query
      })
    }
  },
  refreshDataSet: ({ dispatch }, payload) => {
    dispatch('refreshDataSets', {
      dataSetIdents: [
        {
          appWindowIdent: payload.appWindowIdent,
          dataSetIdent: payload.dataSetIdent
        }
      ],
      refreshAggregates: payload.refreshAggregates
    })
  },
  refreshDataSetDependence: ({ dispatch, getters }, payload) => {
    dispatch('refreshDataSets', {
      dataSetIdents: getters.getDataSetsDependency(
        getters.getDataSet(payload.appWindowIdent, payload.parentDataSetIdent),
        payload.sourceKindFrom
      ),
      refreshAggregates: payload.refreshAggregates
    })
  },
  setTechnicalFields: ({commit, getters}, payload) => {
    if (getters.devAppName != payload.devAppName)
      commit('SET_DEVAPPNAME', payload)
    let dev = payload.DEV == '1'
    if (getters.dev !== dev)
      commit('SET_ISDEV', {dev})
  },
  addStartWindows: async ({ dispatch, getters, commit }, payload) => {
    if (getters.urlLock) {
      await commit('UNLOCK_URL')
      return
    }
    let appWindowIdent = payload.appWindowIdent
    if (appWindowIdent === 'dist') appWindowIdent = getters.mainAppWindowIdent
    let setActive = payload.setActive
    let path = payload.path
    let query = payload.query
    let serverSide = payload.serverSide
    if (serverSide){
      await dispatch('setTechnicalFields', query)
      await dispatch('deleteAppWindowsAll')
    }
    if (appWindowIdent !== getters.mainAppWindowIdent) {
      await dispatch('addAppWindow', {
        appWindowIdent: getters.mainAppWindowIdent,
        setActive: false,
        lookupDef: null,
        addRoutingData: true,
        path: null,
        query: query,
        serverSide: serverSide
      })
    }
    await dispatch('addAppWindow', {
      appWindowIdent: appWindowIdent,
      setActive: setActive,
      lookupDef: null,
      addRoutingData: false,
      path: path,
      query: query,
      serverSide: serverSide
    })
  },
  addLookupWindow: async ({getters, dispatch, commit}, payload) => {
    let appWindows = Object.values(getters.csAppWindows)
    for (var i = 0; i < appWindows.length; i++){
      let lookupDef = appWindows[i].lookupDef
      if (!lookupDef || lookupDef.closeKind !== 'anotherExpanded' || lookupDef === payload.lookupDef)
        continue
      await commit('SET_LOOKUP_DEF_VISIBLE', { lookupDef: lookupDef, lookupVisible: false })
    }
    await dispatch('addAppWindow', payload)
    dispatch('syncDataSetsWithSetters', {appWindowIdent: payload.appWindowUniqIdent || payload.appWindowIdent})
  },
  addAppWindow: async ({ dispatch, getters, commit }, payload) => {
    let appWindowIdent = payload.appWindowIdent
    let appWindow = getters.getAppWindow(appWindowIdent, payload.path)
    let setActive = payload.setActive
    let lookupDef = payload.lookupDef
    
    let query = payload.query
    let serverSide = payload.serverSide
    let row = payload.row
    let params = payload.params
    let commands = payload.commands
    if (appWindow)
      dispatch('unlockActions', appWindow)
    if (appWindow === undefined) {
      await dispatch('loadAppWindow', payload)
      appWindow = getters.getAppWindow(appWindowIdent, payload.path)
    }
    if (appWindow) {
      let appWindowUniqIdent = payload.appWindowUniqIdent || getters.getAppWindowUniqIdentFromAppWindow(
        appWindow,
        query
      )
      if (appWindowUniqIdent !== appWindowIdent) {
        let appWindowNew = getters.getAppWindow(appWindowUniqIdent)
        if (!appWindowNew) {
          appWindowNew = getters.cloneAppWindow(appWindow, appWindowUniqIdent)
          let mainAppWindowIdent = getters.mainAppWindowIdent
          await commit('ADD_APPWINDOW', {
            appWindow: appWindowNew,
            setActive: setActive,
            lookupDef: lookupDef,
            path: payload.path,
            mainAppWindowIdent: mainAppWindowIdent,
            appWindowIdent: appWindowUniqIdent
          })
        }
      }
      if (setActive && appWindowUniqIdent !== getters.activeWindowIdent)
        await dispatch('setActiveAppWindow', {
          appWindowIdent: appWindowUniqIdent
        })
      appWindow = getters.getAppWindow(appWindowUniqIdent)
      if (!commands) commands = getters.getCommandsFromPath(payload.path)
      if (!params) params = getters.getParamsFromPath(payload.path)
      if (commands) {
        await commit('SET_APPWINDOW_COMMANDS', { appWindow, commands })
        await dispatch('processCommands', { commands })
      }
      await dispatch('fillDataSetsFromQuery', {
        appWindowIdent: appWindowUniqIdent,
        query: query
      })
      if (params && JSON.stringify(params) != JSON.stringify(appWindow.params)) {
        await commit('SET_APPWINDOW_PARAMS', { appWindow, params })
        await dispatch('setDataSetRefReqAll', {
          appWindowIdent: appWindowUniqIdent,
          refreshAggregates: 1
        })
      }
      await dispatch('fillDataSetsFromGetters', {
        appWindowIdent: appWindowUniqIdent,
        dataSetIdent: null,
        row: row
      })
      await dispatch('setAppWindowData', {
        appWindowIdent: appWindowUniqIdent,
        serverSide: serverSide,
        query: query,
        row: row
      })
      await dispatch('refreshDataSetFromSetters', {
        appWindowIdent: appWindowUniqIdent
      })
    }
  },
  syncDataSetsWithSetters: ({getters, dispatch}, payload) =>{
    let {appWindowIdent} = payload
    let lookupDef = getters.getAppWindowLookupDef(appWindowIdent)
    let {row, isMultiSelect, sourceKind} = lookupDef
    if(!row || isMultiSelect !== 1 || sourceKind !== 'rows')
      return
    let lookupSetters = getters.getAppWindowLookupSetters(appWindowIdent)
    lookupSetters.forEach(setter =>{
      if (setter.sourceKindFrom !== 'rows' || setter.sourceKindTo !== 'rows')
        return
      let rowLists = row._rowLists[setter.dataFieldIdentTo]
      if (!rowLists)
        return
      dispatch('deleteAllSelectedRow', {dataSetIdent: setter.dataSetIdentFrom, appWindowIdent: setter.appWindowIdentFrom})
      rowLists.forEach(list => {
        if (!list._keyFieldsValues)
          return
        let row = new constructors.csRow(Object.assign({}, list, list._keyFieldsValues))
        dispatch('addSelectedRow', {dataSetIdent: setter.dataSetIdentFrom, appWindowIdent: setter.appWindowIdentFrom, row: row})
      })
    })
  },
  loginUsr: async ({ state, getters, dispatch, rootGetters }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    let action = getters.getDataSetAction(dataSet, 'csLogin')
    let request = {
      sessionId: getters.getSessionId(state),
      csAppNameSpacesG: getters.csAppNameSpacesG,
      connection: getters.getAPIConnectionData,
      route: getters.getAppWindowRoutingData(payload.addRoutingData),
      login: payload.login,
      password: payload.password,
      uPwd: payload.uPwd,
      rPwd: payload.rPwd,
    }
    let url = rootGetters['csServerSettings/getAPIDefinitionMethodURL'](
      'login',
      payload.serverSide
    )
    let response = await axios.post(url, request, getters.getAPIDataRequestConfig())
    let id = uuid.v1()
    await dispatch('setErrors', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: payload.dataSetIdent,
      errors: response.errors,
      action: action,
      row: payload.row,
      id: id
    })
    let data = response.data
    if (data && data.errors) {
      await dispatch('setErrors', {
        appWindowIdent: payload.appWindowIdent,
        dataSetIdent: payload.dataSetIdent,
        errors: data.errors,
        action: action,
        row: payload.row,
        id: id
      })
    }
    if (getters.hasError(id)) return
    await dispatch('deleteAppWindowsAll')
    if (await dispatch('checkRouter'))
      storeUtils.pRouter = storeUtils.pRouter.then(() => storeUtils.router.push(getters.getRoute.from.fullPath))
  },
  logoutUsr: async ({ state, getters, dispatch, rootGetters }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    let action = getters.getDataSetAction(dataSet, 'csLogout')
    let request = {
      sessionId: getters.getSessionId(state),
      csAppNameSpacesG: getters.csAppNameSpacesG,
      connection: getters.getAPIConnectionData,
      route: getters.getAppWindowRoutingData(payload.addRoutingData),
    }
    let url = rootGetters['csServerSettings/getAPIDefinitionMethodURL'](
      'logout',
      payload.serverSide
    )
    let response = await axios.post(url, request, getters.getAPIDataRequestConfig())
    let data = response.data
    let id = uuid.v1()
    await dispatch('setErrors', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: payload.dataSetIdent,
      errors: response.errors,
      action: action,
      row: payload.row,
      id: id
    })
    if (data && data.errors) {
      await dispatch('setErrors', {
        appWindowIdent: payload.appWindowIdent,
        dataSetIdent: payload.dataSetIdent,
        errors: data.errors,
        action: action,
        row: payload.row,
        id: id
      })
    }
    if (getters.hasError(id)) return
    await dispatch('deleteAppWindowsAll')
    if (await dispatch('checkRouter'))
      storeUtils.pRouter = storeUtils.pRouter.then(() => storeUtils.router.go())
  },
  gotoLocation: ({ dispatch }, payload) => {
    let location = payload.location
    let r = new RegExp('^(?:[a-z]+:)?//', 'i')
    if(location != null && r.test(location.path)) {
      window.location = location.path
    } else if (dispatch('checkRouter')) {
      storeUtils.pRouter = storeUtils.pRouter.then(() => storeUtils.router.push(payload.location))
    }
  },
  playAudio: ({getters, commit}, payload) => {
    let {url} = payload
    if (!url)
      return
    let audio = getters.getAudio(url)
    if (!audio){
      audio = new Audio(url)
      payload.audio = audio
      commit('ADD_AUDIO', payload)
    }
    if (payload.replay == 1)
      audio.load()
    audio.play()
  },
  pauseAudio: ({getters}, payload) => {
    let {url} = payload
    if (!url)
      return
    let audio = getters.getAudio(url)
    if (!audio)
      return
    audio.pause()
  },
  unlockActions: ({ commit }, appWindow) => {
    if (appWindow.dataSets)
      for (var dataSet in appWindow.dataSets) {
        if (dataSet.actions)
          dataSet.actions.forEach(action => {
            commit('SET_DATASET_ACTION_STATE', { action: action, state: 1 })
          })
      }
  },
  loadAppWindow: async ({ commit, state, getters, dispatch, rootGetters }, payload) => {
    let refreshParamsJSON = getters.getRefreshParams()
    let request = {
      serverSide: payload.serverSide,
      csAppNameSpacesG: getters.csAppNameSpacesG,
      appWindowIdent: payload.appWindowIdent,
      sessionId: getters.getSessionId(state),
      viewHTMLFromFile: getters.viewHTMLFromFile,
      connection: refreshParamsJSON ? getters.getAPIConnectionData : undefined,
      route: getters.getAppWindowRoutingData(payload.addRoutingData),
      path: payload.path,
      refreshParamsJSON: refreshParamsJSON ? refreshParamsJSON : undefined
    }
    let url = rootGetters['csServerSettings/getAPIDefinitionMethodURL'](
      'getDefinition',
      payload.serverSide
    )
    let response = await axios.post(url, [request], getters.getAPIDataRequestConfig())
    await dispatch('setErrors', response.errors)
    if (response.data.errors)
      await dispatch('setErrors', [{ messageText: response.data.errors }])
    await commit('SET_SESSIONID', { sessionId: response.data.sessionId })
    if (
      response.data.definition === undefined ||
      response.data.definition === null
    ) {
      commit('ADD_LOG', {
        messageText:
          'Error loading window: ' +
          payload.appWindowIdent +
          ' serverSide: ' +
          payload.serverSide +
          ' url: ' +
          url +
          ' request: ' +
          JSON.stringify(request) +
          ':' +
          JSON.stringify(response.data)
      })
      return
    }
    let appWindow = getters.getAppWindowFromDefinition(
      payload.appWindowIdent,
      response.data.definition,
      payload.lookupDef
    )
    let setActive = payload.setActive
    let lookupDef = payload.lookupDef
    let path = response.data.pathChange != null ? response.data.pathChange : payload.path
    payload.path = path
    let mainAppWindowIdent = getters.mainAppWindowIdent
    let appWindowIdent = appWindow.appWindowIdent
    await commit('ADD_APPWINDOW', {
      appWindow,
      setActive,
      lookupDef,
      path,
      mainAppWindowIdent,
      appWindowIdent
    })
    if (!await dispatch('checkRouter'))
      return
    if (response.data.pathChange != null && storeUtils.router != null && storeUtils.router.currentRoute.path !== path){
      storeUtils.pRouter = storeUtils.pRouter.then(() => storeUtils.router.replace({ path: path }))
    }
  },
  deleteAppWindow: async ({ commit }, payload) => {
    if (payload === null) throw Error('[deleteAppWindow] -  payload is null.')
    if (payload.appWindowIdent === null)
      throw Error('[deleteAppWindow] -  appWindowIdent is null.')
    await commit('DELETE_APPWINDOW', payload)
  },
  reloadAppWindow: async ({ dispatch, getters }, payload) => {
    if (payload === null) throw Error('[reloadAppWindow] -  payload is null.')
    if (payload.appWindowIdent === null)
      throw Error('[reloadAppWindow] -  appWindowIdent is null.')
    await dispatch('deleteAppWindow', {
      appWindowIdent: payload.appWindowIdent
    })
    await dispatch('addAppWindow', {
      appWindowIdent: payload.appWindowIdent,
      setActive: true,
      lookupDef: null,
      addRoutingData: true,
      path: null,
      query: getters.getRoute.query
    })
  },
  setActiveAppWindow: async ({ commit }, payload) => {
    if (payload === null)
      throw Error('[setActiveAppWindow] -  payload is null.')
    if (payload.appWindowIdent === null)
      throw Error('[setActiveAppWindow] -  appWindowIdent is null.')
    await commit('SETACTIVE_APPWINDOW', payload)
  },
  dataSetPageChange: ({ dispatch }, payload) => {
    dispatch('refreshDataSet', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: payload.dataSetIdent,
      refreshAggregates: 0
    })
  },
  setDataSetPageNo: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let pagesCount = getters.getDataSetPagesCount(dataSet)
    let pageNo = payload.pageNo
    if (pagesCount > 0 && pageNo > pagesCount)
      return
    if (pageNo < 1)
      return
    commit('SET_DATASET_PAGENOREF', { dataSet, pagesCount, pageNo })
    dispatch('dataSetPageChange', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: dataSet.dataSetIdent
    })
  },
  setDataSetPivotColsPageNo: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let pagesCount = getters.getDataSetPivotColsPagesCount(dataSet)
    let pageNo = payload.pageNo
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    commit('SET_DATASET_PIVOT_COLS_PAGENO', {
      dataSet,
      layout,
      pagesCount,
      pageNo
    })
    dispatch('dataSetPageChange', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: dataSet.dataSetIdent
    })
  },
  setDataSetPivotRowsPageNo: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let pagesCount = getters.getDataSetPivotRowsPagesCount(dataSet)
    let pageNo = payload.pageNo
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    commit('SET_DATASET_PIVOT_ROWS_PAGENO', {
      dataSet,
      layout,
      pagesCount,
      pageNo
    })
    dispatch('dataSetPageChange', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: dataSet.dataSetIdent
    })
  },
  setDataSetPageNoFirst: ({ dispatch }, payload) => {
    payload.pageNo = 1
    dispatch('setDataSetPageNo', payload)
  },
  setDataSetPivotColsPageNoFirst: (
    { commit, getters, dispatch },
    payload
  ) => {
    let dataSet = payload.dataSet
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    commit('SET_DATASET_PIVOT_COLS_PAGENOFIRST', { dataSet, layout })
    dispatch('dataSetPageChange', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: dataSet.dataSetIdent
    })
  },
  setDataSetPivotRowsPageNoFirst: (
    { commit, getters, dispatch },
    payload
  ) => {
    let dataSet = payload.dataSet
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    commit('SET_DATASET_PIVOT_ROWS_PAGENOFIRST', { dataSet, layout })
    dispatch('dataSetPageChange', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: dataSet.dataSetIdent
    })
  },
  setDataSetPageNoLast: ({ getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    payload.pageNo = getters.getDataSetPagesCount(dataSet)
    dispatch('setDataSetPageNo', payload)
  },
  setDataSetPivotColsPageNoLast: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let pagesCount = getters.getDataSetPivotColsPagesCount(dataSet)
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    commit('SET_DATASET_PIVOT_COLS_PAGENOLAST', {
      dataSet,
      layout,
      pagesCount
    })
    dispatch('dataSetPageChange', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: dataSet.dataSetIdent
    })
  },
  setDataSetPivotRowsPageNoLast: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let pagesCount = getters.getDataSetPivotRowsPagesCount(dataSet)
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    commit('SET_DATASET_PIVOT_ROWS_PAGENOLAST', {
      dataSet,
      layout,
      pagesCount
    })
    dispatch('dataSetPageChange', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: dataSet.dataSetIdent
    })
  },
  setDataSetPageNoNext: ({ getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let pagesCount = getters.getDataSetPagesCount(dataSet)
    if (dataSet.pageNo >= pagesCount)
      return
    payload.pageNo = dataSet.pageNo + 1
    dispatch('setDataSetPageNo', payload)
  },
  setDataSetPivotColsPageNoNext: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let pagesCount = getters.getDataSetPivotColsPagesCount(dataSet)
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    commit('SET_DATASET_PIVOT_COLS_PAGENONEXT', {
      dataSet,
      layout,
      pagesCount
    })
    commit('SET_DATASET_SCROLL_DIRECTION', {
      dataSet: dataSet,
      scrollDirection: dataSetUtils.scrollDirection.right
    })
    dispatch('dataSetPageChange', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: dataSet.dataSetIdent
    })
  },
  setDataSetPivotRowsPageNoNext: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let pagesCount = getters.getDataSetPivotRowsPagesCount(dataSet)
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    commit('SET_DATASET_PIVOT_ROWS_PAGENONEXT', {
      dataSet,
      layout,
      pagesCount
    })
    commit('SET_DATASET_SCROLL_DIRECTION', {
      dataSet: dataSet,
      scrollDirection: dataSetUtils.scrollDirection.bottom
    })
    dispatch('dataSetPageChange', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: dataSet.dataSetIdent
    })
  },
  setDataSetPageNoPrev: ({ dispatch }, payload) => {
    let dataSet = payload.dataSet
    if (dataSet.pageNo <= 1)
      return
    payload.pageNo = dataSet.pageNo - 1
    dispatch('setDataSetPageNo', payload)
  },
  setDataSetPivotColsPageNoPrev: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    commit('SET_DATASET_PIVOT_COLS_PAGENOPREV', { dataSet, layout })
    commit('SET_DATASET_SCROLL_DIRECTION', {
      dataSet: dataSet,
      scrollDirection: dataSetUtils.scrollDirection.left
    })
    dispatch('dataSetPageChange', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: dataSet.dataSetIdent
    })
  },
  setDataSetPivotRowsPageNoPrev: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    commit('SET_DATASET_PIVOT_ROWS_PAGENOPREV', { dataSet, layout })
    commit('SET_DATASET_SCROLL_DIRECTION', {
      dataSet: dataSet,
      scrollDirection: dataSetUtils.scrollDirection.top
    })
    dispatch('dataSetPageChange', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: dataSet.dataSetIdent
    })
  },
  setDataSetLayoutIdent: ({ commit }, payload) => {
    commit('SET_LAYOUT_IDENT', payload)
  },
  setDataSetSortIdent: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let sortIdent = payload.sortIdent
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    commit('SET_LAYOUT_SORTIDENT', { layout, sortIdent })
    dispatch('setDataSetWhereFromAttrib', {
      dataSet: dataSet,
      attribName: 'sortIdent',
      attribValue: sortIdent
    })
    dispatch('setDataSetPageNoFirst', {
      appWindowIdent: payload.appWindowIdent,
      dataSet: payload.dataSet
    })
  },
  setDataSetPageSizesIdent: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let pageSizesIdent = payload.pageSizesIdent
    let pageSizes = getters.getDataSetPageSizes(dataSet, pageSizesIdent)
    let pageSize
    if (pageSizes !== null && pageSizes !== undefined) {
      pageSize = pageSizes.pageSize
    }
    commit('SET_DATASET_PAGESIZESIDENT', {
      dataSet,
      pageSizesIdent,
      pageSize
    })
    dispatch('setDataSetWhereFromAttrib', {
      dataSet: dataSet,
      attribName: 'pageSizeIdent',
      attribValue: pageSizesIdent
    })
    dispatch('setDataSetPageNoFirst', {
      appWindowIdent: payload.appWindowIdent,
      dataSet: payload.dataSet
    })

  },
  clearDataSet: ({ commit, getters }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    commit('CLEAR_DATASET', { dataSet, layout })
  },
  incDataSetRefCount: ({ commit, getters }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    commit('INC_DATASET_REFCOUNT', { dataSet })
  },
  deleteDataSetWhereListsItem: async ({ commit, getters, dispatch }, payload)  => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    let {dataFieldIdent, row, sourceKind} = payload
    if (sourceKind === 'rows')
      await commit('DELETE_ROW_LISTS', { row, dataFieldIdent })
    else
      await commit('DELETE_DATASET_WHERE_LISTS', { dataSet, dataFieldIdent })
    dispatch('refreshDataSetDependence', {
      appWindowIdent: payload.appWindowIdent,
      parentDataSetIdent: dataSet.dataSetIdent,
      refreshAggregates: 1,
      sourceKindFrom: 'selectedRows'
    })
  },
  deleteDataSetWhereListItem: async ({ commit, getters, dispatch }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    let {dataFieldIdent, dataFieldValue, row, sourceKind} = payload
    if (sourceKind === 'rows')
      await commit('DELETE_ROW_LIST_ITEM', {
        row,
        dataFieldIdent,
        dataFieldValue
      })
    else
      await commit('DELETE_DATASET_WHERE_LIST_ITEM', {
        dataSet,
        dataFieldIdent,
        dataFieldValue
      })
    let lookupDef = getters.getDataSetLookupDef(
      payload.appWindowIdent,
      payload.dataSetIdent,
      dataFieldIdent
    )
    if (lookupDef && lookupDef.isMultiSelect && payload._keyFieldsValues) {
      let lookupSettersRefresh = lookupDef.lookupSettersRefresh || []
      await lookupSettersRefresh.forEach(item => {
        dispatch('deleteSelectedRow', {
          appWindowIdent: item.appWindowIdentFrom,
          dataSetIdent: item.dataSetIdentFrom,
          row: payload._keyFieldsValues
        })
      })
    }
  },
  setDataSetBusy: ({ commit, getters }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    commit('SET_DATASET_BUSY', { appWindowIdent: payload.appWindowIdent, dataSet: dataSet })
  },
  printDevInfo: ({getters}, payload) => {
    if (!payload || !getters.isDev)
      return
    let {dataSetIdent, appWindowIdent} = payload
    let refConditions = getters.getDataSetRefConditions(getters.getDataSet(appWindowIdent, dataSetIdent))
    if (refConditions.length < 1)
      return
    let result = 'Refresh start\n'
    result += '  appWindowIdent: ' + appWindowIdent + '\n'
    result += '  dataSetIdent: ' + dataSetIdent + '\n'
    result += '  conditions:\n'
    
    refConditions.forEach(msg => {
      result += '    ' + JSON.stringify(msg) +'\n'
    })
    result += 'Refresh end\n'
    /* eslint-disable no-console */
    console.log(result)
    /* eslint-enable no-console */
  },
  setAppWindowData: async ({ dispatch, commit, getters, rootGetters }, payload) => {
    let ord = 0
    let appWindowIdent = payload.appWindowIdent
    if(appWindowIdent == null) return
    let query = payload.query
    let maxOrd = getters.getAppWindowDataSetsMaxOrd(appWindowIdent)
    let dataSetList = null
    let dataSetIdent = null
    let dataToPost = null
    let response = null
    let data = null
    let row = payload.row
    let serverSide = payload.serverSide

    while (ord < maxOrd) {
      ord++
      dataSetList = getters.getDataSetsToRefresh(appWindowIdent, ord)
      if (dataSetList == null || dataSetList.length == 0) {
        continue
      }
      for (let i = 0; i < dataSetList.length; i++) {
        dataSetIdent = null
        dataSetIdent = dataSetList[i].dataSetIdent
        dispatch('printDevInfo', {
          appWindowIdent: appWindowIdent,
          dataSetIdent: dataSetIdent
        })
        await dispatch('setDataSetBusy', {
          appWindowIdent: appWindowIdent,
          dataSetIdent: dataSetIdent
        })
        await dispatch('fillDataSetWhere', {
          appWindowIdent: appWindowIdent,
          dataSetIdent: dataSetIdent
        })
      }
      for (let i = 0; i < dataSetList.length; i++) {
        await dispatch('incDataSetRefCount', {
          appWindowIdent: appWindowIdent,
          dataSetIdent: dataSetIdent
        })
      }
      response = null
      dataToPost = null
      dataToPost = await getters.getAPIDataRequest(appWindowIdent, dataSetList, serverSide)
      response = await axios.post(
        rootGetters['csServerSettings/getAPIDataMethodURL'](
          'getData',
          serverSide
        ),
        dataToPost,
        getters.getAPIDataRequestConfig()
      )
      await dispatch('setErrors', {
        appWindowIdent: appWindowIdent,
        dataSetIdent: dataSetIdent,
        errors: response.errors
      })
      data = null
      data = response.data
      if (data !== null) {
        let wasErrors = await dispatch('setErrors', {
          appWindowIdent: appWindowIdent,
          dataSetIdent: dataSetIdent,
          errors: data.errors
        })
        if (!wasErrors) {
          await commit('SET_APPWINDOWDATA', {
            appWindowIdent,
            dataSetList,
            data,
            query
          })
        }
      }
      for (let i = 0; i < dataSetList.length; i++) {
        dispatch('updateDataSetPageNo', {dataSet: getters.getDataSet(appWindowIdent, dataSetList[i].dataSetIdent)})
        if (dataSetList[i].crLocData === 1) {
          await dispatch('fillDataSetsFromGetters', {
            appWindowIdent: appWindowIdent,
            dataSetIdent: dataSetList[i].dataSetIdent,
            row: row
          })
        }
        if (!getters.getDataSetPivotIsEmpty(dataSetList[i])) {
          let pivotCurrentRowIndex = 0
          let pivotCurrentColIndex = 0
          let pivotCurrentDataFieldIdent = getters.getDataSetAggrFields(
            dataSetList[i]
          )[0].dataFieldIdent
          switch (dataSetList[i].scrollDirection) {
          case dataSetUtils.scrollDirection.right:
            pivotCurrentRowIndex =
              dataSetList[i].pivotPrevRowIndex <
                dataSetList[i].pivotRows.length
                ? dataSetList[i].pivotPrevRowIndex
                : 0
            pivotCurrentDataFieldIdent =
              dataSetList[i].pivotPrevDataFieldIdent
            break
          case dataSetUtils.scrollDirection.left:
            pivotCurrentRowIndex =
              dataSetList[i].pivotPrevRowIndex <
                dataSetList[i].pivotRows.length
                ? dataSetList[i].pivotPrevRowIndex
                : 0
            pivotCurrentDataFieldIdent =
              dataSetList[i].pivotPrevDataFieldIdent
            break
          case dataSetUtils.scrollDirection.bottom:
            pivotCurrentColIndex =
              dataSetList[i].pivotPrevColIndex <
                dataSetList[i].pivotCols.length
                ? dataSetList[i].pivotPrevColIndex
                : 0
            break
          case dataSetUtils.scrollDirection.top:
            pivotCurrentColIndex =
              dataSetList[i].pivotPrevColIndex <
                dataSetList[i].pivotCols.length
                ? dataSetList[i].pivotPrevColIndex
                : 0
            break
          }
          await dispatch('setDataSetCurrentPivotIndex', {
            appWindowIdent: appWindowIdent,
            dataSetIdent: dataSetList[i].dataSetIdent,
            pivotCurrentRowIndex: pivotCurrentRowIndex,
            pivotCurrentColIndex: pivotCurrentColIndex,
            pivotCurrentDataFieldIdent: pivotCurrentDataFieldIdent
          })
        }
        ////
        let dataSetsTo = dataSetList[i].dataSetsTo
        if (dataSetsTo != null) {
          dataSetsTo.forEach(async function (dataSetsToItem) {
            if (dataSetsToItem.sourceKindTo != 'where')
              return
            let dataSetTo = getters.getDataSet(dataSetsToItem.appWindowIdentTo, dataSetsToItem.dataSetIdentTo)
            if (dataSetTo == null || dataSetTo.refReq === 1 || dataSetTo.ord <= ord)
              return
            let whereFieldsIdent = getters.getDataSetWhereFieldsIdentsDataField(dataSetTo, dataSetsToItem.dataFieldIdentTo)
            if (whereFieldsIdent != null && whereFieldsIdent.refreshDependencyKind !== 'none') {
              await dispatch('setDataSetRefReq', {
                appWindowIdent: dataSetsToItem.appWindowIdentTo,
                dataSetIdent: dataSetsToItem.dataSetIdentTo,
                refreshAggregates: 1,
                refCondition: {
                  dataSetIdentFrom: dataSetList[i].dataSetIdent,
                  dataSetsTo: dataSetsToItem
                }
              })
            }
          })
        }
        ////
      }
    }
  },
  updateDataSetPageNo: ({dispatch, commit}, payload) => {
    let {dataSet} = payload
    if (dataSet == null)
      return
    commit('SET_DATASET_PAGENO', {dataSet: dataSet, pageNo: dataSet.pageNoRef})
    commit('SET_DATASET_PAGENOREF', {dataSet: dataSet, pageNo: 1})
    dispatch('setDataSetWhereFromAttrib', {
      dataSet: dataSet,
      attribName: 'pageNo',
      attribValue: dataSet.pageNo
    })
    dispatch('updateUrlQuery', {dataSet})
  },
  invokeAction: async ({ dispatch, commit, getters, state, rootGetters }, payload) => {
    if (payload.actionIdent == null) return
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    let rowIndex = payload.rowIndex
    let row = payload.row
    let action = getters.getDataSetAction(dataSet, payload.actionIdent)
    if (!action) return
    let actionState = getters.getDataSetActionState(dataSet, payload.actionIdent, row)
    if (actionState === 0) return
    if (action.addNewRow && payload.execute !== 1) {
      await dispatch('addRow', {
        appWindowIdent: payload.appWindowIdent,
        dataSet: dataSet,
        fieldsIdents: action.fieldsIdents,
        row: payload.row
      })
      rowIndex = dataSet.rows.length - 1
      row = dataSet.rows[rowIndex]
    }
    if (action.showView === 1 && payload.execute !== 1) {
      let activeAppWindow = getters.getAppWindow(getters.activeWindowIdent)
      await commit('ADD_MODAL_WINDOW', {
        appWindow: activeAppWindow,
        data: {
          appWindowIdent: payload.appWindowIdent,
          dataSetIdent: payload.dataSetIdent,
          actionIdent: payload.actionIdent,
          onCFDataFieldIdent: payload.onCFDataFieldIdent,
          row: row,
          rowIndex: rowIndex,
          addNewRow: action.addNewRow
        }
      })
      return
    }
    await commit('SET_DATASET_ACTION_STATE', { action: action, row: row, state: 0 })
    await commit('CLEAR_ERRORFIELDS', {
      dataSet: dataSet
    })
    if (action.uploadFiles === 1) {
      await dispatch('putAllFiles', { dataSet })
      if (!getters.isFilesUploaded(dataSet)) {
        await commit('SET_DATASET_ACTION_STATE', { action: action, row: row, state: -1 })
        return
      }
    }
    if (payload.actionIdent === 'csLogin') {
      let loginPayload = {
        appWindowIdent: payload.appWindowIdent,
        dataSetIdent: payload.dataSetIdent
      }
      loginPayload.login = row ? row.login : null
      loginPayload.password = row ? row.password : null
      loginPayload.uPwd = row ? row.uPwd : null
      loginPayload.uPwd = row ? row.rPwd : null
      loginPayload.router = payload.router
      loginPayload.row = payload.row
      await dispatch('loginUsr', loginPayload)
    } else if (payload.actionIdent === 'csLogout') {
      await dispatch('logoutUsr', payload)
    } else if (action && (action.kind === 'exportXLSX' || action.kind === 'exportCSV' || action.kind === 'exportTXT')) {
      await dispatch('exportData', payload)
    } else {
      let where = dataSet ? dataSet.where : null
      let whereLists = dataSet ? dataSet.whereLists : null
      let sources = getters.getDataSetActionSourcesValues(action)
      let refreshParamsJSON = getters.getRefreshParams()
      let layout
      if (action.addLayout === 1) {
        let layoutIdent = payload.layoutIdent
        if (dataSet && layoutIdent)
          layout = getters.getDataSetLayout(dataSet, layoutIdent)
      }
      let dataToPost = {
        appWindowIdent: getters.getAppWindowIdent(payload.appWindowIdent),
        dataSetIdent: payload.dataSetIdent,
        actionIdent: payload.actionIdent,
        sessionId: getters.getSessionId(state),
        connection: refreshParamsJSON ? getters.getAPIConnectionData : undefined,
        csAppNameSpacesG: getters.csAppNameSpacesG,
        where: getters.undefinedWhenObjNull(getters.getDataSetActionWhere(action, where), true),
        whereLists: getters.undefinedWhenObjNull(whereLists, true),
        selectedRows: getters.undefinedWhenArrayEmpty(getters.getDataSetActionSelectedRows(action, dataSet)),
        row: getters.undefinedWhenObjNull(getters.getDataSetActionRow(action, payload.row), true),
        sources: getters.undefinedWhenObjNull(sources, true),
        onCFDataFieldIdent: payload.onCFDataFieldIdent ? payload.onCFDataFieldIdent : undefined,
        refreshParamsJSON: refreshParamsJSON ? refreshParamsJSON : undefined,
        files: dataSet.files,
        layout: layout ? layout : undefined
      }
      let response = await axios.post(
        rootGetters['csServerSettings/getAPIDataMethodURL'](
          'invokeAction',
          payload.serverSide
        ),
        dataToPost,
        getters.getAPIDataRequestConfig()
      )
      await dispatch('clearHiddenErrors', {state: state, dispatch: dispatch})
      await dispatch('setErrors', {
        appWindowIdent: payload.appWindowIdent,
        dataSetIdent: payload.dataSetIdent,
        row: payload.row,
        errors: response.errors,
        action: action
      })
      let data = response.data
      if (data !== null) {
        await dispatch('clearHiddenErrors', {state: state, dispatch: dispatch})
        await dispatch('setErrors', {
          appWindowIdent: payload.appWindowIdent,
          dataSetIdent: payload.dataSetIdent,
          row: payload.row,
          errors: data.errors,
          action: action
        })
        await dispatch('processCommands', {
          appWindowIdent: payload.appWindowIdent,
          dataSetIdent: payload.dataSetIdent,
          commands: data.commands,
          row: payload.row,
          where: where,
          router: payload.router,
          window: payload.window
        })
      }
    }
    actionState = getters.getDataSetActionState(dataSet, payload.actionIdent, row)
    if (actionState !== -1) {
      await commit('SET_DATASET_ACTION_STATE', { action: action, row: payload.row, state: 1 })
      if (action.removeFiles === 1)
        await commit('DELETE_ALL_FILES', { dataSet })
      if (payload.execute === 1 && payload.modalWindow)
        await dispatch('deleteModalWindow', payload.modalWindow)
      if (action.clearSelectedRows === 1)
        await commit('DELETE_ALL_SELECTED_ROW', { dataSet })
    }
  },
  exportData: async ({ getters, dispatch, rootGetters }, payload) => {
    if (!payload.appWindowIdent || !payload.dataSetIdent)
      return
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    let action = getters.getDataSetAction(dataSet, payload.actionIdent)
    let request = getters.getAPIExportDataRequest(payload.appWindowIdent, payload.dataSetIdent, action.kind)
    let response = await axios.post(
      rootGetters['csServerSettings/getAPIDataMethodURL']('exportData', payload.serverSide),
      request,
      getters.getAPIDataRequestConfig()
    )
    await dispatch('setErrors', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: payload.dataSetIdent,
      errors: response.errors,
      action: action,
      row: payload.row
    })
    let data = response.data
    if (!data) return
    if (data.errors) {
      await dispatch('setErrors', {
        appWindowIdent: payload.appWindowIdent,
        dataSetIdent: payload.dataSetIdent,
        errors: data.errors,
        action: action,
        row: payload.row
      })
    }
    if (action.state !== -1 && payload.window && data.fileUrl)
      payload.window.location.href = rootGetters['csServerSettings/getAPIDataMethodURL']('content/download', payload.serverSide) + data.fileUrl
  },
  downloadFile: async ({rootGetters}, payload) =>{
    if (!payload.window || payload.remoteFileName == null)
      return
    let localFileName = payload.localFileName == null ? payload.remoteFileName : payload.localFileName
    payload.window.location.href = rootGetters['csServerSettings/getAPIDataMethodURL']('content/download', payload.serverSide) + '/' + payload.remoteFileName + '/' + localFileName
  },
  addError: async ({ dispatch }, payload) => {
    dispatch('setErrors', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: payload.dataSetIdent,
      row: payload.row,
      errors: payload.errors
    })
  },
  addMessage: async ({ dispatch }, payload) => {
    dispatch('setErrors', payload.messages)
    await payload.messages.forEach(message => {
      dispatch('processCommands', {
        commands: message.commands
      })
    })
  },
  processCommands: async ({ dispatch }, payload) => {
    let row = payload.row
    let where = payload.where
    let router = payload.router
    let window = payload.window
    if (payload.commands) {
      await payload.commands.forEach(item => {
        let command = item.command
        let payload = item.payload
        payload = { ...payload, row: row, where: where, router: router, window: window}
        if (command) dispatch(command, payload)
      })
    }
  },
  hideError: ({ commit }, payload) => {
    commit('HIDE_ERROR', payload)
  },
  hideAllErrors: ({ state, dispatch }) => {
    state.errors.forEach(error => {
      dispatch('hideError', {error: error})
    })
  },
  clearHiddenErrors: ({ state, dispatch }) => {
    state.errors.forEach(error => {
      if(error.isVisible === false) {
        dispatch('removeError', {error: error})
      }
    })
  },
  removeError: ({ commit }, payload) => {
    commit('DEL_ERROR', payload)
  },
  clearErrors: ({ state, dispatch }) => {
    while(state.errors.length > 0) {
      dispatch('removeError', {error: state.errors[0]})
    }
  },
  removeMessage: ({ commit }, message) => {
    commit('DEL_MESSAGE', message)
  },
  clearMessages: ({ state, dispatch }) => {
    while(state.messages.length > 0) {
      dispatch('removeMessage', {message: state.messages[0]})
    }
  },
  setDataSetRefReqAll: ({ commit, getters }, payload) => {
    let appWindow = getters.getAppWindow(
      payload.appWindowIdent
    )
    let refreshAggregates = payload.refreshAggregates
    commit('SET_DATASET_REFREQ_ALL', { appWindow, refreshAggregates })
  },
  setDataSetRefReq: ({ commit, getters }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    let {refreshAggregates, refCondition} = payload
    commit('SET_DATASET_REFREQ', { dataSet, refreshAggregates })
    if (getters.isDev && refCondition)
      commit('ADD_REFCONDITION', { dataSet, refCondition })
  },
  setDataSetCurrentRowIndex: ({ dispatch, commit }, payload) => {
    let dataSet = payload.dataSet
    let currentRowIndex = payload.currentRowIndex
    commit('SET_DATASET_CURRENT_ROW_INDEX', { dataSet, currentRowIndex })
    dispatch('refreshDataSetDependence', {
      appWindowIdent: payload.appWindowIdent,
      parentDataSetIdent: dataSet.dataSetIdent,
      refreshAggregates: 1
    })
  },
  setDataSetCurrentRow: ({ dispatch, commit }, payload) => {
    let dataSet = payload.dataSet
    let row = payload.row
    let currentRowIndex = -1
    if (dataSet !== null && dataSet.rows !== null) {
      currentRowIndex = dataSet.rows.indexOf(row)
    }
    commit('SET_DATASET_CURRENT_ROW_INDEX', { dataSet, currentRowIndex })
    dispatch('refreshDataSetDependence', {
      appWindowIdent: payload.appWindowIdent,
      parentDataSetIdent: dataSet.dataSetIdent,
      refreshAggregates: 1
    })
  },
  setDataSetCurrentRowFromFilter: ({getters, commit, dispatch}, payload) => {
    let dataSet = getters.getDataSet(payload.appWindowIdent, payload.dataSetIdent)
    if (!dataSet || !payload.filter)
      return
    if (dataSet.state === dataSetUtils.state.added || dataSet.state === dataSetUtils.state.progress)
      commit('SET_DATASET_CURRENT_ROW_FILTER', { dataSet: dataSet, filter: payload.filter})
    else {
      let row = getters.appWindowDataSetFindRow(payload.appWindowIdent, payload.dataSetIdent, payload.filter)
      if (row)
        dispatch('setDataSetCurrentRow', {dataSet, row})
    }
  },
  setDataSetCurrentPivotIndex: async ({ commit, dispatch, getters }, payload) => {
    let dataSet = getters.getDataSet(
      payload.appWindowIdent,
      payload.dataSetIdent
    )
    let pivotCurrentRowIndex = payload.pivotCurrentRowIndex
    let pivotCurrentColIndex = payload.pivotCurrentColIndex
    let pivotCurrentDataFieldIdent = payload.pivotCurrentDataFieldIdent
    if (dataSet && dataSet.pivotCurrentRowIndex === pivotCurrentRowIndex && 
      dataSet.pivotCurrentColIndex === pivotCurrentColIndex && dataSet.pivotCurrentDataFieldIdent === pivotCurrentDataFieldIdent)
      return
    await commit('SET_DATASET_CURRENT_PIVOT_INDEX', {
      dataSet,
      pivotCurrentRowIndex,
      pivotCurrentColIndex,
      pivotCurrentDataFieldIdent
    })
    await dispatch('refreshDataSetDependence', {
      appWindowIdent: payload.appWindowIdent,
      parentDataSetIdent: payload.dataSetIdent,
      refreshAggregates: 1
    })
  },
  setDataSetColFieldAttr: async ({ getters, commit }, payload) => {
    let dataSet = payload.dataSet
    let colFieldIndex = payload.colFieldIndex
    let colFields = getters.getDataSetColFields(dataSet)
    let colField = colFields[colFieldIndex]
    let attr = payload.attr
    commit('SET_DATASET_COL_FIELD_ATTR', { dataSet, colField, attr })
  },
  setDataSetVisibleColFieldAttr: async ({ getters, commit }, payload) => {
    let dataSet = payload.dataSet
    let colFieldIndex = payload.colFieldIndex
    let colFields = getters.getDataSetVisibleColFields(dataSet)
    let colField = colFields[colFieldIndex]
    let attr = payload.attr
    commit('SET_DATASET_COL_FIELD_ATTR', { dataSet, colField, attr })
  },
  setDataSetFirstRow: ({ commit }, dataSet) => {
    if (dataSet != null && dataSet.rows.length > 1) {
      let currentRowIndex = 0
      commit('SET_DATASET_CURRENT_ROW_INDEX', { dataSet, currentRowIndex })
    }
  },
  setDataSetPrevRow: ({ commit }, dataSet) => {
    let currentRowIndex = dataSet.currentRowIndex
    if (currentRowIndex - 1 >= 0) {
      currentRowIndex--
      commit('SET_DATASET_CURRENT_ROW_INDEX', { dataSet, currentRowIndex })
    }
  },
  setDataSetPrevRowByStep: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let currentRowIndex = dataSet.currentRowIndex
    let pageNo = dataSet.pageNo
    let step = payload.step || 1
    let pagesCount = getters.getDataSetPagesCount(dataSet)
    if (currentRowIndex - 1 >= 0) {
      currentRowIndex--
      commit('SET_DATASET_CURRENT_ROW_INDEX', { dataSet, currentRowIndex })
    } else if (currentRowIndex - 1 < 0 && pageNo > 1) {
      pageNo--
      dispatch('setDataSetPageNo', {dataSet, pageNo})
      currentRowIndex = dataSet.rows.length - step
      commit('SET_DATASET_CURRENT_ROW_INDEX', { dataSet, currentRowIndex })
    } else if (pageNo === 1 && pagesCount > 1) {
      pageNo = pagesCount
      dispatch('setDataSetPageNo', {dataSet, pageNo})
      currentRowIndex = dataSet.rows.length - step
      commit('SET_DATASET_CURRENT_ROW_INDEX', { dataSet, currentRowIndex })
    } else if (pageNo === 1) {
      currentRowIndex = dataSet.rows.length - step
      commit('SET_DATASET_CURRENT_ROW_INDEX', { dataSet, currentRowIndex })
    }
  },
  setDataSetNextRow: ({ commit }, dataSet) => {
    let currentRowIndex = dataSet.currentRowIndex
    if (currentRowIndex + 1 < dataSet.rows.length) {
      currentRowIndex++
      commit('SET_DATASET_CURRENT_ROW_INDEX', { dataSet, currentRowIndex })
    }
  },
  setDataSetNextRowByStep: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let currentRowIndex = dataSet.currentRowIndex
    let pageNo = dataSet.pageNo
    let step = payload.step || 1
    let pagesCount = getters.getDataSetPagesCount(dataSet)
    if (currentRowIndex + step < dataSet.rows.length) {
      currentRowIndex++
      commit('SET_DATASET_CURRENT_ROW_INDEX', { dataSet, currentRowIndex })
    } else if (
      currentRowIndex + step >= dataSet.rows.length &&
      pageNo < pagesCount
    ) {
      pageNo++
      dispatch('setDataSetPageNo', {dataSet, pageNo})
    } else if (pageNo === pagesCount && pagesCount === 1) {
      currentRowIndex = 0
      commit('SET_DATASET_CURRENT_ROW_INDEX', { dataSet, currentRowIndex })
    } else if (pageNo === pagesCount)
      dispatch('setDataSetPageNoFirst', payload)
  },
  setDataSetFieldValue: async ({ dispatch, getters }, payload) => {
    if (payload.dataFieldIdent === null) return null
    if (payload.dataSet == null && payload.appWindowIdent != null && payload.dataSetIdent != null)
      payload.dataSet = getters.getDataSet(payload.appWindowIdent, payload.dataSetIdent)
    let action = 'setDataSetRowsFieldValue'
    switch (payload.sourceKind) {
    case 'aggregates':
      action = 'setDataSetAggregatesFieldValue'
      break
    case 'where':
      action = 'setDataSetWhereFieldValue'
      break
    case 'pivotValues':
      action = 'setDataSetPivotValuesFieldValue'
      break
    }
    await dispatch(action, payload)
  },
  setDataSetRowStatus: async ({ commit }, payload) => {
    commit('SET_DATASET_ROW_STATUS', {
      row: payload.row,
      status: payload.status
    })
  },
  setDataSetRowsFieldValue: async ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let row = payload.row || getters.getDataSetCurrentRow(dataSet)
    if (!row)
      return
    let dataFieldValue = payload.dataFieldValue
    if (dataFieldValue === '') dataFieldValue = null
    let dataFieldIdent = payload.dataFieldIdent
    await commit('SET_DATASET_ROWS_FIELD_VALUE', {
      row,
      dataFieldIdent,
      dataFieldValue
    })
    await dispatch('setDataSetRowStatus', {
      row: row,
      status: dataSetUtils.rowState.modified
    })
    let onCFActionIdent = getters.getFieldsOnCFActionIdentsOnCFActionIdent(
      dataSet,
      dataFieldIdent
    )
    if (onCFActionIdent && payload.onCFLock !== 1 && payload.oncfTimeout) {
      let action = getters.getDataSetAction(dataSet, onCFActionIdent)
      let timer = setTimeout( () => {
        dispatch('invokeAction', {
          appWindowIdent: payload.appWindowIdent,
          dataSetIdent: dataSet.dataSetIdent,
          actionIdent: onCFActionIdent,
          onCFDataFieldIdent: dataFieldIdent,
          row: row
        })
      }, payload.oncfTimeout)
      await commit('SET_DATASET_ACTION_TIMER', {      
        row,
        action,
        timer
      })
    }
    else if (onCFActionIdent && payload.onCFLock !== 1){
      await dispatch('invokeAction', {
        appWindowIdent: payload.appWindowIdent,
        dataSetIdent: dataSet.dataSetIdent,
        actionIdent: onCFActionIdent,
        onCFDataFieldIdent: dataFieldIdent,
        row: row
      })
    }
  },
  setDataSetAggregatesFieldValue: ({ commit }, payload) => {
    let dataSet = payload.dataSet
    let dataFieldValue = payload.dataFieldValue
    let dataFieldIdent = payload.dataFieldIdent
    commit('SET_DATASET_AGGREGATES_FIELD_VALUE', {
      dataSet,
      dataFieldIdent,
      dataFieldValue
    })
  },
  setDataSetPivotValuesFieldValue: async (
    { dispatch, commit, getters },
    payload
  ) => {
    let dataSet = payload.dataSet
    let dataFieldValue = payload.dataFieldValue
    let dataFieldIdent = payload.dataFieldIdent
    let pivotRow = payload.pivotRow
    let pivotCol = payload.pivotCol
    let pivotRowKey = payload.pivotRowKey
    let row =
      payload.dataSet.pivotValues[pivotRowKey] ||
      getters.getPivotEmptyRow(pivotCol, pivotRow)
    let colFields = getters.getDataSetColFields(dataSet)
    let rowFields = getters.getDataSetRowFields(dataSet)
    let rowTransformed = constructors.csRow()
    colFields.forEach((item, index) => {
      rowTransformed[item.dataFieldIdent] =
        payload.dataSet.pivotCols[row[2]['c']][index][0]
    })
    rowFields.forEach((item, index) => {
      rowTransformed[item.dataFieldIdent] =
        payload.dataSet.pivotRows[row[2]['r']][index][0]
    })
    rowTransformed[payload.dataFieldIdent] = payload.dataFieldValue
    await commit('SET_DATASET_PIVOT_VALUES_FIELD_VALUE', {
      dataSet,
      row,
      pivotRowKey,
      dataFieldIdent,
      dataFieldValue
    })
    await dispatch('invokeAction', {
      appWindowIdent: payload.appWindowIdent,
      dataSetIdent: payload.dataSet.dataSetIdent,
      actionIdent: payload.dataSet.pivotUpdateActionIdent,
      row: rowTransformed
    })
  },
  updateUrlQuery: async ({ dispatch, commit, getters }, payload) => {
    let {dataSet, selectedRowsAdd = [], selectedRowsDel = []} = payload
    if (dataSet == null)
      return
    let {whereFieldsIdents, where = {}} = dataSet
    if (!await dispatch('checkRouter'))
      return
    if (whereFieldsIdents == null)
      return
    let query = JSON.parse(JSON.stringify(storeUtils.router.currentRoute.query))
    let changed = false
    whereFieldsIdents.forEach(whereFieldIdent => {
      if (whereFieldIdent.linkedParamName == null || whereFieldIdent.updateUrl === 0)
        return
      let whereVal = where[whereFieldIdent.dataFieldIdent]
      let queryVal = query[whereFieldIdent.linkedParamName]
      if (whereVal == queryVal)
        return
      if (whereVal == null || whereVal == whereFieldIdent.dataFieldValueDef){
        if (query[whereFieldIdent.linkedParamName] !== undefined) {
          delete query[whereFieldIdent.linkedParamName]
          changed = true
        }
      }
      else{
        query[whereFieldIdent.linkedParamName] = whereVal
        changed = true
      }
    })
    selectedRowsAdd.forEach(row => {
      if (row._urlParamName == null)
        return
      switch(row._urlParamKind){
      case 'list':
        if (row._urlParamValue == null)
          break
        if (!(query[row._urlParamName] instanceof Array)){
          if (query[row._urlParamName] != null)
            query[row._urlParamName] = [query[row._urlParamName]]
          else
            query[row._urlParamName] = []
        }
        var paramArr = query[row._urlParamName]
        var param = paramArr.find(p => p == row._urlParamValue)
        if (!param){
          paramArr.push(row._urlParamValue)
          changed = true
        }
        break
      }
    })
    selectedRowsDel.forEach(row => {
      if (row._urlParamName == null)
        return
      switch(row._urlParamKind){
      case 'list':
        if (row._urlParamValue == null)
          break
        if (query[row._urlParamName] instanceof Array) {
          var paramArr = query[row._urlParamName]
          var idx = paramArr.findIndex(p => p == row._urlParamName)
          paramArr.splice(idx, 1)
          changed = true
        }
        else if (query[row._urlParamName] == row._urlParamValue){
          delete query[row._urlParamName]
          changed = true
        }
      }
    })
    if (changed){
      storeUtils.pRouter = storeUtils.pRouter
        .then(() => {
          commit('LOCK_URL')
          return storeUtils.router.replace({ query })
        })
        .catch((e) => {
          if (getters.isDev){
            /* eslint-disable no-console */
            console.log(e)
            /* eslint-enable no-console */
          }
          commit('UNLOCK_URL')
        })
    }
  },
  setDataSetAttribFromWhere: async ({commit, getters}, payload) => {
    let dataSet = payload.dataSet
    if (!dataSet) throw 'Empty dataSet'
    let dataFieldIdent = payload.dataFieldIdent
    let dataFieldValue = payload.dataFieldValue
    let whereFieldsIdent = getters.getDataSetWhereFieldsIdentsDataField(dataSet, dataFieldIdent)
    if (!whereFieldsIdent)
      return
    switch(whereFieldsIdent.dataSetAttrib){
    case 'pageSizeIdent':
      var pageSize = getters.getDataSetPageSizes(dataSet, dataFieldValue)
      if (pageSize == null) {
        break
      }
      commit('SET_DATASET_PAGESIZESIDENT', {dataSet: dataSet, pageSizesIdent: dataFieldValue, pageSize: pageSize.pageSize})
      break
    case 'pageNo':
      var pagesCount = getters.getDataSetPagesCount(dataSet)
      if (pagesCount > 0 && dataFieldValue > pagesCount)
        break
      if (dataFieldValue < 1)
        break
      commit('SET_DATASET_PAGENOREF', {dataSet: dataSet, pageNo: dataFieldValue, pagesCount: pagesCount})
      break
    case 'sortIdent':
      var layout = getters.getDataSetLayout(
        dataSet,
        getters.getDataSetLayoutIdent(dataSet)
      )
      if (getters.getDataSetSort(dataSet, dataFieldValue))
        commit('SET_LAYOUT_SORTIDENT', {
          layout: layout,
          sortIdent: dataFieldValue
        })
      break
    default:
      break
    }
  },
  setDataSetWhereFromAttrib: ({getters, dispatch}, payload) =>{
    let dataSet = payload.dataSet
    let wfis = getters.getDataSetWhereFieldsIdents(dataSet)
    let attribName = payload.attribName
    if (wfis == null || attribName == null)
      return
    let wfi = wfis.find(f => f.dataSetAttrib === attribName)
    if (wfi == null)
      return
    dispatch('setDataSetWhereFieldValue', {
      dataSet: dataSet,
      dataFieldValue: payload.attribValue,
      dataFieldIdent: wfi.dataFieldIdent,
      attribLock: 1
    })
  },
  setDataSetWhereFieldValue: async (
    { dispatch, commit, getters },
    payload
  ) => {
    let dataSet = payload.dataSet
    let dataFieldIdent = payload.dataFieldIdent
    let attribLock = payload.attribLock
    let whereFieldsIdent = getters.getDataSetWhereFieldsIdentsDataField(dataSet, dataFieldIdent) 
    if (!whereFieldsIdent){
      /* eslint-disable no-console */
      console.error('Brak parametru wejściowego [' + dataFieldIdent + '] dataSet [' + (dataSet ? dataSet.dataSetIdent : undefined) + ']')
      /* eslint-enable no-console */
      return
    }
    let noRefReq = payload.noRefReq != null ? payload.noRefReq : (whereFieldsIdent.refreshDependencyKind === 'none' ? 1 : 0)
    let dataFieldValue = payload.dataFieldValue = dataSetUtils.checkDataType(payload.dataFieldValue, whereFieldsIdent ? whereFieldsIdent.formatType : 'string')
    if (dataSet == null || dataFieldIdent == null)
      return
    if (attribLock !== 1){
      await dispatch('setDataSetAttribFromWhere', payload)
    }
    commit('SET_DATASET_WHERE_FIELD_VALUE', {
      dataSet,
      dataFieldValue,
      dataFieldIdent,
      noRefReq
    })
    let onCFActionIdent = getters.getDataSetWhereOnCFActionIdentsOnCFActionIdent(
      dataSet,
      dataFieldIdent
    )

    if (onCFActionIdent && payload.onCFLock !== 1 && payload.oncfTimeout) {
      let action = getters.getDataSetAction(dataSet, onCFActionIdent)
      let timer = setTimeout( async () => {
        await dispatch('invokeAction', {
          appWindowIdent: payload.appWindowIdent,
          dataSetIdent: dataSet.dataSetIdent,
          actionIdent: onCFActionIdent,
          onCFDataFieldIdent: dataFieldIdent
        })
        if (payload.refreshLock !== 1){
          if (!whereFieldsIdent || whereFieldsIdent.refreshDependency !== 1)
            return
    
          await dispatch('refreshDataSet', {
            appWindowIdent: payload.appWindowIdent,
            dataSetIdent: dataSet.dataSetIdent,
            refreshAggregates: 1
          })
        }
      }, payload.oncfTimeout)
      await commit('SET_DATASET_ACTION_TIMER', {      
        action,
        timer
      })
    }
    else if (onCFActionIdent && payload.onCFLock !== 1) {
      await dispatch('invokeAction', {
        appWindowIdent: payload.appWindowIdent,
        dataSetIdent: dataSet.dataSetIdent,
        actionIdent: onCFActionIdent,
        onCFDataFieldIdent: dataFieldIdent
      })
      if (payload.refreshLock !== 1){
        let whereFieldsIdent = getters.getDataSetWhereFieldsIdentsDataField(dataSet, dataFieldIdent)
        if (!whereFieldsIdent || whereFieldsIdent.refreshDependency !== 1)
          return
  
        await dispatch('refreshDataSet', {
          appWindowIdent: payload.appWindowIdent,
          dataSetIdent: dataSet.dataSetIdent,
          refreshAggregates: 1
        })
      }
    }
    else {
      if (payload.refreshLock !== 1){
        let whereFieldsIdent = getters.getDataSetWhereFieldsIdentsDataField(dataSet, dataFieldIdent)
        if (!whereFieldsIdent || whereFieldsIdent.refreshDependency !== 1)
          return
  
        await dispatch('refreshDataSet', {
          appWindowIdent: payload.appWindowIdent,
          dataSetIdent: dataSet.dataSetIdent,
          refreshAggregates: 1
        })
      }
    }
  },
  setDataSetWhereListsFieldValue: ({ commit }, payload) => {
    let dataSet = payload.dataSet
    let lookupDataFieldIdent = payload.lookupDataFieldIdent
    let whereListValue = payload.whereListValue
    commit('SET_DATASET_WHERE_LISTS_FIELD_VALUE', {
      dataSet,
      lookupDataFieldIdent,
      whereListValue
    })
  },
  setRowListsFieldValue: ({ commit, getters }, payload) => {
    let {dataSet, row, lookupDataFieldIdent, whereListValue} = payload
    row = row || getters.getDataSetCurrentRow(dataSet)
    commit('SET_ROW_LISTS_FIELD_VALUE', {row, lookupDataFieldIdent, whereListValue})
  },
  pushRegisterSubscription: async ({ dispatch, getters, state, rootGetters }, payload) => {
    let dataToPost = {
      sessionId: getters.getSessionId(state),
      subscription: payload.subscription
    }
    let response = await axios.post(
      rootGetters['csServerSettings/getAPIDataMethodURL'](
        'pushRegisterSubscription',
        payload.serverSide
      ),
      dataToPost,
      getters.getAPIDataRequestConfig()
    )
    await dispatch('setErrors', {
      errors: response.errors
    })
  },
  pushSendTestMessage: async ({ dispatch, getters, state, rootGetters }, payload) => {
    let dataToPost = {
      sessionId: getters.getSessionId(state),
      subscription: payload.subscription,
      title: payload.title,
      url: payload.url,
      body: payload.body
    }
    let response = await axios.post(
      rootGetters['csServerSettings/getAPIDataMethodURL'](
        'pushSendNotify',
        payload.serverSide
      ),
      dataToPost,
      getters.getAPIDataRequestConfig()
    )
    await dispatch('setErrors', {
      errors: response.errors
    })
  },
  putFile: async ({ commit, rootGetters, dispatch }, payload) => {
    let file = payload.file
    let dataToPost = new FormData()
    dataToPost.append(payload.file.__uuid, file.file)
    let config = {
      onUploadProgress: function (progressEvent) {
        let progress = Math.round((progressEvent.loaded * 100) / progressEvent.total)
        commit('SET_FILE_PROGRESS', { file, progress })
      },
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    }
    await commit('SET_FILE_STATUS', { file: file, status: dataSetUtils.fileState.uploading })
    let url = rootGetters['csServerSettings/getAPIDefinitionMethodURL'](
      'putFiles',
      payload.serverSide
    )
    let response = await axios.put(
      url,
      dataToPost,
      config
    )
    await dispatch('setErrors', {
      errors: response.errors
    })
    if (response.data)
      await dispatch('setErrors', {
        errors: response.data.errors
      })
    if (response.errors || (response.data && response.data.errors))
      await commit('SET_FILE_STATUS', { file: file, status: dataSetUtils.fileState.error })
    else if (response.data) {
      await commit('SET_FILE_STATUS', { file: file, status: dataSetUtils.fileState.uploaded })
      await commit('SET_FILE_DATA', { file: file, data: response.data.data ? response.data.data[0] : undefined })
    }
  },
  putAllFiles: async ({ dispatch }, payload) => {
    if (!payload.dataSet)
      return
    let files = payload.dataSet.files
    await Promise.all(
      files.map(async file => {
        if (file._status !== dataSetUtils.fileState.uploaded)
          await dispatch('putFile', { file })
      })
    )
  },
  deleteAllFiles: async ({ commit }, payload) => {
    if (!payload.dataSet)
      return
    await commit('DELETE_ALL_FILES', payload)
  },
  setScrollDirection: ({ commit }, payload) => {
    let dataSet = payload.dataSet
    let scrollDirection = payload.scrollDirection
    commit('SET_DATASET_SCROLL_DIRECTION', { dataSet, scrollDirection })
  },
  setColFieldOrd: async ({ commit, getters, dispatch }, {dataSet, colField, colFieldNew, setCurrent}) => {
    let layout = getters.getDataSetLayout(dataSet, getters.getDataSetLayoutIdent(dataSet))
    if (!layout || !(layout.colFields instanceof Array))
      return
    let idxOld = layout.colFields.indexOf(colField)
    let idxNew = layout.colFields.indexOf(colFieldNew)
    if (idxOld * idxNew < 0)
      return
    if (!layout.usrDef)
      layout = await dispatch('addUsrLayout', {layout, dataSet})
    commit('MOVE_COL_FIELD', { colFields: layout.colFields, idxOld: idxOld, idxNew: idxNew})
    if (setCurrent)
      commit('SET_CURRENT_COL_FIELD_INDEX', {layout: layout, currentColFieldIndex: idxNew})
  },
  setSortColFieldOrd: async ({ commit, getters, dispatch }, {dataSet, sortColField, sortColFieldNew, setCurrent}) => {
    let layout = getters.getDataSetLayout(dataSet, getters.getDataSetLayoutIdent(dataSet))
    let sortColFields = getters.getDataSetSortColFields(dataSet)
    if (!layout || !(sortColFields instanceof Array))
      return
    let idxOld = sortColFields.indexOf(sortColField)
    let idxNew = sortColFields.indexOf(sortColFieldNew)
    if (idxOld * idxNew < 0)
      return
    if (!layout.usrDef){
      layout = await dispatch('addUsrLayout', {layout, dataSet})
      sortColFields = getters.getDataSetSortColFields(dataSet)
    }
    commit('MOVE_SORT_COL_FIELD', { sortColFields, idxOld, idxNew})
    if (setCurrent){
      let sort = getters.getDataSetSort(
        dataSet,
        getters.getDataSetSortIdent(dataSet)
      )
      commit('SET_CURRENT_SORT_COL_FIELD_INDEX', {sort: sort, currentSortColFieldIndex: idxNew})
    }
  },
  setColFieldVisibility: async ({commit, getters, dispatch}, {colField, isVisible, layout, dataSet}) => {
    if (!layout)
      layout = getters.getDataSetLayout(
        dataSet,
        getters.getDataSetLayoutIdent(dataSet)
      )
    if (!layout)
      return
    if (layout.usrDef){
      commit('SET_COL_FIELD_VISIBILITY', {colField, isVisible})
      return
    }
    let newL = await dispatch('addUsrLayout', { layout, dataSet})
    if (!newL)
      return
    let newCF = newL.colFields.find(c => c.dataFieldIdent === colField.dataFieldIdent)
    commit('SET_COL_FIELD_VISIBILITY', { colField: newCF, isVisible: isVisible})
  },
  addUsrLayout:({commit, getters}, {layout, dataSet}) =>{
    if (!dataSet)
      return null
    let appWindow = getters.getAppWindow(dataSet.appWindowIdent)
    if (!appWindow)
      return null
    if (layout)
      var newL = JSON.parse(JSON.stringify(layout))
    else 
      newL = constructors.csLayout()
    newL.usrDef = 1
    newL.device = getters.deviceType
    newL.owner = 1
    newL.global = 0
    commit('ADD_USR_LAYOUT', {
      layout: newL,
      dataSetUsrSettings: getters.getDataSetUsrSettings(appWindow, dataSet.dataSetIdent)
    })
    return newL
  },
  removeUsrLayout: ({commit, getters}, {layoutIdent, dataSetIdent, appWindowIdent}) =>{
    let appWindow = getters.getAppWindow(appWindowIdent)
    let dataSet = getters.getDataSet(appWindowIdent, dataSetIdent)
    let dataSetUsrSettings = getters.getDataSetUsrSettings(appWindow, dataSetIdent)
    if (!appWindow || !dataSet || !dataSetUsrSettings)
      return
    commit('REMOVE_USR_LAYOUT', {dataSetUsrSettings, layoutIdent})
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    if (layout)
      return
    let layouts = getters.getDataSetLayoutIdents(dataSet)
    if (!(layouts instanceof Array))
      return
    layout = layouts.find(l => l.default === 1)
    if (!layout)
      layout = layouts[0]
    commit('SET_LAYOUT_IDENT', {dataSet: dataSet, layoutIdent: layout.layoutIdent})
  },
  setLayoutAttr({commit}, payload){
    commit('SET_LAYOUT_ATTR', payload)
  },
  setLayoutSortIdentToUsrDefinedWithCopy: ({ commit, getters, dispatch }, payload) => {
    let dataSet = payload.dataSet
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    let sortIdents = getters.getDataSetSortIdents(dataSet)
    let currentSort = getters.getDataSetSort(
      dataSet,
      getters.getDataSetSortIdent(dataSet)
    )
    if (layout === null || sortIdents === null) return
    let usrSort = sortIdents.find(item => {
      return item.isUsrDefined === 1
    })
    if (usrSort) {
      if (currentSort){
        let sortColFields = JSON.parse(JSON.stringify(currentSort.sortColFields))
        commit('SET_SORT_IDENT_SORT_COL_FIELDS', {
          sort: usrSort,
          sortColFields: sortColFields
        })
      }
      commit('SET_LAYOUT_SORTIDENT', {
        layout: layout,
        sortIdent: usrSort.sortIdent
      })
      dispatch('setDataSetWhereFromAttrib', {
        dataSet: dataSet,
        attribName: 'sortIdent',
        attribValue: usrSort.sortIdent
      })
      return usrSort
    }
  },
  setSortIdentSortColFields: ({ commit }, payload) => {
    commit('SET_SORT_IDENT_SORT_COL_FIELDS', { payload })
  },
  addSortColFieldToSortIdent: async ({commit, getters, dispatch}, {dataSet, colField}) => {
    if (!dataSet)
      return
    let layout = getters.getDataSetLayout(dataSet, getters.getDataSetLayoutIdent(dataSet))
    if (!layout.usrDef)
      layout = await dispatch('addUsrLayout', {layout, dataSet})
    let sort = getters.getDataSetSort(
      dataSet,
      getters.getDataSetSortIdent(dataSet)
    )
    if (!sort.isUsrDefined)
      sort = await dispatch('setLayoutSortIdentToUsrDefinedWithCopy', {dataSet})
    if (colField && sort) {
      let sortColField = {
        dataFieldIdent: colField.dataFieldIdent,
        dataFieldColTranslatedDesc: colField.dataFieldColTranslatedDesc,
        isDesc: 0,
        sortType: 0,
        ord: 0
      }
      commit('ADD_SORT_IDENT_SORT_COL_FIELD', { sort, sortColField })
      let sortColFields = sort.sortColFields
      let currentSortColFieldIndex = sortColFields.length - 1
      commit('SET_CURRENT_SORT_COL_FIELD_INDEX', {
        sort,
        currentSortColFieldIndex
      })
    }
  },
  deleteSortColField: async ({commit, getters, dispatch}, {dataSet, sortColField}) => {
    if (!dataSet)
      return
    let layout = getters.getDataSetLayout(dataSet, getters.getDataSetLayoutIdent(dataSet))
    if (!layout.usrDef)
      layout = await dispatch('addUsrLayout', {layout, dataSet})
    let sort = getters.getDataSetSort(
      dataSet,
      getters.getDataSetSortIdent(dataSet)
    )
    let index = sort.sortColFields.findIndex(s => s.dataFieldIdent === sortColField.dataFieldIdent)
    if (!sort.isUsrDefined)
      sort = await dispatch('setLayoutSortIdentToUsrDefinedWithCopy', {dataSet})
    let ord = getters.getDataSetSortColFields(dataSet).length
    commit('DELETE_SORT_IDENT_SORT_COL_FIELD', {
      sort,
      index
    })
    let currentSortColFieldIndex = getters.getCurrentSortColFieldIndex(
      dataSet
    )
    currentSortColFieldIndex =
      currentSortColFieldIndex >= ord - 1
        ? currentSortColFieldIndex === 0
          ? 0
          : currentSortColFieldIndex - 1
        : currentSortColFieldIndex
    commit('SET_CURRENT_SORT_COL_FIELD_INDEX', {
      sort,
      currentSortColFieldIndex
    })
  },
  deleteAllSortColFields: async ({commit, getters, dispatch}, {dataSet}) => {
    if (!dataSet)
      return
    let layout = getters.getDataSetLayout(dataSet, getters.getDataSetLayoutIdent(dataSet))
    if (!layout.usrDef)
      layout = await dispatch('addUsrLayout', {layout, dataSet})
    let sort = getters.getDataSetSort(
      dataSet,
      getters.getDataSetSortIdent(dataSet)
    )
    if (!sort.isUsrDefined)
      sort = await dispatch('setLayoutSortIdentToUsrDefinedWithCopy', {dataSet})
    commit('DELETE_ALL_SORT_IDENT_SORT_COL_FIELDS', {sort})
  },
  setSortColFieldsIsDesc: async ({getters, dispatch, commit}, {dataSet, sortColField, isDesc}) => {
    if (!dataSet)
      return
    let cloned = false
    let layout = getters.getDataSetLayout(dataSet, getters.getDataSetLayoutIdent(dataSet))
    if (!layout.usrDef){
      layout = await dispatch('addUsrLayout', {layout, dataSet})
      cloned = true
    }
    let sort = getters.getDataSetSort(
      dataSet,
      getters.getDataSetSortIdent(dataSet)
    )
    if (!sort.isUsrDefined){
      sort = await dispatch('setLayoutSortIdentToUsrDefinedWithCopy', {dataSet})
      cloned = true
    }
    if (cloned)
      sortColField = sort.sortColFields.find(s => s.dataFieldIdent === sortColField.dataFieldIdent)
    commit('SET_SORT_COL_FIELD_IS_DESC', {sortColField, isDesc})
  },
  setCurrentColField: ({ commit, getters }, payload) => {
    let dataSet = payload.dataSet
    if (dataSet == null) return
    let colField = payload.colField
    let currentColFieldIndex = -1
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    if (layout !== null && layout.colFields !== null) {
      currentColFieldIndex = layout.colFields.indexOf(colField)
    }
    if (currentColFieldIndex > -1)
      commit('SET_CURRENT_COL_FIELD_INDEX', { layout, currentColFieldIndex })
  },
  setCurrentColFieldIndex:({commit, getters}, {dataSet, currentColFieldIndex}) =>{
    let layout = getters.getDataSetLayout(
      dataSet,
      getters.getDataSetLayoutIdent(dataSet)
    )
    if (!layout || !layout.colFields)
      return
    commit('SET_CURRENT_COL_FIELD_INDEX', { layout, currentColFieldIndex })
  },
  setCurrentSortColField: ({ commit, getters }, payload) => {
    let dataSet = payload.dataSet
    if (dataSet == null) return
    let sortColField = payload.sortColField
    let currentSortColFieldIndex = -1
    let sort = getters.getDataSetSort(
      dataSet,
      getters.getDataSetSortIdent(dataSet)
    )
    if (sort !== null && sort.sortColFields !== null) {
      currentSortColFieldIndex = sort.sortColFields.indexOf(sortColField)
    }
    if (currentSortColFieldIndex > -1)
      commit('SET_CURRENT_SORT_COL_FIELD_INDEX', {
        sort,
        currentSortColFieldIndex
      })
  },
  setRefreshParams: ({ commit }, payload) => {
    commit('SET_REFRESH_PARAMS', payload)
  },
  deleteAppWindowsAll: async ({ state, getters, dispatch, commit }) => {
    await commit('SETACTIVE_APPWINDOW', { appWindowIdent: null })
    await commit('CLEAR_PATHS')
    dispatch('clearErrors', {state: state, dispatch: dispatch})
    dispatch('clearMessages', {state: state, dispatch: dispatch})
    for (let key in getters.csAppWindows) {
      await commit('DELETE_APPWINDOW', { appWindowIdent: key })
    }
  },
  deleteModalWindow: async ({ commit, getters }, payload) => {
    let modalWindows = getters.getAppWindowModalWindows(payload.appWindowIdent)
    let modalWindow = modalWindows && payload.modalWindowIndex ? modalWindows[payload.modalWindowIndex] : null
    if (!modalWindow) return
    if (modalWindow.addNewRow) {
      await commit('DELETE_ROW', {
        dataSet: getters.getDataSet(modalWindow.appWindowIdent, modalWindow.dataSetIdent),
        row: modalWindow.row
      })
    }
    await commit('DELETE_MODAL_WINDOW', {
      modalWindows: modalWindows,
      modalWindowIndex: payload.modalWindowIndex
    })
  },
  setDataSetAggrFieldCalc4Cols: ({ commit }, payload) => {
    commit('SET_DATASET_AGGRFIELD_CALC4COLS', payload)
  },
  setDataSetAggrFieldsCalc4Cols: ({ dispatch, getters }, payload) => {
    if (!payload.dataSet)
      return
    let aggrFields = getters.getDataSetAggrFields(payload.dataSet)
    aggrFields.forEach(aggrField => {
      dispatch('setDataSetAggrFieldCalc4Cols', {
        aggrField: aggrField,
        calc4Cols: payload.calc4Cols
      })
    })
  },
  setDataSetAggrFieldCalc4Rows: ({ commit }, payload) => {
    commit('SET_DATASET_AGGRFIELD_CALC4ROWS', payload)
  },
  setDataSetAggrFieldsCalc4Rows: ({ dispatch, getters }, payload) => {
    if (!payload.dataSet)
      return
    let aggrFields = getters.getDataSetAggrFields(payload.dataSet)
    aggrFields.forEach(aggrField => {
      dispatch('setDataSetAggrFieldCalc4Rows', {
        aggrField: aggrField,
        calc4Rows: payload.calc4Rows
      })
    })
  }
}
