Add basic class editor
parent
3292b9c5f6
commit
92f71a6343
|
@ -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 }))
|
||||
{
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 %] → [% 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 %]
|
|
@ -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 %]
|
|
@ -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 %]
|
||||
|
||||
|
|
Loading…
Reference in New Issue