feat(frontend): empty states & wizard work
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user