Skip to content

Commit 5f05792

Browse files
Guillaume Chauiksim
Guillaume Chau
authored and
iksim
committed
refactor(vuex): improved recording/loading UX, closes vuejs#941, closes vuejs#952
1 parent 49d34f0 commit 5f05792

File tree

4 files changed

+113
-45
lines changed

4 files changed

+113
-45
lines changed

shells/dev/target/Counter.vue

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
Do a lot of mutations
2121
</button>
2222

23+
<button @click="startMutationStream()">
24+
Start mutation stream
25+
</button>
26+
27+
<button @click="stopMutationStream()">
28+
Stop mutation stream
29+
</button>
30+
2331
<p>Your counter is {{ $store.getters.isPositive ? 'positive' : 'negative' }}</p>
2432

2533
<h3>Vuex Module</h3>
@@ -176,6 +184,14 @@ export default {
176184
}
177185
},
178186
187+
startMutationStream () {
188+
this.$_mutationTimer = setInterval(this.increment, 1000)
189+
},
190+
191+
stopMutationStream () {
192+
clearInterval(this.$_mutationTimer)
193+
},
194+
179195
...mapMutations('nested', {
180196
addBar: 'ADD_BAR',
181197
removeBar: 'REMOVE_BAR'

src/devtools/components/ScrollPane.vue

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
>
1010
<slot name="scroll" />
1111
</div>
12+
<div
13+
v-if="$slots.footer"
14+
class="footer"
15+
>
16+
<slot name="footer" />
17+
</div>
1218
</div>
1319
</template>
1420

@@ -48,4 +54,9 @@ export default {
4854
height 0
4955
&-thumb
5056
background $active-color
57+
58+
.footer
59+
border-top 1px solid $border-color
60+
.vue-ui-dark-mode &
61+
border-top-color $dark-border-color
5162
</style>

src/devtools/components/StateInspector.vue

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<template>
22
<div class="data-wrapper">
33
<div
4-
v-for="dataType in dataTypes"
4+
v-for="(dataType, index) in dataTypes"
55
:key="dataType"
66
:class="[
77
'data-el',
88
toDisplayType(dataType, true),
99
{
10-
'high-density': highDensity
10+
'high-density': highDensity,
11+
dim: dimAfter !== -1 && index >= dimAfter
1112
}
1213
]"
1314
>
@@ -80,6 +81,11 @@ export default {
8081
state: {
8182
type: Object,
8283
required: true
84+
},
85+
86+
dimAfter: {
87+
type: Number,
88+
default: -1
8389
}
8490
},
8591
@@ -159,6 +165,12 @@ export default {
159165
.data-el
160166
font-size 15px
161167
168+
&.dim
169+
opacity .7
170+
pointer-events none
171+
user-select none
172+
filter grayscale(50%)
173+
162174
&:not(:last-child)
163175
border-bottom rgba($grey, .4) solid 1px
164176

src/devtools/views/vuex/VuexStateInspector.vue

Lines changed: 72 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -54,39 +54,53 @@
5454
<div
5555
slot="scroll"
5656
class="vuex-state-inspector"
57+
:class="{
58+
pointer: isOnlyMutationPayload
59+
}"
60+
@click="isOnlyMutationPayload && loadState()"
5761
>
58-
<state-inspector :state="filteredState" />
59-
60-
<div
61-
v-if="$shared.snapshotLoading"
62-
class="state-info loading-vuex-state"
63-
>
64-
<div class="label">
65-
Loading state...
66-
</div>
62+
<state-inspector
63+
:state="filteredState"
64+
:dim-after="isOnlyMutationPayload ? 1 : -1"
65+
/>
66+
</div>
67+
<div
68+
v-if="$shared.snapshotLoading"
69+
slot="footer"
70+
class="state-info loading-vuex-state"
71+
>
72+
<div class="label">
73+
Loading state...
74+
</div>
6775

68-
<VueLoadingIndicator />
76+
<VueLoadingIndicator />
77+
</div>
78+
<div
79+
v-else-if="isOnlyMutationPayload"
80+
slot="footer"
81+
class="state-info recording-vuex-state"
82+
>
83+
<div class="label">
84+
<VueIcon
85+
class="medium"
86+
icon="cached"
87+
/>
88+
<span>Recording state on-demand...</span>
89+
<span
90+
v-if="lastReceivedState"
91+
class="note"
92+
>displaying last received state</span>
6993
</div>
70-
<div
71-
v-else-if="isOnlyMutationPayload"
72-
class="state-info recording-vuex-state"
73-
>
74-
<div class="label">
75-
<VueIcon
76-
class="medium"
77-
icon="cached"
78-
/>
79-
<span>Recording state...</span>
80-
</div>
8194

82-
<div>
83-
<VueButton
84-
data-id="load-vuex-state"
85-
@click="loadState()"
86-
>
87-
Load state
88-
</VueButton>
89-
</div>
95+
<div>
96+
<VueButton
97+
data-id="load-vuex-state"
98+
icon-left="arrow_forward"
99+
class="accent flat"
100+
@click="loadState()"
101+
>
102+
Load state
103+
</VueButton>
90104
</div>
91105
</div>
92106
</scroll-pane>
@@ -130,7 +144,8 @@ export default {
130144
computed: {
131145
...mapState('vuex', [
132146
'activeIndex',
133-
'inspectedIndex'
147+
'inspectedIndex',
148+
'lastReceivedState'
134149
]),
135150
136151
...mapGetters('vuex', [
@@ -140,22 +155,27 @@ export default {
140155
]),
141156
142157
filteredState () {
158+
const inspectedState = this.isOnlyMutationPayload ? {
159+
mutation: this.inspectedState.mutation,
160+
...this.lastReceivedState
161+
} : this.inspectedState
162+
143163
const getProcessedState = (state, type) => {
144164
if (!Array.isArray(state)) {
145165
return Object.keys(state).map(key => ({
146166
key,
147-
editable: type === 'state',
167+
editable: !this.isOnlyMutationPayload && type === 'state',
148168
value: state[key]
149169
}))
150170
} else {
151171
return state
152172
}
153173
}
154174
155-
const inspectedState = [].concat(
156-
...Object.keys(this.inspectedState).map(
175+
const result = [].concat(
176+
...Object.keys(inspectedState).map(
157177
type => {
158-
const state = this.inspectedState[type]
178+
const state = inspectedState[type]
159179
let processedState
160180
161181
if (type === 'mutation' && this.inspectedEntry) {
@@ -180,7 +200,7 @@ export default {
180200
)
181201
)
182202
183-
return groupBy(sortByKey(inspectedState.filter(
203+
return groupBy(sortByKey(result.filter(
184204
el => searchDeepInObject({
185205
[el.key]: el.value
186206
}, this.filter)
@@ -278,7 +298,7 @@ export default {
278298
if (this.$shared.vuexAutoload) {
279299
this.loadState()
280300
}
281-
}, 800),
301+
}, 300),
282302
283303
onVuexInit () {
284304
if (this.$shared.vuexAutoload) {
@@ -301,23 +321,32 @@ function copyToClipboard (state) {
301321
<style lang="stylus" scoped>
302322
.state-info
303323
display flex
304-
flex-direction column
305-
box-center()
306-
min-height 140px
307-
font-size 16px
308-
margin 0 42px
324+
align-items center
325+
padding 2px 2px 2px 14px
326+
min-height 36px
327+
font-size 14px
309328
310329
.label
330+
flex 1
311331
display flex
312332
align-items center
313333
color $blueishGrey
314-
margin-bottom 12px
315334
316335
.vue-ui-icon
317-
margin-right 12px
336+
margin-right 8px
318337
>>> svg
319338
fill @color
320339
340+
.note
341+
opacity .7
342+
margin-left 4px
343+
344+
.loading-vuex-state
345+
padding-right 14px
346+
347+
.pointer
348+
cursor pointer
349+
321350
.message
322351
margin-left 5px
323352
transition all .3s ease

0 commit comments

Comments
 (0)