# Pull Request Template ## Description This PR adds new eslint rules to the code base. **Error rules** | Rule name | Type | Files updated | | ----------------- | --- | - | | `vue/block-order` | error | ✅ | | `vue/component-name-in-template-casing` | error | ✅ | | `vue/component-options-name-casing` | error | ✅ | | `vue/custom-event-name-casing` | error | ✅ | | `vue/define-emits-declaration` | error | ✅ | | `vue/no-unused-properties` | error | ✅ | | `vue/define-macros-order` | error | ✅ | | `vue/define-props-declaration` | error | ✅ | | `vue/match-component-import-name` | error | ✅ | | `vue/next-tick-style` | error | ✅ | | `vue/no-bare-strings-in-template` | error | ✅ | | `vue/no-empty-component-block` | error | ✅ | | `vue/no-multiple-objects-in-class` | error | ✅ | | `vue/no-required-prop-with-default` | error | ✅ | | `vue/no-static-inline-styles` | error | ✅ | | `vue/no-template-target-blank` | error | ✅ | | `vue/no-this-in-before-route-enter` | error | ✅ | | `vue/no-undef-components` | error | ✅ | | `vue/no-unused-emit-declarations` | error | ✅ | | `vue/no-unused-refs` | error | ✅ | | `vue/no-use-v-else-with-v-for` | error | ✅ | | `vue/no-useless-v-bind` | error | ✅ | | `vue/no-v-text` | error | ✅ | | `vue/padding-line-between-blocks` | error | ✅ | | ~`vue/prefer-prop-type-boolean-first`~ | ~error~ | ❌ (removed this rule, cause a bug in displaying custom attributes) | | `vue/prefer-separate-static-class` | error | ✅ | | `vue/prefer-true-attribute-shorthand` | error | ✅ | | `vue/require-explicit-slots` | error | ✅ | | `vue/require-macro-variable-name` | error | ✅ | **Warn rules** | Rule name | Type | Files updated | | ---- | ------------- | ------------- | | `vue/no-root-v-if` | warn | ❎ | Fixes https://linear.app/chatwoot/issue/CW-3492/vue-eslint-rules ## Type of change - [x] New feature (non-breaking change which adds functionality) ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Fayaz Ahmed <fayazara@gmail.com> Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> Co-authored-by: Shivam Mishra <scm.mymail@gmail.com> Co-authored-by: Pranav <pranav@chatwoot.com>
211 lines
5.8 KiB
Vue
211 lines
5.8 KiB
Vue
<script>
|
|
import { mapGetters } from 'vuex';
|
|
import { getSidebarItems } from './config/default-sidebar';
|
|
|
|
import PrimarySidebar from './sidebarComponents/Primary.vue';
|
|
import SecondarySidebar from './sidebarComponents/Secondary.vue';
|
|
import keyboardEventListenerMixins from 'shared/mixins/keyboardEventListenerMixins';
|
|
import router, { routesWithPermissions } from '../../routes';
|
|
import { hasPermissions } from '../../helper/permissionsHelper';
|
|
|
|
export default {
|
|
components: {
|
|
PrimarySidebar,
|
|
SecondarySidebar,
|
|
},
|
|
mixins: [keyboardEventListenerMixins],
|
|
props: {
|
|
showSecondarySidebar: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
sidebarClassName: {
|
|
type: String,
|
|
default: '',
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
showOptionsMenu: false,
|
|
};
|
|
},
|
|
|
|
computed: {
|
|
...mapGetters({
|
|
accountId: 'getCurrentAccountId',
|
|
currentUser: 'getCurrentUser',
|
|
globalConfig: 'globalConfig/get',
|
|
inboxes: 'inboxes/getInboxes',
|
|
isACustomBrandedInstance: 'globalConfig/isACustomBrandedInstance',
|
|
isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount',
|
|
isOnChatwootCloud: 'globalConfig/isOnChatwootCloud',
|
|
labels: 'labels/getLabelsOnSidebar',
|
|
teams: 'teams/getMyTeams',
|
|
}),
|
|
activeCustomView() {
|
|
if (this.activePrimaryMenu.key === 'contacts') {
|
|
return 'contact';
|
|
}
|
|
if (this.activePrimaryMenu.key === 'conversations') {
|
|
return 'conversation';
|
|
}
|
|
return '';
|
|
},
|
|
customViews() {
|
|
return this.$store.getters['customViews/getCustomViewsByFilterType'](
|
|
this.activeCustomView
|
|
);
|
|
},
|
|
isConversationOrContactActive() {
|
|
return (
|
|
this.activePrimaryMenu.key === 'contacts' ||
|
|
this.activePrimaryMenu.key === 'conversations'
|
|
);
|
|
},
|
|
sideMenuConfig() {
|
|
return getSidebarItems(this.accountId);
|
|
},
|
|
primaryMenuItems() {
|
|
const userPermissions = this.currentUser.permissions;
|
|
const menuItems = this.sideMenuConfig.primaryMenu;
|
|
return menuItems.filter(menuItem => {
|
|
const isAvailableForTheUser = hasPermissions(
|
|
routesWithPermissions[menuItem.toStateName],
|
|
userPermissions
|
|
);
|
|
|
|
if (!isAvailableForTheUser) {
|
|
return false;
|
|
}
|
|
if (
|
|
menuItem.alwaysVisibleOnChatwootInstances &&
|
|
!this.isACustomBrandedInstance
|
|
) {
|
|
return true;
|
|
}
|
|
if (menuItem.featureFlag) {
|
|
return this.isFeatureEnabledonAccount(
|
|
this.accountId,
|
|
menuItem.featureFlag
|
|
);
|
|
}
|
|
return true;
|
|
});
|
|
},
|
|
activeSecondaryMenu() {
|
|
const { secondaryMenu } = this.sideMenuConfig;
|
|
const { name: currentRoute } = this.$route;
|
|
|
|
const activeSecondaryMenu =
|
|
secondaryMenu.find(menuItem =>
|
|
menuItem.routes.includes(currentRoute)
|
|
) || {};
|
|
return activeSecondaryMenu;
|
|
},
|
|
activePrimaryMenu() {
|
|
const activePrimaryMenu =
|
|
this.primaryMenuItems.find(
|
|
menuItem => menuItem.key === this.activeSecondaryMenu.parentNav
|
|
) || {};
|
|
return activePrimaryMenu;
|
|
},
|
|
},
|
|
|
|
watch: {
|
|
activeCustomView() {
|
|
this.fetchCustomViews();
|
|
},
|
|
},
|
|
mounted() {
|
|
this.$store.dispatch('labels/get');
|
|
this.$store.dispatch('inboxes/get');
|
|
this.$store.dispatch('notifications/unReadCount');
|
|
this.$store.dispatch('teams/get');
|
|
this.$store.dispatch('attributes/get');
|
|
this.fetchCustomViews();
|
|
},
|
|
|
|
methods: {
|
|
fetchCustomViews() {
|
|
if (this.isConversationOrContactActive) {
|
|
this.$store.dispatch('customViews/get', this.activeCustomView);
|
|
}
|
|
},
|
|
toggleKeyShortcutModal() {
|
|
this.$emit('openKeyShortcutModal');
|
|
},
|
|
closeKeyShortcutModal() {
|
|
this.$emit('closeKeyShortcutModal');
|
|
},
|
|
getKeyboardEvents() {
|
|
return {
|
|
'$mod+Slash': this.toggleKeyShortcutModal,
|
|
'$mod+Escape': this.closeKeyShortcutModal,
|
|
'Alt+KeyC': {
|
|
action: () => this.navigateToRoute('home'),
|
|
},
|
|
'Alt+KeyV': {
|
|
action: () => this.navigateToRoute('contacts_dashboard'),
|
|
},
|
|
'Alt+KeyR': {
|
|
action: () => this.navigateToRoute('account_overview_reports'),
|
|
},
|
|
'Alt+KeyS': {
|
|
action: () => this.navigateToRoute('agent_list'),
|
|
},
|
|
};
|
|
},
|
|
navigateToRoute(routeName) {
|
|
if (!this.isCurrentRouteSameAsNavigation(routeName)) {
|
|
router.push({ name: routeName });
|
|
}
|
|
},
|
|
isCurrentRouteSameAsNavigation(routeName) {
|
|
return this.$route.name === routeName;
|
|
},
|
|
toggleSupportChatWindow() {
|
|
window.$chatwoot.toggle();
|
|
},
|
|
toggleAccountModal() {
|
|
this.$emit('toggleAccountModal');
|
|
},
|
|
showAddLabelPopup() {
|
|
this.$emit('showAddLabelPopup');
|
|
},
|
|
openNotificationPanel() {
|
|
this.$emit('openNotificationPanel');
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<aside class="flex h-full">
|
|
<PrimarySidebar
|
|
:logo-source="globalConfig.logoThumbnail"
|
|
:installation-name="globalConfig.installationName"
|
|
:is-a-custom-branded-instance="isACustomBrandedInstance"
|
|
:account-id="accountId"
|
|
:menu-items="primaryMenuItems"
|
|
:active-menu-item="activePrimaryMenu.key"
|
|
@toggleAccounts="toggleAccountModal"
|
|
@openKeyShortcutModal="toggleKeyShortcutModal"
|
|
@openNotificationPanel="openNotificationPanel"
|
|
/>
|
|
<SecondarySidebar
|
|
v-if="showSecondarySidebar"
|
|
:class="sidebarClassName"
|
|
:account-id="accountId"
|
|
:inboxes="inboxes"
|
|
:labels="labels"
|
|
:teams="teams"
|
|
:custom-views="customViews"
|
|
:menu-config="activeSecondaryMenu"
|
|
:current-user="currentUser"
|
|
:is-on-chatwoot-cloud="isOnChatwootCloud"
|
|
@addLabel="showAddLabelPopup"
|
|
@toggleAccounts="toggleAccountModal"
|
|
/>
|
|
</aside>
|
|
</template>
|