Skip to content

Commit dbac02f

Browse files
author
Guillaume Chau
committed
feat(ui): route badges
1 parent d51e5f1 commit dbac02f

16 files changed

+518
-30
lines changed

packages/@vue/cli-ui/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"prod-graphql-api": "cross-env NODE_ENV=production vue-cli-service run-graphql-api"
1313
},
1414
"dependencies": {
15-
"@vue/ui": "^0.2.1",
15+
"@vue/ui": "^0.2.2",
1616
"ansi_up": "^2.0.2",
1717
"apollo-cache-inmemory": "^1.1.10",
1818
"apollo-client": "^2.2.6",

packages/@vue/cli-ui/src/components/ProjectNav.vue

+48-8
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@
66
class="vertical small-indicator left-indicator primary"
77
indicator
88
>
9-
<VueGroupButton
9+
<ProjectNavButton
1010
v-for="route of routes"
11-
:key="route.name"
12-
class="flat big icon-button"
13-
:value="route.name"
14-
:icon-left="route.icon"
15-
v-tooltip.right="$t(route.tooltip)"
11+
:key="route.id"
12+
:route="route"
1613
/>
1714
</VueGroup>
1815
</div>
@@ -23,6 +20,9 @@
2320
import { isSameRoute, isIncludedRoute } from '../util/route'
2421
2522
import ROUTES from '../graphql/routes.gql'
23+
import ROUTE_ADDED from '../graphql/routeAdded.gql'
24+
import ROUTE_REMOVED from '../graphql/routeRemoved.gql'
25+
import ROUTE_CHANGED from '../graphql/routeChanged.gql'
2626
2727
export default {
2828
data () {
@@ -34,7 +34,47 @@ export default {
3434
apollo: {
3535
routes: {
3636
query: ROUTES,
37-
fetchPolicy: 'cache-and-network'
37+
fetchPolicy: 'cache-and-network',
38+
subscribeToMore: [
39+
{
40+
document: ROUTE_ADDED,
41+
updateQuery: (previousResult, { subscriptionData }) => {
42+
const route = subscriptionData.data.routeAdded
43+
if (previousResult.routes.find(r => r.id === route.id)) return previousResult
44+
return {
45+
routes: [
46+
...previousResult.routes,
47+
route
48+
]
49+
}
50+
}
51+
},
52+
{
53+
document: ROUTE_REMOVED,
54+
updateQuery: (previousResult, { subscriptionData }) => {
55+
const index = previousResult.routes.findIndex(r => r.id === subscriptionData.data.routeRemoved.id)
56+
if (index === -1) return previousResult
57+
const routes = previousResult.routes.slice()
58+
routes.splice(index, 1)
59+
return {
60+
routes
61+
}
62+
}
63+
},
64+
{
65+
document: ROUTE_CHANGED,
66+
updateQuery: (previousResult, { subscriptionData }) => {
67+
const route = subscriptionData.data.routeChanged
68+
const index = previousResult.routes.findIndex(r => r.id === route.id)
69+
if (index === -1) return previousResult
70+
const routes = previousResult.routes.slice()
71+
routes.splice(index, 1, route)
72+
return {
73+
routes
74+
}
75+
}
76+
}
77+
]
3878
}
3979
},
4080
@@ -69,7 +109,7 @@ export default {
69109
>>> .vue-ui-button
70110
button-colors(rgba($vue-ui-color-light, .7), transparent)
71111
border-radius 0
72-
&:hover
112+
&:hover, &:active
73113
$bg = darken($vue-ui-color-dark, 70%)
74114
button-colors($vue-ui-color-light, $bg)
75115
&.selected
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<template>
2+
<div class="project-nav-button">
3+
<v-popover
4+
trigger="hover"
5+
handle-resize
6+
popover-class="force-tooltip"
7+
placement="right"
8+
offset="4"
9+
>
10+
<VueGroupButton
11+
class="flat big icon-button"
12+
:value="route.name"
13+
:icon-left="route.icon"
14+
/>
15+
16+
<template slot="popover">
17+
<div class="title">{{ $t(route.tooltip) }}</div>
18+
19+
<div v-if="badges" class="badges">
20+
<RouteBadge
21+
v-for="badge of badges"
22+
:key="badge.id"
23+
:badge="badge"
24+
/>
25+
</div>
26+
</template>
27+
</v-popover>
28+
29+
<div
30+
v-if="firstNotHiddenBadge"
31+
class="bullet"
32+
:class="[
33+
`type-${firstNotHiddenBadge.type}`
34+
]"
35+
/>
36+
</div>
37+
</template>
38+
39+
<script>
40+
export default {
41+
props: {
42+
route: {
43+
type: Object,
44+
required: true
45+
}
46+
},
47+
48+
computed: {
49+
badges () {
50+
if (this.route.badges && this.route.badges.length) {
51+
return this.route.badges.slice().sort((a, b) => b.priority - a.priority)
52+
}
53+
},
54+
55+
firstNotHiddenBadge () {
56+
return this.badges && this.badges.find(b => !b.hidden)
57+
}
58+
}
59+
}
60+
</script>
61+
62+
<style lang="stylus" scoped>
63+
@import "~@/style/imports"
64+
65+
$bg = darken($vue-ui-color-dark, 70%)
66+
67+
.project-nav-button
68+
position relative
69+
70+
.v-popover >>> .trigger
71+
display block !important
72+
73+
.bullet
74+
position absolute
75+
width 6px
76+
height @width
77+
border-radius 50%
78+
bottom 12px
79+
right 10px
80+
pointer-events none
81+
border solid 2px $vue-ui-color-dark
82+
transition border-color .1s
83+
&.type-info
84+
background $vue-ui-color-info
85+
&.type-success
86+
background $vue-ui-color-success
87+
&.type-error
88+
background $vue-ui-color-danger
89+
&.type-warning
90+
background $vue-ui-color-warning
91+
&.type-accent
92+
background $vue-ui-color-accent
93+
&.type-dim
94+
background $md-grey
95+
96+
&:hover
97+
.bullet
98+
border-color lighten($bg, 25%)
99+
&:active
100+
.bullet
101+
border-color darken($bg, 8%)
102+
103+
.badges
104+
margin ($padding-item/2) 0
105+
display grid
106+
grid-template-columns auto
107+
grid-gap 4px
108+
</style>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<template>
2+
<div
3+
class="route-badge"
4+
:class="[
5+
`type-${badge.type}`
6+
]"
7+
>
8+
<div class="content">
9+
<div class="counter">{{ badge.count }}</div>
10+
<div class="label">{{ $t(badge.label) }}</div>
11+
</div>
12+
</div>
13+
</template>
14+
15+
<script>
16+
export default {
17+
props: {
18+
badge: {
19+
type: Object,
20+
required: true
21+
}
22+
}
23+
}
24+
</script>
25+
26+
<style lang="stylus" scoped>
27+
@import "~@/style/imports"
28+
29+
.route-badge
30+
.content
31+
font-size 12px
32+
h-box()
33+
box-center()
34+
35+
.counter
36+
min-width 22px
37+
text-align center
38+
border-radius 8px
39+
margin-right 6px
40+
font-family $font-mono
41+
42+
.label
43+
flex auto 1 1
44+
45+
&.type-info
46+
.counter
47+
background $vue-ui-color-info
48+
&.type-success
49+
.counter
50+
background $vue-ui-color-success
51+
&.type-error
52+
.counter
53+
background $vue-ui-color-danger
54+
&.type-warning
55+
.counter
56+
background $vue-ui-color-warning
57+
&.type-accent
58+
.counter
59+
background $vue-ui-color-accent
60+
&.type-dim
61+
.counter
62+
background $md-grey
63+
</style>

packages/@vue/cli-ui/src/graphql-api/channels.js

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ module.exports = {
88
ROUTE_ADDED: 'route_added',
99
ROUTE_REMOVED: 'route_removed',
1010
ROUTE_CHANGED: 'route_changed',
11+
VUE_ROUTER_DEFINITION_ADDED: 'vue_router_definition_added',
12+
VUE_ROUTER_DEFINITION_REMOVED: 'vue_router_definition_removed',
1113
CLIENT_ADDON_ADDED: 'client_addon_added',
1214
SHARED_DATA_UPDATED: 'shared_data_updated',
1315
PLUGIN_ACTION_CALLED: 'plugin_action_called',

0 commit comments

Comments
 (0)