cards 0.7 → 0.9
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.
- data/CHANGES.txt +9 -0
- data/README.txt +1 -1
- data/Rakefile +7 -1
- data/examples/csv to dot/generate_card_walls +3 -3
- data/examples/custom csv builder/Stories.csv +16 -0
- data/examples/custom csv builder/Stories.tracker.csv +29 -0
- data/examples/custom csv builder/generate_card_wall +31 -0
- data/examples/excel to visio/Business Processes.xls +0 -0
- data/examples/excel to visio/TPS-small.png +0 -0
- data/examples/excel to visio/generate card walls.rb +10 -0
- data/examples/excel to visio/readme.html +104 -0
- data/examples/importing into tracker api/Stories.csv +16 -0
- data/examples/importing into tracker api/Voting Example.numbers +0 -0
- data/examples/importing into tracker api/appscript_example.rb +18 -0
- data/examples/importing into tracker api/from_numbers_09 +50 -0
- data/examples/importing into tracker api/generate_card_wall +32 -0
- data/examples/importing into tracker api/osa.rb +39 -0
- data/examples/numbers to omnigraffle/Voting Example.numbers +0 -0
- data/examples/numbers to omnigraffle/generate_card_walls +11 -9
- data/lib/cards.rb +3 -1
- data/lib/cards/csv_builder.rb +36 -34
- data/lib/cards/csv_parser.rb +6 -44
- data/lib/cards/numbers_parser.rb +43 -0
- data/lib/cards/swim_lanes.rb +1 -0
- data/lib/cards/tabular_parser.rb +78 -0
- data/lib/cards/tracker_csv.rb +15 -13
- data/lib/cards/writers/dot_writer.rb +6 -2
- data/spec/cards/csv_parser_spec.rb +22 -4
- data/spec/cards/numbers_parser_spec.rb +25 -0
- data/spec/fixtures/Voting Example.numbers +0 -0
- metadata +37 -17
- data/Manifest.txt +0 -40
- data/examples/csv to dot/Stories.dot +0 -63
- data/examples/numbers to omnigraffle/Voting Example.numbers/Contents/PkgInfo +0 -1
- data/examples/numbers to omnigraffle/Voting Example.numbers/QuickLook/Thumbnail.jpg +0 -0
- data/examples/numbers to omnigraffle/Voting Example.numbers/document-thumbnail.tiff +0 -0
- data/examples/numbers to omnigraffle/Voting Example.numbers/index.xml.gz +0 -0
- data/examples/numbers to omnigraffle/Voting Example/Cards-Goals.csv +0 -7
- data/examples/numbers to omnigraffle/Voting Example/Cards-Stories.csv +0 -16
- data/examples/numbers to omnigraffle/Voting Example/Cards-Workflow.csv +0 -7
data/CHANGES.txt
CHANGED
data/README.txt
CHANGED
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ require 'hoe'
|
|
11
11
|
require 'lib/cards'
|
12
12
|
|
13
13
|
desc "Default Task"
|
14
|
-
task :default => [:spec]
|
14
|
+
task :default => [:generate_manifest, :spec]
|
15
15
|
|
16
16
|
task :test => :spec
|
17
17
|
|
@@ -19,6 +19,12 @@ Spec::Rake::SpecTask.new(:spec) do |t|
|
|
19
19
|
t.spec_files = FileList['spec/**/*_spec.rb']
|
20
20
|
end
|
21
21
|
|
22
|
+
task :generate_manifest do
|
23
|
+
File.open("Manifest.txt", "w") do |f|
|
24
|
+
f << FileList["CHANGES.txt", "Rakefile", "README.txt", "examples/**/*", "lib/**/*", "spec/**/*"].to_a.join("\n")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
22
28
|
desc "export to dot file"
|
23
29
|
task :run_dot do
|
24
30
|
file = ENV["FILE"] || SAMPLE_FILE
|
@@ -1,10 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
2
|
require 'rubygems'
|
3
|
+
gem 'cards'
|
4
4
|
require 'cards'
|
5
|
-
|
6
5
|
include Cards
|
7
6
|
|
7
|
+
|
8
8
|
def csv_file(name)
|
9
9
|
CsvParser.new(File.dirname(__FILE__) + "/#{name}.csv")
|
10
10
|
end
|
@@ -22,4 +22,4 @@ end
|
|
22
22
|
puts "generated Stories.dot"
|
23
23
|
|
24
24
|
# uncomment this line if you want to see the generated file
|
25
|
-
# `open "#{File.dirname(__FILE__)}/Stories.dot"`
|
25
|
+
# `open "#{File.dirname(__FILE__)}/Stories.dot"`
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Activity,Task,Story,Note,Estimate,Priority
|
2
|
+
Voter,Vote on question,Ability to see question,,1,H
|
3
|
+
,,Ability to see choices,,1,M
|
4
|
+
,,Ability to choose,This is the server trip,2,H
|
5
|
+
,Navigate questions,Ability to continue to next / prev,,1,H
|
6
|
+
,,Ability to see list of questions,This includes ability to jump to that question,4,H
|
7
|
+
,Submit,Ability to return to new screen,,1,M
|
8
|
+
Admin,Create questions,Ability to enter question,,4,H
|
9
|
+
,,Ability to reorder question,,4,H
|
10
|
+
,,Ability to enter multiple choice question,,1,L
|
11
|
+
,,Ability to enter text question,,1,H
|
12
|
+
,,Ability to enter long text question,,1,H
|
13
|
+
,,Ability to enter list question,,2,L
|
14
|
+
,Compile votes,Ability to see results in spreadsheet,,4,H
|
15
|
+
,,Ability to see summary of results,This includes percentage of each question answering which answer,2,M
|
16
|
+
,Announce winners,,,,
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Story,Labels,Story Type,Estimate,Description,Priority
|
2
|
+
Ability to see question,"Vote on question, H",,1,"while Voter
|
3
|
+
",2
|
4
|
+
Ability to see choices,"Vote on question, M",,1,"while Voter
|
5
|
+
",1
|
6
|
+
Ability to choose,"Vote on question, H",,2,"while Voter
|
7
|
+
This is the server trip",2
|
8
|
+
Ability to continue to next / prev,"Navigate questions, H",,1,"while Voter
|
9
|
+
",2
|
10
|
+
Ability to see list of questions,"Navigate questions, H",,4,"while Voter
|
11
|
+
This includes ability to jump to that question",2
|
12
|
+
Ability to return to new screen,"Submit, M",,1,"while Voter
|
13
|
+
",1
|
14
|
+
Ability to enter question,"Create questions, H",,4,"while Admin
|
15
|
+
",2
|
16
|
+
Ability to reorder question,"Create questions, H",,4,"while Admin
|
17
|
+
",2
|
18
|
+
Ability to enter multiple choice question,"Create questions, L",,1,"while Admin
|
19
|
+
",0
|
20
|
+
Ability to enter text question,"Create questions, H",,1,"while Admin
|
21
|
+
",2
|
22
|
+
Ability to enter long text question,"Create questions, H",,1,"while Admin
|
23
|
+
",2
|
24
|
+
Ability to enter list question,"Create questions, L",,2,"while Admin
|
25
|
+
",0
|
26
|
+
Ability to see results in spreadsheet,"Compile votes, H",,4,"while Admin
|
27
|
+
",2
|
28
|
+
Ability to see summary of results,"Compile votes, M",,2,"while Admin
|
29
|
+
This includes percentage of each question answering which answer",1
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
gem 'cards'
|
4
|
+
require 'cards'
|
5
|
+
include Cards
|
6
|
+
|
7
|
+
|
8
|
+
def csv_file(name)
|
9
|
+
CsvParser.new(File.dirname(__FILE__) + "/#{name}.csv")
|
10
|
+
end
|
11
|
+
|
12
|
+
class Tracker < CsvBuilder
|
13
|
+
PRIORITY = %w(L M H)
|
14
|
+
|
15
|
+
def header
|
16
|
+
["Story", "Labels", "Story Type", "Estimate", "Description", "Priority"]
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_story(name, row = {})
|
20
|
+
@csv << [
|
21
|
+
name,
|
22
|
+
"#{@task}, #{row[:priority]}",
|
23
|
+
nil,
|
24
|
+
row[:estimate],
|
25
|
+
"while #{@activity}\n#{row[:note]}",
|
26
|
+
PRIORITY.index(row[:priority])
|
27
|
+
]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Tracker.from csv_file("Stories")
|
Binary file
|
Binary file
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)) + '/CardWallGenerator/include.rb'
|
2
|
+
|
3
|
+
|
4
|
+
data = load_excel_data 'Business Processes.xls', 1
|
5
|
+
create_visio_document data, 'Caution.vsd'
|
6
|
+
|
7
|
+
data = load_excel_data 'Business Processes.xls', 2
|
8
|
+
create_visio_document data, 'TPS.vsd'
|
9
|
+
|
10
|
+
|
@@ -0,0 +1,104 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Card Wall Generator</title>
|
4
|
+
</head>
|
5
|
+
<body>
|
6
|
+
<div align="center">
|
7
|
+
<div style="width:800;" align="left">
|
8
|
+
<h1>Card Wall Generator</h1>
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
<h2>What is it?</h2>
|
13
|
+
<hr/>
|
14
|
+
|
15
|
+
<p>
|
16
|
+
this tool will take an excel spreadsheet with a hierarchical story list in it, and generate
|
17
|
+
a "card wall" in visio from it.
|
18
|
+
</p>
|
19
|
+
|
20
|
+
<p style="text-align:right">
|
21
|
+
<img src="TPS-small.png"><br>
|
22
|
+
<i>a "card wall"</i>
|
23
|
+
</p>
|
24
|
+
|
25
|
+
<p>
|
26
|
+
the spreadsheet might look like - <a href="business processes.xls">business processes.xls</a>
|
27
|
+
</p>
|
28
|
+
|
29
|
+
<p>
|
30
|
+
and the card wall might look like - <a href="TPS.vsd">TPS.vsd</a><br>
|
31
|
+
</p>
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
<h2>Installation</h2>
|
37
|
+
<hr/>
|
38
|
+
|
39
|
+
<h3>You will need:</h3>
|
40
|
+
|
41
|
+
<ul>
|
42
|
+
<li>Windows - sorry only works on windows right now...
|
43
|
+
<li>Excel
|
44
|
+
<li>Visio
|
45
|
+
<li>Ruby - download it from here - <a href="http://rubyforge.org/projects/rubyinstaller/">http://rubyforge.org/projects/rubyinstaller/</a>
|
46
|
+
</ul>
|
47
|
+
|
48
|
+
<p>
|
49
|
+
Once you have all those installed, you can test your installation by double clicking the
|
50
|
+
"generate card walls.rb" file. It should open excel for a second, then open up visio and
|
51
|
+
generate 2 card walls.
|
52
|
+
</p>
|
53
|
+
|
54
|
+
<h3>The Driver File</h3>
|
55
|
+
|
56
|
+
<p>
|
57
|
+
What the card wall generator does is configured by the "generate card walls.rb" file. Open
|
58
|
+
it up and take a look. You should see stuff like :
|
59
|
+
</p>
|
60
|
+
|
61
|
+
<code><pre>
|
62
|
+
data = load_excel_data 'Business Processes.xls', 1
|
63
|
+
create_visio_document data, 'Caution.vsd'
|
64
|
+
</pre></code>
|
65
|
+
|
66
|
+
<p>You can customize this for your needs. Basically copy these 2 lines for every card wall
|
67
|
+
you want to create, and substitute these for the values :
|
68
|
+
<ul>
|
69
|
+
<li>excel file with the master story list - "Business Processes.xls"
|
70
|
+
<li>index of the sheet within the excel file - "1"
|
71
|
+
<li>visio file that will be created - "Caution.vsd"
|
72
|
+
</ul>
|
73
|
+
</p>
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
<h2>More Information</h2>
|
78
|
+
<hr/>
|
79
|
+
|
80
|
+
<p>Visit the project website at :</p>
|
81
|
+
|
82
|
+
<p><a href="http://rubyforge.org/projects/cardwallgen">http://rubyforge.org/projects/cardwallgen</a></p>
|
83
|
+
|
84
|
+
<p>The documentation is still pretty sparse. If you can find someone that knows ruby, have them poke
|
85
|
+
around, and they'll probably be able to figure out how to do most things. Otherwise, email the list
|
86
|
+
at cardwallgen-users@rubyforge.org, or sign up for the list at the project website.</p>
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
<h2>License</h2>
|
92
|
+
<hr/>
|
93
|
+
|
94
|
+
<p>
|
95
|
+
<i>Copyright (C) 2006 Jeremy Stell-Smith</i>
|
96
|
+
</p>
|
97
|
+
|
98
|
+
<p>
|
99
|
+
This software is distributed under the LGPL license.
|
100
|
+
</p>
|
101
|
+
</div>
|
102
|
+
</div>
|
103
|
+
</body>
|
104
|
+
</html>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Activity,Task,Story,Note,Estimate,Priority
|
2
|
+
Voter,Vote on question,Ability to see question,,1,H
|
3
|
+
,,Ability to see choices,,1,M
|
4
|
+
,,Ability to choose,This is the server trip,2,H
|
5
|
+
,Navigate questions,Ability to continue to next / prev,,1,H
|
6
|
+
,,Ability to see list of questions,This includes ability to jump to that question,3,H
|
7
|
+
,Submit,Ability to return to new screen,,1,M
|
8
|
+
Admin,Create questions,Ability to enter question,,3,H
|
9
|
+
,,Ability to reorder question,,3,H
|
10
|
+
,,Ability to enter multiple choice question,,1,L
|
11
|
+
,,Ability to enter text question,,1,H
|
12
|
+
,,Ability to enter long text question,,1,H
|
13
|
+
,,Ability to enter list question,,2,L
|
14
|
+
,Compile votes,Ability to see results in spreadsheet,,3,H
|
15
|
+
,,Ability to see summary of results,This includes percentage of each question answering which answer,2,M
|
16
|
+
,Announce winners,,,,
|
Binary file
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'appscript'
|
3
|
+
|
4
|
+
itunes = Appscript.app('iTunes')
|
5
|
+
|
6
|
+
track = itunes.current_track
|
7
|
+
p track # <OSA::Itunes::FileTrack:0x1495e20>
|
8
|
+
p track.name # "Over The Rainbow"
|
9
|
+
p track.artist # "Keith Jarrett"
|
10
|
+
p track.duration # 362.368988037109
|
11
|
+
p track.date_added.to_s # "2006-06-30"
|
12
|
+
p track.enabled? # true
|
13
|
+
|
14
|
+
# Play the selected track.
|
15
|
+
itunes.play
|
16
|
+
|
17
|
+
# Fade the volume.
|
18
|
+
100.times { |i| itunes.sound_volume = i; sleep 0.1 }
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require File.dirname(__FILE__) + "/../../lib/cards" # you probably want to include the gem version
|
4
|
+
require 'rest_client'
|
5
|
+
|
6
|
+
token = "d6b1b5ded944959aec78754ff9f018bd"
|
7
|
+
project_id = "9989"
|
8
|
+
priority = %w(L M H)
|
9
|
+
|
10
|
+
project = RestClient::Resource.new("http://www.pivotaltracker.com/services/v2/projects/#{project_id}",
|
11
|
+
:headers => { "X-TrackerToken" => token })
|
12
|
+
|
13
|
+
# puts project["stories?filter=type:bug"].get
|
14
|
+
|
15
|
+
require 'rbosa'
|
16
|
+
numbers = OSA.app('Numbers')
|
17
|
+
|
18
|
+
# itunes = OSA.app('iTunes')
|
19
|
+
# track = itunes.current_track
|
20
|
+
# p track # <OSA::Itunes::FileTrack:0x1495e20>
|
21
|
+
# p track.name # "Over The Rainbow"
|
22
|
+
# p track.artist # "Keith Jarrett"
|
23
|
+
# p track.duration # 362.368988037109
|
24
|
+
# p track.date_added.to_s # "2006-06-30"
|
25
|
+
# p track.enabled? # true
|
26
|
+
#
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
csv = Cards::CsvParser.new(File.dirname(__FILE__) + "/Stories.csv")
|
34
|
+
rows = csv.denormalized_rows(:story, [:activity, :task])
|
35
|
+
rows = rows.sort_by {|row| priority.index(row[:priority])}
|
36
|
+
|
37
|
+
rows.each do |row|
|
38
|
+
puts "adding #{row[:story]}"
|
39
|
+
|
40
|
+
params = {}
|
41
|
+
params[:name] = row[:story]
|
42
|
+
# params[:story_type] = "bug"
|
43
|
+
params[:current_state] = "unstarted"
|
44
|
+
params[:requested_by] = "Cards Test User"
|
45
|
+
params[:estimate] = row[:estimate]
|
46
|
+
params[:description] = "while #{row[:activity]}\n#{row[:note]}"
|
47
|
+
|
48
|
+
# project["stories"].post(:story => params)
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require File.dirname(__FILE__) + "/../../lib/cards" # you probably want to include the gem version
|
4
|
+
require 'rest_client'
|
5
|
+
|
6
|
+
token = "d6b1b5ded944959aec78754ff9f018bd"
|
7
|
+
project_id = "9989"
|
8
|
+
priority = %w(L M H)
|
9
|
+
|
10
|
+
project = RestClient::Resource.new("http://www.pivotaltracker.com/services/v2/projects/#{project_id}",
|
11
|
+
:headers => { "X-TrackerToken" => token })
|
12
|
+
|
13
|
+
# puts project["stories?filter=type:bug"].get
|
14
|
+
|
15
|
+
csv = Cards::CsvParser.new(File.dirname(__FILE__) + "/Stories.csv")
|
16
|
+
rows = csv.denormalized_rows(:story, [:activity, :task])
|
17
|
+
rows = rows.sort_by {|row| priority.index(row[:priority])}
|
18
|
+
|
19
|
+
rows.each do |row|
|
20
|
+
puts "adding #{row[:story]}"
|
21
|
+
|
22
|
+
params = {}
|
23
|
+
params[:name] = row[:story]
|
24
|
+
# params[:story_type] = "bug"
|
25
|
+
params[:current_state] = "unstarted"
|
26
|
+
params[:requested_by] = "Cards Test User"
|
27
|
+
params[:estimate] = row[:estimate]
|
28
|
+
params[:description] = "while #{row[:activity]}\n#{row[:note]}"
|
29
|
+
|
30
|
+
project["stories"].post(:story => params)
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rbosa'
|
3
|
+
|
4
|
+
def find_table(document, name)
|
5
|
+
document.sheets.each do |sheet|
|
6
|
+
sheet.tables.each do |table|
|
7
|
+
return table
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
numbers = OSA.app('Numbers')
|
13
|
+
document = numbers.open(File.dirname(__FILE__) + "/Voting Example.numbers")
|
14
|
+
table = find_table(document, "Stories")
|
15
|
+
|
16
|
+
p table.name
|
17
|
+
table.rows.each do |row|
|
18
|
+
values = []
|
19
|
+
row.cells.map do |cell|
|
20
|
+
values << cell.name << cell.value
|
21
|
+
end
|
22
|
+
p values
|
23
|
+
end
|
24
|
+
|
25
|
+
# itunes = OSA.app('iTunes')
|
26
|
+
#
|
27
|
+
# track = itunes.current_track
|
28
|
+
# p track # <OSA::Itunes::FileTrack:0x1495e20>
|
29
|
+
# p track.name # "Over The Rainbow"
|
30
|
+
# p track.artist # "Keith Jarrett"
|
31
|
+
# p track.duration # 362.368988037109
|
32
|
+
# p track.date_added.to_s # "2006-06-30"
|
33
|
+
# p track.enabled? # true
|
34
|
+
#
|
35
|
+
# # Play the selected track.
|
36
|
+
# itunes.play
|
37
|
+
#
|
38
|
+
# # Fade the volume.
|
39
|
+
# 100.times { |i| itunes.sound_volume = i; sleep 0.1 }
|
Binary file
|
@@ -1,29 +1,31 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# this doesn't actually read the numbers document, you must export csv from numbers as we've done here,
|
3
|
-
# the csv can then be parsed and turned into omnigraffle
|
4
|
-
|
5
2
|
require 'rubygems'
|
3
|
+
gem 'cards'
|
6
4
|
require 'cards'
|
5
|
+
require 'cards/numbers_parser'
|
7
6
|
include Cards
|
8
7
|
|
9
|
-
|
10
|
-
|
8
|
+
# this requires numbers '09, before that you must export to csv and use the csv parser
|
9
|
+
|
10
|
+
def table(name)
|
11
|
+
file = File.dirname(__FILE__) + "/Voting Example.numbers"
|
12
|
+
NumbersParser.new(file, name)
|
11
13
|
end
|
12
14
|
|
13
15
|
CardWall.colors[:goal] = :green
|
14
16
|
CardWall.writer = GraffleWriter
|
15
17
|
|
16
|
-
CardWall.from
|
18
|
+
CardWall.from table("Goals") do
|
17
19
|
column :goal
|
18
20
|
end
|
19
21
|
|
20
|
-
CardWall.from
|
22
|
+
CardWall.from table("Workflow") do
|
21
23
|
row :role
|
22
24
|
column :task, :wrap_at => 5
|
23
25
|
end
|
24
26
|
|
25
|
-
CardWall.from
|
26
|
-
row :
|
27
|
+
CardWall.from table("Stories") do
|
28
|
+
row :activity
|
27
29
|
row :task
|
28
30
|
column :story, :wrap_at => 4 do |card, row|
|
29
31
|
card.name = " #{row[:estimate]}\n\n#{card.name}" unless row[:estimate].blank?
|
data/lib/cards.rb
CHANGED
@@ -9,9 +9,11 @@ require 'cards/card_wall'
|
|
9
9
|
require 'cards/writers/dot_writer'
|
10
10
|
require 'cards/writers/graffle_writer'
|
11
11
|
|
12
|
+
# csv builders
|
13
|
+
require 'cards/csv_builder'
|
12
14
|
require 'cards/master_story_list'
|
13
15
|
require 'cards/tracker_csv'
|
14
16
|
|
15
17
|
module Cards
|
16
|
-
VERSION = "0.
|
18
|
+
VERSION = "0.9"
|
17
19
|
end
|
data/lib/cards/csv_builder.rb
CHANGED
@@ -1,46 +1,48 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module Cards
|
2
|
+
class CsvBuilder
|
3
|
+
def initialize(file_name)
|
4
|
+
@file_name = file_name
|
5
|
+
@file = File.open(file_name, "wb")
|
6
|
+
@csv = CSV::Writer.create(@file)
|
7
|
+
@csv << header
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
def header
|
11
|
+
raise "implement me"
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
def self.from(parser)
|
15
|
+
builder = self.new(parser.default_output_file + ".#{self.to_s.gsub("Cards::", "").downcase}.csv")
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
parser.each_row do |row|
|
18
|
+
builder.process(row)
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
21
|
+
builder.done
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
def process(row)
|
25
|
+
[:activity, :task, :story].each do |handler|
|
26
|
+
send("add_#{handler}", row[handler], row) if row[handler]
|
27
|
+
end
|
26
28
|
end
|
27
|
-
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
def add_activity(name, params = {})
|
31
|
+
@activity = name
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
34
|
+
def add_task(name, params = {})
|
35
|
+
@task = name
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
def add_story(name, params = {})
|
39
|
+
raise "implement me"
|
40
|
+
end
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
def done
|
43
|
+
@csv.close
|
44
|
+
@file.close
|
45
|
+
`open #{@file_name.gsub(' ', '\\ ')}`
|
46
|
+
end
|
45
47
|
end
|
46
48
|
end
|
data/lib/cards/csv_parser.rb
CHANGED
@@ -1,60 +1,22 @@
|
|
1
1
|
require 'csv'
|
2
|
+
require 'cards/tabular_parser'
|
2
3
|
|
3
4
|
module Cards
|
4
5
|
class CsvParser
|
6
|
+
include TabularParser
|
7
|
+
|
5
8
|
def initialize(file)
|
6
9
|
@file = file
|
7
10
|
end
|
8
11
|
|
9
|
-
def
|
10
|
-
rows = []
|
11
|
-
each_row {|row| rows << row}
|
12
|
-
rows
|
13
|
-
end
|
14
|
-
|
15
|
-
def each_row
|
16
|
-
header = nil
|
12
|
+
def each_unparsed_row
|
17
13
|
CSV.open(@file, 'r') do |row|
|
18
|
-
|
19
|
-
header = define_header(row)
|
20
|
-
else
|
21
|
-
yield Row.new(header, row)
|
22
|
-
end
|
14
|
+
yield row
|
23
15
|
end
|
24
16
|
end
|
25
|
-
|
17
|
+
|
26
18
|
def default_output_file
|
27
19
|
File.basename(@file).sub(/\..*/, '')
|
28
20
|
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def define_header(header_row)
|
33
|
-
header = {}
|
34
|
-
header_row.each_with_index do |name, i|
|
35
|
-
header[name.downcase.gsub(' ', '_').to_sym] = i
|
36
|
-
end
|
37
|
-
return header
|
38
|
-
end
|
39
|
-
|
40
|
-
class Row
|
41
|
-
def initialize(header, row)
|
42
|
-
@header, @row = header, row
|
43
|
-
end
|
44
|
-
|
45
|
-
def [](key)
|
46
|
-
index = @header[key] || raise("can't find column header #{key.inspect} in #{@header.inspect}")
|
47
|
-
@row[index]
|
48
|
-
end
|
49
|
-
|
50
|
-
def to_h
|
51
|
-
h = {}
|
52
|
-
@header.each_key do |column_header|
|
53
|
-
val = @row[@header[column_header]]
|
54
|
-
h[column_header] = val unless val.blank?
|
55
|
-
end
|
56
|
-
h
|
57
|
-
end
|
58
|
-
end
|
59
21
|
end
|
60
22
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rbosa'
|
2
|
+
require 'cards/tabular_parser'
|
3
|
+
|
4
|
+
module Cards
|
5
|
+
class NumbersParser
|
6
|
+
include TabularParser
|
7
|
+
|
8
|
+
def initialize(file, table_name)
|
9
|
+
@file, @table_name = file, table_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def each_unparsed_row
|
13
|
+
numbers = OSA.app('Numbers')
|
14
|
+
document = numbers.open(@file)
|
15
|
+
table = find_table(document, @table_name)
|
16
|
+
|
17
|
+
table.rows.each do |row|
|
18
|
+
values = []
|
19
|
+
row.cells.map do |cell|
|
20
|
+
value = cell.value
|
21
|
+
value = nil if value == 0
|
22
|
+
values << value
|
23
|
+
end
|
24
|
+
yield values
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def default_output_file
|
29
|
+
@table_name
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def find_table(document, name)
|
35
|
+
document.sheets.each do |sheet|
|
36
|
+
sheet.tables.each do |table|
|
37
|
+
return table if table.name.downcase == name.downcase
|
38
|
+
end
|
39
|
+
end
|
40
|
+
raise "table #{name} not found in #{document.name}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/cards/swim_lanes.rb
CHANGED
@@ -0,0 +1,78 @@
|
|
1
|
+
module Cards
|
2
|
+
module TabularParser
|
3
|
+
def rows
|
4
|
+
rows = []
|
5
|
+
each_row {|row| rows << row}
|
6
|
+
rows
|
7
|
+
end
|
8
|
+
|
9
|
+
def each_row
|
10
|
+
header = nil
|
11
|
+
each_unparsed_row do |row|
|
12
|
+
if header.nil?
|
13
|
+
header = define_header(row)
|
14
|
+
else
|
15
|
+
yield Row.new(header, row)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# this method will turn something of the form
|
21
|
+
#
|
22
|
+
# activity | task | story |
|
23
|
+
# a | | |
|
24
|
+
# | b | |
|
25
|
+
# | | c |
|
26
|
+
# | | d |
|
27
|
+
#
|
28
|
+
# into
|
29
|
+
#
|
30
|
+
# activity | task | story |
|
31
|
+
# a | b | c |
|
32
|
+
# a | b | d |
|
33
|
+
#
|
34
|
+
def denormalized_rows(key_column, columns_to_denormalize)
|
35
|
+
last_row = {}
|
36
|
+
rows = []
|
37
|
+
each_row do |row|
|
38
|
+
row = row.to_h
|
39
|
+
columns_to_denormalize.each do |c|
|
40
|
+
row[c] = last_row[c] if row[c].blank?
|
41
|
+
end
|
42
|
+
rows << row unless row[key_column].blank?
|
43
|
+
last_row = row
|
44
|
+
end
|
45
|
+
rows
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def define_header(header_row)
|
51
|
+
header = {}
|
52
|
+
header_row.each_with_index do |name, i|
|
53
|
+
header[name.downcase.gsub(' ', '_').to_sym] = i
|
54
|
+
end
|
55
|
+
return header
|
56
|
+
end
|
57
|
+
|
58
|
+
class Row
|
59
|
+
def initialize(header, row)
|
60
|
+
@header, @row = header, row
|
61
|
+
end
|
62
|
+
|
63
|
+
def [](key)
|
64
|
+
index = @header[key] || raise("can't find column header #{key.inspect} in #{@header.inspect}")
|
65
|
+
@row[index]
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_h
|
69
|
+
h = {}
|
70
|
+
@header.each_key do |column_header|
|
71
|
+
val = @row[@header[column_header]]
|
72
|
+
h[column_header] = val unless val.blank?
|
73
|
+
end
|
74
|
+
h
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/cards/tracker_csv.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
require 'cards/csv_builder'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module Cards
|
4
|
+
class TrackerCsv < CsvBuilder
|
5
|
+
def header
|
6
|
+
["Story", "Labels", "Story Type", "Estimate", "Description"]
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
9
|
+
def add_story(name, params = {})
|
10
|
+
return unless [nil, '', 'Story', 'Chore'].include?(params[:story_type])
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
@csv << [
|
13
|
+
name,
|
14
|
+
@task,
|
15
|
+
params[:story_type],
|
16
|
+
nil, # params[:estimate],
|
17
|
+
"#{@activity}\n#{params[:description]}"
|
18
|
+
]
|
19
|
+
end
|
18
20
|
end
|
19
21
|
end
|
@@ -1,7 +1,11 @@
|
|
1
1
|
module Cards
|
2
2
|
class DotWriter
|
3
|
-
def initialize(
|
4
|
-
|
3
|
+
def initialize(file)
|
4
|
+
if file.respond_to? :puts
|
5
|
+
@file = file
|
6
|
+
else
|
7
|
+
@file = File.open(file + ".dot", "w")
|
8
|
+
end
|
5
9
|
@node_color = {:green => "darkseagreen1", :blue => "lightblue", :red => "pink", :yellow => "lightyellow"}
|
6
10
|
@nodes = []
|
7
11
|
|
@@ -7,22 +7,40 @@ include Cards
|
|
7
7
|
describe CsvParser do
|
8
8
|
include FileSandbox
|
9
9
|
|
10
|
-
|
10
|
+
before do
|
11
11
|
sandbox.new :file => 'tmp.csv', :with_contents =>
|
12
12
|
"activity,task,story,estimate
|
13
13
|
manage email,,
|
14
14
|
,read email,
|
15
15
|
,,display email body
|
16
|
-
manage email,think about email
|
16
|
+
manage email,think about email,mow the lawn,1
|
17
17
|
,read email,,2
|
18
18
|
,,display email body,3"
|
19
|
-
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should parse csv" do
|
20
22
|
rows = CsvParser.new(sandbox['tmp.csv'].path).rows
|
21
23
|
rows[0].to_h.should == {:activity => 'manage email'}
|
22
24
|
rows[1].to_h.should == {:task => 'read email'}
|
23
25
|
rows[2].to_h.should == {:story => 'display email body'}
|
24
|
-
rows[3].to_h.should == {:activity => 'manage email', :task => 'think about email', :estimate => "1"}
|
26
|
+
rows[3].to_h.should == {:activity => 'manage email', :task => 'think about email', :story => 'mow the lawn', :estimate => "1"}
|
25
27
|
rows[4].to_h.should == {:task => 'read email', :estimate => "2"}
|
26
28
|
rows[5].to_h.should == {:story => 'display email body', :estimate => "3"}
|
27
29
|
end
|
30
|
+
|
31
|
+
it "should denormalize rows" do
|
32
|
+
rows = CsvParser.new(sandbox['tmp.csv'].path).denormalized_rows(:story, [:activity, :task])
|
33
|
+
rows.size.should == 3
|
34
|
+
rows[0].should == {:activity => 'manage email',
|
35
|
+
:task => 'read email',
|
36
|
+
:story => 'display email body'}
|
37
|
+
rows[1].should == {:activity => 'manage email',
|
38
|
+
:task => 'think about email',
|
39
|
+
:story => 'mow the lawn',
|
40
|
+
:estimate => "1"}
|
41
|
+
rows[2].should == {:activity => 'manage email',
|
42
|
+
:task => 'read email',
|
43
|
+
:story => 'display email body',
|
44
|
+
:estimate => '3'}
|
45
|
+
end
|
28
46
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require 'cards/numbers_parser'
|
3
|
+
|
4
|
+
# not the best test, but it will do
|
5
|
+
describe Cards::NumbersParser do
|
6
|
+
describe "each_row" do
|
7
|
+
it "should find all rows in Voting Example" do
|
8
|
+
file = File.expand_path(File.dirname(__FILE__) + "/../fixtures/Voting Example.numbers")
|
9
|
+
parser = Cards::NumbersParser.new(file, "Workflow")
|
10
|
+
rows = parser.rows
|
11
|
+
rows[0].to_h.should == {:role => "Voter", :task => "Vote on question"}
|
12
|
+
rows[1].to_h.should == {:task => "Navigate questions"}
|
13
|
+
rows[2].to_h.should == {:task => "Submit"}
|
14
|
+
rows[3].to_h.should == {:role => "Admin", :task => "Create questions"}
|
15
|
+
rows[4].to_h.should == {:task => "Compile votes"}
|
16
|
+
rows[5].to_h.should == {:task => "Announce winners"}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "default_output_file" do
|
21
|
+
it "should be the table name" do
|
22
|
+
Cards::NumbersParser.new("some file.numbers", "larry").default_output_file.should == "larry"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cards
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "0.
|
4
|
+
version: "0.9"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Stell-Smith
|
@@ -9,17 +9,18 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2009-03-05 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: hoe
|
17
|
+
type: :development
|
17
18
|
version_requirement:
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
19
20
|
requirements:
|
20
21
|
- - ">="
|
21
22
|
- !ruby/object:Gem::Version
|
22
|
-
version: 1.
|
23
|
+
version: 1.8.2
|
23
24
|
version:
|
24
25
|
description: CardWallGen is a program that reads a requirements map and generates a view of it. Typically it reads it from excel or csv and generates a graphical view in visio or omnigraffle, though it may also generate another csv view of it.
|
25
26
|
email: jeremystellsmith@gmail.com
|
@@ -29,48 +30,67 @@ extensions: []
|
|
29
30
|
|
30
31
|
extra_rdoc_files:
|
31
32
|
- CHANGES.txt
|
32
|
-
- Manifest.txt
|
33
33
|
- README.txt
|
34
34
|
files:
|
35
35
|
- CHANGES.txt
|
36
|
-
- Manifest.txt
|
37
|
-
- README.txt
|
38
36
|
- Rakefile
|
39
|
-
-
|
40
|
-
- examples/csv to dot
|
37
|
+
- README.txt
|
38
|
+
- examples/csv to dot
|
41
39
|
- examples/csv to dot/generate_card_walls
|
42
|
-
- examples/
|
43
|
-
- examples/
|
44
|
-
- examples/
|
45
|
-
- examples/
|
46
|
-
- examples/
|
47
|
-
- examples/
|
48
|
-
- examples/
|
40
|
+
- examples/csv to dot/Stories.csv
|
41
|
+
- examples/custom csv builder
|
42
|
+
- examples/custom csv builder/generate_card_wall
|
43
|
+
- examples/custom csv builder/Stories.csv
|
44
|
+
- examples/custom csv builder/Stories.tracker.csv
|
45
|
+
- examples/excel to visio
|
46
|
+
- examples/excel to visio/Business Processes.xls
|
47
|
+
- examples/excel to visio/generate card walls.rb
|
48
|
+
- examples/excel to visio/readme.html
|
49
|
+
- examples/excel to visio/TPS-small.png
|
50
|
+
- examples/importing into tracker api
|
51
|
+
- examples/importing into tracker api/appscript_example.rb
|
52
|
+
- examples/importing into tracker api/from_numbers_09
|
53
|
+
- examples/importing into tracker api/generate_card_wall
|
54
|
+
- examples/importing into tracker api/osa.rb
|
55
|
+
- examples/importing into tracker api/Stories.csv
|
56
|
+
- examples/importing into tracker api/Voting Example.numbers
|
57
|
+
- examples/numbers to omnigraffle
|
49
58
|
- examples/numbers to omnigraffle/generate_card_walls
|
50
|
-
-
|
59
|
+
- examples/numbers to omnigraffle/Voting Example.numbers
|
60
|
+
- lib/cards
|
51
61
|
- lib/cards/builder.rb
|
52
62
|
- lib/cards/card.rb
|
53
63
|
- lib/cards/card_wall.rb
|
54
64
|
- lib/cards/csv_builder.rb
|
55
65
|
- lib/cards/csv_parser.rb
|
56
66
|
- lib/cards/extensions.rb
|
67
|
+
- lib/cards/layouts
|
57
68
|
- lib/cards/layouts/column_layout.rb
|
58
69
|
- lib/cards/layouts/nil_layout.rb
|
59
70
|
- lib/cards/layouts/row_layout.rb
|
60
71
|
- lib/cards/master_story_list.rb
|
72
|
+
- lib/cards/numbers_parser.rb
|
61
73
|
- lib/cards/swim_lanes.rb
|
74
|
+
- lib/cards/tabular_parser.rb
|
62
75
|
- lib/cards/text.rb
|
63
76
|
- lib/cards/tracker_csv.rb
|
77
|
+
- lib/cards/writers
|
64
78
|
- lib/cards/writers/dot_writer.rb
|
65
79
|
- lib/cards/writers/graffle_writer.rb
|
66
80
|
- lib/cards/writers/text_writer.rb
|
81
|
+
- lib/cards.rb
|
82
|
+
- spec/cards
|
67
83
|
- spec/cards/card_spec.rb
|
68
84
|
- spec/cards/card_wall_spec.rb
|
69
85
|
- spec/cards/csv_parser_spec.rb
|
70
86
|
- spec/cards/extensions_spec.rb
|
87
|
+
- spec/cards/numbers_parser_spec.rb
|
71
88
|
- spec/cards/swim_lanes_spec.rb
|
89
|
+
- spec/cards/writers
|
72
90
|
- spec/cards/writers/dot_writer_spec.rb
|
73
91
|
- spec/cards/writers/text_writer_spec.rb
|
92
|
+
- spec/fixtures
|
93
|
+
- spec/fixtures/Voting Example.numbers
|
74
94
|
- spec/spec_helper.rb
|
75
95
|
has_rdoc: true
|
76
96
|
homepage: http://rubyforge.org/projects/cardwallgen
|
@@ -95,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
115
|
requirements: []
|
96
116
|
|
97
117
|
rubyforge_project: cardwallgen
|
98
|
-
rubygems_version: 1.
|
118
|
+
rubygems_version: 1.3.1
|
99
119
|
signing_key:
|
100
120
|
specification_version: 2
|
101
121
|
summary: CardWallGen is a program that reads a requirements map and generates a view of it. Typically it reads it from excel or csv and generates a graphical view in visio or omnigraffle, though it may also generate another csv view of it.
|
data/Manifest.txt
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
CHANGES.txt
|
2
|
-
Manifest.txt
|
3
|
-
README.txt
|
4
|
-
Rakefile
|
5
|
-
examples/csv to dot/Stories.csv
|
6
|
-
examples/csv to dot/Stories.dot
|
7
|
-
examples/csv to dot/generate_card_walls
|
8
|
-
examples/numbers to omnigraffle/Voting Example.numbers/Contents/PkgInfo
|
9
|
-
examples/numbers to omnigraffle/Voting Example.numbers/QuickLook/Thumbnail.jpg
|
10
|
-
examples/numbers to omnigraffle/Voting Example.numbers/document-thumbnail.tiff
|
11
|
-
examples/numbers to omnigraffle/Voting Example.numbers/index.xml.gz
|
12
|
-
examples/numbers to omnigraffle/Voting Example/Cards-Goals.csv
|
13
|
-
examples/numbers to omnigraffle/Voting Example/Cards-Stories.csv
|
14
|
-
examples/numbers to omnigraffle/Voting Example/Cards-Workflow.csv
|
15
|
-
examples/numbers to omnigraffle/generate_card_walls
|
16
|
-
lib/cards.rb
|
17
|
-
lib/cards/builder.rb
|
18
|
-
lib/cards/card.rb
|
19
|
-
lib/cards/card_wall.rb
|
20
|
-
lib/cards/csv_builder.rb
|
21
|
-
lib/cards/csv_parser.rb
|
22
|
-
lib/cards/extensions.rb
|
23
|
-
lib/cards/layouts/column_layout.rb
|
24
|
-
lib/cards/layouts/nil_layout.rb
|
25
|
-
lib/cards/layouts/row_layout.rb
|
26
|
-
lib/cards/master_story_list.rb
|
27
|
-
lib/cards/swim_lanes.rb
|
28
|
-
lib/cards/text.rb
|
29
|
-
lib/cards/tracker_csv.rb
|
30
|
-
lib/cards/writers/dot_writer.rb
|
31
|
-
lib/cards/writers/graffle_writer.rb
|
32
|
-
lib/cards/writers/text_writer.rb
|
33
|
-
spec/cards/card_spec.rb
|
34
|
-
spec/cards/card_wall_spec.rb
|
35
|
-
spec/cards/csv_parser_spec.rb
|
36
|
-
spec/cards/extensions_spec.rb
|
37
|
-
spec/cards/swim_lanes_spec.rb
|
38
|
-
spec/cards/writers/dot_writer_spec.rb
|
39
|
-
spec/cards/writers/text_writer_spec.rb
|
40
|
-
spec/spec_helper.rb
|
@@ -1,63 +0,0 @@
|
|
1
|
-
digraph G {
|
2
|
-
graph [nodesep=.1, ranksep=.1, ordering=out];
|
3
|
-
node [shape=box, color=black, style=filled, width=2, height=1.2, fixedsize=true, labeljust="l"];
|
4
|
-
edge [style=invis, weight=1];
|
5
|
-
card_0_0 [label="Voter",fillcolor=lightblue];
|
6
|
-
card_0_1 [label="Vote on question",fillcolor=pink];
|
7
|
-
card_0_2 [label="Ability to see\nquestion 1",fillcolor=lightyellow];
|
8
|
-
card_0_3 [label="Ability to see\nchoices 1",fillcolor=lightyellow];
|
9
|
-
card_0_4 [label="Ability to choose\nThis is the server\ntrip 2",fillcolor=lightyellow];
|
10
|
-
card_1_1 [label="Navigate questions",fillcolor=pink];
|
11
|
-
card_1_2 [label="Ability to continue\nto next / prev 1",fillcolor=lightyellow];
|
12
|
-
card_1_3 [label="Ability to see list\nof questions This\nincludes ability to\njump to that\nquestion 4",fillcolor=lightyellow];
|
13
|
-
card_2_1 [label="Submit",fillcolor=pink];
|
14
|
-
card_2_2 [label="Ability to return to\nnew screen 1",fillcolor=lightyellow];
|
15
|
-
card_3_0 [label="Admin",fillcolor=lightblue];
|
16
|
-
card_3_1 [label="Create questions",fillcolor=pink];
|
17
|
-
card_3_2 [label="Ability to enter\nquestion 4",fillcolor=lightyellow];
|
18
|
-
card_3_3 [label="Ability to reorder\nquestion 4",fillcolor=lightyellow];
|
19
|
-
card_3_4 [label="Ability to enter\nmultiple choice\nquestion 1",fillcolor=lightyellow];
|
20
|
-
card_3_5 [label="Ability to enter\ntext question 1",fillcolor=lightyellow];
|
21
|
-
card_4_2 [label="Ability to enter\nlong text question\n1",fillcolor=lightyellow];
|
22
|
-
card_4_3 [label="Ability to enter\nlist question 2",fillcolor=lightyellow];
|
23
|
-
card_5_1 [label="Compile votes",fillcolor=pink];
|
24
|
-
card_5_2 [label="Ability to see\nresults in\nspreadsheet 4",fillcolor=lightyellow];
|
25
|
-
card_5_3 [label="Ability to see\nsummary of results\nThis includes\npercentage of each\nquestion answering\nwhich answer 2",fillcolor=lightyellow];
|
26
|
-
card_6_1 [label="Announce winners",fillcolor=pink];
|
27
|
-
gap_1_0 [style=invis];
|
28
|
-
gap_2_0 [style=invis];
|
29
|
-
gap_4_0 [style=invis];
|
30
|
-
gap_4_1 [style=invis];
|
31
|
-
gap_5_0 [style=invis];
|
32
|
-
gap_6_0 [style=invis];
|
33
|
-
{rank=same; card_0_0; gap_1_0; gap_2_0; card_3_0; gap_4_0; gap_5_0; gap_6_0};
|
34
|
-
{rank=same; card_0_1; card_1_1; card_2_1; card_3_1; gap_4_1; card_5_1; card_6_1};
|
35
|
-
{rank=same; card_0_2; card_1_2; card_2_2; card_3_2; card_4_2; card_5_2};
|
36
|
-
card_0_0 -> gap_1_0;
|
37
|
-
gap_1_0 -> gap_2_0;
|
38
|
-
gap_2_0 -> card_3_0;
|
39
|
-
card_3_0 -> gap_4_0;
|
40
|
-
gap_4_0 -> gap_5_0;
|
41
|
-
gap_5_0 -> gap_6_0;
|
42
|
-
card_0_0 -> card_0_1;
|
43
|
-
card_0_1 -> card_0_2;
|
44
|
-
card_0_2 -> card_0_3;
|
45
|
-
card_0_3 -> card_0_4;
|
46
|
-
gap_1_0 -> card_1_1;
|
47
|
-
card_1_1 -> card_1_2;
|
48
|
-
card_1_2 -> card_1_3;
|
49
|
-
gap_2_0 -> card_2_1;
|
50
|
-
card_2_1 -> card_2_2;
|
51
|
-
card_3_0 -> card_3_1;
|
52
|
-
card_3_1 -> card_3_2;
|
53
|
-
card_3_2 -> card_3_3;
|
54
|
-
card_3_3 -> card_3_4;
|
55
|
-
card_3_4 -> card_3_5;
|
56
|
-
gap_4_0 -> gap_4_1;
|
57
|
-
gap_4_1 -> card_4_2;
|
58
|
-
card_4_2 -> card_4_3;
|
59
|
-
gap_5_0 -> card_5_1;
|
60
|
-
card_5_1 -> card_5_2;
|
61
|
-
card_5_2 -> card_5_3;
|
62
|
-
gap_6_0 -> card_6_1;
|
63
|
-
}
|
@@ -1 +0,0 @@
|
|
1
|
-
????????
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,16 +0,0 @@
|
|
1
|
-
Role,Task,Story,Note,Estimate
|
2
|
-
Voter,Vote on question,Ability to see question,,1
|
3
|
-
,,Ability to see choices,,1
|
4
|
-
,,Ability to choose,This is the server trip,2
|
5
|
-
,Navigate questions,Ability to continue to next / prev,,1
|
6
|
-
,,Ability to see list of questions,This includes ability to jump to that question,4
|
7
|
-
,Submit,Ability to return to new screen,,1
|
8
|
-
Admin,Create questions,Ability to enter question,,4
|
9
|
-
,,Ability to reorder question,,4
|
10
|
-
,,Ability to enter multiple choice question,,1
|
11
|
-
,,Ability to enter text question,,1
|
12
|
-
,,Ability to enter long text question,,1
|
13
|
-
,,Ability to enter list question,,2
|
14
|
-
,Compile votes,Ability to see results in spreadsheet,,4
|
15
|
-
,,Ability to see summary of results,This includes percentage of each question answering which answer,2
|
16
|
-
,Announce winners,,,
|