Add basic class editor

classes
Vitaliy Filippov 2015-09-17 15:56:03 +03:00
parent 3292b9c5f6
commit 92f71a6343
7 changed files with 230 additions and 20 deletions

View File

@ -87,13 +87,19 @@ sub _after_update
$any_field->touch;
}
# Removes class with history!
sub remove_from_db
sub object_count
{
my $self = shift;
my $table = $self->db_table;
my ($count) = Bugzilla->dbh->selectrow_array("SELECT COUNT(*) FROM $table");
ThrowUserError('class_delete_objects') if $count;
return $count;
}
# Removes class with history!
sub remove_from_db
{
my $self = shift;
ThrowUserError('class_delete_objects') if $self->object_count;
ThrowUserError('class_used_in_fields') if Bugzilla->get_class_fields({ value_class_id => $self->id });
for my $field (Bugzilla->get_class_fields({ class_id => $self->id }))
{

84
editclasses.cgi Executable file
View File

@ -0,0 +1,84 @@
#!/usr/bin/perl -wT
# Class editor
# License: Dual-license GPL 3.0+ or MPL 1.1+
# Contributor(s): Vitaliy Filippov <vitalif@mail.ru>
# FIXME: This editor should also be based on the generic object editor
use strict;
use lib qw(. lib);
use Bugzilla;
use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Util;
use Bugzilla::Field;
use Bugzilla::Token;
my $template = Bugzilla->template;
my $ARGS = Bugzilla->input_params;
my $vars = {};
# Make sure the user is logged in and is an administrator.
my $user = Bugzilla->login(LOGIN_REQUIRED);
$user->in_group('editfields') || ThrowUserError('auth_failure', {
group => 'editfields',
action => 'edit',
object => 'classes',
});
my $action = trim($ARGS->{action} || '');
my $token = $ARGS->{token};
if (!$action)
{
$vars->{classes} = [ sort { lc $a->name cmp lc $b->name } @{ Bugzilla->get_classes } ];
$template->process('admin/classes/list.html.tmpl', $vars)
|| ThrowTemplateError($template->error());
}
elsif ($action eq 'add' || $action eq 'edit')
{
if ($action eq 'edit')
{
$vars->{class} = Bugzilla->get_class($ARGS->{id}) || ThrowUserError('class_not_exists');
if ($vars->{class})
{
$vars->{possible_name_fields} = [ Bugzilla->get_class_fields({
class_id => $vars->{class}->id,
type => [ FIELD_TYPE_FREETEXT, FIELD_TYPE_NUMERIC, FIELD_TYPE_INTEGER ]
}) ];
}
}
$vars->{field_types} = Bugzilla->messages->{field_types};
$vars->{token} = issue_session_token('save_object');
$template->process('admin/classes/edit.html.tmpl', $vars)
|| ThrowTemplateError($template->error());
}
elsif ($action eq 'save' || $action eq 'delete')
{
check_token_data($token, 'save_object');
my $class = $ARGS->{id} ? Bugzilla->get_class($ARGS->{id}) : Bugzilla::Class->new;
$class || ThrowUserError('class_not_exists');
if ($action eq 'delete')
{
$class->remove_from_db;
}
else
{
$class->set_all($ARGS, '_');
$class->update;
}
delete_token($token);
Bugzilla->add_result_message({
message => 'class_updated',
action => $action eq 'delete' ? 'delete' : ($ARGS->{id} ? 'update' : 'create'),
class => { name => $class->name, description => $class->description },
});
Bugzilla->save_session_data;
print Bugzilla->cgi->redirect('editclasses.cgi');
}
else
{
ThrowCodeError('no_valid_action');
}
exit;

View File

@ -64,7 +64,7 @@ elsif ($action eq 'new')
delete_token($token);
Bugzilla->add_result_message({ message => 'custom_field_created', field => { class => $field->class->name, name => $field->name } });
Bugzilla->add_result_message({ message => 'custom_field_updated', action => 'create', field => { class => $field->class->name, name => $field->name } });
Bugzilla->save_session_data;
print Bugzilla->cgi->redirect('editfields.cgi?class='.$class->id);
exit;
@ -153,7 +153,7 @@ elsif ($action eq 'update')
delete_token($token);
Bugzilla->add_result_message({ message => 'custom_field_updated', field => { class => $field->class->name, name => $field->name } });
Bugzilla->add_result_message({ message => 'custom_field_updated', action => 'update', field => { class => $field->class->name, name => $field->name } });
Bugzilla->save_session_data;
print Bugzilla->cgi->redirect('editfields.cgi?class='.$class->id);
exit;
@ -185,7 +185,7 @@ elsif ($action eq 'delete')
delete_token($token);
Bugzilla->add_result_message({ message => 'custom_field_deleted', field => { class => $field->class->name, name => $field->name } });
Bugzilla->add_result_message({ message => 'custom_field_updated', action => 'delete', field => { class => $field->class->name, name => $field->name } });
Bugzilla->save_session_data;
print Bugzilla->cgi->redirect('editfields.cgi?class='.$class->id);
exit;

View File

@ -102,6 +102,10 @@ a:hover, #header a:hover, #footer a:hover {
color: #00539f;
}
p {
margin: .5em 0;
}
#page_index, select, textarea, .text_input, input[type="text"], input[type="password"], input:not([type]) {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;

View File

@ -0,0 +1,94 @@
[%# Edit form / confirm deletion page for class editor
# License: Dual-license GPL 3.0+ or MPL 1.1+
# Author(s): Vitaliy Filippov <vitalif@mail.ru>
#%]
[% title = BLOCK %]
[% IF class %]
Object class '[% class.description | html %]'
[% ELSE %]
Create a new object class
[% END %]
[% END %]
[% PROCESS global/header.html.tmpl title = title %]
<form action="?" method="POST">
<input type="hidden" name="action" value="save" />
<input type="hidden" name="id" value="[% class.id %]" />
<input type="hidden" name="token" value="[% token | html %]" />
<table border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td>
<table border="0" cellspacing="0" cellpadding="5">
<tr>
<th align="left">Class name:</th>
<td>
[% IF class.id %]
[% class.name | html %]
[% ELSE %]
<input type="text" id="name" name="_name" value="[% class.name | html %]" size="40" maxlength="64" />
[% END %]
</td>
</tr>
<tr>
<th align="left"><label for="description">Title:</label></th>
<td><input type="text" id="description" name="_description" style="width: 400px" value="[% class.description | html %]" /></td>
</tr>
[% IF class.id %]
<tr>
<th align="left"><label for="name_field_id">Name field:</label></th>
<td>
<select id="name_field_id" name="_name_field_id" style="width: 400px">
<option value="">---</option>
[% FOREACH f = possible_name_fields %]
<option value="[% f.id | html %]" [% ' selected="selected"' IF f.id == class.name_field_id %]>
[% f.description | html %] ([% f.name | html %])
</option>
[% END %]
</select>
</td>
</tr>
<tr>
<th align="left"><label for="list_order">Default list order:</label></th>
<td><input type="text" id="list_order" name="_list_order" style="width: 400px" value="[% class.list_order | html %]" /></td>
</tr>
[% END %]
</table>
<input type="submit" value="[% IF class.id %]Save[% ELSE %]Create[% END %]" />
[% IF class.id %]
[% FOR f = Bugzilla.get_class_fields({ value_class_id => class.id }) %]
<p>This class is used for <a href="editfields.cgi?class=[% f.class.id %]&name=[% f.name | uri %]&action=edit">[% f.class.description | html %] &rarr; [% f.description | html %]</a> attribute.</p>
[% END %]
<p>[% class.object_count %] object(s) of this class exist.</p>
[% IF !class.object_count && !Bugzilla.get_class_fields({ value_class_id => class.id }) %]
<p><a href="editclasses.cgi?action=delete&token=[% token | uri %]&id=[% class.id %]"
onclick="if (!confirm('Really delete this class?')) { event.preventDefault && event.preventDefault(); return false; }">
Permanently delete this class with all change history
</a></p>
[% ELSE %]
<p>All objects and fields using this class must be deleted before deleting it.</p>
[% END %]
[% END %]
<p><a href="editclasses.cgi">Back to the list of existing classes</a></p>
</td><td style="padding: 0 10px">
[%# FIXME Fields should be edited from this same form %]
[% IF class.id %]
<p>Current fields of this class (<a href="editfields.cgi?class=[% class.id %]">add/edit</a>):</p>
<p>
[% FOR f = class.get_fields({ sort => 'id' }) %]
[% f.description | html %] ([% field_types.${f.type} %][% IF f.is_select %] of [% f.value_class.description | html %][% END %])<br />
[% END %]
</p>
[% END %]
</td></tr>
</table>
</form>
[% PROCESS global/footer.html.tmpl %]

View File

@ -0,0 +1,29 @@
[%# Class list
# License: Dual-license GPL 3.0+ or MPL 1.1+
# Author(s): Vitaliy Filippov <vitalif@mail.ru>
#%]
[% PROCESS global/header.html.tmpl title="Object classes" %]
<h2>Object classes</h2>
<p><a href="editclasses.cgi?action=add">Add new class</a></p>
<table id="admin_table" class="admin_table">
<tr>
<th>Edit class...</th>
<th>Description</th>
<th>Name field</th>
<th>List order</th>
</tr>
[% FOR c = classes %]
<tr>
<td><a href="editclasses.cgi?action=edit&id=[% c.id %]">[% c.name | html %]</a></td>
<td>[% c.description | html %]</td>
<td>[% c.name_field.description | html %]</td>
<td>[% c.list_order | html %]</td>
</tr>
[% END %]
</table>
[% PROCESS global/footer.html.tmpl %]

View File

@ -131,26 +131,19 @@
</p>
[% END %]
[% BLOCK msg_custom_field_created %]
[% title = "Field Created" %]
[% field = Bugzilla.get_class_field(field.name, field.class) %]
<div class="message">
The field [% field.description %] is created for class [% field.class.description %].
</div>
[% END %]
[% BLOCK msg_custom_field_updated %]
[% title = "Field Updated" %]
[% field = Bugzilla.get_class_field(field.name, field.class) %]
[% title = "Field " _ (action == 'create' ? 'created' : (action == 'update' ? 'updated' : 'deleted')) %]
[% f = Bugzilla.get_class_field(field.name, field.class) %]
<div class="message">
The field [% field.description %] of class [% field.class.description %] is updated.
The field [% f.description || field.name | html %] of class [% Bugzilla.get_class(field.class).description %] is [% action == 'create' ? 'created' : (action == 'update' ? 'updated' : 'deleted') %].
</div>
[% END %]
[% BLOCK msg_custom_field_deleted %]
[% title = "Field Deleted" %]
[% BLOCK msg_class_updated %]
[% title = "Class " _ (action == 'create' ? 'created' : (action == 'update' ? 'updated' : 'deleted')) %]
[% c = Bugzilla.get_class(class.name) %]
<div class="message">
The field [% field.name %] of class [% Bugzilla.get_class(field.class).description %] is deleted.
The class [% c.description || class.name | html %] is [% action == 'create' ? 'created' : (action == 'update' ? 'updated' : 'deleted') %].
</div>
[% END %]