feat: Add new sidebar for Chatwoot V4 (#10291)
This PR has the initial version of the new sidebar targeted for the next major redesign of the app. This PR includes the following changes - Components in the `layouts-next` and `base-next` directories in `dashboard/components` - Two generic components `Avatar` and `Icon` - `SidebarGroup` component to manage expandable sidebar groups with nested navigation items. This includes handling active states, transitions, and permissions. - `SidebarGroupHeader` component to display the header of each navigation group with optional icons and active state indication. - `SidebarGroupLeaf` component for individual navigation items within a group, supporting icons and active state. - `SidebarGroupSeparator` component to visually separate nested navigation items. (They look a lot like header) - `SidebarGroupEmptyLeaf` component to render empty state of any navigation groups. ---- Co-authored-by: Pranav <pranav@chatwoot.com> Co-authored-by: Pranav <pranavrajs@gmail.com>
This commit is contained in:
@@ -1,14 +1,22 @@
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
|
||||
import NextSidebar from 'next/sidebar/Sidebar.vue';
|
||||
import Sidebar from '../../components/layout/Sidebar.vue';
|
||||
import { BUS_EVENTS } from 'shared/constants/busEvents';
|
||||
import WootKeyShortcutModal from 'dashboard/components/widgets/modal/WootKeyShortcutModal.vue';
|
||||
import AddAccountModal from 'dashboard/components/layout/sidebarComponents/AddAccountModal.vue';
|
||||
import AccountSelector from 'dashboard/components/layout/sidebarComponents/AccountSelector.vue';
|
||||
import AddLabelModal from 'dashboard/routes/dashboard/settings/labels/AddLabel.vue';
|
||||
import NotificationPanel from 'dashboard/routes/dashboard/notifications/components/NotificationPanel.vue';
|
||||
|
||||
import { useUISettings } from 'dashboard/composables/useUISettings';
|
||||
import { useAccount } from 'dashboard/composables/useAccount';
|
||||
|
||||
import wootConstants from 'dashboard/constants/globals';
|
||||
import { BUS_EVENTS } from 'shared/constants/busEvents';
|
||||
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
|
||||
|
||||
const CommandBar = defineAsyncComponent(
|
||||
() => import('./commands/commandbar.vue')
|
||||
);
|
||||
@@ -16,6 +24,7 @@ import { emitter } from 'shared/helpers/mitt';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
NextSidebar,
|
||||
Sidebar,
|
||||
CommandBar,
|
||||
WootKeyShortcutModal,
|
||||
@@ -26,10 +35,12 @@ export default {
|
||||
},
|
||||
setup() {
|
||||
const { uiSettings, updateUISettings } = useUISettings();
|
||||
const { accountId } = useAccount();
|
||||
|
||||
return {
|
||||
uiSettings,
|
||||
updateUISettings,
|
||||
accountId,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
@@ -44,6 +55,9 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
isFeatureEnabledonAccount: 'accounts/isFeatureEnabledonAccount',
|
||||
}),
|
||||
currentRoute() {
|
||||
return ' ';
|
||||
},
|
||||
@@ -62,6 +76,12 @@ export default {
|
||||
this.uiSettings;
|
||||
return showSecondarySidebar;
|
||||
},
|
||||
showNextSidebar() {
|
||||
return this.isFeatureEnabledonAccount(
|
||||
this.accountId,
|
||||
FEATURE_FLAGS.CHATWOOT_V4
|
||||
);
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
displayLayoutType() {
|
||||
@@ -155,7 +175,16 @@ export default {
|
||||
|
||||
<template>
|
||||
<div class="flex flex-wrap app-wrapper dark:text-slate-300">
|
||||
<NextSidebar
|
||||
v-if="showNextSidebar"
|
||||
@toggle-account-modal="toggleAccountModal"
|
||||
@open-notification-panel="openNotificationPanel"
|
||||
@open-key-shortcut-modal="toggleKeyShortcutModal"
|
||||
@close-key-shortcut-modal="closeKeyShortcutModal"
|
||||
@show-create-account-modal="openCreateAccountModal"
|
||||
/>
|
||||
<Sidebar
|
||||
v-else
|
||||
:route="currentRoute"
|
||||
:has-banner="hasBanner"
|
||||
:show-secondary-sidebar="isSidebarOpen"
|
||||
|
||||
@@ -71,7 +71,7 @@ export default {
|
||||
records: 'contacts/getContacts',
|
||||
uiFlags: 'contacts/getUIFlags',
|
||||
meta: 'contacts/getMeta',
|
||||
segments: 'customViews/getCustomViews',
|
||||
segments: 'customViews/getContactCustomViews',
|
||||
getAppliedContactFilters: 'contacts/getAppliedContactFilters',
|
||||
}),
|
||||
showEmptySearchResult() {
|
||||
|
||||
@@ -7,6 +7,8 @@ import { routes as inboxRoutes } from './inbox/routes';
|
||||
import { frontendURL } from '../../helper/URLHelper';
|
||||
import helpcenterRoutes from './helpcenter/helpcenter.routes';
|
||||
|
||||
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
|
||||
|
||||
const AppContainer = () => import('./Dashboard.vue');
|
||||
const Captain = () => import('./Captain.vue');
|
||||
const Suspended = () => import('./suspended/Index.vue');
|
||||
@@ -24,6 +26,7 @@ export default {
|
||||
component: Captain,
|
||||
meta: {
|
||||
permissions: ['administrator', 'agent'],
|
||||
featureFlag: FEATURE_FLAGS.CAPTAIN,
|
||||
},
|
||||
},
|
||||
...inboxRoutes,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
import { mapGetters } from 'vuex';
|
||||
import UpgradePage from './UpgradePage.vue';
|
||||
import NextSidebar from 'next/sidebar/Sidebar.vue';
|
||||
import { frontendURL } from '../../../../helper/URLHelper';
|
||||
import Sidebar from 'dashboard/components/layout/Sidebar.vue';
|
||||
import { BUS_EVENTS } from 'shared/constants/busEvents';
|
||||
@@ -22,6 +23,7 @@ const CommandBar = defineAsyncComponent(
|
||||
|
||||
export default {
|
||||
components: {
|
||||
NextSidebar,
|
||||
AccountSelector,
|
||||
AddCategory,
|
||||
CommandBar,
|
||||
@@ -68,6 +70,12 @@ export default {
|
||||
FEATURE_FLAGS.HELP_CENTER
|
||||
);
|
||||
},
|
||||
showNextSidebar() {
|
||||
return this.isFeatureEnabledonAccount(
|
||||
this.accountId,
|
||||
FEATURE_FLAGS.CHATWOOT_V4
|
||||
);
|
||||
},
|
||||
isSidebarOpen() {
|
||||
const { show_help_center_secondary_sidebar: showSecondarySidebar } =
|
||||
this.uiSettings;
|
||||
@@ -289,7 +297,15 @@ export default {
|
||||
|
||||
<template>
|
||||
<div class="flex flex-grow-0 w-full h-full min-h-0 app-wrapper">
|
||||
<NextSidebar
|
||||
v-if="showNextSidebar"
|
||||
@toggle-account-modal="toggleAccountModal"
|
||||
@open-notification-panel="openNotificationPanel"
|
||||
@open-key-shortcut-modal="toggleKeyShortcutModal"
|
||||
@close-key-shortcut-modal="closeKeyShortcutModal"
|
||||
/>
|
||||
<Sidebar
|
||||
v-else
|
||||
:route="currentRoute"
|
||||
@toggle-account-modal="toggleAccountModal"
|
||||
@open-notification-panel="openNotificationPanel"
|
||||
|
||||
@@ -7,6 +7,8 @@ import {
|
||||
CONVERSATION_PERMISSIONS,
|
||||
} from 'dashboard/constants/permissions.js';
|
||||
|
||||
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
|
||||
|
||||
export const routes = [
|
||||
{
|
||||
path: frontendURL('accounts/:accountId/inbox-view'),
|
||||
@@ -18,6 +20,7 @@ export const routes = [
|
||||
component: InboxEmptyStateView,
|
||||
meta: {
|
||||
permissions: [...ROLES, ...CONVERSATION_PERMISSIONS],
|
||||
featureFlag: FEATURE_FLAGS.INBOX_VIEW,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -26,6 +29,7 @@ export const routes = [
|
||||
component: InboxDetailView,
|
||||
meta: {
|
||||
permissions: [...ROLES, ...CONVERSATION_PERMISSIONS],
|
||||
featureFlag: FEATURE_FLAGS.INBOX_VIEW,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { frontendURL } from '../../../../helper/URLHelper';
|
||||
import { FEATURE_FLAGS } from 'dashboard/featureFlags';
|
||||
|
||||
const SettingsContent = () => import('../Wrapper.vue');
|
||||
const Index = () => import('./Index.vue');
|
||||
@@ -90,6 +91,7 @@ export default {
|
||||
name: 'bot_reports',
|
||||
meta: {
|
||||
permissions: ['administrator', 'report_manage'],
|
||||
featureFlag: FEATURE_FLAGS.RESPONSE_BOT,
|
||||
},
|
||||
component: BotReports,
|
||||
},
|
||||
@@ -184,6 +186,7 @@ export default {
|
||||
name: 'sla_reports',
|
||||
meta: {
|
||||
permissions: ['administrator', 'report_manage'],
|
||||
featureFlag: FEATURE_FLAGS.SLA,
|
||||
},
|
||||
component: SLAReports,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user