refactor: improvements to the dashboard sidebar (#3709)

Co-authored-by: jamesgeorge007 <jamesgeorge998001@gmail.com>
This commit is contained in:
Joel Jacob Stephen
2024-01-23 21:55:42 +05:30
committed by GitHub
parent d1f6f40ef8
commit ba52c8cc37
2 changed files with 42 additions and 117 deletions

View File

@@ -1,9 +1,9 @@
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core';
import '@vue/runtime-core'
export {};
export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
@@ -13,8 +13,6 @@ declare module '@vue/runtime-core' {
AppModal: typeof import('./components/app/Modal.vue')['default']
AppSidebar: typeof import('./components/app/Sidebar.vue')['default']
AppToast: typeof import('./components/app/Toast.vue')['default']
ButtonPrimary: typeof import('./../../hoppscotch-ui/src/components/button/Primary.vue')['default']
ButtonSecondary: typeof import('./../../hoppscotch-ui/src/components/button/Secondary.vue')['default']
DashboardMetricsCard: typeof import('./components/dashboard/MetricsCard.vue')['default']
HoppButtonPrimary: typeof import('@hoppscotch/ui')['HoppButtonPrimary']
HoppButtonSecondary: typeof import('@hoppscotch/ui')['HoppButtonSecondary']
@@ -23,6 +21,7 @@ declare module '@vue/runtime-core' {
HoppSmartConfirmModal: typeof import('@hoppscotch/ui')['HoppSmartConfirmModal']
HoppSmartInput: typeof import('@hoppscotch/ui')['HoppSmartInput']
HoppSmartItem: typeof import('@hoppscotch/ui')['HoppSmartItem']
HoppSmartLink: typeof import('@hoppscotch/ui')['HoppSmartLink']
HoppSmartModal: typeof import('@hoppscotch/ui')['HoppSmartModal']
HoppSmartPicture: typeof import('@hoppscotch/ui')['HoppSmartPicture']
HoppSmartSpinner: typeof import('@hoppscotch/ui')['HoppSmartSpinner']
@@ -30,42 +29,13 @@ declare module '@vue/runtime-core' {
HoppSmartTable: typeof import('@hoppscotch/ui')['HoppSmartTable']
HoppSmartTabs: typeof import('@hoppscotch/ui')['HoppSmartTabs']
HoppSmartToggle: typeof import('@hoppscotch/ui')['HoppSmartToggle']
IconLucideArrowLeft: typeof import('~icons/lucide/arrow-left')['default']
IconLucideChevronDown: typeof import('~icons/lucide/chevron-down')['default']
IconLucideInbox: typeof import('~icons/lucide/inbox')['default']
IconLucideUser: typeof import('~icons/lucide/user')['default']
SettingsAuthProvider: typeof import('./components/settings/AuthProvider.vue')['default']
SettingsConfigurations: typeof import('./components/settings/Configurations.vue')['default']
SettingsReset: typeof import('./components/settings/Reset.vue')['default']
SettingsServerRestart: typeof import('./components/settings/ServerRestart.vue')['default']
SettingsSmtpConfiguration: typeof import('./components/settings/SmtpConfiguration.vue')['default']
SmartAnchor: typeof import('./../../hoppscotch-ui/src/components/smart/Anchor.vue')['default']
SmartAutoComplete: typeof import('./../../hoppscotch-ui/src/components/smart/AutoComplete.vue')['default']
SmartCheckbox: typeof import('./../../hoppscotch-ui/src/components/smart/Checkbox.vue')['default']
SmartConfirmModal: typeof import('./../../hoppscotch-ui/src/components/smart/ConfirmModal.vue')['default']
SmartExpand: typeof import('./../../hoppscotch-ui/src/components/smart/Expand.vue')['default']
SmartFileChip: typeof import('./../../hoppscotch-ui/src/components/smart/FileChip.vue')['default']
SmartInput: typeof import('./../../hoppscotch-ui/src/components/smart/Input.vue')['default']
SmartIntersection: typeof import('./../../hoppscotch-ui/src/components/smart/Intersection.vue')['default']
SmartItem: typeof import('./../../hoppscotch-ui/src/components/smart/Item.vue')['default']
SmartLink: typeof import('./../../hoppscotch-ui/src/components/smart/Link.vue')['default']
SmartModal: typeof import('./../../hoppscotch-ui/src/components/smart/Modal.vue')['default']
SmartPicture: typeof import('./../../hoppscotch-ui/src/components/smart/Picture.vue')['default']
SmartPlaceholder: typeof import('./../../hoppscotch-ui/src/components/smart/Placeholder.vue')['default']
SmartProgressRing: typeof import('./../../hoppscotch-ui/src/components/smart/ProgressRing.vue')['default']
SmartRadio: typeof import('./../../hoppscotch-ui/src/components/smart/Radio.vue')['default']
SmartRadioGroup: typeof import('./../../hoppscotch-ui/src/components/smart/RadioGroup.vue')['default']
SmartSelectWrapper: typeof import('./../../hoppscotch-ui/src/components/smart/SelectWrapper.vue')['default']
SmartSlideOver: typeof import('./../../hoppscotch-ui/src/components/smart/SlideOver.vue')['default']
SmartSpinner: typeof import('./../../hoppscotch-ui/src/components/smart/Spinner.vue')['default']
SmartTab: typeof import('./../../hoppscotch-ui/src/components/smart/Tab.vue')['default']
SmartTable: typeof import('./../../hoppscotch-ui/src/components/smart/Table.vue')['default']
SmartTabs: typeof import('./../../hoppscotch-ui/src/components/smart/Tabs.vue')['default']
SmartToggle: typeof import('./../../hoppscotch-ui/src/components/smart/Toggle.vue')['default']
SmartTree: typeof import('./../../hoppscotch-ui/src/components/smart/Tree.vue')['default']
SmartTreeBranch: typeof import('./../../hoppscotch-ui/src/components/smart/TreeBranch.vue')['default']
SmartWindow: typeof import('./../../hoppscotch-ui/src/components/smart/Window.vue')['default']
SmartWindows: typeof import('./../../hoppscotch-ui/src/components/smart/Windows.vue')['default']
TeamsAdd: typeof import('./components/teams/Add.vue')['default']
TeamsDetails: typeof import('./components/teams/Details.vue')['default']
TeamsInvite: typeof import('./components/teams/Invite.vue')['default']
@@ -76,27 +46,6 @@ declare module '@vue/runtime-core' {
UsersDetails: typeof import('./components/users/Details.vue')['default']
UsersInviteModal: typeof import('./components/users/InviteModal.vue')['default']
UsersSharedRequests: typeof import('./components/users/SharedRequests.vue')['default']
AppHeader: typeof import('./components/app/Header.vue')['default'];
AppLogin: typeof import('./components/app/Login.vue')['default'];
AppLogout: typeof import('./components/app/Logout.vue')['default'];
AppModal: typeof import('./components/app/Modal.vue')['default'];
AppSidebar: typeof import('./components/app/Sidebar.vue')['default'];
AppToast: typeof import('./components/app/Toast.vue')['default'];
DashboardMetricsCard: typeof import('./components/dashboard/MetricsCard.vue')['default'];
HoppButtonSecondary: typeof import('@hoppscotch/ui')['HoppButtonSecondary'];
HoppSmartAnchor: typeof import('@hoppscotch/ui')['HoppSmartAnchor'];
HoppSmartConfirmModal: typeof import('@hoppscotch/ui')['HoppSmartConfirmModal'];
HoppSmartInput: typeof import('@hoppscotch/ui')['HoppSmartInput'];
HoppSmartItem: typeof import('@hoppscotch/ui')['HoppSmartItem'];
HoppSmartPicture: typeof import('@hoppscotch/ui')['HoppSmartPicture'];
HoppSmartSpinner: typeof import('@hoppscotch/ui')['HoppSmartSpinner'];
IconLucideInbox: typeof import('~icons/lucide/inbox')['default'];
TeamsAdd: typeof import('./components/teams/Add.vue')['default'];
TeamsDetails: typeof import('./components/teams/Details.vue')['default'];
TeamsInvite: typeof import('./components/teams/Invite.vue')['default'];
TeamsMembers: typeof import('./components/teams/Members.vue')['default'];
TeamsPendingInvites: typeof import('./components/teams/PendingInvites.vue')['default'];
Tippy: typeof import('vue-tippy')['Tippy'];
UsersInviteModal: typeof import('./components/users/InviteModal.vue')['default'];
}
}

View File

@@ -12,7 +12,7 @@
:class="isOpen ? '' : '-translate-x-full ease-in'"
class="sidebar-container transform !md:translate-x-0 ease-out"
>
<div :class="isExpanded ? 'w-80' : 'w-full'">
<div :class="isExpanded ? 'w-56' : 'w-full'">
<div class="flex items-center justify-start px-4 my-4">
<div class="flex items-center">
<HoppSmartLink class="flex items-center space-x-4" to="/dashboard">
@@ -26,7 +26,6 @@
</HoppSmartLink>
</div>
</div>
<nav class="my-5">
<HoppSmartLink
v-for="(navigation, index) in primaryNavigations"
@@ -39,19 +38,32 @@
:to="navigation.to"
tabindex="0"
:exact="navigation.exact"
class="nav-link"
:class="
!isExpanded
? 'flex items-center justify-center'
: 'flex items-center'
"
@click="setActiveTab(navigation.label)"
>
<div v-if="navigation.icon">
<component :is="navigation.icon" class="svg-icons" />
<div
class="flex p-5 w-full font-bold"
:class="
activeTab === navigation.label
? 'bg-primaryDark text-secondaryDark border-l-2 border-l-emerald-600'
: 'bg-primary hover:bg-primaryLight hover:text-secondaryDark focus-visible:text-secondaryDark focus-visible:bg-primaryLight focus-visible:outline-none'
"
>
<div
v-if="navigation.icon"
class="svg-icons"
:class="isExpanded ? 'mr-3' : 'mx-auto'"
>
<component :is="navigation.icon" />
</div>
<span v-if="isExpanded" class="nav-title">
{{ navigation.label }}
</span>
</div>
<span v-if="isExpanded" class="nav-title">
{{ navigation.label }}
</span>
</HoppSmartLink>
</nav>
</div>
@@ -60,19 +72,27 @@
</template>
<script setup lang="ts">
import { HoppSmartLink } from '@hoppscotch/ui';
import { ref, type Component } from 'vue';
import { useI18n } from '~/composables/i18n';
import { useSidebar } from '~/composables/useSidebar';
import IconDashboard from '~icons/lucide/layout-dashboard';
import IconSettings from '~icons/lucide/settings';
import IconUser from '~icons/lucide/user';
import IconUsers from '~icons/lucide/users';
import IconSettings from '~icons/lucide/settings';
import { useI18n } from '~/composables/i18n';
const t = useI18n();
const { isOpen, isExpanded } = useSidebar();
const primaryNavigations = [
type NavigationItem = {
label: string;
icon: Component;
to: string;
exact: boolean;
};
const primaryNavigations: NavigationItem[] = [
{
label: t('metrics.dashboard'),
icon: IconDashboard,
@@ -98,6 +118,12 @@ const primaryNavigations = [
exact: true,
},
];
const activeTab = ref('Dashboard');
const setActiveTab = (tab: string) => {
activeTab.value = tab;
};
</script>
<style scoped lang="scss">
@@ -106,54 +132,4 @@ const primaryNavigations = [
@apply transition duration-300;
@apply flex overflow-y-auto bg-primary border-r border-divider;
}
.nav-link {
@apply relative;
@apply p-4;
@apply flex flex-1;
@apply items-center;
@apply space-x-4;
@apply hover:bg-primaryDark hover:text-secondaryDark;
@apply focus-visible:text-secondaryDark;
@apply after:absolute;
@apply after:inset-x-0;
@apply after:md:inset-x-auto;
@apply after:md:inset-y-0;
@apply after:bottom-0;
@apply after:md:bottom-auto;
@apply after:md:left-0;
@apply after:z-10;
@apply after:h-0.5;
@apply after:md:h-full;
@apply after:w-full;
@apply after:md:w-0.5;
@apply after:content-[''];
@apply focus:after:bg-divider;
.svg-icons {
@apply opacity-75;
}
&.router-link-active {
@apply text-secondaryDark;
@apply bg-primaryLight;
@apply hover:text-secondaryDark;
@apply after:bg-accent;
.svg-icons {
@apply opacity-100;
}
}
&.exact-active-link {
@apply text-secondaryDark;
@apply bg-primaryLight;
@apply hover:text-secondaryDark;
@apply after:bg-accent;
.svg-icons {
@apply opacity-100;
}
}
}
</style>