feat(frontend): various last mile improvements
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-app-bar style="position: absolute; top: 0; width: 100%; z-index: 90" elevation="0">
|
||||
<search-bar />
|
||||
</v-app-bar>
|
||||
|
||||
<v-list style="margin-top: 64px" shaped>
|
||||
<v-list-item class="primary" dark link @click="newStreamDialog = true">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>New Stream</v-list-item-title>
|
||||
<v-list-item-subtitle class="caption">
|
||||
Quickly create a new data repository.
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-icon>
|
||||
<v-icon class="">mdi-plus-box</v-icon>
|
||||
</v-list-item-icon>
|
||||
</v-list-item>
|
||||
<v-list-item link @click="showServerInviteDialog()">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>Invite</v-list-item-title>
|
||||
<v-list-item-subtitle class="caption">
|
||||
Invite a colleague to Speckle!
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-icon>
|
||||
<v-icon class="">mdi-email</v-icon>
|
||||
</v-list-item-icon>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
|
||||
<server-invite-dialog ref="serverInviteDialog" />
|
||||
|
||||
<v-dialog v-model="newStreamDialog" max-width="500" :fullscreen="$vuetify.breakpoint.xsOnly">
|
||||
<stream-new-dialog
|
||||
:open="newStreamDialog"
|
||||
@created="newStreamDialog = false"
|
||||
@close="newStreamDialog = false"
|
||||
/>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
ServerInviteDialog: () => import('@/components/dialogs/ServerInviteDialog'),
|
||||
StreamNewDialog: () => import('@/components/dialogs/StreamNewDialog'),
|
||||
SearchBar: () => import('@/components/SearchBar'),
|
||||
},
|
||||
props: {
|
||||
OpenNewStream: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
OpenNewStream(val, old) {
|
||||
this.newStreamDialog = true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
newStreamDialog: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showServerInviteDialog() {
|
||||
this.$refs.serverInviteDialog.show()
|
||||
}
|
||||
},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
@@ -1,51 +1,54 @@
|
||||
<template>
|
||||
<v-dialog v-model="show" width="500" @keydown.esc="cancel">
|
||||
<v-card :loading="loading" class="pa-4">
|
||||
<template slot="progress">
|
||||
<v-progress-linear indeterminate></v-progress-linear>
|
||||
</template>
|
||||
<div v-if="branch && branch.name !== 'main'">
|
||||
<v-card-title>Edit Branch</v-card-title>
|
||||
<v-form ref="form" v-model="valid" lazy-validation @submit.prevent="agree">
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="branch.name"
|
||||
label="Name"
|
||||
:rules="nameRules"
|
||||
validate-on-blur
|
||||
required
|
||||
autofocus
|
||||
></v-text-field>
|
||||
<v-textarea v-model="branch.description" rows="2" label="Description"></v-textarea>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn text @click="cancel">Cancel</v-btn>
|
||||
<v-btn color="primary" text :disabled="!valid" type="submit">Save</v-btn>
|
||||
</v-card-actions>
|
||||
</v-form>
|
||||
<v-card-actions class="error--text body-2 pa-2">
|
||||
<v-btn block x-small text color="error" @click="showDelete = true">Delete Branch</v-btn>
|
||||
<v-dialog v-model="showDelete" max-width="500">
|
||||
<v-card>
|
||||
<v-card-title>Are you sure?</v-card-title>
|
||||
<v-card-text>
|
||||
You cannot undo this action. The branch
|
||||
<b>{{ branch.name }}</b>
|
||||
will be permanently deleted.
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn @click="showDelete = false">Cancel</v-btn>
|
||||
<v-btn color="error" text @click="deleteBranch">Delete</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
<v-card :loading="loading" v-if="branch && branch.name !== 'main'">
|
||||
<v-toolbar color="primary" dark>
|
||||
<v-app-bar-nav-icon style="pointer-events: none">
|
||||
<v-icon>mdi-pencil</v-icon>
|
||||
</v-app-bar-nav-icon>
|
||||
<v-toolbar-title>Edit Branch</v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="show = false"><v-icon>mdi-close</v-icon></v-btn>
|
||||
</v-toolbar>
|
||||
|
||||
<v-form ref="form" v-model="valid" lazy-validation @submit.prevent="agree">
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="branch.name"
|
||||
label="Name"
|
||||
:rules="nameRules"
|
||||
validate-on-blur
|
||||
required
|
||||
autofocus
|
||||
></v-text-field>
|
||||
<v-textarea v-model="branch.description" rows="2" label="Description"></v-textarea>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn text small color="error" @click="showDelete = true">Delete</v-btn>
|
||||
<v-btn @click="cancel">Cancel</v-btn>
|
||||
<v-btn color="primary" :disabled="!valid" type="submit">Save</v-btn>
|
||||
</v-card-actions>
|
||||
</div>
|
||||
<div v-else>
|
||||
<v-card-text>You cannot edit the main branch.</v-card-text>
|
||||
</div>
|
||||
</v-form>
|
||||
<v-card-actions class="error--text body-2 pa-2">
|
||||
<v-dialog v-model="showDelete" max-width="500">
|
||||
<v-card>
|
||||
<v-card-title>Are you sure?</v-card-title>
|
||||
<v-card-text>
|
||||
You cannot undo this action. The branch
|
||||
<b>{{ branch.name }}</b>
|
||||
will be permanently deleted.
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn @click="showDelete = false">Cancel</v-btn>
|
||||
<v-btn color="error" text @click="deleteBranch">Delete</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
<v-card v-else>
|
||||
<v-card-text>You cannot edit the main branch.</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
<template>
|
||||
<v-dialog v-model="show" width="500" @keydown.esc="cancel">
|
||||
<v-card class="pa-4">
|
||||
<v-card-title class="subtitle-1">Edit Commit</v-card-title>
|
||||
<v-card >
|
||||
<v-toolbar color="primary" dark>
|
||||
<v-app-bar-nav-icon style="pointer-events: none">
|
||||
<v-icon>mdi-pencil</v-icon>
|
||||
</v-app-bar-nav-icon>
|
||||
<v-toolbar-title>Edit Commit</v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn icon @click="show = false"><v-icon>mdi-close</v-icon></v-btn>
|
||||
</v-toolbar>
|
||||
<v-form ref="form" v-model="valid" lazy-validation @submit.prevent="agree">
|
||||
<v-card-text class="pl-2 pr-2 pt-0 pb-0">
|
||||
<v-container>
|
||||
@@ -13,7 +20,6 @@
|
||||
:rules="nameRules"
|
||||
validate-on-blur
|
||||
required
|
||||
filled
|
||||
autofocus
|
||||
></v-text-field>
|
||||
</v-col>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-dialog v-model="showDialog" max-width="400" :fullscreen="$vuetify.breakpoint.smAndDown">
|
||||
<v-dialog v-model="showDialog" max-width="400" :fullscreen="$vuetify.breakpoint.xsOnly">
|
||||
<v-card>
|
||||
<v-toolbar color="primary" dark>
|
||||
<v-app-bar-nav-icon style="pointer-events: none">
|
||||
|
||||
@@ -271,7 +271,7 @@ router.beforeEach((to, from, next) => {
|
||||
let redirect = localStorage.getItem('shouldRedirectTo')
|
||||
if (
|
||||
!uuid &&
|
||||
!to.matched.some(({ name }) => name === 'stream' || name === 'commit') && //allow public streams to be viewed
|
||||
!to.matched.some(({ name }) => name === 'stream' || name === 'commit' || name === 'branch') && //allow public streams to be viewed
|
||||
to.name !== 'Embeded Viewer' &&
|
||||
to.name !== 'Login' &&
|
||||
to.name !== 'Register' &&
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
<v-list-item link to="/streams" style="height: 59px">
|
||||
<v-list-item-icon>
|
||||
<v-icon>mdi-folder-multiple</v-icon>
|
||||
<v-icon>mdi-folder</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>Streams</v-list-item-title>
|
||||
@@ -127,7 +127,7 @@
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item link @click="switchTheme" color="primary">
|
||||
<v-list-item link @click="signOut()" color="primary" v-if="user">
|
||||
<v-list-item-icon>
|
||||
<v-icon small class="ml-1">mdi-account-off</v-icon>
|
||||
</v-list-item-icon>
|
||||
@@ -171,6 +171,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
import { signOut } from '@/auth-helpers'
|
||||
import userQuery from '../graphql/user.gql'
|
||||
import UserMenuTop from '../components/UserMenuTop'
|
||||
import SearchBar from '../components/SearchBar'
|
||||
@@ -240,6 +241,9 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
signOut(){
|
||||
signOut()
|
||||
},
|
||||
switchTheme() {
|
||||
this.$vuetify.theme.dark = !this.$vuetify.theme.dark
|
||||
localStorage.setItem('darkModeEnabled', this.$vuetify.theme.dark ? 'dark' : 'light')
|
||||
|
||||
@@ -7,36 +7,37 @@
|
||||
v-model="streamNav"
|
||||
style="left: 56px"
|
||||
>
|
||||
<v-app-bar style="position: absolute; top: 0; width: 100%; z-index: 90" elevation="0">
|
||||
<search-bar />
|
||||
</v-app-bar>
|
||||
|
||||
<v-list style="margin-top: 64px" shaped>
|
||||
<v-list-item class="primary" dark link @click="newStreamDialog = true">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>New Stream</v-list-item-title>
|
||||
<v-list-item-subtitle class="caption">
|
||||
Quickly create a new data repository.
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-icon>
|
||||
<v-icon class="">mdi-plus-box</v-icon>
|
||||
</v-list-item-icon>
|
||||
</v-list-item>
|
||||
<v-list-item link @click="showServerInviteDialog()">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>Invite</v-list-item-title>
|
||||
<v-list-item-subtitle class="caption">
|
||||
Invite a colleague to Speckle!
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-icon>
|
||||
<v-icon class="">mdi-email</v-icon>
|
||||
</v-list-item-icon>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<main-nav-actions :open-new-stream="streamNewDialog" />
|
||||
|
||||
<div v-if="user">
|
||||
<!-- <v-subheader class="caption">Filter:</v-subheader>
|
||||
<v-list dense rounded>
|
||||
<v-list-item link>
|
||||
<v-list-item-icon>
|
||||
<v-icon small class="">mdi-key</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-subtitle class="caption">Owner</v-list-item-subtitle class="caption">
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-item link>
|
||||
<v-list-item-icon>
|
||||
<v-icon small class="">mdi-account</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-subtitle class="caption">Contributor</v-list-item-subtitle class="caption">
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-item link>
|
||||
<v-list-item-icon>
|
||||
<v-icon small class="">mdi-circle</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-subtitle class="caption">Reviewer</v-list-item-subtitle class="caption">
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list> -->
|
||||
|
||||
<v-subheader class="caption">Your stats:</v-subheader>
|
||||
<v-list dense>
|
||||
<v-list-item>
|
||||
@@ -44,7 +45,10 @@
|
||||
<v-icon small class="">mdi-folder-multiple</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-subtitle class="caption"><b>{{ user.streams.totalCount }}</b> total streams</v-list-item-subtitle class="caption">
|
||||
<v-list-item-subtitle class="caption">
|
||||
<b>{{ user.streams.totalCount }}</b>
|
||||
total streams
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
@@ -52,40 +56,59 @@
|
||||
<v-icon small class="">mdi-source-commit</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-subtitle class="caption"><b>{{ user.commits.totalCount }}</b> total commits</v-list-item-subtitle class="caption">
|
||||
<v-list-item-subtitle class="caption">
|
||||
<b>{{ user.commits.totalCount }}</b>
|
||||
total commits
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
|
||||
<v-list
|
||||
v-if="userCommits && userCommits.commits.items.length !== 0"
|
||||
color="transparent"
|
||||
dense
|
||||
>
|
||||
<v-subheader class="mt-3 ml-2">Your latest commits:</v-subheader>
|
||||
<v-list-item
|
||||
v-for="(commit, i) in userCommits.commits.items"
|
||||
:key="i"
|
||||
:to="`streams/${commit.streamId}/${ commit.branchName === 'globals' ? 'globals' : 'commits' }/${commit.id}`"
|
||||
v-if="commit"
|
||||
v-tooltip="`In stream '${commit.streamName}'`"
|
||||
>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>
|
||||
{{ commit.message }}
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle class="caption">
|
||||
<i>
|
||||
Updated
|
||||
<timeago :datetime="commit.createdAt"></timeago>
|
||||
</i>
|
||||
on <v-icon style="font-size: 10px;">mdi-source-branch</v-icon>{{commit.branchName}}
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
|
||||
<div class="ml-5"></div>
|
||||
</div>
|
||||
</v-navigation-drawer>
|
||||
|
||||
<v-app-bar app style="padding-left: 56px" flat>
|
||||
<v-app-bar-nav-icon @click="streamNav = !streamNav" v-show="!streamNav"></v-app-bar-nav-icon>
|
||||
<v-toolbar-title class="space-grotesk">
|
||||
<v-icon>mdi-folder-multiple</v-icon>
|
||||
<v-icon class="mb-1">mdi-folder</v-icon>
|
||||
Streams
|
||||
</v-toolbar-title>
|
||||
<v-spacer v-if="!streamNav"></v-spacer>
|
||||
<v-toolbar-items v-if="!streamNav">
|
||||
<v-btn color="primary" @click="newStreamDialog = true">
|
||||
<v-btn color="primary" @click="streamNewDialog++">
|
||||
<v-icon>mdi-plus-box</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar-items>
|
||||
</v-app-bar>
|
||||
|
||||
<server-invite-dialog ref="serverInviteDialog" />
|
||||
|
||||
<v-dialog v-model="newStreamDialog" max-width="500">
|
||||
<stream-new-dialog
|
||||
v-if="streams && streams.items"
|
||||
:open="newStreamDialog"
|
||||
:redirect="streams.items.length > 0"
|
||||
@created="newStreamDialog = false"
|
||||
/>
|
||||
</v-dialog>
|
||||
|
||||
<!-- <getting-started-wizard /> -->
|
||||
|
||||
<v-row class="px-4" no-gutters>
|
||||
@@ -137,25 +160,17 @@
|
||||
</v-container>
|
||||
</template>
|
||||
<script>
|
||||
import ListItemStream from '../components/ListItemStream'
|
||||
import StreamNewDialog from '../components/dialogs/StreamNewDialog'
|
||||
import GettingStartedWizard from '../components/GettingStartedWizard'
|
||||
import gql from 'graphql-tag'
|
||||
import streamsQuery from '../graphql/streams.gql'
|
||||
import userQuery from '../graphql/user.gql'
|
||||
import InfiniteLoading from 'vue-infinite-loading'
|
||||
import ServerInviteDialog from '../components/dialogs/ServerInviteDialog.vue'
|
||||
import SearchBar from '../components/SearchBar'
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default {
|
||||
name: 'Streams',
|
||||
components: {
|
||||
ListItemStream,
|
||||
StreamNewDialog,
|
||||
InfiniteLoading,
|
||||
ServerInviteDialog,
|
||||
GettingStartedWizard,
|
||||
SearchBar
|
||||
InfiniteLoading: () => import('vue-infinite-loading'),
|
||||
ListItemStream: () => import('@/components/ListItemStream'),
|
||||
GettingStartedWizard: () => import('@/components/GettingStartedWizard'),
|
||||
MainNavActions: () => import('@/components/MainNavActions')
|
||||
},
|
||||
apollo: {
|
||||
streams: {
|
||||
@@ -169,6 +184,30 @@ export default {
|
||||
return !this.loggedIn
|
||||
}
|
||||
},
|
||||
userCommits: {
|
||||
query: gql`
|
||||
query {
|
||||
userCommits: user {
|
||||
id
|
||||
commits {
|
||||
totalCount
|
||||
items {
|
||||
id
|
||||
message
|
||||
sourceApplication
|
||||
streamId
|
||||
streamName
|
||||
branchName
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
skip() {
|
||||
return !this.loggedIn
|
||||
}
|
||||
},
|
||||
$subscribe: {
|
||||
userStreamAdded: {
|
||||
query: gql`
|
||||
@@ -199,10 +238,9 @@ export default {
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
activeTab: 'streams',
|
||||
streams: [],
|
||||
newStreamDialog: false,
|
||||
streamNav: true
|
||||
streamNav: true,
|
||||
streamNewDialog: 0
|
||||
}),
|
||||
computed: {
|
||||
loggedIn() {
|
||||
@@ -217,7 +255,12 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
setTimeout( function() { this.streamNav = !this.$vuetify.breakpoint.smAndDown }.bind(this), 100 )
|
||||
setTimeout(
|
||||
function () {
|
||||
this.streamNav = !this.$vuetify.breakpoint.smAndDown
|
||||
}.bind(this),
|
||||
100
|
||||
)
|
||||
},
|
||||
methods: {
|
||||
showServerInviteDialog() {
|
||||
|
||||
@@ -7,34 +7,8 @@
|
||||
v-model="activityNav"
|
||||
style="left: 56px"
|
||||
>
|
||||
<v-app-bar style="position: absolute; top: 0; width: 100%; z-index: 90" elevation="0">
|
||||
<search-bar />
|
||||
</v-app-bar>
|
||||
<main-nav-actions :open-new-stream="newStreamDialog"/>
|
||||
|
||||
<v-list style="margin-top: 64px" shaped>
|
||||
<v-list-item class="primary" dark link @click="newStreamDialog = true">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>New Stream</v-list-item-title>
|
||||
<v-list-item-subtitle class="caption">
|
||||
Quickly create a new data repository.
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-icon>
|
||||
<v-icon class="">mdi-plus-box</v-icon>
|
||||
</v-list-item-icon>
|
||||
</v-list-item>
|
||||
<v-list-item link @click="showServerInviteDialog()">
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>Invite</v-list-item-title>
|
||||
<v-list-item-subtitle class="caption">
|
||||
Invite a colleague to Speckle!
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-icon>
|
||||
<v-icon class="">mdi-email</v-icon>
|
||||
</v-list-item-icon>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<v-list v-if="streams && streams.items.length > 0" color="transparent" dense>
|
||||
<v-subheader class="mt-3 ml-2">Recently updated streams</v-subheader>
|
||||
<v-list-item
|
||||
@@ -69,26 +43,15 @@
|
||||
</v-toolbar-title>
|
||||
<v-spacer v-if="!activityNav"></v-spacer>
|
||||
<v-toolbar-items v-if="!activityNav" style="position: relative; left: 0">
|
||||
<v-btn color="primary" @click="newStreamDialog = true">
|
||||
<v-btn color="primary" @click="newStreamDialog++">
|
||||
<v-icon>mdi-plus-box</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar-items>
|
||||
</v-app-bar>
|
||||
|
||||
<server-invite-dialog ref="serverInviteDialog" />
|
||||
<v-dialog v-model="newStreamDialog" max-width="500" :fullscreen="$vuetify.breakpoint.smAndDown">
|
||||
<stream-new-dialog
|
||||
v-if="streams"
|
||||
:open="newStreamDialog"
|
||||
:redirect="streams.items.length > 0"
|
||||
@created="newStreamDialog = false"
|
||||
@close="newStreamDialog = false"
|
||||
/>
|
||||
</v-dialog>
|
||||
|
||||
<v-row class="pr-4">
|
||||
<!-- <v-col cols="12"> -->
|
||||
<!-- <getting-started-wizard /> -->
|
||||
<!-- <getting-started-wizard /> -->
|
||||
<!-- </v-col> -->
|
||||
<v-col v-if="$apollo.loading && !timeline">
|
||||
<div class="my-5">
|
||||
@@ -138,7 +101,26 @@
|
||||
<latest-blogposts></latest-blogposts>
|
||||
<v-card rounded="lg" class="mt-2">
|
||||
<v-card-text class="caption">
|
||||
<p class="mb-0">At <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 <a href="https://speckle.community" target="_blank" class="text-decoration-none">forum</a>, and don't forget to give us a ⭐️ on <a href="https://github.com/specklesystems/speckle-sharp" target="_blank" class="text-decoration-none">Github</a>!</p>
|
||||
<p class="mb-0">
|
||||
At
|
||||
<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
|
||||
<a href="https://speckle.community" target="_blank" class="text-decoration-none">
|
||||
forum
|
||||
</a>
|
||||
, and don't forget to give us a ⭐️ on
|
||||
<a
|
||||
href="https://github.com/specklesystems/speckle-sharp"
|
||||
target="_blank"
|
||||
class="text-decoration-none"
|
||||
>
|
||||
Github
|
||||
</a>
|
||||
!
|
||||
</p>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
@@ -148,32 +130,22 @@
|
||||
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
import InfiniteLoading from 'vue-infinite-loading'
|
||||
|
||||
import ListItemActivity from '@/components/ListItemActivity'
|
||||
import GettingStartedWizard from '../components/GettingStartedWizard'
|
||||
import ServerInviteDialog from '@/components/dialogs/ServerInviteDialog.vue'
|
||||
import StreamNewDialog from '@/components/dialogs/StreamNewDialog'
|
||||
import SearchBar from '@/components/SearchBar'
|
||||
import LatestBlogposts from '@/components/LatestBlogposts'
|
||||
|
||||
export default {
|
||||
name: 'Timeline',
|
||||
components: {
|
||||
ListItemActivity,
|
||||
InfiniteLoading,
|
||||
ServerInviteDialog,
|
||||
StreamNewDialog,
|
||||
GettingStartedWizard,
|
||||
SearchBar,
|
||||
LatestBlogposts
|
||||
InfiniteLoading:()=>import( 'vue-infinite-loading'),
|
||||
ListItemActivity:()=>import( '@/components/ListItemActivity'),
|
||||
GettingStartedWizard:()=>import( '@/components/GettingStartedWizard'),
|
||||
LatestBlogposts: () => import('@/components/LatestBlogposts'),
|
||||
MainNavActions: () => import('@/components/MainNavActions')
|
||||
},
|
||||
props: {
|
||||
type: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
newStreamDialog: false,
|
||||
newStreamDialog: 0,
|
||||
activityNav: true
|
||||
}
|
||||
},
|
||||
@@ -261,9 +233,7 @@ export default {
|
||||
// console.log(groupedTimeline)
|
||||
this.groupedTimeline = groupedTimeline
|
||||
},
|
||||
showServerInviteDialog() {
|
||||
this.$refs.serverInviteDialog.show()
|
||||
},
|
||||
|
||||
infiniteHandler($state) {
|
||||
this.$apollo.queries.timeline.fetchMore({
|
||||
variables: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div id="admin-settings">
|
||||
<v-card class="elevation-0" rounded="lg" v-if="serverInfo">
|
||||
<v-card rounded="lg" v-if="serverInfo">
|
||||
<v-toolbar flat :class="`${!$vuetify.theme.dark ? 'grey lighten-5' : ''}`">
|
||||
<v-toolbar-title>{{ serverInfo.name }}</v-toolbar-title>
|
||||
</v-toolbar>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<v-row>
|
||||
<v-col cols="12">
|
||||
<v-timeline v-if="stream" align-top dense>
|
||||
<v-timeline v-if="stream && groupedActivity && groupedActivity.length !== 0" align-top dense>
|
||||
<list-item-activity
|
||||
v-for="activity in groupedActivity"
|
||||
:key="activity.time"
|
||||
@@ -22,6 +22,11 @@
|
||||
<v-skeleton-loader type="article"></v-skeleton-loader>
|
||||
</v-timeline-item>
|
||||
</v-timeline>
|
||||
<div v-if="groupedActivity && groupedActivity.length === 0">
|
||||
<v-card class="transparent elevation-0 mt-10">
|
||||
<v-card-text>Nothing to show 🍃</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
<portal to="streamActionsBar">
|
||||
<v-btn
|
||||
elevation="0"
|
||||
v-if="stream"
|
||||
v-if="loggedInUserId && stream && stream.role !== 'stream:reviewer' && stream.branch.name !== 'main'"
|
||||
color="primary"
|
||||
small
|
||||
v-tooltip="'Edit branch'"
|
||||
@click="editBranch()"
|
||||
rounded
|
||||
>
|
||||
<v-icon small class="mr-2">mdi-pencil</v-icon>
|
||||
<span class="hidden-md-and-down">Edit</span>
|
||||
@@ -50,7 +51,7 @@
|
||||
|
||||
<!-- TODO: pagination -->
|
||||
|
||||
<v-list-item v-if="stream">
|
||||
<!-- <v-list-item v-if="stream">
|
||||
<v-list-item-icon class="pl-4" style="width: 40px">
|
||||
<v-avatar
|
||||
:color="`grey ${this.$vuetify.theme.dark ? 'darken-4' : 'lighten-4'}`"
|
||||
@@ -65,8 +66,8 @@
|
||||
Branch "{{ stream.branch.name }}" created
|
||||
</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-list-item v-if="stream">
|
||||
</v-list-item> -->
|
||||
<!-- <v-list-item v-if="stream">
|
||||
<v-list-item-icon class="pl-4" style="width: 40px">
|
||||
<v-avatar
|
||||
:color="`grey ${this.$vuetify.theme.dark ? 'darken-4' : 'lighten-4'}`"
|
||||
@@ -81,7 +82,7 @@
|
||||
TODO: PAGINATION YO
|
||||
</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list-item> -->
|
||||
</v-list>
|
||||
</v-col>
|
||||
|
||||
@@ -145,6 +146,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
loggedInUserId(){
|
||||
return localStorage.getItem('uuid')
|
||||
},
|
||||
streamId() {
|
||||
return this.$route.params.streamId
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-row>
|
||||
|
||||
<v-col v-if="$apollo.queries.stream.loading" cols="12" class="ma-0 pa-0">
|
||||
<v-card>
|
||||
<v-skeleton-loader type="list-item-avatar, card-avatar, article"></v-skeleton-loader>
|
||||
@@ -10,20 +9,36 @@
|
||||
|
||||
<v-col v-else-if="stream.commit" cols="12" class="ma-0 pa-0">
|
||||
<portal to="streamActionsBar">
|
||||
<v-btn elevation="0" color="primary" small v-tooltip="'Edit commit'" v-if=" stream && (stream.role === 'stream:owner' || stream.role === 'stream:contributor')" @click="editCommit">
|
||||
<v-btn
|
||||
elevation="0"
|
||||
color="primary"
|
||||
small
|
||||
rounded
|
||||
v-tooltip="'Edit commit'"
|
||||
v-if="
|
||||
stream && stream.role!== 'stream:reviewer' && stream.commit.authorId === loggedInUserId
|
||||
"
|
||||
@click="editCommit"
|
||||
>
|
||||
<v-icon small class="mr-2">mdi-pencil</v-icon>
|
||||
<span class="hidden-md-and-down">Edit</span>
|
||||
</v-btn>
|
||||
</portal>
|
||||
<portal to="streamTitleBar">
|
||||
<div>
|
||||
<router-link :to="`/streams/${stream.id}/branches/${stream.commit.branchName}`" class="text-decoration-none space-grotesk" v-tooltip="'Go to branch ' + stream.commit.branchName">
|
||||
<router-link
|
||||
:to="`/streams/${stream.id}/branches/${stream.commit.branchName}`"
|
||||
class="text-decoration-none space-grotesk"
|
||||
v-tooltip="'Go to branch ' + stream.commit.branchName"
|
||||
>
|
||||
<v-icon small class="primary--text mr-1 mb-1">mdi-source-branch</v-icon>
|
||||
<b>{{ stream.commit.branchName }}</b>
|
||||
<b>{{ stream.commit.branchName }}</b>
|
||||
</router-link>
|
||||
/
|
||||
<v-icon small class="mr-1">mdi-source-commit</v-icon>
|
||||
<span class="space-grotesk mr-2" v-tooltip="'Commit message'">{{ stream.commit.message }}</span>
|
||||
<span class="space-grotesk mr-2" v-tooltip="'Commit message'">
|
||||
{{ stream.commit.message }}
|
||||
</span>
|
||||
<user-avatar
|
||||
:id="stream.commit.authorId"
|
||||
:avatar="stream.commit.authorAvatar"
|
||||
@@ -44,7 +59,7 @@
|
||||
<div style="height: 60vh">
|
||||
<renderer :object-url="commitObjectUrl" @selection="handleSelection" />
|
||||
</div>
|
||||
|
||||
|
||||
<v-card elevation="0" rounded="lg">
|
||||
<!-- Selected object -->
|
||||
<v-expand-transition>
|
||||
@@ -92,6 +107,7 @@
|
||||
<error-block :message="'Commit not found'" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
<commit-edit-dialog ref="commitDialog"></commit-edit-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -108,7 +124,7 @@ export default {
|
||||
ObjectSimpleViewer: () => import('@/components/ObjectSimpleViewer'),
|
||||
Renderer: () => import('@/components/Renderer'),
|
||||
SourceAppAvatar: () => import('@/components/SourceAppAvatar'),
|
||||
ErrorBlock: () => import('@/components/ErrorBlock'),
|
||||
ErrorBlock: () => import('@/components/ErrorBlock')
|
||||
},
|
||||
data: () => ({
|
||||
loadedModel: false,
|
||||
@@ -128,6 +144,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
loggedInUserId(){
|
||||
return localStorage.getItem('uuid')
|
||||
},
|
||||
commitDate() {
|
||||
if (!this.stream.commit) return null
|
||||
let date = new Date(this.stream.commit.createdAt)
|
||||
@@ -178,5 +197,4 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,380 +0,0 @@
|
||||
<template>
|
||||
<v-row v-if="!error">
|
||||
<v-col v-if="$apollo.loading" cols="12">
|
||||
<v-skeleton-loader type="heading" class="mb-5"></v-skeleton-loader>
|
||||
<v-skeleton-loader type="text@3" class="mb-5"></v-skeleton-loader>
|
||||
<v-skeleton-loader type="list-item-two-line, image"></v-skeleton-loader>
|
||||
</v-col>
|
||||
<v-col v-if="stream" cols="12">
|
||||
<v-row v-if="stream">
|
||||
<v-col cols="12" sm="12" md="8" lg="9" xl="9">
|
||||
<v-card class="mb-4" rounded="lg" elevation="0">
|
||||
<div class="pt-5 ml-7">
|
||||
<span class="title mb-3 mt-3 mr-3">Branch:</span>
|
||||
<v-select
|
||||
v-model="selectedBranch"
|
||||
:items="branches"
|
||||
item-value="name"
|
||||
solo
|
||||
flat
|
||||
return-object
|
||||
background-color="background"
|
||||
class="d-inline-block mt-2 mr-4 mb-0 pb-0"
|
||||
style="max-width: 50%"
|
||||
>
|
||||
<template #selection="{ item }">
|
||||
<v-icon class="mr-2">mdi-source-branch</v-icon>
|
||||
<span class="text-truncate">{{ item.name }}</span>
|
||||
</template>
|
||||
<template #item="{ item }">
|
||||
<div class="pa-2">
|
||||
<p class="pa-0 ma-0">{{ item.name }}</p>
|
||||
<p class="caption pa-0 ma-0 grey--text">
|
||||
{{ item.description }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</v-select>
|
||||
<!-- <v-btn
|
||||
class="pa-3"
|
||||
color="primary"
|
||||
text
|
||||
block
|
||||
:to="'/streams/' + $route.params.streamId + '/commits/' + latestCommit.id"
|
||||
>
|
||||
<v-icon class="mr-2 float-left">mdi-source-commit</v-icon>
|
||||
See commit details
|
||||
</v-btn> -->
|
||||
</div>
|
||||
|
||||
<div v-if="latestCommit">
|
||||
<div style="height: 50vh">
|
||||
<renderer
|
||||
:object-url="latestCommitObjectUrl"
|
||||
:unload-trigger="clearRendererTrigger"
|
||||
show-selection-helper
|
||||
/>
|
||||
</div>
|
||||
|
||||
<v-list two-line class="pa-0" color="transparent">
|
||||
<v-list-item
|
||||
:to="'/streams/' + $route.params.streamId + '/commits/' + latestCommit.id"
|
||||
>
|
||||
<v-list-item-icon>
|
||||
<user-avatar
|
||||
:id="latestCommit.authorId"
|
||||
:avatar="latestCommit.authorAvatar"
|
||||
:name="latestCommit.authorName"
|
||||
:size="30"
|
||||
/>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title class="mb-2 pt-1">
|
||||
<b>{{ latestCommit.message }}</b>
|
||||
<i class="caption"> (latest)</i>
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle class="caption">
|
||||
<b>{{ latestCommit.authorName }}</b>
|
||||
|
||||
<timeago :datetime="latestCommit.createdAt"></timeago>
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-row align="center" justify="center">
|
||||
<v-chip small class="mr-2 no-hover">
|
||||
<v-icon small class="mr-2">mdi-source-commit</v-icon>
|
||||
{{ latestCommit.id }}
|
||||
</v-chip>
|
||||
|
||||
<source-app-avatar :application-name="latestCommit.sourceApplication" />
|
||||
</v-row>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<!-- LAST 2 COMMITS -->
|
||||
<v-list dense color="transparent" class="mb-0 pa-0">
|
||||
<div v-for="(commit, i) in selectedBranch.commits.items" :key="commit.id">
|
||||
<v-list-item
|
||||
v-if="i > 0"
|
||||
:to="'/streams/' + $route.params.streamId + '/commits/' + commit.id"
|
||||
>
|
||||
<v-list-item-icon>
|
||||
<user-avatar
|
||||
:id="commit.authorId"
|
||||
:avatar="commit.authorAvatar"
|
||||
:name="commit.authorName"
|
||||
:size="30"
|
||||
/>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title class="mb-2 pt-1">
|
||||
{{ commit.message }}
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle class="caption">
|
||||
<b>{{ commit.authorName }}</b>
|
||||
|
||||
<timeago :datetime="commit.createdAt"></timeago>
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-row align="center" justify="center">
|
||||
<v-chip small class="mr-2 no-hover">
|
||||
<v-icon small class="mr-2">mdi-source-commit</v-icon>
|
||||
{{ commit.id }}
|
||||
</v-chip>
|
||||
|
||||
<source-app-avatar :application-name="commit.sourceApplication" />
|
||||
</v-row>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
<v-divider />
|
||||
</div>
|
||||
<v-list-item
|
||||
v-if="selectedBranch"
|
||||
color="transparent"
|
||||
:to="'/streams/' + $route.params.streamId + '/branches/' + selectedBranch.name"
|
||||
>
|
||||
<v-row align="center" justify="center">
|
||||
<span class="font-weight-bold primary--text py-3 my-4">
|
||||
<v-icon class="mr-2 float-left" color="primary">mdi-source-commit</v-icon>
|
||||
See all commits on
|
||||
{{ selectedBranch.name }} ({{ selectedBranch.commits.totalCount }})
|
||||
</span>
|
||||
</v-row>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</div>
|
||||
</v-card>
|
||||
<no-data-placeholder
|
||||
v-if="!latestCommit && selectedBranch"
|
||||
:message="'Branch ' + selectedBranch.name + ' has no commits.'"
|
||||
/>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="4" lg="3" xl="3">
|
||||
<h4 class="space-grotesk mb-3">About:</h4>
|
||||
<div>
|
||||
<v-chip class="mr-3 mb-3 no-hover">
|
||||
<v-icon small left>mdi-source-branch</v-icon>
|
||||
|
||||
{{ stream.branches.totalCount }}
|
||||
branch{{ stream.branches.totalCount === 1 ? '' : 'es' }}
|
||||
</v-chip>
|
||||
<v-chip class="mr-3 mb-3 no-hover">
|
||||
<v-icon small left>mdi-source-commit</v-icon>
|
||||
|
||||
|
||||
{{ stream.commits.totalCount }}
|
||||
commit{{ stream.commits.totalCount === 1 ? '' : 's' }}
|
||||
</v-chip>
|
||||
<v-chip class="mr-3 mb-3 no-hover">
|
||||
<span
|
||||
v-if="stream.isPublic"
|
||||
v-tooltip="`Anyone can view this stream. Only you and collaborators can edit it.`"
|
||||
>
|
||||
<v-icon small left>mdi-lock-open-variant-outline</v-icon>
|
||||
public
|
||||
</span>
|
||||
<span v-else v-tooltip="`Only collaborators can access this stream.`">
|
||||
<v-icon small left>mdi-lock-outline</v-icon>
|
||||
private
|
||||
</span>
|
||||
</v-chip>
|
||||
<v-chip v-if="loggedIn" class="mr-3 mb-3 no-hover">
|
||||
<v-icon small left>mdi-account-key-outline</v-icon>
|
||||
{{ stream.role.split(':')[1] }}
|
||||
</v-chip>
|
||||
</div>
|
||||
<div class="my-3">
|
||||
<div class="caption mb-3">
|
||||
<span v-tooltip="formatDate(stream.createdAt)">
|
||||
Created
|
||||
<timeago :datetime="stream.createdAt"></timeago>
|
||||
</span>
|
||||
</div>
|
||||
<div class="caption">
|
||||
<span v-tooltip="formatDate(stream.updatedAt)">
|
||||
Updated
|
||||
<timeago :datetime="stream.updatedAt"></timeago>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<h4 class="space-grotesk mt-7 mb-3">Collaborators:</h4>
|
||||
<user-avatar
|
||||
v-for="collab in stream.collaborators"
|
||||
:id="collab.id"
|
||||
:key="collab.id"
|
||||
:size="30"
|
||||
:avatar="collab.avatar"
|
||||
:name="collab.name"
|
||||
class="ml-1"
|
||||
></user-avatar>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-else-if="error" justify="center">
|
||||
<v-col cols="12" sm="12" md="8" lg="9" xl="8" class="pt-10">
|
||||
<error-block :message="error" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
<!-- </v-card> -->
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-else justify="center">
|
||||
<v-col cols="12" class="pt-10">
|
||||
<error-block :message="error" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
<script>
|
||||
import streamBranchesQuery from '@/graphql/streamBranches.gql'
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default {
|
||||
name: 'Details',
|
||||
components: {
|
||||
UserAvatar: () => import('@/components/UserAvatar'),
|
||||
SourceAppAvatar: () => import('@/components/SourceAppAvatar'),
|
||||
NoDataPlaceholder: () => import('@/components/NoDataPlaceholder'),
|
||||
Renderer: () => import('@/components/Renderer'),
|
||||
ErrorBlock: () => import('@/components/ErrorBlock')
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
clearRendererTrigger: 0,
|
||||
error: '',
|
||||
selectedBranch: null
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
stream: {
|
||||
query: streamBranchesQuery,
|
||||
variables() {
|
||||
return {
|
||||
id: this.$route.params.streamId
|
||||
}
|
||||
}
|
||||
},
|
||||
$subscribe: {
|
||||
streamUpdated: {
|
||||
query: gql`
|
||||
subscription($streamId: String!) {
|
||||
streamUpdated(streamId: $streamId)
|
||||
}
|
||||
`,
|
||||
variables() {
|
||||
return {
|
||||
streamId: this.$route.params.streamId
|
||||
}
|
||||
},
|
||||
result() {
|
||||
this.$apollo.queries.stream.refetch()
|
||||
},
|
||||
skip() {
|
||||
return !this.loggedIn
|
||||
}
|
||||
},
|
||||
branchCreated: {
|
||||
query: gql`
|
||||
subscription($streamId: String!) {
|
||||
branchCreated(streamId: $streamId)
|
||||
}
|
||||
`,
|
||||
variables() {
|
||||
return {
|
||||
streamId: this.$route.params.streamId
|
||||
}
|
||||
},
|
||||
result() {
|
||||
this.$apollo.queries.stream.refetch()
|
||||
},
|
||||
skip() {
|
||||
return !this.loggedIn
|
||||
}
|
||||
},
|
||||
branchDeleted: {
|
||||
query: gql`
|
||||
subscription($streamId: String!) {
|
||||
branchDeleted(streamId: $streamId)
|
||||
}
|
||||
`,
|
||||
variables() {
|
||||
return {
|
||||
streamId: this.$route.params.streamId
|
||||
}
|
||||
},
|
||||
result() {
|
||||
this.$apollo.queries.stream.refetch()
|
||||
},
|
||||
skip() {
|
||||
return !this.loggedIn
|
||||
}
|
||||
},
|
||||
commitCreated: {
|
||||
query: gql`
|
||||
subscription($streamId: String!) {
|
||||
commitCreated(streamId: $streamId)
|
||||
}
|
||||
`,
|
||||
variables() {
|
||||
return {
|
||||
streamId: this.$route.params.streamId
|
||||
}
|
||||
},
|
||||
result() {
|
||||
this.$apollo.queries.stream.refetch()
|
||||
},
|
||||
skip() {
|
||||
return !this.loggedIn
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
branches() {
|
||||
return this.stream.branches.items.filter((b) => !b.name.startsWith('globals'))
|
||||
},
|
||||
latestCommit() {
|
||||
if (!this.selectedBranch || this.selectedBranch.commits.items.length === 0) return null
|
||||
return this.selectedBranch.commits.items[0]
|
||||
},
|
||||
latestCommitObjectUrl() {
|
||||
if (!this.latestCommit) return null
|
||||
return `${window.location.origin}/streams/${this.$route.params.streamId}/objects/${this.latestCommit.referencedObject}`
|
||||
},
|
||||
loggedIn() {
|
||||
return localStorage.getItem('uuid') !== null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
stream() {
|
||||
if (!this.stream) return
|
||||
let branchName = 'main'
|
||||
let index = this.branches.findIndex((x) => x.name === branchName)
|
||||
if (index > -1) this.selectedBranch = this.branches[index]
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
hyperlink(text) {
|
||||
var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gi
|
||||
return text.replace(exp, '<a target="_blank" href="$1">$1</a>')
|
||||
},
|
||||
truncate(input, length = 250) {
|
||||
if (!input) return ''
|
||||
if (input.length > length) {
|
||||
return input.substring(0, length) + '...'
|
||||
}
|
||||
return input
|
||||
},
|
||||
formatDate(d) {
|
||||
if (!this.stream) return null
|
||||
let date = new Date(d)
|
||||
let options = { year: 'numeric', month: 'short', day: 'numeric' }
|
||||
|
||||
return date.toLocaleString(undefined, options)
|
||||
},
|
||||
changeBranch() {
|
||||
this.clearRendererTrigger += 42
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -18,17 +18,18 @@
|
||||
</v-list>
|
||||
</v-col>
|
||||
<v-col cols="12" class="" style="height: 40px"></v-col>
|
||||
<v-col cols="12" lg="4" class="pa-0 ma-0" :order="`${$vuetify.breakpoint.lgAndUp ? 'last' : ''}`">
|
||||
|
||||
<v-col cols="12" :lg="loggedIn ? 4 : 12" class="pa-0 ma-0" :order="`${$vuetify.breakpoint.lgAndUp ? 'last' : ''}`">
|
||||
<v-card class="transparent elevation-0">
|
||||
<v-toolbar class="transparent elevation-0">
|
||||
<v-toolbar-title>Latest Active Branches</v-toolbar-title>
|
||||
<v-spacer />
|
||||
</v-toolbar>
|
||||
<v-card-title class="caption" style="margin-top: -30px;">
|
||||
The stream's last three updated branches.
|
||||
The stream's last three updated branches
|
||||
</v-card-title>
|
||||
<v-row class="pa-4 mt-1">
|
||||
<v-col cols="12" md="4" lg="12" v-for="branch in latestBranches" :key="branch.name">
|
||||
<v-col cols="12" sm="4" md="4" :lg="loggedIn ? 12 : 4" v-for="branch in latestBranches" :key="branch.name">
|
||||
<v-card :to="`/streams/${$route.params.streamId}/branches/${branch.name}`">
|
||||
<preview-image
|
||||
:height="120"
|
||||
@@ -56,14 +57,14 @@
|
||||
</v-card>
|
||||
</v-col>
|
||||
|
||||
<v-col cols="12" lg="8" class="pr-2">
|
||||
<v-col cols="12" lg="8" class="pr-2" v-if="loggedIn">
|
||||
<v-card class="transparent elevation-0">
|
||||
<v-toolbar class="transparent elevation-0">
|
||||
<v-toolbar-title>Stream Feed</v-toolbar-title>
|
||||
<v-spacer />
|
||||
</v-toolbar>
|
||||
<v-card-title class="caption" style="margin-top: -30px;">
|
||||
Recent activity log.
|
||||
Recent activity log
|
||||
</v-card-title>
|
||||
</v-card>
|
||||
<div style="margin-top:-42px">
|
||||
|
||||
@@ -30,7 +30,9 @@
|
||||
|
||||
<!-- Top padding hack -->
|
||||
<div style="display: block; height: 65px"></div>
|
||||
|
||||
<div class="px-4 mt-2" v-if="!loggedIn" >
|
||||
<v-btn large block color="primary" to="/authn/login">Log In</v-btn>
|
||||
</div>
|
||||
<!-- Various Stream Details -->
|
||||
<v-card elevation="0" v-if="stream" class="pa-1 mb-0" color="transparent">
|
||||
<v-card-text class="caption">
|
||||
@@ -123,10 +125,10 @@
|
||||
<v-list-item
|
||||
link
|
||||
v-tooltip.bottom="'Create a new branch to help categorise your commits.'"
|
||||
v-if="stream.role!=='stream:reviewer'"
|
||||
v-if="stream.role !== 'stream:reviewer'"
|
||||
>
|
||||
<v-list-item-icon>
|
||||
<v-icon small style="padding-top:10px;">mdi-plus-box</v-icon>
|
||||
<v-icon small style="padding-top: 10px">mdi-plus-box</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>New Branch</v-list-item-title>
|
||||
@@ -143,8 +145,10 @@
|
||||
:to="`/streams/${stream.id}/branches/${branch.name}`"
|
||||
>
|
||||
<v-list-item-icon>
|
||||
<v-icon small style="padding-top:10px;" v-if="branch.name !== 'main'">mdi-source-branch</v-icon>
|
||||
<v-icon small style="padding-top:10px;" v-else>mdi-star</v-icon>
|
||||
<v-icon small style="padding-top: 10px" v-if="branch.name !== 'main'">
|
||||
mdi-source-branch
|
||||
</v-icon>
|
||||
<v-icon small style="padding-top: 10px" v-else>mdi-star</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>
|
||||
@@ -233,7 +237,8 @@
|
||||
<!-- child routes can teleport buttons here -->
|
||||
</portal-target>
|
||||
<v-toolbar-items>
|
||||
<v-btn elevation="0" v-if="stream">
|
||||
<v-btn large color="primary" to="/authn/login" v-if="!loggedIn && stream && !streamNav">Log In</v-btn>
|
||||
<v-btn elevation="0" v-if="loggedIn && stream">
|
||||
<v-icon small class="mr-2">mdi-share-variant</v-icon>
|
||||
<v-icon small class="mr-2 hidden-sm-and-down" v-if="!stream.isPublic">mdi-lock</v-icon>
|
||||
<v-icon small class="mr-2 hidden-sm-and-down" v-else>mdi-lock-open</v-icon>
|
||||
@@ -249,8 +254,8 @@
|
||||
</transition>
|
||||
</v-container>
|
||||
<v-container style="padding-left: 56px" v-else>
|
||||
<error-placeholder :error-type='error.toLowerCase().includes("not found") ? "404" : "access"'>
|
||||
<h2>{{error}}</h2>
|
||||
<error-placeholder :error-type="error.toLowerCase().includes('not found') ? '404' : 'access'">
|
||||
<h2>{{ error }}</h2>
|
||||
</error-placeholder>
|
||||
</v-container>
|
||||
</v-container>
|
||||
@@ -347,6 +352,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
loggedIn() {
|
||||
return localStorage.getItem('uuid') !== null
|
||||
},
|
||||
sortedBranches() {
|
||||
// TODO: group by `/` (for later)
|
||||
if (!this.stream) return
|
||||
@@ -357,7 +365,7 @@ export default {
|
||||
},
|
||||
branchesTotalCount() {
|
||||
if (!this.stream) return 0
|
||||
return this.stream.branches.items.filter(b => b.name !== 'globals').length
|
||||
return this.stream.branches.items.filter((b) => b.name !== 'globals').length
|
||||
},
|
||||
userId() {
|
||||
return localStorage.getItem('uuid')
|
||||
@@ -402,7 +410,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.no-overlay.v-list-item--active::before{
|
||||
opacity: 0 !important;
|
||||
}
|
||||
.no-overlay.v-list-item--active::before {
|
||||
opacity: 0 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user