Skip to content

Commit

Permalink
Adding context menu to discussion posts (#156)
Browse files Browse the repository at this point in the history
* added actions to the discussion post context menus

* Changed the backend user object to send back the clientId in the basic user object, this is used to check if the user made a post and present a context menu

* new ContextMenu.vue duplicates the DropDownMenu.vue functionality and turns it from hover to click. This is not quite right

* lots of changes: swapped dropdown and contextmenu icons, contextmenu will now open on click and close when unfocused or an action is taken on the menu. ContextMenu styling changes

* Fixed frontend test

* Lots of fixes, trying to figure out how to test this

* Frontend linting

* Removed a .only in front end test
  • Loading branch information
JmScherer authored Jan 12, 2024
1 parent 7fcd650 commit 006b10e
Show file tree
Hide file tree
Showing 12 changed files with 263 additions and 61 deletions.
2 changes: 1 addition & 1 deletion backend/src/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ class User(BaseModel):
full_name: Optional[str] = None
disabled: Optional[bool] = None
scope: Optional[str] = None
client_id: str


class AccessUserAPI(User):
""" This extends the user class to include the user's credentials for API access """
client_id: str
client_secret: Optional[str] = None


Expand Down
61 changes: 52 additions & 9 deletions frontend/src/components/AnalysisView/DiscussionPost.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
<template>
<div class="discussion-post" data-test="discussion-post">
<div class="discussion-header" data-test="discussion-post-header">
<div>
<b>{{ author_name }}</b>
{{ timestamp }}
</div>
<ul v-if="isUser" class="context-menu" data-test="discussion-post-context-menu">
<ContextMenu :actions="actions" :context_id="id">
<font-awesome-icon class="header-icon" icon="ellipsis-vertical" size="xl" />
</ContextMenu>
</ul>
</div>
<div class="discussion-content" data-test="discussion-post-content">
{{ content }}
Expand All @@ -11,8 +18,13 @@
</template>

<script>
import ContextMenu from '@/components/ContextMenu.vue';
export default {
name: 'discussion-post',
components: {
ContextMenu,
},
props: {
id: {
type: String,
Expand Down Expand Up @@ -41,38 +53,69 @@ export default {
return [];
},
},
userClientId: {
type: String,
},
actions: {
type: Array,
},
},
computed: {
timestamp: function() {
return new Date(this.publish_timestamp).toUTCString();
},
isUser: function() {
return this.userClientId == this.author_id;
},
},
};
</script>

<style scoped>
.discussion-post {
border-radius: var(--content-border-radius);
padding: var(--p-8);
margin-top: var(--p-10);
border-radius: var(--content-border-radius);
padding: var(--p-8);
margin-top: var(--p-10);
}
.discussion-post:nth-child(even) {
background-color: var(--rosalution-grey-50);
background-color: var(--rosalution-grey-50);
}
.discussion-post:nth-child(odd) {
background-color: var(--rosalution-grey-100);
background-color: var(--rosalution-grey-100);
}
.discussion-header {
margin-top: var(--p-5);
margin-bottom: var(--p-5);
display: flex;
justify-content: space-between;
margin-top: var(--p-5);
margin-bottom: var(--p-5);
}
.discussion-content {
margin-bottom: var(--p-10);
margin-bottom: var(--p-10);
}
.fill {
width: 100%;
}
.context-menu {
display:flex;
flex-wrap: nowrap;
justify-content: right;
margin-right: var(--p-10);
}
.actions-menu > li {
float: left;
}
.header-icon {
color: var(--rosalution-purple-300);
cursor: pointer;
padding: var(--p-5)
}
</style>
79 changes: 45 additions & 34 deletions frontend/src/components/AnalysisView/DiscussionSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,41 +17,43 @@
</div>
<div class="rosalution-section-seperator"></div>
<div class="section-content">
<div v-if="this.showNewPost" class="discussion-new-post">
<textarea
contenteditable="plaintext-only"
class="discussion-new-post-text-area"
v-model="newPostContent"
data-test="new-discussion-input"
/>
<div class="discussion-actions">
<button
class="secondary-button"
@click="cancelNewDiscussionPost"
data-test="new-discussion-cancel"
>
Cancel
</button>
<button
class="primary-button publish-button"
@click="newDiscussionPost"
data-test="new-discussion-publish"
:disabled="this.checkPostContent"
>
Publish
</button>
</div>
</div>
<DiscussionPost v-for="discussion in discussions"
:id="discussion.post_id"
:key="discussion.post_id"
:author_id="discussion.author_id"
:author_name="discussion.author_fullname"
:publish_timestamp="discussion.publish_timestamp"
:content="discussion.content"
:attachments="discussion.attachments"
:thread="discussion.thread"
<div v-if="this.showNewPost" class="discussion-new-post">
<textarea
contenteditable="plaintext-only"
class="discussion-new-post-text-area"
v-model="newPostContent"
data-test="new-discussion-input"
/>
<div class="discussion-actions">
<button
class="secondary-button"
@click="cancelNewDiscussionPost"
data-test="new-discussion-cancel"
>
Cancel
</button>
<button
class="primary-button publish-button"
@click="newDiscussionPost"
data-test="new-discussion-publish"
:disabled="this.checkPostContent"
>
Publish
</button>
</div>
</div>
<DiscussionPost v-for="discussion in discussions"
:id="discussion.post_id"
:key="discussion.post_id"
:author_id="discussion.author_id"
:author_name="discussion.author_fullname"
:publish_timestamp="discussion.publish_timestamp"
:content="discussion.content"
:attachments="discussion.attachments"
:thread="discussion.thread"
:userClientId="userClientId"
:actions="actions"
/>
</div>
</div>
</template>
Expand All @@ -75,6 +77,15 @@ export default {
return [];
},
},
userClientId: {
type: String,
},
actions: {
type: Array,
default: () => {
return [];
},
},
},
data: function() {
return {
Expand Down
85 changes: 85 additions & 0 deletions frontend/src/components/ContextMenu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<template>
<li tabindex="1" ref="contextRef">
<slot></slot>
<ul class="grey-rounded-menu drop-down-content">
<li v-for="action in actions" :key="action.text" @click="this.runAction(action.operation)">
<span> {{ action.text }} </span>
<font-awesome-icon v-if="action.icon" :icon="action.icon" size="lg" class="right-side-icon" />
</li>
</ul>
</li>
</template>

<script>
export default {
name: 'context-menu',
props: {
actions: {
type: Array,
validator: (prop) => prop.every(
(action) => action.text !== undefined || action.divider,
),
},
context_id: String,
},
methods: {
runAction(actionOperation) {
actionOperation(this.context_id);
this.closeContext();
},
closeContext() {
this.$refs.contextRef.blur();
},
},
};
</script>

<style scoped>
hr {
border: 1px solid var(--rosalution-grey-100);
}
.grey-rounded-menu {
border-radius: var(--content-border-radius);
background-color: var(--rosalution-white);
border: 3px solid var(--rosalution-grey-000);
width: 175px;
padding: .75rem;
margin-right: var(--p-16)
}
ul li ul {
visibility: hidden;
opacity: 0;
position: absolute;
transition: all 0.5s ease;
right: 0;
display: none;
}
ul li ul:hover li:hover {
color: var(--rosalution-purple-300);
background-color: var(--rosalution-purple-100);
}
ul li ul li {
clear: both;
width: 100%;
line-height: 2rem;
}
li:focus ul {
visibility: visible;
opacity: 1;
display: block;
}
.drop-down-content {
text-align: right;
}
.right-side-icon {
margin-left: var(--p-8);
margin-bottom: 0.12rem;
}
</style>
2 changes: 1 addition & 1 deletion frontend/src/components/RosalutionHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
</router-link>
</drop-down-menu>
<drop-down-menu v-if="actionsExist" :actions="actions" data-test="user-menu">
<font-awesome-icon class="header-icon" icon="ellipsis-vertical" size="xl" />
<font-awesome-icon class="header-icon" icon="bars" size="xl" />
</drop-down-menu>
</ul>
</div>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
faAsterisk, faPause, faCheck, faX, faUser, faUsers, faUserGroup, faCalendar, faBookOpen, faList, faLayerGroup,
faBoxArchive, faQuestion, faClock, faClipboardCheck, faMagnifyingGlass, faChevronDown, faChevronRight,
faUpRightFromSquare, faCirclePlus, faPencil, faEllipsisVertical, faLink, faXmark, faUserDoctor, faPaperclip, faPlus,
faAnglesRight, faFileImage, faFileCirclePlus, faMountainSun, faArrowUp, faArrowDown,
faAnglesRight, faFileImage, faFileCirclePlus, faMountainSun, faArrowUp, faArrowDown, faCaretDown, faBars,
} from '@fortawesome/free-solid-svg-icons';
import {
faCopy, faFile, faComment, faCircleCheck, faCircleQuestion, faCircleXmark, faImages,
Expand All @@ -35,7 +35,7 @@ library.add(
faLayerGroup, faBoxArchive, faQuestion, faClock, faClipboardCheck, faChevronDown, faChevronRight,
faUpRightFromSquare, faCopy, faCirclePlus, faFile, faComment, faPencil, faEllipsisVertical, faLink, faXmark,
faUserDoctor, faPaperclip, faPlus, faAnglesRight, faCircleCheck, faCircleQuestion, faCircleXmark, faImages,
faFileImage, faFileCirclePlus, faMountainSun, faArrowUp, faArrowDown,
faFileImage, faFileCirclePlus, faMountainSun, faArrowUp, faArrowDown, faCaretDown, faBars,
);

// The NotFoundView should always be last because it's an ordered array.
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/stores/authStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ const authStore = {
this.state.username = user['username'];
this.state.email = user['email'];
this.state.roles.push(user['scope']);
this.state.clientId = user['client_id'];

user['client_id'] ? this.state.clientId = user['client_id'] : '';
user['client_secret'] ? this.state.clientSecret = user['client_secret'] : '';
},
getUser() {
Expand Down
21 changes: 20 additions & 1 deletion frontend/src/views/AnalysisView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
<DiscussionSection
id="Discussion"
:discussions="this.discussions"
:userClientId="auth.getClientId()"
:actions="this.discussionContextActions"
@discussion:new-post="this.addDiscussionPost"
/>
<SupplementalFormList
Expand Down Expand Up @@ -200,7 +202,24 @@ export default {
return actionChoices;
},
discussionContextActions() {
return [
{
icon: 'pencil',
text: 'Edit',
operation: (postId) => {
console.log(`Editing Discussion Post: ${postId}`);
},
},
{
icon: 'xmark',
text: 'Delete',
operation: (postId) => {
console.log(`Deleting Discussion Post: ${postId}`);
},
},
];
},
sectionsList() {
return this.analysis.sections;
},
Expand Down
Loading

0 comments on commit 006b10e

Please sign in to comment.