Added missing activity types
This commit is contained in:
@@ -1,136 +1,257 @@
|
||||
<template>
|
||||
<v-card :link="modifier !== 'deleted'" :to="url">
|
||||
<v-card :link="url !== null" :to="url">
|
||||
<v-card-text class="pa-2">
|
||||
<div :class="tagColor" class="rounded-pill pa-2 white--text d-inline-flex justify-center align-center">
|
||||
<div
|
||||
:class="tagColor"
|
||||
class="rounded-pill pa-2 white--text d-inline-flex justify-center align-center"
|
||||
>
|
||||
<v-icon small color="white">{{ activityInfo.icon }}</v-icon>
|
||||
</div>
|
||||
<span class="pa-2">
|
||||
<span v-if="type !== 'stream_permissions'">
|
||||
{{ type | capitalize }}
|
||||
<span class="font-weight-bold font-italic primary--text">{{ this.activityInfo.name }} </span>
|
||||
<span>was {{ modifier }} </span>
|
||||
<span v-if="type !== 'stream'">
|
||||
in stream <span class="font-weight-bold font-italic primary--text">{{ this.stream ? this.stream.name : `[Deleted] ${this.activity.streamId}` }} </span>
|
||||
<span class="font-weight-bold font-italic primary--text">
|
||||
{{ activityInfo.name }}
|
||||
</span>
|
||||
<timeago :datetime="activity.time" class="font-italic"></timeago>
|
||||
by
|
||||
<v-chip small class="pl-0" v-if="user">
|
||||
</span>
|
||||
<span v-else>
|
||||
<v-chip v-if="user" small class="pl-0">
|
||||
<v-avatar color="grey lighten-3" class="mr-1">
|
||||
<img :src="user.avatar || `https://robohash.org/` + this.activity.userId + `.png?size=40x40`"
|
||||
:alt="user.name">
|
||||
<img
|
||||
:src="
|
||||
targetUser.avatar || `https://robohash.org/` + targetUser.id + `.png?size=40x40`
|
||||
"
|
||||
:alt="targetUser.name"
|
||||
/>
|
||||
</v-avatar>
|
||||
{{ user.name }}
|
||||
</v-chip>
|
||||
<v-progress-circular v-else indeterminate></v-progress-circular>
|
||||
</span>
|
||||
<span>{{ activityInfo.modifier }}</span>
|
||||
<span id="streamAttribution" v-if="type !== 'stream' && type !== 'user'">
|
||||
in stream
|
||||
<span class="font-weight-bold font-italic primary--text">
|
||||
{{ stream ? stream.name : `[Deleted] ${activity.streamId}` }}
|
||||
</span>
|
||||
</span>
|
||||
<span>
|
||||
<timeago :datetime="activity.time" class="font-italic ma-1"></timeago>
|
||||
</span>
|
||||
<span id="userAttribution" v-if="type != 'user'">
|
||||
by
|
||||
<v-chip v-if="user" small class="pl-0">
|
||||
<v-avatar color="grey lighten-3" class="mr-1">
|
||||
<img
|
||||
:src="user.avatar || `https://robohash.org/` + activity.userId + `.png?size=40x40`"
|
||||
:alt="user.name"
|
||||
/>
|
||||
</v-avatar>
|
||||
{{ user.name }}
|
||||
</v-chip>
|
||||
<v-progress-circular v-else indeterminate></v-progress-circular>
|
||||
</span>
|
||||
</span>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserAvatar from "@/components/UserAvatar";
|
||||
import gql from "graphql-tag";
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default {
|
||||
components: { UserAvatar },
|
||||
props: ["activity"],
|
||||
components: {},
|
||||
props: ['activity'],
|
||||
apollo: {
|
||||
user: {
|
||||
query: gql`query($id: String) {
|
||||
user(id: $id){
|
||||
name
|
||||
avatar
|
||||
query: gql`
|
||||
query($id: String) {
|
||||
user(id: $id) {
|
||||
name
|
||||
avatar
|
||||
}
|
||||
}
|
||||
}`,
|
||||
`,
|
||||
variables() {
|
||||
id: this.activity.userId;
|
||||
return {
|
||||
id: this.activity.userId
|
||||
}
|
||||
}
|
||||
},
|
||||
targetUser: {
|
||||
query() {
|
||||
return gql`
|
||||
query targetUser($id: String) {
|
||||
user(id: $id) {
|
||||
name
|
||||
avatar
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
},
|
||||
update: (data) => data.user,
|
||||
variables() {
|
||||
return {
|
||||
id: this.activity.info.targetUser
|
||||
}
|
||||
},
|
||||
skip() {
|
||||
return this.activity.info.targetUser === null || this.activity.info.targetUser === undefined
|
||||
}
|
||||
},
|
||||
|
||||
stream: {
|
||||
query: gql`query($id: String!){ stream(id: $id){name}}`,
|
||||
query: gql`
|
||||
query($id: String!) {
|
||||
stream(id: $id) {
|
||||
name
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables() {
|
||||
return {
|
||||
id: this.activity.streamId
|
||||
};
|
||||
}
|
||||
},
|
||||
skip() {
|
||||
return this.type === "stream";
|
||||
return this.type === 'stream'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
computed: {
|
||||
modifier() {
|
||||
return this.activity.actionType.split("_")[1] + "d";
|
||||
return this.activity.actionType.split('_').pop()
|
||||
},
|
||||
type() {
|
||||
return this.activity.actionType.split("_")[0];
|
||||
var x = this.activity.actionType.split('_')
|
||||
x.pop()
|
||||
return x.join('_')
|
||||
},
|
||||
url(){
|
||||
if(this.modifier === "deleted") return
|
||||
switch (this.type){
|
||||
case "stream":
|
||||
url() {
|
||||
if (this.modifier === 'delete' || this.modifier === 'remove') return null
|
||||
switch (this.type) {
|
||||
case 'stream':
|
||||
return `/streams/${this.activity.streamId}`
|
||||
case "branch":
|
||||
return `/streams/${this.activity.streamId}/branches/${this.activity.info.branch.name}`
|
||||
case "commit":
|
||||
case 'stream_permissions':
|
||||
return `/streams/${this.activity.streamId}`
|
||||
case 'branch':
|
||||
return `/streams/${this.activity.streamId}/branches/${this.activity.info.branch?.name}`
|
||||
case 'commit':
|
||||
return `/streams/${this.activity.streamId}/commits/${this.activity.resourceId}`
|
||||
case 'user':
|
||||
return '/profile'
|
||||
default:
|
||||
return null
|
||||
}
|
||||
},
|
||||
activityInfo() {
|
||||
switch (this.activity.actionType) {
|
||||
case "stream_create":
|
||||
case 'stream_create':
|
||||
return {
|
||||
icon: "mdi-cloud",
|
||||
name: this.activity.info.stream?.name
|
||||
};
|
||||
case "stream_delete":
|
||||
icon: 'mdi-cloud',
|
||||
name: this.activity.info.stream?.name,
|
||||
modifier: 'was created'
|
||||
}
|
||||
case 'stream_update':
|
||||
return {
|
||||
icon: "mdi-cloud-alert",
|
||||
name: this.activity.streamId
|
||||
};
|
||||
case "commit_create":
|
||||
icon: 'mdi-cloud',
|
||||
name: this.activity.info.new?.name,
|
||||
modifier: 'was updated'
|
||||
}
|
||||
case 'stream_delete':
|
||||
return {
|
||||
icon: "mdi-timeline-plus",
|
||||
name: this.activity.resourceId
|
||||
};
|
||||
case "commit_delete":
|
||||
icon: 'mdi-cloud-alert',
|
||||
name: this.activity.streamId,
|
||||
modifier: 'was deleted'
|
||||
}
|
||||
case 'stream_permissions_add':
|
||||
return {
|
||||
icon: "mdi-timeline-minus",
|
||||
name: this.activity.resourceId
|
||||
};
|
||||
case "branch_create":
|
||||
icon: 'mdi-cloud-alert',
|
||||
name: this.targetUser.name,
|
||||
modifier: 'was granted access as ' + this.activity.info.role.split(':')[1]
|
||||
}
|
||||
case 'stream_permissions_remove':
|
||||
return {
|
||||
icon: "mdi-source-branch-plus",
|
||||
name: this.activity.info.branch.name
|
||||
};
|
||||
case "branch_delete":
|
||||
icon: 'mdi-cloud-alert',
|
||||
name: 'User',
|
||||
modifier: 'was revoked access'
|
||||
}
|
||||
case 'commit_create':
|
||||
return {
|
||||
icon: "mdi-source-branch-minus",
|
||||
name: this.activity.info.branch.name
|
||||
};
|
||||
icon: 'mdi-timeline-plus',
|
||||
name: this.activity.resourceId,
|
||||
modifier: 'was created'
|
||||
}
|
||||
case 'commit_delete':
|
||||
return {
|
||||
icon: 'mdi-timeline-minus',
|
||||
name: this.activity.resourceId,
|
||||
modifier: 'was deleted'
|
||||
}
|
||||
case 'branch_create':
|
||||
return {
|
||||
icon: 'mdi-source-branch-plus',
|
||||
name: this.activity.info.branch.name,
|
||||
modifier: 'was created'
|
||||
}
|
||||
case 'branch_delete':
|
||||
return {
|
||||
icon: 'mdi-source-branch-minus',
|
||||
name: this.activity.info.branch.name,
|
||||
modifier: 'was deleted'
|
||||
}
|
||||
case 'branch_update':
|
||||
return {
|
||||
icon: 'mdi-source-branch-sync',
|
||||
name: this.activity.info.new.name,
|
||||
modifier: 'was updated'
|
||||
}
|
||||
case 'user_create':
|
||||
return {
|
||||
icon: 'mdi-account-plus',
|
||||
name: this.activity.info.user.name,
|
||||
modifier: 'was created'
|
||||
}
|
||||
case 'user_update':
|
||||
return {
|
||||
icon: 'mdi-account-convert',
|
||||
name: this.activity.info.new.name,
|
||||
modifier: 'was updated'
|
||||
}
|
||||
case 'user_delete':
|
||||
return {
|
||||
icon: 'mdi-account-remove',
|
||||
name: this.activity.resourceId,
|
||||
modifier: 'was deleted'
|
||||
}
|
||||
default:
|
||||
return {
|
||||
icon: "mdi-question",
|
||||
icon: 'mdi-box',
|
||||
name: this.activity.actionType
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
tagColor() {
|
||||
var split = this.activity.actionType.split("_");
|
||||
var mod = split[1];
|
||||
var split = this.activity.actionType.split('_')
|
||||
var mod = split[split.length - 1]
|
||||
console.log('mod', this.activity.actionType, mod)
|
||||
switch (mod) {
|
||||
case "create":
|
||||
return "success";
|
||||
case "delete":
|
||||
return "error";
|
||||
case 'create':
|
||||
return 'success'
|
||||
case 'add':
|
||||
return 'success'
|
||||
case 'delete':
|
||||
return 'error'
|
||||
case 'remove':
|
||||
return 'error'
|
||||
default:
|
||||
return "primary";
|
||||
return 'primary'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
|
||||
@@ -1,82 +1,115 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-card elevation="0" class="my-5" flat>
|
||||
<v-card-text class="pb-0 ">
|
||||
<v-card-text class="pb-0">
|
||||
<span>Filter activity feed</span>
|
||||
<div class="d-flex">
|
||||
<v-select v-model="activityFilter.type" :items="filterTypes" label="Activity type" dense clearable></v-select>
|
||||
<v-menu ref="menub"
|
||||
v-model="menu2"
|
||||
:close-on-content-click="true"
|
||||
transition="scale-transition"
|
||||
offset-y
|
||||
min-width="auto">
|
||||
<v-select
|
||||
v-model="activityFilter.type"
|
||||
:items="filterSelect"
|
||||
item-text="name"
|
||||
item-value="type"
|
||||
label="Activity type"
|
||||
dense
|
||||
clearable
|
||||
></v-select>
|
||||
<v-menu
|
||||
ref="menub"
|
||||
v-model="menu2"
|
||||
:close-on-content-click="true"
|
||||
transition="scale-transition"
|
||||
offset-y
|
||||
min-width="auto"
|
||||
>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-text-field v-model="activityFilter.after"
|
||||
label="After date"
|
||||
prepend-icon="mdi-calendar"
|
||||
readonly
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
dense
|
||||
clearable></v-text-field>
|
||||
<v-text-field
|
||||
v-model="activityFilter.after"
|
||||
label="After date"
|
||||
prepend-icon="mdi-calendar"
|
||||
readonly
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
dense
|
||||
clearable
|
||||
></v-text-field>
|
||||
</template>
|
||||
<v-date-picker v-model="activityFilter.after" no-title color="primary"></v-date-picker>
|
||||
</v-menu>
|
||||
<v-menu ref="menu"
|
||||
v-model="menu"
|
||||
:close-on-content-click="true"
|
||||
transition="scale-transition"
|
||||
offset-y
|
||||
min-width="auto">
|
||||
<v-menu
|
||||
ref="menu"
|
||||
v-model="menu"
|
||||
:close-on-content-click="true"
|
||||
transition="scale-transition"
|
||||
offset-y
|
||||
min-width="auto"
|
||||
>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-text-field v-model="activityFilter.before"
|
||||
label="Before date"
|
||||
prepend-icon="mdi-calendar"
|
||||
readonly
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
dense
|
||||
clearable></v-text-field>
|
||||
<v-text-field
|
||||
v-model="activityFilter.before"
|
||||
label="Before date"
|
||||
prepend-icon="mdi-calendar"
|
||||
readonly
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
dense
|
||||
clearable
|
||||
></v-text-field>
|
||||
</template>
|
||||
<v-date-picker v-model="activityFilter.before"
|
||||
no-title
|
||||
@cancel="activityFilter.before = null"
|
||||
color="primary"></v-date-picker>
|
||||
<v-date-picker
|
||||
v-model="activityFilter.before"
|
||||
no-title
|
||||
@cancel="activityFilter.before = null"
|
||||
color="primary"
|
||||
></v-date-picker>
|
||||
</v-menu>
|
||||
</div>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
<div key="activity-list" v-if="activityFeed">
|
||||
<activity-item
|
||||
v-for="activity in activityFeed.items"
|
||||
:activity="activity"
|
||||
:key="activity.time"
|
||||
class="my-1"></activity-item>
|
||||
<infinite-loading @infinite="infiniteHandler" key="infiniteLoader">
|
||||
<div slot="no-more" class="pa-6 grey--text">No more activity results!</div>
|
||||
<div slot="no-results" class="pa-12 grey--text">There are no streams to load</div>
|
||||
</infinite-loading>
|
||||
</div>
|
||||
<div key="activity-list" v-if="activityFeed">
|
||||
<activity-item
|
||||
v-for="activity in activityFeed.items"
|
||||
:activity="activity"
|
||||
:key="activity.time"
|
||||
class="my-1"
|
||||
></activity-item>
|
||||
<infinite-loading @infinite="infiniteHandler" key="infiniteLoader">
|
||||
<div slot="no-more" class="pa-6 grey--text">No more activity results!</div>
|
||||
<div slot="no-results" class="pa-12 grey--text">There are no streams to load</div>
|
||||
</infinite-loading>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ActivityItem from "@/components/ActivityItem";
|
||||
import gql from "graphql-tag";
|
||||
import InfiniteLoading from "vue-infinite-loading";
|
||||
import ActivityItem from '@/components/ActivityItem'
|
||||
import gql from 'graphql-tag'
|
||||
import InfiniteLoading from 'vue-infinite-loading'
|
||||
|
||||
export default {
|
||||
name: "ActivityFeed",
|
||||
name: 'ActivityFeed',
|
||||
components: { ActivityItem, InfiniteLoading },
|
||||
props: {
|
||||
type: String
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
filterTypes: ["branch_create", "branch_delete", "stream_create", "stream_delete", "commit_create", "commit_delete"],
|
||||
filterTypes: [
|
||||
'branch_create',
|
||||
'branch_delete',
|
||||
'branch_update',
|
||||
'stream_create',
|
||||
'stream_delete',
|
||||
'stream_update',
|
||||
'stream_permissions_add',
|
||||
'stream_permissions_remove',
|
||||
'commit_create',
|
||||
'commit_delete',
|
||||
'commit_udpate',
|
||||
'user_update',
|
||||
'user_create',
|
||||
'user_delete'
|
||||
],
|
||||
activityFilter: {
|
||||
type: null,
|
||||
before: null,
|
||||
@@ -86,63 +119,81 @@ export default {
|
||||
menu2: false,
|
||||
load: false,
|
||||
showContent: false
|
||||
};
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
activityFeed: {
|
||||
query: gql`query($type: String, $before: DateTime, $after: DateTime) {
|
||||
user {
|
||||
id
|
||||
activity(actionType: $type, before: $before, after: $after) {
|
||||
totalCount
|
||||
cursor
|
||||
items {
|
||||
actionType
|
||||
userId
|
||||
streamId
|
||||
resourceId
|
||||
resourceType
|
||||
time
|
||||
info
|
||||
query: gql`
|
||||
query($type: String, $before: DateTime, $after: DateTime) {
|
||||
user {
|
||||
id
|
||||
activity(actionType: $type, before: $before, after: $after) {
|
||||
totalCount
|
||||
cursor
|
||||
items {
|
||||
actionType
|
||||
userId
|
||||
streamId
|
||||
resourceId
|
||||
resourceType
|
||||
time
|
||||
info
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`,
|
||||
`,
|
||||
variables() {
|
||||
var obj = {
|
||||
type: this.activityFilter.type,
|
||||
before: this.activityFilter.before ? new Date(this.activityFilter.before).toISOString() : undefined,
|
||||
after: this.activityFilter.after ? new Date(this.activityFilter.after).toISOString() : undefined
|
||||
};
|
||||
return obj;
|
||||
before: this.activityFilter.before
|
||||
? new Date(this.activityFilter.before).toISOString()
|
||||
: undefined,
|
||||
after: this.activityFilter.after
|
||||
? new Date(this.activityFilter.after).toISOString()
|
||||
: undefined
|
||||
}
|
||||
return obj
|
||||
},
|
||||
update: data => {
|
||||
return data.user.activity;
|
||||
update: (data) => {
|
||||
return data.user.activity
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filterSelect() {
|
||||
return this.filterTypes.map((t) => {
|
||||
var split = t.split('_')
|
||||
var name = `${split[0]} ${split[1]}`
|
||||
return {
|
||||
type: t,
|
||||
name: name
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
infiniteHandler($state) {
|
||||
if (!this.activityFeed.cursor) {
|
||||
$state.loaded();
|
||||
$state.complete();
|
||||
return;
|
||||
$state.loaded()
|
||||
$state.complete()
|
||||
return
|
||||
}
|
||||
this.$apollo.queries.activityFeed.fetchMore({
|
||||
variables: {
|
||||
before: this.activityFeed.cursor,
|
||||
after: this.activityFilter.after ? new Date(this.activityFilter.after).toISOString() : undefined
|
||||
after: this.activityFilter.after
|
||||
? new Date(this.activityFilter.after).toISOString()
|
||||
: undefined
|
||||
},
|
||||
// Transform the previous result with new data
|
||||
updateQuery: (previousResult, { fetchMoreResult }) => {
|
||||
const newItems = fetchMoreResult.user.activity.items;
|
||||
console.warn("new items", newItems);
|
||||
const newItems = fetchMoreResult.user.activity.items
|
||||
console.warn('new items', newItems)
|
||||
//$state.complete()
|
||||
//set vue-infinite state
|
||||
if (newItems.length === 0)
|
||||
$state.complete();
|
||||
else
|
||||
$state.loaded();
|
||||
if (newItems.length === 0) $state.complete()
|
||||
else $state.loaded()
|
||||
|
||||
return {
|
||||
user: {
|
||||
@@ -156,14 +207,12 @@ export default {
|
||||
items: [...previousResult.user.activity.items, ...newItems]
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
Reference in New Issue
Block a user