Showing 5 changed files with 130 additions and 17 deletions
+2 -1
lib/Gitprep.pm
... ...
@@ -431,7 +431,8 @@ sub startup {
431 431
             $r->get('/issues' => sub { shift->render_maybe('/issues') })->to(tab => 'issues');
432 432
 
433 433
             # New issue
434
-            $r->get('/issues/new' => sub { shift->render_maybe('/issues/new') })->to(tab => 'issues');
434
+            $r->any('/issues/new' => sub { shift->render_maybe('/issues/new') })->to(tab => 'issues');
435
+            $r->get('/issues/:number' => sub { shift->render_maybe('/issue') })->to(tab => 'issues');
435 436
             
436 437
             # Pull requests
437 438
             $r->get('/pulls' => sub { shift->render_maybe('/pulls') })->to(tab => 'pulls');
+1 -1
templates/include/header.html.ep
... ...
@@ -124,7 +124,7 @@
124 124
               <li class="<%= $tab eq 'issues' ? 'active' :  '' %>">
125 125
                 <a href="<%= url_for("/$user_id/$project_id/issues") %>">
126 126
                   <i class="icon-tasks"></i>
127
-                  Issue
127
+                  Issues
128 128
                 </a>
129 129
               </li>
130 130
               <li class="<%= $tab eq 'pulls' ? 'active' :  '' %>">
+18
templates/issue.html.ep
... ...
@@ -0,0 +1,18 @@
1
+<%
2
+  # API
3
+  my $api = gitprep_api;
4
+
5
+  # Parameters
6
+  my $user_id = param('user');
7
+  my $project_id = param('project');
8
+  my $issue_number = param('number');
9
+
10
+  layout 'common', title => "Issue - $user_id/$project_id #$issue_number";
11
+%>
12
+
13
+%= include '/include/header';
14
+
15
+<div class="container">
16
+</div>
17
+
18
+%= include '/include/footer';
+1 -1
templates/issues.html.ep
... ...
@@ -75,7 +75,7 @@
75 75
               %>
76 76
               <li>
77 77
                 <div class="pulls-title">
78
-                  <a href="<%= "/$user_id/$project_id/pull/$issue->{number}" %>">
78
+                  <a href="<%= "/$user_id/$project_id/issues/$issue->{number}" %>">
79 79
                     <b><%= $issue->{title} %></b>
80 80
                   </a>
81 81
                 </div>
+108 -14
templates/issues/new.html.ep
... ...
@@ -6,20 +6,114 @@
6 6
   my $user_id = param('user');
7 7
   my $project_id = param('project');
8 8
   my $issue_number = param('number');
9
+  
10
+  my $errors;
11
+  if (lc $self->req->method eq 'post') {
12
+    my $op = param('op');
9 13
 
14
+    if ($op eq 'create') {
15
+      
16
+      # Parameters
17
+      my $title = param('title');
18
+      my $message = param('message');
19
+      
20
+      # Validation
21
+      my $vc = app->vc;
22
+      my $validation = $vc->validation;
23
+      
24
+      # Check title
25
+      if (!(defined $title && length $title)) {
26
+        $validation->add_failed(title => 'title is empty');
27
+      }
28
+      elsif (length $title > 300) {
29
+        $validation->add_failed(title => 'title is too long');
30
+      }
31
+      
32
+      # Message
33
+      if (!(defined $message && length $message)) {
34
+        $message = '';
35
+        if (length $message > 1000) {
36
+          $validation->add_failed(message => 'message is too long');
37
+        }
38
+      }
39
+      
40
+      if ($validation->is_valid) {
41
+        my $project_row_id = app->dbi->model('project')->select(
42
+          'project.row_id',
43
+          where => {'user.id' => $user_id, 'project.id' => $project_id}
44
+        )->value;
45
+        
46
+        my $issue;
47
+        my $now_tm = Time::Moment->now_utc;
48
+        my $now_epoch = $now_tm->epoch;
49
+        my $session_user_row_id = $api->session_user_row_id;
50
+        my $issue_number;
51
+        
52
+        app->dbi->connector->txn(sub {
53
+
54
+          # issue number
55
+          $issue_number = app->dbi->model('issue')->select(
56
+            'max(number)',
57
+            where => {project => $project_row_id},
58
+            append => 'group by project'
59
+          )->value;
60
+          $issue_number++;
61
+          
62
+          # New issue
63
+          my $new_issue = {
64
+            title => $title,
65
+            open => 1,
66
+            open_time => $now_epoch,
67
+            open_user => $session_user_row_id,
68
+            pull_request => 0,
69
+            project => $project_row_id,
70
+            number => $issue_number
71
+          };
72
+          app->dbi->model('issue')->insert($new_issue);
73
+          my $new_issue_row_id = app->dbi->execute("select LAST_INSERT_ROWID()")->value;
74
+          
75
+          # New issue message
76
+          my $new_issue_message = {
77
+            issue => $new_issue_row_id,
78
+            number => 1,
79
+            message => $message,
80
+            create_time => $now_epoch,
81
+            update_time => $now_epoch,
82
+            user => $session_user_row_id
83
+          };
84
+          
85
+          app->dbi->model('issue_message')->insert($new_issue_message);
86
+        });
87
+        
88
+        $self->redirect_to("/$user_id/$project_id/issues/$issue_number");
89
+        return;
90
+      }
91
+      else {
92
+        $errors = $validation->messages;
93
+      }
94
+    }
95
+  }
96
+  
10 97
   layout 'common', title => "New issue - $user_id/$project_id";
11 98
 %>
12
-    <div class="compare-open-pull-request">
13
-      <form action="<%= url_for %>" method="post">
14
-        <%= hidden_field op => 'create-pull-request' %>
15
-        <div class="compare-open-pull-request-title">
16
-          <%= text_field 'title' %>
17
-        </div>
18
-        <div class="compare-open-pull-request-message">
19
-          <%= text_area 'message' %>
20
-        </div>
21
-        <div class="compare-open-pull-request-button">
22
-          <%= submit_button 'Create pull request', class => 'btn btn-success' %>
23
-        </div>
24
-      </form>
25
-    </div>
99
+
100
+%= include '/include/header';
101
+<div class="container">
102
+  %= include '/include/errors', errors => $errors;
103
+  <div class="compare-open-pull-request">
104
+    <form action="<%= url_for %>" method="post">
105
+      <%= hidden_field op => 'create' %>
106
+      <div class="compare-open-pull-request-title">
107
+        <%= text_field 'title' %>
108
+      </div>
109
+      <div class="compare-open-pull-request-message">
110
+        <%= text_area 'message' %>
111
+      </div>
112
+      <div class="compare-open-pull-request-button">
113
+        <%= submit_button 'Submit new issue', class => 'btn btn-success' %>
114
+      </div>
115
+    </form>
116
+  </div>
117
+</div>
118
+
119
+%= include '/include/footer';