Skip to content

Commit

Permalink
Merge branch 'staging' into feat/locker-management
Browse files Browse the repository at this point in the history
  • Loading branch information
PencilAmazing authored Jan 9, 2025
2 parents 6b2fa08 + 8c685e4 commit f167d14
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 28 deletions.
12 changes: 7 additions & 5 deletions app/controllers/admin/shifts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class Admin::ShiftsController < AdminAreaController
def index
@staff =
User
.staff
.where(id: StaffSpace.where(space_id: @space_id).pluck(:user_id))
.order("LOWER(name) ASC")
.pluck(:name, :id)
Expand All @@ -20,21 +21,21 @@ def index
StaffSpace
.joins(:user)
.where(space_id: @space_id)
.merge(
User.staff
) # NOTE why isn't this the default scope? Ask Alex *again* sometime later lol
.order("users.name")
.each do |staff|
if !staff.nil? && !staff.user.nil?
@colors << {
id: staff.user.id,
name: staff.user.name,
color: staff.color
}
@colors << { user: staff.user, color: staff.color }
end
end
end

def shifts
@staff =
User
.staff
.where(id: StaffSpace.where(space_id: @space_id).pluck(:user_id))
.order("LOWER(name) ASC")
.pluck(:name, :id)
Expand All @@ -44,6 +45,7 @@ def shifts
StaffSpace
.joins(:user)
.where(space_id: @space_id)
.merge(User.staff)
.order("users.name")
.each do |staff|
if !staff.nil? && !staff.user.nil? && !staff.user_id.nil?
Expand Down
33 changes: 19 additions & 14 deletions app/controllers/admin/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,35 +215,40 @@ def toggle_lock_user
# user_ids: [array of ids], role: role
# for space management:
# Takes a hash of { user_id: [space_id array]}

def set_role
# Update user roles
# All user ids sent in this query get set to the same role
# Keep staff spaces attached, even if demoted
params["user_ids"]&.each do |user_id|
user = User.find(user_id)
user.role = params[:role]
user.save
if params[:role].present? && params[:user_ids].is_a?(Array)
params[:user_ids].each do |user_id|
user = User.find(user_id)
user.role = params[:role]
user.save
end
end

# Update user staff spaces
params["spaces"]&.each do |user_id, spaces|
user = User.find(user_id)
if user.present? && user.staff?
space_list = spaces.present? ? spaces : []
if params[:spaces].present?
params["spaces"]&.each do |user_id, spaces|
user = User.find(user_id)
if user.present? && user.staff?
space_list = spaces.present? ? spaces : []

space_list.each do |space|
StaffSpace.find_or_create_by(space_id: space, user: user)
end
space_list.each do |space|
StaffSpace.find_or_create_by(space_id: space, user: user)
end

user.staff_spaces.where.not(space_id: space_list).destroy_all
user.staff_spaces.where.not(space_id: space_list).destroy_all

flash[:notice] = "Successfully changed spaces for the user."
flash[:notice] = "Successfully changed spaces for the user."
end
end
end

# response is js
respond_to do |format|
format.html { redirect_back(fallback_location: root_path) }
format.json { head :ok }
format.js { render layout: false }
format.all { redirect_back(fallback_location: root_path) }
end
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/entrypoints/admin_availability_calendar.js
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ saveButton.addEventListener("click", () => createCalendarEvent());
const openModal = (arg) => {
// Reset defaults
modalTitle.innerText = "New Unavailability";
recurringInput.checked = false;
recurringInput.checked = true;
wholeDayCheckbox.checked = false; // Reset checkbox state
unavailabilityId.value = "";
switchInputVisibility(recurringInput.checked);
Expand Down
24 changes: 24 additions & 0 deletions app/javascript/entrypoints/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,28 @@ document.addEventListener("turbo:load", function () {
},
});
});

document.querySelectorAll("input.set-user-space-button").forEach((i) => {
i.addEventListener("change", (event) => {
// Get total space list
let space_list = [
...i.parentElement.querySelectorAll("input.set-user-space-button"),
].reduce(function (result, element) {
if (element.checked) {
result.push(element.dataset.spaceId);
}
return result;
}, []);
let body = { user_ids: [i.dataset.userId], spaces: {} };
body["spaces"][i.dataset.userId] = space_list;
fetch("/admin/users/set_role/", {
method: "PATCH",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
});
});
});
2 changes: 1 addition & 1 deletion app/views/admin/shifts/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

<% @colors.each do |user| %>
<div class="pb-2">
<label><%= user[:name] %></label>
<label><%= link_to user[:user].name, user_path(user[:user].username), target: :_blank, rel: :noopener %></label>
<br>
<div class="d-flex">
<input type="color" name="color" onchange="updateColor(<%= user[:id] %>, this.value)" class="form-control form-control-color-shift" value="<%= user[:color] %>" title="Choose your color">
Expand Down
4 changes: 3 additions & 1 deletion app/views/admin/users/_user_table.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
<div class="row row-cols-lg-2 justify-content-center">
<% @space_list.each do |space| %>
<%# use check_box_tag, not check_box, to avoid sending a 'ghost value'. In this case we do want values to be left out%>
<%= check_box_tag "spaces[#{admin.id}][]", space.id, (user_spaces[admin.id].include? space.id), form: space_form_id, class: 'btn-check', id: "space-#{space.name.parameterize.underscore}-#{admin.id}" %>
<%= check_box_tag "spaces[#{admin.id}][]", space.id, (user_spaces[admin.id].include? space.id),
form: space_form_id, class: 'btn-check set-user-space-button', id: "space-#{space.name.parameterize.underscore}-#{admin.id}",
data: { user_id: admin.id, space_id: space.id } %>
<%= label_tag "space-#{space.name.parameterize.underscore}-#{admin.id}", space.name, class: "btn btn-outline-primary btn-outline-#{space.name}" %>
<% end %>
</div>
Expand Down
5 changes: 3 additions & 2 deletions app/views/users/tabs/_roles.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
<div class="container" style="max-width: 600px;"> <!-- Adjust max-width as needed -->
<div class="row">
<div class="col-md-12">
<%= form_tag set_role_admin_users_path(@user, user_ids: [@repo_user.id]), method: :patch do %>
<%= form_tag set_role_admin_users_path, method: :patch do %>
<%= hidden_field_tag :'user_ids[]', @repo_user.id %>
<div class="mb-3">
<label>Role</label><br>
<%= radio_button_tag :role, 'admin', @repo_user.admin?, class: 'form-check-input role-button', id: 'role_admin' %>
Expand All @@ -19,7 +20,7 @@
<% @space_list.each do |space| %>
<% color = space.assigned_color %>
<div class="space-bubble" style="margin-right: 10px; border-color: <%= rgba(color, 1) %>; background-color: <%= rgba(color, 0.3) %>;">
<%= check_box_tag 'space[]', space.id, @staff_spaces.include?(space.id), class: 'form-check-input', id: "space_#{space.id}" %>
<%= check_box_tag "spaces[#{@repo_user.id}][]", space.id, @staff_spaces.include?(space.id), class: 'form-check-input', id: "space_#{space.id}" %>
<%= label_tag "space_#{space.id}", space.name, class: 'form-check-label' %>
</div>
<% end %>
Expand Down
74 changes: 70 additions & 4 deletions spec/controllers/admin/users_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
require "rails_helper"

RSpec.describe Admin::UsersController, type: :controller do
before(:each) do
@admin = create(:user, :admin)
session[:user_id] = @admin.id
session[:expires_at] = Time.zone.now + 10_000
@space = create(:space)
end

describe "GET /index" do
context "logged in as regular user" do
it "should redirect to root" do
Expand All @@ -14,10 +21,6 @@

context "logged in as admin" do
before(:each) do
@admin = create(:user, :admin)
session[:user_id] = @admin.id
session[:expires_at] = Time.zone.now + 10_000
@space = create(:space)
PiReader.create(
pi_mac_address: "12:34:56:78:90",
pi_location: @space.name
Expand Down Expand Up @@ -95,4 +98,67 @@
# end
end
end

describe "PATCH /set_role" do
context "setting roles" do
it "should make one user into staff" do
@user = create(:user, :regular_user)
patch :set_role, params: { user_ids: [@user.id], role: "staff" }

@user.reload
# keep staff role
expect(@user.role).to eq "staff"
# no spaces
expect(@user.staff_spaces).not_to exist
end

it "should make multiple users into staff" do
@user_one = create :user, :regular_user
@user_two = create :user, :regular_user
patch :set_role,
params: {
user_ids: [@user_one.id, @user_two.id],
role: "staff"
}

[@user_one, @user_two].each do |user|
user.reload
expect(user.role).to eq "staff"
expect(user.staff_spaces).not_to exist
end
end

it "should keep assigned spaces when demoted" do
user = create :user, :staff, :with_staff_spaces
assigned_spaces = user.staff_spaces
patch :set_role, params: { user_ids: [user.id], role: "regular_user" }
user.reload
expect(user.role).to eq "regular_user"
expect(user.staff_spaces).to eq assigned_spaces
end
end

context "assigning spaces to staff" do
it "should assign and remove a space to different users" do
@user_one = create :user, :with_staff_spaces, :staff
@user_two = create :user, :with_staff_spaces, :staff
prev_staff_spaces = @user_one.staff_spaces.pluck(:space_id)
additional_space = create(:space).id
patch :set_role,
params: {
spaces: {
@user_two.id => [],
@user_one.id => prev_staff_spaces << additional_space
}
},
as: :json # to keep the empty array
[@user_one, @user_two].each do |user|
user.reload
expect(user.role).to eq "staff"
end
expect(@user_one.staff_spaces.pluck :space_id).to eq(prev_staff_spaces)
expect(@user_two.staff_spaces.pluck :space_id).to eq []
end
end
end
end
9 changes: 9 additions & 0 deletions spec/factories/users.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@
student_id { Faker::Number.number(digits: 9) }
end

trait :with_staff_spaces do
# https://thoughtbot.github.io/factory_bot/cookbook/has_many-associations.html
# Make two spaces
#create_list(:staff_spaces, 2, user: instance)
after(:create) do |user|
2.times { StaffSpace.new(user:, space: create(:space)).save! }
end
end

factory :user_with_announcements do
transient { announcements_count { 5 } }
after(:create) do |user, evaluator|
Expand Down

0 comments on commit f167d14

Please sign in to comment.