saga 0.14.0 → 0.15
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 +4 -4
- data/lib/saga/planning.rb +19 -0
- data/lib/saga/tokenizer.rb +3 -0
- data/lib/saga/version.rb +1 -1
- data/templates/default/document.erb +178 -218
- data/templates/default/helpers.rb +29 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2cafeea9d1c74e5312fb8cd3909e06492a9f2d6b0e4d25554aaf196bfc940aff
|
|
4
|
+
data.tar.gz: a59f8478840bc9e48d99d32d76847f570f440893759c3ba95b746a46bb964a3a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ce5e4ccb1fae09c89f12bf82737f4917f1decdf109a93d739f793d28778f8b5997748d19eae7c34e147619702fe50a863f3b84ad42dbae4effb1ea880fcb3be3
|
|
7
|
+
data.tar.gz: b885628cd6d2f61c4a9a778a487ff6e1fef038f5e33ba2fbaf2e7fea9cbb02a962aea2bea12d8f88329689e69de429bd190fe38e74a0bbaf42ad9e29c4956304
|
data/lib/saga/planning.rb
CHANGED
|
@@ -48,6 +48,16 @@ module Saga
|
|
|
48
48
|
range_estimated
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
def relative_estimated
|
|
52
|
+
relative_estimated = 0
|
|
53
|
+
@document.stories_as_flat_list.each do |story|
|
|
54
|
+
if story[:estimate] && story[:estimate][1] == :relative
|
|
55
|
+
relative_estimated += 1
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
relative_estimated
|
|
59
|
+
end
|
|
60
|
+
|
|
51
61
|
def statusses
|
|
52
62
|
statusses = {}
|
|
53
63
|
@document.stories_as_flat_list.each do |story|
|
|
@@ -75,6 +85,9 @@ module Saga
|
|
|
75
85
|
parts << ''
|
|
76
86
|
parts << self.class.format_unestimated(unestimated) if unestimated > 0
|
|
77
87
|
parts << self.class.format_range_estimated(range_estimated) if range_estimated > 0
|
|
88
|
+
if relative_estimated > 0
|
|
89
|
+
parts << self.class.format_relative_estimated(relative_estimated)
|
|
90
|
+
end
|
|
78
91
|
parts << self.class.format_statusses(statusses) unless statusses.empty?
|
|
79
92
|
end
|
|
80
93
|
parts.shift if parts[0] == ''
|
|
@@ -92,6 +105,8 @@ module Saga
|
|
|
92
105
|
estimate[0] * 40
|
|
93
106
|
when :range
|
|
94
107
|
0
|
|
108
|
+
when :relative
|
|
109
|
+
0
|
|
95
110
|
else
|
|
96
111
|
estimate[0]
|
|
97
112
|
end
|
|
@@ -115,6 +130,10 @@ module Saga
|
|
|
115
130
|
"Range-estimate: #{format_stories_count(range_estimated)}"
|
|
116
131
|
end
|
|
117
132
|
|
|
133
|
+
def self.format_relative_estimated(relative_estimated)
|
|
134
|
+
"Relative : #{format_stories_count(relative_estimated)}"
|
|
135
|
+
end
|
|
136
|
+
|
|
118
137
|
def self.format_stories_count(count)
|
|
119
138
|
count > 1 ? "#{count} stories" : 'one story'
|
|
120
139
|
end
|
data/lib/saga/tokenizer.rb
CHANGED
|
@@ -54,6 +54,7 @@ module Saga
|
|
|
54
54
|
|
|
55
55
|
RE_STORY_NUMBER = /\#(\d+)/.freeze
|
|
56
56
|
RE_STORY_ITERATION = /i(\d+)/.freeze
|
|
57
|
+
RE_STORY_RELATIVE_ESTIMATE = /(trivial|easy|simple|straightforward|hard|epic)/.freeze
|
|
57
58
|
RE_STORY_ESTIMATE_PART = /(\d+)(d|w|h|)/.freeze
|
|
58
59
|
|
|
59
60
|
def self.tokenize_story_attributes(input)
|
|
@@ -70,6 +71,8 @@ module Saga
|
|
|
70
71
|
attributes[:id] = match[1].to_i
|
|
71
72
|
elsif match = RE_STORY_ITERATION.match(part)
|
|
72
73
|
attributes[:iteration] = match[1].to_i
|
|
74
|
+
elsif match = RE_STORY_RELATIVE_ESTIMATE.match(part)
|
|
75
|
+
attributes[:estimate] = [match[1], :relative]
|
|
73
76
|
elsif match = /#{RE_STORY_ESTIMATE_PART}-#{RE_STORY_ESTIMATE_PART}/.match(part)
|
|
74
77
|
estimate = "#{match[1, 2].join}-#{match[3, 2].join}"
|
|
75
78
|
attributes[:estimate] = [estimate, :range]
|
data/lib/saga/version.rb
CHANGED
|
@@ -4,250 +4,219 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<title>Requirements <%= title %></title>
|
|
6
6
|
<style>
|
|
7
|
-
|
|
7
|
+
:root
|
|
8
8
|
{
|
|
9
|
-
|
|
9
|
+
color-scheme: light dark;
|
|
10
|
+
|
|
11
|
+
--primary: hsl(232 0% 0%);
|
|
12
|
+
--background: white;
|
|
13
|
+
--done-background: hsl(232 90% 95%);
|
|
14
|
+
--dropped: hsl(232 0% 60%);
|
|
15
|
+
--target-background: hsl(40 90% 95%);
|
|
16
|
+
--border: hsl(232 0% 90%);
|
|
17
|
+
--link: hsl(232 80% 60%);
|
|
18
|
+
--link-active: hsl(232 80% 40%);
|
|
19
|
+
|
|
20
|
+
--inset-left: max(env(safe-area-inset-left), 1rem, 2.5vw);
|
|
21
|
+
--inset-right: max(env(safe-area-inset-right), 1rem, 2.5vw);
|
|
22
|
+
--inset-top: max(env(safe-area-inset-top), 1rem);
|
|
23
|
+
--inset-bottom: max(env(safe-area-inset-bottom), 1rem);
|
|
10
24
|
}
|
|
11
|
-
|
|
12
|
-
a:active
|
|
25
|
+
@media (prefers-color-scheme: dark)
|
|
13
26
|
{
|
|
14
|
-
|
|
27
|
+
:root
|
|
28
|
+
{
|
|
29
|
+
--primary: hsl(232 0% 90%);
|
|
30
|
+
--background: hsl(232 0% 10%);
|
|
31
|
+
--done-background: hsl(232 90% 10%);
|
|
32
|
+
--dropped: hsl(232 0% 40%);
|
|
33
|
+
--target-background: hsl(40 90% 10%);
|
|
34
|
+
--border: hsl(232 0% 20%);
|
|
35
|
+
--link: hsl(232 80% 70%);
|
|
36
|
+
--link-active: hsl(232 80% 60%);
|
|
37
|
+
}
|
|
15
38
|
}
|
|
16
39
|
body
|
|
17
40
|
{
|
|
18
|
-
margin: 1.5em 1em;
|
|
19
41
|
font-family: palatino, georgia, serif;
|
|
20
42
|
line-height: 1.25;
|
|
43
|
+
-webkit-text-size-adjust: none;
|
|
44
|
+
text-size-adjust: none;
|
|
45
|
+
margin: var(--inset-top) var(--inset-right) var(--inset-bottom) var(--inset-left);
|
|
46
|
+
background: var(--background);
|
|
47
|
+
color: var(--primary);
|
|
21
48
|
}
|
|
49
|
+
p,
|
|
22
50
|
h1,
|
|
23
51
|
h2,
|
|
24
|
-
h3
|
|
52
|
+
h3,
|
|
53
|
+
ul,
|
|
54
|
+
li,
|
|
55
|
+
dl,
|
|
56
|
+
dt,
|
|
57
|
+
dd
|
|
25
58
|
{
|
|
26
59
|
margin: 0;
|
|
27
|
-
|
|
28
|
-
|
|
60
|
+
padding: 0
|
|
61
|
+
}
|
|
62
|
+
h1,
|
|
63
|
+
h2,
|
|
64
|
+
h3
|
|
65
|
+
{
|
|
29
66
|
font-weight: normal;
|
|
30
67
|
}
|
|
68
|
+
h1
|
|
69
|
+
{
|
|
70
|
+
font-size: 162.5%;
|
|
71
|
+
}
|
|
31
72
|
h2
|
|
32
73
|
{
|
|
33
|
-
|
|
74
|
+
font-size: 137.5%;
|
|
34
75
|
}
|
|
35
76
|
h3
|
|
36
77
|
{
|
|
37
|
-
|
|
38
|
-
font-size: 125%;
|
|
78
|
+
font-size: 118.75%;
|
|
39
79
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
table + h3
|
|
80
|
+
h2,
|
|
81
|
+
h3
|
|
43
82
|
{
|
|
44
|
-
margin
|
|
83
|
+
margin: 2rem 0 1.25rem 0;
|
|
45
84
|
}
|
|
46
|
-
p,
|
|
47
85
|
ul
|
|
48
86
|
{
|
|
49
|
-
margin:
|
|
50
|
-
}
|
|
51
|
-
ul.authors
|
|
52
|
-
{
|
|
53
|
-
padding: 0;
|
|
54
|
-
font-style: italic;
|
|
87
|
+
margin: 1rem 0;
|
|
55
88
|
list-style-type: none;
|
|
56
|
-
|
|
89
|
+
font-style: italic;
|
|
57
90
|
}
|
|
58
|
-
|
|
91
|
+
dl
|
|
59
92
|
{
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
margin-top: -1em;
|
|
93
|
+
display: grid;
|
|
94
|
+
grid-template-columns: auto 1fr;
|
|
95
|
+
gap: 0.5rem 1rem;
|
|
96
|
+
margin: 1rem 0;
|
|
65
97
|
}
|
|
66
|
-
|
|
98
|
+
dt:after
|
|
67
99
|
{
|
|
68
|
-
|
|
100
|
+
content: ':';
|
|
69
101
|
}
|
|
70
|
-
|
|
102
|
+
a[href]
|
|
71
103
|
{
|
|
72
|
-
|
|
104
|
+
color: var(--link);
|
|
73
105
|
}
|
|
74
|
-
|
|
106
|
+
a[href]:active
|
|
75
107
|
{
|
|
76
|
-
color:
|
|
77
|
-
font-style: italic;
|
|
108
|
+
color: var(--link-active);
|
|
78
109
|
}
|
|
79
|
-
|
|
80
|
-
td
|
|
110
|
+
div.stories
|
|
81
111
|
{
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
112
|
+
display: grid;
|
|
113
|
+
grid-template-columns: fit-content(0) 1fr repeat(4, fit-content(0));
|
|
114
|
+
margin: 1rem calc(-1 * var(--inset-right)) 1rem calc(-1 * var(--inset-left));
|
|
85
115
|
}
|
|
86
|
-
|
|
87
|
-
|
|
116
|
+
h3,
|
|
117
|
+
div.stories > div.story
|
|
88
118
|
{
|
|
89
|
-
|
|
119
|
+
grid-column-start: 1;
|
|
120
|
+
grid-column-end: 6;
|
|
90
121
|
}
|
|
91
|
-
|
|
92
|
-
tr.nested td:first-child
|
|
122
|
+
div.stories > h3
|
|
93
123
|
{
|
|
94
|
-
|
|
124
|
+
margin: 1.5rem var(--inset-right) 0.75rem var(--inset-left);
|
|
95
125
|
}
|
|
96
|
-
|
|
97
|
-
td:last-child
|
|
126
|
+
div.stories > h3:first-child
|
|
98
127
|
{
|
|
99
|
-
|
|
128
|
+
margin-top: 0;
|
|
100
129
|
}
|
|
101
|
-
|
|
130
|
+
div.stories > div.story
|
|
102
131
|
{
|
|
103
|
-
|
|
132
|
+
display: grid;
|
|
133
|
+
grid-template-columns: subgrid;
|
|
134
|
+
border-top: 1px solid var(--border);
|
|
135
|
+
padding: 0.5rem;
|
|
104
136
|
}
|
|
105
|
-
|
|
137
|
+
div.stories > div.story:not(:has(+ div.story))
|
|
106
138
|
{
|
|
107
|
-
|
|
139
|
+
border-bottom: 1px solid var(--border);
|
|
108
140
|
}
|
|
109
|
-
|
|
141
|
+
div.story.done
|
|
110
142
|
{
|
|
111
|
-
|
|
143
|
+
background: var(--done-background);
|
|
112
144
|
}
|
|
113
|
-
|
|
145
|
+
div.story.dropped
|
|
114
146
|
{
|
|
115
|
-
|
|
147
|
+
color: var(--dropped);
|
|
116
148
|
}
|
|
117
|
-
|
|
149
|
+
div.story.dropped > div.content
|
|
118
150
|
{
|
|
119
|
-
text-
|
|
120
|
-
white-space: nowrap;
|
|
151
|
+
text-decoration: line-through;
|
|
121
152
|
}
|
|
122
|
-
.
|
|
153
|
+
div.story:target
|
|
123
154
|
{
|
|
124
|
-
|
|
125
|
-
text-decoration: line-through;
|
|
155
|
+
background: var(--target-background);
|
|
126
156
|
}
|
|
127
|
-
.
|
|
157
|
+
div.story > *
|
|
128
158
|
{
|
|
129
|
-
|
|
159
|
+
padding: 0 0.5rem;
|
|
130
160
|
}
|
|
131
|
-
|
|
161
|
+
div.story > *:first-child
|
|
132
162
|
{
|
|
133
|
-
|
|
163
|
+
padding-left: calc(var(--inset-right) - 0.5rem);
|
|
134
164
|
}
|
|
135
|
-
|
|
165
|
+
div.story > *:last-child
|
|
136
166
|
{
|
|
137
|
-
|
|
167
|
+
padding-right: calc(var(--inset-left) - 0.5rem);
|
|
138
168
|
}
|
|
139
|
-
|
|
169
|
+
div.story > a.id
|
|
140
170
|
{
|
|
141
|
-
|
|
171
|
+
grid-column: 1;
|
|
172
|
+
color: inherit;
|
|
173
|
+
text-decoration: none;
|
|
142
174
|
}
|
|
143
|
-
|
|
144
|
-
dd
|
|
175
|
+
div.story > div.content
|
|
145
176
|
{
|
|
146
|
-
|
|
177
|
+
grid-column: 2;
|
|
147
178
|
}
|
|
148
|
-
|
|
179
|
+
div.story > div.estimate
|
|
149
180
|
{
|
|
150
|
-
|
|
151
|
-
clear: both;
|
|
152
|
-
margin: 0;
|
|
153
|
-
padding: 0 0 0 1em;
|
|
154
|
-
font-weight: bold;
|
|
181
|
+
grid-column: 3;
|
|
155
182
|
}
|
|
156
|
-
|
|
183
|
+
div.story > div.iteration
|
|
157
184
|
{
|
|
158
|
-
|
|
185
|
+
grid-column: 4;
|
|
186
|
+
font-variant-numeric: tabular-nums;
|
|
159
187
|
}
|
|
160
|
-
|
|
188
|
+
div.story > div.status
|
|
161
189
|
{
|
|
162
|
-
|
|
163
|
-
padding: 0 1em;
|
|
164
|
-
display: block;
|
|
190
|
+
grid-column: 5;
|
|
165
191
|
}
|
|
166
|
-
@media (
|
|
167
|
-
|
|
168
|
-
{
|
|
169
|
-
margin: 2em;
|
|
170
|
-
}
|
|
171
|
-
table,
|
|
172
|
-
dl
|
|
192
|
+
@media (max-width: 25rem) {
|
|
193
|
+
div.story > div.content
|
|
173
194
|
{
|
|
174
|
-
|
|
175
|
-
margin-right: -2em;
|
|
195
|
+
grid-column: 2 / span 4;
|
|
176
196
|
}
|
|
177
|
-
|
|
178
|
-
|
|
197
|
+
div.story > div.estimate,
|
|
198
|
+
div.story > div.iteration,
|
|
199
|
+
div.story > div.status
|
|
179
200
|
{
|
|
180
|
-
padding-
|
|
181
|
-
}
|
|
182
|
-
th:last-child,
|
|
183
|
-
td:last-child
|
|
184
|
-
{
|
|
185
|
-
padding-right: 2em;
|
|
186
|
-
}
|
|
187
|
-
tr.nested th:first-child,
|
|
188
|
-
tr.nested td:first-child
|
|
189
|
-
{
|
|
190
|
-
padding-left: 4em;
|
|
191
|
-
}
|
|
192
|
-
dl
|
|
193
|
-
{
|
|
194
|
-
border-bottom: 1px solid #ddd;
|
|
195
|
-
}
|
|
196
|
-
dt
|
|
197
|
-
{
|
|
198
|
-
padding: .5em 0 0 2em;
|
|
199
|
-
border-top: none;
|
|
200
|
-
}
|
|
201
|
-
dd
|
|
202
|
-
{
|
|
203
|
-
margin: 0;
|
|
204
|
-
padding: .5em 2em .5em 20em;
|
|
205
|
-
border-top: 1px solid #ddd;
|
|
201
|
+
padding-top: 0.25rem;
|
|
206
202
|
}
|
|
207
203
|
}
|
|
208
|
-
|
|
204
|
+
div.content p:not(:first-of-type)
|
|
209
205
|
{
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
padding-left: 0;
|
|
225
|
-
}
|
|
226
|
-
tr.nested th:first-child,
|
|
227
|
-
tr.nested td:first-child
|
|
228
|
-
{
|
|
229
|
-
padding-left: 2em;
|
|
230
|
-
}
|
|
231
|
-
th:last-child,
|
|
232
|
-
td:last-child
|
|
233
|
-
{
|
|
234
|
-
padding-right: 0;
|
|
235
|
-
}
|
|
236
|
-
dl
|
|
237
|
-
{
|
|
238
|
-
border-bottom: 1px solid #ddd;
|
|
239
|
-
}
|
|
240
|
-
dt
|
|
241
|
-
{
|
|
242
|
-
padding: .5em 0 0 0;
|
|
243
|
-
border-top: none;
|
|
244
|
-
}
|
|
245
|
-
dd
|
|
246
|
-
{
|
|
247
|
-
margin: 0;
|
|
248
|
-
padding: .5em 0 .5em 40%;
|
|
249
|
-
border-top: 1px solid #ddd;
|
|
250
|
-
}
|
|
206
|
+
font-style: italic;
|
|
207
|
+
margin-top: 0.25rem;
|
|
208
|
+
}
|
|
209
|
+
div.story.nested div.content
|
|
210
|
+
{
|
|
211
|
+
padding-left: 2rem;
|
|
212
|
+
}
|
|
213
|
+
a.id,
|
|
214
|
+
div.estimate:not(.relative),
|
|
215
|
+
div.iteration
|
|
216
|
+
{
|
|
217
|
+
text-align: right;
|
|
218
|
+
white-space: nowrap;
|
|
219
|
+
font-variant-numeric: tabular-nums;
|
|
251
220
|
}
|
|
252
221
|
</style>
|
|
253
222
|
</head>
|
|
@@ -256,67 +225,58 @@ dd
|
|
|
256
225
|
<h1>Requirements <%= title %></h1>
|
|
257
226
|
|
|
258
227
|
<% unless authors.empty? %>
|
|
259
|
-
<ul
|
|
228
|
+
<ul>
|
|
260
229
|
<% authors.each do |author| %>
|
|
261
|
-
<li><%=
|
|
230
|
+
<li><%= author(author) %></li>
|
|
262
231
|
<% end %>
|
|
263
232
|
</ul>
|
|
264
233
|
<% end %>
|
|
265
234
|
|
|
266
235
|
<% introduction.each do |paragraph| %>
|
|
267
|
-
<p><%=h paragraph %></p>
|
|
236
|
+
<p><%= h paragraph %></p>
|
|
268
237
|
<% end %>
|
|
269
238
|
|
|
239
|
+
<h2>User stories</h2>
|
|
240
|
+
|
|
270
241
|
<% unless stories.empty? %>
|
|
271
|
-
<
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
<
|
|
279
|
-
|
|
280
|
-
<
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
</tr>
|
|
285
|
-
</thead>
|
|
286
|
-
<tbody>
|
|
287
|
-
<% stories.each do |story| %>
|
|
288
|
-
<tr class="<%= story[:status] %>" id="story<%= story[:id] %>">
|
|
289
|
-
<td class="story"><%=h story[:description] %></td>
|
|
290
|
-
<td class="meta id"><%=h story[:id] %></td>
|
|
291
|
-
<td class="meta estimate"><%= format_estimate(*story[:estimate]) if story[:estimate] %></td>
|
|
292
|
-
<td class="meta iteration"><%=h story[:iteration] %></td>
|
|
293
|
-
<td class="meta status"><%=h story[:status] %></td>
|
|
294
|
-
</tr>
|
|
295
|
-
<% if story[:notes] %>
|
|
296
|
-
<tr class="notes <%= story[:status] %>">
|
|
297
|
-
<td colspan="5"><%=h story[:notes] %></td>
|
|
298
|
-
</tr>
|
|
299
|
-
<% end %>
|
|
300
|
-
<% if story[:stories] %>
|
|
301
|
-
<% story[:stories].each do |nested| %>
|
|
302
|
-
<tr class="nested <%= nested[:status] %>" id="story<%= nested[:id] %>">
|
|
303
|
-
<td class="story"><%=h nested[:description] %></td>
|
|
304
|
-
<td class="meta id"><%=h nested[:id] %></td>
|
|
305
|
-
<td class="meta estimate"><%= format_estimate(*nested[:estimate]) if nested[:estimate] %></td>
|
|
306
|
-
<td class="meta iteration"><%=h nested[:iteration] %></td>
|
|
307
|
-
<td class="meta status"><%=h nested[:status] %></td>
|
|
308
|
-
</tr>
|
|
309
|
-
<% if nested[:notes] %>
|
|
310
|
-
<tr class="nested notes <%= nested[:status] %>">
|
|
311
|
-
<td colspan="5"><%=h nested[:notes] %></td>
|
|
312
|
-
</tr>
|
|
313
|
-
<% end %>
|
|
242
|
+
<div class="stories">
|
|
243
|
+
<% stories.each do |header, stories| %>
|
|
244
|
+
<% unless header.strip == '' %>
|
|
245
|
+
<h3><%= h header %></h3>
|
|
246
|
+
<% end %>
|
|
247
|
+
|
|
248
|
+
<% stories.each do |story| %>
|
|
249
|
+
<div class="story <%= story[:status] %>" id="<%= dom_story_id(story[:id]) %>">
|
|
250
|
+
<%= id(story[:id]) %>
|
|
251
|
+
<div class="content">
|
|
252
|
+
<p><%= h story[:description] %></p>
|
|
253
|
+
<% if story[:notes] %>
|
|
254
|
+
<p><%= h story[:notes] %></p>
|
|
314
255
|
<% end %>
|
|
256
|
+
</div>
|
|
257
|
+
<%= estimate(*story[:estimate]) %>
|
|
258
|
+
<%= iteration(story[:iteration]) %>
|
|
259
|
+
<%= status(story[:status]) %>
|
|
260
|
+
</div>
|
|
261
|
+
<% if story[:stories] %>
|
|
262
|
+
<% story[:stories].each do |nested| %>
|
|
263
|
+
<div class="story nested <%= nested[:status] %>" id="<%= dom_story_id(nested[:id]) %>">
|
|
264
|
+
<%= id(nested[:id]) %>
|
|
265
|
+
<div class="content">
|
|
266
|
+
<p><%= h nested[:description] %></p>
|
|
267
|
+
<% if nested[:notes] %>
|
|
268
|
+
<p><%= h nested[:notes] %></p>
|
|
269
|
+
<% end %>
|
|
270
|
+
</div>
|
|
271
|
+
<%= estimate(*nested[:estimate]) %>
|
|
272
|
+
<%= iteration(nested[:iteration]) %>
|
|
273
|
+
<%= status(nested[:status]) %>
|
|
274
|
+
</div>
|
|
315
275
|
<% end %>
|
|
316
276
|
<% end %>
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
277
|
+
<% end %>
|
|
278
|
+
<% end %>
|
|
279
|
+
</div>
|
|
320
280
|
<% end %>
|
|
321
281
|
|
|
322
282
|
<% definitions.each do |header, definitions| %>
|
|
@@ -325,8 +285,8 @@ dd
|
|
|
325
285
|
<% end %>
|
|
326
286
|
<dl>
|
|
327
287
|
<% definitions.each do |definition| %>
|
|
328
|
-
<dt><%=h definition[:title] %></dt>
|
|
329
|
-
<dd><%=h definition[:definition] %></dd>
|
|
288
|
+
<dt><%= h definition[:title] %></dt>
|
|
289
|
+
<dd><%= h definition[:definition] %></dd>
|
|
330
290
|
<% end %>
|
|
331
291
|
</dl>
|
|
332
292
|
<% end %>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
def
|
|
1
|
+
def author(author)
|
|
2
2
|
parts = []
|
|
3
3
|
parts << author[:name] if author[:name]
|
|
4
4
|
parts << "<a href=\"mailto:#{author[:email]}\">#{author[:email]}</a>" if author[:email]
|
|
@@ -24,7 +24,35 @@ def format_estimate(cardinality, interval)
|
|
|
24
24
|
pluralize(cardinality, 'day', 'days')
|
|
25
25
|
when :weeks
|
|
26
26
|
pluralize(cardinality, 'week', 'days')
|
|
27
|
+
when :relative
|
|
28
|
+
cardinality.gsub('straightforward', "straight\u00ADforward")
|
|
27
29
|
else
|
|
28
30
|
cardinality.to_s
|
|
29
31
|
end
|
|
30
32
|
end
|
|
33
|
+
|
|
34
|
+
def dom_story_id(id)
|
|
35
|
+
"story#{id}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def id(id)
|
|
39
|
+
["<a href=\"##{dom_story_id(id)}\" class=\"id\" title=\"ID\">#", id, '</a>'].join if id
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def iteration(iteration)
|
|
43
|
+
['<div class="iteration" title="Iteration">', iteration, '</div>'].join if iteration
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def status(status)
|
|
47
|
+
['<div class="status" title="Status">', status, '</div>'].join if status
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def estimate(cardinality = nil, interval = nil)
|
|
51
|
+
if cardinality
|
|
52
|
+
[
|
|
53
|
+
"<div class=\"estimate #{interval}\" title=\"Estimate\">",
|
|
54
|
+
format_estimate(cardinality, interval),
|
|
55
|
+
'</div>'
|
|
56
|
+
].join
|
|
57
|
+
end
|
|
58
|
+
end
|