diff --git a/app.rb b/app.rb index 928b944d8bad13d9f806705e3e75766babfa6fa6..f0e81d85109c25e78eeea379f75f2dbb063f4ae9 100644 --- a/app.rb +++ b/app.rb @@ -72,7 +72,7 @@ helpers do raise Sinatra::NotFound if space.nil? @space = space - if !@user.in_space(@space) + if !@user.in_space?(@space) flash :error, 'Unauthorized', 'Sorry, you don\'t have access to this service space.' redirect '/' end diff --git a/models/service_space.rb b/models/service_space.rb index 23ee9d2485a733abd4d108a8dcaba734b2e4755a..e0018b8449db18e8e1c160657a323840883fab94 100644 --- a/models/service_space.rb +++ b/models/service_space.rb @@ -26,4 +26,12 @@ class ServiceSpace < ActiveRecord::Base def admin_resources_href "/#{self.url_name}/admin/resources/" end + + def admin_hours_href + "/#{self.url_name}/admin/hours/" + end + + def admin_users_href + "/#{self.url_name}/admin/users/" + end end \ No newline at end of file diff --git a/models/user.rb b/models/user.rb index c4f8656878ee4ef233d45af972667d3687c8aef3..59e5a49e6d22ea7764be502e6b2da40dacac45e7 100644 --- a/models/user.rb +++ b/models/user.rb @@ -15,10 +15,14 @@ class User < ActiveRecord::Base def service_spaces ServiceSpace.all.select do |space| - self.in_space(space) + self.in_space?(space) end end + def permissions_in_space(space) + self.user_has_permissions.where(:service_space_id => space.id).all.map {|uhp| uhp.permission} + end + def authorized_resource_ids self.resource_authorizations.map {|res_auth| res_auth.resource_id} end @@ -47,9 +51,10 @@ class User < ActiveRecord::Base end # just notes whether they have any permissions in the space, and can access it at all - def in_space(space) + def is_in_space?(space) !self.user_has_permissions.where(:service_space_id => space.id).empty? end + alias_method :in_space?, :is_in_space? def full_name "#{first_name} #{last_name}" diff --git a/models/user_has_permission.rb b/models/user_has_permission.rb index 24ec5aac86cc5f3a1995c0d70f4ad3f5a674a5c6..c944b38a51fdf7907760395c89da117d6e5f45a0 100644 --- a/models/user_has_permission.rb +++ b/models/user_has_permission.rb @@ -5,7 +5,7 @@ class UserHasPermission < ActiveRecord::Base belongs_to :permission belongs_to :service_space - scope :in_space, ->(space) { + scope :in_space?, ->(space) { where(:service_space_id => space.id) } end \ No newline at end of file diff --git a/routes/admin.rb b/routes/admin.rb index 758377fe9ca4e026452009de5da8a2c6cc14ce09..e1a8f628434ff7eed6ff9176d34072a6ab4d57e8 100644 --- a/routes/admin.rb +++ b/routes/admin.rb @@ -12,7 +12,6 @@ end get '/:service_space_url_name/admin/?' do @breadcrumbs << {:text => 'Admin Home'} - user_count = User.where(:service_space_id => @space.id).count upcoming_event_count = Event.where(:service_space_id => @space.id).where('start_time >= ?', Time.now).count resource_count = Resource.where(:service_space_id => @space.id).count @@ -32,7 +31,6 @@ get '/:service_space_url_name/admin/?' do end erb :'admin/home', :layout => :fixed, :locals => { - :user_count => user_count, :upcoming_event_count => upcoming_event_count, :resource_count => resource_count, :space_hour => correct_hour, diff --git a/routes/admin/events.rb b/routes/admin/events.rb index 3bd265a39674764acc7616ed898ca435a4e09f1f..79f833b55a55b3fce1e182a5a66dfb1230fadf0a 100644 --- a/routes/admin/events.rb +++ b/routes/admin/events.rb @@ -37,7 +37,7 @@ get '/:service_space_url_name/admin/events/?' do end get '/:service_space_url_name/admin/events/:event_id/signup_list/?' do - @breadcrumbs << {:text => 'Admin Events', :href => '/admin/events/'} << {text: 'Signup List'} + @breadcrumbs << {:text => 'Admin Events', :href => @space.admin_events_href} << {text: 'Signup List'} event = Event.includes(:event_signups).find_by(:id => params[:event_id], :service_space_id => @space.id) if event.nil? # that event does not exist @@ -51,7 +51,7 @@ get '/:service_space_url_name/admin/events/:event_id/signup_list/?' do end get '/:service_space_url_name/admin/events/create/?' do - @breadcrumbs << {:text => 'Admin Events', :href => '/admin/events/'} << {text: 'Create Event'} + @breadcrumbs << {:text => 'Admin Events', :href => @space.admin_events_href} << {text: 'Create Event'} erb :'admin/new_event', :layout => :fixed, :locals => { :event => Event.new, :types => EventType.where(:service_space_id => @space.id).all, @@ -94,7 +94,7 @@ post '/:service_space_url_name/admin/events/create/?' do end get '/:service_space_url_name/admin/events/:event_id/edit/?' do - @breadcrumbs << {:text => 'Admin Events', :href => '/admin/events/'} << {text: 'Edit Event'} + @breadcrumbs << {:text => 'Admin Events', :href => @space.admin_events_href} << {text: 'Edit Event'} event = Event.includes(:event_type, :location, :reservation => :resource).find_by(:id => params[:event_id], :service_space_id => @space.id) if event.nil? # that event does not exist diff --git a/routes/admin/hours.rb b/routes/admin/hours.rb new file mode 100644 index 0000000000000000000000000000000000000000..bf95df8ec73ddb5719659856a233cba96821fdd4 --- /dev/null +++ b/routes/admin/hours.rb @@ -0,0 +1,222 @@ +require 'json' +require 'models/space_hour' +require 'models/permission' + +before '/:service_space_url_name/admin/hours*' do + unless @user.has_permission?(Permission::MANAGE_SPACE_HOURS, @space) + raise Sinatra::NotFound + end +end + +get '/:service_space_url_name/admin/hours/?' do + session.delete(:space_hour) + session.delete(:hours) + + # get the hours for this week to show + date = params[:date].nil? ? Time.now.in_time_zone.midnight : Time.parse(params[:date]).in_time_zone.midnight + sunday = date.week_start + + hours = SpaceHour.where(:service_space_id => @space.id) + .where('effective_date < ?', (sunday+1.week+1.hour).midnight.utc.strftime('%Y-%m-%d %H:%M:%S')) + .order(:day_of_week, :effective_date => :desc, :id => :desc).all.to_a + + hours_days = hours.group_by do |space_hour| + space_hour.day_of_week + end + + week_hours = {} + hours_days.each do |number_of_days, array| + this_day = (sunday + number_of_days.days + 1.hour).midnight + + # find the correct hour record to use for this day + array.each do |space_hour| + if space_hour.effective_date.in_time_zone.midnight == this_day.in_time_zone.midnight || (!space_hour.one_off && space_hour.effective_date.in_time_zone.midnight <= this_day.in_time_zone.midnight) + week_hours[number_of_days] = space_hour + break + end + end + end + + upcoming_hours = SpaceHour.where(:service_space_id => @space.id) + .where('effective_date >= ?', date.utc.strftime('%Y-%m-%d %H:%M:%S')) + .where('effective_date <= ?', (date+31.days).utc.strftime('%Y-%m-%d %H:%M:%S')) + .order(:effective_date).all + + erb :'admin/hours', :layout => :fixed, :locals => { + :weeks_hours => week_hours, + :upcoming_hours => upcoming_hours, + :sunday => sunday, + :date => date + } +end + +get '/:service_space_url_name/admin/hours/create/?' do + # show a form for setting a weekly schedule for a day or a one-off + erb :'admin/new_hours', :layout => :fixed, :locals => { + :space_hour => SpaceHour.new, + :hours => session.delete(:hours) + } +end + +get '/:service_space_url_name/admin/hours/:hour_id/edit/?' do + space_hour = SpaceHour.where(:service_space_id => @space.id, :id => params[:hour_id]).first + if space_hour.nil? + flash :error, 'Not Found', 'Those hours were not found.' + redirect @space.admin_hours_href + end + + # show form for editing + erb :'admin/new_hours', :layout => :fixed, :locals => { + :space_hour => session.delete(:space_hour) || space_hour, + :hours => session.delete(:hours) || space_hour.hours + } +end + +post '/:service_space_url_name/admin/hours/:hour_id/edit/?' do + space_hour = SpaceHour.where(:service_space_id => @space.id, :id => params[:hour_id]).first + if space_hour.nil? + flash :error, 'Not Found', 'Those hours were not found.' + redirect @space.admin_hours_href + end + + # basically put the inputted data into the database + eff_date = calculate_time(params[:effective_date], 0, 0, 'am').in_time_zone.midnight + day_of_week = params[:day_of_week] == 'one_off' ? eff_date.wday : params[:day_of_week] + + space_hour.day_of_week = day_of_week + space_hour.effective_date = eff_date + space_hour.one_off = params[:day_of_week] == 'one_off' + + # Sort records by start + hours_params = JSON.parse(params[:hours]) + hours_params.map! do |record| + start_time = calculate_time(eff_date.strftime('%Y-%m-%d'), record['start_hour'], record['start_minute'], record['start_am_pm']) + end_time = calculate_time(eff_date.strftime('%Y-%m-%d'), record['end_hour'], record['end_minute'], record['end_am_pm']) + { + :status => record['status'], + :start => start_time.hour * 60 + start_time.min, + :end => end_time.hour * 60 + end_time.min + } + end.sort! do |a,b| + a[:start] <=> b[:start] + end + + hours_params.each do |record| + if record[:start] > record[:end] + # error here, this is invalid + flash :danger, 'Improper Hours', "Your end times must each be after their start time." + session[:space_hour] = space_hour + session[:hours] = hours_params + redirect "#{@space.admin_hours_href}#{space_hour.id}/edit/" + end + end + + # check that record starts and ends do not overlap. + zones = [] + hours_params.each do |record| + zones.each do |zone| + if zone.include?(record[:start]) || zone.include?(record[:end]) + # record starts or ends inside of zone, invalid + flash :danger, 'Improper Hours', "Your hours for this day must not overlap." + session[:hours] = hours_params + session[:space_hour] = space_hour + redirect "#{@space.admin_hours_href}#{space_hour.id}/edit/" + elsif zone.min < record[:start] && zone.max > record[:end] + # new record covers entire zone, invalid + flash :danger, 'Improper Hours', "Your hours for this day must not overlap." + session[:hours] = hours_params + session[:space_hour] = space_hour + redirect "#{@space.admin_hours_href}#{space_hour.id}/edit/" + end + end + # add this record to the zones + zones << (record[:start]..record[:end]) + end + + space_hour.update({ + :service_space_id => @space.id, + :day_of_week => day_of_week, + :effective_date => eff_date, + :one_off => params[:day_of_week] == 'one_off', + :hours => hours_params + }) + + flash :success, 'Hours Saved', "Your hours effective #{eff_date.strftime('%B %d, %Y')} have been saved." + session.delete :hours + redirect @space.admin_hours_href +end + +post '/:service_space_url_name/admin/hours/create/?' do + # basically put the inputted data into the database + eff_date = calculate_time(params[:effective_date], 0, 0, 'am').in_time_zone.midnight + day_of_week = params[:day_of_week] == 'one_off' ? eff_date.wday : params[:day_of_week] + + # Sort records by start + hours_params = JSON.parse(params[:hours]) + hours_params.map! do |record| + start_time = calculate_time(eff_date.strftime('%Y-%m-%d'), record['start_hour'], record['start_minute'], record['start_am_pm']) + end_time = calculate_time(eff_date.strftime('%Y-%m-%d'), record['end_hour'], record['end_minute'], record['end_am_pm']) + { + :status => record['status'], + :start => start_time.hour * 60 + start_time.min, + :end => end_time.hour * 60 + end_time.min + } + end.sort! do |a,b| + a[:start] <=> b[:start] + end + + hours_params.each do |record| + if record[:start] > record[:end] + # error here, this is invalid + flash :danger, 'Improper Hours', "Your end times must each be after their start time." + session[:hours] = hours_params + redirect "#{@space.admin_hours_href}create" + end + end + + # check that record starts and ends do not overlap. + zones = [] + hours_params.each do |record| + zones.each do |zone| + if zone.include?(record[:start]) || zone.include?(record[:end]) + # record starts or ends inside of zone, invalid + flash :danger, 'Improper Hours', "Your hours for this day must not overlap." + session[:hours] = hours_params + redirect "#{@space.admin_hours_href}create" + elsif zone.min < record[:start] && zone.max > record[:end] + # new record covers entire zone, invalid + flash :danger, 'Improper Hours', "Your hours for this day must not overlap." + session[:hours] = hours_params + redirect "#{@space.admin_hours_href}create" + end + end + # add this record to the zones + zones << (record[:start]..record[:end]) + end + + SpaceHour.create({ + :service_space_id => @space.id, + :day_of_week => day_of_week, + :effective_date => eff_date, + :one_off => params[:day_of_week] == 'one_off', + :hours => hours_params + }) + + flash :success, 'Hours Saved', "Your hours effective #{eff_date.strftime('%B %d, %Y')} have been saved." + session.delete :hours + redirect @space.admin_hours_href +end + +post '/:service_space_url_name/admin/hours/:hour_id/delete/?' do + space_hour = SpaceHour.find_by(:id => params[:hour_id], :service_space_id => @space.id) + if space_hour.nil? + # that space hour does not exist + flash(:danger, 'Not Found', 'That hours record does not exist.') + redirect @space.admin_hours_href + end + + space_hour.delete + + flash(:success, 'Hours Change Deleted', "This hours change has been removed.") + redirect @space.admin_hours_href +end \ No newline at end of file diff --git a/routes/admin/resources.rb b/routes/admin/resources.rb index 1c09841a748413139afcba70b9742740938220ec..4da73e8e1f5c2ba94bf289867a87a2c9d42406f4 100644 --- a/routes/admin/resources.rb +++ b/routes/admin/resources.rb @@ -17,7 +17,7 @@ get '/:service_space_url_name/admin/resources/?' do end get '/:service_space_url_name/admin/resources/create/?' do - @breadcrumbs << {:text => 'Admin Resources', :href => '/admin/resources/'} << {:text => 'Create Resource'} + @breadcrumbs << {:text => 'Admin Resources', :href => @space.admin_resources_href} << {:text => 'Create Resource'} erb :'admin/edit_resource', :layout => :fixed, :locals => { :resource => Resource.new @@ -42,7 +42,7 @@ post '/:service_space_url_name/admin/resources/create/?' do end get '/:service_space_url_name/admin/resources/:resource_id/edit/?' do - @breadcrumbs << {:text => 'Admin Resources', :href => '/admin/resources/'} << {:text => 'Edit Resource'} + @breadcrumbs << {:text => 'Admin Resources', :href => @space.admin_resources_href} << {:text => 'Edit Resource'} # check that this is a valid resource resource = Resource.find_by(:id => params[:resource_id], :service_space_id => @space.id) diff --git a/routes/admin/users.rb b/routes/admin/users.rb new file mode 100644 index 0000000000000000000000000000000000000000..1845710417f789f246becd08253d0ad3f9cbad0b --- /dev/null +++ b/routes/admin/users.rb @@ -0,0 +1,212 @@ +require 'models/user' +require 'models/resource' +require 'models/permission' +require 'models/user_has_permission' + +before '/:service_space_url_name/admin/users*' do + unless @user.has_permission?(Permission::MANAGE_USERS, @space) || @user.has_permission?(Permission::SUPER_USER, @space) + raise Sinatra::NotFound + end +end + +get '/:service_space_url_name/admin/users/?' do + @breadcrumbs << {:text => 'Admin Users'} + + selected_resource = params[:selected_resource] + + # get all the users that this admin has created + users = User.includes(:resource_authorizations => :resource) + users = users.order(:last_name, :first_name).all.to_a.select{|user| user.in_space?(@space)} + + unless selected_resource.nil? + users.select! do |user| + user.authorized_resource_ids.include?(selected_resource.to_i) + end + end + + # we need all the resources for the searching + resources = Resource.where(:service_space_id => @space.id).order(:name).all + + erb :'admin/users', :layout => :fixed, :locals => { + :users => users, + :resources => resources, + :selected_resource => selected_resource + } +end + +get '/:service_space_url_name/admin/users/add/?' do + @breadcrumbs << {:text => 'Admin Users', :href => @space.admin_users_href} << {:text => 'Add User'} + + available_users = User.where(:service_space_id => nil).select{|user| !user.in_space?(@space)} + erb :'admin/add_user', :layout => :fixed, :locals => { + :available_users => available_users, + :permissions => Permission.where.not(:id => Permission::SUPER_USER).all, + :su_permission => Permission.find(Permission::SUPER_USER) + } +end + +post '/:service_space_url_name/admin/users/add/?' do + user = User.find_by(:id => params[:user_id]) + + if user.nil? + flash :error, 'Not Found', 'That user could not be found.' + redirect back + end + + # check the permissions, check for new ones + params.select {|k,v| k =~ /permission_*/}.each do |k,v| + if params.checked?(k) + perm_id = k.split('permission_')[1].to_i + unless user.has_permission?(perm_id, @space) + UserHasPermission.create( + :service_space_id => @space.id, + :user_id => user.id, + :permission_id => perm_id + ) + end + end + end + + flash :success, 'User Added', "#{user.full_name} has been added to the space." + redirect @space.admin_users_href +end + +get '/:service_space_url_name/admin/users/:user_id/edit/?' do + if params[:user_id].to_i == @user.id + user = @user + else + user = User.includes(:permissions).find_by(:id => params[:user_id]) + end + + if user.nil? + flash :alert, "Not Found", "Sorry, that user was not found" + redirect @space.admin_users_href + end + + @breadcrumbs << {:text => 'Admin Users', :href => @space.admin_users_href} << {:text => 'Edit User'} + erb :'admin/edit_user', :layout => :fixed, :locals => { + :user => user, + :permissions => Permission.where.not(:id => Permission::SUPER_USER).all, + :su_permission => Permission.find(Permission::SUPER_USER) + } +end + +post '/:service_space_url_name/admin/users/:user_id/edit/?' do + if params[:user_id].to_i == @user.id + user = @user + else + user = User.includes(:permissions).find_by(:id => params[:user_id]) + end + + if user.nil? + flash :alert, "Not Found", "Sorry, that user was not found" + redirect @space.admin_users_href + end + + # check the permissions, check for new ones + params.select {|k,v| k =~ /permission_*/}.each do |k,v| + if params.checked?(k) + perm_id = k.split('permission_')[1].to_i + unless user.has_permission?(perm_id, @space) + UserHasPermission.create( + :service_space_id => @space.id, + :user_id => user.id, + :permission_id => perm_id + ) + end + end + end + + # check for any removed + user.permissions_in_space(@space).each do |perm| + unless params.checked?("permission_#{perm.id}") + x = UserHasPermission.find_by( + :service_space_id => @space.id, + :user_id => user.id, + :permission_id => perm.id + ) + x.delete if x + end + end + + flash :success, 'User Updated', 'Your user has been updated.' + redirect @space.admin_users_href +end + +post '/:service_space_url_name/admin/users/:user_id/delete/?' do + if params[:user_id].to_i == @user.id + user = @user + else + user = User.where(:id => params[:user_id]).first + end + + if user.nil? + flash :alert, "Not Found", "Sorry, that user was not found." + redirect @space.admin_users_href + end + + user.destroy + + flash :success, 'User Deleted', 'That user has been deleted.' + redirect @space.admin_users_href +end + +get '/:service_space_url_name/admin/users/:user_id/manage/?' do + @breadcrumbs << {:text => 'Admin Users', :href => @space.admin_users_href} << {:text => 'Manage User Permissions'} + # check that the admin user has permission to manage this user + if params[:user_id].to_i == @user.id + user = @user + else + user = User.includes(:resource_authorizations).where(:id => params[:user_id]).first + end + + if user.nil? + flash :alert, "Not Found", "Sorry, that user was not found." + redirect @space.admin_users_href + end + + resources = Resource.where(:service_space_id => @space.id, :needs_authorization => true).order(:name).all + erb :'admin/manage_authorizations', :layout => :fixed, :locals => { + :user => user, + :resources => resources + } +end + +post '/:service_space_url_name/admin/users/:user_id/manage/?' do + # check that the admin user has permission to manage this user + if params[:user_id].to_i == @user.id + user = @user + else + user = User.includes(:resource_authorizations).where(:id => params[:user_id]).first + end + + if user.nil? + flash :alert, "Not Found", "Sorry, that user was not found." + redirect @space.admin_users_href + end + + # check for removed permissions + user.authorized_resource_ids.each do |resource_id| + unless params.has_key?("permission_#{resource_id}") && params["permission_#{resource_id}"] == 'on' + ResourceAuthorization.find_by(:user_id => user.id, :resource_id => resource_id).delete + end + end + + # now add new permissions that are checked + params.each do |key, value| + if key.start_with?('permission_') && value == 'on' + id = key.split('permission_')[1].to_i + # check if the user already has permission for this resource + unless user.authorized_resource_ids.include?(id) + ResourceAuthorization.create( + :user_id => user.id, + :resource_id => id, + :authorized_date => Time.now + ) + end + end + end + + flash :success, 'User Authorizations Updated', "User #{user.username}'s authorizations have been updated." + redirect @space.admin_users_href +end \ No newline at end of file diff --git a/views/admin/add_user.erb b/views/admin/add_user.erb new file mode 100644 index 0000000000000000000000000000000000000000..a444b1662f5c5acbce92dd1b90fcd9ea31e89f35 --- /dev/null +++ b/views/admin/add_user.erb @@ -0,0 +1,40 @@ +<div id="pagetitle"> + <h3>Add User</h3> +</div> + +<form id="edit-user" action="" method="POST"> + <div class="wdn-grid-set"> + <fieldset class="bp2-wdn-col-one-half"> + <legend>User Details</legend> + + <label for="user_id">User</label> + <select id="user_id" name="user_id"> + <option value=""></option> + <% available_users.each do |user| %> + <option value="<%= user.id %>"><%= user.sortable_name %> + <% end %> + </select> + </fieldset> + + <% if @user.is_super_user?(@space) %> + <div class="bp2-wdn-col-one-half"> + <fieldset> + <legend>Manager Permissions</legend> + <% permissions.each do |perm| %> + <input type="checkbox" id="permission-<%= perm.id %>" name="permission_<%= perm.id %>"> + <label for="permission-<%= perm.id %>"><%= perm.name %></label><br> + <% end %> + </fieldset> + <fieldset> + <legend>Make Super User</legend> + <label>Super Users can edit any user's permissions in the space and can create new Super Users, as well as + remove your Super User status. Only give Super User to someone you <em>absolutely</em> trust.</label><br> + <br> + <input type="checkbox" id="permission-<%= su_permission.id %>" name="permission_<%= su_permission.id %>"> + <label for="permission-<%= su_permission.id %>"><%= su_permission.name %></label><br> + </fieldset> + </div> + <% end %> + </div> + <button class="wdn-button wdn-button-brand" type="submit">Add</button> +</form> \ No newline at end of file diff --git a/views/admin/edit_user.erb b/views/admin/edit_user.erb new file mode 100644 index 0000000000000000000000000000000000000000..05016d87ec001bc900c604635150383bf2b85a0d --- /dev/null +++ b/views/admin/edit_user.erb @@ -0,0 +1,28 @@ +<div id="pagetitle"> + <h3>Edit User <%= user.username %></h3> +</div> + +<form id="edit-user" action="" method="POST"> + <div class="wdn-grid-set"> + <% if @user.is_super_user?(@space) %> + <div class="bp2-wdn-col-one-half"> + <fieldset> + <legend>Manager Permissions</legend> + <% permissions.each do |perm| %> + <input <%= 'checked="checked"' if user.permissions_in_space(@space).include?(perm) %> type="checkbox" id="permission-<%= perm.id %>" name="permission_<%= perm.id %>"> + <label for="permission-<%= perm.id %>"><%= perm.name %> <%= '(Tools)' if perm.id == Permission::MANAGE_RESOURCES %></label><br> + <% end %> + </fieldset> + <fieldset> + <legend>Make Super User</legend> + <label>Super Users can edit any user's permissions in the space and can create new Super Users, as well as + remove your Super User status. Only give Super User to someone you <em>absolutely</em> trust.</label><br> + <br> + <input <%= 'checked="checked"' if user.permissions_in_space(@space).include?(su_permission) %> type="checkbox" id="permission-<%= su_permission.id %>" name="permission_<%= su_permission.id %>"> + <label for="permission-<%= su_permission.id %>"><%= su_permission.name %></label><br> + </fieldset> + </div> + <% end %> + </div> + <button class="wdn-button wdn-button-brand" type="submit">Update</button> +</form> \ No newline at end of file diff --git a/views/admin/home.erb b/views/admin/home.erb index d4240e15f037fa570d3d1259feb911f44a0b4083..b9858217e18d3206c6adc4b8101611dadb0f795d 100644 --- a/views/admin/home.erb +++ b/views/admin/home.erb @@ -8,7 +8,7 @@ <% if @user.has_permission?(Permission::MANAGE_USERS, @space) || @user.has_permission?(Permission::SUPER_USER, @space) %> <tr> <td><strong>Users</strong></td> - <td><%= user_count %> users</td> + <td></td> <td><a class="wdn-button wdn-button-brand" href="/admin/users/">Manage</a></td> </tr> <% end %> diff --git a/views/admin/hours.erb b/views/admin/hours.erb new file mode 100644 index 0000000000000000000000000000000000000000..49409306178320e334ee71a39fff57269555acfe --- /dev/null +++ b/views/admin/hours.erb @@ -0,0 +1,99 @@ +<div id="pagetitle"> + <h3> + Your Hours For The Week + <span class="wdn-subhead"><%= "#{sunday.strftime("%m/%d")} - #{(sunday+6.days).strftime("%m/%d")}" %></span> + </h3> +</div> + +<div style="margin-bottom: 16px;"> +<a href="<%= @space.admin_hours_href %>?date=<%= (date-7.days).strftime('%Y-%m-%d') %>" class="wdn-button wdn-button-triad" id="prev-week">< PREV</a> +<a href="<%= @space.admin_hours_href %>?date=<%= (date+7.days).strftime('%Y-%m-%d') %>" class="wdn-button wdn-button-triad" style="float: right;" id="next-week">NEXT ></a> +</div> + +<table> + <thead> + <tr> + <th>Day</th> + <th>Hours</th> + </tr> + </thead> + <tbody> + <% (0..6).each do |i| %> + <% day = (sunday + i.days + 1.hour).midnight %> + <tr> + <td> + <%= day.strftime('%a %m/%d') %> + </td> + <td> + <% if weeks_hours.has_key?(i) %> + <%= weeks_hours[i].hours.map do |record| + start_time = day + record[:start].minutes + end_time = day + record[:end].minutes + "#{record[:status].capitalize_all}: #{start_time.strftime('%l:%M %P')} - #{end_time.strftime('%l:%M %P')}" + end.join(', ') %> + <% else %> + Open All Day + <% end %> + </td> + </tr> + <% end %> + </tbody> +</table> + +<h3> +Upcoming Changes +</h3> +<a class="wdn-button wdn-button-brand" href="<%= @space.admin_hours_href %>create/">Add Hours Change</a><br><br> + +<table> + <thead> + <tr> + <th>Day</th> + <th>Hours</th> + <th>Actions</th> + </tr> + </thead> + <tbody> + <% upcoming_hours.each do |space_hour| %> + <tr> + <td> + <%= space_hour.effective_date.strftime('%a %m/%d') %> + </td> + <td> + <% if space_hour.one_off %> + <%= space_hour.hours.map do |record| + start_time = space_hour.effective_date.in_time_zone + record[:start].minutes + end_time = space_hour.effective_date.in_time_zone + record[:end].minutes + "#{record[:status].capitalize_all}: #{start_time.strftime('%l:%M %P')} - #{end_time.strftime('%l:%M %P')}" + end.join(', ') %> + <% else %> + <strong><%= %w(Sundays Mondays Tuesdays Wednesdays Thursdays Fridays Saturdays)[space_hour.day_of_week] %></strong> change to: + <%= space_hour.hours.map do |record| + start_time = space_hour.effective_date.in_time_zone + record[:start].minutes + end_time = space_hour.effective_date.in_time_zone + record[:end].minutes + "#{record[:status].capitalize_all}: #{start_time.strftime('%l:%M %P')} - #{end_time.strftime('%l:%M %P')}" + end.join(', ') %> + <% end %> + </td> + <td class="table-actions"> + <a class="wdn-button wdn-button-brand" href="<%= @space.admin_hours_href %><%= space_hour.id %>/edit/">Edit</a> + <form class="delete-space-hour delete-form" action="<%= @space.admin_hours_href %><%= space_hour.id %>/delete/" method="POST"> + <button type="submit" class="wdn-button">Remove</button> + </form> + </td> + </tr> + <% end %> + </tbody> +</table> + +<script type="text/javascript"> +require(['jquery'], function($) { + $(document).ready(function() { + $('.delete-space-hour').submit(function (submit) { + if (!window.confirm('Are you sure you want to remove this hours change?')) { + submit.preventDefault(); + } + }); + }); +}); +</script> \ No newline at end of file diff --git a/views/admin/manage_authorizations.erb b/views/admin/manage_authorizations.erb new file mode 100644 index 0000000000000000000000000000000000000000..99c81cdbf7e1be4b6bf21e981657ee3777cf1ccf --- /dev/null +++ b/views/admin/manage_authorizations.erb @@ -0,0 +1,33 @@ +<div id="pagetitle"> + <h3>Manage Resource Authorizations for <%= user.full_name %></h3> +</div> + +<form id="signup" action="" method="POST"> +<table> + <thead> + <th> + Resource + </th> + <th> + Authorized On + </th> + </thead> + <tbody> + <% resources.each do |resource| %> + <tr> + <td> + <input <%= 'checked="checked"' if user.authorized_resource_ids.include?(resource.id) %> type="checkbox" name="permission_<%= resource.id %>" id="permission-<%= resource.id %>"> + <label for="permission-<%= resource.id %>"><%= resource.name %></label> + </td> + <td> + <% unless (auth = user.get_authorization(resource.id)).nil? || auth.authorized_date.nil? %> + <%= auth.authorized_date.in_time_zone.strftime('%m/%d/%Y @ %l:%M %P') %> + <% end %> + </td> + </tr> + <% end %> + </tbody> +</table> +<br> +<button class="wdn-button wdn-button-brand" type="submit">Save User</button> +</form> diff --git a/views/admin/new_hours.erb b/views/admin/new_hours.erb new file mode 100644 index 0000000000000000000000000000000000000000..266f8509fd83ee94e38c89fd8be04e00f40ab835 --- /dev/null +++ b/views/admin/new_hours.erb @@ -0,0 +1,130 @@ +<div id="pagetitle"> + <h3>Set New Hours</h3> +</div> + +<form id="create-hours" action="" method="POST"> + <div class="wdn-grid-set"> + <div class="bp1-wdn-col-one-half"> + <label for="day-of-week">Day Of Week</label> + <select id="day-of-week" name="day_of_week"> + <% (weekdays = %w(Sunday Monday Tuesday Wednesday Thursday Friday Saturday)).each_index do |i| %> + <option <%= 'selected="selected"' if space_hour.day_of_week == i && !space_hour.one_off %> value="<%= i %>"><%= weekdays[i] %></option> + <% end %> + <option <%= 'selected="selected"' if space_hour.one_off %> value="one_off">Set hours for a single day</option> + </select> + + <label for="effective-date">Effective Date</label> + <div class="date-time-select"> + <span class="wdn-icon-calendar"></span> + <input style="width: 90%;" id="effective-date" name="effective_date" title="Effective Date" type="text" class="datepicker" value="<%= (space_hour.effective_date || Time.now).strftime('%m/%d/%Y') %>" /> + </div> + </div> + </div> + + <fieldset> + <legend>Hours</legend> + <label>Studio will be closed for all hours you do not indicate here.</label> + <input type="text" class="hidden" name="hours" id="hours" /> + <div id="hours-container"> + <% hours = [{:status => 'open', :start => 540, :end => 1020}] if hours.nil? %> + <% hours.each_index do |x| %> + <% record = hours[x] %> + <div id="base-hours-<%=x%>" class="date-time-select hours-record"> + <select class="hours-type"> + <option <%= 'selected="selected"' if record[:status] == 'open' %> value="open">Open</option> + <option <%= 'selected="selected"' if record[:status] == 'open_without_reservations' %> value="open_without_reservations">Open but Machine Reservations are Not Allowed</option> + <option <%= 'selected="selected"' if record[:status] == 'closed' %> value="closed">Closed</option> + </select> + <label>from</label> + <select class="start-time-hour" title="Start Time Hour"> + <option value=""></option> + <% (1..12).each do |i| %> + <option <%= 'selected="selected"' if [y = record[:start] / 60, y+12, y-12].include?(i) %> value="<%= i %>"><%= i %></option> + <% end %> + </select> : + + <select class="start-time-minute"title="Start Time Minute"> + <option value=""></option> + <% (0..11).each do |i| %> + <option <%= 'selected="selected"' if record[:start] % 60 == i*5 %> value="<%= i * 5 %>"><%= (i*5).to_s.rjust(2, '0') %></option> + <% end %> + </select> + + <div class="am_pm"> + <input <%= 'checked="checked"' if record[:start] < 720 %> class="start-time-am-pm" title="AM" type="radio" value="am" name="<%= z = String.token %>">AM<br> + <input <%= 'checked="checked"' if record[:start] >= 720 %> class="start-time-am-pm" title="PM" type="radio" value="pm" name="<%= z %>">PM + </div> + <label>until</label> + + <select class="end-time-hour" title="End Time Hour"> + <option value=""></option> + <% (1..12).each do |i| %> + <option <%= 'selected="selected"' if [y = record[:end] / 60, y+12, y-12].include?(i) %> value="<%= i %>"><%= i %></option> + <% end %> + </select> : + + <select class="end-time-minute"title="End Time Minute"> + <option value=""></option> + <% (0..11).each do |i| %> + <option <%= 'selected="selected"' if record[:end] % 60 == i*5 %> value="<%= i * 5 %>"><%= (i*5).to_s.rjust(2, '0') %></option> + <% end %> + </select> + + <div class="am_pm"> + <input <%= 'checked="checked"' if record[:end] < 720 %> class="end-time-am-pm" title="AM" type="radio" value="am" name="<%= z = String.token %>">AM<br> + <input <%= 'checked="checked"' if record[:end] >= 720 %> class="end-time-am-pm" title="PM" type="radio" value="pm" name="<%= z %>">PM + </div> + + <button title="Remove" type="button" class="<%= 'hidden' if x == 0 %> remove-hours wdn-button">×</button> + </div> + <% end %> + </div> + <button id="add-hours" type="button" class="wdn-button wdn-button-complement">Add Hours</button> + </fieldset> + + <button type="submit" class="wdn-button wdn-button-brand">Submit</button> +</form> + +<script type="text/javascript"> +WDN.initializePlugin('jqueryui', [function() { + $ = require('jquery'); + $('.datepicker').datepicker(); + $("LINK[href^='//unlcms.unl.edu/wdn/templates_4.0/scripts/plugins/ui/css/jquery-ui.min.css']").remove(); + + $('#hours-container').on('click', '.remove-hours', function(click) { + click.preventDefault(); + $(this).closest('.hours-record').remove(); + }); + + $('#add-hours').click(function (click) { + click.preventDefault(); + var random1 = Math.random().toString(36).substring(7); + var random2 = Math.random().toString(36).substring(7); + var element = $('#base-hours-0').clone(); + element.find('.remove-hours').removeClass('hidden'); + element.find('.start-time-am-pm').attr('name', random1); + element.find('.end-time-am-pm').attr('name', random2); + $('#hours-container').append(element); + }); + + $('#create-hours').submit(function (submit) { + var hours = [] + + $.each($('.hours-record'), function (index, element) { + element = $(element); + hours.push({ + status: element.find('.hours-type').val(), + start_hour: element.find('.start-time-hour').val(), + start_minute: element.find('.start-time-minute').val(), + start_am_pm: element.find('.start-time-am-pm:checked').val(), + end_hour: element.find('.end-time-hour').val(), + end_minute: element.find('.end-time-minute').val(), + end_am_pm: element.find('.end-time-am-pm:checked').val(), + }); + }); + + $('#hours').val(JSON.stringify(hours)); + }); + +}]); +</script> \ No newline at end of file diff --git a/views/admin/users.erb b/views/admin/users.erb new file mode 100644 index 0000000000000000000000000000000000000000..220a835da2f5e91dc711f3da68bbfa6bb350f78c --- /dev/null +++ b/views/admin/users.erb @@ -0,0 +1,113 @@ +<div id="pagetitle"> + <h3>Manage Users<span class="wdn-subhead"><a id="show-toolbox" href="#">Show Toolbox</a></span></h3> +</div> + +<div id="toolbox" class="toolbox" style="display: none;"> + <h3>Toolbox <span style="float: right;"><a style="color: white;" href="#" id="hide-toolbox">–</a></span></h3> + <div class="tools"> + <a class="wdn-button wdn-button-brand" href="<%= @space.admin_users_href %>add/">Add User</a> + <a class="wdn-button wdn-button-brand" href="<%= @space.admin_users_href %><%= @user.id %>/edit/">Edit My User</a> + <a class="wdn-button wdn-button-triad" href="<%= @space.admin_users_href %><%= @user.id %>/manage/">My Resources</a> + </div> +</div> + +<form id="find-controls"> + <div class="wdn-grid-set"> + <div class="wdn-col-one-fifth"> + <label style="font-size: 120%; margin-right: 20px;">Find users by:</label> + <br> + <a href="<%= @space.admin_users_href %>" class="wdn-button" style="font-size: 60%">Clear</a> + </div> + <div class="wdn-col-two-fifths"> + <label>Resource Authorization:</label> + <select id="resource-authorization" name="resource_authorization"> + <option value=""></option> + <% resources.each do |resource| %> + <option <%= 'selected="selected"' if selected_resource.to_i == resource.id %> value="<%= resource.id %>"><%= resource.name %></option> + <% end %> + </select> + </div> + </div> +</form> + +<% if users.count > 0 %> +<div> + <table class="event-list"> + <thead class="small-hidden"> + <tr> + <th>Name</th> + <th>Email</th> + <th>Resource Authorizations</th> + <th>Actions</th> + </tr> + </thead> + <tbody> + <% users.each do |user| %> + <tr> + <td> + <%= user.full_name %><br> + <small><%= user.university_status %></small> + </td> + <td> + <%= user.email %> + </td> + <td> + <% if user.authorized_resource_ids.count == 0 %> + None + <% else %> + <%= user.resource_authorizations.map(&:resource).map(&:name).first(5).join('<br>') %> + <% if user.authorized_resource_ids.count > 5 %> + <br><a href="<%= @space.admin_users_href %><%= user.id %>/manage/">... and <%= user.authorized_resource_ids.count - 5 %> more</a> + <% end %> + <% end %> + </td> + <td class="table-actions"> + <a href="<%= @space.admin_users_href %><%= user.id %>/edit/" class="wdn-button wdn-button-brand">Edit</a> + <a href="<%= @space.admin_users_href %><%= user.id %>/manage/" class="wdn-button wdn-button-triad">Resources</a> + <form class="delete-form delete-user" action="<%= @space.admin_users_href %><%= user.id %>/delete/" method="POST"> + <button type="submit" class="wdn-button">Delete</button> + </form> + </td> + </tr> + <% end %> + </tbody> + </table> +</div> +<% else %> +<br> +<label>No users meet this criteria, or you have not added any. Open the toolbox to get started.</label> +<% end %> + +<script type="text/javascript"> +require(['jquery'], function($) { + $(document).ready(function() { + $('.delete-user').submit(function (submit) { + if (!window.confirm('Are you sure you want to delete this user?')) { + submit.preventDefault(); + } + }); + + $('#show-toolbox').click(function (click) { + click.preventDefault(); + $('#show-toolbox').hide(); + $('#toolbox').slideDown(); + }); + $('#hide-toolbox').click(function (click) { + click.preventDefault(); + $('#toolbox').slideUp(400, function () { + $('#show-toolbox').show(); + }); + }); + + $('#resource-authorization').change(function (change) { + // construct new get URL from what we have + var conditions = []; + if ($('#resource-authorization').val() != '') { + conditions.push('selected_resource=' + $('#resource-authorization').val()); + } + + window.location = '?' + conditions.join('&'); + }); + }); +}); +</script> \ No newline at end of file