fs-ticket 0.0.0 → 0.0.1

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 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