Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI Modal for Flagging ContentNodes #4375

Draft
wants to merge 1 commit into
base: unstable
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,80 +1,93 @@
<template>

<DraggableItem
:draggableId="contentNode.id"
:draggableMetadata="contentNode"
:dragEffect="dragEffect"
:dropEffect="draggableDropEffect"
:beforeStyle="dragBeforeStyle"
:afterStyle="dragAfterStyle"
>
<template #default>
<ContentNodeListItem
:node="contentNode"
:compact="compact"
:comfortable="comfortable"
:active="active"
:canEdit="canEdit"
:draggableHandle="{
grouped: selected,
draggable,
draggableMetadata: contentNode,
effectAllowed: draggableEffectAllowed,
}"
:aria-selected="selected"
class="content-node-edit-item"
@infoClick="$emit('infoClick', $event)"
@topicChevronClick="$emit('topicChevronClick', $event)"
>
<template #actions-start="{ hover }">
<VListTileAction class="handle-col" :aria-hidden="!hover" @click.stop>
<transition name="fade">
<VBtn :disabled="copying" flat icon>
<Icon color="#686868">
drag_indicator
</Icon>
</VBtn>
</transition>
</VListTileAction>
<VListTileAction class="mx-2 select-col" @click.stop>
<Checkbox
v-model="selected"
:disabled="copying"
class="mt-0 pt-0"
@dblclick.stop
/>
</VListTileAction>
</template>
<div>
<DraggableItem
:draggableId="contentNode.id"
:draggableMetadata="contentNode"
:dragEffect="dragEffect"
:dropEffect="draggableDropEffect"
:beforeStyle="dragBeforeStyle"
:afterStyle="dragAfterStyle"
>
<template #default>
<ContentNodeListItem
:node="contentNode"
:compact="compact"
:comfortable="comfortable"
:active="active"
:canEdit="canEdit"
:draggableHandle="{
grouped: selected,
draggable,
draggableMetadata: contentNode,
effectAllowed: draggableEffectAllowed,
}"
:aria-selected="selected"
class="content-node-edit-item"
@infoClick="$emit('infoClick', $event)"
@topicChevronClick="$emit('topicChevronClick', $event)"
>
<template #actions-start="{ hover }">
<VListTileAction class="handle-col" :aria-hidden="!hover" @click.stop>
<transition name="fade">
<VBtn :disabled="copying" flat icon>
<Icon color="#686868">
drag_indicator
</Icon>
</VBtn>
</transition>
</VListTileAction>
<VListTileAction class="mx-2 select-col" @click.stop>
<Checkbox
v-model="selected"
:disabled="copying"
class="mt-0 pt-0"
@dblclick.stop
/>
</VListTileAction>
</template>

<template #actions-end>
<VListTileAction :aria-hidden="!active" class="action-icon px-1">
<Menu v-model="activated">
<template #activator="{ on }">
<IconButton
icon="optionsVertical"
:text="$tr('optionsTooltip')"
size="small"
:disabled="copying"
v-on="on"
@click.stop
<template #actions-end>
<VListTileAction :aria-hidden="!active" class="action-icon px-1">
<Menu v-model="activated">
<template #activator="{ on }">
<IconButton
icon="optionsVertical"
:text="$tr('optionsTooltip')"
size="small"
:disabled="copying"
v-on="on"
@click.stop
/>
</template>
<ContentNodeOptions
v-if="!copying"
:nodeId="nodeId"
@node-flagged="showFlagFeedbackModal = true"
/>
</template>
<ContentNodeOptions v-if="!copying" :nodeId="nodeId" />
</Menu>
</VListTileAction>
</template>
</Menu>
</VListTileAction>
</template>

<template #context-menu="{ showContextMenu, positionX, positionY }">
<ContentNodeContextMenu
:show="showContextMenu"
:positionX="positionX"
:positionY="positionY"
:nodeId="nodeId"
/>
</template>
</ContentNodeListItem>
</template>
</DraggableItem>

<FlagFeedbackModal
v-if="showFlagFeedbackModal"
v-model="showFlagFeedbackModal"
:nodeId="nodeId"
/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of embedding the modal in each content node list item, having the component emit an event to a common place in the UI, makes more sense.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't remember why I did this way 🤔

@ozer550 will you be willing to refactor this and take this forward?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah no worries @vkWeb! I talked to @ozer550 about this. Happy to make the update too

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good :D

Btw upon trying to remember, my mind trace says that --

Most probably I did this because Vue allows emmiting events from a parent to a direct child only. So I had to catch the event on contentnode list item, I was not able to catch the event anywhere else.

The workaround for this was to utilise an event bus. So to keep things simple I might have done this.


<template #context-menu="{ showContextMenu, positionX, positionY }">
<ContentNodeContextMenu
:show="showContextMenu"
:positionX="positionX"
:positionY="positionY"
:nodeId="nodeId"
/>
</template>
</ContentNodeListItem>
</template>
</DraggableItem>
</div>

</template>

Expand All @@ -85,6 +98,7 @@

import ContentNodeListItem from './ContentNodeListItem';
import ContentNodeOptions from './ContentNodeOptions';
import FlagFeedbackModal from './FlagFeedbackModal';
import ContentNodeContextMenu from './ContentNodeContextMenu';
import Checkbox from 'shared/views/form/Checkbox';
import IconButton from 'shared/views/IconButton';
Expand All @@ -102,6 +116,7 @@
ContentNodeContextMenu,
Checkbox,
IconButton,
FlagFeedbackModal,
},
props: {
nodeId: {
Expand Down Expand Up @@ -137,6 +152,7 @@
data() {
return {
activated: false,
showFlagFeedbackModal: false,
};
},
computed: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
<VListTile v-if="canEdit" @click="removeNode()">
<VListTileTitle>{{ $tr('remove') }}</VListTileTitle>
</VListTile>
<VListTile v-if="canShowFlagOption" @click="$emit('node-flagged')">
<VListTileTitle>{{ $tr('flag') }}</VListTileTitle>
</VListTile>
</VList>

</template>
Expand Down Expand Up @@ -69,8 +72,9 @@
};
},
computed: {
...mapGetters('currentChannel', ['canEdit', 'trashId']),
...mapGetters('currentChannel', ['canEdit', 'trashId', 'currentChannel']),
...mapGetters('contentNode', ['getContentNode', 'getContentNodeDescendants']),
...mapGetters(['isAdmin', 'isAIFeatureEnabled']),
node() {
return this.getContentNode(this.nodeId);
},
Expand All @@ -95,6 +99,11 @@
},
};
},
canShowFlagOption() {
return (
this.isAIFeatureEnabled && !this.isTopic && (!this.currentChannel.edit || this.isAdmin)
);
},
},
watch: {
moveModalOpen(open) {
Expand Down Expand Up @@ -222,6 +231,7 @@
copiedSnackbar: 'Copy operation complete',
copiedToClipboardSnackbar: 'Copied to clipboard',
removedItems: 'Sent to trash',
flag: 'Flag content',
},
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<template>

<KModal
:title="$tr('flagFeedBackModalTitle')"
:submitText="$tr('flagSubmitButtonLabel')"
:cancelText="$tr('flagCancelButtonLabel')"
:submitDisabled="isSubmitDisabled"
@cancel="modalShowing = false"
@submit="handleSubmit"
@dblclick.native.capture.stop
>
<VList>
<VListTile @click.stop>
<VListTileAction>
<VCheckbox v-model="reportViolent" color="primary" />
</VListTileAction>
<VListTileContent @click="reportViolent = !reportViolent">
<VListTileTitle>{{ $tr('reportViolentTitle') }}</VListTileTitle>
</VListTileContent>
</VListTile>

<VListTile @click.stop>
<VListTileAction>
<VCheckbox v-model="reportHateful" color="primary" />
</VListTileAction>
<VListTileContent @click="reportHateful = !reportHateful">
<VListTileTitle>{{ $tr('reportHatefulTitle') }}</VListTileTitle>
</VListTileContent>
</VListTile>

<VListTile @click.stop>
<VListTileAction>
<VCheckbox v-model="reportHarmful" color="primary" />
</VListTileAction>
<VListTileContent @click="reportHarmful = !reportHarmful">
<VListTileTitle>{{ $tr('reportHarmfulTitle') }}</VListTileTitle>
</VListTileContent>
</VListTile>

<VListTile @click.stop>
<VListTileAction>
<VCheckbox v-model="reportSpam" color="primary" />
</VListTileAction>
<VListTileContent @click="reportSpam = !reportSpam">
<VListTileTitle>{{ $tr('reportSpamTitle') }}</VListTileTitle>
</VListTileContent>
</VListTile>

<VListTile @click.stop>
<VListTileAction>
<VCheckbox v-model="reportSexual" color="primary" />
</VListTileAction>
<VListTileContent @click="reportSexual = !reportSexual">
<VListTileTitle>{{ $tr('reportSexualTitle') }}</VListTileTitle>
</VListTileContent>
</VListTile>
</VList>
</KModal>

</template>

<script>

import { mapGetters } from 'vuex';

export default {
name: 'FlagFeedbackModal',
props: {
nodeId: {
type: String,
required: true,
},
},
data() {
return {
reportViolent: false,
reportHateful: false,
reportHarmful: false,
reportSpam: false,
reportSexual: false,
};
},
computed: {
...mapGetters('contentNode', ['getContentNode']),
targetContentNode() {
return this.getContentNode(this.nodeId);
},
modalShowing: {
get() {
return this.value;
},
set(value) {
this.$emit('input', value);
},
},
reportList() {
return [
this.reportViolent,
this.reportHateful,
this.reportHarmful,
this.reportSpam,
this.reportSexual,
];
},
isSubmitDisabled() {
const anyOneCheckboxTick = this.reportList.some(report => report === true);
return !anyOneCheckboxTick; // if any one checkbox is tick, enable submit.
},
},
methods: {
handleSubmit() {
/* NOTE: This is just a placeholder method. It will be implemented after
feedbackApiUtils PR is merged. */
console.log(`Node with title "${this.targetContentNode.title}" is flagged!`);
},
},
$trs: {
flagFeedBackModalTitle: 'Flag content',
reportViolentTitle: 'Violent or repulsive content',
reportHatefulTitle: 'Hateful or abusive content',
reportHarmfulTitle: 'Harmful or dangerous acts',
reportSpamTitle: 'Spam or misleading',
reportSexualTitle: 'Sexual Content',
flagCancelButtonLabel: 'Cancel',
flagSubmitButtonLabel: 'Flag',
},
};

</script>