Skip to content

Commit

Permalink
adds the start of a staffplan, componentized a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
fermion committed Nov 29, 2023
1 parent 0c8ff89 commit 29b0aee
Show file tree
Hide file tree
Showing 16 changed files with 114 additions and 6 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ gem "jbuilder"
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: %i[ windows jruby ]

gem "view_component"

# Reduces boot times through caching; required in config/boot.rb
gem "bootsnap", require: false

Expand Down
6 changes: 6 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ GEM
net-smtp
marcel (1.0.2)
matrix (0.4.2)
method_source (1.0.0)
mini_mime (1.1.5)
minitest (5.20.0)
msgpack (1.7.2)
Expand Down Expand Up @@ -271,6 +272,10 @@ GEM
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
uniform_notifier (1.16.0)
view_component (3.8.0)
activesupport (>= 5.2.0, < 8.0)
concurrent-ruby (~> 1.0)
method_source (~> 1.0)
web-console (4.2.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
Expand Down Expand Up @@ -314,6 +319,7 @@ DEPENDENCIES
tailwindcss-rails
turbo-rails
tzinfo-data
view_component
web-console

RUBY VERSION
Expand Down
6 changes: 6 additions & 0 deletions app/components/assignment_row_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<tr>
<td class="whitespace-nowrap py-2 pl-4 pr-3 text-sm text-gray-500 sm:pl-0 truncate" style="width: 200px;">
<%= @project.name %>
</td>
<%= render(AssignmentWorkWeeksComponent.new(assignment: @assignment, work_weeks: [])) %>
</tr>
10 changes: 10 additions & 0 deletions app/components/assignment_row_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

class AssignmentRowComponent < ViewComponent::Base
def initialize(assignment:, work_weeks:)
@assignment = assignment
@project = @assignment.project
@work_weeks = work_weeks
end

end
3 changes: 3 additions & 0 deletions app/components/assignment_work_weeks_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<% 12.times do |count| %>
<%= render(WorkWeekComponent.new(work_week: nil)) %>
<% end %>
9 changes: 9 additions & 0 deletions app/components/assignment_work_weeks_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

class AssignmentWorkWeeksComponent < ViewComponent::Base
def initialize(assignment:, work_weeks:)
@assignment = assignment
@work_weeks = work_weeks
end

end
5 changes: 5 additions & 0 deletions app/components/client_row_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<tr class="border-t border-gray-200">
<th colspan="8" scope="colgroup" class="bg-gray-50 py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-3">
<%= @client.name %>
</th>
</tr>
7 changes: 7 additions & 0 deletions app/components/client_row_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class ClientRowComponent < ViewComponent::Base
def initialize(client:)
@client = client
end
end
10 changes: 10 additions & 0 deletions app/components/staff_plan_column_header_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<thead>
<tr>
<th>&nbsp;</th>
<% 12.times do |count| %>
<th scope="col" class="whitespace-nowrap px-2 py-3.5 text-left text-sm font-semibold text-gray-900">
<%= Time.at(date_plus_count(count)).to_date.strftime("%m/%d") %>
</th>
<% end %>
</tr>
</thead>
11 changes: 11 additions & 0 deletions app/components/staff_plan_column_header_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

class StaffPlanColumnHeaderComponent < ViewComponent::Base
def initialize(beginning_of_week:)
@beginning_of_week = beginning_of_week
end

def date_plus_count(count)
(@beginning_of_week + count.weeks).to_i
end
end
1 change: 1 addition & 0 deletions app/components/work_week_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<td class="whitespace-nowrap px-2 py-2 text-sm text-gray-500">work week</td>
8 changes: 8 additions & 0 deletions app/components/work_week_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

class WorkWeekComponent < ViewComponent::Base
def initialize(work_week:)
@work_week = work_week
end

end
5 changes: 4 additions & 1 deletion app/controllers/staff_plan/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ class StaffPlan::UsersController < ApplicationController

def show
@viewing_user = params[:id].blank? ? current_user : current_company.users.find(params[:id])
@query = Queries::UserStaffPlan.new(user: @viewing_user, company: current_company)
@query = Queries::UserStaffPlan.new(
user: @viewing_user,
company: current_company
)
end
end
13 changes: 11 additions & 2 deletions app/lib/queries/user_staff_plan.rb
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
module Queries
class UserStaffPlan
attr_reader :user, :company
attr_reader :user, :company, :beginning_of_week

def initialize(user:, company:)
def initialize(user:, company:, beginning_of_week: Date.today.beginning_of_week)
raise ArgumentError, "user must be a User" unless user.is_a?(User)
raise ArgumentError, "company must be a Company" unless company.is_a?(Company)

@user = user
@company = company
@beginning_of_week = beginning_of_week.to_datetime.to_i
@assignments = user.
assignments.
where(project: company.projects.active).
includes(:work_weeks, project: :client).
order('clients.name')
end

def assignment_for(project:)
@assignments.find { |assignment| assignment.project == project }
end

def work_weeks
@work_weeks ||= @assignments.flat_map(&:work_weeks)
end

def work_weeks_for(project:)
work_weeks.select { |work_week| work_week.project == project }
end

def clients
@clients ||= @assignments.flat_map(&:project).map(&:client).uniq
end
Expand Down
2 changes: 0 additions & 2 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white rounded-md px-3 py-2 text-sm font-medium">Projects</a>
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white rounded-md px-3 py-2 text-sm font-medium">People</a>
<% if current_user.owner? %>
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white rounded-md px-3 py-2 text-sm font-medium">Employee Management</a>
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white rounded-md px-3 py-2 text-sm font-medium">Settings</a>
<% end %>
</div>
Expand Down Expand Up @@ -105,7 +104,6 @@
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white block rounded-md px-3 py-2 text-base font-medium">Projects</a>
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white block rounded-md px-3 py-2 text-base font-medium">People</a>
<% if current_user.owner? %>
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white block rounded-md px-3 py-2 text-base font-medium">Employee Management</a>
<a href="#" class="text-gray-300 hover:bg-gray-700 hover:text-white block rounded-md px-3 py-2 text-base font-medium">Settings</a>
<% end %>
</div>
Expand Down
22 changes: 21 additions & 1 deletion app/views/staff_plan/users/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
<% content_for(:header) do %>
<%= current_user == @viewing_user ? "My StaffPlan" : "#{@viewing_user.name}'s StaffPlan" %>
<% end %>
<% end %>

<div class="px-4 sm:px-6 lg:px-8">
<div class="mt-8 flow-root">
<div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
<table class="min-w-full divide-y divide-gray-300">
<%= render(StaffPlanColumnHeaderComponent.new(beginning_of_week: @query.beginning_of_week)) %>
<tbody class="divide-y divide-gray-200 bg-white">
<% @query.clients.each do |client| %>
<%= render(ClientRowComponent.new(client:)) %>
<% @query.projects_for(client: client).each do |project| %>
<%= render(AssignmentRowComponent.new(assignment: @query.assignment_for(project:), work_weeks: @query.work_weeks_for(project:))) %>
<% end %>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
</div>

0 comments on commit 29b0aee

Please sign in to comment.