/*
** Copyright (c) 2007 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public
** License version 2 as published by the Free Software Foundation.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public
** License along with this library; if not, write to the
** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
** Boston, MA 02111-1307, USA.
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code to implement the ticket configuration
** setup screens.
*/
#include "config.h"
#include "tktsetup.h"
#include <assert.h>
/*
** Main sub-menu for configuring the ticketing system.
** WEBPAGE: tktsetup
*/
void tktsetup_page(void){
login_check_credentials();
if( !g.okSetup ){
login_needed();
}
style_header("Ticket Setup");
@ <table border="0" cellspacing="20">
setup_menu_entry("Table", "tktsetup_tab",
"Specify the schema of the \"ticket\" table in the database.");
setup_menu_entry("Common", "tktsetup_com",
"Common TH1 code run before all ticket processing.");
setup_menu_entry("New Ticket Page", "tktsetup_newpage",
"HTML with embedded TH1 code for the \"new ticket\" webpage.");
setup_menu_entry("View Ticket Page", "tktsetup_viewpage",
"HTML with embedded TH1 code for the \"view ticket\" webpage.");
setup_menu_entry("Edit Ticket Page", "tktsetup_editpage",
"HTML with embedded TH1 code for the \"edit ticket\" webpage.");
setup_menu_entry("Report Template", "tktsetup_rpttplt",
"The default ticket report format.");
setup_menu_entry("Key Template", "tktsetup_keytplt",
"The default color key for reports.");
@ </table>
style_footer();
}
/* @-comment: ** */
static const char zDefaultTicketTable[] =
@ CREATE TABLE ticket(
@ -- Do not change any column that begins with tkt_
@ tkt_id INTEGER PRIMARY KEY,
@ tkt_uuid TEXT,
@ tkt_mtime DATE,
@ -- Add as many field as required below this line
@ type TEXT,
@ status TEXT,
@ subsystem TEXT,
@ priority TEXT,
@ severity TEXT,
@ foundin TEXT,
@ contact TEXT,
@ resolution TEXT,
@ title TEXT,
@ comment TEXT,
@ -- Do not alter this UNIQUE clause:
@ UNIQUE(tkt_uuid, tkt_mtime)
@ );
;
/*
** Return the ticket table definition
*/
const char *ticket_table_schema(void){
return db_get("ticket-table", (char*)zDefaultTicketTable);
}
/*
** Common implementation for the ticket setup editor pages.
*/
static void tktsetup_generic(
const char *zTitle, /* Page title */
const char *zDbField, /* Configuration field being edited */
const char *zDfltValue, /* Default text value */
const char *zDesc, /* Description of this field */
char *(*xText)(const char*), /* Validitity test or NULL */
void (*xRebuild)(void), /* Run after successulf update */
int height /* Height of the edit box */
){
const char *z;
int isSubmit;
login_check_credentials();
if( !g.okSetup ){
login_needed();
}
if( P("setup") ){
cgi_redirect("tktsetup");
}
isSubmit = P("submit")!=0;
z = P("x");
if( z==0 ){
z = db_get(zDbField, (char*)zDfltValue);
}
style_header("Edit %s", zTitle);
if( P("clear")!=0 ){
db_unset(zDbField, 0);
if( xRebuild ) xRebuild();
z = zDfltValue;
}else if( isSubmit ){
char *zErr = 0;
if( xText && (zErr = xText(z))!=0 ){
@ <p><font color="red"><b>ERROR: %h(zErr)</b></font></p>
}else{
db_set(zDbField, z, 0);
if( xRebuild ) xRebuild();
}
}
@ <form action="%s(g.zBaseURL)/%s(g.zPath)" method="POST">
@ %s(zDesc)
@ <textarea name="x" rows="%d(height)" cols="80">%h(z)</textarea>
@ <br />
@ <input type="submit" name="submit" value="Apply Changes">
@ <input type="submit" name="clear" value="Revert To Default">
@ <input type="submit" name="setup" value="Ticket Setup Menu">
@ </form>
@ <hr>
@ <h2>Default %s(zTitle)</h2>
@ <blockquote><pre>
@ %h(zDfltValue)
@ </pre></blockquote>
style_footer();
}
/*
** WEBPAGE: tktsetup_tab
*/
void tktsetup_tab_page(void){
static const char zDesc[] =
@ <p>Enter a valid CREATE TABLE statement for the "ticket" table. The
@ table must contain columns named "tkt_id", "tkt_uuid", and "tkt_mtime"
@ with an unique index on "tkt_uuid" and "tkt_mtime".</p>
;
tktsetup_generic(
"Ticket Table Schema",
"ticket-table",
zDefaultTicketTable,
zDesc,
ticket_schema_check,
ticket_rebuild,
20
);
}
static const char zDefaultTicketCommon[] =
@ set type_choices {
@ Code_Defect
@ Build_Problem
@ Documentation
@ Feature_Request
@ Incident
@ }
@ set priority_choices {
@ Immediate
@ High
@ Medium
@ Low
@ Zero
@ }
@ set severity_choices {
@ Critical
@ Severe
@ Important
@ Minor
@ Cosmetic
@ }
@ set resolution_choices {
@ Open
@ Fixed
@ Rejected
@ Unable_To_Reproduce
@ Works_As_Designed
@ External_Bug
@ Not_A_Bug
@ Duplicate
@ Overcome_By_Events
@ Drive_By_Patch
@ }
@ set status_choices {
@ Open
@ Verified
@ Review
@ Deferred
@ Fixed
@ Tested
@ Closed
@ }
@ set subsystem_choices {one two three}
;
/*
** Return the ticket common code.
*/
const char *ticket_common_code(void){
return db_get("ticket-common", (char*)zDefaultTicketCommon);
}
/*
** WEBPAGE: tktsetup_com
*/
void tktsetup_com_page(void){
static const char zDesc[] =
@ <p>Enter TH1 script that initializes variables prior to generating
@ any of the ticket view, edit, or creation pages.</p>
;
tktsetup_generic(
"Ticket Common Script",
"ticket-common",
zDefaultTicketCommon,
zDesc,
0,
0,
30
);
}
static const char zDefaultNew[] =
@ <th1>
@ if {[info exists submit]} {
@ set status Open
@ submit_ticket
@ }
@ </th1>
@ <h1 align="center">Enter A New Bug Report</h1>
@ <table cellpadding="5">
@ <tr>
@ <td colspan="2">
@ Enter a one-line summary of the problem:<br>
@ <input type="text" name="title" size="60" value="$<title>">
@ </td>
@ </tr>
@
@ <tr>
@ <td align="right">Type:
@ <th1>combobox type $type_choices 1</th1>
@ </td>
@ <td>What type of ticket is this?</td>
@ </tr>
@
@ <tr>
@ <td align="right">Version:
@ <input type="text" name="foundin" size="20" value="$<foundin>">
@ </td>
@ <td>In what version or build number do you observe the problem?</td>
@ </tr>
@
@ <tr>
@ <td align="right">Severity:
@ <th1>combobox severity $severity_choices 1</th1>
@ </td>
@ <td>How debilitating is the problem? How badly does the problem
@ effect the operation of the product?</td>
@ </tr>
@
@ <tr>
@ <td align="right">EMail:
@ <input type="text" name="contact" value="$<contact>" size="30">
@ </td>
@ <td><u>Not publicly visible</u>. Used by developers to contact you with
@ questions.</td>
@ </tr>
@
@ <tr>
@ <td colspan="2">
@ Enter a detailed description of the problem.
@ For code defects, be sure to provide details on exactly how
@ the problem can be reproduced. Provide as much detail as
@ possible.
@ <br>
@ <th1>set nline [linecount $comment 50 10]</th1>
@ <textarea name="comment" cols="80" rows="$nline"
@ wrap="virtual" class="wikiedit">$<comment></textarea><br>
@ <input type="submit" name="preview" value="Preview">
@ </tr>
@
@ <th1>enable_output [info exists preview]</th1>
@ <tr><td colspan="2">
@ Description Preview:<br><hr>
@ <th1>wiki $comment</th1>
@ <hr>
@ </td></tr>
@ <th1>enable_output 1</th1>
@
@ <tr>
@ <td align="right">
@ <input type="submit" name="submit" value="Submit">
@ </td>
@ <td>After filling in the information above, press this button to create
@ the new ticket</td>
@ </tr>
@ </table>
;
/*
** Return the code used to generate the new ticket page
*/
const char *ticket_newpage_code(void){
return db_get("ticket-newpage", (char*)zDefaultNew);
}
/*
** WEBPAGE: tktsetup_newpage
*/
void tktsetup_newpage_page(void){
static const char zDesc[] =
@ <p>Enter HTML with embedded TH1 script that will render the "new ticket"
@ page</p>
;
tktsetup_generic(
"HTML For New Tickets",
"ticket-newpage",
zDefaultNew,
zDesc,
0,
0,
40
);
}
static const char zDefaultView[] =
@ <table cellpadding="5">
@ <tr><td align="right">Ticket UUID:</td><td bgcolor="#d0d0d0" colspan="3">
@ $<tkt_uuid>
@ </td></tr>
@ <tr><td align="right">Title:</td>
@ <td bgcolor="#d0d0d0" colspan="3" valign="top">
@ $<title>
@ </td></tr>
@ <tr><td align="right">Status:</td><td bgcolor="#d0d0d0">
@ $<status>
@ </td>
@ <td align="right">Type:</td><td bgcolor="#d0d0d0">
@ $<type>
@ </td></tr>
@ <tr><td align="right">Severity:</td><td bgcolor="#d0d0d0">
@ $<severity>
@ </td>
@ <td align="right">Priority:</td><td bgcolor="#d0d0d0">
@ $<priority>
@ </td></tr>
@ <tr><td align="right">Subsystem:</td><td bgcolor="#d0d0d0">
@ $<subsystem>
@ </td>
@ <td align="right">Resolution:</td><td bgcolor="#d0d0d0">
@ $<resolution>
@ </td></tr>
@ <tr><td align="right">Last Modified:</td><td bgcolor="#d0d0d0">
@ $<tkt_datetime>
@ </td>
@ <th1>enable_output [hascap e]</th1>
@ <td align="right">Contact:</td><td bgcolor="#d0d0d0">
@ $<contact>
@ </td>
@ <th1>enable_output 1</th1>
@ </tr>
@ <tr><td align="right">Version Found In:</td>
@ <td colspan="3" valign="top" bgcolor="#d0d0d0">
@ $<foundin>
@ </td></tr>
@ <tr><td>Description & Comments:</td></tr>
@ <tr><td colspan="4" bgcolor="#d0d0d0">
@ Description And Comments:<br>
@ <span bgcolor="#d0d0d0"><th1>wiki $comment</th1></span>
@ </td></tr>
@ </table>
;
/*
** Return the code used to generate the view ticket page
*/
const char *ticket_viewpage_code(void){
return db_get("ticket-viewpage", (char*)zDefaultView);
}
/*
** WEBPAGE: tktsetup_viewpage
*/
void tktsetup_viewpage_page(void){
static const char zDesc[] =
@ <p>Enter HTML with embedded TH1 script that will render the "view ticket"
@ page</p>
;
tktsetup_generic(
"HTML For Viewing Tickets",
"ticket-viewpage",
zDefaultView,
zDesc,
0,
0,
40
);
}
static const char zDefaultEdit[] =
@ <th1>
@ if {![info exists username]} {set username $login}
@ if {[info exists submit]} {
@ if {[info exists cmappnd]} {
@ if {[string length $cmappnd]>0} {
@ set ctxt "\n\n<hr><i>[htmlize $login]"
@ if {$username ne $login} {
@ set ctxt "$ctxt claiming to be [htmlize $username]"
@ }
@ set ctxt "$ctxt added on [date]:</i><br>\n$cmappnd"
@ append_field comment $ctxt
@ }
@ }
@ submit_ticket
@ }
@ </th1>
@ <table cellpadding="5">
@ <tr><td align="right">Title:</td><td>
@ <input type="text" name="title" value="$<title>" size="60">
@ </td></tr>
@ <tr><td align="right">Status:</td><td>
@ <th1>combobox status $status_choices 1</th1>
@ </td></tr>
@ <tr><td align="right">Type:</td><td>
@ <th1>combobox type $type_choices 1</th1>
@ </td></tr>
@ <tr><td align="right">Severity:</td><td>
@ <th1>combobox severity $severity_choices 1</th1>
@ </td></tr>
@ <tr><td align="right">Priority:</td><td>
@ <th1>combobox priority $priority_choices 1</th1>
@ </td></tr>
@ <tr><td align="right">Resolution:</td><td>
@ <th1>combobox resolution $resolution_choices 1</th1>
@ </td></tr>
@ <tr><td align="right">Subsystem:</td><td>
@ <th1>combobox subsystem $subsystem_choices 1</th1>
@ </td></tr>
@ <th1>enable_output [hascap e]</th1>
@ <tr><td align="right">Contact:</td><td>
@ <input type="text" name="contact" size="40" value="$<contact>">
@ </td></tr>
@ <th1>enable_output 1</th1>
@ <tr><td align="right">Version Found In:</td><td>
@ <input type="text" name="foundin" size="50" value="$<foundin>">
@ </td></tr>
@ <tr><td colspan="2">
@ <th1>
@ if {![info exists eall]} {set eall 0}
@ if {[info exists aonlybtn]} {set eall 0}
@ if {[info exists eallbtn]} {set eall 1}
@ if {![hascap w]} {set eall 0}
@ if {![info exists cmappnd]} {set cmappnd {}}
@ set nline [linecount $comment 15 10]
@ enable_output $eall
@ </th1>
@ Description And Comments:<br>
@ <textarea name="comment" cols="80" rows="$nline"
@ wrap="virtual" class="wikiedit">$<comment></textarea><br>
@ <input type="hidden" name="eall" value="1">
@ <input type="submit" name="aonlybtn" value="Append Remark">
@ <th1>enable_output [expr {!$eall}]</th1>
@ Append Remark from
@ <input type="text" name="username" value="$<username>" size="30">:<br>
@ <textarea name="cmappnd" cols="80" rows="15"
@ wrap="virtual" class="wikiedit">$<cmappnd></textarea><br>
@ <th1>enable_output [expr {[hascap w] && !$eall}]</th1>
@ <input type="submit" name="eallbtn" value="Edit All">
@ <th1>enable_output 1</th1>
@ </td></tr>
@ <tr><td align="right"></td><td>
@ <input type="submit" name="submit" value="Submit Changes">
@ </td></tr>
@ </table>
;
/*
** Return the code used to generate the edit ticket page
*/
const char *ticket_editpage_code(void){
return db_get("ticket-editpage", (char*)zDefaultEdit);
}
/*
** WEBPAGE: tktsetup_editpage
*/
void tktsetup_editpage_page(void){
static const char zDesc[] =
@ <p>Enter HTML with embedded TH1 script that will render the "edit ticket"
@ page</p>
;
tktsetup_generic(
"HTML For Editing Tickets",
"ticket-editpage",
zDefaultEdit,
zDesc,
0,
0,
40
);
}
/*
** The default template ticket report format:
*/
static char zDefaultReport[] =
@ SELECT
@ CASE WHEN status IN ('Open','Verified') THEN '#f2dcdc'
@ WHEN status='Review' THEN '#e8e8e8'
@ WHEN status='Fixed' THEN '#cfe8bd'
@ WHEN status='Tested' THEN '#bde5d6'
@ WHEN status='Deferred' THEN '#cacae5'
@ ELSE '#c8c8c8' END AS 'bgcolor',
@ substr(tkt_uuid,1,10) AS '#',
@ datetime(tkt_mtime) AS 'mtime',
@ type,
@ status,
@ subsystem,
@ title,
@ comment AS '_comments'
@ FROM ticket
;
/*
** Return the template ticket report format:
*/
char *ticket_report_template(void){
return db_get("ticket-report-template", zDefaultReport);
}
/*
** WEBPAGE: tktsetup_rpttplt
*/
void tktsetup_rpttplt_page(void){
static const char zDesc[] =
@ <p>Enter the default ticket report format template. This is the
@ the template report format that initial appears when creating a
@ new ticket summary report.</p>
;
tktsetup_generic(
"Default Report Template",
"ticket-report-template",
zDefaultReport,
zDesc,
0,
0,
20
);
}
/*
** The default template ticket key:
*/
static const char zDefaultKey[] =
@ #ffffff Key:
@ #f2dcdc Active
@ #e8e8e8 Review
@ #cfe8bd Fixed
@ #bde5d6 Tested
@ #cacae5 Deferred
@ #c8c8c8 Closed
;
/*
** Return the template ticket report format:
*/
const char *ticket_key_template(void){
return db_get("ticket-key-template", (char*)zDefaultKey);
}
/*
** WEBPAGE: tktsetup_keytplt
*/
void tktsetup_keytplt_page(void){
static const char zDesc[] =
@ <p>Enter the default ticket report key template. This is the
@ the template report format that initial appears when creating a
@ new ticket summary report.</p>
;
tktsetup_generic(
"Default Report Template",
"ticket-report-template",
zDefaultReport,
zDesc,
0,
0,
20
);
}