<template>
  <div :style="'height: ' + (tableHeight) + 'px'">
    <!--字段-->
    <div style="display: flex">
      <DkButton ref="button" :icon="hideFlag?'md-arrow-dropleft':'md-arrow-dropright'" @click="handleTools">{{ '字段' }}</DkButton>
      <slot name="button"></slot>
    </div>
    <DkSplit ref="toolSplit" v-model="split" style="margin-top: 3px">
      <div slot="left">
        <DkSplit mode="vertical" :height="tableHeight + 20" v-model="leftSplit">
          <div slot="top" style="display: flex; justify-content: space-between; "
               :style="{height:(this.tableHeight * leftSplit -10) + 'px'}">
            <!-- all fields -->
            <div class="flex-fill drag-area" :class="dragAreaClass" style="margin-right: 4px">
              <div class="drag-area-title mb-3">{{ availableFieldsLabelText }}</div>
              <!--              <div class="d-flex flex-column align-items-start gutter-sm drag-area-zone"></div>-->
              <draggable
                class="d-flex flex-column align-items-start gutter-sm drag-area-zone"
                v-model="internal.availableFieldKeys"
                :scroll="true" animation="300"
                group="fields"
                handle=".btn-draggable"
                @start="start"
                @end="end">
                <div v-for="key in internal.availableFieldKeys" :key="key" class="field">
                  <DkFilterButton :title="fieldsWithValues[key].label" label-key="key" value-key="key"
                                  :multiple="true"
                                  :disabled="true"
                                  :filter="!!fieldsWithValues[key].valueFilter"
                                  v-model="fieldsWithValues[key].values"
                                  :options="fieldsWithValues[key].optionValues"
                                  @on-select="handleSelect(Object.assign({key:key},{model:$event}))"></DkFilterButton>
                </div>
              </draggable>
            </div>
            <!-- Row fields -->
            <div class="drag-area border-primary" :class="dragAreaClass">
              <div class="drag-area-title mb-3">{{ rowsLabelText }}</div>
              <draggable
                v-model="internal.rowFieldKeys"
                class="d-flex flex-column align-items-start gutter-sm drag-area-zone"
                group="fields"
                handle=".btn-draggable"
                :scroll="true" animation="300"
                @start="start"
                @end="end">
                <div v-for="key in internal.rowFieldKeys" :key="key" class="field">
                  <DkFilterButton :title="fieldsWithValues[key].label" label-key="key" value-key="key"
                                  :multiple="true"
                                  :filter="!!fieldsWithValues[key].valueFilter"
                                  v-model="fieldsWithValues[key].values"
                                  :options="fieldsWithValues[key].optionValues"
                                  @on-select="handleSelect(Object.assign({key:key},{model:$event}))"></DkFilterButton>
                </div>
              </draggable>
            </div>
          </div>
          <div slot="bottom" style="display: flex; justify-content: space-between;"
               :style="{height:(this.tableHeight * (1-leftSplit) -10) + 'px'}">
            <!-- Column fields -->
            <div class="flex-fill drag-area border-primary" :class="dragAreaClass" style="margin-right: 4px">
              <div class="drag-area-title mb-3">{{ colsLabelText }}</div>
              <draggable
                :disabled="false"
                v-model="internal.colFieldKeys"
                class="d-flex flex-column align-items-start gutter-sm drag-area-zone"
                group="fields"
                handle=".btn-draggable"
                @start="start"
                @end="end">
                <div v-for="key in internal.colFieldKeys" :key="key" class="field">
                  <DkFilterButton :title="fieldsWithValues[key].label" label-key="key" value-key="key"
                                  :multiple="true"
                                  :filter="!!fieldsWithValues[key].valueFilter"
                                  v-model="fieldsWithValues[key].values"
                                  :options="fieldsWithValues[key].optionValues"
                                  @on-select="handleSelect(Object.assign({key:key},{model:$event}))"></DkFilterButton>
                </div>
              </draggable>
            </div>
            <!-- data fields -->
            <div class="drag-area border-primary" :class="dragAreaClass">
              <div class="drag-area-title mb-3">{{ dataLabelText }}</div>
              <draggable
                :disabled="false"
                v-model="internal.dataFieldKeys"
                class="d-flex flex-column align-items-start gutter-sm drag-area-zone"
                group="fields"
                handle=".btn-draggable"
                @start="start"
                @end="end">
                <div v-for="key in internal.dataFieldKeys" :key="key" class="field">
                  <DkFilterButton :title="fieldsWithValues[key].label" label-key="key" value-key="key"
                                  :multiple="true"
                                  :filter="false"
                                  v-model="fieldsWithValues[key].values"
                                  :options="fieldsWithValues[key].optionValues"
                                  @on-select="handleSelect(Object.assign({key:key},{model:$event}))"></DkFilterButton>
                </div>
              </draggable>
            </div>
          </div>
        </DkSplit>
        <!--        <div style="height: 50px">-->
        <!--          <DkButton @click="currentType='table'">表格</DkButton>-->
        <!--          <DkButton @click="currentType='bar'">柱状图</DkButton>-->
        <!--          <DkButton @click="currentType='line'">折线图</DkButton>-->
        <!--          <DkButton @click="currentType='pie'">饼状图</DkButton>-->
        <!--        </div>-->
      </div>

      <div slot="right">
        <!--  tab区域 -->
        <DkTabs v-model="currentType" :options="tabsOptions"
        ></DkTabs>

        <DkTable v-show="currentType==='table'"
                 :id="'table-'+$options.name" ref="table-select" :data="tableData"
                 :height="tableHeight - 20"
                 :choose-flag="false"
                 :show-setting-flag="false"
                 :pageFlag="false"
                 :perspective-flag="false"
                 :select-flag="false"
                 :loading="isDataLoading">
          <!--行维度-->
          <div v-for="(item,index) in rowFields" :key="index">
            <DkTableColumn :field="item.key" width="auto" :filter="false"
                           :title="item.label"></DkTableColumn>
          </div>

          <div v-if="colFlag">
            <div v-if="colFields && colFields.length > 0">
              <!--列维度(单维度)-->
              <div v-if="colFields.length === 1 && dataFields.length <= 1">
                <DkTableColumn v-for="(item,index) in [...colFields[0].valuesFiltered]"
                               ref="col"
                               :key="index"
                               :field="item+''"
                               width="auto" :filter="false"
                               :title="getTitle(item)"></DkTableColumn>
              </div>
              <!--列维度(多维度)-->
              <div v-else>
                <!--顶层-->
                <vxe-colgroup :title="itemTop+''" v-for="(itemTop,index) in [...colFields[0].valuesFiltered]"
                              :key="index">
                  <!--中间层-->
                  <div v-if="groupCols && groupCols.length > 0">
                    <div v-for="(it,gIndex) in groupCols" :key="gIndex">
                      <vxe-colgroup :title="item+''" v-for="(item,index) in [...groupCols[gIndex].valuesFiltered]"
                                    :key="index">
                        <div v-if="gIndex === groupCols.length - 1 && dataFields.length <= 1">
                          <!--子级(无值列或者一个值列）-->
                          <DkTableColumn v-for="(cItem,cIndex) in [...colFields[colFields.length - 1].valuesFiltered]"
                                         ref="col"
                                         :key="cIndex"
                                         :field="itemTop + '_' + getField(groupCols,index) + cItem"
                                         width="auto" :filter="false"
                                         :title="getTitle(cItem)"></DkTableColumn>
                        </div>
                        <div v-if="gIndex === groupCols.length - 1 && dataFields.length > 1">
                          <!--子级(有多个值列）-->
                          <DkTableColumn v-for="(cItem,cIndex) in dataFields"
                                         ref="col"
                                         :key="cIndex"
                                         :field="itemTop + '_' + getField(groupCols,index) + cItem.key"
                                         width="auto" :filter="false"
                                         :digits="cItem.params?cItem.params.digits:0"
                                         :title="cItem.label"></DkTableColumn>
                        </div>
                      </vxe-colgroup>
                    </div>
                  </div>
                  <div v-else>
                    <div v-if="dataFields.length <= 1">
                      <!--子级(无值列或者一个值列）-->
                      <DkTableColumn v-for="(cItem,cIndex) in [...colFields[colFields.length - 1].valuesFiltered]"
                                     ref="col"
                                     :key="cIndex"
                                     :field="itemTop + '_' + cItem"
                                     width="auto" :filter="false"
                                     :title="getTitle(cItem)"></DkTableColumn>
                    </div>
                    <div v-else>
                      <!--子级(有多个值列）-->
                      <DkTableColumn v-for="(cItem,cIndex) in dataFields"
                                     ref="col"
                                     :key="cIndex"
                                     :field="itemTop + '_' + cItem.key"
                                     width="auto" :filter="false"
                                     :digits="cItem.params?cItem.params.digits:0"
                                     :title="cItem.label"></DkTableColumn>
                    </div>
                  </div>
                </vxe-colgroup>

                <!--              </vxe-colgroup>-->
                <!--              <vxe-colgroup :title="item+''" v-for="(item,index) in [...colFields[0].valuesFiltered]" :key="index">-->
                <!--                <div v-for="(cItem,cIndex) in [...colFields[1].valuesFiltered]" :key="cIndex">-->
                <!--                  <DkTableColumn-->
                <!--                    :field="cItem+''"-->
                <!--                    width="auto" :filter="false" :freeze="false"-->
                <!--                    :title="cItem+''"></DkTableColumn>-->
                <!--                </div>-->
                <!--              </vxe-colgroup>-->
              </div>
            </div>
            <!--列维度(无维度)-->
            <div v-else>
              <DkTableColumn v-for="(cItem,cIndex) in dataFields"
                             ref="col"
                             :key="cIndex"
                             :field="cItem.key"
                             width="auto" :filter="false"
                             :digits="cItem.params?cItem.params.digits:0"
                             :title="cItem.label"></DkTableColumn>
            </div>
          </div>

        </DkTable>
        <Echarts v-if="currentType!='table'" :type="currentType" :row-field-keys="internal.rowFieldKeys" ref="chart"
                 :style="'height: '+tableHeight+'px; width: 100%'" :table-instance="$refs['table-select']" line-no/>
      </div>
    </DkSplit>
  </div>
</template>

<script>
import Draggable from 'vuedraggable'
import naturalSort from 'javascript-natural-sort'
import HashTable from "_c/base/dk-perspective/HashTable";
import Echarts from '../../sub/echarts/echarts'

export default {
  name: 'dk-pivot',
  components: {Draggable, Echarts},
  props: {
    data: {
      type: Array,
      default: () => []
    },
    fields: {
      type: Array,
      default: () => []
    },
    availableFieldKeys: {
      type: Array,
      default: () => []
    },
    rowFieldKeys: {
      type: Array,
      default: () => []
    },
    dataFieldKeys: {
      type: Array,
      default: () => []
    },
    colFieldKeys: {
      type: Array,
      default: () => []
    },
    defaultShowSettings: {
      type: Boolean,
      default: true
    },
    availableFieldsLabelText: {
      type: String,
      default: 'Available fields'
    },
    colsLabelText: {
      type: String,
      default: 'Columns'
    },
    rowsLabelText: {
      type: String,
      default: 'Rows'
    },
    dataLabelText: {
      type: String,
      default: 'data'
    },
    hideSettingsText: {
      type: String,
      default: 'Hide settings'
    },
    showSettingsText: {
      type: String,
      default: 'Show settings'
    },
    noDataWarningText: {
      type: String,
      default: 'No data to display.'
    },
    selectAllText: {
      type: String,
      default: 'Select all'
    },
    unselectAllText: {
      type: String,
      default: 'Unselect all'
    },
  },
  data: function () {
    const fieldValues = {}
    this.fields.filter(field => field.valueFilter).forEach(field => {
      fieldValues[field.key] = {}
    })
    const vm = Window.vm
    return {
      vm: vm,
      internal: {
        availableFieldKeys: this.availableFieldKeys,
        rowFieldKeys: this.rowFieldKeys,
        colFieldKeys: this.colFieldKeys,
        dataFieldKeys: this.dataFieldKeys,
      },
      hideFlag: false,
      split: 0.4,
      leftSplit: 0.5,
      tableHeight: 750,
      tableData: [],
      groupCols: [],// 分组列集合
      fieldValues,
      dragging: false,
      showSettings: true,
      colFlag: false,
      computingInterval: null,
      rowKeys: [],// 行列
      isDataLoading: false,
      reducer: (sum, item) => sum + 1,
      currentType: 'table',
      tabsOptions: [
        {label: '表格', name: 'table'},
        {label: '柱状图', name: 'bar'},
        {label: '折线图', name: 'line'},
        {label: '饼状图', name: 'pie'},
      ],
    }
  },
  computed: {
    // Fields with values extracted from data (if field has valueFilter)
    fieldsWithValues: function () {
      // Create object: field.key => field
      const fieldsWithValues = {}

      this.fields.forEach(field => {
        fieldsWithValues[field.key] = field
      })

      // Add valuesSet
      const valueFilterableFields = this.fields.filter(field => field.valueFilter)

      // Create valuesSet for each value filterable field
      valueFilterableFields.forEach(field => {
        fieldsWithValues[field.key].valuesSet = new Set()
      })

      // 获取没有过滤，需要处理值，这些列都可能作为列和行出现
      const valueNoFilterableFields = this.fields.filter(field => !field.valueFilter)
      valueNoFilterableFields.forEach(field => {
        fieldsWithValues[field.key].valuesFiltered = new Set()
      })

      // Iterate on data once
      this.data.forEach(item => {
        // 有过滤
        valueFilterableFields.forEach(field => {
          let value = field.getter(item);
          if (typeof value === 'boolean') {
            fieldsWithValues[field.key].valuesSet.add(value)
          } else {
            if (value) {
              fieldsWithValues[field.key].valuesSet.add(value)
            }
          }
        })
        // 无过滤
        valueNoFilterableFields.forEach(field => {
          let value = field.getter(item);
          if (value) {
            fieldsWithValues[field.key].valuesFiltered.add(value)
          }
        })
      })

      // Creates values sorted from valuesSet
      valueFilterableFields.forEach(field => {
        fieldsWithValues[field.key].values = Array.from(fieldsWithValues[field.key].valuesSet).sort(field.sort || naturalSort)
        // 给optionsValue赋值
        fieldsWithValues[field.key].optionValues = fieldsWithValues[field.key].values.map(it => {
          return {
            key: it
          }
        })
      })
      // console.log('fieldsWithValues', fieldsWithValues)
      return fieldsWithValues
    },
    // Fields selected values as set
    valuesFiltered: function () {
      const valuesFiltered = {}
      let arr = Object.entries(this.fieldValues);
      if (arr && arr.length > 0) {
        for (let [key, valuesObject] of arr) {
          if (valuesFiltered) {
            valuesFiltered[key] = new Set()
            valuesObject.forEach(valueObject => {
              if (valueObject.checked) {
                valuesFiltered[key].add(valueObject.value)
              }
            })
          }
        }
      }
      return valuesFiltered
    },
    // Pivot table props from Pivot props & data
    rowFields: function () {
      const rowFields = []
      this.rowKeys = []

      this.internal.rowFieldKeys.forEach(key => {
        const field = this.fields.find(field => field.key === key)

        // Generate headerSlotNames from headers
        if (field.headers) {
          field.headerSlotNames = field.headers
            .filter(header => header.checked)
            .map(header => header.slotName)
        }

        // Add selected values
        if (field.valueFilter) {
          field.valuesFiltered = this.valuesFiltered[field.key]
        }
        this.rowKeys.push(key);
        rowFields.push(field)
      })
      // 更新数据
      this.$nextTick(() => {
        this.updateValues();
      })
      return rowFields
    },
    colFields: function () {
      this.colFlag = false;
      const colFields = []

      this.internal.colFieldKeys.forEach(key => {
        const field = this.fields.find(field => field.key === key)

        // Generate headerSlotNames from headers
        if (field.headers) {
          field.headerSlotNames = field.headers
            .filter(header => header.checked)
            .map(header => header.slotName)
        }
        // Add selected values
        if (field.valueFilter) {
          field.valuesFiltered = this.valuesFiltered[field.key]
        }
        colFields.push(field)
      })
      // 说明多个值列，要展开
      if (this.dataFields && this.dataFields.length > 1) {
        this.groupCols = colFields.filter((a, b) => b !== 0)
      } else {
        this.groupCols = colFields.filter((a, b) => b !== colFields.length - 1 && b !== 0)
      }

      setTimeout(() => {
        this.colFlag = true;
      }, 300)

      // 更新数据
      this.$nextTick(() => {
        this.updateValues();
      })
      return colFields
    },
    dataFields: function () {
      const dataFields = []

      this.internal.dataFieldKeys.forEach(key => {
        const field = this.fields.find(field => field.key === key)

        // Generate headerSlotNames from headers
        if (field.headers) {
          field.headerSlotNames = field.headers
            .filter(header => header.checked)
            .map(header => header.slotName)
        }

        // Add selected values
        if (field.valueFilter) {
          field.valuesFiltered = this.valuesFiltered[field.key]
        }

        dataFields.push(field)
      })
      return dataFields
    },
    // Drag area class
    dragAreaClass: function () {
      return this.dragging ? 'drag-area-highlight' : null
    },
    // Table wrapper style
    tableWrapperStyle: function () {
      const maxWidth = this.showSettings ? 'calc(100% - 200px - 2rem)' : '100%'
      return `max-width: ${maxWidth};`
    }
  },
  methods: {
    // Toggle settings
    toggleShowSettings() {
      this.showSettings = !this.showSettings
    },
    // Update dragging boolean
    start() {
      this.dragging = true
    },
    end() {
      this.dragging = false
    },
    /**
     * @desc   : 操作字段列表
     * @author : 周兴
     * @date   : 2023/3/23 21:32
     */
    handleTools() {
      this.hideFlag = !this.hideFlag;
      if (this.hideFlag) {
        this.$refs['toolSplit'].hidePane();
      } else {
        this.$refs['toolSplit'].showPane()
      }
    },
    /**
     * @desc   : 选择数据
     * @author : 周兴
     * @date   : 2023/3/23 11:09
     */
    handleSelect(e) {
      if (this.fieldValues && this.fieldValues[e.key]) {
        this.fieldValues[e.key].forEach(it => {
          if (e.model && e.model.includes(it.value)) {
            it.checked = true;
          } else {
            it.checked = false;
          }
        })
      }
    },
    /**
     * @desc   : 获取标题
     * @author : 周兴
     * @date   : 2023/3/21 13:34
     */
    getField(groupCols, index) {
      let titles = []
      if (groupCols && groupCols.length > 0) {
        groupCols.forEach(it => {
          if (it.valuesFiltered) {
            let values = [...it.valuesFiltered]
            if (values[index]) {
              titles.push(values[index]);
            }
          }
        })
        return titles.join('_') + '_';
      }
      return '';
    },
    /**
     * @desc   : 要处理boolean的显示
     * @author : 周兴
     * @date   : 2023/4/6 15:36
     */
    getTitle(value) {
      if (typeof value === 'boolean') {
        return value ? vm.$t('yes') : vm.$t('no')
      } else {
        return value + '';
      }
    },
    /**
     * @desc   : 更新表头列
     * @author : 周兴
     * @date   : 2023/3/21 9:02
     */
    updateFieldValues() {
      return new Promise(resolve => {
        for (let [key, field] of Object.entries(this.fieldsWithValues)) {
          if (field.valueFilter) {
            this.fieldValues[key] = []
            field.values.forEach(value => {
              this.fieldValues[key].push({value, checked: true})
            })
          }
        }
        resolve();
      })
    },
    /**
     * @desc   : 更新数据
     * @author : 周兴
     * @date   : 2023/3/21 9:03
     */
    updateValues(updateValuesHashTable = true) {
      this.isDataComputing = true;
      // Start a task to avoid blocking the page
      clearInterval(this.computingInterval)
      this.computingInterval = setTimeout(() => {
        // this.tableData = this.data.filterColumns(this.rowKeys).unique();
        this.tableData = []
        const valuesHashTable = new HashTable()
        const fields = [...this.rowFields, ...this.colFields]
        const dataKey = []
        this.data.forEach(it => {
          const rowKey = []
          const colKey = []
          let filtered = false

          // Check if item passes fields value filters
          for (let field of fields) {
            if (field.valuesFiltered && !field.valuesFiltered.has(field.getter(it))) {
              filtered = true
              break
            }
          }
          // Build item rowKey/colKey if necessary
          if (!filtered) {
            let rowColumns = {}
            this.rowFields.forEach(field => {
              rowKey.push(field.getter(it) + '')
              rowColumns[field.key] = field.getter(it) + ''
            })
            if (rowColumns && Object.keys(rowColumns).length > 0) {
              this.tableData.pushNoRepeat(rowColumns)
            }
            this.colFields.forEach(field => {
              colKey.push(field.getter(it) + '')
            })
            if (this.dataFields && this.dataFields.length > 1) {
              this.dataFields.forEach(field => {
                dataKey.push(field.key)
              })
            }
          }
          // Update valuesHashTable
          // if (updateValuesHashTable) {
          if (dataKey && dataKey.length > 0) {
            dataKey.forEach(item => {
              // 计算公式
              this.reducer = (sum, itm) => sum + itm[item];
              const key = [...rowKey, ...colKey, item]
              const previousValue = valuesHashTable.get(key) || 0
              // console.log('key', key, previousValue, this.reducer(previousValue, it))
              valuesHashTable.set(key, this.reducer(previousValue, it))
            })
          } else {
            // 说明值域小于等于1个
            if (this.dataFields && this.dataFields.length > 0) {
              let item = this.dataFields[0].key
              // 计算公式
              this.reducer = (sum, itm) => sum + itm[item];
              const key = [...rowKey, ...colKey]
              const previousValue = valuesHashTable.get(key) || 0
              // console.log('key', key, previousValue, valuesHashTable)
              valuesHashTable.set(key, this.reducer(previousValue, it))
            }
          }
          // }
        })

        this.$nextTick(() => {
          // 是否包括值域
          let hasData = this.dataFields.length > 0 ? true : false;
          // 把数据装入table
          if (this.tableData && this.$refs.col && this.$refs.col.length > 0) {
            this.tableData.forEach(item => {
              let rowKeys = []
              this.rowKeys.forEach(k => {
                rowKeys.push(item[k]);
              })
              // 循环列
              this.$refs.col.forEach(col => {
                let headerFields = col.field.split('_')
                // 如果只有一个值域，是不要显示
                if (this.dataFields.length == 1) {
                  let index = headerFields.findIndex(it => it == this.dataFields[0].key)
                  // 删除掉
                  if (index >= 0) {
                    headerFields.splice(index, 1)
                  }
                }
                let key = [...rowKeys, ...headerFields]
                if (hasData) {
                  let digits = col.digits;
                  let value = valuesHashTable.get(key);
                  item[col.field] = value ? value.toThousandth(digits) : null;
                  // console.log('col.field', this.dataFields, headerFields, valuesHashTable, key,col)
                } else {
                  item[col.field] = null;
                }
              })
            })
          }
          this.isDataLoading = false;

          //更新图表
          if (this.currentType !== 'table') {
            this.$nextTick(() => {
              this.$refs.chart.init()
            })
          }
        })

      }, 300)
      this.isDataComputing = false
      // this.updateInternalFields()
    },
    /**
     * @desc   : 复制列
     * @author : 周兴
     * @date   : 2023/3/21 9:04
     */
    updateInternalFields() {
      // this.internalRowFields = cloneDeep(this.rowFields)
      // this.internalColFields = cloneDeep(this.colFields)
    },
    /**
     * @desc   : 滚动滑轮
     * @author : 洪旭东
     * @date   : 2023-10-07 11:42
     */
    resize() {
      this.tableHeight = this.$el.parentNode.clientHeight <= 0 ? 750 : this.$el.parentNode.clientHeight - 80
    },
  },
  watch: {
    data() {
      this.isDataLoading = true;
      this.updateFieldValues().then(res => {
        this.updateValues();  // 更新数据
      }); // 更新列
    },
    dataFields(n, o) {
      this.isDataLoading = true;
      this.updateValues();        // 更新数据
    },
  },
  mounted() {
    this.resize()
    window.addEventListener('resize', this.resize)
  },
  created() {
    this.showSettings = this.defaultShowSettings
    this.updateFieldValues().then(res => {
      this.updateValues();  // 更新数据
    }); // 更新列
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resize)
  }
}
</script>

<style lang="scss" scoped>

/* Grid with gutter */
.gutter, .gutter-y {
  margin-top: -1rem;

  > * {
    margin-top: 1rem;
  }
}

.gutter-x, .gutter {
  margin-left: -1rem;

  > * {
    margin-left: 1rem;
  }
}

.gutter-sm, .gutter-y-sm {
  margin-top: -.2rem;

  > * {
    margin-top: .2rem;
  }
}

.gutter-x-sm, .gutter-sm {
  margin-left: -.5rem;

  > * {
    margin-left: .5rem;
  }
}

/* Drag & drop stuff */
.drag-area {
  width: 49%;
  border: 1px dashed #ccc;
  padding: 0.75rem;
  transition: background-color 0.4s;


  .drag-area-title {
    line-height: 1;
  }

  .drag-area-zone {
    min-width: 10rem;
    min-height: 46px;
    height: calc(100% - 20px);
    overflow-y: auto;
    overflow-x: hidden;
  }
}

.drag-area-highlight {
  background-color: #f3f3f3;
}

.sortable-ghost {
  opacity: 0.4;
}

.field {
  position: relative;
  width: 100% !important;
}


</style>
