219 lines
7.2 KiB
Vue
219 lines
7.2 KiB
Vue
<template>
|
|
<v-container>
|
|
<v-row>
|
|
<v-col cols="12" sm="12" md="4" lg="3" xl="2">
|
|
<v-card rounded="lg" class="mt-5 mx-5" elevation="0" color="background">
|
|
<!-- <v-card-title>Streams</v-card-title> -->
|
|
<!-- <v-card-text>
|
|
You have {{ streams.totalCount }} stream{{ streams.totalCount == 1 ? `` : `s` }}
|
|
in total.
|
|
</v-card-text> -->
|
|
<v-card-actions>
|
|
<v-btn large rounded color="primary" block @click="newStreamDialog = true">
|
|
<v-icon small class="mr-1">mdi-plus-box</v-icon>
|
|
new stream
|
|
</v-btn>
|
|
</v-card-actions>
|
|
<v-dialog v-model="newStreamDialog" max-width="500">
|
|
<stream-new-dialog :open="newStreamDialog" />
|
|
</v-dialog>
|
|
</v-card>
|
|
|
|
<v-card
|
|
v-if="recentActivity"
|
|
rounded="lg"
|
|
class="mx-5 mt-3 d-none d-md-block"
|
|
elevation="0"
|
|
color="background"
|
|
>
|
|
<v-card-title v-if="recentActivity.length > 0" class="subtitle-1 pb-0">
|
|
Recent Activity
|
|
</v-card-title>
|
|
<v-list color="transparent" two-lines class="recent-commits">
|
|
<div v-for="(a, i) in recentActivity" :key="i">
|
|
<v-list-item v-if="a.__typename === 'Commit'">
|
|
<v-list-item-avatar size="30" class="mr-2">
|
|
<user-avatar
|
|
:id="a.authorId"
|
|
:avatar="a.authorAvatar"
|
|
:size="30"
|
|
:name="a.authorName"
|
|
/>
|
|
</v-list-item-avatar>
|
|
<v-list-item-content>
|
|
<v-list-item-title class="subtitle-2">
|
|
<router-link :to="'streams/' + a.streamId + '/commits/' + a.id">
|
|
{{ a.message }}
|
|
</router-link>
|
|
</v-list-item-title>
|
|
<v-list-item-subtitle class="caption">
|
|
<i>
|
|
Sent to
|
|
<router-link :to="'streams/' + a.streamId">
|
|
{{ a.streamName }}
|
|
</router-link>
|
|
</i>
|
|
</v-list-item-subtitle>
|
|
</v-list-item-content>
|
|
</v-list-item>
|
|
|
|
<v-list-item v-if="a.__typename === 'Stream'">
|
|
<v-list-item-content>
|
|
<v-list-item-title class="subtitle-2">
|
|
<router-link :to="'streams/' + a.id">
|
|
{{ a.name }}
|
|
</router-link>
|
|
</v-list-item-title>
|
|
<v-list-item-subtitle class="caption">
|
|
<i>A new stream was created</i>
|
|
</v-list-item-subtitle>
|
|
</v-list-item-content>
|
|
</v-list-item>
|
|
<v-divider v-if="i < recentActivity.length - 1" />
|
|
</div>
|
|
</v-list>
|
|
<v-card-actions></v-card-actions>
|
|
</v-card>
|
|
</v-col>
|
|
<v-col cols="12" sm="12" md="8" lg="9" xl="8">
|
|
<div v-if="!$apollo.loading && streams.totalCount === 0" class="pa-4">
|
|
<no-data-placeholder
|
|
:message="`Hello there! It seems like you don't have any streams yet. Here's a handful of useful links to help you get started:`"
|
|
/>
|
|
</div>
|
|
<v-card v-if="user && user.streams.totalCount > 0" class="mt-5 mx-4" flat>
|
|
<v-card-text class="body-1">
|
|
<span>
|
|
You have
|
|
<v-icon small>mdi-compare-vertical</v-icon>
|
|
<b>{{ user.streams.totalCount }}</b>
|
|
streams and
|
|
<v-icon small>mdi-source-commit</v-icon>
|
|
<b>{{ user.commits.totalCount }}</b>
|
|
commits.
|
|
</span>
|
|
</v-card-text>
|
|
</v-card>
|
|
<v-card elevation="0" color="transparent">
|
|
<div v-if="$apollo.loading" class="mx-5">
|
|
<v-skeleton-loader type="card, article, article"></v-skeleton-loader>
|
|
</div>
|
|
<v-card-text v-if="streams && streams.items" class="mt-0 pt-3">
|
|
<div v-for="(stream, i) in streams.items" :key="i">
|
|
<list-item-stream :stream="stream"></list-item-stream>
|
|
</div>
|
|
<infinite-loading
|
|
v-if="streams.items.length < streams.totalCount"
|
|
@infinite="infiniteHandler"
|
|
>
|
|
<div slot="no-more">These are all your streams!</div>
|
|
<div slot="no-results">There are no streams to load</div>
|
|
</infinite-loading>
|
|
</v-card-text>
|
|
</v-card>
|
|
</v-col>
|
|
</v-row>
|
|
</v-container>
|
|
</template>
|
|
<script>
|
|
import ListItemStream from '../components/ListItemStream'
|
|
import StreamNewDialog from '../components/dialogs/StreamNewDialog'
|
|
import NoDataPlaceholder from '../components/NoDataPlaceholder'
|
|
import UserAvatar from '../components/UserAvatar'
|
|
import streamsQuery from '../graphql/streams.gql'
|
|
import userQuery from '../graphql/user.gql'
|
|
import InfiniteLoading from 'vue-infinite-loading'
|
|
|
|
export default {
|
|
name: 'Streams',
|
|
components: { ListItemStream, StreamNewDialog, InfiniteLoading, UserAvatar, NoDataPlaceholder },
|
|
apollo: {
|
|
streams: {
|
|
prefetch: true,
|
|
query: streamsQuery,
|
|
fetchPolicy: 'cache-and-network' //https://www.apollographql.com/docs/react/data/queries/
|
|
},
|
|
user: {
|
|
query: userQuery
|
|
}
|
|
},
|
|
data: () => ({
|
|
streams: [],
|
|
newStreamDialog: false
|
|
}),
|
|
computed: {
|
|
recentActivity() {
|
|
let activity = []
|
|
|
|
if (this.streams && this.streams.items) {
|
|
this.streams.items.forEach((x) =>
|
|
x.commits.items.forEach((y) => {
|
|
y.streamName = x.name
|
|
y.streamId = x.id
|
|
activity.push(y)
|
|
})
|
|
)
|
|
activity.push(...this.streams.items)
|
|
}
|
|
|
|
activity.sort(this.compareUpdates)
|
|
return activity
|
|
}
|
|
},
|
|
watch: {
|
|
streams(val) {
|
|
if (val.items.length === 0 && !localStorage.getItem('onboarding')) {
|
|
this.$router.push('/onboarding')
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
infiniteHandler($state) {
|
|
this.$apollo.queries.streams.fetchMore({
|
|
variables: {
|
|
cursor: this.streams.cursor
|
|
},
|
|
// Transform the previous result with new data
|
|
updateQuery: (previousResult, { fetchMoreResult }) => {
|
|
const newItems = fetchMoreResult.streams.items
|
|
|
|
//set vue-infinite state
|
|
if (newItems.length === 0) $state.complete()
|
|
else $state.loaded()
|
|
|
|
return {
|
|
streams: {
|
|
__typename: previousResult.streams.__typename,
|
|
totalCount: fetchMoreResult.streams.totalCount,
|
|
cursor: fetchMoreResult.streams.cursor,
|
|
// Merging the new streams
|
|
items: [...previousResult.streams.items, ...newItems]
|
|
}
|
|
}
|
|
}
|
|
})
|
|
},
|
|
compareUpdates(a, b) {
|
|
if (a.createdAt < b.createdAt) {
|
|
return 1
|
|
}
|
|
if (a.createdAt > b.createdAt) {
|
|
return -1
|
|
}
|
|
return 0
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<style scoped>
|
|
.recent-commits a {
|
|
color: inherit;
|
|
text-decoration: none;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.recent-commits a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
</style>
|