This document describes additional functionality to be added to the Bugzilla bug tracking system. Definition ========== Currently, Bugzilla offers a fixed number of named fields to describe bugs. These fields are shared by every project in the system. The proposed additional functionalty is the ability to define additional fields on a global or per-project basis. These additional fields are called "custom fields". Each custom field has a name, consisting of up to 255 characters. A field's name may not contain any vertical whitespace characters (carriage return, newline, and vertical tab), nor may it begin or end with whitespace. Each field also has a type: one of Integer, String, Date, or Selection. The Integer, String, and Date types are collectively referred to as "scalar" types. Once created, a field's name may be changed, but its type is immutable. All scalar fields can be set to a special "undefined" value in additional to the valid values described below. Integer ------- An integer custom field contains values which are integers. Such fields must be able to store at least the range of integers which are typically represented as a signed four-byte quantity. An Integer field is presented on Bugzilla's web interface as a single-line text form element. When a user enters text into an Integer form element, Bugzilla will signal an error condition if the text does not conform to the usual string format for integers (a sequence of digit characters optionally preceded by a plus or minus sign), or if the resulting number falls outside of the allowed range. Leading and trailing whitespace is trimmed from the text before the conversion to an integer is attempted. If no text remains after whitespace is trimmed, the field will be set to the undefined value. String ------ A String field contains text which is intended to be readable by humans. However, for i18n reasons, any binary data may be stored in a string field. Each string field is flagged as belonging to one of two varieties: short and long. A short string field can hold a maximum of 255 characters, and may contain no vertical whitespace characters. It is presented on Bugzilla's Web interface as a single-line text form element. A long string field can hold up to 65535 arbitrary characters. It is presented on Bugzilla's Web interface as a multiline textarea form element. If the users enters no text at all (including whitespace) into a String form element, the field will be set to the undefined value. Date ---- A Date field describes a particular moment of time. It is represented on Bugzilla's web interface as a single-line text form element. Each Date field is flagged as belonging to one of two varieties: date-only and date/time. A date-only Date field is represented using the format 'YYYY-MM-DD'; a date/time Date field is represented using the format 'YYYY-MM-DD HH24:MM:SS'. (Arbitrary whitespace may separate the two components in the latter case.) When a user enters text into a Date form element, it must conform to the appropriate format, or Bugzilla will signal an error condition. Alternately, a user may enter either of the words "now" or "today"; in either of these cases, Bugzilla sets the value of the field to the date (and time, for date/time fields) that the transaction was initiated. If the user enters no text at all into a Date form element, the field will be set to the undefined value. Bugzilla will signal an error condition if a user attempts to store an illegal date value in a date field. Examples: * An invalid day of the month: March 50, February 30 * An invalid date: February 29, 2001 * An invalid time: 12:66:00 Selection --------- A selection field derives its value from a set of distinct string values, called the field's "value set". No element of any Selection field's value set may contain vertical whitespace, contain leading or trailing whitespace, or exceed 255 characters in length. Each selection field comes in one of two varieties: "single-selection" and "multiselection". A single-selection field's value is a subset of the field's value set of size either zero or one. It is represented on Bugzilla's web interface as a drop-down listbox form element. A field whose value is the empty set is represented on the Web interface by a special "unset" string which is defined when the field is created. A multiselection field's value is an arbitrary subset of the field's value set. It is represented on Bugzilla's web interface as a multiline listbox in which multiple simultaneous selections are allowed. The listbox's vertical size is equal to the value set's size or five, whichever is smaller. It will be possible to share a Selection field's value set among multiple fields, such that a change to one field's value set is immediately reflected in all fields which share that value set. [Open question: How should value sets be shared among multiple Selection fields?] Logging ======= Whenever a user edits a bug and changes one or more custom fields, the changes must be logged. Every change to a bug must be tagged with a unique ID, so that it is possible to later determine which changes were made during the same transaction. Information logged with each transaction must include the identity of the user who made the changes and the date and time when the changes were made. The old and new values of each field modified during a transaction must be logged. Presentation ============ Custom fields are to be presented on each Bugzilla page that presents the standard Bugzilla fields. These pages include at least the following: On "show_bug.cgi" and "post_bug.cgi", the custom fields will be shown just prior to the list of attachments. On "enter_bug.cgi" and "long_list.cgi", the custom fields will be shown just after the "Description" text box. The Bugzilla administrator may edit Bugzilla's templates to display the custom fields at some other location on the page, or to display individual custom fields at chosen locations. The template for each page must be intelligent enough to display at the default location only those fields which have not been set to be displayed elsewhere on the page. When a bug is being created or edited, custom fields are represented as per the field type descriptions above. When a bug is being displayed but not edited, scalar fields and single-selection fields are represented as text inside a preformatted (
) block; multiselection fields are represented using unnamed multiline listboxes. The query.cgi page requires more extensive modifications. Currently query.cgi knows only about Bugzilla's standard fields. Since all components share the same set of standard fields, these fields can be displayed before the user has chosen a Product at the top of the page. To add the capability to search on custom fields, a straightforward approach would be to require the user to first specify the projects within which to search, then display the usual query page augmented with the custom fields which exist in those projects. However, this is too invasive for projects which don't use custom fields, and also for queries which don't care about custom fields. Here is an alternate approach. Global custom fields are always displayed. A button is to be added to the query page, to the right of the "Product", "Component", and "Version" listboxes, labelled "Show custom fields for these projects". If the user clicks it, the query form is redisplayed, augmented with all custom fields in all of the selected projects. If no projects were selected, or if no selected project has any custom fields, the page is simply redisplayed as it was before. The user may freely change the target projects and press the "Show custom fields" button again. The query page will be redisplayed with new form elements for the most recently chosen projects. When custom fields are being shown, a second button is to be added below the "Show custom fields" button, labelled "Hide custom fields". When it is clicked, the query page is redisplayed as it was originally, showing only custom fields in the global scope (if any). It is an error for the user to select one or more target projects, show the custom fields for those components, change the target projects, and begin a search. In this case Bugzilla will redisplay the query page with an appropriate error message at the top. Different projects may define different custom fields with the same name. Therefore, custom field form elements for custom fields belonging to the same project will need to be grouped together, clearly labelled as belonging to that project. Custom fields in the global scope (if any) are grouped together under the italicized label "Global fields". Custom string fields may be queried in the same manner as the stock fields "Comment" and "URL". That is, they may be matched against a user-supplied string using any of the following predicates: * contains all of the words/strings * contains any of the words/strings * contains the string * contains the string (exact case) * contains all of the words * contains any of the words * matches the regexp * doesn't match the regexp Custom integer fields may be queried against a user-supplied string (which must obey the proper format for Integers, as described above) using the following predicates: * is equal to * is less than * is greater than * is less than or equal to * is greater than or equal to Custom date fields may be queried against a user-supplied string (which must obey the appropriate date-only or date/time patter, as described above). The available predicates are: * is exactly * is at or earlier than * is at or later than (The open versions of the latter two inequalities--ie, strictly earlier than or strictly later than--are probably not worth including.) Custom single-selection selection fields may be queried against a multiline listbox containing the field's value set, one element per line. Multiple selections within this listbox are allowed. A bug matches this query term if this field's value is a subset of the user-selected values. Custom multiselection selection fields may be queried against a multiline listbox containing all valid values for the fields. Multiple selections within this listbox are allowed. A pair of radiobuttons is placed next to the listbox which present two choices: "Any" and "All". Initially, "Any" is selected. If the "Any" button is selected at the time the query is initiated, then a bug matches this query term if the intersection of the field's value and the user-selected values is nonempty. If the "All" button is selected instead, then a bug matches this query term if the field's value is a subset of the user-selected values. Administration ============== A new CGI program for managing custom fields, cdadmin.cgi, will be created. The program is only accessible to the Bugzilla administrator. The initial page served by cfadmin.cgi will present a drop-down, single-selection listbox which enumerates all existing projects. Near this listbox is a button labelled "View custom fields in this project". Below this is a second button labelled "View custom fields in the global scope". If, for whatever reason, no projects exist, then the project listbox is suppressed, and only editing of globally scoped fields is possible. If no project was selected when the "View custom fields" button was pressed, the initial page is redisplayed. Otherwise, a page is presented which contains the following elements. [See the accompanying file cfadmin.html for a concrete visualization of the following page format.] First, a table for describing each custom field defined for the selected project. It has four columns: "Name", "Type", "Default", and "Value Set". For every custom field, the Name column naturally contains the name of the field. The Type column contains one of the following strings: * string (short) * string (long) * selection (single) * selection (multiple) * integer * date * date (with time) The Default column describes the default value of the field. If a field has no default value, the content of this column is the italicized word "none". This includes multiselection fields whose default value is the empty set. Nontrivial multiselection field default values are presented via a multiline selection element; the default values of all other field types are text enclosed in a preformatted () block. The Value Set column is empty for all fields other than those of the Selection type. For such fields, the value set is presented via a multiline selection element. Below the field table is a sequence of five HTML paragraphs. Each paragraph describes one operation that may be carried out, and includes appropriate form elements to specify the important parameters of the operation and a button to initiate the operation. The available operations include the following: * Edit one of the fields. * Insert a new field, of any type, at the beginning of the list, the end of the list, or between any two existing fields. * Move a field to a different position in the list. * Rename a field. * Remove a field. Pressing any of the buttons causes a new page to be displayed, as described below. Each of the pages includes a "Cancel" button, which will abort the operation and return the user to this page. Editing a custom field ---------------------- The only aspect of a string, integer, and date field that may be edited (other than its name, handled by a separate Rename operation) is its default value. Thus, the Edit page presents only a single form element for such fields: a multiline textarea element for long string fields, and a single-line text element for the others. Pressing the form's submit button initiates the change. The default value of a selection field may also be edited, via either a drop-down listbox element (for single-selection fields) or a multiline listbox element (for multiselection fields). In addition, the field's set of valid selection values may be edited. The field's value set is presented in a multiline textarea element, one element per line. The administrator is free to cut and paste elements around within the textarea, insert new values, or delete old values. Pressing the submit button on a selection field's Edit page initiates sanity checking as follows. * If any elements were removed from the field's value set, the administrator is warned that those elements will be removed from the value of that field in each bug. * If any of the field's default values were removed from the field's value set, the administrator is warned that the deleted values will be removed from the field's default value. If either of the above warnings are issued, the administrator must explicitly confirm that the operation should be carried out. Inserting a new field --------------------- For a new Integer or Date field, a single-line text element is provided into which the user may enter the new field's default value. When the user presses the page's "Create field" button, the field will be created, assuming the supplied default value is appropriate for the chosen field type. For a new String field, the first page presented includes only a pair of radiobuttons, labelled "Long string (multiline, up to 64K characters)" and "Short string (single line, up to 255 characters)". Pressing a "Continue field creation" button produces a page which allows the user to enter the field's default value, using an appropriate form element (single-line text element for short strings, multiline textarea element for long strings). A "Create field" button starts the field creation process. For a new Selection field, the first page presented includes a pair of radiobuttons, labelled "Single selection" and "Multiple selection". The page also includes a multiline textarea element into which the administrator may enter the field's value set, one element per line. Pressing the page's "Continue field creation" produces a second page which allows the administrator to select the field's default value, via either a drop-down listbox element (for single-selection fields) or a multiline listbox element (for multiselection fields). A second form element is provided for single-selection fields, a single-line text element into which the "unset" label for the field may be entered. (If the administrator did not enter any selection values before pressing the "Continue field creation" button, the first page is redisplayed with a warning.) A "Create field" button is provided on the second page. Pressing the "Create field" button in any of these cases initiates field creation. The field is added to every bug in the selected project--or every bug in the entire Bugzilla installation, if the field was created in the global scope. The field's value in every case is set to the new field's default value. In addition, the field ordering for the selected project (or global scope) is rearranged so that the new field will appear in the position specified by the administrator. Moving a field to a different position -------------------------------------- This action is performed immediately. The field ordering for the selected project (or for the global scope) is rearranged so that the fields appear in the new order specified by the administrator. The initial cfadmin.cgi page is redisplayed, showing the fields in their new order. Since this action is easily reversible, no confirmation step is required. Rename a field -------------- A page is presented into which the user may enter the new name for the selected field into a single-line text element. Pressing a button labelled "Change field name" causes the field to assume the new name. The initial cfadmin.cgi page is redisplayed, showing the selected field with its new name. Since this action is easily reversible, no confirmation step is required. Remove a field -------------- A page is presented which warns the administrator that deleting a custom field causes the irrecoverable loss of data. The number of bugs which will be affected by the removal operation is described. If the administrator pushes the "Confirm field removal" button, the field is expunged from the database. [Open question: Since this is such a potentially damaging operation, maybe it should not be available via the web interface at all. Perhaps the administrator should be required to run, from the command line, a special program provided for this purpose. Or perhaps deleted field data should be retained for a time to make an undo operation possible.]