luck_remover 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0345edd017f11b270d9f18808531d96cc86e0fead799a40b8d5e67cbb9903779
4
- data.tar.gz: b8e18a33f15e910d852069ebb2c2110a7eaf2b5c3ad7e786fad7cf0235834e95
3
+ metadata.gz: 9e73001c8648d7782184b015b863e8bfd8ae79dd1aac51a515b1602d42c9ba4d
4
+ data.tar.gz: 4f6353e7a93b1fca872521ce1722fe1bf2b12de3fb866f07897a483bef4865bd
5
5
  SHA512:
6
- metadata.gz: c92fa7e46a58569543c9cf2c4b9de1ec15c8579a1c5adb3f44b08f425fc5274f21f23ab94a85ec59073266dfdccbb4bd9550551ca0de3c6be1bcfe77db6e446c
7
- data.tar.gz: c17e61593422a82880e069c59b7d83c546e3b153da40710e9e45f64d74fcc17a200e78022dbb6266dbb1c1e630d9e2d166f7280a4d097772b896c369e0fa4981
6
+ metadata.gz: 01a1c6517768b4c6d690d16b46a6d240130e58333463d9d08379f8113b5d86ebdfc68ae543396b2686a49ba4fc4eb787f8f46f95aece39f2706b0f0a7ba14bdf
7
+ data.tar.gz: 053c049721cbbd0a957040c5ffe97f8b3752da0bfdc6e208331c2f1ad4e98ca90c9d3cfa0ae9657bdaf5d559e1d0940943abf515ea21d738a99373ad4ade52d5
@@ -2,31 +2,32 @@ module LuckRemover
2
2
  class GoalsController < LuckRemover.parent_controller.constantize
3
3
  def index
4
4
  @goals = goal_scope.order(:name)
5
+ @person_names = LuckRemover.people(current_goal_owner).to_h { |label, id| [ id, label ] }
5
6
  end
6
7
 
7
8
  def new
8
9
  @goal = goal_scope.new
9
- @metrics = LuckRemover.metrics.all
10
+ load_choices
10
11
  end
11
12
 
12
13
  def create
13
14
  @goal = goal_scope.new(goal_params)
14
15
  return redirect_to goals_path if @goal.save
15
16
 
16
- @metrics = LuckRemover.metrics.all
17
+ load_choices
17
18
  render :new, status: :unprocessable_content
18
19
  end
19
20
 
20
21
  def edit
21
22
  @goal = goal_scope.find(params[:id])
22
- @metrics = LuckRemover.metrics.all
23
+ load_choices
23
24
  end
24
25
 
25
26
  def update
26
27
  @goal = goal_scope.find(params[:id])
27
28
  return redirect_to goals_path if @goal.update(goal_params)
28
29
 
29
- @metrics = LuckRemover.metrics.all
30
+ load_choices
30
31
  render :edit, status: :unprocessable_content
31
32
  end
32
33
 
@@ -37,12 +38,21 @@ module LuckRemover
37
38
 
38
39
  private
39
40
 
41
+ def load_choices
42
+ @metrics = LuckRemover.metrics.all
43
+ @people = LuckRemover.people(current_goal_owner)
44
+ end
45
+
46
+ def current_goal_owner
47
+ send(LuckRemover.current_owner_method)
48
+ end
49
+
40
50
  def goal_params
41
- params.expect(goal: [ :name, :metric_key, :target, :direction, :period ])
51
+ params.expect(goal: [ :name, :metric_key, :person_id, :target, :direction, :period ])
42
52
  end
43
53
 
44
54
  def goal_scope
45
- Goal.for_owner(send(LuckRemover.current_owner_method))
55
+ Goal.for_owner(current_goal_owner)
46
56
  end
47
57
  end
48
58
  end
@@ -11,19 +11,37 @@ module LuckRemover
11
11
 
12
12
  validates :name, :target, presence: true
13
13
  validate :metric_is_registered
14
+ validate :person_is_one_the_host_gives, if: :person_id
15
+ validate :metric_is_readable_for_one_person, if: :person_id
14
16
 
15
17
  def standing(now: Time.current)
16
- value = LuckRemover.metric(metric_key).read(range: current_period(now)).value
18
+ value = LuckRemover.metric(metric_key).read(range: current_period(now), **for_person).value
17
19
  Standing.new(value: value, target: target, direction: direction)
18
20
  end
19
21
 
20
22
  private
21
23
 
24
+ def for_person
25
+ person_id ? { person_id: person_id } : {}
26
+ end
27
+
22
28
  def current_period(now)
23
29
  range = month? ? Cs133::Range.this_month(zone: Time.zone, now: now) : Cs133::Range.last_weeks(1, zone: Time.zone, now: now).first
24
30
  range.to_range
25
31
  end
26
32
 
33
+ def person_is_one_the_host_gives
34
+ return if LuckRemover.people(owner).any? { |_label, id| id == person_id }
35
+
36
+ errors.add(:person_id, "is not one of the people this goal can be for")
37
+ end
38
+
39
+ def metric_is_readable_for_one_person
40
+ return if LuckRemover.metrics.per_person?(metric_key.to_s)
41
+
42
+ errors.add(:metric_key, "#{metric_key} cannot be read for one person")
43
+ end
44
+
27
45
  def metric_is_registered
28
46
  return if LuckRemover.metrics.registered?(metric_key.to_s)
29
47
 
@@ -7,6 +7,7 @@
7
7
  <%= ui_radio_card(name: "goal[metric_key]", value: metric.key, label: metric.title, hint: metric.definition, checked: goal.metric_key.to_s == metric.key.to_s) %>
8
8
  <% end %>
9
9
 
10
+ <%= ui_form_field(attribute: "goal[person_id]", label: "Person", type: :select, options: [["Whole business", ""]] + people, value: goal.person_id, errors: goal.errors[:person_id]) %>
10
11
  <%= ui_form_field(attribute: "goal[target]", label: "Target", type: :number, step: "any", required: true, value: goal.target, errors: goal.errors[:target]) %>
11
12
  <%= ui_form_field(attribute: "goal[direction]", label: "Direction", type: :select, required: true, options: [["At least", "at_least"], ["At most", "at_most"]], value: goal.direction, errors: goal.errors[:direction]) %>
12
13
  <%= ui_form_field(attribute: "goal[period]", label: "Period", type: :select, required: true, options: [["Week", "week"], ["Month", "month"]], value: goal.period, errors: goal.errors[:period]) %>
@@ -1,7 +1,7 @@
1
1
  <%= ui_form_page(title: "Edit", subtitle: @goal.name) %>
2
2
  <%= ui_page(max_width: :md) do %>
3
3
  <%= ui_form(action: luck_remover.goal_path(@goal), method: :patch) do %>
4
- <%= render "luck_remover/goals/form", goal: @goal, metrics: @metrics %>
4
+ <%= render "luck_remover/goals/form", goal: @goal, metrics: @metrics, people: @people %>
5
5
  <%= ui_button(label: "Save") %>
6
6
  <% end %>
7
7
  <%= ui_action_menu do %>
@@ -1,3 +1,4 @@
1
+ <%= ui_show_page(title: "Goals") %>
1
2
  <%= ui_page(max_width: :xl) do %>
2
3
  <%= ui_page_header(title: "Goals", action_url: luck_remover.new_goal_path, action_label: "Add") do |header| %>
3
4
  <% header.action do %>
@@ -7,6 +8,7 @@
7
8
  <% rows = @goals.map do |goal|
8
9
  { name: goal.name,
9
10
  edit_url: luck_remover.edit_goal_path(goal),
11
+ person: goal.person_id ? @person_names[goal.person_id] : "Whole business",
10
12
  metric: LuckRemover.metric(goal.metric_key).title,
11
13
  target: number_with_precision(goal.target, precision: 2, strip_insignificant_zeros: true),
12
14
  direction: goal.direction.humanize,
@@ -14,7 +16,7 @@
14
16
  end %>
15
17
  <%= ui_data_table(
16
18
  items: rows,
17
- columns: [{ name: "Name" }, { metric: "Metric" }, { target: "Target" }, { direction: "Direction" }, { period: "Period" }],
19
+ columns: [{ name: "Name" }, { person: "Person" }, { metric: "Metric" }, { target: "Target" }, { direction: "Direction" }, { period: "Period" }],
18
20
  empty_message: "No goals yet."
19
21
  ) { |table| table.link(:name) { |row| row[:edit_url] } } %>
20
22
  <% end %>
@@ -1,7 +1,7 @@
1
1
  <%= ui_form_page(title: "Add goal") %>
2
2
  <%= ui_page(max_width: :md) do %>
3
3
  <%= ui_form(action: luck_remover.goals_path) do %>
4
- <%= render "luck_remover/goals/form", goal: @goal, metrics: @metrics %>
4
+ <%= render "luck_remover/goals/form", goal: @goal, metrics: @metrics, people: @people %>
5
5
  <%= ui_button(label: "Create") %>
6
6
  <% end %>
7
7
  <% end %>
@@ -0,0 +1,5 @@
1
+ class AddPersonIdToLuckRemoverGoals < ActiveRecord::Migration[8.1]
2
+ def change
3
+ add_column :luck_remover_goals, :person_id, :integer, limit: 8
4
+ end
5
+ end
@@ -6,15 +6,21 @@ module LuckRemover
6
6
  class MetricRegistry
7
7
  def initialize
8
8
  @stats = {}
9
+ @per_person = Set.new
9
10
  end
10
11
 
11
- def register(stat)
12
+ def register(stat, per_person: false)
12
13
  key = stat.key.to_sym
13
14
  raise DuplicateMetricError, "A goal metric is already registered under #{key}" if registered?(key)
14
15
 
16
+ @per_person << key if per_person
15
17
  @stats[key] = stat
16
18
  end
17
19
 
20
+ def per_person?(key)
21
+ @per_person.include?(key.to_sym)
22
+ end
23
+
18
24
  def registered?(key)
19
25
  @stats.key?(key.to_sym)
20
26
  end
@@ -1,3 +1,3 @@
1
1
  module LuckRemover
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/luck_remover.rb CHANGED
@@ -8,12 +8,20 @@ module LuckRemover
8
8
  mattr_accessor :parent_controller, default: "LuckRemover::ApplicationController"
9
9
  mattr_accessor :current_owner_method, default: nil
10
10
 
11
+ NO_PEOPLE = ->(_owner) { [] }
12
+
13
+ mattr_accessor :people_for, default: NO_PEOPLE
14
+
15
+ def self.people(owner)
16
+ people_for.call(owner)
17
+ end
18
+
11
19
  def self.metrics
12
20
  @metrics ||= MetricRegistry.new
13
21
  end
14
22
 
15
- def self.register_metric(stat)
16
- metrics.register(stat)
23
+ def self.register_metric(stat, per_person: false)
24
+ metrics.register(stat, per_person: per_person)
17
25
  end
18
26
 
19
27
  def self.metric(key)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: luck_remover
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Schneider
@@ -92,6 +92,7 @@ files:
92
92
  - app/views/luck_remover/goals/new.html.erb
93
93
  - config/routes.rb
94
94
  - db/migrate/20261022212722_create_luck_remover_goals.rb
95
+ - db/migrate/20261023134729_add_person_id_to_luck_remover_goals.rb
95
96
  - lib/luck_remover.rb
96
97
  - lib/luck_remover/engine.rb
97
98
  - lib/luck_remover/metric_registry.rb