fs-ticket 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 146341c184c747b654b08d7e1c7145d410a2b2e4
4
- data.tar.gz: 083d0e74aa12dd6b04774eb0a6253cdc4e398b3e
3
+ metadata.gz: 5e61f73a9d7829488435431894b0c726b5206df2
4
+ data.tar.gz: f7f457a9174d871a59fdfb4d59a1fe888bbd1301
5
5
  SHA512:
6
- metadata.gz: d0f40c88ca36c2b2f5740b4e2f4eed5823043d113eac98b3569f0e482266993abcd865bc16fcc0ac2eff600b84e4bec31a17fb1d430109dd064fbb97ef8fc1be
7
- data.tar.gz: 7736fb517c07a77a01ef7401d427fad364c1247ffd5c3e20fea11dacca7015b057da5bc4c246d27e909e69fcbf1f167335b8582ee483a14d110dd6c7a5ee17e2
6
+ metadata.gz: 9c73ddb25eafc4c972febdc33d9a5fba94f83cdcac99bf6f81ea79f99e078c5ff4b31e719237052816b25a42f90a6a3b0b7476679b5de5cf39ff41d00ffe9ca5
7
+ data.tar.gz: 06ac829e5ac908c93c8d9479fe2794665fd1d8341c00fb07c6aa89ebe003ff2cb2c9a3ef56dedf6d36bbec77c8c8514d1255458a260281fb251c34d62b2f2b4c
data/lib/render.rb CHANGED
@@ -8,6 +8,7 @@ require_relative "widget/button-widget.rb"
8
8
  require_relative "view/report-view.rb"
9
9
  require_relative "view/ticket-view.rb"
10
10
  require_relative "view/add-ticket-view.rb"
11
+ require_relative "view/edit-ticket-view.rb"
11
12
 
12
13
 
13
14
  #Curses render
data/lib/ticket.rb CHANGED
@@ -2,9 +2,7 @@ class Ticket
2
2
  def initialize(database, id)
3
3
  @db = database
4
4
  @ticketid = id
5
- @title = nil
6
- @status = nil
7
- @comments = nil
5
+ refresh
8
6
  end
9
7
 
10
8
  def select(field)
@@ -60,6 +58,10 @@ class Ticket
60
58
  def priority
61
59
  @priority ||= select("priority")
62
60
  end
61
+
62
+ def resolution
63
+ @resolution ||= select("resolution")
64
+ end
63
65
 
64
66
 
65
67
  def resolve
@@ -69,6 +71,20 @@ class Ticket
69
71
  end
70
72
  end
71
73
 
74
+ def id
75
+ @ticketid
76
+ end
77
+
78
+ def refresh
79
+ @title = nil
80
+ @status = nil
81
+ @type = nil
82
+ @subsystem = nil
83
+ @priority = nil
84
+ @resolution = nil
85
+ @comments = nil
86
+ end
87
+
72
88
  def match(regex)
73
89
  (comments && comments.match(regex)) || (title && title.match(regex))
74
90
  end
@@ -19,7 +19,7 @@ class AddTicketView
19
19
  @screen.clear
20
20
  @screen.setpos(0,0)
21
21
  @screen.attron(Curses.color_pair(1));
22
- @screen.addstr("Issue Creation")
22
+ @screen.addstr("Issue Creation - [e]dit (with vim)")
23
23
  @screen.attroff(Curses.color_pair(1));
24
24
 
25
25
 
@@ -64,9 +64,6 @@ class AddTicketView
64
64
  when ?\t, 9
65
65
  changeActive (@active_id + 1) % @widgets.length
66
66
  display
67
- when ?e
68
- edit
69
- display
70
67
  else
71
68
  if(!@widgets[@active_id].handle(c))
72
69
  if(c == Curses::KEY_UP)
@@ -75,6 +72,9 @@ class AddTicketView
75
72
  elsif(c == Curses::KEY_DOWN)
76
73
  changeActive @active_id + 1
77
74
  display
75
+ elsif(c == ?e)
76
+ edit
77
+ display
78
78
  else
79
79
  @screen.setpos(0,0)
80
80
  @screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
@@ -0,0 +1,129 @@
1
+ class AddTicketView
2
+ def initialize(screen)
3
+ @screen = screen
4
+ @props = Hash.new
5
+ @title = TextLineWidget.new(@screen, "", 11, 1, 30)
6
+ @priort = DropdownWidget.new(@screen, "Zero", 11, 2, 30)
7
+ @type = DropdownWidget.new(@screen, "Unclassified", 11, 3, 30)
8
+ @desc = TextFieldWidget.new(@screen, "", 0, 5, 78, 14)
9
+ @cancel = ButtonWidget.new(@screen, "Cancel", 20, 20)
10
+ @submit = ButtonWidget.new(@screen, "Submit", 0, 20)
11
+ @priort.options = %w{Zero Low Medium High Immediate}
12
+ @type.options = %w{Incident Code_Defect Build_Problem Documentation Feature_Request}
13
+ @widgets = [@title, @priort, @type, @desc, @submit, @cancel]
14
+ @title.active = true
15
+ @active_id = 0
16
+ end
17
+
18
+ def display
19
+ @screen.clear
20
+ @screen.setpos(0,0)
21
+ @screen.attron(Curses.color_pair(1));
22
+ @screen.addstr("Issue Creation - [e]dit (with vim)")
23
+ @screen.attroff(Curses.color_pair(1));
24
+
25
+
26
+ @screen.setpos(1,0)
27
+ @screen.addstr("Title:")
28
+ @screen.setpos(2,0)
29
+ @screen.addstr("Priority:")
30
+ @screen.setpos(3,0)
31
+ @screen.addstr("Type:")
32
+ @screen.setpos(4,0)
33
+ @screen.addstr("Description:")
34
+
35
+ ln = 6
36
+ @widgets.each_with_index do |w, idx|
37
+ if(idx != @active_id)
38
+ w.draw
39
+ end
40
+ end
41
+
42
+ #Draw the active widget last as it might have an overlay
43
+ @widgets[@active_id].draw
44
+ end
45
+
46
+ def changeActive(a)
47
+ a = [a,0].max
48
+ a = [a,@widgets.length-1].min
49
+
50
+ if(@active_id != a)
51
+ @widgets[@active_id].active = false
52
+ @active_id = a
53
+ @widgets[@active_id].active = true
54
+ end
55
+ end
56
+
57
+ def interact
58
+ while true
59
+ result = true
60
+ c = Curses.getch
61
+ case c
62
+ when 27
63
+ break
64
+ when ?\t, 9
65
+ changeActive (@active_id + 1) % @widgets.length
66
+ display
67
+ else
68
+ if(!@widgets[@active_id].handle(c))
69
+ if(c == Curses::KEY_UP)
70
+ changeActive @active_id - 1
71
+ display
72
+ elsif(c == Curses::KEY_DOWN)
73
+ changeActive @active_id + 1
74
+ display
75
+ elsif(c == ?e)
76
+ edit
77
+ display
78
+ else
79
+ @screen.setpos(0,0)
80
+ @screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
81
+ end
82
+ else
83
+ if((c == "\n" || c == 13) && @submit == @widgets[@active_id])
84
+ `fossil ticket add title '#{@title.value}' priority '#{@priort.value}' type '#{@type.value}' icomment '#{@desc.value}' status Open`
85
+ return :do_refresh
86
+ elsif((c == "\n" || c == 13) && @cancel == @widgets[@active_id])
87
+ break
88
+ else
89
+ display
90
+ end
91
+ end
92
+ end
93
+ @screen.setpos(0,0)
94
+ end
95
+ end
96
+
97
+ def edit
98
+ tmp = File.open("fs-ticket-edit.yaml", "w+")
99
+ tmp.puts({"title" => @title.value,
100
+ "priority" => @priort.value,
101
+ "type" => @type.value,
102
+ "description" => @desc.value}.to_yaml)
103
+ tmp.close
104
+
105
+ system("vim fs-ticket-edit.yaml")
106
+
107
+ #Restore curses options
108
+ Curses.raw
109
+ Curses.nonl
110
+ #Curses.cbreak
111
+ Curses.noecho
112
+ Curses.curs_set(0)
113
+ @screen.scrollok(true)
114
+ @screen.keypad(true)
115
+
116
+ begin
117
+ tmp = File.open("fs-ticket-edit.yaml", "r")
118
+ yy = YAML.load(tmp.read)
119
+ tmp.close
120
+ @title.value = yy["title"]
121
+ @priort.value = yy["priority"]
122
+ @type.value = yy["type"]
123
+ @desc.value = yy["description"]
124
+
125
+ #Later these editing errors should be handled correctly
126
+ #rescue Exception=>e
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,155 @@
1
+ class EditTicketView
2
+ attr_accessor :status
3
+
4
+ def initialize(screen, ticket)
5
+ @screen = screen
6
+ @ticket = ticket
7
+ @props = Hash.new
8
+ @title = TextLineWidget.new(@screen, @ticket.title, 11, 1, 30)
9
+ @priort = DropdownWidget.new(@screen, @ticket.priority, 11, 2, 30)
10
+ @type = DropdownWidget.new(@screen, @ticket.type, 11, 3, 30)
11
+ @status = DropdownWidget.new(@screen, @ticket.status, 11, 4, 30)
12
+ @resolv = DropdownWidget.new(@screen, @ticket.resolution, 11, 5, 30)
13
+ @desc = TextFieldWidget.new(@screen, "", 0, 7, 78, 12)
14
+ @cancel = ButtonWidget.new(@screen, "Cancel", 20, 20)
15
+ @submit = ButtonWidget.new(@screen, "Submit", 0, 20)
16
+ @priort.options = %w{Zero Low Medium High Immediate}
17
+ @type.options = %w{Incident Code_Defect Build_Problem Documentation Feature_Request}
18
+ @status.options = %w{Open Verified Review Deferred Fixed Tested Closed}
19
+ @resolv.options= %w{Open Fixed Rejected Workaround Unable_To_Reproduce Works_As_Designed External_Bug Not_A_Bug Duplicate Overcome_By_Events Drive_By_Patch Misconfiguration}
20
+
21
+ @widgets = [@title, @priort, @type, @status, @resolv, @desc, @submit, @cancel]
22
+ @title.active = true
23
+ @active_id = 0
24
+
25
+ @title.value = @ticket.title
26
+ @priort.value = @ticket.priority
27
+ @type.value = @ticket.type
28
+ @status.value = @ticket.status
29
+ @resolv.value = @ticket.resolution
30
+ end
31
+
32
+ def display
33
+ @screen.clear
34
+ @screen.setpos(0,0)
35
+ @screen.attron(Curses.color_pair(1));
36
+ @screen.addstr("Issue Edit Window - [e]dit (in vim)")
37
+ @screen.attroff(Curses.color_pair(1));
38
+
39
+
40
+ @screen.setpos(1,0)
41
+ @screen.addstr("Title:")
42
+ @screen.setpos(2,0)
43
+ @screen.addstr("Priority:")
44
+ @screen.setpos(3,0)
45
+ @screen.addstr("Type:")
46
+ @screen.setpos(4,0)
47
+ @screen.addstr("Status:")
48
+ @screen.setpos(5,0)
49
+ @screen.addstr("Resolution:")
50
+ @screen.setpos(6,0)
51
+ @screen.addstr("Comment:")
52
+
53
+ ln = 7
54
+ @widgets.each_with_index do |w, idx|
55
+ if(idx != @active_id)
56
+ w.draw
57
+ end
58
+ end
59
+
60
+ #Draw the active widget last as it might have an overlay
61
+ @widgets[@active_id].draw
62
+ end
63
+
64
+ def changeActive(a)
65
+ a = [a,0].max
66
+ a = [a,@widgets.length-1].min
67
+
68
+ if(@active_id != a)
69
+ @widgets[@active_id].active = false
70
+ @active_id = a
71
+ @widgets[@active_id].active = true
72
+ end
73
+ end
74
+
75
+ def interact
76
+ while true
77
+ result = true
78
+ c = Curses.getch
79
+ case c
80
+ when 27
81
+ break
82
+ when ?\t, 9
83
+ changeActive (@active_id + 1) % @widgets.length
84
+ display
85
+ else
86
+ if(!@widgets[@active_id].handle(c))
87
+ if(c == Curses::KEY_UP)
88
+ changeActive @active_id - 1
89
+ display
90
+ elsif(c == Curses::KEY_DOWN)
91
+ changeActive @active_id + 1
92
+ display
93
+ elsif(c == ?e)
94
+ edit
95
+ display
96
+ else
97
+ @screen.setpos(0,0)
98
+ @screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
99
+ end
100
+ else
101
+ if((c == "\n" || c == 13) && @submit == @widgets[@active_id])
102
+ `fossil ticket set #{@ticket.id} title '#{@title.value}' priority '#{@priort.value}' type '#{@type.value}' status '#{@status.value}' resolution '#{@resolv.value}'`
103
+ if(!@desc.value.empty?)
104
+ `fossil ticket set #{@ticket.id} icomment '#{@desc.value}'`
105
+ end
106
+ @ticket.refresh
107
+ return :do_refresh
108
+ elsif((c == "\n" || c == 13) && @cancel == @widgets[@active_id])
109
+ break
110
+ else
111
+ display
112
+ end
113
+ end
114
+ end
115
+ @screen.setpos(0,0)
116
+ end
117
+ end
118
+
119
+ def edit
120
+ tmp = File.open("fs-ticket-edit.yaml", "w+")
121
+ tmp.puts({"title" => @title.value,
122
+ "priority" => @priort.value,
123
+ "type" => @type.value,
124
+ "status" => @status.value,
125
+ "resolution" => @resolv.value,
126
+ "comment" => @desc.value}.to_yaml)
127
+ tmp.close
128
+
129
+ system("vim fs-ticket-edit.yaml")
130
+
131
+ #Restore curses options
132
+ Curses.raw
133
+ Curses.nonl
134
+ #Curses.cbreak
135
+ Curses.noecho
136
+ Curses.curs_set(0)
137
+ @screen.scrollok(true)
138
+ @screen.keypad(true)
139
+
140
+ begin
141
+ tmp = File.open("fs-ticket-edit.yaml", "r")
142
+ yy = YAML.load(tmp.read)
143
+ tmp.close
144
+ @title.value = yy["title"]
145
+ @priort.value = yy["priority"]
146
+ @type.value = yy["type"]
147
+ @status.value = yy["status"]
148
+ @resolv.value = yy["resolution"]
149
+ @desc.value = yy["description"]
150
+
151
+ #Later these editing errors should be handled correctly
152
+ #rescue Exception=>e
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,155 @@
1
+ class EditTicketView
2
+ attr_accessor :status
3
+
4
+ def initialize(screen, ticket)
5
+ @screen = screen
6
+ @ticket = ticket
7
+ @props = Hash.new
8
+ @title = TextLineWidget.new(@screen, @ticket.title, 11, 1, 30)
9
+ @priort = DropdownWidget.new(@screen, @ticket.priority, 11, 2, 30)
10
+ @type = DropdownWidget.new(@screen, @ticket.type, 11, 3, 30)
11
+ @status = DropdownWidget.new(@screen, @ticket.status, 11, 4, 30)
12
+ @resolv = DropdownWidget.new(@screen, @ticket.resolution, 11, 5, 30)
13
+ @desc = TextFieldWidget.new(@screen, "", 0, 7, 78, 12)
14
+ @cancel = ButtonWidget.new(@screen, "Cancel", 20, 20)
15
+ @submit = ButtonWidget.new(@screen, "Submit", 0, 20)
16
+ @priort.options = %w{Zero Low Medium High Immediate}
17
+ @type.options = %w{Incident Code_Defect Build_Problem Documentation Feature_Request}
18
+ @status.options = %w{Open Verified Review Deferred Fixed Tested Closed}
19
+ @resolv.options= %w{Open Fixed Rejected Workaround Unable_To_Reproduce Works_As_Designed External_Bug Not_A_Bug Duplicate Overcome_By_Events Drive_By_Patch Misconfiguration}
20
+
21
+ @widgets = [@title, @priort, @type, @status, @resolv, @desc, @submit, @cancel]
22
+ @title.active = true
23
+ @active_id = 0
24
+
25
+ @title.value = @ticket.title
26
+ @priort.value = @ticket.priority
27
+ @type.value = @ticket.type
28
+ @status.value = @ticket.status
29
+ @resolv.value = @ticket.resolution
30
+ end
31
+
32
+ def display
33
+ @screen.clear
34
+ @screen.setpos(0,0)
35
+ @screen.attron(Curses.color_pair(1));
36
+ @screen.addstr("Issue Edit Window - [e]dit (in vim)")
37
+ @screen.attroff(Curses.color_pair(1));
38
+
39
+
40
+ @screen.setpos(1,0)
41
+ @screen.addstr("Title:")
42
+ @screen.setpos(2,0)
43
+ @screen.addstr("Priority:")
44
+ @screen.setpos(3,0)
45
+ @screen.addstr("Type:")
46
+ @screen.setpos(4,0)
47
+ @screen.addstr("Status:")
48
+ @screen.setpos(5,0)
49
+ @screen.addstr("Resolution:")
50
+ @screen.setpos(6,0)
51
+ @screen.addstr("Comment:")
52
+
53
+ ln = 7
54
+ @widgets.each_with_index do |w, idx|
55
+ if(idx != @active_id)
56
+ w.draw
57
+ end
58
+ end
59
+
60
+ #Draw the active widget last as it might have an overlay
61
+ @widgets[@active_id].draw
62
+ end
63
+
64
+ def changeActive(a)
65
+ a = [a,0].max
66
+ a = [a,@widgets.length-1].min
67
+
68
+ if(@active_id != a)
69
+ @widgets[@active_id].active = false
70
+ @active_id = a
71
+ @widgets[@active_id].active = true
72
+ end
73
+ end
74
+
75
+ def interact
76
+ while true
77
+ result = true
78
+ c = Curses.getch
79
+ case c
80
+ when 27
81
+ break
82
+ when ?\t, 9
83
+ changeActive (@active_id + 1) % @widgets.length
84
+ display
85
+ else
86
+ if(!@widgets[@active_id].handle(c))
87
+ if(c == Curses::KEY_UP)
88
+ changeActive @active_id - 1
89
+ display
90
+ elsif(c == Curses::KEY_DOWN)
91
+ changeActive @active_id + 1
92
+ display
93
+ elsif(c == ?e)
94
+ edit
95
+ display
96
+ else
97
+ @screen.setpos(0,0)
98
+ @screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
99
+ end
100
+ else
101
+ if((c == "\n" || c == 13) && @submit == @widgets[@active_id])
102
+ `fossil ticket set #{@ticket.id} title '#{@title.value}' priority '#{@priort.value}' type '#{@type.value}' status '#{@status.value}' resolution '#{@resolv.value}'`
103
+ if(!@desc.value.empty?)
104
+ `fossil ticket set #{@ticket.id} icomment '#{@desc.value}'`
105
+ end
106
+ @ticket.refresh
107
+ return :do_refresh
108
+ elsif((c == "\n" || c == 13) && @cancel == @widgets[@active_id])
109
+ break
110
+ else
111
+ display
112
+ end
113
+ end
114
+ end
115
+ @screen.setpos(0,0)
116
+ end
117
+ end
118
+
119
+ def edit
120
+ tmp = File.open("fs-ticket-edit.yaml", "w+")
121
+ tmp.puts({"title" => @title.value,
122
+ "priority" => @priort.value,
123
+ "type" => @type.value,
124
+ "status" => @status.value,
125
+ "resolution" => @resolv.value,
126
+ "comment" => @desc.value}.to_yaml)
127
+ tmp.close
128
+
129
+ system("vim fs-ticket-edit.yaml")
130
+
131
+ #Restore curses options
132
+ Curses.raw
133
+ Curses.nonl
134
+ #Curses.cbreak
135
+ Curses.noecho
136
+ Curses.curs_set(0)
137
+ @screen.scrollok(true)
138
+ @screen.keypad(true)
139
+
140
+ begin
141
+ tmp = File.open("fs-ticket-edit.yaml", "r")
142
+ yy = YAML.load(tmp.read)
143
+ tmp.close
144
+ @title.value = yy["title"]
145
+ @priort.value = yy["priority"]
146
+ @type.value = yy["type"]
147
+ @status.value = yy["status"]
148
+ @resolv.value = yy["resolution"]
149
+ @desc.value = yy["description"]
150
+
151
+ #Later these editing errors should be handled correctly
152
+ #rescue Exception=>e
153
+ end
154
+ end
155
+ end
@@ -66,7 +66,7 @@ class ReportView
66
66
 
67
67
  @screen.setpos(0,0)
68
68
  @screen.attron(Curses.color_pair(1));
69
- @screen.addstr("Issue Overview - [a]dd new issue, [t]oggle open issues, [q]uit")
69
+ @screen.addstr("Issue Overview - [a]dd new issue, [t]oggle open issues, [q]uit, [/]search")
70
70
  @screen.attroff(Curses.color_pair(1));
71
71
 
72
72
  start = 0
@@ -0,0 +1,170 @@
1
+ class ReportView
2
+ def initialize(screen, tickets, block)
3
+ @screen = screen
4
+ @mode = :all
5
+ @real_tickets = tickets
6
+ @tickets = tickets
7
+ @refresh = block
8
+ @highlight = 0
9
+ display_lines
10
+ end
11
+
12
+ def refresh
13
+ @real_tickets = @refresh.call
14
+ toggle_open_tickets
15
+ toggle_open_tickets
16
+ end
17
+
18
+ def toggle_open_tickets
19
+ @highlight = 0
20
+ if(@mode == :all)
21
+ @tickets = []
22
+ @real_tickets.each do |t|
23
+ if(t.status == "Open")
24
+ @tickets << t
25
+ end
26
+ end
27
+ @mode = :open
28
+ elsif(@mode == :open || @mode == :search)
29
+ @tickets = @real_tickets
30
+ @mode = :all
31
+ end
32
+ display_lines
33
+ end
34
+
35
+ def run_search(term)
36
+ @highlight = 0
37
+ @tickets = []
38
+ @real_tickets.each do |t|
39
+ if(t.match term)
40
+ @tickets << t
41
+ end
42
+ end
43
+ @mode = :search
44
+ display_lines
45
+ end
46
+
47
+ def search
48
+ label = TextLineWidget.new(@screen, "search: ", 0, @screen.maxy-1, 40)
49
+ line = TextLineWidget.new(@screen, "", 10, @screen.maxy-1, 40)
50
+ label.draw
51
+ line.draw
52
+ while true
53
+ c = Curses.getch
54
+ if(c == "\n" || !line.handle(c))
55
+ run_search(line.value)
56
+ break
57
+ else
58
+ label.draw
59
+ line.draw
60
+ end
61
+ end
62
+ end
63
+
64
+ def display_lines
65
+ @screen.clear
66
+
67
+ @screen.setpos(0,0)
68
+ @screen.attron(Curses.color_pair(1));
69
+ @screen.addstr("Issue Overview - [a]dd new issue, [t]oggle open issues, [q]uit")
70
+ @screen.attroff(Curses.color_pair(1));
71
+
72
+ start = 0
73
+ ylimit = @screen.maxy-1
74
+ upper = ylimit-1
75
+ if(@highlight >= ylimit)
76
+ start = ylimit*(@highlight/ylimit).to_i
77
+ upper = start + ylimit - 1
78
+ end
79
+
80
+ if(@tickets.empty?)
81
+ return
82
+ end
83
+
84
+ @tickets[start..upper].each_with_index{|tick, idx|
85
+ line = tick.title
86
+ line_id = idx+start
87
+ @screen.setpos(idx+1, 0)
88
+ @screen.addstr(line_id.to_s+".")
89
+ @screen.setpos(idx+1, 4)
90
+ if(tick.status)
91
+ @screen.addstr("["+tick.status[0]+"]")
92
+ end
93
+ @screen.setpos(idx+1, 9)
94
+ if(@highlight == line_id)
95
+ @screen.attron Curses::A_BOLD
96
+ @screen.addstr(line)
97
+ @screen.attroff Curses::A_BOLD
98
+ else
99
+ @screen.addstr(line)
100
+ end
101
+ }
102
+ @screen.setpos(0,0)
103
+ @screen.refresh
104
+ end
105
+
106
+ def scroll_up(draw=true)
107
+ if(@highlight > 0)
108
+ @highlight -= 1
109
+ display_lines if draw
110
+ end
111
+ end
112
+
113
+ def scroll_down(draw=true)
114
+ if(@highlight < @tickets.length-1)
115
+ @highlight += 1
116
+ display_lines if draw
117
+ end
118
+ end
119
+
120
+ def interact
121
+ while true
122
+ result = true
123
+ c = Curses.getch
124
+ case c
125
+ when ?t
126
+ toggle_open_tickets
127
+ when ?a
128
+ at = AddTicketView.new(@screen)
129
+ @screen.clear
130
+ at.display
131
+ ret = at.interact
132
+ if(ret == :do_refresh)
133
+ refresh
134
+ end
135
+ @screen.clear
136
+ display_lines
137
+ when Curses::KEY_DOWN, Curses::KEY_CTRL_N, ?j
138
+ result = scroll_down
139
+ when Curses::KEY_UP, Curses::KEY_CTRL_P, ?k
140
+ result = scroll_up
141
+ when Curses::KEY_NPAGE, ?\s # white space
142
+ for i in 0..(@screen.maxy - 2)
143
+ scroll_down(false)
144
+ end
145
+ display_lines
146
+ when Curses::KEY_PPAGE
147
+ for i in 0..(@screen.maxy - 2)
148
+ scroll_up(false)
149
+ end
150
+ display_lines
151
+ when Curses::KEY_RIGHT, Curses::KEY_ENTER, ?\n, 13
152
+ tv = TicketView.new(@screen, @tickets[@highlight])
153
+ @screen.clear
154
+ tv.display
155
+ ret = tv.interact
156
+ @screen.clear
157
+ display_lines
158
+ when "/"
159
+ search
160
+ when ?q
161
+ break
162
+ else
163
+ @screen.setpos(0,0)
164
+ @screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
165
+ end
166
+ @screen.setpos(0,0)
167
+ end
168
+ Curses.close_screen
169
+ end
170
+ end
@@ -10,7 +10,7 @@ class TicketView
10
10
  @screen.clear
11
11
  @screen.setpos(0,0)
12
12
  @screen.attron(Curses.color_pair(1));
13
- @screen.addstr("Issue Details - [f]ix [q]uit")
13
+ @screen.addstr("Issue Details - [f]ix, [e]dit, [q]uit")
14
14
  @screen.attroff(Curses.color_pair(1));
15
15
 
16
16
 
@@ -35,6 +35,7 @@ class TicketView
35
35
  end
36
36
 
37
37
  def interact
38
+ ret = nil
38
39
  while true
39
40
  result = true
40
41
  c = Curses.getch
@@ -44,10 +45,26 @@ class TicketView
44
45
  when ?q
45
46
  break
46
47
  when ?f
47
- @ticket.resolve
48
+ et = EditTicketView.new(@screen, @ticket)
49
+ @screen.clear
50
+ if(et.status.value == "Open")
51
+ et.status.value = "Fixed"
52
+ end
53
+ et.display
54
+ tmp = et.interact
55
+ ret ||= tmp
56
+ @screen.clear
48
57
  display
49
58
  when ?e
50
- edit
59
+ et = EditTicketView.new(@screen, @ticket)
60
+ @screen.clear
61
+ if(et.status == "Open")
62
+ et.status = "Fixed"
63
+ end
64
+ et.display
65
+ tmp = et.interact
66
+ ret ||= tmp
67
+ @screen.clear
51
68
  display
52
69
  else
53
70
  @screen.setpos(0,0)
@@ -55,6 +72,7 @@ class TicketView
55
72
  end
56
73
  @screen.setpos(0,0)
57
74
  end
75
+ ret
58
76
  end
59
77
 
60
78
  def edit
@@ -0,0 +1,98 @@
1
+ require 'yaml'
2
+
3
+ class TicketView
4
+ def initialize(screen, ticket)
5
+ @screen = screen
6
+ @ticket = ticket
7
+ end
8
+
9
+ def display
10
+ @screen.clear
11
+ @screen.setpos(0,0)
12
+ @screen.attron(Curses.color_pair(1));
13
+ @screen.addstr("Issue Details - [f]ix [q]uit")
14
+ @screen.attroff(Curses.color_pair(1));
15
+
16
+
17
+ @screen.setpos(1,0)
18
+ @screen.addstr("Title: #{@ticket.title}")
19
+ @screen.setpos(2,0)
20
+ @screen.addstr("Status: #{@ticket.status}")
21
+ @screen.setpos(3,0)
22
+ @screen.addstr("Priority: #{@ticket.priority}")
23
+ @screen.setpos(4,0)
24
+ @screen.addstr("Type: #{@ticket.type}")
25
+ @screen.setpos(5,0)
26
+ @screen.addstr("Subsystem: #{@ticket.subsystem}")
27
+ @screen.setpos(6,0)
28
+ @screen.addstr("Comments:")
29
+ ln = 7
30
+ @ticket.comments.split("\n").each do |l|
31
+ @screen.setpos(ln,0)
32
+ @screen.addstr(l)
33
+ ln += 1
34
+ end
35
+ end
36
+
37
+ def interact
38
+ ret = nil
39
+ while true
40
+ result = true
41
+ c = Curses.getch
42
+ case c
43
+ when Curses::KEY_LEFT
44
+ break
45
+ when ?q
46
+ break
47
+ when ?f
48
+ et = EditTicketView.new(@screen, @ticket)
49
+ @screen.clear
50
+ if(et.status.value == "Open")
51
+ et.status.value = "Fixed"
52
+ end
53
+ et.display
54
+ tmp = et.interact
55
+ ret ||= tmp
56
+ @screen.clear
57
+ display
58
+ when ?e
59
+ et = EditTicketView.new(@screen, @ticket)
60
+ @screen.clear
61
+ if(et.status == "Open")
62
+ et.status = "Fixed"
63
+ end
64
+ et.display
65
+ tmp = et.interact
66
+ ret ||= tmp
67
+ @screen.clear
68
+ display
69
+ else
70
+ @screen.setpos(0,0)
71
+ @screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
72
+ end
73
+ @screen.setpos(0,0)
74
+ end
75
+ ret
76
+ end
77
+
78
+ def edit
79
+ tmp = File.open("fs-ticket-edit.txt", "w+")
80
+ tmp.puts({"title" => @ticket.title,
81
+ "status" => @ticket.status,
82
+ "priority" => @ticket.priority,
83
+ "type" => @ticket.type,
84
+ "comment" => @ticket.comments}.to_yaml)
85
+ tmp.close
86
+
87
+ system("vim fs-ticket-edit.txt")
88
+
89
+ #Restore curses options
90
+ Curses.raw
91
+ Curses.nonl
92
+ #Curses.cbreak
93
+ Curses.noecho
94
+ Curses.curs_set(0)
95
+ @screen.scrollok(true)
96
+ @screen.keypad(true)
97
+ end
98
+ end
@@ -27,7 +27,9 @@ class TextFieldWidget
27
27
  end
28
28
 
29
29
  def draw
30
+ @value ||= ""
30
31
  value = @value
32
+
31
33
  if(value.empty?)
32
34
  (0..@h).each do |x|
33
35
  value += "_"*@w+"\n"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fs-ticket
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark McCurry
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-02 00:00:00.000000000 Z
11
+ date: 2015-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: curses
@@ -55,8 +55,13 @@ files:
55
55
  - lib/render.rb
56
56
  - lib/ticket.rb
57
57
  - lib/view/add-ticket-view.rb
58
+ - lib/view/add-ticket-view.rb~
59
+ - lib/view/edit-ticket-view.rb
60
+ - lib/view/edit-ticket-view.rb~
58
61
  - lib/view/report-view.rb
62
+ - lib/view/report-view.rb~
59
63
  - lib/view/ticket-view.rb
64
+ - lib/view/ticket-view.rb~
60
65
  - lib/widget/button-widget.rb
61
66
  - lib/widget/dropdown-widget.rb
62
67
  - lib/widget/text-field-widget.rb