Files
growstuff/app/controllers/jobs_controller.rb
T

132 lines
3.7 KiB
Ruby

# frozen_string_literal: true
class JobsController < DataController
def index
@show_all = params[:all] == '1'
@owner = Member.find_by!(slug: params[:member_slug]) if params[:member_slug].present?
if notepad?
load_notepad
return render_groups(:ok) if request.xhr?
else
@jobs = listed_jobs.paginate(page: params[:page], per_page: 30)
end
@filename = "Growstuff-#{specifics}Jobs-#{Time.zone.now.to_fs(:number)}.csv"
respond_with(@jobs)
end
def new
@job = Job.new(new_job_params.to_h.reverse_merge(due_date: Time.zone.today))
@job.owner = current_member
@job.garden = nil unless @job.garden&.owner == current_member
@job.planting = nil unless @job.planting&.owner == current_member
respond_with @job
end
def create
@job = Job.new(job_params)
@job.owner = current_member
@job.due_date ||= Time.zone.today
saved = @job.save
return render_notepad(:created) if request.xhr? && saved
return head :unprocessable_entity if request.xhr?
repeat if saved
respond_with @job, location: after_save_path
end
def update
updated = @job.update(job_params)
return render_notepad(:ok) if request.xhr? && updated
return head :unprocessable_entity if request.xhr?
respond_with @job, location: after_save_path
end
def destroy
@job.destroy
respond_with @job, location: after_save_path
end
private
# There is no page for a single job: saving or deleting one goes back to the
# list it is on.
def after_save_path
member_jobs_path(@job.owner)
end
# The jobs in a list: open ones, newest first, unless finished ones are asked
# for, and one member's if the list is theirs.
def listed_jobs
jobs = Job.includes(:owner).order(created_at: :desc)
jobs = jobs.active unless @show_all
@owner ? jobs.where(owner: @owner) : jobs
end
# A member looking at their own jobs sees them as a notepad. The data formats,
# and anyone else's jobs, are lists.
def notepad?
@owner.present? && @owner == current_member && request.format.html?
end
# Adding or moving a job from the notepad sends back the notepad's groups, so
# the page can show the change without reloading.
def render_notepad(status)
@owner = current_member
load_notepad
render_groups(status)
end
def render_groups(status)
response.set_header('X-Jobs-Done-This-Week', @done_this_week.to_s)
render partial: 'jobs/notepad_groups', locals: { groups: @job_groups, in_garden: garden.present? }, status:
end
def load_notepad
notepad = JobsNotepad.new(@owner, garden:, pinned: pinned_ids)
@job_groups = notepad.groups
@done_this_week = notepad.done_this_week
end
# The garden a notepad on a garden's page is for, if it is.
def garden
Garden.find_by(id: params[:garden_id]) if params[:garden_id].present?
end
# The jobs the page has crossed off since it loaded, which stay where they are
# until it is loaded again.
def pinned_ids
Array(params[:keep]).map(&:to_i)
end
def job_params
params.require(:job).permit(:name, :description, :finished, :due_date,
:garden_id, :planting_id, :jobbable_type, :jobbable_id, :action)
end
# What a link to "new job" can fill in ahead of time, as Copy does.
def new_job_params
params.permit(:name, :description, :due_date, :garden_id, :planting_id)
end
# "Repeat how many times, every how many weeks" on the form: copies of the job
# on later days.
def repeat
weeks = params[:repeat_weeks].to_i.weeks
params[:repeat_times].to_i.times do |i|
@job.dup.tap { |copy| copy.due_date = @job.due_date + ((i + 1) * weeks) }.save
end
end
def specifics
return if @owner.blank?
"#{@owner.to_param}-"
end
end