feat: Adds keyboard shortcuts for conversation actions (#2672)
* feat: Adds keyboard shortcuts for conversation actions * Minor fixes * Minor fixes * Minor fixes and add new shortcut * MInor fixes * Review fixes * Minor fixes * Code cleanup * Minor fixes * Uses Alt or Option key instead of shift-key * Review fixes * Review fixes Co-authored-by: Pranav Raj S <pranav@chatwoot.com> Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
parent
c7482696d4
commit
c523a953f7
15 changed files with 311 additions and 51 deletions
|
@ -10,8 +10,11 @@
|
|||
</template>
|
||||
<script>
|
||||
import wootConstants from '../../constants';
|
||||
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
|
||||
import { hasPressedAltAndNKey } from 'shared/helpers/KeyboardHelpers';
|
||||
|
||||
export default {
|
||||
mixins: [eventListenerMixins],
|
||||
props: {
|
||||
items: {
|
||||
type: Array,
|
||||
|
@ -28,6 +31,15 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
handleKeyEvents(e) {
|
||||
if (hasPressedAltAndNKey(e)) {
|
||||
if (this.activeTab === wootConstants.ASSIGNEE_TYPE.ALL) {
|
||||
this.onTabChange(0);
|
||||
} else {
|
||||
this.onTabChange(this.activeTabIndex + 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
onTabChange(selectedTabIndex) {
|
||||
if (this.items[selectedTabIndex].key !== this.activeTab) {
|
||||
this.$emit('chatTabChange', this.items[selectedTabIndex].key);
|
||||
|
|
|
@ -78,11 +78,17 @@
|
|||
|
||||
<script>
|
||||
import FileUpload from 'vue-upload-component';
|
||||
import {
|
||||
hasPressedAltAndWKey,
|
||||
hasPressedAltAndAKey,
|
||||
} from 'shared/helpers/KeyboardHelpers';
|
||||
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
|
||||
|
||||
import { REPLY_EDITOR_MODES } from './constants';
|
||||
export default {
|
||||
name: 'ReplyTopPanel',
|
||||
components: { FileUpload },
|
||||
mixins: [eventListenerMixins],
|
||||
props: {
|
||||
mode: {
|
||||
type: String,
|
||||
|
@ -156,6 +162,14 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
handleKeyEvents(e) {
|
||||
if (hasPressedAltAndWKey(e)) {
|
||||
this.toggleFormatMode();
|
||||
}
|
||||
if (hasPressedAltAndAKey(e)) {
|
||||
this.$refs.upload.$children[1].$el.click();
|
||||
}
|
||||
},
|
||||
toggleFormatMode() {
|
||||
this.setFormatMode(!this.isFormatMode);
|
||||
},
|
||||
|
|
|
@ -32,11 +32,17 @@
|
|||
<script>
|
||||
import { REPLY_EDITOR_MODES, CHAR_LENGTH_WARNING } from './constants';
|
||||
import EmojiOrIcon from 'shared/components/EmojiOrIcon';
|
||||
import {
|
||||
hasPressedAltAndPKey,
|
||||
hasPressedAltAndLKey,
|
||||
} from 'shared/helpers/KeyboardHelpers';
|
||||
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
|
||||
export default {
|
||||
name: 'ReplyTopPanel',
|
||||
components: {
|
||||
EmojiOrIcon,
|
||||
},
|
||||
mixins: [eventListenerMixins],
|
||||
props: {
|
||||
mode: {
|
||||
type: String,
|
||||
|
@ -76,6 +82,14 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
handleKeyEvents(e) {
|
||||
if (hasPressedAltAndPKey(e)) {
|
||||
this.handleNoteClick();
|
||||
}
|
||||
if (hasPressedAltAndLKey(e)) {
|
||||
this.handleReplyClick();
|
||||
}
|
||||
},
|
||||
handleReplyClick() {
|
||||
this.setReplyMode(REPLY_EDITOR_MODES.REPLY);
|
||||
},
|
||||
|
|
|
@ -12,12 +12,29 @@
|
|||
|
||||
<script>
|
||||
import wootConstants from '../../../constants';
|
||||
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
|
||||
import { hasPressedAltAndBKey } from 'shared/helpers/KeyboardHelpers';
|
||||
|
||||
export default {
|
||||
mixins: [eventListenerMixins],
|
||||
data: () => ({
|
||||
activeStatus: wootConstants.STATUS_TYPE.OPEN,
|
||||
}),
|
||||
methods: {
|
||||
handleKeyEvents(e) {
|
||||
if (hasPressedAltAndBKey(e)) {
|
||||
if (this.activeStatus === wootConstants.STATUS_TYPE.OPEN) {
|
||||
this.activeStatus = wootConstants.STATUS_TYPE.RESOLVED;
|
||||
} else if (this.activeStatus === wootConstants.STATUS_TYPE.RESOLVED) {
|
||||
this.activeStatus = wootConstants.STATUS_TYPE.PENDING;
|
||||
} else if (this.activeStatus === wootConstants.STATUS_TYPE.PENDING) {
|
||||
this.activeStatus = wootConstants.STATUS_TYPE.SNOOZED;
|
||||
} else if (this.activeStatus === wootConstants.STATUS_TYPE.SNOOZED) {
|
||||
this.activeStatus = wootConstants.STATUS_TYPE.OPEN;
|
||||
}
|
||||
}
|
||||
this.onTabChange();
|
||||
},
|
||||
onTabChange() {
|
||||
this.$store.dispatch('setChatFilter', this.activeStatus);
|
||||
this.$emit('statusFilterChange', this.activeStatus);
|
||||
|
|
|
@ -68,7 +68,9 @@ import { mapGetters } from 'vuex';
|
|||
import MoreActions from './MoreActions';
|
||||
import Thumbnail from '../Thumbnail';
|
||||
import agentMixin from '../../../mixins/agentMixin.js';
|
||||
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
|
||||
import AvailabilityStatusBadge from '../conversation/AvailabilityStatusBadge';
|
||||
import { hasPressedAltAndOKey } from 'shared/helpers/KeyboardHelpers';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
@ -76,7 +78,7 @@ export default {
|
|||
Thumbnail,
|
||||
AvailabilityStatusBadge,
|
||||
},
|
||||
mixins: [agentMixin],
|
||||
mixins: [agentMixin, eventListenerMixins],
|
||||
props: {
|
||||
chat: {
|
||||
type: Object,
|
||||
|
@ -117,6 +119,11 @@ export default {
|
|||
},
|
||||
|
||||
methods: {
|
||||
handleKeyEvents(e) {
|
||||
if (hasPressedAltAndOKey(e)) {
|
||||
this.$emit('contact-panel-toggle');
|
||||
}
|
||||
},
|
||||
assignAgent(agent) {
|
||||
this.$store
|
||||
.dispatch('assignAgent', {
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
import { mapGetters } from 'vuex';
|
||||
import { mixin as clickaway } from 'vue-clickaway';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
|
||||
|
||||
import EmojiInput from 'shared/components/emoji/EmojiInput';
|
||||
import CannedResponse from './CannedResponse';
|
||||
|
@ -105,7 +106,13 @@ export default {
|
|||
ReplyBottomPanel,
|
||||
WootMessageEditor,
|
||||
},
|
||||
mixins: [clickaway, inboxMixin, uiSettingsMixin, alertMixin],
|
||||
mixins: [
|
||||
clickaway,
|
||||
inboxMixin,
|
||||
uiSettingsMixin,
|
||||
alertMixin,
|
||||
eventListenerMixins,
|
||||
],
|
||||
props: {
|
||||
selectedTweet: {
|
||||
type: [Object, String],
|
||||
|
@ -289,12 +296,6 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener('keydown', this.handleKeyEvents);
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener('keydown', this.handleKeyEvents);
|
||||
},
|
||||
methods: {
|
||||
toggleUserMention(currentMentionState) {
|
||||
this.hasUserMention = currentMentionState;
|
||||
|
@ -353,6 +354,9 @@ export default {
|
|||
if (this.showRichContentEditor) {
|
||||
return;
|
||||
}
|
||||
if (this.$refs.messageInput === undefined) {
|
||||
return;
|
||||
}
|
||||
this.$nextTick(() => this.$refs.messageInput.focus());
|
||||
},
|
||||
emojiOnClick(emoji) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue