Skip to content

Commit

Permalink
Added nuance to project counts
Browse files Browse the repository at this point in the history
  • Loading branch information
jyruzicka committed Aug 1, 2016
1 parent 6c972d4 commit aadf960
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 30 deletions.
1 change: 1 addition & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
36 changes: 32 additions & 4 deletions lib/omniboard/column.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)

Expand Down Expand Up @@ -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
%|<div class="#{css_class}">#{total}</div>|
end


#---------------------------------------
# Class-level methods

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down
21 changes: 19 additions & 2 deletions lib/omniboard/property.rb
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 1 addition & 3 deletions lib/omniboard/templates/column.erb
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<div class="column width-<%=column.columns%>" style="flex-grow: <%=column.width%>">
<div class="column-header">
<h2><%=column%></h2>
<% if column.display_total_projects %>
<div class="<%="column-total" + (column.project_limit && column.project_limit < column.projects.size ? " limit-breached" : "")%>"><%= column.projects.size %></div>
<% end %>
<% if column.display_project_counts %><%= column.count_div %><% end %>
<% if column.filter_button %>
<svg class="filter-button" xmlns:xlink="http://www.w3.org/1999/xlink"><use xlink:href="#filter-<%= column.property(:hide_dimmed) ? "remove" : "apply" %>" /></svg>
<% end %>
Expand Down
24 changes: 21 additions & 3 deletions spec/property_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
16 changes: 0 additions & 16 deletions spec/rendering/column_totals_spec.rb

This file was deleted.

51 changes: 51 additions & 0 deletions spec/rendering/display_project_counts_spec.rb
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions spec/rendering/project_limit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down

0 comments on commit aadf960

Please sign in to comment.