From 3b1a5c5fb950dc9ec399219c809924d8f34cda17 Mon Sep 17 00:00:00 2001 From: Rafael Araujo Lehmkuhl Date: Mon, 20 Jan 2025 15:51:48 -0300 Subject: [PATCH 1/2] main-menu: Create new "Tools" sub-menu --- src/App.vue | 141 +++++++++++------- src/components/ConfigurationMenu.vue | 98 ------------ src/stores/appInterface.ts | 2 +- src/types/general.ts | 2 +- ...DataLakeView.vue => ToolsDataLakeView.vue} | 0 ...onMAVLinkView.vue => ToolsMAVLinkView.vue} | 0 6 files changed, 92 insertions(+), 151 deletions(-) delete mode 100644 src/components/ConfigurationMenu.vue rename src/views/{ConfigurationDataLakeView.vue => ToolsDataLakeView.vue} (100%) rename src/views/{ConfigurationMAVLinkView.vue => ToolsMAVLinkView.vue} (100%) diff --git a/src/App.vue b/src/App.vue index ab419744c..4eac862ab 100644 --- a/src/App.vue +++ b/src/App.vue @@ -115,7 +115,7 @@ :variant="simplifiedMainMenu ? 'uncontained' : 'round'" :tooltip="simplifiedMainMenu ? 'Configuration' : undefined" :width="buttonSize" - :selected="showConfigurationMenu" + :selected="showSubMenu" class="mb-2" :style=" interfaceStore.highlightedComponent === 'config-menu-item' && { @@ -123,7 +123,30 @@ borderRadius: '10px', } " - @click="interfaceStore.mainMenuCurrentStep = 2" + @click="selectSubMenu('config')" + /> + @@ -172,13 +195,13 @@ :class="simplifiedMainMenu ? 'py-0 gap-y-0' : 'py-2 gap-y-1'" >
@@ -205,7 +228,7 @@ @click=" () => { interfaceStore.mainMenuCurrentStep = 1 - currentConfigMenuComponent = null + currentSubMenuComponent = null } " /> @@ -219,15 +242,15 @@ - + @@ -348,18 +371,18 @@ import { useSnackbar } from './composables/snackbar' import { useAppInterfaceStore } from './stores/appInterface' import { useMainVehicleStore } from './stores/mainVehicle' import { useWidgetManagerStore } from './stores/widgetManager' -import { ConfigComponent } from './types/general' +import { SubMenuComponent } from './types/general' import ConfigurationActionsView from './views/ConfigurationActionsView.vue' import ConfigurationAlertsView from './views/ConfigurationAlertsView.vue' -import ConfigurationDataLakeView from './views/ConfigurationDataLakeView.vue' import ConfigurationDevelopmentView from './views/ConfigurationDevelopmentView.vue' import ConfigurationGeneralView from './views/ConfigurationGeneralView.vue' import ConfigurationJoystickView from './views/ConfigurationJoystickView.vue' import ConfigurationTelemetryView from './views/ConfigurationLogsView.vue' -import ConfigurationMAVLinkView from './views/ConfigurationMAVLinkView.vue' import ConfigurationMissionView from './views/ConfigurationMissionView.vue' import ConfigurationUIView from './views/ConfigurationUIView.vue' import ConfigurationVideoView from './views/ConfigurationVideoView.vue' +import ToolsDataLakeView from './views/ToolsDataLakeView.vue' +import ToolsMAVLinkView from './views/ToolsMAVLinkView.vue' const { showDialog, closeDialog } = useInteractionDialog() const { showSnackbar } = useSnackbar() @@ -369,8 +392,9 @@ const vehicleStore = useMainVehicleStore() const interfaceStore = useAppInterfaceStore() const showAboutDialog = ref(false) -const showConfigurationMenu = ref(false) -const currentConfigMenuComponent = ref(null) +const showSubMenu = ref(false) +const currentSubMenuName = ref(null) +const currentSubMenuComponent = ref(null) // Main menu const isMenuOpen = ref(false) @@ -382,83 +406,98 @@ const configMenu = [ { icon: 'mdi-view-dashboard-variant', title: 'General', - component: markRaw(ConfigurationGeneralView) as ConfigComponent, + component: markRaw(ConfigurationGeneralView) as SubMenuComponent, }, { icon: 'mdi-monitor-cellphone', title: 'Interface', - component: markRaw(ConfigurationUIView) as ConfigComponent, + component: markRaw(ConfigurationUIView) as SubMenuComponent, }, { icon: 'mdi-controller', title: 'Joystick', - component: markRaw(ConfigurationJoystickView) as ConfigComponent, + component: markRaw(ConfigurationJoystickView) as SubMenuComponent, }, { icon: 'mdi-video', title: 'Video', - component: markRaw(ConfigurationVideoView) as ConfigComponent, + component: markRaw(ConfigurationVideoView) as SubMenuComponent, }, { icon: 'mdi-subtitles-outline', title: 'Telemetry', - component: markRaw(ConfigurationTelemetryView) as ConfigComponent, + component: markRaw(ConfigurationTelemetryView) as SubMenuComponent, }, { icon: 'mdi-alert-rhombus-outline', title: 'Alerts', - component: markRaw(ConfigurationAlertsView) as ConfigComponent, + component: markRaw(ConfigurationAlertsView) as SubMenuComponent, }, { icon: 'mdi-dev-to', title: 'Dev', - component: markRaw(ConfigurationDevelopmentView) as ConfigComponent, - }, - { - icon: 'mdi-protocol', - title: 'MAVLink', - component: markRaw(ConfigurationMAVLinkView) as ConfigComponent, + component: markRaw(ConfigurationDevelopmentView) as SubMenuComponent, }, { icon: 'mdi-map-marker-path', title: 'Mission', - component: markRaw(ConfigurationMissionView) as ConfigComponent, - }, - { - icon: 'mdi-database-outline', - title: 'Data-lake', - component: markRaw(ConfigurationDataLakeView) as ConfigComponent, + component: markRaw(ConfigurationMissionView) as SubMenuComponent, }, { icon: 'mdi-run-fast', title: 'Actions', - component: markRaw(ConfigurationActionsView) as ConfigComponent, + component: markRaw(ConfigurationActionsView) as SubMenuComponent, }, ] +const toolsMenu = [ + { + icon: 'mdi-protocol', + title: 'MAVLink', + component: markRaw(ToolsMAVLinkView) as SubMenuComponent, + }, + { + icon: 'mdi-database-outline', + title: 'Data-lake', + component: markRaw(ToolsDataLakeView) as SubMenuComponent, + }, +] + +const availableSubMenus = { + config: configMenu, + tools: toolsMenu, +} + +const currentSubMenu = computed(() => { + if (currentSubMenuName.value === null) return [] + return availableSubMenus[currentSubMenuName.value] +}) + watch( - () => interfaceStore.configComponent, - (component) => { - if (component < 0) { - currentConfigMenuComponent.value = null - return - } - currentConfigMenuComponent.value = configMenu[component].component + () => interfaceStore.subMenuComponentName, + (subMenuComponentName) => { + currentSubMenuComponent.value = + currentSubMenu.value.find((item) => item.title === subMenuComponentName)?.component || null } ) -const toggleConfigComponent = (component: ConfigComponent): void => { - if (currentConfigMenuComponent.value === null) { - currentConfigMenuComponent.value = component +const selectSubMenu = (subMenuName: keyof typeof availableSubMenus): void => { + currentSubMenuName.value = subMenuName + interfaceStore.mainMenuCurrentStep = 2 +} + +const toggleSubMenuComponent = (component: SubMenuComponent): void => { + if (currentSubMenuComponent.value === null) { + currentSubMenuComponent.value = component interfaceStore.configModalVisibility = true return } - if (currentConfigMenuComponent.value === component) { - currentConfigMenuComponent.value = null + if (currentSubMenuComponent.value === component) { + currentSubMenuComponent.value = null interfaceStore.configModalVisibility = false return } - currentConfigMenuComponent.value = component + currentSubMenuComponent.value = component interfaceStore.configModalVisibility = true } @@ -466,7 +505,7 @@ const isConfigModalVisible = computed(() => interfaceStore.isConfigModalVisible) watch(isConfigModalVisible, (newVal) => { if (newVal === false) { - currentConfigMenuComponent.value = null + currentSubMenuComponent.value = null } }) @@ -556,7 +595,7 @@ const closeMainMenu = (): void => { isSlidingOut.value = false isMenuOpen.value = false interfaceStore.mainMenuCurrentStep = 1 - currentConfigMenuComponent.value = null + currentSubMenuComponent.value = null }, 20) } @@ -645,7 +684,7 @@ onClickOutside(mainMenu, () => { } if ( interfaceStore.mainMenuCurrentStep === 2 && - currentConfigMenuComponent.value === null && + currentSubMenuComponent.value === null && !interfaceStore.isTutorialVisible ) { closeMainMenu() diff --git a/src/components/ConfigurationMenu.vue b/src/components/ConfigurationMenu.vue deleted file mode 100644 index 5a691f328..000000000 --- a/src/components/ConfigurationMenu.vue +++ /dev/null @@ -1,98 +0,0 @@ - - - diff --git a/src/stores/appInterface.ts b/src/stores/appInterface.ts index 00b900fd9..871b99ac4 100644 --- a/src/stores/appInterface.ts +++ b/src/stores/appInterface.ts @@ -24,7 +24,7 @@ export const useAppInterfaceStore = defineStore('responsive', { componentToHighlight: 'none', isMainMenuVisible: false, mainMenuCurrentStep: 1, - configComponent: -1, + subMenuComponentName: null, isGlassModalAlwaysOnTop: false, isTutorialVisible: false, configPanelVisible: false, diff --git a/src/types/general.ts b/src/types/general.ts index f01f8ae57..58a49988d 100644 --- a/src/types/general.ts +++ b/src/types/general.ts @@ -32,7 +32,7 @@ export interface DialogActions { disabled?: boolean } -export type ConfigComponent = DefineComponent, Record, unknown> | null +export type SubMenuComponent = DefineComponent, Record, unknown> | null export interface StorageDB { getItem: (key: string) => Promise diff --git a/src/views/ConfigurationDataLakeView.vue b/src/views/ToolsDataLakeView.vue similarity index 100% rename from src/views/ConfigurationDataLakeView.vue rename to src/views/ToolsDataLakeView.vue diff --git a/src/views/ConfigurationMAVLinkView.vue b/src/views/ToolsMAVLinkView.vue similarity index 100% rename from src/views/ConfigurationMAVLinkView.vue rename to src/views/ToolsMAVLinkView.vue From a8c39a05a5f7bb4820e06596dfd7faf8667cffca Mon Sep 17 00:00:00 2001 From: Rafael Araujo Lehmkuhl Date: Wed, 29 Jan 2025 14:41:51 -0300 Subject: [PATCH 2/2] main-menu: Improve logic that controls the simplified main menu The simplified main menu is shown when the screen height is too small to show the full menu. The threshold is different for small and large screens. --- src/App.vue | 44 +++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/src/App.vue b/src/App.vue index 4eac862ab..a10312b88 100644 --- a/src/App.vue +++ b/src/App.vue @@ -197,7 +197,7 @@ (null) const currentSubMenuComponent = ref(null) +const mainMenu = ref() // Main menu const isMenuOpen = ref(false) const isSlidingOut = ref(false) -const simplifiedMainMenu = ref(false) -const windowHeight = ref(window.innerHeight) + +const { width: windowWidth, height: windowHeight } = useWindowSize() const configMenu = [ { @@ -509,26 +510,20 @@ watch(isConfigModalVisible, (newVal) => { } }) -watch( - () => windowHeight.value < 450, - (isSmall: boolean) => { - simplifiedMainMenu.value = isSmall - } -) - -const updateWindowHeight = (): void => { - windowHeight.value = window.innerHeight -} +const topBottomBarScale = computed(() => { + return windowWidth.value / originalBarWidth +}) -onMounted(() => { - window.addEventListener('resize', updateWindowHeight) - if (windowHeight.value < 450) { - simplifiedMainMenu.value = true - } +const maxScreenHeightPixelsThatFitsLargeMenu = computed(() => { + const heightTopBar = widgetStore.currentTopBarHeightPixels * topBottomBarScale.value + const heightBottomBar = widgetStore.currentBottomBarHeightPixels * topBottomBarScale.value + const visibleAreaHeight = windowHeight.value - heightTopBar - heightBottomBar + return visibleAreaHeight }) -onBeforeUnmount(() => { - window.removeEventListener('resize', updateWindowHeight) +const simplifiedMainMenu = computed(() => { + const threshold = windowWidth.value > 1300 ? 860 : 680 + return maxScreenHeightPixelsThatFitsLargeMenu.value < threshold }) const mainMenuWidth = computed(() => { @@ -677,7 +672,6 @@ const menuLabelSize = computed(() => { return 'text-[10px]' }) -const mainMenu = ref() onClickOutside(mainMenu, () => { if (interfaceStore.mainMenuCurrentStep === 1 && !interfaceStore.isTutorialVisible) { closeMainMenu() @@ -719,23 +713,19 @@ const fullScreenToggleIcon = computed(() => (isFullscreen.value ? 'mdi-fullscree const currentSelectedViewName = computed(() => widgetStore.currentView.name) -const { width: windowWidth } = useWindowSize() - const originalBarWidth = 1800 const topBarScaleStyle = computed(() => { - const scale = windowWidth.value / originalBarWidth return { - transform: `scale(${scale})`, + transform: `scale(${topBottomBarScale.value})`, transformOrigin: 'top left', width: `${originalBarWidth}px`, } }) const bottomBarScaleStyle = computed(() => { - const scale = windowWidth.value / originalBarWidth return { - transform: `scale(${scale})`, + transform: `scale(${topBottomBarScale.value})`, transformOrigin: 'bottom left', width: `${originalBarWidth}px`, }