diff --git a/HISTORY.md b/HISTORY.md index 995f4bd..bbc525a 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,6 +9,7 @@ Hopefully integrating all the little changes, bugfixes, and modifications that I * [New] The column's `icon` methods may now return an array of `[icon, alt]`, for supplying popup information on icons. * [New] You can add a "refresh" link to the top of the page using the `refresh_link` property inside `config`. * [New] Setting `hide_dimmed` on a column will automatically hide dimmed projects on page load +* [New] Set project counts using the `display_project_counts` property on columns. Can be set to `all`, `active`, or `marked`. # 0.4.0 // 2016-06-27 diff --git a/README.md b/README.md index 54c52a5..cee5acc 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,8 @@ end * **columns**: The number of sub-columns within this column. If `columns` is greater than 1, projects will be displayed side-by-side. By default, each column's width is 1. * **filter_button**: Whether or not to show a small button which, when clicked, will hide all "dimmed" projects. By default, set to false. * **hide_dimmed**: When set to true, dimmed projects will be automatically hidden on page load. By default, set to false. +* **display_project_counts**: Set this to `:all`, `:active`, or `:marked`. Will display the total number of projects in a column: the value you give it will determine if it counts all projects (`:all`), projects which are not dimmed (`:active`), or only marked projected (`:marked`). +* **project_limit**: If you're display project counts and you have more projects than this number, the project count will show up highlighted red. Useful if you're trying to keep down your total number of active projects! The following column properties take blocks of ruby code. You can alter these inside the column block in the following manner: diff --git a/lib/omniboard/column.rb b/lib/omniboard/column.rb index d3f77ec..d2eaa45 100644 --- a/lib/omniboard/column.rb +++ b/lib/omniboard/column.rb @@ -23,7 +23,9 @@ def to_s; @name; end block_property :sort_groups block_property :group_name - INHERITED_PROPERTIES = %i(sort mark_when dim_when icon group_by sort_groups group_name hide_dimmed) + INHERITED_PROPERTIES = %i(sort mark_when dim_when icon group_by sort_groups group_name hide_dimmed display_project_counts) + ALLOWED_PROJECT_COUNTS = %i(all active marked inherit) + ALLOWED_PROJECT_DISPLAYS = %i(full compact) # Order in the kanban board. Lower numbers are further left. Default 0 property :order @@ -32,10 +34,11 @@ def to_s; @name; end property :width # Display - compact or full? Full includes task info. - property :display + property :display, allowed_values: ALLOWED_PROJECT_DISPLAYS # Display a heading with the total number of projects in this column? - property :display_total_projects + # Allowed values: "all", "active", "marked", nil + property :display_project_counts, allowed_values: ALLOWED_PROJECT_COUNTS # Display total projects in red if this project limit is breached property :project_limit @@ -58,7 +61,7 @@ def initialize(name, &blck) self.width(1) self.columns(1) self.display(:full) - self.display_total_projects(false) + self.display_project_counts(nil) self.project_limit(nil) self.filter_button(false) @@ -213,6 +216,25 @@ def icon_for(project) end end + #--------------------------------------- + # Presentation methods + def count_div + total = case property(:display_project_counts) + when :all + self.projects.count + when :active + self.projects.select{ |p| !p.dimmed? }.count + when :marked + self.projects.select{ |p| p.marked? }.count + else + 0 + end + css_class = "column-total" + css_class << " limit-breached" if project_limit && project_limit < total + %|
#{total}
| + end + + #--------------------------------------- # Class-level methods @@ -245,6 +267,10 @@ def add(c) # If set, will provide a link in the heading allowing you to refresh the page property :refresh_link + # Fallback default for displaying project counts + # Allowed values: "all", "active", "marked", nil + property :display_project_counts, allowed_values: ALLOWED_PROJECT_COUNTS + # Global conditions, apply to all columns block_property :conditions @@ -309,6 +335,8 @@ def clear_config config @group_name = nil when :hide_dimmed @hide_dimmed = false + when :display_project_counts + @display_project_counts = nil else raise ArgumentError, "Do not know how to clear config: #{config}" end diff --git a/lib/omniboard/property.rb b/lib/omniboard/property.rb index ebde2de..07540c9 100644 --- a/lib/omniboard/property.rb +++ b/lib/omniboard/property.rb @@ -1,12 +1,29 @@ module Omniboard::Property module PropertyClassMethods - def property p + def property p, allowed_values: nil, munge: nil define_method(p) do |*args| ivar = "@#{p}" if args.empty? instance_variable_get(ivar) elsif args.size == 1 - instance_variable_set(ivar, args.first) + # Set values! + new_value = args.first + if allowed_values && !new_value.nil? && !allowed_values.include?(new_value) + raise(ArgumentError, "attempted to set property #{p} to forbidden value #{new_value.inspect}") + else + if new_value # Only run munge for non-nil values + case munge + when Symbol + new_value = new_value.send(munge) + when Proc + new_value = munge[new_value] + when nil + else + raise ArgumentError, "Property munge must be a symbol or a block - you supplied a #{munge.class}." + end + end + instance_variable_set(ivar, new_value) + end else raise ArgumentError, "wrong number of arguments (#{args.size} for 0,1)" end diff --git a/lib/omniboard/templates/column.erb b/lib/omniboard/templates/column.erb index 5eea855..ff0a2ac 100644 --- a/lib/omniboard/templates/column.erb +++ b/lib/omniboard/templates/column.erb @@ -1,9 +1,7 @@

<%=column%>

- <% if column.display_total_projects %> -
"><%= column.projects.size %>
- <% end %> + <% if column.display_project_counts %><%= column.count_div %><% end %> <% if column.filter_button %> " /> <% end %> diff --git a/spec/property_spec.rb b/spec/property_spec.rb index d905702..4c60a9f 100644 --- a/spec/property_spec.rb +++ b/spec/property_spec.rb @@ -5,27 +5,45 @@ class SampleClass property :foo block_property :bar + + property :restricted_property, allowed_values: [1,2,3] + + property :munged_property, munge: lambda{ |o| o / 2 } + property :symbol_munged_property, munge: :to_i end describe Omniboard::Property do + let(:o){ SampleClass.new} + describe "#property" do it "should allow us to set and retrieve properties" do - o = SampleClass.new o.foo(3) expect(o.foo).to eq(3) expect{ o.foo(1,2) }.to raise_error(ArgumentError) end + + it "should only allow allowed_values" do + o.restricted_property(2) + + expect{ o.restricted_property(4) }.to raise_error(ArgumentError) + end + + it "should munge values when munge is set" do + o.munged_property(4) + expect(o.munged_property).to eq(2) + + o.symbol_munged_property("4") + expect(o.symbol_munged_property).to eq(4) + end end describe "#block_property" do it "should allow us to set and retrieve blocks" do - o = SampleClass.new o.bar{ |i| i * 2 } expect(o.bar[3]).to eq(6) end it "should also take non-block arguments, but only if no block is supplied" do - o = SampleClass.new o.bar(3){ true } expect(o.bar).to be_a(Proc) diff --git a/spec/rendering/column_totals_spec.rb b/spec/rendering/column_totals_spec.rb deleted file mode 100644 index 165f0db..0000000 --- a/spec/rendering/column_totals_spec.rb +++ /dev/null @@ -1,16 +0,0 @@ -require_relative "../spec_helper" - -# Ensure that setting +display_total_projects+ to true on a column will show the number of projects in it -describe "Column#display_total_projects" do - it "should cause column project totals to be displayed" do - - # Set up - d = Rubyfocus::Document.new - Omniboard::document = d - - c = Omniboard::Column.new("Default"){ display_total_projects true } - c << Rubyfocus::Project.new(d, name: "Highlighted Project", note: "Highlighted", id: "1") - - expect(render c).to contain_one_xpath("//div[@class='column-total']") - end -end \ No newline at end of file diff --git a/spec/rendering/display_project_counts_spec.rb b/spec/rendering/display_project_counts_spec.rb new file mode 100644 index 0000000..7aad2a0 --- /dev/null +++ b/spec/rendering/display_project_counts_spec.rb @@ -0,0 +1,51 @@ +require_relative "../spec_helper" + +# Ensure that setting +display_project_counts+ on a column will show the number of projects in it +describe "Column#display_project_counts" do + + before(:all) do + d = Rubyfocus::Document.new + @c = Omniboard::Column.new("Default") do + dim_when{ |p| p.name == "Dim me" } + mark_when{ |p| p.name == "Mark me" } + end + + @c << Rubyfocus::Project.new(d, name: "Dim me", id: "dim") + @c << Rubyfocus::Project.new(d, name: "Do nothing", id: "nil") + @c << Rubyfocus::Project.new(d, name: "Mark me", id: "mark") + end + + describe "when set to 'all'" do + it "should show the count of all projects in a column" do + @c.display_project_counts :all + + doc = render_xml(@c) + expect(doc.elements.to_a("//div[@class='column-total']").first.text).to eq("3") + end + end + + describe "when set to 'active'" do + it "should show the count of all active (i.e. non-dimmed) projects in a column" do + @c.display_project_counts :active + + doc = render_xml(@c) + expect(doc.elements.to_a("//div[@class='column-total']").first.text).to eq("2") + end + end + + describe "when set to 'marked'" do + it "should show the count of all marked projects in a column" do + @c.display_project_counts :marked + + doc = render_xml(@c) + expect(doc.elements.to_a("//div[@class='column-total']").first.text).to eq("1") + end + end + + describe "when set to an invalid value" do + it "should throw an error" do + expect{ @c.display_project_counts "foobar" }.to raise_exception(ArgumentError) + expect{ Omniboard::Column.display_project_counts "foobar" }.to raise_exception(ArgumentError) + end + end +end \ No newline at end of file diff --git a/spec/rendering/project_limit_spec.rb b/spec/rendering/project_limit_spec.rb index 7c02521..a3199c3 100644 --- a/spec/rendering/project_limit_spec.rb +++ b/spec/rendering/project_limit_spec.rb @@ -19,7 +19,7 @@ Omniboard::document = d c = Omniboard::Column.new("Default") do - display_total_projects true + display_project_counts :all project_limit 1 end @@ -33,7 +33,7 @@ Omniboard::document = d c = Omniboard::Column.new("Default") do - display_total_projects true + display_project_counts :all project_limit 0 end