feat(frontend): empty states & wizard work

This commit is contained in:
Dimitrie Stefanescu
2021-08-28 14:23:20 +03:00
parent 37934e64f2
commit cfa562c446
11 changed files with 139 additions and 802 deletions
@@ -1,44 +0,0 @@
<template>
<div>
<v-sheet v-if="message === 'You are not authorised.'" rounded="lg" class="pa-15">
<h1>
<v-icon large>mdi-account-cancel</v-icon>
{{ message }}
</h1>
<!-- <v-img src="@/assets/bug.svg" responsive contain max-height="100"/> -->
<p class="headline mt-5 font-weight-light">
Please log in or register to access this content.
</p>
<v-btn color="primary" to="/authn/login">
<v-icon left>mdi-account-arrow-right</v-icon>
Logn in / Register
</v-btn>
</v-sheet>
<v-sheet v-else rounded="lg" class="pa-15">
<h1>
<v-icon large>mdi-bug</v-icon>
Oups...
<br />
{{ message }}
</h1>
<!-- <v-img src="@/assets/bug.svg" responsive contain max-height="100"/> -->
<p class="headline mt-5 font-weight-light">
Don't worry - you haven't deleted the internet,
<br />
just 👉 go back
<router-link to="/">home</router-link>
!
</p>
</v-sheet>
</div>
</template>
<script>
export default {
props: {
message: {
type: String,
default: ''
}
}
}
</script>
@@ -1,255 +0,0 @@
<template>
<!-- <div v-if="quickstart > 0 && !$apollo.loading" class="ma-3"> -->
<div v-if="true">
<div v-if="user" class="ma-5 headline">
Hello {{ user.name.split(' ')[0] }} 👋,
It seems you're new here, let's get you set up!
</div>
<v-stepper v-model="quickstart" flat shaped vertical class="rounded-lg quickstart-stepper mt-5 transparent">
<v-btn
small
text
class="white--grey"
style="position: absolute; top: 5px; right: 5px; z-index: 1002"
@click="skip"
>
Skip
</v-btn>
<v-stepper-step :complete="quickstart > 1" step="1">Create your first stream</v-stepper-step>
<v-stepper-content step="1" class="body-2">
<p>
Streams are the
<b>primary way Speckle organizes data</b>
. You can see them as a folder, a project or a repository.
</p>
<p>
Streams
<b>can be shared with others</b>
and can be made publicly visible on the web. Only the owner of a stream can manage its
permissions and visibility.
</p>
<p>
In order to use Speckle you first need to create a stream, so
<b>go ahead and create your first one</b>
!
</p>
</v-stepper-content>
<v-stepper-step :complete="quickstart > 2" step="2">Install Speckle Manager</v-stepper-step>
<v-stepper-content step="2" class="body-2">
<p>
Speckle Manager is a free
<b>desktop application</b>
that lets you install connectors for some of the most popular design and analysis
software.
</p>
<p>
The connectors
<b>exchange</b>
geometry and BIM data with Speckle, so that you can access it wherever you want!
</p>
<v-btn elevation="10" class="my-5" rounded color="primary" @click="downloadManager">
<v-icon small class="mr-4">mdi-download</v-icon>
Download Manager
</v-btn>
</v-stepper-content>
<v-stepper-step :complete="quickstart > 3" step="3">Set up Speckle Manager</v-stepper-step>
<v-stepper-content step="3">
<p>
With Speckle Manager installed,
<b>log into your account</b>
and then
<b>install the connectors</b>
for the software that you use.
</p>
<p>
<v-btn
elevation="10"
rounded
color="primary"
target="_blank"
@click="refreshApplications"
>
Done
</v-btn>
</p>
<p v-if="refreshFailied" class="red--text caption">
Please install Manager and log into your account to continue.
</p>
<p class="caption">Having issues logging in Manager? Try with the button below:</p>
<v-btn small text rounded color="primary" @click="addAccount">
<v-icon small class="mr-4">mdi-account-plus</v-icon>
Add account to manager
</v-btn>
</v-stepper-content>
<v-stepper-step step="4">Send data to Speckle</v-stepper-step>
<v-stepper-content step="4">
<p>Great progress 🥳!</p>
<p>
We're almost done here, and just need to send your first set of data to Speckle. By doing
so you will also be creating your first
<b>commit.</b>
</p>
<p>
Commits are
<b>snapshots or versions of your data in time.</b>
Every time you send to Speckle, a new commit is created for you.
</p>
<p>Send data to Speckle now by using one of our connetors!</p>
<p>
<v-btn
elevation="10"
class="my-5"
rounded
color="primary"
href="https://speckle.guide/user/connectors.html"
target="_blank"
>
Send Some Data
</v-btn>
</p>
</v-stepper-content>
</v-stepper>
</div>
</template>
<script>
import gql from 'graphql-tag'
export default {
apollo: {
user: {
query: gql`
query {
user {
id
name
streams {
totalCount
}
commits {
totalCount
}
}
}
`,
skip() {
return !this.loggedIn
}
},
authorizedApps: {
query: gql`
query {
user {
id
authorizedApps {
id
}
}
}
`,
update: (data) => data.user.authorizedApps
},
$subscribe: {
userStreamAdded: {
query: gql`
subscription {
userStreamAdded
}
`,
result() {
this.$apollo.queries.user.refetch()
},
skip() {
return !this.loggedIn
}
},
userStreamRemoved: {
query: gql`
subscription {
userStreamRemoved
}
`,
result() {
this.$apollo.queries.user.refetch()
},
skip() {
return !this.loggedIn
}
}
}
},
data: () => ({
streams: [],
hasClickedDownload: false,
refreshFailied: false,
skipped: false
}),
computed: {
loggedIn() {
return localStorage.getItem('uuid') !== null
},
rootUrl() {
return window.location.origin
},
quickstart() {
if (!this.user || this.skipped) return 0
if (this.user.streams.totalCount === 0) return 1
if (this.user.streams.totalCount > 0 && !this.hasManager && !this.hasClickedDownload) return 2
if (this.user.streams.totalCount > 0 && !this.hasManager && this.hasClickedDownload) return 3
if (this.hasManager && this.user.commits.totalCount === 0) return 4
if (this.user.commits.totalCount > 0) return 0
return 0
},
hasManager() {
if (!this.authorizedApps) return false
return this.authorizedApps.findIndex((a) => a.id === 'sdm') !== -1
}
},
watch: {
streams(val) {
if (val.items.length === 0 && !localStorage.getItem('onboarding')) {
this.$router.push('/onboarding')
}
}
},
mounted() {
this.skipped = localStorage.getItem('wizard')
},
methods: {
skip() {
localStorage.setItem('wizard', 'skipped')
this.skipped = true
},
downloadManager() {
this.hasClickedDownload = true
this.$matomo && this.$matomo.trackPageView(`onboarding/managerdownload`)
this.$matomo && this.$matomo.trackEvent('onboarding', 'managerdownload')
window.open('https://releases.speckle.dev/manager/SpeckleManager%20Setup.exe', '_blank')
},
addAccount() {
this.$matomo && this.$matomo.trackPageView(`onboarding/accountadd`)
this.$matomo && this.$matomo.trackEvent('onboarding', 'accountadd')
window.open(`speckle://accounts?add_server_account=${this.rootUrl}`, '_blank')
},
async refreshApplications() {
await this.$apollo.queries.authorizedApps.refetch()
if (!this.hasManager) {
this.refreshFailied = true
} else this.refreshFailied = false
}
}
}
</script>
<style scoped>
.quickstart-stepper {
box-shadow: none !important;
}
</style>
@@ -82,7 +82,7 @@
<v-container>
<v-row class="align-center">
<router-link :to="url" class="title">
<v-icon color="primary" small>mdi-compare-vertical</v-icon>
<v-icon color="primary" small>mdi-folder</v-icon>
{{ stream.name }}
</router-link>
<span class="ml-3 body-2 font-italic">{{ lastActivityBrief.actionText }}</span>
@@ -12,29 +12,69 @@
<v-container style="max-width: 500px">
<slot name="actions">
<v-list rounded class="transparent">
<v-list-item
link
class="primary mb-4"
dark
href="https://speckle.systems/features/connectors"
target="_blank"
>
<v-list-item-icon>
<v-icon>mdi-swap-horizontal</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>Connectors</v-list-item-title>
<v-list-item-subtitle class="caption">
Learn how to send data from various software.
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item
v-if="user && !hasManager"
href="https://releases.speckle.dev/manager/SpeckleManager%20Setup.exe"
link
class="primary mb-4"
dark
>
<v-list-item-icon>
<v-icon class="pt-5">mdi-download</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>Install Connectors</v-list-item-title>
<p class="caption pb-0 mb-0">
Download Speckle Manager to install connectors for your design applications and start sending data in no time!
</p>
</v-list-item-content>
</v-list-item>
<v-list-item
v-if="user && !hasManager"
:href="`speckle://accounts?add_server_account=${this.rootUrl}`"
link
:class="`grey ${$vuetify.theme.dark ? 'darken-4' : 'lighten-4'} mb-4`"
>
<v-list-item-icon>
<v-icon class="pt-4">mdi-account-plus</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>Authenticate</v-list-item-title>
<p class="caption pb-0 mb-0">
Link up your Speckle account with the desktop connectors you have installed.
</p>
</v-list-item-content>
</v-list-item>
<v-list-item
link
:class="`${!hasManager ? 'primary' : ''} mb-4 grey ${
$vuetify.theme.dark ? 'darken-4' : 'lighten-4'
}`"
dark
href="https://speckle.systems/features/connectors"
target="_blank"
v-if="hasManager"
>
<v-list-item-icon>
<v-icon>mdi-swap-horizontal</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>Connectors Guides</v-list-item-title>
<v-list-item-subtitle class="caption">
Learn how to send data from various software.
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item
link
:class="`grey ${$vuetify.theme.dark ? 'darken-4' : 'lighten-4'} mb-4`"
href="https://speckle.systems/tutorials"
target="_blank"
v-if="hasManager"
>
<v-list-item-icon>
<v-icon>mdi-school</v-icon>
@@ -52,6 +92,7 @@
:class="`grey ${$vuetify.theme.dark ? 'darken-4' : 'lighten-4'} mb-4`"
href="https://speckle.guide"
target="_blank"
v-if="hasManager"
>
<v-list-item-icon>
<v-icon>mdi-book-open-variant</v-icon>
@@ -76,12 +117,13 @@
<v-list-item-content>
<v-list-item-title>Community Forum</v-list-item-title>
<v-list-item-subtitle class="caption">
Our community is friendly and here to help!
Need help? We're here for you!
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
</slot>
<slot name="append"></slot>
</v-container>
</v-card>
</v-col>
@@ -89,8 +131,32 @@
</v-container>
</template>
<script>
import gql from 'graphql-tag'
export default {
computed: {},
apollo: {
user: {
query: gql`
query {
user {
id
authorizedApps {
id
name
}
}
}
`
}
},
computed: {
rootUrl() {
return window.location.origin
},
hasManager() {
if (!this.user) return
return this.user.authorizedApps.filter((app) => app.id === 'sdm').length !== 0
}
},
methods: {}
}
</script>
@@ -24,6 +24,7 @@
/>
<v-textarea v-model="description" rows="1" row-height="15" label="Description (optional)" />
<v-switch
inset
v-model="isPublic"
v-tooltip="
isPublic
-344
View File
@@ -1,344 +0,0 @@
<template>
<v-app id="speckle">
<v-app-bar app clipped-left>
<!-- DESKTOP APP BAR -->
<v-container
fluid
class="py-0 fill-height hidden-md-and-down"
>
<v-app-bar-nav-icon v-if="isStreamPage" @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
<v-btn text to="/" active-class="no-active">
<v-img class="" contain max-height="30" max-width="30" src="@/assets/logo.svg" />
<div class="logo">
<span><b>Speckle</b></span>
</div>
</v-btn>
<span class="mr-5">|</span>
<span v-if="serverInfo" v-tooltip="`Version: `+serverInfo.version" class="subtitle-2">{{ serverInfo.name }}</span>
<span v-if="serverInfo && isDevServer" v-tooltip="`This is a test server and should not be used in production!`" class="ml-4" ></span>
<span v-if="loggedIn">
<v-btn
v-for="link in navLinks"
:key="link.name"
text
exact
class="text-uppercase ml-5"
:to="link.link"
>
{{ link.name }}
</v-btn>
</span>
<v-spacer></v-spacer>
<v-responsive v-if="user" max-width="300">
<search-bar />
</v-responsive>
<user-menu-top v-if="user" :user="user" />
<v-btn v-else color="primary" to="/authn/login">
<v-icon left>mdi-account-arrow-right</v-icon>
Log in
</v-btn>
</v-container>
<!-- MOBILE APP BAR -->
<v-container class="hidden-lg-and-up">
<v-row>
<v-col>
<v-app-bar-nav-icon v-if="isStreamPage" @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
</v-col>
<v-col class="text-center">
<v-menu
v-if="loggedIn"
:value="showMobileMenu"
transition="slide-y-transition"
bottom
offset-y
:close-on-content-click="false"
min-width="100%"
>
<template #activator="{ on, attrs }">
<v-btn active-class="no-active" large icon text v-bind="attrs" v-on="on" @click="showMobileMenu = true">
<v-img contain max-height="40" max-width="40" src="@/assets/logo.svg" />
</v-btn>
</template>
<v-card>
<v-row>
<v-col v-for="link in navLinks" :key="link.name" cols="12">
<v-btn text block :to="link.link" exact>
{{ link.name }}
</v-btn>
</v-col>
<v-col cols="12" class="px-10 pb-7">
<v-divider class="mb-5"></v-divider>
<search-bar />
</v-col>
</v-row>
</v-card>
</v-menu>
</v-col>
<v-col class="text-right" style="margin-top: 5px">
<user-menu-top v-if="user" :user="user" />
</v-col>
</v-row>
</v-container>
</v-app-bar>
<v-navigation-drawer v-if="isStreamPage && stream" v-model="drawer" app clipped left>
<v-list>
<v-subheader>Stream menu</v-subheader>
<v-list-item-group color="primary">
<v-list-item
v-for="menu in menues"
:key="menu.name"
:to="menu.to"
:disabled="menu.disabled"
exact
@click="handleFunction(menu.click)"
>
<v-list-item-icon>
<v-icon>{{ menu.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ menu.name }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list-item-group>
</v-list>
<div class="mx-5 m t-5">
<v-btn
v-if="stream.role === 'stream:owner'"
outlined
color="primary"
rounded
block
height="50"
@click="showStreamInviteDialog"
>
<v-icon small class="mr-2">mdi-email-send-outline</v-icon>
Invite to this
<br />
stream by email
</v-btn>
</div>
<stream-invite-dialog ref="streamInviteDialog" :stream-id="stream.id" />
</v-navigation-drawer>
<v-main :style="background">
<router-view></router-view>
<v-snackbar
v-if="streamSnackbarInfo"
v-model="streamSnackbar"
:timeout="5000"
color="primary"
absolute
right
top
>
<b>New stream!</b></br>
<i v-if="streamSnackbarInfo && streamSnackbarInfo.name">{{ streamSnackbarInfo.name }}</i>
<span v-else>available</span>
<template #action="{ attrs }">
<v-btn
v-if="streamSnackbarInfo"
text
v-bind="attrs"
:to="'/streams/' + streamSnackbarInfo.id"
@click="streamSnackbar = false"
>
see
</v-btn>
<!-- <v-btn icon v-bind="attrs" @click="streamSnackbar = false">
<v-icon>mdi-close</v-icon>
</v-btn> -->
</template>
</v-snackbar>
</v-main>
</v-app>
</template>
<script>
import gql from 'graphql-tag'
import userQuery from '../graphql/user.gql'
import UserMenuTop from '../components/UserMenuTop'
import SearchBar from '../components/SearchBar'
import StreamInviteDialog from '../components/dialogs/StreamInviteDialog'
export default {
components: { UserMenuTop, SearchBar, StreamInviteDialog },
data() {
return {
search: '',
drawer: true,
streamSnackbar: false,
streamSnackbarInfo: {},
showMobileMenu: false,
streams: { items: [] },
selectedSearchResult: null,
navLinks: [
{ link: '/', name: 'feed' },
{ link: '/streams', name: 'streams' },
{ link: '/profile', name: 'profile' }
]
}
},
apollo: {
stream: {
query: gql`
query Stream($id: String!) {
stream(id: $id) {
id
name
role
}
}
`,
variables() {
return {
id: this.$route.params.streamId
}
},
skip() {
return !this.isStreamPage
}
},
serverInfo: {
query: gql`
query {
serverInfo {
name
company
description
adminContact
version
}
}
`
},
user: {
query: userQuery,
skip() {
return !this.loggedIn
}
},
$subscribe: {
userStreamAdded: {
query: gql`
subscription {
userStreamAdded
}
`,
result(streamInfo) {
if (!streamInfo.data.userStreamAdded) return
this.streamSnackbar = true
this.streamSnackbarInfo = streamInfo.data.userStreamAdded
},
skip() {
return !this.loggedIn
}
}
}
},
computed: {
background() {
let theme = this.$vuetify.theme.dark ? 'dark' : 'light'
return `background-color: ${this.$vuetify.theme.themes[theme].background};`
},
isDevServer(){
return (this.serverInfo.version[0]!=="v" ) ? true : false
},
loggedIn() {
return localStorage.getItem('uuid') !== null
},
isStreamPage() {
return this.$route.params.streamId && this.loggedIn
},
menues() {
return [
{
name: 'Details',
icon: 'mdi-compare-vertical',
to: '/streams/' + this.$route.params.streamId
},
{
name: 'Activity',
icon: 'mdi-history',
to: '/streams/' + this.$route.params.streamId + '/activity'
},
{
name: 'Branches',
icon: 'mdi-source-branch',
to: '/streams/' + this.$route.params.streamId + '/branches'
},
{
name: 'Globals',
icon: 'mdi-earth',
to: '/streams/' + this.$route.params.streamId + '/globals'
},
{
name: 'Collaborators',
icon: 'mdi-account-group-outline',
to: '/streams/' + this.$route.params.streamId + '/collaborators',
disabled: this.stream.role !== 'stream:owner'
},
{
name: 'Webhooks',
icon: 'mdi-webhook',
to: '/streams/' + this.$route.params.streamId + '/webhooks',
disabled: this.stream.role !== 'stream:owner'
},
{
name: 'Settings',
icon: 'mdi-cog-outline',
to: '/streams/' + this.$route.params.streamId + '/settings',
disabled: this.stream.role !== 'stream:owner'
}
]
}
},
watch: {
$route() {
this.showMobileMenu = false
}
},
methods: {
handleFunction(f) {
if (this[f]) this[f]()
},
showStreamInviteDialog() {
this.$refs.streamInviteDialog.show()
}
}
}
</script>
<style>
.space-grotesk {
font-family: 'Space Grotesk' !important;
}
.logo {
font-family: 'Space Grotesk', sans-serif;
text-transform: none;
color: rgb(37, 99, 235);
font-weight: 500;
font-size: 1rem;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 1s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
.no-hover:before {display: none}
</style>
@@ -1,117 +0,0 @@
<template>
<v-app id="inspire">
<v-app-bar
app
clipped-right
flat
height="72"
>
<v-spacer></v-spacer>
<v-responsive max-width="156">
<v-text-field
dense
flat
hide-details
rounded
solo-inverted
></v-text-field>
</v-responsive>
</v-app-bar>
<v-navigation-drawer
v-model="drawer"
app
width="300"
>
<v-navigation-drawer
v-model="drawer"
absolute
color="grey lighten-3"
mini-variant
>
<v-avatar
class="d-block text-center mx-auto mt-4"
color="grey darken-1"
size="36"
></v-avatar>
<v-divider class="mx-3 my-5"></v-divider>
<v-avatar
v-for="n in 6"
:key="n"
class="d-block text-center mx-auto mb-9"
color="grey lighten-1"
size="28"
></v-avatar>
</v-navigation-drawer>
<v-sheet
color="grey lighten-5"
height="128"
width="100%"
></v-sheet>
<v-list
class="pl-14"
shaped
>
<v-list-item
v-for="n in 5"
:key="n"
link
>
<v-list-item-content>
<v-list-item-title>Item {{ n }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-navigation-drawer
app
clipped
right
>
<v-list>
<v-list-item
v-for="n in 5"
:key="n"
link
>
<v-list-item-content>
<v-list-item-title>Item {{ n }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-main>
<!-- -->
</v-main>
<v-footer
app
color="transparent"
height="72"
inset
>
<v-text-field
background-color="grey lighten-1"
dense
flat
hide-details
rounded
solo
></v-text-field>
</v-footer>
</v-app>
</template>
<script>
export default {
data: () => ({ drawer: null }),
}
</script>
+5 -3
View File
@@ -3,17 +3,19 @@
<v-container fill-height fluid>
<v-row align="center" justify="center">
<v-col cols="12" md="8">
<error-block :message="'Page not found'" />
<error-placeholder error-type="404">
<h2>Page not found.</h2>
</error-placeholder>
</v-col>
</v-row>
</v-container>
</v-app>
</template>
<script>
import ErrorBlock from '../components/ErrorBlock'
import ErrorPlaceholder from '../components/ErrorPlaceholder'
export default {
components: {
ErrorBlock
ErrorPlaceholder
}
}
</script>
-1
View File
@@ -169,7 +169,6 @@ export default {
components: {
InfiniteLoading: () => import('vue-infinite-loading'),
ListItemStream: () => import('@/components/ListItemStream'),
GettingStartedWizard: () => import('@/components/GettingStartedWizard'),
MainNavActions: () => import('@/components/MainNavActions')
},
apollo: {
+47 -17
View File
@@ -7,7 +7,7 @@
v-model="activityNav"
style="left: 56px"
>
<main-nav-actions :open-new-stream="newStreamDialog"/>
<main-nav-actions :open-new-stream="newStreamDialog" />
<v-list v-if="streams && streams.items.length > 0" color="transparent" dense>
<v-subheader class="mt-3 ml-2">Recently updated streams</v-subheader>
@@ -86,18 +86,44 @@
</div>
</v-col>
<v-col v-else cols="12">
<div class="ma-5 headline justify-center text-center">
🎈
<br />
Your feed is empty!
<!-- <getting-started-wizard @newstream="newStreamDialog++" /> -->
<no-data-placeholder v-if="user">
<h2>Welcome {{user.name.split(' ')[0]}}!</h2>
<p class="caption">
Once you will create a stream and start sending some data, your activity will show up
here.
</p>
<br />
<span class="subtitle-2 font-italic">
Try creating a stream, sending data etc and your activity will show up here.
</span>
</div>
<template v-slot:actions>
<v-list rounded class="transparent">
<v-list-item
link
class="primary mb-4"
dark
@click="newStreamDialog++"
>
<v-list-item-icon>
<v-icon>mdi-plus-box</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>Create a new stream!</v-list-item-title>
<v-list-item-subtitle class="caption">
Streams are like folders, or data repositories.
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
</template>
</no-data-placeholder>
</v-col>
<v-col cols="12" lg="4" v-show="$vuetify.breakpoint.lgAndUp" class="mt-7">
<v-col
cols="12"
lg="4"
v-show="$vuetify.breakpoint.lgAndUp"
class="mt-7"
v-if="timeline && timeline.items.length > 0"
>
<latest-blogposts></latest-blogposts>
<v-card rounded="lg" class="mt-2">
<v-card-text class="caption">
@@ -106,8 +132,8 @@
<a href="https://speckle.systems" target="_blank" class="text-decoration-none">
Speckle
</a>
we're working tirelessly to bring you the best open source data platform for AEC.
Tell us what you think on our
we're working tirelessly to bring you the best open source data platform for AEC. Tell
us what you think on our
<a href="https://speckle.community" target="_blank" class="text-decoration-none">
forum
</a>
@@ -134,11 +160,11 @@ import gql from 'graphql-tag'
export default {
name: 'Timeline',
components: {
InfiniteLoading:()=>import( 'vue-infinite-loading'),
ListItemActivity:()=>import( '@/components/ListItemActivity'),
GettingStartedWizard:()=>import( '@/components/GettingStartedWizard'),
InfiniteLoading: () => import('vue-infinite-loading'),
ListItemActivity: () => import('@/components/ListItemActivity'),
LatestBlogposts: () => import('@/components/LatestBlogposts'),
MainNavActions: () => import('@/components/MainNavActions')
MainNavActions: () => import('@/components/MainNavActions'),
NoDataPlaceholder: () => import('@/components/NoDataPlaceholder')
},
props: {
type: String
@@ -159,6 +185,9 @@ export default {
)
},
apollo: {
user: {
query: gql`query { user { id name } } `
},
timeline: {
query: gql`
query($cursor: DateTime) {
@@ -181,6 +210,7 @@ export default {
}
}
`,
fetchPolicy: 'cache-and-network',
update(data) {
return data.user.timeline
},
@@ -92,7 +92,6 @@ export default {
SourceAppAvatar: () => import('@/components/SourceAppAvatar'),
NoDataPlaceholder: () => import('@/components/NoDataPlaceholder'),
Renderer: () => import('@/components/Renderer'),
ErrorBlock: () => import('@/components/ErrorBlock'),
ListItemCommit: () => import('@/components/ListItemCommit'),
PreviewImage: () => import('@/components/PreviewImage'),
StreamActivity: () => import('@/views/stream/Activity')