Skip to content

Commit

Permalink
[MS] Added Responsive Menu
Browse files Browse the repository at this point in the history
  • Loading branch information
fabienSvstr committed Feb 26, 2025
1 parent f0a3e31 commit e63a404
Show file tree
Hide file tree
Showing 18 changed files with 970 additions and 467 deletions.
12 changes: 9 additions & 3 deletions client/src/components/sidebar/SidebarMenuList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const emits = defineEmits<{
padding: 0.25rem 0.5rem;
opacity: 0.8;
cursor: pointer;
width: 100%;

&:hover {
opacity: 1;
Expand All @@ -83,16 +84,20 @@ const emits = defineEmits<{
color: var(--parsec-color-light-secondary-inversed-contrast);
display: flex;
align-items: center;
overflow: hidden;

&__icon {
font-size: 1rem;
margin-right: 0.5rem;
flex-shrink: 0;
padding: 0.125rem;
font-size: 1rem;
}

&__text {
margin-right: 0.5rem;
line-height: auto;
user-select: none;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
}
Expand All @@ -103,6 +108,7 @@ const emits = defineEmits<{
font-size: 1rem;
border-radius: var(--parsec-radius-6);
color: var(--parsec-color-light-secondary-inversed-contrast);
flex-shrink: 0;
}

&-content {
Expand Down
13 changes: 13 additions & 0 deletions client/src/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,19 @@
"goToHome": "My workspaces",
"recentDocuments": "Recent documents",
"back": "Back",
"tabbar": {
"workspaces": "Workspaces",
"files": "Files",
"organization": "Organization",
"myProfile": "My profile",
"newWorkspace": "New workspace",
"newFolder": "New folder",
"importFile": "Import file",
"importFolder": "Import folder",
"scanDocument": "Scan document",
"importPhoto": "Import photo",
"addUser": "Add user"
},
"trial": {
"tag": "Trial version",
"description": "You are currently on the free trial version.",
Expand Down
13 changes: 13 additions & 0 deletions client/src/locales/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,19 @@
"goToHome": "Mes espaces",
"recentDocuments": "Documents récents",
"back": "Retour",
"tabbar": {
"workspaces": "Espaces de travail",
"files": "Fichiers",
"organization": "Organisation",
"myProfile": "Mon profil",
"newWorkspace": "Créer un espace de travail",
"newFolder": "Nouveau dossier",
"importFile": "Importer un fichier",
"importFolder": "Importer un dossier",
"scanDocument": "Scanner un document",
"importPhoto": "Importer une photo",
"addUser": "Ajouter un utilisateur"
},
"trial": {
"tag": "Version d'essai",
"description": "Vous êtes actuellement sur la version d'essai gratuite.",
Expand Down
12 changes: 11 additions & 1 deletion client/src/router/checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { WorkspaceHandle } from '@/parsec';
import { getConnectionHandle, getWorkspaceHandle } from '@/router/params';
import { Routes, getRouter } from '@/router/types';
import { RouteBackup, Routes, getRouter, getVisitedLastHistory } from '@/router/types';

export function isLoggedIn(): boolean {
return getConnectionHandle() !== null;
Expand Down Expand Up @@ -56,6 +56,16 @@ export function currentRouteIsFileRoute(): boolean {
return currentRouteIsOneOf([Routes.Documents, Routes.Workspaces]);
}

export function getLastVisited(route: Routes): RouteBackup | undefined {
const history = getVisitedLastHistory();

return history.get(route);
}

export function hasVisited(route: Routes): boolean {
return getLastVisited(route) !== undefined;
}

export function currentRouteIsLoggedRoute(): boolean {
return currentRouteIsOneOf([
Routes.Workspaces,
Expand Down
33 changes: 32 additions & 1 deletion client/src/router/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const routes: Array<RouteRecordRaw> = [
children: [
{
path: '/sidebar',
component: () => import('@/views/sidebar-menu/SidebarMenuPage.vue'),
component: () => import('@/views/menu/MenuPage.vue'),
children: [
{
path: '/header',
Expand Down Expand Up @@ -139,10 +139,41 @@ const router: Router = createRouter({
routes,
});

const visitedLastHistory = new Map<Routes, RouteBackup>();

router.beforeEach((to, from, next) => {
// Clearing history if we come from a page that has no handle.
// Not taking any risk.
if (!to.params.handle || !from.params.handle) {
visitedLastHistory.clear();
}
if (!to.name || !to.params.handle) {
next();
return;
}
const routeName = to.name as Routes;
if (visitedLastHistory.has(to.name as Routes)) {
visitedLastHistory.delete(routeName);
}
visitedLastHistory.set(routeName, {
handle: Number(to.params.handle),
data: {
route: routeName,
params: to.params,
query: to.query,
},
});
next();
});

export function getRouter(): Router {
return router;
}

export function getVisitedLastHistory(): Map<Routes, RouteBackup> {
return visitedLastHistory;
}

export function getCurrentRoute(): Ref<RouteLocationNormalizedLoaded> {
return (router as Router).currentRoute;
}
Expand Down
2 changes: 1 addition & 1 deletion client/src/services/sidebarMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { ref } from 'vue';

const defaultWidth = 300;
const hiddenWidth = 2;
const hiddenWidth = 0;
const computedWidth = ref<number>(defaultWidth);
const storedWidth = ref<number>(defaultWidth);

Expand Down
10 changes: 10 additions & 0 deletions client/src/theme/components/modals.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
/* Parsec Cloud (https://parsec.cloud) Copyright (c) BUSL-1.1 2016-present Scille SAS */

@import '@/theme/responsive-mixin';

/* -- modal-global -- */
@include breakpoint('sm') {
ion-modal::part(content) {
width: 100%;
min-width: 100%;
}
}

/* -- modal-stepper -- */
.modal-stepper {
// global
Expand Down
1 change: 1 addition & 0 deletions client/src/theme/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
@import 'components/notifications';
@import 'components/popovers';
@import 'components/tags';
@import '@/theme/responsive-mixin';
@import 'global-client';

/**** Global CSS overloads ****/
Expand Down
37 changes: 37 additions & 0 deletions client/src/theme/responsive-mixin.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* Parsec Cloud (https://parsec.cloud) Copyright (c) BUSL-1.1 2016-present Scille SAS */

$breakpoints: (
'xs': (
max-width: 576px,
),
'sm': (
max-width: 768px,
),
'md': (
max-width: 992px,
),
'lg': (
max-width: 1200px,
),
'wide': (
max-width: 1500px,
),
'ultra-wide': (
max-width: 1921px,
),
) !default;

@mixin breakpoint($breakpoint) {
// If the key exists in the map
@if map-has-key($breakpoints, $breakpoint) {
// Prints a media query based on the value
@media #{inspect(map-get($breakpoints, $breakpoint))} {
@content;
}
}
// If the key doesn't exist in the map
@else {
@warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. "
+ "Available breakpoints are: #{map-keys($breakpoints)}.";
}
}
10 changes: 3 additions & 7 deletions client/src/views/client-area/ClientAreaPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -300,13 +300,6 @@ function getTitleByPage(): Translatable {
height: 100%;
}

// -------- sidebar ------------
ion-split-pane {
--side-min-width: var(--parsec-sidebar-menu-min-width);
--side-max-width: var(--parsec-sidebar-menu-max-width);
--side-width: v-bind(sidebarWidthProperty);
}

.resize-divider {
width: 0.25rem;
height: 100%;
Expand All @@ -332,6 +325,9 @@ ion-split-pane {
}

.sidebar {
--side-min-width: var(--parsec-sidebar-menu-min-width);
--side-max-width: var(--parsec-sidebar-menu-max-width);
--side-width: v-bind(sidebarWidthProperty);
--background: var(--parsec-color-light-secondary-background);
border-right: 1px solid var(--parsec-color-light-secondary-disabled);
user-select: none;
Expand Down
78 changes: 78 additions & 0 deletions client/src/views/menu/MenuPage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<!-- Parsec Cloud (https://parsec.cloud) Copyright (c) BUSL-1.1 2016-present Scille SAS -->

<template>
<ion-page>
<sidebar-menu
v-if="userInfo"
:user-info="userInfo"
@sidebar-width-changed="onSidebarWidthChanged"
/>
<tab-menu
v-if="userInfo"
v-show="menuMode === MenuMode.Tabs"
:user-info="userInfo"
/>
</ion-page>
</template>

<script setup lang="ts">
import { ClientInfo, getClientInfo as parsecGetClientInfo } from '@/parsec';
import { IonPage } from '@ionic/vue';
import { Ref, onMounted, onUnmounted, ref } from 'vue';
import TabMenu from '@/views/menu/TabMenu.vue';
import SidebarMenu from '@/views/menu/SidebarMenu.vue';

enum MenuMode {
Sidebar = 'sidebar',
Tabs = 'tabs',
}

const sidebarWidth = ref<number>(0);
const userInfo: Ref<ClientInfo | null> = ref(null);
const menuMode = ref<MenuMode>(MenuMode.Sidebar);

function onSidebarWidthChanged(value: number): void {
sidebarWidth.value = value;
setToastOffset(value);
}

async function updateWindowWidth(): Promise<void> {
if (window.innerWidth <= 768) {
setToastOffset(0);
menuMode.value = MenuMode.Tabs;
} else {
setToastOffset(sidebarWidth.value);
menuMode.value = MenuMode.Sidebar;
}
}

onMounted(async () => {
const infoResult = await parsecGetClientInfo();

if (infoResult.ok) {
userInfo.value = infoResult.value;
} else {
window.electronAPI.log('error', `Failed to retrieve user info ${JSON.stringify(infoResult.error)}`);
}

window.addEventListener('resize', updateWindowWidth);
updateWindowWidth();
});

onUnmounted(async () => {
setToastOffset(0);
window.removeEventListener('resize', updateWindowWidth);
});

function setToastOffset(width: number): void {
window.document.documentElement.style.setProperty('--ms-toast-offset', `${width}px`);
}
</script>

<style lang="scss" scoped>
@import '@/theme/responsive-mixin';

* {
transition: all 100ms ease-in-out;
}
</style>
Loading

0 comments on commit e63a404

Please sign in to comment.