follows for maps in the ui for internal testing only still (#1072)
* follows for maps in the ui for testers * require user for these actions * match how map follow works
This commit is contained in:
parent
8d771543d8
commit
013e3c7f21
14 changed files with 145 additions and 30 deletions
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
class MapsController < ApplicationController
|
class MapsController < ApplicationController
|
||||||
before_action :require_user, only: [:create, :update, :destroy, :events]
|
before_action :require_user, only: [:create, :update, :destroy, :events, :follow, :unfollow]
|
||||||
before_action :set_map, only: [:show, :conversation, :update, :destroy, :contains, :events, :export]
|
before_action :set_map, only: [:show, :conversation, :update, :destroy, :contains, :events, :export, :follow, :unfollow]
|
||||||
after_action :verify_authorized
|
after_action :verify_authorized
|
||||||
|
|
||||||
# GET maps/:id
|
# GET maps/:id
|
||||||
|
@ -138,6 +138,32 @@ class MapsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# POST maps/:id/follow
|
||||||
|
def follow
|
||||||
|
follow = FollowService.follow(@map, current_user, 'followed')
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.json do
|
||||||
|
if follow
|
||||||
|
head :ok
|
||||||
|
else
|
||||||
|
head :bad_request
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST maps/:id/unfollow
|
||||||
|
def unfollow
|
||||||
|
FollowService.unfollow(@map, current_user)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.json do
|
||||||
|
head :ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_map
|
def set_map
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
class TopicsController < ApplicationController
|
class TopicsController < ApplicationController
|
||||||
include TopicsHelper
|
include TopicsHelper
|
||||||
|
|
||||||
before_action :require_user, only: [:create, :update, :destroy]
|
before_action :require_user, only: [:create, :update, :destroy, :follow, :unfollow]
|
||||||
|
before_action :set_topic, only: [:show, :update, :relative_numbers, :relatives, :network, :destroy, :follow, :unfollow]
|
||||||
after_action :verify_authorized, except: :autocomplete_topic
|
after_action :verify_authorized, except: :autocomplete_topic
|
||||||
|
|
||||||
respond_to :html, :js, :json
|
respond_to :html, :js, :json
|
||||||
|
@ -31,9 +32,6 @@ class TopicsController < ApplicationController
|
||||||
|
|
||||||
# GET topics/:id
|
# GET topics/:id
|
||||||
def show
|
def show
|
||||||
@topic = Topic.find(params[:id])
|
|
||||||
authorize @topic
|
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
@alltopics = [@topic].concat(policy_scope(Topic.relatives(@topic.id, current_user)).to_a)
|
@alltopics = [@topic].concat(policy_scope(Topic.relatives(@topic.id, current_user)).to_a)
|
||||||
|
@ -49,9 +47,6 @@ class TopicsController < ApplicationController
|
||||||
|
|
||||||
# GET topics/:id/network
|
# GET topics/:id/network
|
||||||
def network
|
def network
|
||||||
@topic = Topic.find(params[:id])
|
|
||||||
authorize @topic
|
|
||||||
|
|
||||||
@alltopics = [@topic].concat(policy_scope(Topic.relatives(@topic.id, current_user)).to_a)
|
@alltopics = [@topic].concat(policy_scope(Topic.relatives(@topic.id, current_user)).to_a)
|
||||||
@allsynapses = policy_scope(Synapse.for_topic(@topic.id))
|
@allsynapses = policy_scope(Synapse.for_topic(@topic.id))
|
||||||
|
|
||||||
|
@ -71,9 +66,6 @@ class TopicsController < ApplicationController
|
||||||
|
|
||||||
# GET topics/:id/relative_numbers
|
# GET topics/:id/relative_numbers
|
||||||
def relative_numbers
|
def relative_numbers
|
||||||
@topic = Topic.find(params[:id])
|
|
||||||
authorize @topic
|
|
||||||
|
|
||||||
topics_already_has = params[:network] ? params[:network].split(',').map(&:to_i) : []
|
topics_already_has = params[:network] ? params[:network].split(',').map(&:to_i) : []
|
||||||
|
|
||||||
alltopics = policy_scope(Topic.relatives(@topic.id, current_user)).to_a
|
alltopics = policy_scope(Topic.relatives(@topic.id, current_user)).to_a
|
||||||
|
@ -94,9 +86,6 @@ class TopicsController < ApplicationController
|
||||||
|
|
||||||
# GET topics/:id/relatives
|
# GET topics/:id/relatives
|
||||||
def relatives
|
def relatives
|
||||||
@topic = Topic.find(params[:id])
|
|
||||||
authorize @topic
|
|
||||||
|
|
||||||
topics_already_has = params[:network] ? params[:network].split(',').map(&:to_i) : []
|
topics_already_has = params[:network] ? params[:network].split(',').map(&:to_i) : []
|
||||||
|
|
||||||
alltopics = policy_scope(Topic.relatives(@topic.id, current_user)).to_a
|
alltopics = policy_scope(Topic.relatives(@topic.id, current_user)).to_a
|
||||||
|
@ -149,8 +138,6 @@ class TopicsController < ApplicationController
|
||||||
# PUT /topics/1
|
# PUT /topics/1
|
||||||
# PUT /topics/1.json
|
# PUT /topics/1.json
|
||||||
def update
|
def update
|
||||||
@topic = Topic.find(params[:id])
|
|
||||||
authorize @topic
|
|
||||||
@topic.updated_by = current_user
|
@topic.updated_by = current_user
|
||||||
@topic.assign_attributes(topic_params)
|
@topic.assign_attributes(topic_params)
|
||||||
|
|
||||||
|
@ -165,8 +152,6 @@ class TopicsController < ApplicationController
|
||||||
|
|
||||||
# DELETE topics/:id
|
# DELETE topics/:id
|
||||||
def destroy
|
def destroy
|
||||||
@topic = Topic.find(params[:id])
|
|
||||||
authorize @topic
|
|
||||||
@topic.updated_by = current_user
|
@topic.updated_by = current_user
|
||||||
@topic.destroy
|
@topic.destroy
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
|
@ -174,8 +159,39 @@ class TopicsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# POST topics/:id/follow
|
||||||
|
def follow
|
||||||
|
follow = FollowService.follow(@topic, current_user, 'followed')
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.json do
|
||||||
|
if follow
|
||||||
|
head :ok
|
||||||
|
else
|
||||||
|
head :bad_request
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST topics/:id/unfollow
|
||||||
|
def unfollow
|
||||||
|
FollowService.unfollow(@topic, current_user)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.json do
|
||||||
|
head :ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def set_topic
|
||||||
|
@topic = Topic.find(params[:id])
|
||||||
|
authorize @topic
|
||||||
|
end
|
||||||
|
|
||||||
def topic_params
|
def topic_params
|
||||||
params.require(:topic).permit(:id, :name, :desc, :link, :permission, :metacode_id, :defer_to_map_id)
|
params.require(:topic).permit(:id, :name, :desc, :link, :permission, :metacode_id, :defer_to_map_id)
|
||||||
end
|
end
|
||||||
|
|
|
@ -52,10 +52,20 @@ class User < ApplicationRecord
|
||||||
|
|
||||||
# override default as_json
|
# override default as_json
|
||||||
def as_json(_options = {})
|
def as_json(_options = {})
|
||||||
{ id: id,
|
json = { id: id,
|
||||||
name: name,
|
name: name,
|
||||||
image: image.url(:sixtyfour),
|
image: image.url(:sixtyfour),
|
||||||
admin: admin }
|
admin: admin }
|
||||||
|
if (_options[:follows])
|
||||||
|
json['follows'] = {
|
||||||
|
topics: following.where(followed_type: 'Topic').to_a.map(&:followed_id),
|
||||||
|
maps: following.where(followed_type: 'Map').to_a.map(&:followed_id)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
if (_options[:email])
|
||||||
|
json['email'] = email
|
||||||
|
end
|
||||||
|
json
|
||||||
end
|
end
|
||||||
|
|
||||||
def as_json_for_autocomplete
|
def as_json_for_autocomplete
|
||||||
|
|
|
@ -90,4 +90,12 @@ class MapPolicy < ApplicationPolicy
|
||||||
def unstar?
|
def unstar?
|
||||||
user.present?
|
user.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def follow?
|
||||||
|
show? && user.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def unfollow?
|
||||||
|
user.present?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -55,6 +55,14 @@ class TopicPolicy < ApplicationPolicy
|
||||||
show?
|
show?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def follow?
|
||||||
|
show? && user.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def unfollow?
|
||||||
|
user.present?
|
||||||
|
end
|
||||||
|
|
||||||
# Helpers
|
# Helpers
|
||||||
def map_policy
|
def map_policy
|
||||||
@map_policy ||= Pundit.policy(user, record.defer_to_map)
|
@map_policy ||= Pundit.policy(user, record.defer_to_map)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<%= render :partial => 'shared/metacodeBgColors' %>
|
<%= render :partial => 'shared/metacodeBgColors' %>
|
||||||
<script type="text/javascript" charset="utf-8">
|
<script type="text/javascript" charset="utf-8">
|
||||||
<% if current_user %>
|
<% if current_user %>
|
||||||
Metamaps.ServerData.ActiveMapper = <%= current_user.to_json.html_safe %>
|
Metamaps.ServerData.ActiveMapper = <%= current_user.to_json({follows: true, email: true}).html_safe %>
|
||||||
<% else %>
|
<% else %>
|
||||||
Metamaps.ServerData.ActiveMapper = null
|
Metamaps.ServerData.ActiveMapper = null
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -48,6 +48,8 @@ Metamaps::Application.routes.draw do
|
||||||
|
|
||||||
post :star, to: 'stars#create', default: { format: :json }
|
post :star, to: 'stars#create', default: { format: :json }
|
||||||
post :unstar, to: 'stars#destroy', default: { format: :json }
|
post :unstar, to: 'stars#destroy', default: { format: :json }
|
||||||
|
post :follow, default: { format: :json }
|
||||||
|
post :unfollow, default: { format: :json }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -83,6 +85,8 @@ Metamaps::Application.routes.draw do
|
||||||
get :network
|
get :network
|
||||||
get :relative_numbers
|
get :relative_numbers
|
||||||
get :relatives
|
get :relatives
|
||||||
|
post :follow, default: { format: :json }
|
||||||
|
post :unfollow, default: { format: :json }
|
||||||
end
|
end
|
||||||
collection do
|
collection do
|
||||||
get :autocomplete_topic
|
get :autocomplete_topic
|
||||||
|
|
|
@ -34,6 +34,9 @@ const Map = Backbone.Model.extend({
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
isFollowedBy: function(mapper) {
|
||||||
|
return mapper.get('follows') && mapper.get('follows').maps.indexOf(this.get('id')) > -1
|
||||||
|
},
|
||||||
getUser: function() {
|
getUser: function() {
|
||||||
return Mapper.get(this.get('user_id'))
|
return Mapper.get(this.get('user_id'))
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,7 +5,7 @@ import outdent from 'outdent'
|
||||||
|
|
||||||
const Mapper = Backbone.Model.extend({
|
const Mapper = Backbone.Model.extend({
|
||||||
urlRoot: '/users',
|
urlRoot: '/users',
|
||||||
blacklist: ['created_at', 'updated_at'],
|
blacklist: ['created_at', 'updated_at', 'follows'],
|
||||||
toJSON: function(options) {
|
toJSON: function(options) {
|
||||||
return _.omit(this.attributes, this.blacklist)
|
return _.omit(this.attributes, this.blacklist)
|
||||||
},
|
},
|
||||||
|
@ -15,6 +15,20 @@ const Mapper = Backbone.Model.extend({
|
||||||
<img src="${this.get('image')}" data-id="${this.id}" alt="${this.get('name')}" />
|
<img src="${this.get('image')}" data-id="${this.id}" alt="${this.get('name')}" />
|
||||||
<p>${this.get('name')}</p>
|
<p>${this.get('name')}</p>
|
||||||
</li>`
|
</li>`
|
||||||
|
},
|
||||||
|
followMap: function(id) {
|
||||||
|
this.get('follows').maps.push(id)
|
||||||
|
},
|
||||||
|
unfollowMap: function(id) {
|
||||||
|
const idIndex = this.get('follows').maps.indexOf(id)
|
||||||
|
if (idIndex > -1) this.get('follows').maps.splice(idIndex, 1)
|
||||||
|
},
|
||||||
|
followTopic: function(id) {
|
||||||
|
this.get('follows').topics.push(id)
|
||||||
|
},
|
||||||
|
unfollowTopic: function(id) {
|
||||||
|
const idIndex = this.get('follows').topics.indexOf(id)
|
||||||
|
if (idIndex > -1) this.get('follows').topics.splice(idIndex, 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,9 @@ const Topic = Backbone.Model.extend({
|
||||||
if (mapper && this.get('user_id') === mapper.get('id')) return true
|
if (mapper && this.get('user_id') === mapper.get('id')) return true
|
||||||
else return false
|
else return false
|
||||||
},
|
},
|
||||||
|
isFollowedBy: function(mapper) {
|
||||||
|
return mapper.get('follows') && mapper.get('follows').topics.indexOf(this.get('id')) > -1
|
||||||
|
},
|
||||||
getDate: function() {},
|
getDate: function() {},
|
||||||
getMetacode: function() {
|
getMetacode: function() {
|
||||||
return DataModel.Metacodes.get(this.get('metacode_id'))
|
return DataModel.Metacodes.get(this.get('metacode_id'))
|
||||||
|
|
|
@ -181,6 +181,9 @@ const Util = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return text
|
return text
|
||||||
|
},
|
||||||
|
isTester: function(currentUser) {
|
||||||
|
return ['connorturland@gmail.com', 'devin@callysto.com', 'chessscholar@gmail.com', 'solaureum@gmail.com', 'ishanshapiro@gmail.com'].indexOf(currentUser.get('email')) > -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,20 @@ const ExploreMaps = {
|
||||||
url: `/maps/${map.id}/access_request`
|
url: `/maps/${map.id}/access_request`
|
||||||
})
|
})
|
||||||
GlobalUI.notifyUser('You will be notified by email if request accepted')
|
GlobalUI.notifyUser('You will be notified by email if request accepted')
|
||||||
|
},
|
||||||
|
onFollow: function(map) {
|
||||||
|
const isFollowing = map.isFollowedBy(Active.Mapper)
|
||||||
|
$.post({
|
||||||
|
url: `/maps/${map.id}/${isFollowing ? 'un' : ''}follow`
|
||||||
|
})
|
||||||
|
if (isFollowing) {
|
||||||
|
GlobalUI.notifyUser('You are no longer following this map')
|
||||||
|
Active.Mapper.unfollowMap(map.id)
|
||||||
|
} else {
|
||||||
|
GlobalUI.notifyUser('You are now following this map')
|
||||||
|
Active.Mapper.followMap(map.id)
|
||||||
|
}
|
||||||
|
self.render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React, { Component, PropTypes } from 'react'
|
import React, { Component, PropTypes } from 'react'
|
||||||
import { find, values } from 'lodash'
|
import { find, values } from 'lodash'
|
||||||
|
import Util from '../../Metamaps/Util'
|
||||||
|
|
||||||
const IN_CONVERSATION = 1 // shared with /realtime/reducer.js
|
const IN_CONVERSATION = 1 // shared with /realtime/reducer.js
|
||||||
|
|
||||||
|
@ -23,7 +24,8 @@ class Menu extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render = () => {
|
render = () => {
|
||||||
const { currentUser, map, onStar, onRequest } = this.props
|
const { currentUser, map, onStar, onRequest, onFollow } = this.props
|
||||||
|
const isFollowing = map.isFollowedBy(currentUser)
|
||||||
const style = { display: this.state.open ? 'block' : 'none' }
|
const style = { display: this.state.open ? 'block' : 'none' }
|
||||||
|
|
||||||
return <div className='dropdownMenu'>
|
return <div className='dropdownMenu'>
|
||||||
|
@ -35,6 +37,7 @@ class Menu extends Component {
|
||||||
<ul className='menuItems' style={ style }>
|
<ul className='menuItems' style={ style }>
|
||||||
<li className='star' onClick={ () => { this.toggle() && onStar(map) }}>Star Map</li>
|
<li className='star' onClick={ () => { this.toggle() && onStar(map) }}>Star Map</li>
|
||||||
{ !map.authorizeToEdit(currentUser) && <li className='request' onClick={ () => { this.toggle() && onRequest(map) }}>Request Access</li> }
|
{ !map.authorizeToEdit(currentUser) && <li className='request' onClick={ () => { this.toggle() && onRequest(map) }}>Request Access</li> }
|
||||||
|
{ Util.isTester(currentUser) && <li className='follow' onClick={ () => { this.toggle() && onFollow(map) }}>{isFollowing ? 'Unfollow' : 'Follow'}</li> }
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -43,7 +46,8 @@ Menu.propTypes = {
|
||||||
currentUser: PropTypes.object.isRequired,
|
currentUser: PropTypes.object.isRequired,
|
||||||
map: PropTypes.object.isRequired,
|
map: PropTypes.object.isRequired,
|
||||||
onStar: PropTypes.func.isRequired,
|
onStar: PropTypes.func.isRequired,
|
||||||
onRequest: PropTypes.func.isRequired
|
onRequest: PropTypes.func.isRequired,
|
||||||
|
onFollow: PropTypes.func.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
const Metadata = (props) => {
|
const Metadata = (props) => {
|
||||||
|
@ -80,7 +84,7 @@ const checkAndWrapInA = (shouldWrap, classString, mapId, element) => {
|
||||||
|
|
||||||
class MapCard extends Component {
|
class MapCard extends Component {
|
||||||
render = () => {
|
render = () => {
|
||||||
const { map, mobile, juntoState, currentUser, onRequest, onStar } = this.props
|
const { map, mobile, juntoState, currentUser, onRequest, onStar, onFollow } = this.props
|
||||||
|
|
||||||
const hasMap = (juntoState.liveMaps[map.id] && values(juntoState.liveMaps[map.id]).length) || null
|
const hasMap = (juntoState.liveMaps[map.id] && values(juntoState.liveMaps[map.id]).length) || null
|
||||||
const realtimeMap = juntoState.liveMaps[map.id]
|
const realtimeMap = juntoState.liveMaps[map.id]
|
||||||
|
@ -131,7 +135,7 @@ class MapCard extends Component {
|
||||||
</div>) }
|
</div>) }
|
||||||
{ !mobile && hasMapper && <div className='mapHasMapper'><MapperList mappers={ mapperList } /></div> }
|
{ !mobile && hasMapper && <div className='mapHasMapper'><MapperList mappers={ mapperList } /></div> }
|
||||||
{ !mobile && hasConversation && <div className='mapHasConversation'><MapperList mappers={ mapperList } /></div> }
|
{ !mobile && hasConversation && <div className='mapHasConversation'><MapperList mappers={ mapperList } /></div> }
|
||||||
{ !mobile && currentUser && <Menu currentUser={ currentUser } map={ map } onStar= { onStar } onRequest={ onRequest } /> }
|
{ !mobile && currentUser && <Menu currentUser={ currentUser } map={ map } onStar= { onStar } onRequest={ onRequest } onFollow={ onFollow } /> }
|
||||||
</div>
|
</div>
|
||||||
</div>) }
|
</div>) }
|
||||||
</div>
|
</div>
|
||||||
|
@ -145,7 +149,8 @@ MapCard.propTypes = {
|
||||||
juntoState: PropTypes.object,
|
juntoState: PropTypes.object,
|
||||||
currentUser: PropTypes.object,
|
currentUser: PropTypes.object,
|
||||||
onStar: PropTypes.func.isRequired,
|
onStar: PropTypes.func.isRequired,
|
||||||
onRequest: PropTypes.func.isRequired
|
onRequest: PropTypes.func.isRequired,
|
||||||
|
onFollow: PropTypes.func.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MapCard
|
export default MapCard
|
||||||
|
|
|
@ -46,7 +46,7 @@ class Maps extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render = () => {
|
render = () => {
|
||||||
const { maps, currentUser, juntoState, pending, section, user, onStar, onRequest } = this.props
|
const { maps, currentUser, juntoState, pending, section, user, onStar, onRequest, onFollow } = this.props
|
||||||
const style = { width: this.state.mapsWidth + 'px' }
|
const style = { width: this.state.mapsWidth + 'px' }
|
||||||
const mobile = document && document.body.clientWidth <= MOBILE_VIEW_BREAKPOINT
|
const mobile = document && document.body.clientWidth <= MOBILE_VIEW_BREAKPOINT
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ class Maps extends Component {
|
||||||
<div style={ style }>
|
<div style={ style }>
|
||||||
{ user ? <MapperCard user={ user } /> : null }
|
{ user ? <MapperCard user={ user } /> : null }
|
||||||
{ currentUser && !user && !(pending && maps.length === 0) ? <div className="map newMap"><a href="/maps/new"><div className="newMapImage"></div><span>Create new map...</span></a></div> : null }
|
{ currentUser && !user && !(pending && maps.length === 0) ? <div className="map newMap"><a href="/maps/new"><div className="newMapImage"></div><span>Create new map...</span></a></div> : null }
|
||||||
{ maps.models.map(map => <MapCard key={ map.id } map={ map } mobile={ mobile } juntoState={ juntoState } currentUser={ currentUser } onStar={ onStar } onRequest={ onRequest } />) }
|
{ maps.models.map(map => <MapCard key={ map.id } map={ map } mobile={ mobile } juntoState={ juntoState } currentUser={ currentUser } onStar={ onStar } onRequest={ onRequest } onFollow={ onFollow } />) }
|
||||||
<div className='clearfloat'></div>
|
<div className='clearfloat'></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -79,7 +79,8 @@ Maps.propTypes = {
|
||||||
loadMore: PropTypes.func,
|
loadMore: PropTypes.func,
|
||||||
pending: PropTypes.bool.isRequired,
|
pending: PropTypes.bool.isRequired,
|
||||||
onStar: PropTypes.func.isRequired,
|
onStar: PropTypes.func.isRequired,
|
||||||
onRequest: PropTypes.func.isRequired
|
onRequest: PropTypes.func.isRequired,
|
||||||
|
onFollow: PropTypes.func.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Maps
|
export default Maps
|
||||||
|
|
Loading…
Add table
Reference in a new issue