Skip to content

Commit

Permalink
Resolve #15: Add publicly viewable comment functionality for PBs
Browse files Browse the repository at this point in the history
  • Loading branch information
big213 committed Apr 11, 2021
1 parent 9d34da9 commit 51d0574
Show file tree
Hide file tree
Showing 14 changed files with 198 additions and 98 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import * as Knex from "knex";


export async function up(knex: Knex): Promise<void> {
return knex.schema.alterTable("personalBest", function (t) {
t.text("public_comments").nullable();
});
}


export async function down(knex: Knex): Promise<void> {
return knex.schema.alterTable("personalBest", function (t) {
t.dropColumn("public_comments");
});
}

2 changes: 2 additions & 0 deletions backend/functions/migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ export async function up(knex: Knex): Promise<void[]> {
table.integer("time_elapsed").nullable();
table.decimal("moves_count").nullable();
table.boolean("is_current").notNullable();
table.text("private_comments").nullable();
table.text("public_comments").nullable();
table.dateTime("created_at").notNullable().defaultTo(knex.fn.now());
table.dateTime("updated_at").nullable();
table.integer("created_by").notNullable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ export default {
"getMultiple",
"delete",
"create",
// "update",
"update",
]),
};
21 changes: 21 additions & 0 deletions backend/functions/src/schema/models/personalBest/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,27 @@ export class PersonalBestService extends PaginatedService {
return false;
},

update: async ({ req, args, fieldPath }) => {
// can only update the publicComments field as non-admin
if (
Object.keys(args.fields).some((field) => field !== "publicComments")
) {
return false;
}

// must be creator of the PB to update it
const result = await this.lookupRecord(
[
{
field: "createdBy.id",
},
],
args,
fieldPath
);
return req.user?.id === result["createdBy.id"];
},

delete: async ({ req, args, fieldPath }) => {
// must be creator of the PB to delete it
const result = await this.lookupRecord(
Expand Down
7 changes: 7 additions & 0 deletions backend/functions/src/schema/models/personalBest/typeDef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
generateBooleanField,
generateCreatedByField,
generateDecimalField,
generateTextField,
} from "../../core/helpers/typeDef";
import * as Scalars from "../../scalars";
import * as Resolver from "../../core/helpers/resolver";
Expand Down Expand Up @@ -81,6 +82,12 @@ export default new GiraffeqlObjectType(<ObjectTypeDefinition>{
typeDefOptions: { addable: false, updateable: false },
sqlOptions: { field: "is_current" },
}),
publicComments: generateTextField({
allowNull: true,
sqlOptions: {
field: "public_comments",
},
}),
ranking: {
type: Scalars.number,
description:
Expand Down
137 changes: 116 additions & 21 deletions frontend/components/dialog/editRecordDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
v-model="status"
scrollable
max-width="800px"
:persistent="mode !== 'view'"
:persistent="computedMode !== 'view'"
>
<component
:is="interfaceComponent"
v-if="status"
:selected-item="selectedItem"
:record-info="recordInfo"
:mode="mode"
:mode="computedMode"
dialog-mode
@handleSubmit="handleSubmit"
>
Expand All @@ -21,20 +21,89 @@
<span class="headline">{{ title }}</span>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-menu left offset-x>
<template v-slot:activator="{ on, attrs }">
<v-icon v-bind="attrs" v-on="on">mdi-dots-vertical</v-icon>
</template>

<v-list dense>
<v-list-item
v-if="recordInfo.enterOptions"
key="enter"
@click="goToPage(true)"
>
<v-list-item-icon>
<v-icon>mdi-open-in-new</v-icon>
</v-list-item-icon>
<v-list-item-title
>Go To Page
<v-icon small right>mdi-open-in-new</v-icon>
</v-list-item-title>
</v-list-item>
<v-list-item
v-if="recordInfo.shareOptions"
key="view"
@click="openEditDialog('view')"
>
<v-list-item-icon>
<v-icon>mdi-eye</v-icon>
</v-list-item-icon>
<v-list-item-title>View</v-list-item-title>
</v-list-item>
<v-list-item
v-if="recordInfo.shareOptions"
key="share"
@click="openEditDialog('share')"
>
<v-list-item-icon>
<v-icon>mdi-share-variant</v-icon>
</v-list-item-icon>
<v-list-item-title>Share</v-list-item-title>
</v-list-item>
<v-list-item
v-if="recordInfo.editOptions"
key="edit"
@click="openEditDialog('edit')"
>
<v-list-item-icon>
<v-icon>mdi-pencil</v-icon>
</v-list-item-icon>
<v-list-item-title>Edit</v-list-item-title>
</v-list-item>
<v-list-item
v-if="recordInfo.deleteOptions"
key="delete"
@click="openEditDialog('delete')"
>
<v-list-item-icon>
<v-icon>mdi-delete</v-icon>
</v-list-item-icon>
<v-list-item-title>Delete</v-list-item-title>
</v-list-item>
<v-divider v-if="recordInfo.expandTypes.length > 0"></v-divider>
<v-list-item
v-for="(item, i) in recordInfo.expandTypes"
:key="i"
dense
@click="goToPage(true, i)"
>
<v-list-item-icon>
<v-icon>{{ item.icon || item.recordInfo.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-title
>{{ item.name || item.recordInfo.name }}
<v-icon small right>mdi-open-in-new</v-icon>
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
<v-btn icon @click="close()">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-toolbar>
</template>
<template v-slot:footer-action>
<v-btn color="blue darken-1" text @click="close()">Close</v-btn>
<v-btn
v-if="recordInfo.shareOptions && mode === 'view'"
color="primary"
@click="goToPage()"
>
<v-icon left>mdi-open-in-new</v-icon> Go To Page</v-btn
>
</template>
</component>
</v-dialog>
Expand All @@ -45,6 +114,7 @@ import EditRecordInterface from '~/components/interface/crud/editRecordInterface
import ViewRecordInterface from '~/components/interface/crud/viewRecordInterface.vue'
import DeleteRecordInterface from '~/components/interface/crud/deleteRecordInterface.vue'
import ShareRecordInterface from '~/components/interface/crud/shareRecordInterface.vue'
import { goToPage } from '~/services/base'
const modesMap = {
add: {
Expand Down Expand Up @@ -103,40 +173,65 @@ export default {
required: false,
},
},
data() {
return {
overrideMode: null,
}
},
computed: {
computedMode() {
return this.overrideMode ?? this.mode
},
interfaceComponent() {
return (
this.recordInfo[this.mode + 'Options']?.component ??
modesMap[this.mode].defaultInterface
this.recordInfo[this.computedMode + 'Options']?.component ??
modesMap[this.computedMode].defaultInterface
)
},
title() {
return modesMap[this.mode].prefix + ' ' + this.recordInfo.name
return modesMap[this.computedMode].prefix + ' ' + this.recordInfo.name
},
icon() {
return modesMap[this.mode].icon
return modesMap[this.computedMode].icon
},
},
watch: {
status(val) {
if (val) {
this.reset()
}
},
},
methods: {
close() {
this.$emit('close')
},
// toggle the dialog to another mode
openEditDialog(mode) {
this.overrideMode = mode
},
goToPage() {
const routeData = this.$router.resolve({
name: this.recordInfo.viewRecordRoute,
query: {
id: this.selectedItem.id,
expand: this.$route.query.expand ?? 0,
},
})
window.open(routeData.href, '_blank')
goToPage(
this,
this.recordInfo.viewRecordRoute,
this.selectedItem,
...arguments
)
},
handleSubmit(data) {
this.close()
this.$emit('handleSubmit', data)
},
reset() {
this.overrideMode = null
},
},
}
</script>
52 changes: 9 additions & 43 deletions frontend/components/interface/crud/crudRecordInterface.vue
Original file line number Diff line number Diff line change
Expand Up @@ -309,49 +309,15 @@
{{ headerItem.text }}
</div>
<div class="v-data-table__mobile-row__cell truncate-mobile-row">
<div v-if="headerItem.value === null">
<nuxt-link
v-if="recordInfo.enterOptions && recordInfo.viewRecordRoute"
:to="recordInfo.viewRecordRoute + '?id=' + props.item.id"
>
<v-icon small icon>mdi-location-enter</v-icon>
</nuxt-link>
<v-icon
v-if="recordInfo.shareOptions"
class="mr-2"
@click.stop="openEditDialog('share', props.item)"
>mdi-share-variant</v-icon
>
<v-icon
v-if="recordInfo.viewOptions"
class="mr-2"
@click.stop="openEditDialog('view', props.item)"
>mdi-eye</v-icon
>
<v-icon
v-if="recordInfo.editOptions"
class="mr-2"
@click.stop="openEditDialog('edit', props.item)"
>mdi-pencil</v-icon
>
<v-icon
v-if="recordInfo.deleteOptions"
class="mr-2"
@click.stop="openEditDialog('delete', props.item)"
>mdi-delete</v-icon
>
</div>
<div v-else>
<component
:is="headerItem.fieldInfo.component"
v-if="headerItem.fieldInfo.component"
:item="props.item"
:field-path="headerItem.path"
></component>
<span v-else>
{{ getTableRowData(headerItem, props.item) }}
</span>
</div>
<component
:is="headerItem.fieldInfo.component"
v-if="headerItem.fieldInfo.component"
:item="props.item"
:field-path="headerItem.path"
></component>
<span v-else>
{{ getTableRowData(headerItem, props.item) }}
</span>
</div>
</template>
</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
: item.field
"
></component>
<span v-else>{{
<span v-else style="white-space: break-spaces">{{
getNestedProperty(currentItem, item.field)
}}</span>
</td>
Expand Down
14 changes: 7 additions & 7 deletions frontend/components/interface/viewPbCardInterface.vue
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,13 @@ export default {
text: 'Event',
value: 'event.name',
},
{ text: 'Single', value: 'single', width: '125px', align: 'right' },
{ text: 'Mo3', value: 'mo3', width: '125px', align: 'right' },
{ text: 'Ao5', value: 'ao5', width: '125px', align: 'right' },
{ text: 'Ao12', value: 'ao12', width: '125px', align: 'right' },
{ text: 'Ao50', value: 'ao50', width: '125px', align: 'right' },
{ text: 'Ao100', value: 'ao100', width: '125px', align: 'right' },
{ text: 'Ao1000', value: 'ao1000', width: '125px', align: 'right' },
{ text: 'Single', value: 'single', width: '130px', align: 'right' },
{ text: 'Mo3', value: 'mo3', width: '130px', align: 'right' },
{ text: 'Ao5', value: 'ao5', width: '130px', align: 'right' },
{ text: 'Ao12', value: 'ao12', width: '130px', align: 'right' },
{ text: 'Ao50', value: 'ao50', width: '130px', align: 'right' },
{ text: 'Ao100', value: 'ao100', width: '130px', align: 'right' },
{ text: 'Ao1000', value: 'ao1000', width: '130px', align: 'right' },
],
items: [],
Expand Down
14 changes: 0 additions & 14 deletions frontend/components/page/viewRecordPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,6 @@
{{ recordInfo.name }}
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn
v-if="recordInfo.editOptions"
icon
@click="openEditDialog('edit')"
>
<v-icon>mdi-pencil</v-icon>
</v-btn>
<v-btn
v-if="recordInfo.deleteOptions"
icon
@click="openEditDialog('delete')"
>
<v-icon>mdi-delete</v-icon>
</v-btn>
<v-menu left offset-x>
<template v-slot:activator="{ on, attrs }">
<v-icon v-bind="attrs" v-on="on"
Expand Down
Loading

0 comments on commit 51d0574

Please sign in to comment.