diff --git a/pkg/webui/components/sidebar/side-footer/index.js b/pkg/webui/components/sidebar/side-footer/index.js index bd05e09e24..f9e3fad506 100644 --- a/pkg/webui/components/sidebar/side-footer/index.js +++ b/pkg/webui/components/sidebar/side-footer/index.js @@ -116,31 +116,36 @@ const SideFooter = () => { 'al-center', 'gap-cs-xs', 'fs-s', + { [style.isMinimized]: isMinimized }, ) return (
+
) } diff --git a/pkg/webui/components/sidebar/side-footer/side-footer.styl b/pkg/webui/components/sidebar/side-footer/side-footer.styl index b73cfed7d2..657a4eb245 100644 --- a/pkg/webui/components/sidebar/side-footer/side-footer.styl +++ b/pkg/webui/components/sidebar/side-footer/side-footer.styl @@ -15,12 +15,41 @@ .side-footer margin-top: auto - &-full-width + .support-button width: 100% + button + width: 100% + &-button justify-content: space-between - &-cluster-dropdown - left: initial !important - right: 0 !important + &.is-minimized + +media-query-min($bp.m) + .cluster-button + display: none + + .side-footer-version + display: none + + .support-button button + justify-content: center + + span:first-child + margin: 0 + + .side-footer-dropdown + width: calc(19rem - 2px) + min-width: initial + max-width: initial + + .side-footer-version + margin-left: $cs.xxs + + .support-button button + width: 100% !important + justify-content: flex-start + + ul.side-footer-cluster-dropdown + left: initial + right: 0 diff --git a/pkg/webui/components/sidebar/side-menu/item/collapsible.js b/pkg/webui/components/sidebar/side-menu/item/collapsible.js index ef32675810..7d030d8c27 100644 --- a/pkg/webui/components/sidebar/side-menu/item/collapsible.js +++ b/pkg/webui/components/sidebar/side-menu/item/collapsible.js @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React from 'react' +import React, { useRef } from 'react' import classnames from 'classnames' import Dropdown from '@ttn-lw/components/dropdown' @@ -38,6 +38,7 @@ const CollapsibleItem = ({ onDropdownItemsClick, currentPathName, }) => { + const ref = useRef() const subItems = children .filter(item => Boolean(item) && 'props' in item) .map(item => ({ @@ -49,50 +50,45 @@ const CollapsibleItem = ({ const subItemActive = subItems.some(item => currentPathName.includes(item.path)) return ( - <> +
- {!isMinimized && ( - - {children} - + {isMinimized && ( + + + {subItems.map(item => ( + + ))} + )} - + + {children} + +
) } diff --git a/pkg/webui/components/sidebar/side-menu/item/item.styl b/pkg/webui/components/sidebar/side-menu/item/item.styl index 3dc423ae50..876f0aa2b3 100644 --- a/pkg/webui/components/sidebar/side-menu/item/item.styl +++ b/pkg/webui/components/sidebar/side-menu/item/item.styl @@ -12,11 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -.item - &:hover - .fly-out-list-container - display: block - .message vertical-align: middle @@ -30,20 +25,9 @@ &-open transform: translateY(-50%) rotate(180deg) -.fly-out-list-container - display: none - top: - $cs.m - left: calc(3rem - 2px) - position: absolute - padding-left: 1rem - z-index: $zi.dropdown - -.fly-out-list - position: static !important - .link transition: color 50ms linear - border-radius: $br.l + border-radius: $br.m text-decoration: none color: $c.grey-700 display: flex @@ -53,10 +37,7 @@ position: relative box-sizing: border-box width: 100% - - .icon - transition: color 50ms linear - color: $c.grey-500 + padding-left: $cs.xs &.active background: $c.tts-primary-150 @@ -73,8 +54,41 @@ &:hover color: $c.grey-900 - text-decoration: none .icon color: inherit +.is-minimized + justify-content: center + + .title + display: none + + .expand-icon + display: none + + .icon + transition: color 50ms linear + color: $c.grey-500 + +.sub-item-list + &.is-minimized + +media-query-min($bp.m) + display: none + +.fly-out-list + top: - $cs.xs + left: calc(4rem - 3px) + position: absolute + padding-left: 1rem + z-index: $zi.dropdown + + // Pseudo element to extend the clickable area + // to connect with the parent button. + &:before + content: "" + position: absolute + top: 0 + left: -1rem + width: 1rem + height: 100% diff --git a/pkg/webui/components/sidebar/switcher/index.js b/pkg/webui/components/sidebar/switcher/index.js index 7d484b86b3..4248e5fbca 100644 --- a/pkg/webui/components/sidebar/switcher/index.js +++ b/pkg/webui/components/sidebar/switcher/index.js @@ -12,11 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -import React, { useCallback } from 'react' -import { NavLink } from 'react-router-dom' +import React, { useCallback, useRef } from 'react' +import { NavLink, useLocation } from 'react-router-dom' import classnames from 'classnames' import Icon from '@ttn-lw/components/icon' +import Dropdown from '@ttn-lw/components/dropdown' import Message from '@ttn-lw/lib/components/message' @@ -26,39 +27,69 @@ import PropTypes from '@ttn-lw/lib/prop-types' import style from './switcher.styl' const Switcher = ({ isMinimized }) => { - const paddingClass = isMinimized ? 'p-vert-cs-xs' : 'p-vert-cs-s' + const overviewRef = useRef(null) + const applicationsRef = useRef(null) + const gatewaysRef = useRef(null) + const { pathname } = useLocation() const getNavLinkClass = useCallback( ({ isActive }) => - classnames(style.link, isActive ? style.active : '', paddingClass, 'p-sides-0'), - [paddingClass], + classnames(style.link, { + [style.active]: isActive, + }), + [], ) + const getOverviewNavLinkClass = classnames(style.link, { + [style.active]: !pathname.startsWith('/applications') && !pathname.startsWith('/gateways'), + }) + return (
- - {isMinimized ? ( - - ) : ( - + + + + {isMinimized && ( + + + )} - - {isMinimized ? ( - - ) : ( - + + + + {isMinimized && ( + + + )} - - {isMinimized ? ( - - ) : ( - + + + + {isMinimized && ( + + + )}
diff --git a/pkg/webui/console/containers/side-bar/navigation/app-side-navigation.js b/pkg/webui/console/containers/side-bar/navigation/app-side-navigation.js index 01c5a8a959..7db79a6770 100644 --- a/pkg/webui/console/containers/side-bar/navigation/app-side-navigation.js +++ b/pkg/webui/console/containers/side-bar/navigation/app-side-navigation.js @@ -75,7 +75,7 @@ const AppSideNavigation = () => { {mayViewApplicationInfo.check(rights) && ( @@ -83,14 +83,14 @@ const AppSideNavigation = () => { {mayViewApplicationDevices.check(rights) && ( )} {mayViewApplicationEvents.check(rights) && ( )} @@ -103,12 +103,12 @@ const AppSideNavigation = () => { > @@ -121,25 +121,25 @@ const AppSideNavigation = () => { > {mayAddPubSubIntegrations.check(natsDisabled, mqttDisabled) && ( )} {mayViewOrEditApplicationPackages.check(rights) && ( )} @@ -148,21 +148,21 @@ const AppSideNavigation = () => { {mayViewOrEditApplicationCollaborators.check(rights) && ( )} {mayViewOrEditApplicationApiKeys.check(rights) && ( )} {mayEditBasicApplicationInfo.check(rights) && ( )} diff --git a/pkg/webui/console/containers/side-bar/navigation/gtw-side-navigation.js b/pkg/webui/console/containers/side-bar/navigation/gtw-side-navigation.js index 5cd47a4b6a..e8997706fb 100644 --- a/pkg/webui/console/containers/side-bar/navigation/gtw-side-navigation.js +++ b/pkg/webui/console/containers/side-bar/navigation/gtw-side-navigation.js @@ -64,7 +64,7 @@ const GtwSideNavigation = () => { {mayViewGatewayInfo.check(rights) && ( @@ -72,35 +72,35 @@ const GtwSideNavigation = () => { {mayViewGatewayEvents.check(rights) && ( )} {mayViewOrEditGatewayLocation.check(rights) && ( )} {mayViewOrEditGatewayCollaborators.check(rights) && ( )} {mayViewOrEditGatewayApiKeys.check(rights) && ( )} {mayEditBasicGatewayInformation.check(rights) && ( )} diff --git a/pkg/webui/console/containers/side-bar/story.js b/pkg/webui/console/containers/side-bar/story.js index 7d64118f2f..ecf8c6b1a1 100644 --- a/pkg/webui/console/containers/side-bar/story.js +++ b/pkg/webui/console/containers/side-bar/story.js @@ -18,7 +18,7 @@ import classnames from 'classnames' import TtsLogo from '@assets/static/tts-logo.svg' import Switcher from '@ttn-lw/components/sidebar/switcher' -import SideNavigation from '@ttn-lw/components/navigation/side' +import SideNavigation from '@ttn-lw/components/sidebar/side-menu' import SideHeader from '@ttn-lw/components/sidebar/side-header' import SearchButton from '@ttn-lw/components/sidebar/search-button' import SideFooter from '@ttn-lw/components/sidebar/side-footer'