Fixed all ESLint issues in frontend

This commit is contained in:
Fabians
2022-04-01 18:24:51 +03:00
parent 92f44e7e17
commit 96fded5e52
63 changed files with 306 additions and 1374 deletions
+1 -4
View File
@@ -27,10 +27,7 @@ const config = {
}
}
],
plugins: ['vue'],
rules: {
'no-console': 1
}
plugins: ['vue']
}
module.exports = config
+2
View File
@@ -7,6 +7,8 @@ export default {
mounted() {
let mixpanelId = this.$mixpanelId()
this.$mixpanel.register({
// Unfortunately we can't replace this to camelCase, because that will break metrics
// eslint-disable-next-line camelcase
server_id: this.$mixpanelServerId(),
hostApp: 'web-embed'
})
+3 -3
View File
@@ -58,19 +58,19 @@
</v-btn>
</div>
<div style="position: fixed" class="no-scrollbar">
<viewer @load-progress="captureProgress" />
<speckle-viewer @load-progress="captureProgress" />
</div>
</v-app>
</template>
<script>
import Viewer from '@/main/components/common/Viewer.vue'
import SpeckleViewer from '@/main/components/common/SpeckleViewer.vue'
import { getCommit, getLatestBranchCommit, getServerInfo } from '@/embed/speckleUtils'
export default {
name: 'EmbedViewer',
components: {
Viewer
SpeckleViewer
},
filters: {
truncate: function (str, n = 20) {
@@ -1,4 +1,5 @@
<template>
<!-- eslint-disable vue/no-v-html -->
<v-timeline-item medium>
<template #icon>
<user-avatar v-if="user" :id="user.id" :avatar="user.avatar" :name="user.name" />
@@ -256,13 +257,6 @@
>
SEE ALL {{ activityGroup.length }} COMMITS
</router-link>
<!-- <div class="mt-3 body-1">
<div
v-for="activityItem in activityGroup"
:key="activityItem.time"
v-html="updatedDescription(activityItem)"
></div>
</div> -->
</v-card-text>
</v-col>
@@ -297,7 +291,12 @@ import gql from 'graphql-tag'
export default {
components: { UserAvatar, SourceAppAvatar, PreviewImage, UserPill },
props: ['activityGroup'],
props: {
activityGroup: {
type: Array,
default: () => []
}
},
apollo: {
you: {
query: gql`
@@ -540,6 +539,10 @@ export default {
}
},
methods: {
/**
* TODO: no bueno, needs refactoring. As eslint warns us - using v-html can lead to XSS attacks.
* Additionally I don't see why this can't be done with Vue templates
*/
updatedDescription(activity) {
//CREATED
if (activity.actionType === 'stream_create') {
@@ -42,13 +42,13 @@
}}
</v-icon>
<v-select
v-tooltip="'Change role'"
:value="selfUser.role"
:items="roles"
dense
filled
rounded
hide-details
v-tooltip="'Change role'"
@change="(e) => $emit('change-role', { user, role: e })"
></v-select>
<!-- </v-col>
@@ -31,8 +31,25 @@
</template>
<script>
export default {
name: 'Strategies',
props: ['strategies', 'appId', 'challenge', 'suuid'],
name: 'AuthStrategies',
props: {
strategies: {
type: Array,
default: () => []
},
appId: {
type: String,
default: () => null
},
challenge: {
type: String,
default: () => null
},
suuid: {
type: String,
default: () => null
}
},
data() {
return {
inviteId: null
@@ -16,7 +16,7 @@
, empowering your design and construction data.
</span>
</v-card-text>
<div class="">
<div>
<v-card-text class="text-h6 font-weight-regular">
Speckle helps leading AEC companies freely exchange data between software silos
and automate design and delivery processes:
@@ -30,7 +30,6 @@
</template>
<script>
export default {
name: 'Blurb',
props: ['serverInfo']
name: 'LoginBlurb'
}
</script>
@@ -2,7 +2,7 @@
<v-snackbar v-model="snack" app bottom color="primary">
{{ text }}
<template #action="{}">
<v-btn v-if="actionName" :to="to" @click.append="snack = false">
<v-btn v-if="actionName" :to="to" @click="snack = false">
{{ actionName }}
</v-btn>
<v-btn small icon @click="snack = false">
@@ -12,6 +12,7 @@ import { Viewer } from '@speckle/viewer'
import throttle from 'lodash/throttle'
export default {
name: 'SpeckleViewer',
data() {
return {}
},
@@ -40,14 +40,14 @@
</v-card-text>
<div style="position: absolute; top: 10px; left: 12px">
<v-chip
:to="`/streams/${stream.id}/comments`"
v-if="stream.commentCount !== 0"
small
class="caption primary"
dark
v-tooltip="
`${stream.commentCount} comment${stream.commentCount === 1 ? '' : 's'}`
"
:to="`/streams/${stream.id}/comments`"
small
class="caption primary"
dark
>
<v-icon x-small class="mr-1">mdi-comment-outline</v-icon>
{{ stream.commentCount }}
@@ -73,15 +73,12 @@
import gql from 'graphql-tag'
export default {
name: 'Timeline',
name: 'FeedTimeline',
components: {
InfiniteLoading: () => import('vue-infinite-loading'),
ListItemActivity: () => import('@/main/components/activity/ListItemActivity'),
NoDataPlaceholder: () => import('@/main/components/common/NoDataPlaceholder')
},
props: {
type: String
},
data() {
return {
newStreamDialog: 0,
@@ -32,7 +32,12 @@
</v-toolbar>
<div v-for="post in posts" :key="post.uuid">
<v-hover v-slot="{ hover }">
<v-card class="my-4">
<v-card
class="my-4"
:elevation="hover ? 16 : 2"
:href="post.url"
:target="'_blank'"
>
<v-img
:src="post.feature_image"
height="100"
@@ -1,616 +0,0 @@
<template>
<v-timeline-item medium>
<template #icon>
<user-avatar v-if="user" :id="user.id" :avatar="user.avatar" :name="user.name" />
</template>
<v-row class="pt-1 timeline-activity">
<v-col cols="12" class="mb-0 pb-0">
<div v-if="user && you && stream" class="body-2">
&nbsp;
<router-link :to="'/profile/' + user.id">
{{ userName }}
</router-link>
<span>&nbsp;{{ lastActivityBrief.captionText }} &nbsp;</span>
<span v-if="stream">
<router-link :to="'/streams/' + stream.id">{{ stream.name }}</router-link>
</span>
<timeago :datetime="lastActivity.time" class="font-italic ma-1"></timeago>
</div>
</v-col>
<v-col cols="12">
<!-- STREAM PERMISSIONS -->
<v-card
v-if="lastActivity.actionType.includes('stream_permissions') && stream"
class="activity-card"
:flat="$vuetify.theme.dark"
>
<v-card-text class="pa-5 body-1">
<v-container>
<v-row
v-for="activityItem in activityGroup"
:key="activityItem.time"
class="align-center"
>
<v-col cols="12" md="10">
<user-pill
class="mr-3"
:user-id="activityItem.info.targetUser"
:color="
lastActivity.actionType === 'stream_permissions_add'
? 'success'
: 'error'
"
></user-pill>
<span
v-if="$vuetify.breakpoint.smAndUp"
class="mr-3 body-2 font-italic"
>
{{
lastActivity.actionType === 'stream_permissions_add'
? 'user added as'
: 'user removed'
}}
</span>
<v-chip v-if="activityItem.info.role" small outlined class="my-2">
<v-icon small left>mdi-account-key-outline</v-icon>
{{ activityItem.info.role.split(':')[1] }}
</v-chip>
</v-col>
<v-col v-if="$vuetify.breakpoint.mdAndUp" cols="2" class="text-right">
<v-btn
v-if="
activityItem.info.targetUser &&
activityItem.actionType === `stream_permissions_add`
"
text
outlined
small
:to="'/profile/' + activityItem.info.targetUser"
color="primary"
>
view
</v-btn>
</v-col>
</v-row>
</v-container>
</v-card-text>
</v-card>
<!-- STREAM -->
<v-card
v-else-if="lastActivity.resourceType === 'stream' && stream"
class="activity-card"
:flat="$vuetify.theme.dark"
>
<v-card-text class="pa-5 body-1">
<v-container>
<v-row class="align-center">
<router-link :to="url" class="title">
<v-icon color="primary" small>mdi-folder</v-icon>
{{ stream.name }}
</router-link>
<span class="ml-3 body-2 font-italic">
{{ lastActivityBrief.actionText }}
</span>
<v-spacer />
<v-btn
v-if="
(lastActivity.actionType === `stream_create` ||
lastActivity.actionType === `stream_update`) &&
$vuetify.breakpoint.mdAndUp
"
text
outlined
small
exact
:to="url"
color="primary"
>
view
</v-btn>
</v-row>
</v-container>
<div class="mt-3">
<div
v-for="activityItem in activityGroup"
:key="activityItem.time"
v-html="updatedDescription(activityItem)"
></div>
</div>
</v-card-text>
<v-card-actions class="pt-0">
<div>
<v-btn
v-tooltip="
stream.branches.totalCount +
' branch' +
(stream.branches.totalCount === 1 ? '' : 'es')
"
color="primary"
text
class="px-0 ml-3"
small
:to="'/streams/' + stream.id + '/branches'"
>
<v-icon small class="mr-2 float-left">mdi-source-branch</v-icon>
{{ stream.branches.totalCount }}
</v-btn>
<v-btn
v-tooltip="
stream.commits.totalCount +
' commit' +
(stream.commits.totalCount === 1 ? '' : 's')
"
color="primary"
text
class="px-0 ml-3"
small
:to="'/streams/' + stream.id + '/branches/main'"
>
<v-icon small class="mr-2 float-left">mdi-source-commit</v-icon>
{{ stream.commits.totalCount }}
</v-btn>
<v-chip small outlined class="ml-3 no-hover">
<v-icon small left>mdi-account-key-outline</v-icon>
{{ stream.role.split(':')[1] }}
</v-chip>
<span class="caption mb-2 ml-3 font-italic">
Updated
<timeago :datetime="stream.updatedAt"></timeago>
</span>
</div>
</v-card-actions>
</v-card>
<!-- BRANCHES -->
<v-card
v-else-if="lastActivity.resourceType === 'branch'"
class="activity-card"
:flat="$vuetify.theme.dark"
>
<v-card-text class="pa-5 body-1">
<v-chip :to="url" :color="lastActivityBrief.color">
<v-icon small class="mr-2 float-left" light>
{{ lastActivityBrief.icon }}
</v-icon>
{{ branchName }}
</v-chip>
<span class="ml-3 body-2 font-italic">
{{ lastActivityBrief.actionText }}
</span>
<div class="mt-3">
<div
v-for="activityItem in activityGroup"
:key="activityItem.time"
v-html="updatedDescription(activityItem)"
></div>
</div>
</v-card-text>
</v-card>
<!-- COMMITS -->
<v-card
v-else-if="lastActivity.resourceType === 'commit' && commit"
class="activity-card"
:flat="$vuetify.theme.dark"
>
<v-container>
<v-row class="align-center">
<v-col sm="10" cols="12">
<v-card-text class="pa-5">
<div>
<v-chip :to="url" :color="lastActivityBrief.color">
<v-icon small class="mr-2 float-left" light>
{{ lastActivityBrief.icon }}
</v-icon>
{{ lastActivity.resourceId }}
</v-chip>
<span class="mx-3 body-2 font-italic">
{{ lastActivityBrief.actionText }}
</span>
<span v-if="lastActivity.actionType !== 'commit_delete' && commit">
<v-chip
:to="`/streams/${lastActivity.streamId}/branches/${commit.branchName}`"
small
color="primary"
>
<v-icon v-if="commit" small class="float-left" light>
mdi-source-branch
</v-icon>
{{ commit.branchName }}
</v-chip>
<span v-if="lastActivity.actionType === 'commit_create'">
<span class="mx-3 body-2 font-italic">from</span>
<source-app-avatar
:application-name="commit.sourceApplication"
/>
</span>
<span v-if="lastActivity.actionType === 'commit_receive'">
<span class="mx-3 body-2 font-italic">in</span>
<source-app-avatar
:application-name="lastActivity.info.sourceApplication"
/>
</span>
</span>
<span v-if="lastActivity.actionType !== 'commit_delete' && !commit">
[commit deleted]
</span>
</div>
<div
v-if="lastActivity.info.commit && lastActivity.info.commit.message"
class="mt-3 body-1"
>
{{ lastActivity.info.commit.message }}
</div>
<!-- NOTE: currently assumes all commits are on the same branch
can't easily group them by branch as that info is not in the activity stream -->
<router-link
v-if="activityGroup.length > 1"
:to="`/streams/${lastActivity.streamId}/branches/${commit.branchName}`"
class="mt-5 caption"
>
SEE ALL {{ activityGroup.length }} COMMITS
</router-link>
<!-- <div class="mt-3 body-1">
<div
v-for="activityItem in activityGroup"
:key="activityItem.time"
v-html="updatedDescription(activityItem)"
></div>
</div> -->
</v-card-text>
</v-col>
<v-col sm="2" cols="12">
<v-hover
v-if="lastActivity.actionType !== 'commit_delete' && commit"
v-slot="{ hover }"
>
<router-link :to="url">
<preview-image
:url="`/preview/${lastActivity.streamId}/commits/${lastActivity.resourceId}`"
:height="100"
:color="hover"
/>
</router-link>
</v-hover>
</v-col>
</v-row>
</v-container>
</v-card>
</v-col>
</v-row>
</v-timeline-item>
</template>
<script>
import UserAvatar from '@/main/components/common/UserAvatar'
import UserPill from '@/main/components/activity/UserPill'
import SourceAppAvatar from '@/main/components/common/SourceAppAvatar'
import PreviewImage from '@/main/components/common/PreviewImage'
import gql from 'graphql-tag'
export default {
components: { UserAvatar, SourceAppAvatar, PreviewImage, UserPill },
props: ['activityGroup'],
apollo: {
you: {
query: gql`
query {
user {
id
name
}
}
`,
update: (data) => data.user
},
user: {
query: gql`
query ($id: String) {
user(id: $id) {
name
avatar
id
}
}
`,
variables() {
return {
id: this.lastActivity.userId
}
}
},
stream: {
query: gql`
query ($id: String!) {
stream(id: $id) {
id
name
updatedAt
role
branches {
totalCount
}
commits {
totalCount
}
}
}
`,
variables() {
return {
id: this.lastActivity.streamId
}
}
},
branch: {
query: gql`
query ($id: String!, $branchName: String!) {
stream(id: $id) {
id
branch(name: $branchName) {
id
}
}
}
`,
variables() {
return {
id: this.lastActivity.streamId,
branchName: this.branchName
}
},
skip() {
return this.lastActivity.resourceType !== 'branch'
},
update: (data) => data.stream.branch
},
commit: {
query: gql`
query ($id: String!, $commitId: String!) {
stream(id: $id) {
id
commit(id: $commitId) {
branchName
sourceApplication
id
}
}
}
`,
variables() {
return {
id: this.lastActivity.streamId,
commitId: this.lastActivity.resourceId
}
},
skip() {
return this.lastActivity.resourceType !== 'commit'
},
update: (data) => data.stream.commit
}
},
computed: {
lastActivity() {
return this.activityGroup[0]
},
userName() {
return this.user.id === this.you.id ? 'You' : this.user.name
},
captionText() {
return this.lastActivity.actionType.split('_').pop()
},
branchName() {
if (this.lastActivity.info?.branch) return this.lastActivity.info.branch.name
else if (this.lastActivity.info?.new?.name) return this.lastActivity.info.new.name
else if (this.lastActivity.info?.old?.name) return this.lastActivity.info.old.name
return ''
},
url() {
switch (this.lastActivity.resourceType) {
case 'stream':
return this.stream ? `/streams/${this.lastActivity.streamId}` : null
case 'branch':
return this.branch
? `/streams/${this.lastActivity.streamId}/branches/${this.branchName}`
: null
case 'commit':
return this.commit
? `/streams/${this.lastActivity.streamId}/commits/${this.lastActivity.resourceId}`
: null
case 'user':
return '/profile'
default:
return null
}
},
lastActivityBrief() {
switch (this.lastActivity.actionType) {
case 'stream_create':
return {
captionText: 'created',
actionText: 'new stream'
}
case 'stream_update':
return {
captionText: 'updated',
actionText: 'stream updated'
}
case 'stream_delete': //not used
return {
captionText: 'deleted'
}
case 'stream_permissions_add':
return {
captionText: `added ${
this.activityGroup.length === 1
? 'a user'
: this.activityGroup.length + ' users'
} to`
}
case 'stream_permissions_remove':
return {
captionText: `removed ${
this.activityGroup.length === 1
? 'a user'
: this.activityGroup.length + ' users'
} from`
}
case 'branch_create':
return {
icon: 'mdi-source-branch-plus',
captionText: 'created a branch in',
actionText: 'new branch',
color: 'success'
}
case 'branch_delete':
return {
icon: 'mdi-source-branch-minus',
captionText: 'deleted a branch from',
actionText: 'branch deleted',
color: 'error'
}
case 'branch_update':
return {
icon: 'mdi-source-branch-sync',
captionText: 'updated a branch in',
actionText: 'branch updated in',
color: 'primary'
}
case 'commit_create':
return {
icon: 'mdi-timeline-plus-outline',
captionText: `pushed ${this.activityGroup.length} commit${
this.activityGroup.length === 0 ? '' : 's'
} to`,
actionText: 'new commit in',
color: 'success'
}
case 'commit_update':
return {
icon: 'mdi-timeline-text-outline',
captionText: 'updated a commit in',
actionText: 'commit updated in',
color: 'primary'
}
case 'commit_receive':
return {
icon: 'mdi-source-branch-sync',
captionText: 'received',
actionText: 'commit received from',
color: 'primary'
}
case 'commit_delete':
return {
icon: 'mdi-timeline-remove-outline',
captionText: 'deleted a commit from',
color: 'error',
actionText: 'commit deleted'
}
case 'user_create':
return {
icon: 'mdi-account-plus',
captionText: 'created'
}
case 'user_update':
return {
icon: 'mdi-account-convert',
captionText: 'updated'
}
case 'user_delete':
return {
icon: 'mdi-account-remove',
captionText: 'deleted'
}
default:
return {
icon: 'mdi-box',
name: this.lastActivity.actionType
}
}
}
},
methods: {
updatedDescription(activity) {
//CREATED
if (activity.actionType === 'stream_create') {
return activity.info?.stream?.description
? this.truncate(this.lastActivity.info.stream.description, 50)
: ''
} else if (activity.actionType === 'branch_create') {
return this.activity?.info?.branch?.description
? this.truncate(this.lastActivity.info.branch.description, 50)
: ''
}
//UPDATED
let changes = ''
if (activity.info.new) {
for (const [key] of Object.entries(activity.info.new)) {
if (
activity.info.old[key] !== undefined &&
activity.info.new[key] !== activity.info.old[key]
) {
if (key === 'name')
changes +=
'<p>✏️ Renamed from <i><del>' +
activity.info.old[key] +
'</del></i> to <i>' +
activity.info.new[key] +
'</i></p>'
if (key === 'description') {
let oldDesc = activity.info.old[key] ? activity.info.old[key] : 'empty'
changes +=
'<p>📋 Description changed from <i><del>' +
this.truncate(oldDesc) +
'</del></i> to <i>' +
this.truncate(activity.info.new[key]) +
'</ib></p>'
}
if (key === 'message') {
let oldDesc = activity.info.old[key] ? activity.info.old[key] : 'empty'
changes +=
'<p>📋 Message changed from <i><del>' +
this.truncate(oldDesc) +
'</del></i> to <i>' +
this.truncate(activity.info.new[key]) +
'</ib></p>'
}
if (key === 'isPublic' && activity.info.new[key])
changes += '<p>👀 Stream is now <i>public</i></p>'
if (key === 'isPublic' && !activity.info.new[key])
changes += '<p>👀 Stream is now <i>private</i></p>'
}
}
}
return changes
},
truncate(input, length = 25) {
if (!input) return ''
if (input.length > length) {
return input.substring(0, length) + '...'
}
return input
}
}
}
</script>
<style>
.activity-card p {
margin: 0 !important;
}
.timeline-activity a {
text-decoration: none;
}
</style>
@@ -1,616 +0,0 @@
<template>
<v-timeline-item medium>
<template #icon>
<user-avatar v-if="user" :id="user.id" :avatar="user.avatar" :name="user.name" />
</template>
<v-row class="pt-1 timeline-activity">
<v-col cols="12" class="mb-0 pb-0">
<div v-if="user && you && stream" class="body-2">
&nbsp;
<router-link :to="'/profile/' + user.id">
{{ userName }}
</router-link>
<span>&nbsp;{{ lastActivityBrief.captionText }} &nbsp;</span>
<span v-if="stream">
<router-link :to="'/streams/' + stream.id">{{ stream.name }}</router-link>
</span>
<timeago :datetime="lastActivity.time" class="font-italic ma-1"></timeago>
</div>
</v-col>
<v-col cols="12">
<!-- STREAM PERMISSIONS -->
<v-card
v-if="lastActivity.actionType.includes('stream_permissions') && stream"
class="activity-card"
:flat="$vuetify.theme.dark"
>
<v-card-text class="xxxpa-5 body-1">
<v-container>
<v-row
v-for="activityItem in activityGroup"
:key="activityItem.time"
class="align-center"
>
<v-col cols="12" md="10">
<user-pill
class="mr-3"
:user-id="activityItem.info.targetUser"
:color="
lastActivity.actionType === 'stream_permissions_add'
? 'success'
: 'error'
"
></user-pill>
<span
v-if="$vuetify.breakpoint.smAndUp"
class="mr-3 body-2 font-italic"
>
{{
lastActivity.actionType === 'stream_permissions_add'
? 'user added as'
: 'user removed'
}}
</span>
<v-chip v-if="activityItem.info.role" small outlined class="my-2">
<v-icon small left>mdi-account-key-outline</v-icon>
{{ activityItem.info.role.split(':')[1] }}
</v-chip>
</v-col>
<v-col v-if="$vuetify.breakpoint.mdAndUp" cols="2" class="text-right">
<v-btn
v-if="
activityItem.info.targetUser &&
activityItem.actionType === `stream_permissions_add`
"
text
outlined
small
:to="'/profile/' + activityItem.info.targetUser"
color="primary"
>
view
</v-btn>
</v-col>
</v-row>
</v-container>
</v-card-text>
</v-card>
<!-- STREAM -->
<v-card
v-else-if="lastActivity.resourceType === 'stream' && stream"
class="activity-card"
:flat="$vuetify.theme.dark"
>
<v-card-text class="xxxpa-5 body-1">
<v-container>
<v-row class="align-center">
<router-link :to="url" class="title">
<v-icon color="primary" small>mdi-folder</v-icon>
{{ stream.name }}
</router-link>
<span class="ml-3 caption font-italic">
{{ lastActivityBrief.actionText }}
</span>
<v-spacer />
<v-btn
v-if="
(lastActivity.actionType === `stream_create` ||
lastActivity.actionType === `stream_update`) &&
$vuetify.breakpoint.mdAndUp
"
text
outlined
small
exact
:to="url"
color="primary"
>
view
</v-btn>
</v-row>
</v-container>
<div class="mt-3">
<div
v-for="activityItem in activityGroup"
:key="activityItem.time"
v-html="updatedDescription(activityItem)"
></div>
</div>
</v-card-text>
<v-card-actions class="pt-0">
<div>
<v-btn
v-tooltip="
stream.branches.totalCount +
' branch' +
(stream.branches.totalCount === 1 ? '' : 'es')
"
color="primary"
text
class="px-0 ml-3"
small
:to="'/streams/' + stream.id + '/branches'"
>
<v-icon small class="mr-2 float-left">mdi-source-branch</v-icon>
{{ stream.branches.totalCount }}
</v-btn>
<v-btn
v-tooltip="
stream.commits.totalCount +
' commit' +
(stream.commits.totalCount === 1 ? '' : 's')
"
color="primary"
text
class="px-0 ml-3"
small
:to="'/streams/' + stream.id + '/branches/main'"
>
<v-icon small class="mr-2 float-left">mdi-source-commit</v-icon>
{{ stream.commits.totalCount }}
</v-btn>
<v-chip small outlined class="ml-3 no-hover">
<v-icon small left>mdi-account-key-outline</v-icon>
{{ stream.role.split(':')[1] }}
</v-chip>
<span class="caption mb-2 ml-3 font-italic">
Updated
<timeago :datetime="stream.updatedAt"></timeago>
</span>
</div>
</v-card-actions>
</v-card>
<!-- BRANCHES -->
<v-card
v-else-if="lastActivity.resourceType === 'branch'"
class="activity-card"
:flat="$vuetify.theme.dark"
>
<v-card-text class="xxxpa-5 body-1">
<v-chip :to="url" :color="lastActivityBrief.color">
<v-icon small class="mr-2 float-left" light>
{{ lastActivityBrief.icon }}
</v-icon>
{{ branchName }}
</v-chip>
<span class="ml-3 body-2 font-italic">
{{ lastActivityBrief.actionText }}
</span>
<div class="mt-3">
<div
v-for="activityItem in activityGroup"
:key="activityItem.time"
v-html="updatedDescription(activityItem)"
></div>
</div>
</v-card-text>
</v-card>
<!-- COMMITS -->
<v-card
v-else-if="lastActivity.resourceType === 'commit' && commit"
class="activity-card"
:flat="$vuetify.theme.dark"
>
<v-container>
<v-row class="align-center">
<v-col sm="10" cols="12">
<v-card-text class="pa-5">
<div>
<v-chip :to="url" :color="lastActivityBrief.color">
<v-icon small class="mr-2 float-left" light>
{{ lastActivityBrief.icon }}
</v-icon>
{{ lastActivity.resourceId }}
</v-chip>
<span class="mx-3 body-2 font-italic">
{{ lastActivityBrief.actionText }}
</span>
<span v-if="lastActivity.actionType !== 'commit_delete' && commit">
<v-chip
:to="`/streams/${lastActivity.streamId}/branches/${commit.branchName}`"
small
color="primary"
>
<v-icon v-if="commit" small class="float-left" light>
mdi-source-branch
</v-icon>
{{ commit.branchName }}
</v-chip>
<span v-if="lastActivity.actionType === 'commit_create'">
<span class="mx-3 body-2 font-italic">from</span>
<source-app-avatar
:application-name="commit.sourceApplication"
/>
</span>
<span v-if="lastActivity.actionType === 'commit_receive'">
<span class="mx-3 body-2 font-italic">in</span>
<source-app-avatar
:application-name="lastActivity.info.sourceApplication"
/>
</span>
</span>
<span v-if="lastActivity.actionType !== 'commit_delete' && !commit">
[commit deleted]
</span>
</div>
<div
v-if="lastActivity.info.commit && lastActivity.info.commit.message"
class="mt-3 body-1"
>
{{ lastActivity.info.commit.message }}
</div>
<!-- NOTE: currently assumes all commits are on the same branch
can't easily group them by branch as that info is not in the activity stream -->
<router-link
v-if="activityGroup.length > 1"
:to="`/streams/${lastActivity.streamId}/branches/${commit.branchName}`"
class="mt-5 caption"
>
SEE ALL {{ activityGroup.length }} COMMITS
</router-link>
<!-- <div class="mt-3 body-1">
<div
v-for="activityItem in activityGroup"
:key="activityItem.time"
v-html="updatedDescription(activityItem)"
></div>
</div> -->
</v-card-text>
</v-col>
<v-col sm="2" cols="12">
<v-hover
v-if="lastActivity.actionType !== 'commit_delete' && commit"
v-slot="{ hover }"
>
<router-link :to="url">
<preview-image
:url="`/preview/${lastActivity.streamId}/commits/${lastActivity.resourceId}`"
:height="100"
:color="hover"
/>
</router-link>
</v-hover>
</v-col>
</v-row>
</v-container>
</v-card>
</v-col>
</v-row>
</v-timeline-item>
</template>
<script>
import UserAvatar from '@/main/components/common/UserAvatar'
import UserPill from '@/main/components/activity/UserPill'
import SourceAppAvatar from '@/main/components/common/SourceAppAvatar'
import PreviewImage from '@/main/components/common/PreviewImage'
import gql from 'graphql-tag'
export default {
components: { UserAvatar, SourceAppAvatar, PreviewImage, UserPill },
props: ['activityGroup'],
apollo: {
you: {
query: gql`
query {
user {
id
name
}
}
`,
update: (data) => data.user
},
user: {
query: gql`
query ($id: String) {
user(id: $id) {
name
avatar
id
}
}
`,
variables() {
return {
id: this.lastActivity.userId
}
}
},
stream: {
query: gql`
query ($id: String!) {
stream(id: $id) {
id
name
updatedAt
role
branches {
totalCount
}
commits {
totalCount
}
}
}
`,
variables() {
return {
id: this.lastActivity.streamId
}
}
},
branch: {
query: gql`
query ($id: String!, $branchName: String!) {
stream(id: $id) {
id
branch(name: $branchName) {
id
}
}
}
`,
variables() {
return {
id: this.lastActivity.streamId,
branchName: this.branchName
}
},
skip() {
return this.lastActivity.resourceType !== 'branch'
},
update: (data) => data.stream.branch
},
commit: {
query: gql`
query ($id: String!, $commitId: String!) {
stream(id: $id) {
id
commit(id: $commitId) {
branchName
sourceApplication
id
}
}
}
`,
variables() {
return {
id: this.lastActivity.streamId,
commitId: this.lastActivity.resourceId
}
},
skip() {
return this.lastActivity.resourceType !== 'commit'
},
update: (data) => data.stream.commit
}
},
computed: {
lastActivity() {
return this.activityGroup[0]
},
userName() {
return this.user.id === this.you.id ? 'You' : this.user.name
},
captionText() {
return this.lastActivity.actionType.split('_').pop()
},
branchName() {
if (this.lastActivity.info?.branch) return this.lastActivity.info.branch.name
else if (this.lastActivity.info?.new?.name) return this.lastActivity.info.new.name
else if (this.lastActivity.info?.old?.name) return this.lastActivity.info.old.name
return ''
},
url() {
switch (this.lastActivity.resourceType) {
case 'stream':
return this.stream ? `/streams/${this.lastActivity.streamId}` : null
case 'branch':
return this.branch
? `/streams/${this.lastActivity.streamId}/branches/${this.branchName}`
: null
case 'commit':
return this.commit
? `/streams/${this.lastActivity.streamId}/commits/${this.lastActivity.resourceId}`
: null
case 'user':
return '/profile'
default:
return null
}
},
lastActivityBrief() {
switch (this.lastActivity.actionType) {
case 'stream_create':
return {
captionText: 'created',
actionText: 'new stream'
}
case 'stream_update':
return {
captionText: 'updated',
actionText: 'stream updated'
}
case 'stream_delete': //not used
return {
captionText: 'deleted'
}
case 'stream_permissions_add':
return {
captionText: `added ${
this.activityGroup.length === 1
? 'a user'
: this.activityGroup.length + ' users'
} to`
}
case 'stream_permissions_remove':
return {
captionText: `removed ${
this.activityGroup.length === 1
? 'a user'
: this.activityGroup.length + ' users'
} from`
}
case 'branch_create':
return {
icon: 'mdi-source-branch-plus',
captionText: 'created a branch in',
actionText: 'new branch',
color: 'success'
}
case 'branch_delete':
return {
icon: 'mdi-source-branch-minus',
captionText: 'deleted a branch from',
actionText: 'branch deleted',
color: 'error'
}
case 'branch_update':
return {
icon: 'mdi-source-branch-sync',
captionText: 'updated a branch in',
actionText: 'branch updated in',
color: 'primary'
}
case 'commit_create':
return {
icon: 'mdi-timeline-plus-outline',
captionText: `pushed ${this.activityGroup.length} commit${
this.activityGroup.length === 0 ? '' : 's'
} to`,
actionText: 'new commit in',
color: 'success'
}
case 'commit_update':
return {
icon: 'mdi-timeline-text-outline',
captionText: 'updated a commit in',
actionText: 'commit updated in',
color: 'primary'
}
case 'commit_receive':
return {
icon: 'mdi-source-branch-sync',
captionText: 'received',
actionText: 'commit received from',
color: 'primary'
}
case 'commit_delete':
return {
icon: 'mdi-timeline-remove-outline',
captionText: 'deleted a commit from',
color: 'error',
actionText: 'commit deleted'
}
case 'user_create':
return {
icon: 'mdi-account-plus',
captionText: 'created'
}
case 'user_update':
return {
icon: 'mdi-account-convert',
captionText: 'updated'
}
case 'user_delete':
return {
icon: 'mdi-account-remove',
captionText: 'deleted'
}
default:
return {
icon: 'mdi-box',
name: this.lastActivity.actionType
}
}
}
},
methods: {
updatedDescription(activity) {
//CREATED
if (activity.actionType === 'stream_create') {
return activity.info?.stream?.description
? this.truncate(this.lastActivity.info.stream.description, 50)
: ''
} else if (activity.actionType === 'branch_create') {
return this.activity?.info?.branch?.description
? this.truncate(this.lastActivity.info.branch.description, 50)
: ''
}
//UPDATED
let changes = ''
if (activity.info.new) {
for (const [key] of Object.entries(activity.info.new)) {
if (
activity.info.old[key] !== undefined &&
activity.info.new[key] !== activity.info.old[key]
) {
if (key === 'name')
changes +=
'<p>✏️ Renamed from <i><del>' +
activity.info.old[key] +
'</del></i> to <i>' +
activity.info.new[key] +
'</i></p>'
if (key === 'description') {
let oldDesc = activity.info.old[key] ? activity.info.old[key] : 'empty'
changes +=
'<p>📋 Description changed from <i><del>' +
this.truncate(oldDesc) +
'</del></i> to <i>' +
this.truncate(activity.info.new[key]) +
'</ib></p>'
}
if (key === 'message') {
let oldDesc = activity.info.old[key] ? activity.info.old[key] : 'empty'
changes +=
'<p>📋 Message changed from <i><del>' +
this.truncate(oldDesc) +
'</del></i> to <i>' +
this.truncate(activity.info.new[key]) +
'</ib></p>'
}
if (key === 'isPublic' && activity.info.new[key])
changes += '<p>👀 Stream is now <i>public</i></p>'
if (key === 'isPublic' && !activity.info.new[key])
changes += '<p>👀 Stream is now <i>private</i></p>'
}
}
}
return changes
},
truncate(input, length = 25) {
if (!input) return ''
if (input.length > length) {
return input.substring(0, length) + '...'
}
return input
}
}
}
</script>
<style>
.activity-card p {
margin: 0 !important;
}
.timeline-activity a {
text-decoration: none;
}
</style>
@@ -40,7 +40,7 @@
import gql from 'graphql-tag'
export default {
name: 'Activity',
name: 'StreamActivity',
components: {
ListItemActivity: () => import('@/main/components/activity/ListItemActivity'),
InfiniteLoading: () => import('vue-infinite-loading')
@@ -197,7 +197,7 @@ export default {
this.$matomo && this.$matomo.trackPageView('stream/webhook/create')
this.$mixpanel.track('Webhook Action', { type: 'action', name: 'create' })
let res = await this.$apollo.mutate({
await this.$apollo.mutate({
mutation: gql`
mutation webhookCreate($params: WebhookCreateInput!) {
webhookCreate(webhook: $params)
@@ -41,7 +41,16 @@
</template>
<script>
export default {
props: ['file', 'branches'],
props: {
file: {
type: File,
default: () => null
},
branches: {
type: Array,
default: () => []
}
},
data: () => ({
percentCompleted: -1,
error: null,
@@ -46,7 +46,12 @@
<script>
export default {
props: ['user'],
props: {
user: {
type: Object,
default: () => null
}
},
data() {
return {
errors: false,
@@ -30,7 +30,9 @@
</template>
<script>
export default {
props: ['small'],
props: {
small: { type: Boolean, default: false }
},
data() {
return {
items: [
@@ -149,6 +149,8 @@
</div>
</template>
<script>
// TODO: Need to fix the viewer package build process to be able to properly reference THREE.js
/* global THREE */
import gql from 'graphql-tag'
import debounce from 'lodash.debounce'
@@ -140,6 +140,8 @@
</div>
</template>
<script>
// TODO: Need to fix the viewer package build process to be able to properly reference THREE.js
/* global THREE */
import debounce from 'lodash.debounce'
import gql from 'graphql-tag'
@@ -76,7 +76,12 @@ export default {
UserAvatar: () => import('@/main/components/common/UserAvatar'),
ObjectProperties: () => import('@/main/components/viewer/ObjectProperties')
},
props: ['resource'],
props: {
resource: {
type: Object,
default: () => null
}
},
data() {
return {
expanded: false
@@ -59,7 +59,12 @@ export default {
components: {
ObjectProperties: () => import('@/main/components/viewer/ObjectProperties')
},
props: ['resource'],
props: {
resource: {
type: Object,
default: () => null
}
},
data() {
return {
expanded: false
@@ -34,7 +34,16 @@ export default {
components: {
ObjectPropertiesRow: () => import('@/main/components/viewer/ObjectPropertiesRow')
},
props: ['obj', 'streamId'],
props: {
obj: {
type: Object,
default: () => null
},
streamId: {
type: String,
default: () => null
}
},
data() {
return {
realObject: this.obj,
@@ -129,7 +129,24 @@ export default {
components: {
ObjectProperties: () => import('@/main/components/viewer/ObjectProperties')
},
props: ['prop', 'streamId', 'parent', 'refId'],
props: {
prop: {
type: Object,
default: () => null
},
parent: {
type: Object,
default: () => null
},
refId: {
type: String,
default: () => null
},
streamId: {
type: String,
default: () => null
}
},
data() {
return {
expanded: false,
@@ -57,10 +57,10 @@
:margin="false"
></user-avatar>
<v-avatar
color="background"
:size="30"
v-else
v-tooltip="sessionUser.name"
color="background"
:size="30"
style="cursor: pointer"
>
👀
@@ -87,11 +87,14 @@
</div>
</template>
<script>
// TODO: Need to fix the viewer package build process to be able to properly reference THREE.js
/* global THREE */
import gql from 'graphql-tag'
import { v4 as uuid } from 'uuid'
import debounce from 'lodash.debounce'
export default {
name: 'ViewerBubbles',
components: {
UserAvatar: () => import('@/main/components/common/UserAvatar'),
TextDotsTyping: () => import('@/main/components/common/TextDotsTyping')
@@ -196,16 +199,12 @@ export default {
this.uuid = window.__bubblesId
this.raycaster = new THREE.Raycaster()
// window.__viewer.cameraHandler.controls.addEventListener(
// 'update',
// throttle(this.updateBubbles, 120)
// )
window.__viewer.cameraHandler.controls.addEventListener('update', () =>
this.updateBubbles(false)
)
this.updateInterval = window.setInterval(this.sendUpdateAndPrune, 2000)
window.addEventListener('beforeunload', async (e) => {
window.addEventListener('beforeunload', async () => {
await this.sendDisconnect()
})
this.resourceId = this.$route.params.resourceId
@@ -219,7 +218,7 @@ export default {
this.sendUpdateAndPrune()
}, 50)
)
window.__viewer.on('object-doubleclicked', (selectionInfo) => {})
window.__viewer.on('object-doubleclicked', () => {})
},
async beforeDestroy() {
await this.sendDisconnect()
@@ -443,14 +442,11 @@ export default {
}
</script>
<style scoped>
.user-bubble {
}
.absolute-pos {
pointer-events: auto;
position: absolute;
top: 0;
left: 0;
/* transition: all 0.3s ease; */
transform-origin: center;
}
</style>
@@ -87,6 +87,7 @@
</template>
<script>
export default {
name: 'ViewerFilters',
components: {
FilterRowSelect: () => import('@/main/components/viewer/FilterRowSelect'),
FilterCategoryActive: () => import('@/main/components/viewer/FilterCategoryActive'),
@@ -56,7 +56,12 @@ export default {
import('@/main/components/common/CommitReceivedReceipts'),
SourceAppAvatar: () => import('@/main/components/common/SourceAppAvatar')
},
props: ['streamId'],
props: {
streamId: {
type: String,
default: () => null
}
},
apollo: {
stream: {
query: gql`
@@ -57,7 +57,16 @@ export default {
import('@/main/components/common/CommitReceivedReceipts'),
SourceAppAvatar: () => import('@/main/components/common/SourceAppAvatar')
},
props: ['streamId', 'branchName'],
props: {
streamId: {
type: String,
default: () => null
},
branchName: {
type: String,
default: () => null
}
},
data() {
return {
skip: true,
@@ -95,13 +95,18 @@
import gql from 'graphql-tag'
import streamObjectQuery from '@/graphql/objectSingleNoData.gql'
export default {
name: 'StreamOverlayViewer',
components: {
// SectionCard: () => import('@/main/components/common/SectionCard')
AllCommits: () => import('@/main/components/viewer/dialogs/AllCommits'),
AllCommitsBranch: () => import('@/main/components/viewer/dialogs/AllCommitsBranch'),
PreviewImage: () => import('@/main/components/common/PreviewImage')
},
props: ['streamId'],
props: {
streamId: {
type: String,
default: () => null
}
},
apollo: {},
data() {
return {
@@ -82,9 +82,16 @@
</template>
<script>
import gql from 'graphql-tag'
import isNull from 'lodash/isNull'
import isUndefined from 'lodash/isUndefined'
export default {
props: ['stream'],
props: {
stream: {
type: Object,
default: () => null
}
},
data() {
return {
dialog: false,
@@ -139,7 +146,7 @@ export default {
.map((b) => b.name)
},
skip() {
return this.stream.branch == null
return isNull(this.stream.branch) || isUndefined(this.stream.branch)
}
}
},
@@ -82,7 +82,12 @@
<script>
import gql from 'graphql-tag'
export default {
props: ['stream'],
props: {
stream: {
type: Object,
default: () => null
}
},
data() {
return {
showDeleteDialog: false,
@@ -103,12 +103,13 @@
</v-toolbar-title>
<v-spacer></v-spacer>
<v-switch
v-model="stream.isPublic"
:input-value="stream.isPublic"
inset
class="mt-4"
:loading="swapPermsLoading"
:disabled="swapPermsLoading"
@click="changeVisibility"
></v-switch>
/>
</v-toolbar>
<v-card-text v-if="stream.isPublic" class="pt-2">
This stream is public. This means that anyone with the link can view and read
@@ -198,12 +199,19 @@
</template>
<script>
import gql from 'graphql-tag'
import { COMMON_STREAM_FIELDS } from '@/graphql/streams'
// import { $resourceType } from '@/plugins/resourceIdentifier'
export default {
name: 'ShareStreamDialog',
components: {
UserAvatar: () => import('@/main/components/common/UserAvatar')
},
props: ['stream'],
props: {
stream: {
type: Object,
default: () => null
}
},
data() {
return {
swapPermsLoading: false
@@ -237,6 +245,8 @@ export default {
},
async changeVisibility() {
this.swapPermsLoading = true
let newIsPublic = !this.stream.isPublic
try {
await this.$apollo.mutate({
mutation: gql`
@@ -247,19 +257,37 @@ export default {
variables: {
input: {
id: this.$route.params.streamId,
isPublic: this.stream.isPublic
isPublic: newIsPublic
}
},
optimisticResponse: {
__typename: 'Mutation',
streamUpdate: newIsPublic
},
update: (cache, { data: { streamUpdate: isSuccessFul } }) => {
// Update stream public value in cache
const normalizedId = `Stream:${this.stream.id}`
const cachedStream = cache.readFragment({
id: normalizedId,
fragment: COMMON_STREAM_FIELDS
})
cache.writeFragment({
id: normalizedId,
fragment: COMMON_STREAM_FIELDS,
data: {
...cachedStream,
isPublic: isSuccessFul ? newIsPublic : !newIsPublic
}
})
}
})
} catch (e) {
this.$eventHub.$emit('notification', {
text: e.message ? e.message : 'Something went wrong.'
})
this.stream.isPublic = !this.stream.isPublic
}
this.swapPermsLoading = false
this.$emit('visibility-change')
// this.$apollo.queries.stream.refetch()
}
}
}
@@ -54,7 +54,7 @@ export default {
email: null,
dialog: false,
isLoading: false,
emailRules: [(v) => v == this.correctEmail || 'Incorrect email'],
emailRules: [(v) => v === this.correctEmail || 'Incorrect email'],
valid: true
}
},
@@ -1,4 +1,5 @@
<template>
<!-- eslint-disable vue/no-v-html -->
<v-app :class="`${$vuetify.theme.dark ? 'background-dark' : 'background-light'}`">
<v-container fill-height fluid>
<v-row align="center" justify="center">
@@ -10,7 +11,7 @@
xl="4"
class="hidden-sm-and-down"
>
<blurb :server-info="serverInfo" />
<login-blurb :server-info="serverInfo" />
</v-col>
<v-col cols="11" sm="8" md="6" lg="4" xl="3">
<router-view></router-view>
@@ -25,11 +26,12 @@
</v-app>
</template>
<script>
import Blurb from '@/main/components/auth/Blurb'
import LoginBlurb from '@/main/components/auth/LoginBlurb.vue'
import { MainServerInfoQuery } from '@/graphql/server'
export default {
components: { Blurb },
name: 'TheAuth',
components: { LoginBlurb },
data() {
return {}
},
@@ -44,6 +46,7 @@ export default {
}
},
mounted() {
// eslint-disable-next-line camelcase
this.$mixpanel.register({ server_id: this.$mixpanelServerId(), hostApp: 'web' })
}
}
@@ -129,6 +129,7 @@ export default {
mounted() {
this.setNavResizeEvents()
// eslint-disable-next-line camelcase
this.$mixpanel.register({ server_id: this.$mixpanelServerId(), hostApp: 'web' })
let mixpanelId = this.$mixpanelId()
if (mixpanelId !== null) {
@@ -20,13 +20,13 @@
<v-list-item-title class="font-weight-bold">Streams</v-list-item-title>
</v-list-item-content>
</v-list-item>
<!-- <v-divider></v-divider> -->
<!-- <v-subheader>DESC</v-subheader> -->
<div class="caption px-3 my-4">
<perfect-scrollbar
style="max-height: 100px"
:options="{ suppressScrollX: true }"
>
<!-- TODO: Need to get rid of this, as it opens us up for an XSS attack -->
<!-- eslint-disable-next-line vue/no-v-html -->
<span v-html="parsedDescription"></span>
</perfect-scrollbar>
<router-link
@@ -225,7 +225,12 @@ export default {
components: {
NewBranch: () => import('@/main/dialogs/NewBranch')
},
props: ['stream'],
props: {
stream: {
type: Object,
default: () => null
}
},
apollo: {
branchQuery: {
query: gql`
@@ -319,6 +324,7 @@ export default {
return this.branchQuery.branches.items.filter((b) => b.name !== 'globals').length
},
parsedDescription() {
// TODO: Pretty sketchy, isn't the descripton user editable? A user could inject XSS this way
if (!this.stream || !this.stream.description) return 'No description provided.'
return this.stream.description.replace(
/\[(.+?)\]\((https?:\/\/[a-zA-Z0-9/.(]+?)\)/g,
@@ -62,6 +62,7 @@
<script>
import gql from 'graphql-tag'
export default {
name: 'TheCommits',
components: {
InfiniteLoading: () => import('vue-infinite-loading'),
CommitPreviewCard: () => import('@/main/components/common/CommitPreviewCard'),
@@ -5,16 +5,17 @@
</portal>
<v-row>
<v-col cols="12" lg="12">
<timeline />
<feed-timeline />
</v-col>
</v-row>
<latest-blogposts></latest-blogposts>
<latest-blogposts />
</div>
</template>
<script>
export default {
name: 'TheFeed',
components: {
Timeline: () => import('@/main/components/feed/Timeline'),
FeedTimeline: () => import('@/main/components/feed/FeedTimeline.vue'),
LatestBlogposts: () => import('@/main/components/feed/LatestBlogposts')
}
}
@@ -19,7 +19,7 @@
<span class="hidden-md-and-up mr-2 primary--text">Speckle:</span>
Interoperability in seconds
</v-card-title>
<strategies
<auth-strategies
:strategies="strategies"
:app-id="appId"
:challenge="challenge"
@@ -104,12 +104,12 @@
<script>
import gql from 'graphql-tag'
import crs from 'crypto-random-string'
import Strategies from '@/main/components/auth/Strategies'
import AuthStrategies from '@/main/components/auth/AuthStrategies.vue'
import { isEmailValid } from '@/plugins/authHelpers'
export default {
name: 'Login',
components: { Strategies },
name: 'TheLogin',
components: { AuthStrategies },
apollo: {
serverInfo: {
query: gql`
@@ -24,7 +24,7 @@
<span class="hidden-md-and-up mr-2 primary--text">Speckle:</span>
Interoperability in seconds
</v-card-title>
<strategies
<auth-strategies
:strategies="strategies"
:app-id="appId"
:challenge="challenge"
@@ -187,12 +187,12 @@ import gql from 'graphql-tag'
import debounce from 'lodash/debounce'
import crs from 'crypto-random-string'
import Strategies from '@/main/components/auth/Strategies'
import AuthStrategies from '@/main/components/auth/AuthStrategies.vue'
import { isEmailValid } from '@/plugins/authHelpers'
export default {
name: 'Registration',
components: { Strategies },
name: 'TheRegistration',
components: { AuthStrategies },
apollo: {
serverInfo: {
query: gql`
@@ -55,7 +55,9 @@
</v-app>
</template>
<script>
export default {}
export default {
name: 'TheError'
}
</script>
<style scoped>
pre {
@@ -15,6 +15,7 @@
<script>
import GettingStartedSteps from '@/main/components/onboarding/GettingStartedSteps.vue'
export default {
name: 'TheOnboarding',
components: { GettingStartedSteps }
}
</script>
@@ -64,7 +64,7 @@
<views-display v-if="views.length !== 0" :views="views" class="mt-4" />
<!-- Filters display -->
<filters
<viewer-filters
class="mt-4"
:props="objectProperties"
:source-application="
@@ -103,7 +103,7 @@
!$vuetify.breakpoint.smAndDown ? 'top: -64px;' : 'top: -56px;'
} left: 0px; position: absolute`"
>
<viewer @load-progress="captureProgress" @selection="captureSelect" />
<speckle-viewer @load-progress="captureProgress" @selection="captureSelect" />
</div>
<div
@@ -147,7 +147,7 @@
"
class=""
>
<bubbles key="a" />
<viewer-bubbles key="a" />
<comments-overlay key="c" @add-resources="addResources" />
<comment-add-overlay key="b" />
</div>
@@ -216,25 +216,26 @@
import debounce from 'lodash/debounce'
import streamCommitQuery from '@/graphql/commit.gql'
import streamObjectQuery from '@/graphql/objectSingleNoData.gql'
import Viewer from '@/main/components/common/Viewer' // do not import async
import SpeckleViewer from '@/main/components/common/SpeckleViewer.vue' // do not import async
import { resourceType } from '@/plugins/resourceIdentifier'
export default {
components: {
Viewer,
SpeckleViewer,
CommitToolbar: () => import('@/main/toolbars/CommitToolbar'),
ObjectToolbar: () => import('@/main/toolbars/ObjectToolbar'),
MultipleResourcesToolbar: () => import('@/main/toolbars/MultipleResourcesToolbar'),
CommitEdit: () => import('@/main/dialogs/CommitEdit'),
StreamOverlayViewer: () => import('@/main/components/viewer/dialogs/AddOverlay'),
StreamOverlayViewer: () =>
import('@/main/components/viewer/dialogs/StreamOverlayViewer.vue'),
ErrorPlaceholder: () => import('@/main/components/common/ErrorPlaceholder'),
PreviewImage: () => import('@/main/components/common/PreviewImage'),
ViewerControls: () => import('@/main/components/viewer/ViewerControls'),
ObjectSelection: () => import('@/main/components/viewer/ObjectSelection'),
ResourceGroup: () => import('@/main/components/viewer/ResourceGroup'),
ViewsDisplay: () => import('@/main/components/viewer/ViewsDisplay'),
Filters: () => import('@/main/components/viewer/Filters'),
Bubbles: () => import('@/main/components/viewer/Bubbles'),
ViewerFilters: () => import('@/main/components/viewer/ViewerFilters.vue'),
ViewerBubbles: () => import('@/main/components/viewer/ViewerBubbles.vue'),
CommentAddOverlay: () => import('@/main/components/viewer/CommentAddOverlay'),
CommentsOverlay: () => import('@/main/components/viewer/CommentsOverlay')
},
@@ -39,8 +39,9 @@
<script>
import gql from 'graphql-tag'
// TODO: Is this unused?
export default {
name: 'Activity',
name: 'TheActivity',
components: {
ListItemActivity: () => import('@/main/components/activity/ListItemActivity'),
InfiniteLoading: () => import('vue-infinite-loading')
@@ -104,17 +104,13 @@ import gql from 'graphql-tag'
import branchQuery from '@/graphql/branch.gql'
export default {
name: 'Branch',
name: 'TheBranch',
components: {
InfiniteLoading: () => import('vue-infinite-loading'),
NoDataPlaceholder: () => import('@/main/components/common/NoDataPlaceholder'),
ErrorPlaceholder: () => import('@/main/components/common/ErrorPlaceholder'),
ListItemCommit: () => import('@/main/components/stream/ListItemCommit'),
BranchEditDialog: () => import('@/main/dialogs/BranchEditDialog'),
PreviewImage: () => import('@/main/components/common/PreviewImage'),
CommitReceivedReceipts: () =>
import('@/main/components/common/CommitReceivedReceipts'),
SourceAppAvatar: () => import('@/main/components/common/SourceAppAvatar'),
BranchToolbar: () => import('@/main/toolbars/BranchToolbar'),
CommitPreviewCard: () => import('@/main/components/common/CommitPreviewCard')
},
@@ -238,6 +238,7 @@ import userSearchQuery from '@/graphql/userSearch.gql'
import { FullServerInfoQuery } from '@/graphql/server'
export default {
name: 'TheCollaborators',
components: {
UserAvatar: () => import('@/main/components/common/UserAvatar'),
UserRole: () => import('@/main/components/stream/UserRole'),
@@ -70,7 +70,7 @@
import gql from 'graphql-tag'
export default {
name: 'Comments',
name: 'TheComments',
components: {
CommentListItem: () => import('@/main/components/comments/CommentListItem.vue'),
NoDataPlaceholder: () => import('@/main/components/common/NoDataPlaceholder'),
@@ -151,7 +151,7 @@ import gql from 'graphql-tag'
import branchQuery from '@/graphql/branch.gql'
export default {
name: 'Globals',
name: 'TheGlobals',
components: {
GlobalsBuilder: () => import('@/main/components/stream/globals/GlobalsBuilder'),
ListItemCommit: () => import('@/main/components/stream/ListItemCommit'),
@@ -203,7 +203,7 @@ export default {
commit() {
return this.$route.params.commitId
? this.branch?.commits?.items?.filter(
(c) => c.id == this.$route.params.commitId
(c) => c.id === this.$route.params.commitId
)[0]
: this.branch?.commits?.items[0]
},
@@ -156,7 +156,7 @@
import gql from 'graphql-tag'
export default {
name: 'StreamSettings',
name: 'TheSettings',
components: {
SectionCard: () => import('@/main/components/common/SectionCard')
},
@@ -128,7 +128,6 @@ export default {
this.$refs.streamInviteDialog.show()
}, 500)
}
},
methods: {}
}
}
</script>
@@ -68,7 +68,7 @@
</v-card-title>
</v-card>
<div class="mr-0">
<stream-activity></stream-activity>
<stream-activity />
</div>
</v-col>
</v-row>
@@ -86,12 +86,11 @@
import gql from 'graphql-tag'
export default {
name: 'StreamHome',
name: 'TheStreamHome',
components: {
NoDataPlaceholder: () => import('@/main/components/common/NoDataPlaceholder'),
ListItemCommit: () => import('@/main/components/stream/ListItemCommit'),
PreviewImage: () => import('@/main/components/common/PreviewImage'),
StreamActivity: () => import('@/main/components/stream/Activity'),
StreamActivity: () => import('@/main/components/stream/StreamActivity.vue'),
CommitPreviewCard: () => import('@/main/components/common/CommitPreviewCard')
},
data() {
@@ -130,7 +130,7 @@
import gql from 'graphql-tag'
export default {
name: 'Webhooks',
name: 'TheUploads',
components: {
FileUploadItem: () => import('@/main/components/stream/uploads/FileUploadItem'),
FileProcessingItem: () =>
@@ -53,7 +53,7 @@
</p>
</error-placeholder>
<v-container fluid v-if="!$apollo.loading && webhooks.length !== 0" class="pa-0">
<v-container v-if="!$apollo.loading && webhooks.length !== 0" fluid class="pa-0">
<portal to="toolbar">
<div class="d-flex align-center">
<div class="text-truncate">
@@ -269,7 +269,7 @@
<script>
import webhooksQuery from '@/graphql/webhooks.gql'
export default {
name: 'Webhooks',
name: 'TheWebhooks',
components: {
WebhookForm: () => import('@/main/components/stream/WebhookForm'),
NoDataPlaceholder: () => import('@/main/components/common/NoDataPlaceholder'),
@@ -52,7 +52,7 @@ import { ProfileSelfQuery } from '@/graphql/user'
import { signOut } from '@/plugins/authHelpers'
export default {
name: 'Profile',
name: 'TheProfileSelf',
components: {
SectionCard: () => import('@/main/components/common/SectionCard'),
UserInfoCard: () => import('@/main/components/user/UserInfoCard'),
@@ -42,7 +42,7 @@ import ListItemStream from '@/main/components/user/ListItemStream'
import gql from 'graphql-tag'
export default {
name: 'ProfileUser',
name: 'TheProfileUser',
components: {
UserInfoCard: () => import('@/main/components/user/UserInfoCard'),
SectionCard: () => import('@/main/components/common/SectionCard'),
+18 -18
View File
@@ -8,7 +8,7 @@ const routes = [
path: '/authn',
name: 'Auth',
redirect: '/authn/login',
component: () => import('@/main/layouts/Auth.vue'),
component: () => import('@/main/layouts/TheAuth.vue'),
children: [
{
path: 'login',
@@ -16,7 +16,7 @@ const routes = [
meta: {
title: 'Login | Speckle'
},
component: () => import('@/main/pages/auth/Login.vue')
component: () => import('@/main/pages/auth/TheLogin.vue')
},
{
path: 'register',
@@ -24,7 +24,7 @@ const routes = [
meta: {
title: 'Register | Speckle'
},
component: () => import('@/main/pages/auth/Registration.vue')
component: () => import('@/main/pages/auth/TheRegistration.vue')
},
{
path: 'resetpassword',
@@ -65,7 +65,7 @@ const routes = [
meta: {
title: 'Home | Speckle'
},
component: () => import('@/main/pages/Feed.vue')
component: () => import('@/main/pages/TheFeed.vue')
},
{
path: '/commits',
@@ -73,7 +73,7 @@ const routes = [
meta: {
title: 'Commits | Speckle'
},
component: () => import('@/main/pages/Commits.vue')
component: () => import('@/main/pages/TheCommits.vue')
},
{
path: 'streams',
@@ -104,7 +104,7 @@ const routes = [
meta: {
title: 'Stream | Speckle'
},
component: () => import('@/main/pages/stream/StreamHome.vue')
component: () => import('@/main/pages/stream/TheStreamHome.vue')
},
{
path: 'branches/',
@@ -117,7 +117,7 @@ const routes = [
meta: {
title: 'Branch | Speckle'
},
component: () => import('@/main/pages/stream/Branch.vue'),
component: () => import('@/main/pages/stream/TheBranch.vue'),
beforeEnter: (to, from, next) => {
if (to.params.branchName.toLowerCase() !== to.params.branchName)
return next(
@@ -135,7 +135,7 @@ const routes = [
title: 'Stream Comments | Speckle',
resizableNavbar: false
},
component: () => import('@/main/pages/stream/Comments.vue')
component: () => import('@/main/pages/stream/TheComments.vue')
},
{
path: 'commits/:resourceId*',
@@ -162,7 +162,7 @@ const routes = [
title: 'Stream Collaborators | Speckle'
},
props: true,
component: () => import('@/main/pages/stream/Collaborators.vue')
component: () => import('@/main/pages/stream/TheCollaborators.vue')
},
{
path: 'settings/',
@@ -171,7 +171,7 @@ const routes = [
title: 'Stream Settings | Speckle'
},
props: true,
component: () => import('@/main/pages/stream/Settings.vue')
component: () => import('@/main/pages/stream/TheSettings.vue')
},
{
path: 'webhooks/',
@@ -180,7 +180,7 @@ const routes = [
title: 'Webhooks | Speckle'
},
props: true,
component: () => import('@/main/pages/stream/Webhooks.vue')
component: () => import('@/main/pages/stream/TheWebhooks.vue')
},
{
path: 'uploads/',
@@ -189,7 +189,7 @@ const routes = [
title: 'Stream Uploads | Speckle'
},
props: true,
component: () => import('@/main/pages/stream/Uploads.vue')
component: () => import('@/main/pages/stream/TheUploads.vue')
},
{
path: 'globals/',
@@ -198,7 +198,7 @@ const routes = [
title: 'Globals | Speckle'
},
props: true,
component: () => import('@/main/pages/stream/Globals.vue')
component: () => import('@/main/pages/stream/TheGlobals.vue')
},
{
path: 'globals/:commitId',
@@ -206,7 +206,7 @@ const routes = [
meta: {
title: 'Globals | Speckle'
},
component: () => import('@/main/pages/stream/Globals.vue')
component: () => import('@/main/pages/stream/TheGlobals.vue')
}
]
},
@@ -216,7 +216,7 @@ const routes = [
meta: {
title: 'Your Profile | Speckle'
},
component: () => import('@/main/pages/user/ProfileSelf.vue')
component: () => import('@/main/pages/user/TheProfileSelf.vue')
},
{
path: 'profile/:userId',
@@ -224,7 +224,7 @@ const routes = [
meta: {
title: 'User Profile | Speckle'
},
component: () => import('@/main/pages/user/Profile.vue')
component: () => import('@/main/pages/user/TheProfileUser.vue')
},
{
path: 'admin',
@@ -271,7 +271,7 @@ const routes = [
meta: {
title: 'Error | Speckle'
},
component: () => import('@/main/pages/common/Error.vue')
component: () => import('@/main/pages/common/TheError.vue')
},
{
path: '/onboarding',
@@ -279,7 +279,7 @@ const routes = [
meta: {
title: 'Getting Started | Speckle'
},
component: () => import('@/main/pages/onboarding/Onboarding.vue')
component: () => import('@/main/pages/onboarding/TheOnboarding.vue')
},
{
path: '*',
@@ -104,6 +104,11 @@
</template>
<script>
export default {
props: ['stream']
props: {
stream: {
type: Object,
default: () => null
}
}
}
</script>
@@ -166,7 +166,12 @@ export default {
CommitReceivedReceipts: () =>
import('@/main/components/common/CommitReceivedReceipts')
},
props: ['stream'],
props: {
stream: {
type: Object,
default: () => null
}
},
data() {
return { showCommitInfo: false }
},
@@ -28,6 +28,15 @@
</template>
<script>
export default {
props: ['stream', 'resources']
props: {
stream: {
type: Object,
default: () => null
},
resources: {
type: Array,
default: () => []
}
}
}
</script>
@@ -44,7 +44,12 @@
</template>
<script>
export default {
props: ['stream'],
props: {
stream: {
type: Object,
default: () => null
}
},
data() {
return { showInfo: false }
},
@@ -63,11 +63,7 @@
max-width="600"
:fullscreen="$vuetify.breakpoint.xsOnly"
>
<share-stream-dialog
:stream="stream"
@close="shareStream = false"
@visibility-changexxxx="$apollo.queries.stream.refetch()"
/>
<share-stream-dialog :stream="stream" @close="shareStream = false" />
</v-dialog>
</div>
</template>
@@ -75,7 +71,7 @@
export default {
components: {
CollaboratorsDisplay: () => import('@/main/components/stream/CollaboratorsDisplay'),
ShareStreamDialog: () => import('@/main/dialogs/ShareStream'),
ShareStreamDialog: () => import('@/main/dialogs/ShareStreamDialog.vue'),
StreamFavoriteBtn: () =>
import('@/main/components/stream/favorites/StreamFavoriteBtn.vue')
},
-1
View File
@@ -43,7 +43,6 @@
"editor.formatOnPaste": true,
"editor.multiCursorModifier": "ctrlCmd",
"editor.snippetSuggestions": "top",
"eslint.format.enable": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true