diff --git a/app/assets/images/view-only.png b/app/assets/images/view-only.png new file mode 100644 index 00000000..a4cc262f Binary files /dev/null and b/app/assets/images/view-only.png differ diff --git a/app/assets/stylesheets/request_access.scss.erb b/app/assets/stylesheets/request_access.scss.erb index 59c82dd7..19ae2792 100644 --- a/app/assets/stylesheets/request_access.scss.erb +++ b/app/assets/stylesheets/request_access.scss.erb @@ -1,3 +1,58 @@ +.viewOnly { + float: left; + margin-left: 16px; + display: none; + height: 32px; + border: 1px solid #BDBDBD; + border-radius: 2px; + background-color: #424242; + color: #FFF; + font-size: 14px; + line-height: 32px; + + &.isViewOnly { + display: block; + } + + .eyeball { + background: url('<%= asset_path('view-only.png') %>') no-repeat 4px 0; + padding-left: 40px; + border-right: #747474; + padding-right: 10px; + display: inline-block; + } + + .requestNotice { + display: none; + padding: 0 8px; + } + + .requestAccess { + background-color: #a354cd; + &:hover { + background-color: #9150bc; + } + cursor: pointer; + } + + .requestPending { + background-color: #4fc059; + } + + .requestNotAccepted { + background-color: #c04f4f; + } + + &.sendRequest .requestAccess { + display: inline-block; + } + &.sentRequest .requestPending { + display: inline-block; + } + &.requestDenied .requestNotAccepted { + display: inline-block; + } +} .request_access { position: absolute; diff --git a/app/controllers/access_controller.rb b/app/controllers/access_controller.rb new file mode 100644 index 00000000..302e9385 --- /dev/null +++ b/app/controllers/access_controller.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true +class AccessController < ApplicationController + before_action :require_user, only: [:access, :access_request, :approve_access, :approve_access_post, + :deny_access, :deny_access_post, :request_access] + before_action :set_map, only: [:access, :access_request, :approve_access, :approve_access_post, + :deny_access, :deny_access_post, :request_access] + after_action :verify_authorized + + + # GET maps/:id/request_access + def request_access + @map = nil + respond_to do |format| + format.html do + render 'maps/request_access' + end + end + end + + # POST maps/:id/access_request + def access_request + request = AccessRequest.create(user: current_user, map: @map) + # what about push notification to map owner? + MapMailer.access_request_email(request, @map).deliver_later + + respond_to do |format| + format.json do + head :ok + end + end + end + + # POST maps/:id/access + def access + user_ids = params[:access] || [] + + @map.add_new_collaborators(user_ids).each do |user_id| + # add_new_collaborators returns array of added users, + # who we then send an email to + MapMailer.invite_to_edit_email(@map, current_user, User.find(user_id)).deliver_later + end + @map.remove_old_collaborators(user_ids) + + respond_to do |format| + format.json do + head :ok + end + end + end + + # GET maps/:id/approve_access/:request_id + def approve_access + request = AccessRequest.find(params[:request_id]) + request.approve() + respond_to do |format| + format.html { redirect_to map_path(@map), notice: 'Request was approved' } + end + end + + # GET maps/:id/deny_access/:request_id + def deny_access + request = AccessRequest.find(params[:request_id]) + request.deny() + respond_to do |format| + format.html { redirect_to map_path(@map), notice: 'Request was turned down' } + end + end + + # POST maps/:id/approve_access/:request_id + def approve_access_post + request = AccessRequest.find(params[:request_id]) + request.approve() + respond_to do |format| + format.json do + head :ok + end + end + end + + # POST maps/:id/deny_access/:request_id + def deny_access_post + request = AccessRequest.find(params[:request_id]) + request.deny() + respond_to do |format| + format.json do + head :ok + end + end + end + + private + + def set_map + @map = Map.find(params[:id]) + authorize @map + end + +end diff --git a/app/controllers/maps_controller.rb b/app/controllers/maps_controller.rb index f166d4ee..7044d424 100644 --- a/app/controllers/maps_controller.rb +++ b/app/controllers/maps_controller.rb @@ -1,9 +1,7 @@ # frozen_string_literal: true class MapsController < ApplicationController - before_action :require_user, only: [:create, :update, :destroy, :access, :events] - before_action :set_map, only: [:show, :request_access, :update, :destroy, :access, :contains, - :events, :export, :access_request, :approve_access, :deny_access, :approve_access_post, - :deny_access_post] + before_action :require_user, only: [:create, :update, :destroy, :events] + before_action :set_map, only: [:show, :update, :destroy, :contains, :events, :export] after_action :verify_authorized # GET maps/:id @@ -17,17 +15,13 @@ class MapsController < ApplicationController @allmappings = policy_scope(@map.mappings) @allmessages = @map.messages.sort_by(&:created_at) @allstars = @map.stars + @allrequests = @map.access_requests end format.json { render json: @map } format.csv { redirect_to action: :export, format: :csv } end end - # GET maps/:id/request_access - def request_access - @map = nil - end - # GET maps/new def new @map = Map.new(name: 'Untitled Map', permission: 'public', arranged: true) @@ -86,37 +80,6 @@ class MapsController < ApplicationController end end - # POST maps/:id/access_request - def access_request - request = AccessRequest.create(user: current_user, map: @map) - # what about push notification to map owner? - MapMailer.access_request_email(request, @map).deliver_later - - respond_to do |format| - format.json do - head :ok - end - end - end - - # POST maps/:id/access - def access - user_ids = params[:access] || [] - - @map.add_new_collaborators(user_ids).each do |user_id| - # add_new_collaborators returns array of added users, - # who we then send an email to - MapMailer.invite_to_edit_email(@map, current_user, User.find(user_id)).deliver_later - end - @map.remove_old_collaborators(user_ids) - - respond_to do |format| - format.json do - head :ok - end - end - end - # GET maps/:id/contains def contains respond_to do |format| @@ -152,48 +115,6 @@ class MapsController < ApplicationController end end - # GET maps/:id/approve_access/:request_id - def approve_access - request = AccessRequest.find_by_id(params[:request_id]) - request.approve() if request - respond_to do |format| - format.html { redirect_to map_path(@map), notice: request ? 'Request was approved' : 'No request there to approve' } - end - end - - # GET maps/:id/deny_access/:request_id - def deny_access - request = AccessRequest.find_by_id(params[:request_id]) - request.deny() if request - respond_to do |format| - format.html { redirect_to map_path(@map), notice: request ? 'Request was turned down' : 'No request there to deny' } - end - end - - # POST maps/:id/approve_access/:request_id - def approve_access_post - request = AccessRequest.find_by_id(params[:request_id]) - request.approve() if request - respond_to do |format| - format.json do - head :bad_request unless request - head :ok - end - end - end - - # POST maps/:id/deny_access/:request_id - def deny_access_post - request = AccessRequest.find_by_id(params[:request_id]) - request.deny() if request - respond_to do |format| - format.json do - head :bad_request unless request - head :ok - end - end - end - private def set_map diff --git a/app/models/access_request.rb b/app/models/access_request.rb index bbe3d562..185a04f0 100644 --- a/app/models/access_request.rb +++ b/app/models/access_request.rb @@ -7,13 +7,12 @@ class AccessRequest < ApplicationRecord self.answered = true self.save UserMap.create(user: self.user, map: self.map) - # send an email and push notification here? + MapMailer.invite_to_edit_email(self.map, self.map.user, self.user).deliver_later end def deny self.approved = false self.answered = true self.save - # send an email and push notification here? end end diff --git a/app/models/map.rb b/app/models/map.rb index 53ffd7af..cdd6b333 100644 --- a/app/models/map.rb +++ b/app/models/map.rb @@ -103,7 +103,8 @@ class Map < ApplicationRecord mappers: contributors, collaborators: editors, messages: messages.sort_by(&:created_at), - stars: stars + stars: stars, + requests: access_requests } end @@ -123,6 +124,7 @@ class Map < ApplicationRecord removed = current_collaborators.map(&:id).map do |old_user_id| next nil if user_ids.include?(old_user_id) user_maps.where(user_id: old_user_id).find_each(&:destroy) + access_requests.where(user_id: old_user_id).find_each(&:destroy) old_user_id end removed.compact diff --git a/app/views/layouts/_upperelements.html.erb b/app/views/layouts/_upperelements.html.erb index c2344643..1d26ced9 100644 --- a/app/views/layouts/_upperelements.html.erb +++ b/app/views/layouts/_upperelements.html.erb @@ -14,6 +14,23 @@
+ + <% request = current_user && @map && @allrequests.find{|a| a.user == current_user} + className = (@map and not policy(@map).update?) ? 'isViewOnly ' : '' + if @map + className += 'sendRequest' if not request + className += 'sentRequest' if request and not request.answered + className += 'requestDenied' if request and request.answered and not request.approved + end %> + +<%= @inviter.name %> has invited you to collaboratively edit the following metamap:
+<%= @inviter.name %> has invited you to collaboratively edit the following map:
<%= link_to @map.name, map_url(@map), target: "_blank", style: "font-size: 18px; text-decoration: none; color: #4fc059;" %>
<% if @map.desc %><%= @map.desc %>
diff --git a/app/views/map_mailer/invite_to_edit_email.text.erb b/app/views/map_mailer/invite_to_edit_email.text.erb index 62bd2c90..80eecfed 100644 --- a/app/views/map_mailer/invite_to_edit_email.text.erb +++ b/app/views/map_mailer/invite_to_edit_email.text.erb @@ -1,4 +1,4 @@ -<%= @inviter.name %> has invited you to collaboratively edit the following metamap: +<%= @inviter.name %> has invited you to collaboratively edit the following map: <%= @map.name %> [<%= map_url(@map) %>] diff --git a/app/views/maps/request_access.html.erb b/app/views/maps/request_access.html.erb index fe036c37..cf8aadb4 100644 --- a/app/views/maps/request_access.html.erb +++ b/app/views/maps/request_access.html.erb @@ -7,12 +7,14 @@ <% content_for :title, 'Request Access | Metamaps' %> <% content_for :mobile_title, 'Request Access' %> -