From a1d4c99ff641002b6474efb87ed264fb1021a276 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Fri, 13 Oct 2017 13:58:21 -0400 Subject: [PATCH 1/2] abstract exploreMapsBar into reusable navBar --- app/assets/stylesheets/clean.css.erb | 44 ++++----- app/assets/stylesheets/mobile.scss.erb | 2 +- app/views/layouts/doorkeeper.html.erb | 31 ------ app/views/notifications/_header.html.erb | 14 --- app/views/notifications/index.html.erb | 2 - app/views/notifications/show.html.erb | 6 +- config/application.rb | 6 +- frontend/src/components/App/NavBar.js | 19 ++++ frontend/src/components/App/NavBarLink.js | 28 ++++++ frontend/src/components/Apps/index.js | 21 ++++ frontend/src/components/Maps/Header.js | 96 +++++++------------ frontend/src/components/Maps/index.js | 1 - .../src/components/Notifications/index.js | 18 ++++ frontend/src/components/makeRoutes.js | 24 ++--- 14 files changed, 164 insertions(+), 148 deletions(-) delete mode 100644 app/views/layouts/doorkeeper.html.erb delete mode 100644 app/views/notifications/_header.html.erb create mode 100644 frontend/src/components/App/NavBar.js create mode 100644 frontend/src/components/App/NavBarLink.js create mode 100644 frontend/src/components/Apps/index.js create mode 100644 frontend/src/components/Notifications/index.js diff --git a/app/assets/stylesheets/clean.css.erb b/app/assets/stylesheets/clean.css.erb index 3bc37d68..0790437e 100644 --- a/app/assets/stylesheets/clean.css.erb +++ b/app/assets/stylesheets/clean.css.erb @@ -668,19 +668,19 @@ box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16); } -#exploreMapsHeader { +#navBar { position: absolute; width: 100%; } -.exploreMapsBar { +.navBarContainer { z-index:2; background-color:#FAFAFA; height: 42px; padding-top: 52px; } -.exploreMapsMenu { +.navBarMenu { display: block; width: 100%; height:42px; @@ -689,11 +689,11 @@ text-align: center; } -.exploreMapsCenter { +.navBarCenter { display: block; } -.exploreMapsButton { +.navBarButton { color: #757575; cursor: default; font-weight: normal; @@ -706,13 +706,13 @@ cursor: pointer; position:relative; } -.exploreMapsButton:hover, .exploreMapsButton.active { +.navBarButton:hover, .navBarButton.active { text-decoration: none; color: #424242; border-bottom: 2px solid #00BCD4; } -.exploreMapsButton.mapperButton { +.navBarButton.mapperButton { height: 40px; padding: 0; } @@ -729,7 +729,7 @@ } -.exploreMapsButton .exploreMapsIcon { +.navBarButton .navBarIcon { background-repeat: no-repeat; width:32px; height:32px; @@ -738,53 +738,53 @@ left:5px; } -.exploreMapsCenter .authedApps .exploreMapsIcon { +.navBarCenter .authedApps .navBarIcon { background-image: url(<%= asset_path('user_sprite.png') %>); background-position: 0 -32px; } -.exploreMapsCenter .myMaps .exploreMapsIcon { +.navBarCenter .myMaps .navBarIcon { background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-position: -32px 0; } -.exploreMapsCenter .sharedMaps .exploreMapsIcon { +.navBarCenter .sharedMaps .navBarIcon { background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-position: -128px 0; } -.exploreMapsCenter .activeMaps .exploreMapsIcon { +.navBarCenter .activeMaps .navBarIcon { background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-position: 0 0; } -.exploreMapsCenter .featuredMaps .exploreMapsIcon { +.navBarCenter .featuredMaps .navBarIcon { background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-position: -96px 0; } -.exploreMapsCenter .starredMaps .exploreMapsIcon { +.navBarCenter .starredMaps .navBarIcon { background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-position: -96px 0; } -.exploreMapsCenter .notificationsLink .exploreMapsIcon { +.navBarCenter .notificationsLink .navBarIcon { background-image: url(<%= asset_path 'topright_sprite.png' %>); background-position: -128px 0; } -.authedApps:hover .exploreMapsIcon, .authedApps.active .exploreMapsIcon { +.authedApps:hover .navBarIcon, .authedApps.active .navBarIcon { background-position-x: -32px; } -.myMaps:hover .exploreMapsIcon, .myMaps.active .exploreMapsIcon { +.myMaps:hover .navBarIcon, .myMaps.active .navBarIcon { background-position: -32px -32px; } -.activeMaps:hover .exploreMapsIcon, .activeMaps.active .exploreMapsIcon { +.activeMaps:hover .navBarIcon, .activeMaps.active .navBarIcon { background-position: 0 -32px; } -.featuredMaps:hover .exploreMapsIcon, .featuredMaps.active .exploreMapsIcon { +.featuredMaps:hover .navBarIcon, .featuredMaps.active .navBarIcon { background-position: -96px -32px; } -.starredMaps:hover .exploreMapsIcon, .starredMaps.active .exploreMapsIcon { +.starredMaps:hover .navBarIcon, .starredMaps.active .navBarIcon { background-position: -96px -32px; } -.sharedMaps:hover .exploreMapsIcon, .sharedMaps.active .exploreMapsIcon { +.sharedMaps:hover .navBarIcon, .sharedMaps.active .navBarIcon { background-position: -128px -32px; } -.notificationsLink:hover .exploreMapsIcon, .notificationsLink.active .exploreMapsIcon { +.notificationsLink:hover .navBarIcon, .notificationsLink.active .navBarIcon { background-position-y: -32px; } diff --git a/app/assets/stylesheets/mobile.scss.erb b/app/assets/stylesheets/mobile.scss.erb index 704569c8..02aefeb4 100644 --- a/app/assets/stylesheets/mobile.scss.erb +++ b/app/assets/stylesheets/mobile.scss.erb @@ -32,7 +32,7 @@ /* Smartphones (portrait and landscape) ----------- the minimum space that two map cards can fit side by side */ @media only screen and (max-width : 504px) { - .upperLeftUI, .upperRightUI, .openCheatsheet, .mapInfoIcon, .feedback-icon, .chat-box, #exploreMapsHeader { + .upperLeftUI, .upperRightUI, .openCheatsheet, .mapInfoIcon, .feedback-icon, .chat-box, #navBar { display: none !important; } diff --git a/app/views/layouts/doorkeeper.html.erb b/app/views/layouts/doorkeeper.html.erb deleted file mode 100644 index b9ff5bef..00000000 --- a/app/views/layouts/doorkeeper.html.erb +++ /dev/null @@ -1,31 +0,0 @@ -<%# -# @file -# Main application file. Holds scaffolding present on every page. -# Then a certain non-partial view (no _ preceding filename) will be -# displayed within, based on URL -#%> - -<%= render :partial => 'layouts/head' %> - -
- <%= yield %> -
-
-
-
- <% if current_user && current_user.admin %> - -
Registered Apps -
- <% end %> - -
Authorized Apps -
- -
Maps -
-
-
-
-
-<%= render :partial => 'layouts/foot' %> diff --git a/app/views/notifications/_header.html.erb b/app/views/notifications/_header.html.erb deleted file mode 100644 index 2507b2ef..00000000 --- a/app/views/notifications/_header.html.erb +++ /dev/null @@ -1,14 +0,0 @@ -
- -
diff --git a/app/views/notifications/index.html.erb b/app/views/notifications/index.html.erb index 3efbcb45..4b0a69d2 100644 --- a/app/views/notifications/index.html.erb +++ b/app/views/notifications/index.html.erb @@ -76,5 +76,3 @@ <% end %> - -<%= render partial: 'notifications/header' %> diff --git a/app/views/notifications/show.html.erb b/app/views/notifications/show.html.erb index a552aa77..e2cb2bd2 100644 --- a/app/views/notifications/show.html.erb +++ b/app/views/notifications/show.html.erb @@ -9,7 +9,7 @@

<% case @notification.notification_code when MAP_ACCESS_REQUEST - request = @notification.notified_object + request = @notification.notified_object map = request.map %> <%= image_tag @notification.sender.image(:thirtytwo), class: 'thirty-two-avatar' %> <%= request.user.name %> wants to collaborate on map <%= map.name %> <% else %> @@ -24,7 +24,7 @@ <% if request.approved %> You already responded to this access request, and allowed access. <% elsif !request.approved %> - You already responded to this access request, and declined access. If you changed your mind, you can still grant + You already responded to this access request, and declined access. If you changed your mind, you can still grant them access by going to the map and adding them as a collaborator. <% end %> <% else %> @@ -50,5 +50,3 @@ <% end %> - -<%= render partial: 'notifications/header' %> diff --git a/config/application.rb b/config/application.rb index 8731e76a..715ee8af 100644 --- a/config/application.rb +++ b/config/application.rb @@ -25,9 +25,9 @@ module Metamaps config.encoding = 'utf-8' config.to_prepare do - Doorkeeper::ApplicationsController.layout 'doorkeeper' - Doorkeeper::AuthorizationsController.layout 'doorkeeper' - Doorkeeper::AuthorizedApplicationsController.layout 'doorkeeper' + Doorkeeper::ApplicationsController.layout "application" + Doorkeeper::AuthorizationsController.layout "application" + Doorkeeper::AuthorizedApplicationsController.layout "application" Doorkeeper::ApplicationController.helper ApplicationHelper end diff --git a/frontend/src/components/App/NavBar.js b/frontend/src/components/App/NavBar.js new file mode 100644 index 00000000..92ec9591 --- /dev/null +++ b/frontend/src/components/App/NavBar.js @@ -0,0 +1,19 @@ +import React, { Component } from 'react' + +class NavBar extends Component { + render() { + return ( + + ) + } +} + +export default NavBar diff --git a/frontend/src/components/App/NavBarLink.js b/frontend/src/components/App/NavBarLink.js new file mode 100644 index 00000000..ff0856e7 --- /dev/null +++ b/frontend/src/components/App/NavBarLink.js @@ -0,0 +1,28 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { Link } from 'react-router' +import _ from 'lodash' + +const NavBarLink = props => { + const { show, text, href, linkClass } = props + const otherProps = _.omit(props, ['show', 'text', 'href', 'linkClass']) + if (!show) { + return null + } + + return ( + +
+ {text} + + ) +} + +NavBarLink.propTypes = { + show: PropTypes.bool, + text: PropTypes.string, + href: PropTypes.string, + linkClass: PropTypes.string +} + +export default NavBarLink diff --git a/frontend/src/components/Apps/index.js b/frontend/src/components/Apps/index.js new file mode 100644 index 00000000..53d23a0f --- /dev/null +++ b/frontend/src/components/Apps/index.js @@ -0,0 +1,21 @@ +import React, { Component } from 'react' +import NavBar from '../App/Navbar' +import NavBarLink from '../App/NavBarLink' + +class Apps extends Component { + render = () => { + const { currentUser } = this.props + + return ( + + {currentUser.get('admin') && } + + + + ) + } +} + +export default Apps diff --git a/frontend/src/components/Maps/Header.js b/frontend/src/components/Maps/Header.js index 2168e0c0..3f6181c3 100644 --- a/frontend/src/components/Maps/Header.js +++ b/frontend/src/components/Maps/Header.js @@ -1,30 +1,14 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { Link } from 'react-router' -import _ from 'lodash' - -const MapLink = props => { - const { show, text, href, linkClass } = props - const otherProps = _.omit(props, ['show', 'text', 'href', 'linkClass']) - if (!show) { - return null - } - - return ( - -
- {text} - - ) -} +import NavBar from '../App/Navbar' +import NavBarLink from '../App/NavBarLink' class Header extends Component { render = () => { const { signedIn, section, user } = this.props const activeClass = (title) => { - let forClass = 'exploreMapsButton' - forClass += ' ' + title + 'Maps' + let forClass = title + 'Maps' if (title === 'my' && section === 'mine' || title === section) forClass += ' active' return forClass @@ -34,47 +18,41 @@ class Header extends Component { const mapper = section === 'mapper' return ( -
-
-
-
- - - - - + + + + + + - {mapper ? ( -
- {user && } - {user &&
{user.name}’s Maps
} -
-
- ) : null } -
-
-
-
+ {mapper ? ( +
+ {user && } + {user &&
{user.name}’s Maps
} +
+
+ ) : null } + ) } } diff --git a/frontend/src/components/Maps/index.js b/frontend/src/components/Maps/index.js index 081515fe..c6835a5f 100644 --- a/frontend/src/components/Maps/index.js +++ b/frontend/src/components/Maps/index.js @@ -6,7 +6,6 @@ import MapperCard from './MapperCard' import MapCard from './MapCard' class Maps extends Component { - static propTypes = { section: PropTypes.string, maps: PropTypes.object, diff --git a/frontend/src/components/Notifications/index.js b/frontend/src/components/Notifications/index.js new file mode 100644 index 00000000..52a3c63c --- /dev/null +++ b/frontend/src/components/Notifications/index.js @@ -0,0 +1,18 @@ +import React, { Component } from 'react' +import NavBar from '../App/Navbar' +import NavBarLink from '../App/NavBarLink' + +class Notifications extends Component { + render = () => { + const { currentUser } = this.props + return ( + + + + + ) + } +} + +export default Notifications diff --git a/frontend/src/components/makeRoutes.js b/frontend/src/components/makeRoutes.js index 45f8b746..c0ff2b1c 100644 --- a/frontend/src/components/makeRoutes.js +++ b/frontend/src/components/makeRoutes.js @@ -1,8 +1,10 @@ import React from 'react' import { Route, IndexRoute } from 'react-router' import App from './App' +import Apps from './Apps' import Maps from './Maps' import MapView from './MapView' +import Notifications from './Notifications' import TopicView from './TopicView' function nullComponent(props) { @@ -31,8 +33,8 @@ export default function makeRoutes (currentUser) { - - + + @@ -50,20 +52,20 @@ export default function makeRoutes (currentUser) { - + - - + + - - + + - - - - + + + + From 693e6f5e101a2d11babd9c8bf9e19d3b90d60c31 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Sat, 14 Oct 2017 12:03:05 -0400 Subject: [PATCH 2/2] bug fixes and make active class auto --- app/assets/stylesheets/application.scss.erb | 1 + app/views/layouts/application.html.erb | 4 +- config/application.rb | 6 +- frontend/src/components/App/NavBarLink.js | 71 +++++++++++++----- frontend/src/components/App/index.js | 21 ++++++ frontend/src/components/Apps/index.js | 11 +-- frontend/src/components/Maps/Header.js | 72 +++++++++---------- .../src/components/Notifications/index.js | 5 +- frontend/src/components/makeRoutes.js | 4 +- 9 files changed, 124 insertions(+), 71 deletions(-) diff --git a/app/assets/stylesheets/application.scss.erb b/app/assets/stylesheets/application.scss.erb index d255b652..11330ef9 100644 --- a/app/assets/stylesheets/application.scss.erb +++ b/app/assets/stylesheets/application.scss.erb @@ -826,6 +826,7 @@ label { font-size: 14px; line-height: 14px; color: #757575; + cursor: pointer; } .accountListItem:hover { color: #424242; diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 3ebbbad6..340874fc 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -6,10 +6,10 @@ #%> <%= render :partial => 'layouts/head' %> - controller-<%= controller_name %> action-<%= action_name %>"> + controller-<%= controller_name %> action-<%= action_name %>">
<%= yield %> - <% if authenticated? %> + <% if current_user %> <% # for creating and pulling in topics and synapses %> <% if controller_name == 'maps' && action_name == "conversation" %> <%= render :partial => 'maps/newtopicsecret' %> diff --git a/config/application.rb b/config/application.rb index 715ee8af..06842eb6 100644 --- a/config/application.rb +++ b/config/application.rb @@ -25,9 +25,9 @@ module Metamaps config.encoding = 'utf-8' config.to_prepare do - Doorkeeper::ApplicationsController.layout "application" - Doorkeeper::AuthorizationsController.layout "application" - Doorkeeper::AuthorizedApplicationsController.layout "application" + Doorkeeper::ApplicationsController.layout 'application' + Doorkeeper::AuthorizationsController.layout 'application' + Doorkeeper::AuthorizedApplicationsController.layout 'application' Doorkeeper::ApplicationController.helper ApplicationHelper end diff --git a/frontend/src/components/App/NavBarLink.js b/frontend/src/components/App/NavBarLink.js index ff0856e7..033de2e9 100644 --- a/frontend/src/components/App/NavBarLink.js +++ b/frontend/src/components/App/NavBarLink.js @@ -3,26 +3,63 @@ import PropTypes from 'prop-types' import { Link } from 'react-router' import _ from 'lodash' -const NavBarLink = props => { - const { show, text, href, linkClass } = props - const otherProps = _.omit(props, ['show', 'text', 'href', 'linkClass']) - if (!show) { - return null +const PROP_LIST = [ + 'matchChildRoutes', + 'hardReload', + 'show', + 'text', + 'href', + 'linkClass' +] + +class NavBarLink extends Component { + static propTypes = { + matchChildRoutes: PropTypes.bool, + hardReload: PropTypes.bool, + show: PropTypes.bool, + text: PropTypes.string, + href: PropTypes.string, + linkClass: PropTypes.string } - return ( - -
- {text} - - ) -} + static contextTypes = { + location: PropTypes.object + } -NavBarLink.propTypes = { - show: PropTypes.bool, - text: PropTypes.string, - href: PropTypes.string, - linkClass: PropTypes.string + render = () => { + const { + matchChildRoutes, + hardReload, + show, + text, + href, + linkClass + } = this.props + const { location } = this.context + const otherProps = _.omit(this.props, PROP_LIST) + const classes = ['navBarButton', linkClass] + const active = matchChildRoutes ? + location.pathname.startsWith(href) : + location.pathname === href + if (active) classes.push('active') + if (!show) { + return null + } + if (hardReload) { + return ( + +
+ {text} +
+ ) + } + return ( + +
+ {text} + + ) + } } export default NavBarLink diff --git a/frontend/src/components/App/index.js b/frontend/src/components/App/index.js index 9d4d3ee0..9a830255 100644 --- a/frontend/src/components/App/index.js +++ b/frontend/src/components/App/index.js @@ -38,17 +38,38 @@ class App extends Component { return {location} } + constructor (props) { + super(props) + this.state = { + yieldHTML: null + } + } + + componentDidMount () { + this.setYield() + } + + setYield () { + const yieldHTML = document.getElementById('yield') + if (yieldHTML) { + this.setState({yieldHTML: yieldHTML.innerHTML}) + document.body.removeChild(yieldHTML) + } + } + render () { const { children, toast, unreadNotificationsCount, openInviteLightbox, mobile, mobileTitle, mobileTitleWidth, mobileTitleClick, location, map, userRequested, requestAnswered, requestApproved, serverData, onRequestAccess, notifications, fetchNotifications, markAsRead, markAsUnread } = this.props + const { yieldHTML } = this.state const { pathname } = location || {} // this fixes a bug that happens otherwise when you logout const currentUser = this.props.currentUser && this.props.currentUser.id ? this.props.currentUser : null const unauthedHome = pathname === '/' && !currentUser return
+ {yieldHTML &&
} {mobile && - {currentUser.get('admin') && } - } + - + ) } diff --git a/frontend/src/components/Maps/Header.js b/frontend/src/components/Maps/Header.js index 3f6181c3..770c0efb 100644 --- a/frontend/src/components/Maps/Header.js +++ b/frontend/src/components/Maps/Header.js @@ -7,51 +7,43 @@ class Header extends Component { render = () => { const { signedIn, section, user } = this.props - const activeClass = (title) => { - let forClass = title + 'Maps' - if (title === 'my' && section === 'mine' || - title === section) forClass += ' active' - return forClass - } - const explore = section === 'mine' || section === 'active' || section === 'starred' || section === 'shared' || section === 'featured' const mapper = section === 'mapper' return ( - - - - - - - {mapper ? ( -
- {user && } - {user &&
{user.name}’s Maps
} -
-
- ) : null } + + + + + + {mapper ? ( +
+ {user && } + {user &&
{user.name}’s Maps
} +
+
+ ) : null }
) } diff --git a/frontend/src/components/Notifications/index.js b/frontend/src/components/Notifications/index.js index 52a3c63c..a744e0c3 100644 --- a/frontend/src/components/Notifications/index.js +++ b/frontend/src/components/Notifications/index.js @@ -4,11 +4,10 @@ import NavBarLink from '../App/NavBarLink' class Notifications extends Component { render = () => { - const { currentUser } = this.props return ( - + ) diff --git a/frontend/src/components/makeRoutes.js b/frontend/src/components/makeRoutes.js index c0ff2b1c..90146627 100644 --- a/frontend/src/components/makeRoutes.js +++ b/frontend/src/components/makeRoutes.js @@ -54,8 +54,8 @@ export default function makeRoutes (currentUser) { - - + +