/* ** 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 /* ** 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"); @ setup_menu_entry("Table", "tktsetup_tab", "Specify the schema of the \"ticket\" table in the database."); setup_menu_entry("Timeline", "tktsetup_timeline", "How to display ticket status in the timeline"); 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."); @
style_footer(); } /* ** NOTE: When changing the table definition below, also change the ** equivalent definition found in schema.c. */ /* @-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 UNIQUE, @ tkt_mtime DATE, @ -- Add as many field as required below this line @ type TEXT, @ status TEXT, @ subsystem TEXT, @ priority TEXT, @ severity TEXT, @ foundin TEXT, @ private_contact TEXT, @ resolution TEXT, @ title TEXT, @ comment TEXT @ ); ; /* ** 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 ){ login_verify_csrf_secret(); db_unset(zDbField, 0); if( xRebuild ) xRebuild(); z = zDfltValue; }else if( isSubmit ){ char *zErr = 0; login_verify_csrf_secret(); if( xText && (zErr = xText(z))!=0 ){ @

ERROR: %h(zErr)

}else{ db_set(zDbField, z, 0); if( xRebuild ) xRebuild(); cgi_redirect("tktsetup"); } } @
login_insert_csrf_secret(); @

%s(zDesc)

@ @
@ @ @ @
@
@
@

Default %s(zTitle)

@
  @ %h(zDfltValue)
  @ 
style_footer(); } /* ** WEBPAGE: tktsetup_tab */ void tktsetup_tab_page(void){ static const char zDesc[] = @

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".

; 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[] = @

Enter TH1 script that initializes variables prior to generating @ any of the ticket view, edit, or creation pages.

; tktsetup_generic( "Ticket Common Script", "ticket-common", zDefaultTicketCommon, zDesc, 0, 0, 30 ); } static const char zDefaultNew[] = @ @ if {[info exists submit]} { @ set status Open @ submit_ticket @ } @ @

Enter A New Bug Report

@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ enable_output [info exists preview] @ @ enable_output 1 @ @ @ @ @ @ @ @ @ @
@ Enter a one-line summary of the problem:
@ @
Type: @ combobox type $type_choices 1 @ What type of ticket is this?
Version: @ @ In what version or build number do you observe the problem?
Severity: @ combobox severity $severity_choices 1 @ How debilitating is the problem? How badly does the problem @ affect the operation of the product?
EMail: @ @ Not publicly visible. Used by developers to contact you with @ questions.
@ 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. @
@ set nline [linecount $comment 50 10] @
@ @
@ Description Preview:

@ wiki $comment @
@
@ @ After filling in the information above, press this button to create @ the new ticket
@ @ Abandon and forget this bug report
; /* ** 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[] = @

Enter HTML with embedded TH1 script that will render the "new ticket" @ page

; tktsetup_generic( "HTML For New Tickets", "ticket-newpage", zDefaultNew, zDesc, 0, 0, 40 ); } static const char zDefaultView[] = @ @ @ @
Ticket UUID: @ $ @
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"> @ $<private_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"> @ <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="private_contact" size="40" @ value="$<private_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"> @ <input type="submit" name="cancel" value="Cancel"> @ </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 initially 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 color-key template. This is the @ the color-key that initially appears when creating a @ new ticket summary report.</p> ; tktsetup_generic( "Default Report Color-Key Template", "ticket-key-template", zDefaultKey, zDesc, 0, 0, 10 ); } /* ** WEBPAGE: tktsetup_timeline */ void tktsetup_timeline_page(void){ login_check_credentials(); if( !g.okSetup ){ login_needed(); } if( P("setup") ){ cgi_redirect("tktsetup"); } style_header("Ticket Display On Timelines"); db_begin_transaction(); @ <form action="%s(g.zBaseURL)/tktsetup_timeline" method="POST"> login_insert_csrf_secret(); @ <hr> entry_attribute("Ticket Title", 40, "ticket-title-expr", "t", "title"); @ <p>An SQL expression in a query against the TICKET table that will @ return the title of the ticket for display purposes after hyperlinks to @ that ticket</p> @ <hr> entry_attribute("Ticket Closed", 40, "ticket-closed-expr", "c", "status='Closed'"); @ <p>An SQL expression that evaluates to true in a TICKET table query if @ the ticket is closed.</p> @ <hr> @ <p> @ <input type="submit" name="submit" value="Apply Changes"> @ <input type="submit" name="setup" value="Cancel"> @ </p> @ </form> db_end_transaction(0); style_footer(); }