| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831 |
- <template>
- <div :style="'height: ' + tableHeight + 'px'">
- <DkSplit ref="toolSplit" v-model="split">
- <div slot="left">
- <!--字段-->
- <DkButton ref="button" class="btn-class" size="small">{{ '字段' }}
- <Icon v-if="hideFlag" type="md-arrow-dropleft" @click.stop="handleTools"/>
- <Icon v-else type="md-arrow-dropright" @click.stop="handleTools"/>
- </DkButton>
- <DkSplit mode="vertical" :height="tableHeight" 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>
- <DkTable slot="right" v-show="currentType==='table'"
- :id="'table-'+$options.name" ref="table-select" :data="tableData"
- :height="tableHeight"
- :choose-flag="false"
- :show-setting-flag="false"
- :pageFlag="false"
- :perspective-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 slot="right" v-if="currentType!='table'" :type="currentType" :columns="internal"
- :style="'height: '+tableHeight+'px; width: 100%'" :table-instance="$refs['table-select']"/>
- </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 './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'
- }
- },
- 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();
- ``
- }
- },
- /**
- * @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, this.reducer(previousValue, it))
- 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;
- })
- }, 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)
- }
- },
- watch: {
- data() {
- this.isDataLoading = true;
- this.updateFieldValues().then(res => {
- this.updateValues(); // 更新数据
- }); // 更新列
- },
- dataFields(n, o) {
- this.isDataLoading = true;
- this.updateValues(); // 更新数据
- },
- },
- mounted() {
- },
- created() {
- this.showSettings = this.defaultShowSettings
- this.updateFieldValues().then(res => {
- this.updateValues(); // 更新数据
- }); // 更新列
- }
- }
- </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;
- }
- .btn-class {
- width: 100%;
- text-align: left;
- }
- /deep/ .ivu-btn .ivu-icon-md-arrow-dropleft {
- display: inline-block;
- overflow: hidden;
- position: absolute;
- top: 0;
- right: 10px;
- cursor: pointer;
- font-size: 22px;
- color: #C2C2C2;
- }
- /deep/ .ivu-btn .ivu-icon-md-arrow-dropright {
- display: inline-block;
- overflow: hidden;
- position: absolute;
- top: 0;
- right: 10px;
- cursor: pointer;
- font-size: 22px;
- color: #C2C2C2;
- }
- </style>
|