Skip to content

Commit b7ca1f7

Browse files
authored
Merge pull request #12 from vue-pivottable/feat/pivottable-ui
Feat/pivottable UI
2 parents 630c708 + a02ebff commit b7ca1f7

18 files changed

+437
-226
lines changed

src/App.vue

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
<script setup>
2-
import { VPivottable } from './index.js'
32
import tips from './tips.js'
43
</script>
54

65
<template>
76
<div>
8-
<VPivottable
9-
:data="tips"
10-
:rows="['Payer Smoker']"
11-
:cols="['Payer Gender']"
12-
/>
137
<VPivottableUi
148
:data="tips"
159
:rows="['Payer Smoker']"

src/components/pivottable-ui/VDragAndDropCell.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ const props = defineProps({
8989
const modelItems = ref([])
9090
9191
const onDrag = evt => {
92-
console.log('event', Object.keys(evt)[0])
92+
// console.log('event', Object.keys(evt)[0])
9393
emit('update:draggedAttribute', {
9494
cellType: props.cellType,
95-
attributes: modelItems.value
95+
attributes: Object.values(modelItems.value)
9696
})
9797
}
9898

src/components/pivottable-ui/VPivottableUi.vue

Lines changed: 133 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@
44
<tbody>
55
<tr>
66
<VRendererCell
7-
:rendererName="rendererName"
8-
@update:propUpdater="propUpdater"
7+
:rendererItems="rendererItems"
8+
:rendererName="state.rendererName"
9+
@update:rendererName="onUpdateRendererName"
910
/>
1011
<VDragAndDropCell
12+
classes="pvtAxisContainer pvtUnused pvtHorizList"
1113
cellType="unused"
1214
:attributeNames="unusedAttrs"
13-
classes="pvtAxisContainer pvtUnused pvtHorizList"
14-
:restrictedFromDragDrop="[]"
15-
:disabledFromDragDrop="[]"
16-
:zIndices="{}"
17-
:openStatus="{}"
18-
:hideFilterBoxOfUnusedAttributes="false"
19-
:valueFilter="{}"
15+
:valueFilter="state.valueFilter"
16+
:disabledFromDragDrop="state.disabledFromDragDrop"
17+
:hideFilterBoxOfUnusedAttrs="state.hideFilterBoxOfUnusedAttrs"
18+
@update:zIndexOfFilterBox="onMoveFilterBoxToTop"
19+
@update:unselectedFilterValues="onUpdateValueFilter"
20+
@update:openStatusOfFilterBox="onUpdateOpenStatus"
21+
@update:draggedAttribute="onDraggedAttribute"
2022
>
2123
<template v-slot:pvtAttr="props">
2224
<slot name="pvtAttr" v-bind="props" />
@@ -27,28 +29,30 @@
2729
<slot name="aggregatorCell">
2830
<VAggregatorCell
2931
:aggregatorItems="aggregatorItems"
30-
:aggregatorName="newProps.aggregatorName"
31-
:rowOrder="newProps.rowOrder"
32-
:colOrder="newProps.colOrder"
33-
:vals="newProps.vals"
34-
:attrValues="newProps.attrValues"
35-
:hiddenAttributes="newProps.hiddenAttributes"
36-
:hiddenFromAggregators="newProps.hiddenFromAggregators"
37-
:numValsAllowed="numValsAllowed"
38-
@update:propUpdater="propUpdater"
39-
@update:valSlice="onValSlice"
32+
:aggregatorName="state.aggregatorName"
33+
:rowOrder="state.rowOrder"
34+
:colOrder="state.colOrder"
35+
:attributeNames="state.attributeNames"
36+
:hiddenFromAggregators="state.hiddenFromAggregators"
37+
:vals="state.vals"
38+
@update:aggregatorName="onUpdateAggregatorName"
39+
@update:rowOrder="onUpdateRowOrder"
40+
@update:colOrder="onUpdateColOrder"
41+
@update:vals="onUpdateVals"
4042
/>
4143
</slot>
4244

4345
<VDragAndDropCell
44-
cellType="col"
45-
:attributeNames="colAttrs"
4646
classes="pvtAxisContainer pvtHorizList pvtCols"
47-
:restrictedFromDragDrop="[]"
48-
:disabledFromDragDrop="[]"
49-
:zIndices="{}"
50-
:openStatus="{}"
51-
:valueFilter="{}"
47+
cellType="cols"
48+
:attributeNames="colAttrs"
49+
:valueFilter="state.valueFilter"
50+
:disabledFromDragDrop="state.disabledFromDragDrop"
51+
:hideFilterBoxOfUnusedAttrs="state.hideFilterBoxOfUnusedAttrs"
52+
@update:zIndexOfFilterBox="onMoveFilterBoxToTop"
53+
@update:unselectedFilterValues="onUpdateValueFilter"
54+
@update:openStatusOfFilterBox="onUpdateOpenStatus"
55+
@update:draggedAttribute="onDraggedAttribute"
5256
>
5357
<template v-slot:pvtAttr="props">
5458
<slot name="pvtAttr" v-bind="props" />
@@ -57,26 +61,37 @@
5761
</tr>
5862
<tr>
5963
<VDragAndDropCell
60-
cellType="row"
61-
:attributeNames="rowAttrs"
6264
classes="pvtAxisContainer pvtVertList pvtRows"
63-
:restrictedFromDragDrop="[]"
64-
:disabledFromDragDrop="[]"
65-
:zIndices="{}"
66-
:openStatus="{}"
67-
:valueFilter="{}"
65+
cellType="rows"
66+
:attributeNames="rowAttrs"
67+
:valueFilter="state.valueFilter"
68+
:disabledFromDragDrop="state.disabledFromDragDrop"
69+
:hideFilterBoxOfUnusedAttrs="state.hideFilterBoxOfUnusedAttrs"
70+
@update:zIndexOfFilterBox="onMoveFilterBoxToTop"
71+
@update:unselectedFilterValues="onUpdateValueFilter"
72+
@update:openStatusOfFilterBox="onUpdateOpenStatus"
73+
@update:draggedAttribute="onDraggedAttribute"
6874
>
6975
<template v-slot:pvtAttr="props">
7076
<slot v-bind="props" name="pvtAttr" />
7177
</template>
72-
<!-- <slot name="pvtAttr" v-bind="$props"></slot> -->
7378
</VDragAndDropCell>
7479
<td class="pvtOutput">
7580
<slot name="outputSlot" :outputSlot="{ pivotData }">
76-
<VPivottable v-bind="newProps" />
81+
<VPivottable v-bind="state" />
7782
</slot>
7883
</td>
7984
</tr>
85+
<tr>
86+
<td colspan="2">
87+
<h4>State</h4>
88+
rows: {{ state.rows }} <br>
89+
cols: {{ state.cols }} <br>
90+
aggregatorName: {{ state.aggregatorName }} <br>
91+
rendererName: {{ state.rendererName }} <br>
92+
vals: {{ state.vals }}
93+
</td>
94+
</tr>
8095
</tbody>
8196
</table>
8297
</template>
@@ -85,64 +100,52 @@
85100
import {
86101
defaultProps,
87102
PivotData,
88-
aggregators,
89-
sortAs,
90-
getSort
91-
} from '../../helper'
103+
sortAs
104+
} from '@/helper'
92105
import VRendererCell from './VRendererCell.vue'
93106
import VAggregatorCell from './VAggregatorCell.vue'
94107
import VDragAndDropCell from './VDragAndDropCell.vue'
95-
import { VPivottable } from '../'
96-
import { computed, ref, watch } from 'vue'
97-
import { usePropsData } from '../../composables'
108+
import { VPivottable } from '@/'
109+
import { computed, ref, toRefs, watch } from 'vue'
110+
import { usePropsState } from '@/composables'
111+
import TableRenderer from '../pivottable/renderer/index'
112+
98113
const props = defineProps({
99114
...defaultProps,
100-
async: {
101-
type: Boolean,
102-
default: false
103-
},
104115
hiddenAttributes: {
105116
type: Array,
106-
default: function () {
107-
return []
108-
}
117+
default: () => []
109118
},
110119
hiddenFromAggregators: {
111120
type: Array,
112-
default: function () {
113-
return []
114-
}
121+
default: () => []
115122
},
116123
hiddenFromDragDrop: {
117124
type: Array,
118-
default: function () {
119-
return []
120-
}
125+
default: () => []
121126
},
122-
sortonlyFromDragDrop: {
127+
restrictedFromDragDrop: {
123128
type: Array,
124-
default: function () {
125-
return []
126-
}
129+
default: () => []
127130
},
128131
disabledFromDragDrop: {
129132
type: Array,
130-
default: function () {
131-
return []
132-
}
133+
default: () => []
133134
},
134135
menuLimit: {
135136
type: Number,
136137
default: 500
137138
},
138-
config: {
139+
pivotModel: {
139140
type: Object,
140-
default: function () {
141-
return {}
142-
}
141+
default: () => ({})
142+
},
143+
hideFilterBoxOfUnusedAttrs: {
144+
type: Boolean,
145+
default: false
143146
}
144147
})
145-
const state = ref({
148+
const pivotUiState = ref({
146149
unusedOrder: props.unusedAttrs,
147150
zIndices: {},
148151
maxZIndex: 1000,
@@ -151,40 +154,37 @@ const state = ref({
151154
attrValues: {},
152155
materializedInput: []
153156
})
154-
const { newProps, setProps, propUpdater } = usePropsData(props)
157+
const propsRefs = toRefs(props)
158+
159+
const { state, updateState, updateMultiple } = usePropsState(propsRefs)
160+
const rendererItems = computed(() => Object.keys(state.value.renderers).length ? state.value.renderers : TableRenderer)
161+
const aggregatorItems = computed(() => state.value.aggregators)
155162
const rowAttrs = computed(() => {
156-
return newProps.value.rows.filter(
163+
return state.value.rows.filter(
157164
e =>
158-
!newProps.value.hiddenAttributes.includes(e) &&
159-
!newProps.value.hiddenFromDragDrop.includes(e)
165+
!state.value.hiddenAttributes.includes(e) &&
166+
!state.value.hiddenFromDragDrop.includes(e)
160167
)
161168
})
162-
163169
const colAttrs = computed(() => {
164-
return newProps.value.cols.filter(
170+
return state.value.cols.filter(
165171
e =>
166-
!newProps.value.hiddenAttributes.includes(e) &&
167-
!newProps.value.hiddenFromDragDrop.includes(e)
172+
!state.value.hiddenAttributes.includes(e) &&
173+
!state.value.hiddenFromDragDrop.includes(e)
168174
)
169175
})
170176
const unusedAttrs = computed(() => {
171-
return newProps.value.attributes
177+
return state.value.attributes
172178
.filter(
173179
e =>
174-
!newProps.rows.includes(e) &&
175-
!newProps.value.cols.includes(e) &&
176-
!newProps.value.hiddenAttributes.includes(e) &&
177-
!newProps.value.hiddenFromDragDrop.includes(e)
180+
!state.value.rows.includes(e) &&
181+
!state.value.cols.includes(e) &&
182+
!state.value.hiddenAttributes.includes(e) &&
183+
!state.value.hiddenFromDragDrop.includes(e)
178184
)
179-
.sort(sortAs(newProps.value.unusedOrder))
185+
.sort(sortAs(state.value.unusedOrder))
180186
})
181-
const aggregatorItems = computed(
182-
() => newProps.value.aggregators || aggregators
183-
)
184-
const numValsAllowed = computed(
185-
() =>
186-
aggregatorItems.value[newProps.value.aggregatorName]([])().numInputs || 0
187-
)
187+
188188
const materializeInput = nextData => {
189189
if (props.data === nextData) {
190190
return
@@ -219,39 +219,57 @@ const materializeInput = nextData => {
219219
recordsProcessed++
220220
}
221221
)
222-
state.value = newState
223-
setProps({
224-
...newProps.value,
225-
...state.value
222+
223+
updateMultiple({
224+
...state.value,
225+
...newState,
226+
...pivotUiState.value
227+
})
228+
}
229+
230+
const onMoveFilterBoxToTop = ({ attribute }) => {
231+
updateState('maxZIndex', state.value.maxZIndex++)
232+
updateState('zIndices', {
233+
...state.value.zIndices,
234+
[attribute]: state.value.maxZIndex
226235
})
227236
}
228237
const onUpdateValueFilter = ({ attribute, valueFilter }) => {
229-
newProps.value.valueFilter[attribute] = valueFilter
238+
updateState('valueFilter', {
239+
...state.value.valueFilter,
240+
[attribute]: valueFilter
241+
})
230242
}
231-
const onMoveFilterBoxToTop = ({ attribute }) => {
232-
newProps.value.maxZIndex += 1
233-
newProps.value.zIndices[attribute] = newProps.value.maxZIndex + 1
243+
const onUpdateRendererName = (rendererName) => {
244+
updateState('rendererName', rendererName)
234245
}
235-
const onNoFilterBox = () => this.$emit('no:filterbox')
236-
const onValSlice = (e, i) => newProps.value.vals.splice(i, 1, e.target.value)
237-
238-
const pivotData = new PivotData(newProps.value)
239-
240-
watch(
241-
() => props.data,
242-
value => {
243-
state.value.unusedOrder = props.unusedAttrs
244-
materializeInput(value)
245-
},
246-
{
247-
immediate: false
248-
}
249-
)
250-
251-
const updateFilters = ({ cellType, filters }) => {
252-
console.log('updated cell type', cellType)
253-
console.log('updated filter items', filters)
246+
const onUpdateAggregatorName = (aggregatorName) => {
247+
updateState('aggregatorName', aggregatorName)
248+
}
249+
const onUpdateRowOrder = (rowOrder) => {
250+
updateState('rowOrder', rowOrder)
251+
}
252+
const onUpdateColOrder = (colOrder) => {
253+
updateState('colOrder', colOrder)
254+
}
255+
const onUpdateVals = (vals) => {
256+
updateState('vals', vals)
254257
}
258+
const onDraggedAttribute = ({ cellType, attributes }) => {
259+
updateState(cellType, attributes)
260+
}
261+
const onUpdateOpenStatus = ({ attribute, status }) => {
262+
updateState('openStatus', {
263+
...state.value.openStatus,
264+
[attribute]: status
265+
})
266+
}
267+
const pivotData = computed(() => new PivotData(state.value))
268+
269+
watch(() => props.data, value => {
270+
updateState('unusedOrder', props.unusedAttrs)
271+
materializeInput(value)
272+
})
255273
</script>
256274

257275
<style>

0 commit comments

Comments
 (0)