refactor: improvements to the dashboard sidebar (#3709)
Co-authored-by: jamesgeorge007 <jamesgeorge998001@gmail.com>
This commit is contained in:
committed by
GitHub
parent
d1f6f40ef8
commit
ba52c8cc37
59
packages/hoppscotch-sh-admin/src/components.d.ts
vendored
59
packages/hoppscotch-sh-admin/src/components.d.ts
vendored
@@ -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'];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user