name varchar not null,
PRIMARY KEY (id)
);
+ALTER TABLE commitfest_topic ADD COLUMN sortorder INTEGER NOT NULL DEFAULT 50;
CREATE TABLE patch_status (
id integer not null,
+DROP FUNCTION IF EXISTS most_recent_comments(integer);
+DROP VIEW IF EXISTS patch_comment_view;
+DROP VIEW IF EXISTS patch_view;
+DROP VIEW IF EXISTS commitfest_view;
+
CREATE OR REPLACE VIEW commitfest_view AS
SELECT
v.id, v.name, v.commitfest_status_id, s.name AS commitfest_status
CREATE OR REPLACE VIEW patch_view AS
SELECT v.id, v.commitfest_topic_id, s.name AS commitfest_topic,
+ s.sortorder AS commitfest_topic_sortorder,
s.commitfest_id, f.name AS commitfest, v.name,
v.patch_status_id, ps.name AS patch_status, v.author, v.reviewers,
v.date_closed, v.creation_time
SELECT id, name, patch_status_id, patch_status, author, reviewers,
commitfest_topic_id, commitfest_topic, commitfest_id, date_closed
FROM patch_view WHERE commitfest_id = ?
- ORDER BY date_closed, commitfest_topic, id
+ ORDER BY date_closed, commitfest_topic_sortorder, commitfest_topic, id
EOM
for my $p (@$patch_list) {
if (grep { $_ eq $p->{'patch_status_id'} } qw(4 5 6)) {
if (defined $id) {
$r->set_title('Edit CommitFest Topic');
$d = $r->db->select_one(<<EOM, $id);
-SELECT id, commitfest_id, name FROM commitfest_topic WHERE id = ?
+SELECT id, commitfest_id, name, sortorder FROM commitfest_topic WHERE id = ?
EOM
$r->error_exit('CommitFest not found.') if !defined $d;
}
else {
$d = $r->db->select_one(<<EOM, $r->cgi_required_id('commitfest'));
-SELECT id AS commitfest_id FROM commitfest WHERE id = ?
+SELECT id AS commitfest_id, 50 AS sortorder FROM commitfest WHERE id = ?
EOM
$r->set_title('New CommitFest Topic');
}
# Add controls.
$r->add_control('name', 'text', 'Name', 'required' => 1);
+ $r->add_control('sortorder', 'integer', 'Sort Order', 'required' => 1,
+ 'min_value' => 0);
my %value = $r->initialize_controls($d);
# Handle commit.
if ($r->cgi('go') && ! $r->is_error()) {
if (defined $id) {
- $r->db->update('commitfest_topic', { 'id' => $id }, {
- 'name' => $value{'name'},
- });
+ $r->db->update('commitfest_topic', { 'id' => $id }, \%value);
}
else {
$id = $r->db->insert_returning_id('commitfest_topic', {
'commitfest_id' => $d->{'commitfest_id'},
- 'name' => $value{'name'},
+ %value
});
}
$r->db->commit;
}
# Display template.
- $r->render_template('commitfest_topic_form', { 'id' => $id,
- 'd' => $d });
+ $r->render_template('commitfest_topic_form', { 'id' => $id, 'd' => $d });
}
sub search {
$r->set_title('CommitFest Topics: %s', $d->{'name'});
my $topic_list = $r->db->select(<<EOM, $d->{'id'});
-SELECT id, name FROM commitfest_topic WHERE commitfest_id = ? ORDER BY name
+SELECT id, name, sortorder FROM commitfest_topic
+ WHERE commitfest_id = ? ORDER BY sortorder, name
EOM
$r->add_link('/action/commitfest_topic_form?commitfest=' . $id,
'_base' => 'text',
},
'hidden' => {},
+ 'integer' => {
+ '_base' => 'text',
+ 'min_value' => qr/^\d+$/,
+ 'max_value' => qr/^\d+$/,
+ },
'password' => {
'_base' => 'text',
},
sub render {
my ($self) = @_;
if ($self->{'istype'}{'text'}) {
+ my $size = 60;
+ my $maxlength = 200;
+ if ($self->{'istype'}{'date'} || $self->{'istype'}{'integer'}) {
+ $size = 10;
+ $maxlength = 10;
+ }
return sprintf
"<input name='%s' type='%s' size='%d' maxlength='%d' value='%s'>",
$self->{'name'},
$self->{'istype'}{'password'} ? 'password' : 'text',
- defined $self->{'size'} ? $self->{'size'}
- : ($self->{'istype'}{'date'} ? 10 : 60),
- defined $self->{'maxlength'} ? $self->{'maxlength'}
- : ($self->{'istype'}{'date'} ? 10 : 120),
+ defined $self->{'size'} ? $self->{'size'} : $size,
+ defined $self->{'maxlength'} ? $self->{'maxlength'} : $maxlength,
$self->{'istype'}{'password'} ? '' : escape($self->{'value'});
}
elsif ($self->{'istype'}{'textarea'}) {
$error = 'is not a valid date (use YYYY-MM-DD format).' if ! $ok;
}
- # We store NULL for empty dates.
- if ($self->{'istype'}{'date'} && $value eq '') {
+ # If the field is an integer, complain if it doesn't look like a
+ # valid integer or is out of range.
+ if ($self->{'istype'}{'integer'} && $value ne '' && $r->cgi('go')) {
+ if ($value !~ /^-?\d+$/) {
+ $error = 'must be an integer.';
+ }
+ elsif (defined $self->{'min_value'} && $value < $self->{'min_value'}) {
+ $error = 'is too small (the minimum value is '
+ . $self->{'min_value'} . ').';
+ }
+ elsif (defined $self->{'max_value'} && $value > $self->{'max_value'}) {
+ $error = 'is too large (the minimum value is '
+ . $self->{'max_value'} . ').';
+ }
+ }
+
+ # We store NULL for empty dates and integers.
+ if (($self->{'istype'}{'date'} || $self->{'istype'}{'integer'})
+ && $value eq '') {
$db_value = undef;
}
<div class='tblBasic'>
<table cellspacing='0' class='tblBasicGrey'>
-<tr class='firstrow lastrow'>
+<tr class='firstrow'>
<td class='colFirst'>[% control.name.display_name_html %]</td>
<td class='colLast'>[% control.name.render %]</td>
</tr>
+<tr class='lastrow'>
+ <td class='colFirst'>[% control.sortorder.display_name_html %]</td>
+ <td class='colLast'>[% control.sortorder.render %]</td>
+</tr>
</table>
</div>
<table cellspacing='0' class='tblBasicGrey'>
<tr class='firstrow'>
<th class='colFirst'>Topic</th>
+ <th>Sort Order</th>
<th class='colLast'>Action</th>
</tr>
[% FOREACH t = topic_list %]
<tr[% IF loop.last %] class='lastrow'[% END %]>
<td class='colFirst'>[% t.name | htmlsafe %]</a></td>
+ <td>[% t.sortorder | htmlsafe %]</a></td>
<td class='colLast'><a href='/action/commitfest_topic_form?id=[% t.id %]'>Edit Topic</a> -
<a href='/action/commitfest_topic_delete?id=[% t.id %]' onClick='return confirm("Are you sure you want to delete this topic?");'>Delete Topic</a></td>
</tr>