2024-04-06 13:25:13 +08:00
< template >
< nav class = "navbar" : class = "{ 'is-search-open': isSearchOpen, 'has-user-notification': isNotificationVisible }" >
< ul class = "navbar-elementsContainer" >
< router -link : to = "{ name: 'home' }" class = "navbar-elementItem" : class = "{'is-active': isHomePage()}" staticRoute = "/dashboard" >
< span class = "navbar-icon" >
< img svg -inline class = "navbar-iconFill" src = "../../assets/icons/navbar/home.svg" / >
< / span >
2024-04-09 12:00:11 +08:00
< span class = "title is-caption is-txtWhite u-hideTablet" > 主页 < / span >
2024-04-06 13:25:13 +08:00
< / r o u t e r - l i n k >
< router -link : to = "{ name: 'maps' }" class = "navbar-elementItem" active -class = " is -active " staticRoute = "/dashboard/maps" >
< span class = "navbar-icon" >
< img svg -inline class = "navbar-iconFill" src = "../../assets/icons/navbar/maps.svg" / >
< / span >
2024-04-09 12:00:11 +08:00
< span class = "title is-caption is-txtWhite u-hideTablet" > 地图 < / span >
2024-04-06 13:25:13 +08:00
< / r o u t e r - l i n k >
<!-- < router -link : to = "{ name: 'solutions' }" class = "navbar-elementItem" active -class = " is -active " >
< span class = "navbar-icon" >
< img svg -inline class = "navbar-iconFill" src = "../../assets/icons/navbar/solutions.svg" / >
< / span >
< span class = "title is-caption is-txtWhite u-hideTablet" > Solutions < / span >
< / r o u t e r - l i n k > - - >
< router -link : to = "{ name: 'datasets' }" class = "navbar-elementItem" active -class = " is -active " staticRoute = "/dashboard/datasets" >
< span class = "navbar-icon" >
< img svg -inline class = "navbar-iconFill" src = "../../assets/icons/navbar/data.svg" / >
< / span >
2024-04-09 12:00:11 +08:00
< span class = "title is-caption is-txtWhite u-hideTablet" > 数据 < / span >
2024-04-06 13:25:13 +08:00
< / r o u t e r - l i n k >
< span class = "navbar-elementItem navbar-icon navbar-searchIcon u-showMobile" @click ="toggleSearch" >
< img svg -inline src = "../../assets/icons/navbar/loupe_white.svg" / >
< / span >
< / ul >
< div class = "navbar-imagotype u-hideMobile" >
< img src = "../../assets/icons/navbar/imagotype.svg" / >
< / div >
< div class = "navbar-elementsContainer navbar-searchContainer" >
< Search / >
< div class = "navbar-user" >
< div class = "navbar-avatar" : class = "{'has-notification': notificationsCount}" : style = "{ backgroundImage: `url('${user.avatar_url}')` }" @click.stop.prevent ="toggleDropdown" > < / div >
< UserDropdown :userModel ="user" :notificationsCount ="notificationsCount" :open ="isDropdownOpen" :baseUrl ="baseUrl" v -click -outside = " closeDropdown " @linkClick ="closeDropdown" / >
< NotificationPopup
v - if = "!popupWasShown('feedback.popupWasShown')"
class = "notification-popup"
: title = "$t('FeedbackMessage.title')"
: message = "$t('FeedbackMessage.message')"
@ click . native . stop . prevent = "onFeedbackClicked" / >
< NotificationPopup
v - if = "!popupWasShown('popups.directDBConnection') && !twoWeeksSinceRelease && hasDBFFActive"
class = "notification-popup"
title = "New Connection Feature"
: message = "`Bring your CARTO data to the tools you already use. You can now connect to your CARTO account from other GIS or BI tools and database clients. <a href='${this.$router.resolve({name: 'connections'}).href}'>Discover it!</a>`"
: messageHasHTML = "true" / >
< NotificationPopup
v - if = "!popupWasShown('popups.snowflakeRedshiftConnectors') && !twoWeeksSinceRelease && hasCCFFActive"
class = "notification-popup"
title = "New database connectors"
: message = "`You can now import data from Snowflake and Amazon Redshift.<br>Please request access to the beta.<br><a href='${this.$router.resolve({name: 'datasets'}).href}'>Connect a new dataset!</a>`"
: messageHasHTML = "true"
@ click . native = "markPopupAsRead('popups.snowflakeRedshiftConnectors')" / >
< / div >
< span class = "navbar-searchClose" @click ="toggleSearch" >
< img svg -inline src = "../../assets/icons/navbar/close.svg" / >
< / span >
< / div >
< / nav >
< / template >
< script >
import isAfter from 'date-fns/is_after' ;
import Search from '../Search/Search' ;
import UserDropdown from './UserDropdown' ;
import NotificationPopup from '../Popups/NotificationPopup' ;
import storageAvailable from 'new-dashboard/utils/is-storage-available' ;
import { hasFeatureEnabled } from 'new-dashboard/core/models/user' ;
export default {
name : 'NavigationBar' ,
components : {
Search ,
UserDropdown ,
NotificationPopup
} ,
props : {
user : Object ,
baseUrl : String ,
notificationsCount : Number ,
isNotificationVisible : {
type : Boolean ,
default : false
} ,
isFirstTimeInDashboard : Boolean ,
bundleType : {
type : String ,
default : 'other'
}
} ,
data ( ) {
return {
isDropdownOpen : false ,
isSearchOpen : false ,
hasDropdownOpenedForFirstTime : false
} ;
} ,
mounted ( ) {
this . markPopupAsRead ( 'feedback.popupWasShown' ) ;
this . markPopupAsRead ( 'popups.directDBConnection' ) ;
} ,
computed : {
hasDBFFActive ( ) {
return hasFeatureEnabled ( this . $props . user , 'dbdirect' ) ;
} ,
hasCCFFActive ( ) {
return hasFeatureEnabled ( this . $props . user , 'carto-connectors' ) ;
} ,
isDashboardBundle ( ) {
return this . $props . bundleType === 'dashboard' ;
} ,
shouldShowFeedbackPopup ( ) {
return this . isDashboardBundle &&
! this . isFirstTimeInDashboard &&
! this . hasDropdownOpenedForFirstTime &&
! this . popupWasShown ;
} ,
twoWeeksSinceRelease ( ) {
// 2020/09/22 + 2w = 2020/10/06
return isAfter ( new Date ( ) , new Date ( 2020 , 9 , 6 ) ) ;
}
} ,
methods : {
toggleDropdown ( ) {
this . hasDropdownOpenedForFirstTime = true ;
this . isDropdownOpen = ! this . isDropdownOpen ;
} ,
closeDropdown ( ) {
this . isDropdownOpen = false ;
} ,
toggleSearch ( ) {
this . isSearchOpen = ! this . isSearchOpen ;
} ,
isHomePage ( ) {
return ( this . $route || { } ) . name === 'home' ;
} ,
onFeedbackClicked ( ) {
this . toggleDropdown ( ) ;
} ,
popupWasShown ( type ) {
if ( ! storageAvailable ( 'localStorage' ) ) {
return true ;
}
return JSON . parse ( window . localStorage . getItem ( ` carto. ${ type } ` ) ) ;
} ,
markPopupAsRead ( type ) {
if ( ! storageAvailable ( 'localStorage' ) ) {
return ;
}
window . localStorage . setItem ( ` carto. ${ type } ` , JSON . stringify ( true ) ) ;
}
}
} ;
< / script >
< style scoped lang = "scss" >
@ import 'new-dashboard/styles/variables' ;
. navbar {
display : flex ;
position : fixed ;
top : 0 ;
z - index : $z - index _ _navbar ;
align - items : center ;
justify - content : space - between ;
width : 100 % ;
padding : 0 64 px ;
border - bottom : 1 px solid $white ;
background - color : $primary - color ;
@ media ( max - width : $layout - tablet ) {
padding : 0 24 px 0 40 px ;
}
@ media ( max - width : $layout - mobile ) {
padding : 0 16 px 0 20 px ;
}
}
. navbar - elementsContainer {
display : flex ;
position : relative ;
a : last - of - type {
margin - right : 0 ;
}
@ media ( max - width : $layout - mobile ) {
a : last - of - type {
margin - right : 36 px ;
}
}
}
. navbar - elementItem {
display : flex ;
align - items : center ;
margin - right : 54 px ;
padding : 20 px 2 px 16 px ;
border - bottom : 4 px solid transparent ;
@ media ( max - width : $layout - tablet ) {
margin - right : 48 px ;
}
@ media ( max - width : $layout - mobile ) {
margin - right : 36 px ;
}
& . is - active {
border - color : $white ;
. navbar - iconFill {
fill : # FFF ;
}
. navbar - iconNegativeFill {
fill : transparent ;
}
}
}
. navbar - searchIcon {
padding - top : 21 px ;
cursor : pointer ;
}
. navbar - searchClose {
display : none ;
cursor : pointer ;
}
. navbar - icon {
margin - right : 12 px ;
@ media ( max - width : $layout - tablet ) {
margin - right : 0 ;
}
}
. navbar - imagotype {
position : absolute ;
left : 50 % ;
width : 24 px ;
height : 24 px ;
transform : translate3d ( - 50 % , 0 , 0 ) ;
}
. navbar - user {
position : relative ;
}
. navbar - avatar {
display : flex ;
width : 36 px ;
height : 36 px ;
margin - left : 24 px ;
overflow : hidden ;
border - radius : 50 % ;
background - color : $navbar - avatar _ _bg - color ;
background - size : cover ;
& . has - notification {
& : : after {
content : "" ;
position : absolute ;
top : - 4 px ;
right : - 4 px ;
width : 12 px ;
height : 12 px ;
border : 2 px solid $primary - color ;
border - radius : 50 % ;
background - color : $notification _ _bg - color ;
}
}
& : hover {
cursor : pointer ;
}
}
. navbar . is - search - open {
padding : 0 ;
. navbar - elementsContainer {
align - items : center ;
}
. navbar - elementsContainer ,
. navbar - imagotype ,
. navbar - user {
visibility : hidden ;
opacity : 0 ;
}
. navbar - searchContainer {
visibility : visible ;
position : absolute ;
width : 100 % ;
opacity : 1 ;
}
. navbar - searchClose {
display : block ;
position : absolute ;
right : 16 px ;
}
}
. navbar . has - user - notification {
top : $notification - warning _ _height ;
}
. notification - popup {
position : absolute ;
top : calc ( 100 % + 18 px ) ;
right : 0 ;
}
< / style >