feat(frontend): various display improvements

This commit is contained in:
Dimitrie Stefanescu
2020-12-20 02:19:54 +02:00
parent efb91aa14e
commit 5ee98e8db6
9 changed files with 195 additions and 180 deletions
+31
View File
@@ -12,6 +12,37 @@
<v-card-text>
{{ branch.description }}
</v-card-text>
</v-card>
<v-card>
<v-expansion-panels flat focusable>
<v-expansion-panel>
<v-expansion-panel-header>
<span>How to use this branch in desktop clients</span>
</v-expansion-panel-header>
<v-expansion-panel-content>
<p class="caption mt-4">
<b>Grasshopper & Dynamo:</b>
Copy and paste this page's url into a text panel and connect
that to the "Stream" input of a receiver component or sender
component.
<b>Senders</b>
will push commits to this branch, whereas
<b>receivers</b>
will always pull the latest commit from this branch.
</p>
<p class="caption">
<b>Other clients:</b>
Select this branch from the UI. You will now be able to either
<b>send</b>
(push commits to), or
<b>receive</b>
the latest commit or a specified one.
</p>
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
</v-card>
<v-card class="pa-4" elevation="0" rounded="lg" color="background2">
<v-subheader class="text-uppercase">
Commits ({{ branch.commits.totalCount }})
</v-subheader>
+32 -35
View File
@@ -39,13 +39,12 @@
<v-expansion-panel-content>
<p class="caption mt-4">
<b>Grasshopper & Dynamo:</b>
Copy and paste this page's url into a text panel and connect
that to the "Stream" input of a receiver component.
Copy and paste this page's url into a text panel and connect that to the "Stream"
input of a receiver component.
</p>
<p class="caption">
<b>Other clients:</b>
Switch to this commit's branch, and then select it from commits
the dropdown.
Switch to this commit's branch, and then select it from commits the dropdown.
</p>
</v-expansion-panel-content>
</v-expansion-panel>
@@ -70,15 +69,15 @@
</v-row>
</template>
<script>
import gql from "graphql-tag"
import SidebarStream from "../components/SidebarStream"
import UserAvatar from "../components/UserAvatar"
import ObjectSpeckleViewer from "../components/ObjectSpeckleViewer"
import streamCommitQuery from "../graphql/commit.gql"
import CommitDialog from "../components/dialogs/CommitDialog"
import gql from 'graphql-tag'
import SidebarStream from '../components/SidebarStream'
import UserAvatar from '../components/UserAvatar'
import ObjectSpeckleViewer from '../components/ObjectSpeckleViewer'
import streamCommitQuery from '../graphql/commit.gql'
import CommitDialog from '../components/dialogs/CommitDialog'
export default {
name: "Commit",
name: 'Commit',
components: { SidebarStream, CommitDialog, UserAvatar, ObjectSpeckleViewer },
data: () => ({}),
apollo: {
@@ -98,43 +97,41 @@ export default {
commitDate() {
if (!this.stream.commit) return null
let date = new Date(this.stream.commit.createdAt)
let options = { year: "numeric", month: "long", day: "numeric" }
let options = { year: 'numeric', month: 'long', day: 'numeric' }
return date.toLocaleString(undefined, options)
},
commitObject() {
return {
speckle_type: "reference",
speckle_type: 'reference',
referencedId: this.stream.commit.referencedObject
}
}
},
methods: {
editCommit() {
this.$refs.commitDialog
.open(this.stream.commit, this.stream.id)
.then((dialog) => {
if (!dialog.result) return
this.$refs.commitDialog.open(this.stream.commit, this.stream.id).then((dialog) => {
if (!dialog.result) return
this.$apollo
.mutate({
mutation: gql`
mutation commitUpdate($myCommit: CommitUpdateInput!) {
commitUpdate(commit: $myCommit)
}
`,
variables: {
myCommit: { ...dialog.commit }
this.$apollo
.mutate({
mutation: gql`
mutation commitUpdate($myCommit: CommitUpdateInput!) {
commitUpdate(commit: $myCommit)
}
})
.then((data) => {
this.$apollo.queries.stream.refetch()
})
.catch((error) => {
// Error
console.error(error)
})
})
`,
variables: {
myCommit: { ...dialog.commit }
}
})
.then((data) => {
this.$apollo.queries.stream.refetch()
})
.catch((error) => {
// Error
console.error(error)
})
})
}
}
}
+33 -41
View File
@@ -2,30 +2,29 @@
<v-container>
<v-row>
<v-col sm="12" lg="3" md="4" xl="2" class="d-none d-md-flex">
<div>
<v-card rounded="lg" class="pa-4" elevation="0" color="transparent">
<server-info-card></server-info-card>
<v-card class="elevation-0" color="transparent">
<v-card-text>
<v-btn
href="https://twitter.com/specklesystems"
target="_blank"
text
small
style="margin-left: -10px"
>
<v-icon small class="mr-2">mdi-twitter</v-icon>
Speckle on Twitter!
</v-btn>
</v-card-text>
</v-card>
</div>
<v-card-text>
<v-btn color="primary" elevation="0" block @click="newStreamDialog = true">
<v-icon small class="mr-1">mdi-plus-box</v-icon>
new stream
</v-btn>
<br />
<v-dialog v-model="newStreamDialog" max-width="500">
<new-stream-dialog :open="newStreamDialog" />
</v-dialog>
<v-btn href="https://twitter.com/specklesystems" target="_blank" text small>
<v-icon small class="mr-2">mdi-twitter</v-icon>
Speckle on Twitter!
</v-btn>
</v-card-text>
</v-card>
</v-col>
<v-col v-if="$apollo.loading" sm="12" md="8" lg="9">
<v-skeleton-loader
type="list-item-two-line, list-item-three-line"
></v-skeleton-loader>
<v-col v-if="$apollo.loading" sm="12" md="8" lg="9" xl="7">
<v-skeleton-loader type="list-item-two-line, list-item-three-line"></v-skeleton-loader>
</v-col>
<v-col v-if="recentActivity && !$apollo.loading" sm="12" md="8" lg="9">
<v-col v-if="recentActivity && !$apollo.loading" sm="12" md="8" lg="9" xl="7">
<v-row>
<v-col class="pt-0">
<v-card class="pa-5" elevation="0" rounded="lg" color="background2">
@@ -65,39 +64,32 @@
</v-container>
</template>
<script>
import ServerInfoCard from "../components/ServerInfoCard"
import FeedStream from "../components/FeedStream"
import FeedCommit from "../components/FeedCommit"
import userFeedQuery from "../graphql/userFeed.gql"
import ServerInfoCard from '../components/ServerInfoCard'
import FeedStream from '../components/FeedStream'
import FeedCommit from '../components/FeedCommit'
import userFeedQuery from '../graphql/userFeed.gql'
import NewStreamDialog from '../components/dialogs/NewStreamDialog'
export default {
name: "Home",
components: { ServerInfoCard, FeedStream, FeedCommit },
name: 'Home',
components: { ServerInfoCard, FeedStream, FeedCommit, NewStreamDialog },
apollo: {
user: {
prefetch: true,
query: userFeedQuery
}
},
data: () => ({ selectedActivity: 0, user: {} }),
data: () => ({ selectedActivity: 0, user: {}, newStreamDialog: false }),
computed: {
recentActivity() {
let activity = []
let activityGrouped = []
if (
this.user.streams &&
this.user.streams.items &&
this.selectedActivity != 2
) {
if (this.user.streams && this.user.streams.items && this.selectedActivity != 2) {
activity.push(...this.user.streams.items)
}
if (
this.user.commits &&
this.user.commits.items &&
this.selectedActivity != 1
) {
if (this.user.commits && this.user.commits.items && this.selectedActivity != 1) {
activity.push(...this.user.commits.items)
}
@@ -114,7 +106,7 @@ export default {
}
if (
group[0].__typename === "CommitCollectionUserNode" &&
group[0].__typename === 'CommitCollectionUserNode' &&
group[0].streamId === activity[i].streamId
) {
group.push(activity[i])
@@ -125,7 +117,7 @@ export default {
streamId: group[0].streamId,
createdAt: group[0].createdAt,
message: group[0].message,
__typename: "CommitCollectionUserNode",
__typename: 'CommitCollectionUserNode',
items: group
})
} else activityGrouped.push(...group)
@@ -141,7 +133,7 @@ export default {
streamId: group[0].streamId,
createdAt: group[0].createdAt,
message: group[0].message,
__typename: "CommitCollectionUserNode",
__typename: 'CommitCollectionUserNode',
items: group
})
} else activityGrouped.push(...group)
+18 -16
View File
@@ -1,16 +1,22 @@
<template>
<v-container>
<v-row>
<v-col cols="3">
<server-info-card></server-info-card>
</v-col>
<v-col cols="9">
<v-sheet rounded="lg" class="pa-15 text-center">
<h1>Page not found _ಥ</h1>
<img :src="'https://robohash.org/' + $route.path + '.png'" />
<p class="ma-10 subtitle-1 font-weight-light">
We can't find the page you're looking for but hey, here's a cool
robot!
<v-row align="center" justify="center">
<v-col cols="12" md="8">
<v-sheet rounded="lg" class="pa-15">
<h1>
Oups. Page not found
<v-icon large>mdi-bug</v-icon>
</h1>
<!-- <v-img src="@/assets/bug.svg" responsive contain max-height="100"/> -->
<p class="subtitle-1 font-weight-light">
Don't worry - you haven't deleted the internet. Here's a bunch of places you might want to go to:
<br />
<br />
<router-link to="/">Home</router-link>
<br />
<router-link to="/streams">Streams</router-link>
<br />
<router-link to="/profile">Your Profile</router-link>
</p>
</v-sheet>
</v-col>
@@ -18,9 +24,5 @@
</v-container>
</template>
<script>
import ServerInfoCard from "../components/ServerInfoCard"
export default {
components: { ServerInfoCard }
}
export default {}
</script>
+8 -10
View File
@@ -4,7 +4,7 @@
<v-col cols="12" sm="12" md="4" lg="3" xl="2">
<user-info-card :user="user"></user-info-card>
</v-col>
<v-col cols="12" sm="12" md="8" lg="9" xl="10">
<v-col cols="12" sm="12" md="8" lg="9" xl="7">
<v-card v-if="user" class="mb-3">
<v-card-text class="body-1">
You have
@@ -16,9 +16,7 @@
commits.
</v-card-text>
</v-card>
<v-alert type="info">
Heads up! The sections below are intended for developers.
</v-alert>
<v-alert type="info">Heads up! The sections below are intended for developers.</v-alert>
<user-access-tokens />
<user-apps />
</v-col>
@@ -26,14 +24,14 @@
</v-container>
</template>
<script>
import gql from "graphql-tag"
import userQuery from "../graphql/user.gql"
import UserInfoCard from "../components/UserInfoCard"
import UserAccessTokens from "../components/UserAccessTokens"
import UserApps from "../components/UserApps"
import gql from 'graphql-tag'
import userQuery from '../graphql/user.gql'
import UserInfoCard from '../components/UserInfoCard'
import UserAccessTokens from '../components/UserAccessTokens'
import UserApps from '../components/UserApps'
export default {
name: "Profile",
name: 'Profile',
components: { UserInfoCard, UserAccessTokens, UserApps },
data: () => ({}),
apollo: {
+6 -6
View File
@@ -24,12 +24,12 @@
</v-container>
</template>
<script>
import userById from "../graphql/userById.gql"
import UserInfoCard from "../components/UserInfoCard"
import ListItemStream from "../components/ListItemStream"
import userById from '../graphql/userById.gql'
import UserInfoCard from '../components/UserInfoCard'
import ListItemStream from '../components/ListItemStream'
export default {
name: "ProfileUser",
name: 'ProfileUser',
components: { UserInfoCard, ListItemStream },
data: () => ({}),
apollo: {
@@ -45,8 +45,8 @@ export default {
computed: {},
created() {
// Move to self profile
if (this.$route.params.userId === localStorage.getItem("uuid")) {
this.$router.replace({ path: "/profile" })
if (this.$route.params.userId === localStorage.getItem('uuid')) {
this.$router.replace({ path: '/profile' })
}
},
methods: {}
+29 -13
View File
@@ -1,31 +1,41 @@
<template>
<v-container>
<v-container v-if="error">
<v-card>
<v-card-title>Something went wrong.</v-card-title>
</v-card>
</v-container>
<v-container v-else>
<v-row v-if="$apollo.loading">
<v-skeleton-loader type="card, article"></v-skeleton-loader>
<v-skeleton-loader type="card, article"></v-skeleton-loader>
<v-col cols="12" sm="12" md="4" lg="3" xl="2">
<v-skeleton-loader type="card, article"></v-skeleton-loader>
</v-col>
<v-col cols="12" sm="12" md="8" lg="9" xl="7">
<v-skeleton-loader type="article, article"></v-skeleton-loader>
</v-col>
</v-row>
<v-row v-if="stream">
<v-col cols="12" sm="12" md="4" lg="3" xl="2">
<sidebar-stream :stream="stream" :user-role="userRole"></sidebar-stream>
<sidebar-stream :stream="stream" :user-role="userRole" @refresh="refresh"></sidebar-stream>
</v-col>
<v-col cols="12" sm="12" md="8" lg="9" xl="10">
<v-col cols="12" sm="12" md="8" lg="9" xl="7">
<router-view :stream="stream" :user-role="userRole"></router-view>
</v-col>
</v-row>
</v-container>
</template>
<script>
import SidebarStream from "../components/SidebarStream"
import streamQuery from "../graphql/stream.gql"
import streamCommitsQuery from "../graphql/streamCommits.gql"
import SidebarStream from '../components/SidebarStream'
import streamQuery from '../graphql/stream.gql'
import streamCommitsQuery from '../graphql/streamCommits.gql'
export default {
name: "Stream",
name: 'Stream',
components: {
SidebarStream
},
data() {
return {
error: null,
dialogDescription: false,
selectedBranch: 0,
stream: {
@@ -53,6 +63,9 @@ export default {
return {
id: this.$route.params.streamId
}
},
error(error) {
this.$router.push({ path: '/error' })
}
},
commits: {
@@ -67,16 +80,19 @@ export default {
},
computed: {
userRole() {
let uuid = localStorage.getItem("uuid")
let uuid = localStorage.getItem('uuid')
if (!uuid) return null
if (this.$apollo.loading) return null
let contrib = this.stream.collaborators.find((u) => u.id === uuid)
if (contrib) return contrib.role.split(":")[1]
if (contrib) return contrib.role.split(':')[1]
else return null
}
},
mounted() {},
methods: {}
methods: {
refresh() {
this.$apollo.queries.stream.refetch()
}
}
}
</script>
<style scoped>
+20 -40
View File
@@ -6,18 +6,14 @@
<v-col v-else sm="12">
<v-card rounded="lg" class="pa-4 mb-4" elevation="0" color="background2">
<v-card-title v-if="!stream.description">Description</v-card-title>
<v-card-text v-if="!stream.description">
No description provided.
</v-card-text>
<v-card-text v-if="!stream.description">No description provided.</v-card-text>
<v-card-text
v-if="stream.description"
class="marked-preview"
v-html="compiledStreamDescription"
></v-card-text>
<v-card-actions v-if="userRole === 'owner'">
<v-btn small @click="dialogDescription = true">
Edit Description
</v-btn>
<v-btn small @click="dialogDescription = true">Edit Description</v-btn>
<v-dialog v-model="dialogDescription">
<stream-description-dialog
:id="stream.id"
@@ -34,26 +30,19 @@
Branches
</v-card-title>
<v-card-text>
Branches allow you to manage parallel versions of data in a single
stream, by organising them within a topic.
Branches allow you to manage parallel versions of data in a single stream, by organising
them within a topic.
</v-card-text>
<v-card-text>
<v-list two-line color="transparent">
<template v-for="item in branches">
<v-list-item
:key="item.id"
:to="`/streams/${stream.id}/branches/${item.name}`"
>
<v-list-item :key="item.id" :to="`/streams/${stream.id}/branches/${item.name}`">
<v-list-item-content>
<v-list-item-title>
<b>{{ item.name }}</b>
</v-list-item-title>
<v-list-item-subtitle>
{{
item.description
? item.description
: "no description provided"
}}
{{ item.description ? item.description : 'no description provided' }}
</v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
@@ -65,26 +54,17 @@
</v-list-item>
</template>
</v-list>
<v-btn
v-if="userRole === 'contributor' || userRole === 'owner'"
small
@click="newBranch"
>
<v-btn v-if="userRole === 'contributor' || userRole === 'owner'" small @click="newBranch">
new branch
</v-btn>
<branch-dialog
ref="branchDialog"
:branches="branches"
></branch-dialog>
<branch-dialog ref="branchDialog" :branches="branches"></branch-dialog>
</v-card-text>
</v-card>
<v-card rounded="lg" class="pa-4 mb-4" elevation="0" color="background2">
<v-card-title>
Latest activity &nbsp;&nbsp;&nbsp;
<span class="font-weight-light ml-2 body-1">
({{ commits.totalCount }} total)
</span>
<span class="font-weight-light ml-2 body-1">({{ commits.totalCount }} total)</span>
</v-card-title>
<v-card-text>All the commits from this stream are below.</v-card-text>
<v-card-text v-if="stream.commits">
@@ -100,16 +80,16 @@
</v-row>
</template>
<script>
import marked from "marked"
import DOMPurify from "dompurify"
import gql from "graphql-tag"
import BranchDialog from "../components/dialogs/BranchDialog"
import StreamDescriptionDialog from "../components/dialogs/StreamDescriptionDialog"
import ListItemCommit from "../components/ListItemCommit"
import streamCommitsQuery from "../graphql/streamCommits.gql"
import marked from 'marked'
import DOMPurify from 'dompurify'
import gql from 'graphql-tag'
import BranchDialog from '../components/dialogs/BranchDialog'
import StreamDescriptionDialog from '../components/dialogs/StreamDescriptionDialog'
import ListItemCommit from '../components/ListItemCommit'
import streamCommitsQuery from '../graphql/streamCommits.gql'
export default {
name: "StreamMain",
name: 'StreamMain',
components: {
BranchDialog,
ListItemCommit,
@@ -144,7 +124,7 @@ export default {
},
computed: {
compiledStreamDescription() {
if (!this.stream.description) return ""
if (!this.stream.description) return ''
let md = marked(this.stream.description)
return DOMPurify.sanitize(md)
},
@@ -154,7 +134,7 @@ export default {
}
},
mounted() {
this.$matomo && this.$matomo.trackPageView("streams/single")
this.$matomo && this.$matomo.trackPageView('streams/single')
},
methods: {
closeDescription(newDescription) {
@@ -164,7 +144,7 @@ export default {
newBranch() {
this.$refs.branchDialog.open().then((dialog) => {
if (!dialog.result) return
this.$apollo
.mutate({
mutation: gql`
+18 -19
View File
@@ -5,26 +5,24 @@
<v-card rounded="lg" class="pa-5" elevation="0" color="background">
<v-card-title>Streams</v-card-title>
<v-card-text>
You have {{ streams.totalCount }} stream{{
streams.totalCount == 1 ? `` : `s`
}}
You have {{ streams.totalCount }} stream{{ streams.totalCount == 1 ? `` : `s` }}
in total.
</v-card-text>
<v-card-actions>
<v-btn color="primary" elevation="0" block @click="newStream">
<v-btn color="primary" elevation="0" block @click="newStreamDialog = true">
<v-icon small class="mr-1">mdi-plus-box</v-icon>
new stream
</v-btn>
</v-card-actions>
<stream-dialog ref="streamDialog"></stream-dialog>
<v-dialog v-model="newStreamDialog" max-width="500">
<new-stream-dialog :open="newStreamDialog" />
</v-dialog>
</v-card>
</v-col>
<v-col cols="12" sm="12" md="8" lg="9">
<v-col cols="12" sm="12" md="8" lg="9" xl="7">
<v-card class="mt-4" elevation="0" color="transparent">
<div v-if="$apollo.loading">
<v-skeleton-loader
type="card, article, article"
></v-skeleton-loader>
<v-skeleton-loader type="card, article, article"></v-skeleton-loader>
</div>
<v-card-text v-if="streams && streams.items">
<div v-for="(stream, i) in streams.items" :key="i">
@@ -44,29 +42,30 @@
</v-container>
</template>
<script>
import gql from "graphql-tag"
import ListItemStream from "../components/ListItemStream"
import StreamDialog from "../components/dialogs/StreamDialog"
import streamsQuery from "../graphql/streams.gql"
import InfiniteLoading from "vue-infinite-loading"
import gql from 'graphql-tag'
import ListItemStream from '../components/ListItemStream'
import NewStreamDialog from '../components/dialogs/NewStreamDialog'
import streamsQuery from '../graphql/streams.gql'
import InfiniteLoading from 'vue-infinite-loading'
export default {
name: "Streams",
components: { ListItemStream, StreamDialog, InfiniteLoading },
name: 'Streams',
components: { ListItemStream, NewStreamDialog, InfiniteLoading },
apollo: {
streams: {
prefetch: true,
query: streamsQuery,
fetchPolicy: "cache-and-network" //https://www.apollographql.com/docs/react/data/queries/
fetchPolicy: 'cache-and-network' //https://www.apollographql.com/docs/react/data/queries/
}
},
data: () => ({
streams: []
streams: [],
newStreamDialog: false
}),
computed: {},
watch: {},
mounted() {
this.$matomo && this.$matomo.trackPageView("streams")
this.$matomo && this.$matomo.trackPageView('streams')
},
methods: {
infiniteHandler($state) {