summaryrefslogtreecommitdiff
path: root/rt/html
diff options
context:
space:
mode:
Diffstat (limited to 'rt/html')
-rw-r--r--rt/html/Admin/CustomFields/GroupRights.html172
-rw-r--r--rt/html/Admin/CustomFields/Modify.html258
-rw-r--r--rt/html/Admin/CustomFields/Objects.html147
-rw-r--r--rt/html/Admin/CustomFields/UserRights.html170
-rw-r--r--rt/html/Admin/CustomFields/index.html93
-rw-r--r--rt/html/Admin/Elements/AddCustomFieldValue74
-rw-r--r--rt/html/Admin/Elements/ConfigureMyRT80
-rw-r--r--rt/html/Admin/Elements/CreateUserCalled50
-rw-r--r--rt/html/Admin/Elements/CustomFieldTabs118
-rw-r--r--rt/html/Admin/Elements/EditCustomField159
-rw-r--r--rt/html/Admin/Elements/EditCustomFieldValues96
-rw-r--r--rt/html/Admin/Elements/EditCustomFields205
-rw-r--r--rt/html/Admin/Elements/EditQueueWatchers78
-rw-r--r--rt/html/Admin/Elements/EditScrip183
-rw-r--r--rt/html/Admin/Elements/EditScrips125
-rw-r--r--rt/html/Admin/Elements/EditTemplates128
-rw-r--r--rt/html/Admin/Elements/EditUserComments56
-rwxr-xr-xrt/html/Admin/Elements/GlobalCustomFieldTabs95
-rw-r--r--rt/html/Admin/Elements/GroupTabs102
-rw-r--r--rt/html/Admin/Elements/Header52
-rw-r--r--rt/html/Admin/Elements/ListGlobalCustomFields61
-rw-r--r--rt/html/Admin/Elements/ListGlobalScrips76
-rw-r--r--rt/html/Admin/Elements/ModifyTemplate84
-rw-r--r--rt/html/Admin/Elements/ObjectCustomFields111
-rw-r--r--rt/html/Admin/Elements/PickCustomFields98
-rw-r--r--rt/html/Admin/Elements/PickObjects81
-rw-r--r--rt/html/Admin/Elements/QueueRightsForUser64
-rw-r--r--rt/html/Admin/Elements/QueueTabs120
-rw-r--r--rt/html/Admin/Elements/SelectCustomFieldLookupType60
-rw-r--r--rt/html/Admin/Elements/SelectCustomFieldType60
-rw-r--r--rt/html/Admin/Elements/SelectGroups62
-rw-r--r--rt/html/Admin/Elements/SelectModifyGroup57
-rw-r--r--rt/html/Admin/Elements/SelectModifyQueue57
-rw-r--r--rt/html/Admin/Elements/SelectModifyUser73
-rw-r--r--rt/html/Admin/Elements/SelectNewGroupMembers99
-rw-r--r--rt/html/Admin/Elements/SelectRights118
-rw-r--r--rt/html/Admin/Elements/SelectScrip72
-rw-r--r--rt/html/Admin/Elements/SelectScripAction73
-rw-r--r--rt/html/Admin/Elements/SelectScripCondition72
-rw-r--r--rt/html/Admin/Elements/SelectSingleOrMultiple67
-rw-r--r--rt/html/Admin/Elements/SelectStage66
-rw-r--r--rt/html/Admin/Elements/SelectTemplate87
-rw-r--r--rt/html/Admin/Elements/SelectUsers64
-rw-r--r--rt/html/Admin/Elements/SystemTabs97
-rw-r--r--rt/html/Admin/Elements/Tabs93
-rwxr-xr-xrt/html/Admin/Elements/ToolTabs80
-rw-r--r--rt/html/Admin/Elements/UserTabs113
-rw-r--r--rt/html/Admin/Global/CustomFields/Groups.html58
-rwxr-xr-xrt/html/Admin/Global/CustomFields/Queue-Tickets.html58
-rwxr-xr-xrt/html/Admin/Global/CustomFields/Queue-Transactions.html58
-rw-r--r--rt/html/Admin/Global/CustomFields/Users.html58
-rw-r--r--rt/html/Admin/Global/CustomFields/index.html93
-rw-r--r--rt/html/Admin/Global/GroupRights.html123
-rw-r--r--rt/html/Admin/Global/MyRT.html104
-rw-r--r--rt/html/Admin/Global/Scrip.html87
-rw-r--r--rt/html/Admin/Global/Scrips.html77
-rw-r--r--rt/html/Admin/Global/Template.html125
-rw-r--r--rt/html/Admin/Global/Templates.html77
-rw-r--r--rt/html/Admin/Global/UserRights.html101
-rw-r--r--rt/html/Admin/Global/index.html94
-rw-r--r--rt/html/Admin/Groups/CustomFields.html48
-rw-r--r--rt/html/Admin/Groups/GroupRights.html119
-rw-r--r--rt/html/Admin/Groups/History.html68
-rw-r--r--rt/html/Admin/Groups/Members.html168
-rw-r--r--rt/html/Admin/Groups/Modify.html174
-rw-r--r--rt/html/Admin/Groups/UserRights.html116
-rw-r--r--rt/html/Admin/Groups/index.html113
-rw-r--r--rt/html/Admin/Queues/CustomField.html87
-rw-r--r--rt/html/Admin/Queues/CustomFields.html72
-rw-r--r--rt/html/Admin/Queues/GroupRights.html134
-rw-r--r--rt/html/Admin/Queues/Modify.html193
-rw-r--r--rt/html/Admin/Queues/People.html210
-rw-r--r--rt/html/Admin/Queues/Scrip.html100
-rw-r--r--rt/html/Admin/Queues/Scrips.html87
-rw-r--r--rt/html/Admin/Queues/Template.html130
-rw-r--r--rt/html/Admin/Queues/Templates.html81
-rw-r--r--rt/html/Admin/Queues/UserRights.html114
-rw-r--r--rt/html/Admin/Queues/index.html86
-rw-r--r--rt/html/Admin/Tools/Configuration.html100
-rw-r--r--rt/html/Admin/Tools/index.html55
-rw-r--r--rt/html/Admin/Users/CustomFields.html71
-rw-r--r--rt/html/Admin/Users/History.html68
-rw-r--r--rt/html/Admin/Users/Memberships.html67
-rw-r--r--rt/html/Admin/Users/Modify.html445
-rw-r--r--rt/html/Admin/Users/MyRT.html132
-rw-r--r--rt/html/Admin/Users/index.html115
-rw-r--r--rt/html/Admin/autohandler53
-rw-r--r--rt/html/Admin/index.html101
-rw-r--r--rt/html/Approvals/Display.html72
-rw-r--r--rt/html/Approvals/Elements/Approve94
-rw-r--r--rt/html/Approvals/Elements/PendingMyApproval111
-rw-r--r--rt/html/Approvals/Elements/ShowDependency109
-rw-r--r--rt/html/Approvals/Elements/Tabs58
-rw-r--r--rt/html/Approvals/index.html90
-rw-r--r--rt/html/Callbacks/ActivityReports/Elements/Tabs/Default7
-rw-r--r--rt/html/Callbacks/ActivityReports/NoAuth/webrt.css/Default71
-rw-r--r--rt/html/Callbacks/ActivityReports/Search/Results.html/SearchActions7
-rw-r--r--rt/html/Callbacks/RT-WebCronTool/Elements/Tabs/Default13
-rw-r--r--rt/html/Callbacks/kStatistics/Elements/Tabs/Default11
-rw-r--r--rt/html/Developer/CronTool/autohandler9
-rw-r--r--rt/html/Developer/CronTool/index.html116
-rw-r--r--rt/html/Download/CustomFieldValue/dhandler77
-rw-r--r--rt/html/Download/Tabular/dhandler76
-rw-r--r--rt/html/Elements/AddCustomers59
-rw-r--r--rt/html/Elements/BevelBoxRaisedEnd50
-rw-r--r--rt/html/Elements/BevelBoxRaisedStart50
-rw-r--r--rt/html/Elements/Callback92
-rw-r--r--rt/html/Elements/Checkbox63
-rw-r--r--rt/html/Elements/CollectionAsTable/Header125
-rw-r--r--rt/html/Elements/CollectionAsTable/ParseFormat106
-rw-r--r--rt/html/Elements/CollectionAsTable/Row117
-rw-r--r--rt/html/Elements/CreateTicket50
-rw-r--r--rt/html/Elements/EditCustomField99
-rw-r--r--rt/html/Elements/EditCustomFieldBinary62
-rw-r--r--rt/html/Elements/EditCustomFieldCombobox68
-rw-r--r--rt/html/Elements/EditCustomFieldFreeform74
-rw-r--r--rt/html/Elements/EditCustomFieldImage62
-rw-r--r--rt/html/Elements/EditCustomFieldSelect128
-rw-r--r--rt/html/Elements/EditCustomFieldText67
-rw-r--r--rt/html/Elements/EditCustomFieldWikitext67
-rw-r--r--rt/html/Elements/EditCustomers63
-rwxr-xr-xrt/html/Elements/EditLinks177
-rw-r--r--rt/html/Elements/EmailInput0
-rw-r--r--rt/html/Elements/Error86
-rw-r--r--rt/html/Elements/Footer94
-rw-r--r--rt/html/Elements/FreesideInvoiceSearch20
-rw-r--r--rt/html/Elements/FreesideNewCust3
-rw-r--r--rt/html/Elements/FreesideSearch13
-rw-r--r--rt/html/Elements/FreesideSvcSearch11
-rw-r--r--rt/html/Elements/GotoTicket48
-rw-r--r--rt/html/Elements/Header172
-rw-r--r--rt/html/Elements/ListActions65
-rw-r--r--rt/html/Elements/Login138
-rw-r--r--rt/html/Elements/Logo56
-rw-r--r--rt/html/Elements/Menu134
-rw-r--r--rt/html/Elements/MessageBox74
-rw-r--r--rt/html/Elements/MyAdminQueues54
-rw-r--r--rt/html/Elements/MyRT100
-rwxr-xr-xrt/html/Elements/MyReminders73
-rw-r--r--rt/html/Elements/MyRequests49
-rw-r--r--rt/html/Elements/MySupportQueues54
-rw-r--r--rt/html/Elements/MyTickets49
-rw-r--r--rt/html/Elements/PageLayout256
-rw-r--r--rt/html/Elements/QueryString63
-rw-r--r--rt/html/Elements/QueueSummary92
-rw-r--r--rt/html/Elements/QuickCreate71
-rw-r--r--rt/html/Elements/Quicksearch61
-rw-r--r--rt/html/Elements/RT__Ticket/ColumnMap314
-rw-r--r--rt/html/Elements/Refresh69
-rw-r--r--rt/html/Elements/RefreshHomepage51
-rw-r--r--rt/html/Elements/ScrubHTML73
-rw-r--r--rt/html/Elements/Section51
-rw-r--r--rt/html/Elements/SelectAttachmentField56
-rw-r--r--rt/html/Elements/SelectBoolean71
-rw-r--r--rt/html/Elements/SelectCustomFieldOperator64
-rw-r--r--rt/html/Elements/SelectCustomFieldValue65
-rw-r--r--rt/html/Elements/SelectDate75
-rw-r--r--rt/html/Elements/SelectDateRelation60
-rw-r--r--rt/html/Elements/SelectDateType60
-rw-r--r--rt/html/Elements/SelectEqualityOperator64
-rw-r--r--rt/html/Elements/SelectGroups62
-rw-r--r--rt/html/Elements/SelectLang80
-rw-r--r--rt/html/Elements/SelectLinkType61
-rw-r--r--rt/html/Elements/SelectMatch82
-rw-r--r--rt/html/Elements/SelectNewTicketQueue50
-rw-r--r--rt/html/Elements/SelectOwner110
-rw-r--r--rt/html/Elements/SelectQueue97
-rw-r--r--rt/html/Elements/SelectResultsPerPage68
-rw-r--r--rt/html/Elements/SelectSortOrder65
-rw-r--r--rt/html/Elements/SelectStatus67
-rw-r--r--rt/html/Elements/SelectTicketSortBy62
-rw-r--r--rt/html/Elements/SelectTicketTypes58
-rwxr-xr-xrt/html/Elements/SelectTimeUnits57
-rw-r--r--rt/html/Elements/SelectUsers62
-rw-r--r--rt/html/Elements/SelectWatcherType71
-rw-r--r--rt/html/Elements/SetupSessionCookie126
-rw-r--r--rt/html/Elements/ShowCustomFieldBinary51
-rw-r--r--rt/html/Elements/ShowCustomFieldImage53
-rw-r--r--rt/html/Elements/ShowCustomFieldWikitext58
-rw-r--r--rt/html/Elements/ShowCustomFields115
-rw-r--r--rt/html/Elements/ShowLink64
-rwxr-xr-xrt/html/Elements/ShowLinks112
-rw-r--r--rt/html/Elements/ShowMemberships88
-rw-r--r--rt/html/Elements/ShowSearch126
-rw-r--r--rt/html/Elements/SimpleSearch58
-rw-r--r--rt/html/Elements/Submit86
-rw-r--r--rt/html/Elements/Tabs137
-rw-r--r--rt/html/Elements/TicketList179
-rw-r--r--rt/html/Elements/TitleBox51
-rw-r--r--rt/html/Elements/TitleBoxEnd51
-rw-r--r--rt/html/Elements/TitleBoxStart51
-rw-r--r--rt/html/Elements/ValidateCustomFields81
-rw-r--r--rt/html/Helpers/CalPopup.html129
-rw-r--r--rt/html/Helpers/EmailAutocomplete0
-rw-r--r--rt/html/NoAuth/Logout.html74
-rw-r--r--rt/html/NoAuth/Reminder.html50
-rw-r--r--rt/html/NoAuth/css/3.4-compat/body.css75
-rw-r--r--rt/html/NoAuth/css/3.4-compat/footer.css61
-rw-r--r--rt/html/NoAuth/css/3.4-compat/forms.css104
-rw-r--r--rt/html/NoAuth/css/3.4-compat/header.css88
-rw-r--r--rt/html/NoAuth/css/3.4-compat/login.css54
-rw-r--r--rt/html/NoAuth/css/3.4-compat/main.css69
-rw-r--r--rt/html/NoAuth/css/3.4-compat/misc.css49
-rw-r--r--rt/html/NoAuth/css/3.4-compat/nav.css106
-rw-r--r--rt/html/NoAuth/css/3.4-compat/quickbar.css82
-rw-r--r--rt/html/NoAuth/css/3.4-compat/ticket.css50
-rw-r--r--rt/html/NoAuth/css/3.4-compat/titlebox.css103
-rw-r--r--rt/html/NoAuth/css/3.4-compat/transactions.css83
-rw-r--r--rt/html/NoAuth/css/3.5-default/approvals.css97
-rwxr-xr-xrt/html/NoAuth/css/3.5-default/body.css81
-rw-r--r--rt/html/NoAuth/css/3.5-default/footer.css91
-rwxr-xr-xrt/html/NoAuth/css/3.5-default/forms.css136
-rw-r--r--rt/html/NoAuth/css/3.5-default/freeside.css82
-rw-r--r--rt/html/NoAuth/css/3.5-default/header.css152
-rw-r--r--rt/html/NoAuth/css/3.5-default/login.css85
-rw-r--r--rt/html/NoAuth/css/3.5-default/logo.css60
-rw-r--r--rt/html/NoAuth/css/3.5-default/main.css62
-rwxr-xr-xrt/html/NoAuth/css/3.5-default/misc.css92
-rw-r--r--rt/html/NoAuth/css/3.5-default/nav.css163
-rw-r--r--rt/html/NoAuth/css/3.5-default/quickbar.css98
-rw-r--r--rt/html/NoAuth/css/3.5-default/ticket.css57
-rw-r--r--rt/html/NoAuth/css/3.5-default/titlebox.css179
-rwxr-xr-xrt/html/NoAuth/css/3.5-default/transactions.css150
-rw-r--r--rt/html/NoAuth/css/autohandler53
-rw-r--r--rt/html/NoAuth/css/dhandler30
-rw-r--r--rt/html/NoAuth/css/print.css85
-rw-r--r--rt/html/NoAuth/images/autohandler28
-rw-r--r--rt/html/NoAuth/images/bplogo.gifbin0 -> 755 bytes
-rw-r--r--rt/html/NoAuth/images/css/cb-light.gifbin0 -> 186 bytes
-rw-r--r--rt/html/NoAuth/images/css/cb.gifbin0 -> 110 bytes
-rw-r--r--rt/html/NoAuth/images/css/cbr-b2g.gifbin0 -> 135 bytes
-rw-r--r--rt/html/NoAuth/images/css/cbr-b2lb.gifbin0 -> 137 bytes
-rw-r--r--rt/html/NoAuth/images/css/cbr-gray.gifbin0 -> 137 bytes
-rw-r--r--rt/html/NoAuth/images/css/cbr-trans.gifbin0 -> 183 bytes
-rw-r--r--rt/html/NoAuth/images/css/cbr.gifbin0 -> 110 bytes
-rw-r--r--rt/html/NoAuth/images/css/ct-light.gifbin0 -> 162 bytes
-rw-r--r--rt/html/NoAuth/images/css/ct.gifbin0 -> 110 bytes
-rw-r--r--rt/html/NoAuth/images/css/ctr-b2g.gifbin0 -> 136 bytes
-rw-r--r--rt/html/NoAuth/images/css/ctr-b2lb.gifbin0 -> 114 bytes
-rw-r--r--rt/html/NoAuth/images/css/ctr-gray.gifbin0 -> 138 bytes
-rw-r--r--rt/html/NoAuth/images/css/ctr-trans.gifbin0 -> 182 bytes
-rw-r--r--rt/html/NoAuth/images/css/ctr.gifbin0 -> 111 bytes
-rw-r--r--rt/html/NoAuth/images/css/dark-arrow-up.pngbin0 -> 346 bytes
-rw-r--r--rt/html/NoAuth/images/css/dark-arrow.pngbin0 -> 337 bytes
-rw-r--r--rt/html/NoAuth/images/css/fieldbg-autocomplete.gifbin0 -> 1164 bytes
-rw-r--r--rt/html/NoAuth/images/css/light-arrow-up.pngbin0 -> 348 bytes
-rw-r--r--rt/html/NoAuth/images/css/light-arrow.pngbin0 -> 340 bytes
-rw-r--r--rt/html/NoAuth/images/css/rolldown-arrow.gifbin0 -> 83 bytes
-rw-r--r--rt/html/NoAuth/images/css/rolldown-arrow.pngbin0 -> 259 bytes
-rw-r--r--rt/html/NoAuth/images/css/rollup-arrow.gifbin0 -> 82 bytes
-rw-r--r--rt/html/NoAuth/images/favicon.pngbin0 -> 335 bytes
-rw-r--r--rt/html/NoAuth/images/small-logo.pngbin0 -> 4887 bytes
-rw-r--r--rt/html/NoAuth/js/ahah.js80
-rw-r--r--rt/html/NoAuth/js/autohandler53
-rw-r--r--rt/html/NoAuth/js/cascaded.js66
-rw-r--r--rt/html/NoAuth/js/class.js62
-rw-r--r--rt/html/NoAuth/js/combobox.js265
-rw-r--r--rt/html/NoAuth/js/list.js159
-rw-r--r--rt/html/NoAuth/js/scriptaculous/controls.js0
-rw-r--r--rt/html/NoAuth/js/scriptaculous/effects.js0
-rw-r--r--rt/html/NoAuth/js/scriptaculous/prototype.js0
-rw-r--r--rt/html/NoAuth/js/scriptaculous/scriptaculous.js0
-rw-r--r--rt/html/NoAuth/js/titlebox-state.js83
-rw-r--r--rt/html/NoAuth/js/util.js250
-rw-r--r--rt/html/Prefs/Elements/Tabs72
-rw-r--r--rt/html/Prefs/MyRT.html151
-rw-r--r--rt/html/Prefs/Quicksearch.html96
-rw-r--r--rt/html/Prefs/Search.html108
-rw-r--r--rt/html/Prefs/SearchOptions.html114
-rw-r--r--rt/html/REST/1.0/Forms/queue/default170
-rw-r--r--rt/html/REST/1.0/Forms/queue/ns62
-rw-r--r--rt/html/REST/1.0/Forms/ticket/attachments135
-rwxr-xr-xrt/html/REST/1.0/Forms/ticket/comment152
-rw-r--r--rt/html/REST/1.0/Forms/ticket/default345
-rw-r--r--rt/html/REST/1.0/Forms/ticket/history200
-rw-r--r--rt/html/REST/1.0/Forms/ticket/links172
-rwxr-xr-xrt/html/REST/1.0/Forms/ticket/merge96
-rwxr-xr-xrt/html/REST/1.0/Forms/ticket/take135
-rw-r--r--rt/html/REST/1.0/Forms/transaction/default143
-rw-r--r--rt/html/REST/1.0/Forms/user/default188
-rw-r--r--rt/html/REST/1.0/Forms/user/ns65
-rw-r--r--rt/html/REST/1.0/NoAuth/mail-gateway84
-rw-r--r--rt/html/REST/1.0/autohandler56
-rw-r--r--rt/html/REST/1.0/dhandler316
-rw-r--r--rt/html/REST/1.0/logout51
-rw-r--r--rt/html/REST/1.0/search/dhandler56
-rw-r--r--rt/html/REST/1.0/search/ticket158
-rw-r--r--rt/html/REST/1.0/ticket/comment177
-rw-r--r--rt/html/REST/1.0/ticket/link123
-rw-r--r--rt/html/REST/1.0/ticket/merge102
-rwxr-xr-xrt/html/RTx/Statistics/CallsMultiQueue/Elements/Chart39
-rwxr-xr-xrt/html/RTx/Statistics/CallsMultiQueue/index.html330
-rwxr-xr-xrt/html/RTx/Statistics/CallsQueueDay/Elements/Chart29
-rw-r--r--rt/html/RTx/Statistics/CallsQueueDay/Results.tsv191
-rwxr-xr-xrt/html/RTx/Statistics/CallsQueueDay/index.html275
-rwxr-xr-xrt/html/RTx/Statistics/DayOfWeek/Elements/Chart26
-rwxr-xr-xrt/html/RTx/Statistics/DayOfWeek/index.html155
-rwxr-xr-xrt/html/RTx/Statistics/DurationAsString18
-rw-r--r--rt/html/RTx/Statistics/Elements/CollectionAsTable/Header126
-rw-r--r--rt/html/RTx/Statistics/Elements/CollectionAsTable/ParseFormat109
-rw-r--r--rt/html/RTx/Statistics/Elements/CollectionAsTable/Row112
-rw-r--r--rt/html/RTx/Statistics/Elements/ControlsAsTable/ControlBox103
-rw-r--r--rt/html/RTx/Statistics/Elements/ControlsAsTable/UpdatePage5
-rw-r--r--rt/html/RTx/Statistics/Elements/DateSelectRow55
-rwxr-xr-xrt/html/RTx/Statistics/Elements/DurationAsString18
-rw-r--r--rt/html/RTx/Statistics/Elements/GraphBox27
-rwxr-xr-xrt/html/RTx/Statistics/Elements/SelectMultiQueue81
-rw-r--r--rt/html/RTx/Statistics/Elements/StatColumnMap173
-rwxr-xr-xrt/html/RTx/Statistics/Elements/Tabs72
-rw-r--r--rt/html/RTx/Statistics/FAQ/index.html23
-rwxr-xr-xrt/html/RTx/Statistics/OpenStalled/Elements/Chart27
-rw-r--r--rt/html/RTx/Statistics/OpenStalled/Results.tsv114
-rwxr-xr-xrt/html/RTx/Statistics/OpenStalled/index.html188
-rwxr-xr-xrt/html/RTx/Statistics/Resolution/Elements/Chart29
-rw-r--r--rt/html/RTx/Statistics/Resolution/index.html269
-rwxr-xr-xrt/html/RTx/Statistics/TimeToResolve/Elements/Chart23
-rwxr-xr-xrt/html/RTx/Statistics/TimeToResolve/index.html75
-rwxr-xr-xrt/html/RTx/Statistics/UserTest/Elements/Chart28
-rwxr-xr-xrt/html/RTx/Statistics/UserTest/index.html54
-rwxr-xr-xrt/html/RTx/Statistics/index.html59
-rw-r--r--rt/html/Reports/Activity/ActivityDetail.html83
-rw-r--r--rt/html/Reports/Activity/ActivitySummary.html61
-rw-r--r--rt/html/Reports/Activity/Elements/LimitReport23
-rw-r--r--rt/html/Reports/Activity/Elements/MiniPlot57
-rw-r--r--rt/html/Reports/Activity/Elements/PrintFooter7
-rw-r--r--rt/html/Reports/Activity/Elements/PrintHeader32
-rw-r--r--rt/html/Reports/Activity/Elements/ScreenFooter13
-rw-r--r--rt/html/Reports/Activity/Elements/ScreenHeader8
-rw-r--r--rt/html/Reports/Activity/Elements/Tabs52
-rw-r--r--rt/html/Reports/Activity/Elements/Wrapper16
-rw-r--r--rt/html/Reports/Activity/ResolutionComments.html62
-rw-r--r--rt/html/Reports/Activity/ResolutionStatistics.html95
-rw-r--r--rt/html/Reports/Activity/index.html29
-rw-r--r--rt/html/Search/Build.html832
-rw-r--r--rt/html/Search/Bulk.html396
-rw-r--r--rt/html/Search/Chart188
-rw-r--r--rt/html/Search/Chart.html73
-rwxr-xr-xrt/html/Search/Edit.html88
-rw-r--r--rt/html/Search/Elements/BuildFormatString244
-rw-r--r--rt/html/Search/Elements/Chart139
-rw-r--r--rt/html/Search/Elements/DisplayOptions143
-rw-r--r--rt/html/Search/Elements/EditFormat116
-rw-r--r--rt/html/Search/Elements/EditQuery67
-rw-r--r--rt/html/Search/Elements/EditSearches103
-rw-r--r--rt/html/Search/Elements/NewListActions68
-rw-r--r--rt/html/Search/Elements/PickBasics176
-rw-r--r--rt/html/Search/Elements/PickCFs80
-rw-r--r--rt/html/Search/Elements/PickCriteria82
-rw-r--r--rt/html/Search/Elements/SearchPrivacy55
-rw-r--r--rt/html/Search/Elements/SearchesForObject65
-rw-r--r--rt/html/Search/Elements/SelectAndOr53
-rw-r--r--rt/html/Search/Elements/SelectChartType56
-rw-r--r--rt/html/Search/Elements/SelectGroup67
-rw-r--r--rt/html/Search/Elements/SelectGroupBy63
-rw-r--r--rt/html/Search/Elements/SelectLinks66
-rw-r--r--rt/html/Search/Elements/SelectPersonType84
-rw-r--r--rt/html/Search/Elements/SelectSearchObject60
-rw-r--r--rt/html/Search/Elements/SelectSearchesForObjects69
-rwxr-xr-xrt/html/Search/Results.html177
-rw-r--r--rt/html/Search/Results.rdf87
-rw-r--r--rt/html/Search/Results.tsv134
-rw-r--r--rt/html/Search/Simple.html107
-rw-r--r--rt/html/SelfService/Attachment/dhandler51
-rw-r--r--rt/html/SelfService/Closed.html56
-rw-r--r--rt/html/SelfService/Create.html117
-rwxr-xr-xrt/html/SelfService/CreateTicketInQueue.html63
-rw-r--r--rt/html/SelfService/Display.html235
-rw-r--r--rt/html/SelfService/Elements/GotoTicket48
-rw-r--r--rt/html/SelfService/Elements/Header49
-rw-r--r--rt/html/SelfService/Elements/MyRequests84
-rw-r--r--rt/html/SelfService/Elements/Tabs113
-rw-r--r--rt/html/SelfService/Error.html70
-rw-r--r--rt/html/SelfService/Prefs.html92
-rw-r--r--rt/html/SelfService/Update.html129
-rw-r--r--rt/html/SelfService/index.html54
-rw-r--r--rt/html/Ticket/Attachment/dhandler94
-rw-r--r--rt/html/Ticket/Create.html405
-rw-r--r--rt/html/Ticket/Display.html182
-rw-r--r--rt/html/Ticket/Elements/AddCustomers52
-rw-r--r--rt/html/Ticket/Elements/AddWatchers123
-rw-r--r--rt/html/Ticket/Elements/BulkLinks77
-rw-r--r--rt/html/Ticket/Elements/EditBasics117
-rw-r--r--rt/html/Ticket/Elements/EditCustomField57
-rw-r--r--rt/html/Ticket/Elements/EditCustomFields110
-rw-r--r--rt/html/Ticket/Elements/EditCustomers63
-rw-r--r--rt/html/Ticket/Elements/EditDates77
-rw-r--r--rt/html/Ticket/Elements/EditPeople93
-rw-r--r--rt/html/Ticket/Elements/EditWatchers81
-rwxr-xr-xrt/html/Ticket/Elements/FindAttachments95
-rwxr-xr-xrt/html/Ticket/Elements/LoadTextAttachments94
-rwxr-xr-xrt/html/Ticket/Elements/PreviewScrips133
-rw-r--r--rt/html/Ticket/Elements/Reminders168
-rw-r--r--rt/html/Ticket/Elements/ShowAttachments104
-rw-r--r--rt/html/Ticket/Elements/ShowBasics85
-rw-r--r--rt/html/Ticket/Elements/ShowCustomFields51
-rw-r--r--rt/html/Ticket/Elements/ShowCustomers38
-rw-r--r--rt/html/Ticket/Elements/ShowDates86
-rw-r--r--rt/html/Ticket/Elements/ShowDependencies65
-rw-r--r--rt/html/Ticket/Elements/ShowGroupMembers63
-rw-r--r--rt/html/Ticket/Elements/ShowHistory166
-rw-r--r--rt/html/Ticket/Elements/ShowMembers68
-rw-r--r--rt/html/Ticket/Elements/ShowMessageHeaders92
-rw-r--r--rt/html/Ticket/Elements/ShowMessageStanza84
-rw-r--r--rt/html/Ticket/Elements/ShowPeople68
-rw-r--r--rt/html/Ticket/Elements/ShowQueue9
-rw-r--r--rt/html/Ticket/Elements/ShowRequestor89
-rw-r--r--rt/html/Ticket/Elements/ShowSummary120
-rw-r--r--rt/html/Ticket/Elements/ShowTime55
-rw-r--r--rt/html/Ticket/Elements/ShowTransaction194
-rw-r--r--rt/html/Ticket/Elements/ShowTransactionAttachments215
-rw-r--r--rt/html/Ticket/Elements/ShowUserEntry61
-rw-r--r--rt/html/Ticket/Elements/Tabs250
-rw-r--r--rt/html/Ticket/History.html89
-rw-r--r--rt/html/Ticket/Modify.html91
-rw-r--r--rt/html/Ticket/ModifyAll.html221
-rw-r--r--rt/html/Ticket/ModifyCustomers.html49
-rw-r--r--rt/html/Ticket/ModifyDates.html77
-rw-r--r--rt/html/Ticket/ModifyLinks.html82
-rw-r--r--rt/html/Ticket/ModifyPeople.html94
-rwxr-xr-xrt/html/Ticket/Reminders.html71
-rw-r--r--rt/html/Ticket/ShowEmailRecord.html73
-rw-r--r--rt/html/Ticket/Update.html228
-rw-r--r--rt/html/Tools/Elements/Tabs84
-rw-r--r--rt/html/Tools/MyDay.html117
-rw-r--r--rt/html/Tools/Offline.html166
-rw-r--r--rt/html/Tools/Reports/CreatedByDates.html94
-rw-r--r--rt/html/Tools/Reports/Elements/Tabs89
-rw-r--r--rt/html/Tools/Reports/ResolvedByDates.html95
-rw-r--r--rt/html/Tools/Reports/ResolvedByOwner.html70
-rw-r--r--rt/html/Tools/Reports/index.html50
-rw-r--r--rt/html/Tools/index.html52
-rw-r--r--rt/html/User/Delegation.html107
-rw-r--r--rt/html/User/Elements/DelegateRights109
-rw-r--r--rt/html/User/Elements/GroupTabs84
-rw-r--r--rt/html/User/Elements/Tabs89
-rw-r--r--rt/html/User/Groups/Members.html160
-rw-r--r--rt/html/User/Groups/Modify.html157
-rw-r--r--rt/html/User/Groups/index.html67
-rw-r--r--rt/html/User/Prefs.html289
-rw-r--r--rt/html/Widgets/ComboBox69
-rw-r--r--rt/html/Widgets/SavedSearch158
-rw-r--r--rt/html/Widgets/SelectionBox243
-rw-r--r--rt/html/Widgets/TitleBox54
-rwxr-xr-xrt/html/Widgets/TitleBoxEnd59
-rwxr-xr-xrt/html/Widgets/TitleBoxStart86
-rw-r--r--rt/html/autohandler331
-rw-r--r--rt/html/index.html117
-rw-r--r--rt/html/l52
448 files changed, 41054 insertions, 0 deletions
diff --git a/rt/html/Admin/CustomFields/GroupRights.html b/rt/html/Admin/CustomFields/GroupRights.html
new file mode 100644
index 000000000..a416327c5
--- /dev/null
+++ b/rt/html/Admin/CustomFields/GroupRights.html
@@ -0,0 +1,172 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/CustomFieldTabs,
+ id => $id,
+ current_tab => "Admin/CustomFields/GroupRights.html?id=".$id,
+ Title => $title
+&>
+<& /Elements/ListActions, actions => \@results &>
+
+ <form method="post" action="GroupRights.html">
+ <input type="hidden" class="hidden" name="id" value="<% $CustomFieldObj->id %>" />
+
+
+<h1><&|/l&>System groups</&></h1>
+<table>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToSystemInternalGroups();
+% while (my $Group = $Groups->Next()) {
+ <tr align="right">
+ <td valign="top">
+ <% loc($Group->Type) %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+ Object => $CustomFieldObj &>
+ </td>
+ </tr>
+% }
+</table>
+<h1><&|/l&>User defined groups</&></h1>
+<table>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToUserDefinedGroups();
+% while (my $Group = $Groups->Next()) {
+ <tr align="right">
+ <td valign="top">
+ <% $Group->Name %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+ Object => $CustomFieldObj &>
+ </td>
+ </tr>
+% }
+</table>
+
+ <& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+
+ </form>
+
+<%INIT>
+
+
+
+
+
+
+if (!defined $id) {
+ $m->comp("/Elements/Error", Why => loc("No CustomField defined"));
+}
+
+my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
+$CustomFieldObj->Load($id) || $m->comp("/Elements/Error", Why => loc("Couldn't load CustomField [_1]",$id));
+
+my $Groups;
+
+ my ( $ACL, @results );
+
+ foreach my $arg (keys %ARGS) {
+ if ($arg =~ /GrantRight-(\d+)-(.*?)-(\d+)$/) {
+ my $principal_id = $1;
+ my $object_type = $2;
+ my $object_id = $3;
+ my $rights = $ARGS{$arg};
+
+ my $principal = RT::Principal->new($session{'CurrentUser'});
+ $principal->Load($principal_id);
+ my $obj;
+
+ if ($object_type eq 'RT::CustomField') {
+ $obj = RT::CustomField->new($session{'CurrentUser'});
+ $obj->Load($object_id);
+ } else {
+ push (@results, loc("System Error").
+ loc("Rights could not be granted for [_1]", $object_type));
+ next;
+ }
+
+ my @rights = ref($ARGS{$arg}) eq 'ARRAY' ? @{$ARGS{$arg}} : ($ARGS{$arg});
+ foreach my $right (@rights) {
+ next unless ($right);
+ my ($val, $msg) = $principal->GrantRight(Object => $obj, Right => $right);
+ push (@results, $msg);
+ }
+ }
+ elsif ($arg =~ /RevokeRight-(\d+)-(.*?)-(\d+)-(.*?)$/) {
+ my $principal_id = $1;
+ my $object_type = $2;
+ my $object_id = $3;
+ my $right = $4;
+
+ my $principal = RT::Principal->new($session{'CurrentUser'});
+ $principal->Load($principal_id);
+ next unless ($right);
+ my $obj;
+
+ if ($object_type eq 'RT::CustomField') {
+ $obj = RT::CustomField->new($session{'CurrentUser'});
+ $obj->Load($object_id);
+ } else {
+ push (@results, loc("System Error").
+ loc("Rights could not be revoked for [_1]", $object_type));
+ next;
+ }
+ my ($val, $msg) = $principal->RevokeRight(Object => $obj, Right => $right);
+ push (@results, $msg);
+ }
+}
+
+my $title = loc('Modify group rights for custom field [_1]', $CustomFieldObj->Name);
+
+</%INIT>
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/CustomFields/Modify.html b/rt/html/Admin/CustomFields/Modify.html
new file mode 100644
index 000000000..0202f0ad6
--- /dev/null
+++ b/rt/html/Admin/CustomFields/Modify.html
@@ -0,0 +1,258 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/CustomFieldTabs,
+ id => $CustomFieldObj->Id ,
+ current_tab => $current_tab,
+ Title => $title &>
+<& /Elements/ListActions, actions => \@results &>
+
+
+<form method="post" action="Modify.html" name="ModifyCustomField">
+<input type="hidden" class="hidden" name="id" value="<%$id %>" />
+<table>
+<tr>
+<td class="label"><&|/l&>Name</&></td>
+<td><input name="Name" value="<%$CustomFieldObj->Name%>" size="20" /></td></tr>
+<tr>
+<td class="label"><&|/l&>Description</&></td>
+<td><input name="Description" value="<%$CustomFieldObj->Description%>" size="80" /></td>
+</tr>
+
+<tr>
+<td class="label"><&|/l&>Type</&></td>
+<td><& /Admin/Elements/SelectCustomFieldType,
+ Name => "TypeComposite",
+ Default => $CustomFieldObj->TypeComposite, &>
+</td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Applies to</&></td>
+<td><& /Admin/Elements/SelectCustomFieldLookupType,
+ Name => "LookupType",
+ Default => $CustomFieldObj->LookupType, &>
+</td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Validation</&></td>
+<td>
+<& /Widgets/ComboBox,
+ Name => 'Pattern',
+ Default => $CustomFieldObj->Pattern,
+ Size => 20,
+ Values => [
+ '(?#Mandatory).',
+ '(?#Digits)^[\d.]+$',
+ '(?#Year)^[12]\d{3}$',
+ ],
+&>
+</td></tr>
+</tr>
+<tr>
+<td class="label">&nbsp;</td>
+<td>
+<input type="hidden" class="hidden" name="SetEnabled" value="1" />
+<input type="checkbox" class="checkbox" name="Enabled" value="1" <%$EnabledChecked%> /> <&|/l&>Enabled (Unchecking this box disables this custom field)</&>
+</td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Link values to</&></td>
+</td>
+<td><input size="60" name="LinkValueTo" value="<%$CustomFieldObj->LinkValueTo%>" />
+<div class="hints">
+<&|/l&>RT can make this custom field's values into hyperlinks to another service.</&>
+<&|/l&>Fill in this field with a URL.</&>
+<&|/l&>RT will replace <tt>__id__</tt> and <tt>__CustomField__</tt> with the record id and custom field value, respectively</&>
+</div>
+</td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Include page</&></td>
+</td>
+<td><input size="60" name="IncludeContentForValue" value="<%$CustomFieldObj->IncludeContentForValue%>" />
+<div class="hints">
+<&|/l&>RT can include content from another web service when showing this custom field.</&>
+<&|/l&>Fill in this field with a URL.</&>
+<&|/l&>RT will replace <tt>__id__</tt> and <tt>__CustomField__</tt> with the record id and custom field value, respectively</&>
+<i><&|/l&>Some browsers may only load content from the same domain as your RT server.</&></i>
+</div>
+</td>
+</tr>
+
+
+
+</table>
+<br />
+% if ($CustomFieldObj->Id && $CustomFieldObj->IsSelectionType) {
+<h2><&|/l&>Values</&></h2>
+<div>
+<& /Admin/Elements/EditCustomFieldValues, CustomField => $CustomFieldObj &>
+<& /Admin/Elements/AddCustomFieldValue, CustomField => $CustomFieldObj &>
+</div>
+% }
+<&/Elements/Submit&>
+</form>
+
+
+
+<%INIT>
+
+
+
+my $CustomFieldObj = RT::CustomField->new( $session{'CurrentUser'} );
+my ( $title, @results, $EnabledChecked, $Disabled);
+$EnabledChecked = "CHECKED";
+
+if ( !$id ) {
+ $title = loc("Create a CustomField");
+ $id = 'new';
+}
+else {
+
+ if ( $id eq 'new' ) {
+ my ( $val, $msg ) = $CustomFieldObj->Create(Name => $Name,
+ TypeComposite => $TypeComposite,
+ LookupType => $LookupType,
+ Description => $Description,
+ Pattern => $Pattern,);
+ $m->comp("/Elements/Error", Why => loc( "Could not create CustomField", $msg ) ) unless ($val);
+ push @results, $msg;
+ $title = loc( 'Created CustomField [_1]', $CustomFieldObj->Name() );
+ }
+ else {
+ $CustomFieldObj->Load($id) || $m->comp("/Elements/Error", Why => loc('No CustomField') );
+ $title = loc( 'Editing CustomField [_1]', $CustomFieldObj->Name() );
+
+ my @attribs = qw( Pattern Name TypeComposite LookupType Description LinkValueTo IncludeContentForValue);
+ my @aresults = UpdateRecordObject( AttributesRef => \@attribs,
+ Object => $CustomFieldObj,
+ ARGSRef => \%ARGS );
+
+ push @results, @aresults;
+
+ #we're asking about enabled on the web page but really care about disabled.
+ if ($Enabled == 1) {
+ $Disabled = 0;
+ }
+ else {
+ $Disabled = 1;
+ }
+ if ( ($SetEnabled) and ( $Disabled != $CustomFieldObj->Disabled) ) {
+ my ($code, $msg) = $CustomFieldObj->SetDisabled($Disabled);
+ push @results, loc('Enabled status: [_1]', loc_fuzzy($msg));
+ }
+
+ if ($CustomFieldObj->Disabled()) {
+ $EnabledChecked ="";
+ }
+ }
+
+ $id = $CustomFieldObj->id;
+}
+
+
+
+
+my $paramtag = "CustomField-".$CustomFieldObj->Id."-Value-";
+# Delete any fields that want to be deleted
+foreach my $key (keys %ARGS) {
+
+ next unless ($key =~ /^Delete-$paramtag(\d+)$/);
+ my ($val, $msg) = $CustomFieldObj->DeleteValue($1);
+ push (@results, $msg);
+
+
+}
+# Update any existing values
+my $values = $CustomFieldObj->ValuesObj;
+while (my $value = $values->Next) {
+ foreach my $attr qw(Name Description SortOrder Category) {
+ my $param = $paramtag.$value->Id."-".$attr;
+
+ if ( $ARGS{$param} && ($value->$attr() ne $ARGS{$param})) {
+ my $mutator = "Set$attr";
+ my ($id, $msg) = $value->$mutator($ARGS{$param});
+ push (@results, $msg);
+ }
+ }
+
+
+}
+
+
+
+# Add any new values
+if ($ARGS{$paramtag."new-Name"}) {
+ my ($id, $msg) = $CustomFieldObj->AddValue (
+ map { $_ => $ARGS{$paramtag."new-$_"} }
+ qw( Name Description SortOrder Category )
+ );
+ push (@results, $msg);
+}
+
+my $current_tab;
+if ($ARGS{'Create'}){
+ $current_tab = "Admin/CustomFields/Modify.html?Create=1";
+} else {
+ $current_tab = "Admin/CustomFields/Modify.html?id=".$id;
+ }
+
+
+</%INIT>
+<%ARGS>
+$id => undef
+$TypeComposite => undef
+$LookupType => undef
+$MaxValues => undef
+$SortOrder => undef
+$Description => undef
+$Pattern => undef
+$Name => undef
+$SetEnabled => undef
+$Enabled => undef
+</%ARGS>
diff --git a/rt/html/Admin/CustomFields/Objects.html b/rt/html/Admin/CustomFields/Objects.html
new file mode 100644
index 000000000..d829a0da3
--- /dev/null
+++ b/rt/html/Admin/CustomFields/Objects.html
@@ -0,0 +1,147 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/CustomFieldTabs,
+ id => $id,
+ current_tab => "Admin/CustomFields/Objects.html?id=".$id,
+ Title => $title
+ &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<form action="Objects.html" method="post">
+<input type="hidden" class="hidden" name="id" value="<% $id %>" />
+<input type="hidden" class="hidden" name="UpdateObjs" value="1" />
+
+<h2><&|/l&>Selected objects</&></h2>
+<& /Admin/Elements/PickObjects, Objects => \@AssignedObjs, id => $id, Checked => 1 &>
+<h2><&|/l&>Unselected objects</&></h2>
+<& /Admin/Elements/PickObjects, Objects => \@UnassignedObjs, id => $id &>
+
+<& /Elements/Submit, CheckAll => 1, ClearAll => 1 &>
+</form>
+
+<%INIT>
+my $CF = RT::CustomField->new($session{'CurrentUser'});
+$CF->Load($id) or Abort(loc("Could not load CustomField [_1]"), $id);
+my $LookupType = $CF->LookupType;
+$LookupType =~ /^(.*?)-/ ||
+ Abort(loc("Object of type [_1] cannot take custom fields", $LookupType));
+
+my $Class = $1;
+my $CollectionClass;
+if (UNIVERSAL::can($Class.'Collection', 'new') ) {
+$CollectionClass = $Class.'Collection';
+
+} elsif (UNIVERSAL::can($Class.'es', 'new') ) {
+ $CollectionClass = $Class.'es';
+
+} elsif (UNIVERSAL::can($Class.'s', 'new') ) {
+ $CollectionClass = $Class.'s';
+
+} else {
+ Abort(loc("Can't find a collection class for '[_1]'", $Class));
+}
+
+
+my $title = loc('Modify associated objects for [_1]', $CF->Name);
+
+my $Objects = $CollectionClass->new($session{'CurrentUser'});
+my (@results);
+my (@AssignedObjs, @UnassignedObjs);
+
+$Objects->UnLimit;
+$Objects->OrderBy( FIELD => 'Name' );
+
+
+my $ObjectCFs;
+$ObjectCFs = RT::ObjectCustomFields->new($session{'CurrentUser'});
+$ObjectCFs->UnLimit;
+$ObjectCFs->LimitToCustomField($id);
+
+my %seen;
+while (my $OCF = $ObjectCFs->Next) {
+ $seen{$OCF->ObjectId}++;
+}
+
+while (my $obj = $Objects->Next) {
+ my $obj_id = $obj->Id;
+
+ if ($UpdateObjs) {
+ # Go through and delete all the custom field relationships that this object
+ # no longer has
+ my $key = "Object-$obj_id-CF-$id";
+ if ($ARGS{$key}) {
+ if (!$seen{$obj_id}) {
+ my ($val, $msg) = $CF->AddToObject($obj);
+ push (@results, $msg);
+ push @UnassignedObjs, $obj if !$val;
+ }
+ }
+ else {
+ push @UnassignedObjs, $obj;
+ if ($seen{$obj_id}) {
+ my ($val, $msg) = $CF->RemoveFromObject($obj);
+ push (@results, $msg);
+ pop @UnassignedObjs if !$val;
+ }
+ }
+ }
+ elsif (!$seen{$obj_id}) {
+ push @UnassignedObjs, $obj;
+ }
+ next if @UnassignedObjs and $UnassignedObjs[-1] == $obj;
+ push @AssignedObjs, $obj;
+}
+
+</%INIT>
+<%ARGS>
+$id => undef
+$FindDisabledObjects => 0
+$UpdateObjs => 0
+</%ARGS>
diff --git a/rt/html/Admin/CustomFields/UserRights.html b/rt/html/Admin/CustomFields/UserRights.html
new file mode 100644
index 000000000..a7145977c
--- /dev/null
+++ b/rt/html/Admin/CustomFields/UserRights.html
@@ -0,0 +1,170 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/CustomFieldTabs, id => $id,
+current_tab => "Admin/CustomFields/UserRights.html?id=".$id,
+Title => $title, &>
+<& /Elements/ListActions, actions => \@results &>
+
+ <form method="post" action="UserRights.html">
+ <input type="hidden" class="hidden" name="id" value="<% $CustomFieldObj->id %>" />
+
+
+<table>
+
+% while (my $Member = $Users->Next()) {
+% my $UserObj = $Member->MemberObj->Object();
+% my $group = RT::Group->new($session{'CurrentUser'});
+% $group->LoadACLEquivalenceGroup($Member->MemberObj);
+ <tr align="right">
+ <td valign="top">
+ <% $UserObj->Name %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId=> $group->PrincipalId,
+ Object => $CustomFieldObj &>
+ </td>
+ </tr>
+% }
+ </table>
+
+ <& /Elements/Submit, Caption => loc("Be sure to save your changes"), Reset => 1 &>
+
+ </form>
+
+<%INIT>
+
+ #Update the acls.
+ my @results;
+foreach my $arg (keys %ARGS) {
+ if ($arg =~ /GrantRight-(\d+)-(.*?)-(\d+)$/) {
+ my $principal_id = $1;
+ my $object_type = $2;
+ my $object_id = $3;
+ my $rights = $ARGS{$arg};
+
+ my $principal = RT::Principal->new($session{'CurrentUser'});
+ $principal->Load($principal_id);
+ my $obj;
+
+ if ($object_type eq 'RT::CustomField') {
+ $obj = RT::CustomField->new($session{'CurrentUser'});
+ $obj->Load($object_id);
+
+ } else {
+ push (@results, loc("System Error").
+ loc("Rights could not be granted for [_1]",
+$object_type));
+ next;
+ }
+
+ my @rights = ref($ARGS{$arg}) eq 'ARRAY' ? @{$ARGS{$arg}} :
+($ARGS{$arg});
+ foreach my $right (@rights) {
+ next unless ($right);
+ my ($val, $msg) = $principal->GrantRight(Object => $obj, Right
+=> $right);
+ push (@results, $msg);
+ }
+ }
+ elsif ($arg =~ /RevokeRight-(\d+)-(.*?)-(\d+)-(.*?)$/) {
+ my $principal_id = $1;
+ my $object_type = $2;
+ my $object_id = $3;
+ my $right = $4;
+
+ my $principal = RT::Principal->new($session{'CurrentUser'});
+ $principal->Load($principal_id);
+ next unless ($right);
+ my $obj;
+
+ if ($object_type eq 'RT::CustomField') {
+ $obj = RT::CustomField->new($session{'CurrentUser'});
+ $obj->Load($object_id);
+ } else {
+ push (@results, loc("System Error").
+ loc("Rights could not be revoked for [_1]",
+$object_type));
+ next;
+ }
+ my ($val, $msg) = $principal->RevokeRight(Object => $obj, Right =>
+$right);
+ push (@results, $msg);
+ }
+}
+
+
+# {{{ Deal with setting up the display of current rights.
+
+
+
+if (!defined $id) {
+ $m->comp("/Elements/Error", Why => loc("No Class defined"));
+}
+
+my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
+$CustomFieldObj->Load($id) || $m->comp("/Elements/Error", Why => loc("Couldn't load Class [_1]",$id));
+
+# Find out which users we want to display ACL selects for
+my $Privileged = RT::Group->new($session{'CurrentUser'});
+$Privileged->LoadSystemInternalGroup('Privileged');
+my $Users = $Privileged->MembersObj();
+
+
+my $title = loc('Modify user rights for custom field [_1]', $CustomFieldObj->Name);
+
+# }}}
+
+</%INIT>
+
+<%ARGS>
+$id => undef
+$UserString => undef
+$UserOp => undef
+$UserField => undef
+</%ARGS>
diff --git a/rt/html/Admin/CustomFields/index.html b/rt/html/Admin/CustomFields/index.html
new file mode 100644
index 000000000..badee95a7
--- /dev/null
+++ b/rt/html/Admin/CustomFields/index.html
@@ -0,0 +1,93 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => loc('Select a Custom Field') &>
+<& /Admin/Elements/CustomFieldTabs,
+ current_tab => 'Admin/CustomFields/',
+ Title => loc('Select a Custom Field') &>
+
+% my @types;
+% my $prev_lookup = '';
+% while (my $CustomFieldObj = $CustomFields->Next) {
+% $CustomFieldObj->CurrentUserHasRight('AdminCustomField') or next;
+% my $lookup = $CustomFieldObj->FriendlyLookupType;
+% if ($lookup ne $prev_lookup) {
+% if ($prev_lookup) {
+</ul>
+% }
+<h2><% loc("Custom Fields for [_1]", $lookup) %></h2>
+<ul>
+% $prev_lookup = $lookup;
+% push @types, [$lookup, $CustomFieldObj->LookupType];
+% }
+%
+<li>
+<a href="Modify.html?id=<%$CustomFieldObj->id()%>"><%$CustomFieldObj->Name%>: <%$CustomFieldObj->Description%></a>
+</li>
+% }
+% if ($prev_lookup) {
+</ul>
+% }
+
+<form action="<%$RT::WebPath%>/Admin/CustomFields/index.html" method="get">
+<&|/l&>Only show custom fields for:</&>
+<select name="type">
+% for (@types) {
+<option value="<% $_->[1] %>"><% $_->[0] %></option>
+% }
+</select> <input type="submit" value="<%loc('Go!')%>" />
+</form>
+
+<%args>
+$type => undef
+</%args>
+<%INIT>
+my $CustomFields = RT::CustomFields->new($session{'CurrentUser'});
+$CustomFields->UnLimit();
+$CustomFields->LimitToLookupType($type) if defined $type;
+$CustomFields->OrderByCols( { FIELD => 'LookupType' }, { FIELD => 'Name' } );
+</%INIT>
diff --git a/rt/html/Admin/Elements/AddCustomFieldValue b/rt/html/Admin/Elements/AddCustomFieldValue
new file mode 100644
index 000000000..39916e5ab
--- /dev/null
+++ b/rt/html/Admin/Elements/AddCustomFieldValue
@@ -0,0 +1,74 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<b><&|/l&>Add Value</&></b>
+<table border="0">
+<tr><td>
+<&|/l&>Sort</&>:<br />
+<input size="3" name="CustomField-<%$CustomField->Id%>-Value-new-SortOrder" />
+</td>
+<td>
+<&|/l&>Name</&>:<br />
+<input type="text" size="30" name="CustomField-<%$CustomField->Id%>-Value-new-Name" />
+</td>
+<td>
+<&|/l&>Description</&>:<br />
+<input type="text" size="50" name="CustomField-<%$CustomField->Id%>-Value-new-Description" />
+</td>
+% if ($CustomField->Type ne 'Combobox') {
+<td>
+<&|/l&>Category</&>:<br />
+<input type="text" size="10" name="CustomField-<%$CustomField->Id%>-Value-new-Category" />
+</td>
+% }
+</tr>
+</table>
+<%init>
+</%init>
+<%args>
+$CustomField => undef
+</%args>
diff --git a/rt/html/Admin/Elements/ConfigureMyRT b/rt/html/Admin/Elements/ConfigureMyRT
new file mode 100644
index 000000000..363a3b6db
--- /dev/null
+++ b/rt/html/Admin/Elements/ConfigureMyRT
@@ -0,0 +1,80 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Action
+$OnSave
+$items
+$panes
+$current_portlets
+</%args>
+<%init>
+my $portlets = $current_portlets;
+my @panes;
+for my $pane (@$panes) {
+ push @panes, $m->comp(
+ '/Widgets/SelectionBox:new',
+ Action => $Action,
+ Name => $pane,
+ Available => $items,
+ AutoSave => 1,
+ OnSubmit => sub {
+ my $sel = shift;
+ $portlets->{$pane} = [
+ map { m/(\w+)-(.*)$}/;
+ { type => $1,
+ name => $2 } } @{ $sel->{Current} }
+ ];
+ $OnSave->( $portlets, $pane );
+ },
+ Selected => [ map { join( '-', @{$_}{qw/type name/} ) }
+ @{ $portlets->{$pane} } ]
+ );
+}
+
+return @panes;
+</%init>
diff --git a/rt/html/Admin/Elements/CreateUserCalled b/rt/html/Admin/Elements/CreateUserCalled
new file mode 100644
index 000000000..69183258e
--- /dev/null
+++ b/rt/html/Admin/Elements/CreateUserCalled
@@ -0,0 +1,50 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<form method="get" action="<% $RT::WebPath %>/Admin/Users/Create.html">
+<&|/l&>New user called</&> <input name="Name" size="10" /><input type="submit" class="button" value="<&|/l&>Create</&>" />
+</form>
diff --git a/rt/html/Admin/Elements/CustomFieldTabs b/rt/html/Admin/Elements/CustomFieldTabs
new file mode 100644
index 000000000..078dbe0de
--- /dev/null
+++ b/rt/html/Admin/Elements/CustomFieldTabs
@@ -0,0 +1,118 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Tabs,
+ current_tab => 'Admin/CustomFields/',
+ subtabs => $tabs,
+ current_subtab => $current_tab,
+ Title => $Title &>
+<%INIT>
+my $tabs;
+
+if ($id) {
+ my $cf = RT::CustomField->new( $session{'CurrentUser'} );
+ $cf->Load($id);
+ $tabs = {
+ this => {
+ title => $cf->Name,
+ path => "Admin/CustomFields/Modify.html?id=" . $id,
+ current_subtab => $current_tab,
+
+ subtabs => {
+
+ C => { title => loc('Basics'),
+ path => "Admin/CustomFields/Modify.html?id=" . $id,
+ },
+ F => { title => loc('Group Rights'),
+ path => "Admin/CustomFields/GroupRights.html?id="
+ . $id, },
+ G => {
+ title => loc('User Rights'),
+ path => "Admin/CustomFields/UserRights.html?id=" . $id,
+ },
+
+ } }
+
+ };
+
+
+ if ($cf->LookupType =~ /^RT::Queue/io) {
+ $tabs->{'this'}->{subtabs}->{D} = {
+ title => loc('Applies to'),
+ path => "Admin/CustomFields/Objects.html?id=" . $id,
+ };
+ }
+}
+
+if ($session{'CurrentUser'}->HasRight( Object => $RT::System, Right => 'AdminCustomField')) {
+ $tabs->{"A"} = { title => loc('Select custom field'),
+ path => "Admin/CustomFields/",
+ };
+ $tabs->{"B"} = { title => loc('New custom field'),
+ path => "Admin/CustomFields/Modify.html?Create=1",
+ separator => 1,
+ };
+}
+
+ # Now let callbacks add their extra tabs
+ $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+foreach my $tab (sort keys %{$tabs->{'this'}->{'subtabs'}}) {
+ if ($tabs->{'this'}->{'subtabs'}->{$tab}->{'path'} eq $current_tab) {
+ $tabs->{'this'}->{'subtabs'}->{$tab}->{'subtabs'} = $subtabs;
+ $tabs->{'this'}->{'subtabs'}->{$tab}->{'current_subtab'} = $current_subtab;
+ }
+}
+if( $id ) { $current_tab = "Admin/CustomFields/Modify.html?id=" . $id }
+</%INIT>
+<%ARGS>
+$Title => undef
+$id => undef
+$current_tab => undef
+$subtabs => undef
+$current_subtab => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/EditCustomField b/rt/html/Admin/Elements/EditCustomField
new file mode 100644
index 000000000..d6dda06f3
--- /dev/null
+++ b/rt/html/Admin/Elements/EditCustomField
@@ -0,0 +1,159 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/ListActions, actions => \@results &>
+
+
+<form method="post" action="CustomField.html">
+<input type="hidden" class="hidden" name="CustomField" value="<%$id %>" />
+<input type="hidden" class="hidden" name="Queue" value="<%$Queue%>" />
+
+<table width="100%" border="0">
+<tr><td align="right">
+<&|/l&>Name</&>:
+</td><td>
+<input name="Name" value="<%$CustomFieldObj->Name%>" size="20" />
+</td></tr>
+<tr><td align="right">
+<&|/l&>Description</&>:
+</td><td>
+<input name="Description" value="<%$CustomFieldObj->Description%>" size="80" />
+</td></tr>
+<tr><td align="right">
+<&|/l&>Type</&>:
+</td><td>
+<& /Admin/Elements/SelectCustomFieldType, Name => "Type", Default => $CustomFieldObj->Type &>
+</td></tr>
+<tr><td>
+</td><td>
+<input type="hidden" class="hidden" name="SetEnabled" value="1" />
+<input type="checkbox" class="checkbox" name="Enabled" value="1" <%$EnabledChecked%> /> <&|/l&>Enabled (Unchecking this box disables this custom field)</&>
+</td></tr>
+</table>
+
+<p>
+% if ($CustomFieldObj->Id and $CustomFieldObj->Type =~ /Select/) {
+<h2><&|/l&>Values</&></h2>
+<font size="-1">
+<& /Admin/Elements/EditCustomFieldValues, CustomField => $CustomFieldObj &>
+<& /Admin/Elements/AddCustomFieldValue, CustomField => $CustomFieldObj &>
+</font>
+% }
+<&/Elements/Submit, Label => loc('Create') &>
+</form>
+
+
+
+<%INIT>
+
+my $CustomFieldObj = RT::CustomField->new($session{'CurrentUser'});
+my $EnabledChecked = "CHECKED";
+my (@results);
+
+if (! $CustomField ) {
+ $title = loc("Create a CustomField");
+ $id = 'new';
+} else {
+
+ if ($CustomField eq 'new') {
+ my ($val, $msg) = $CustomFieldObj->Create(Queue => $Queue,
+ Name => $Name,
+ Type => $Type,
+ Description => $Description,
+ );
+
+ # if there is an error, then abort. But since at this point there's
+ # stuff already printed, clear it out.
+ # (This only works in conjunction with temporarily turning autoflush
+ # off in the files that use this component.)
+ unless ($val) {
+ $m->clear_buffer;
+ Abort(loc("Could not create CustomField: [_1]", $msg));
+ }
+ push @results, $msg;
+ $CustomFieldObj->SetSortOrder($CustomFieldObj->id);
+ $title = loc('Created CustomField [_1]', $CustomFieldObj->Name());
+ } else {
+ $CustomFieldObj->Load($CustomField) || Abort(loc('No CustomField'));
+ $title = loc('Editing CustomField [_1]', $CustomFieldObj->Name());
+
+ my @aresults = ProcessCustomFieldUpdates (
+ CustomFieldObj => $CustomFieldObj,
+ ARGSRef => \%ARGS );
+ push @results, @aresults;
+ }
+
+
+$id = $CustomFieldObj->id;
+
+ #we're asking about enabled on the web page but really care about disabled.
+ my $Disabled = ($Enabled ? 0 : 1);
+
+ if ( ($SetEnabled) and ( $Disabled != $CustomFieldObj->Disabled) ) {
+ my ($code, $msg) = $CustomFieldObj->SetDisabled($Disabled);
+ push @results, loc('Enabled status [_1]', loc_fuzzy($msg));
+ }
+
+ if ($CustomFieldObj->Disabled()) {
+ $EnabledChecked ="";
+ }
+
+}
+
+
+</%INIT>
+<%ARGS>
+$id => undef
+$title => undef
+$Queue => undef
+$CustomField => undef
+$Type => undef
+$Description => undef
+$Name => undef
+$SetEnabled => undef
+$Enabled => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/EditCustomFieldValues b/rt/html/Admin/Elements/EditCustomFieldValues
new file mode 100644
index 000000000..e7da87cf7
--- /dev/null
+++ b/rt/html/Admin/Elements/EditCustomFieldValues
@@ -0,0 +1,96 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% if (!$values->Count) {
+<p><em><&|/l&>(no values)</&></em></p>
+% return;
+% }
+<i><&|/l&>(Check box to delete)</&></i>
+<table>
+<tr>
+<td>&nbsp;</td>
+<td><&|/l&>Sort</&></td>
+<td><&|/l&>Name</&></td>
+<td><&|/l&>Description</&></td>
+% if ($CustomField->Type ne 'Combobox') {
+<td><&|/l&>Category</&></td>
+% }
+</tr>
+% while (my $value = $values->Next) {
+<tr>
+<td>
+<input type="checkbox" class="checkbox" name="Delete-CustomField-<%$CustomField->Id%>-Value-<%$value->Id%>" />
+</td>
+<td>
+<input size="3" name="CustomField-<%$CustomField->Id%>-Value-<%$value->Id%>-SortOrder" value="<%$value->SortOrder%>" />
+</td>
+<td>
+<input type="text" size="30" name="CustomField-<%$CustomField->Id%>-Value-<%$value->Id%>-Name" value="<%$value->Name%>" />
+</td>
+<td>
+<font size="-1">
+<input type="text" size="50" name="CustomField-<%$CustomField->Id%>-Value-<%$value->Id%>-Description" value="<%$value->Description%>" />
+</font>
+</td>
+% if ($CustomField->Type ne 'Combobox') {
+<td>
+<font size="-1">
+<input type="text" size="10" name="CustomField-<%$CustomField->Id%>-Value-<%$value->Id%>-Category" value="<%$value->Category%>" />
+</font>
+</td>
+% }
+</tr>
+% }
+</table>
+<%init>
+
+my $values = $CustomField->ValuesObj();
+
+</%init>
+<%args>
+$CustomField => undef
+</%args>
diff --git a/rt/html/Admin/Elements/EditCustomFields b/rt/html/Admin/Elements/EditCustomFields
new file mode 100644
index 000000000..9b1176a40
--- /dev/null
+++ b/rt/html/Admin/Elements/EditCustomFields
@@ -0,0 +1,205 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/ListActions, actions => \@results &>
+
+<form action="<%$RT::WebPath%><% $m->request_comp->path |n %>" method="post" name="EditCustomFields">
+<input type="hidden" class="hidden" name="id" value="<% $Object->Id %>" />
+<input type="hidden" class="hidden" name="ObjectType" value="<% $ObjectType %>" />
+<input type="hidden" class="hidden" name="SubType" value="<% $SubType %>" />
+<input type="hidden" class="hidden" name="UpdateCFs" value="1" />
+
+% if ($Object->Id) {
+<h2><&|/l&>Global Custom Fields</&></h2>
+<& PickCustomFields, CustomFields => \@GlobalCFs, ReadOnly => 1, id => $id, SubType => $SubType &>
+% }
+<h2><&|/l&>Selected Custom Fields</&></h2>
+<& PickCustomFields, CustomFields => [$ObjectCFs->CustomFields], id => $id, Checked => 1, SubType => $SubType &>
+<h2><&|/l&>Unselected Custom Fields</&></h2>
+<& PickCustomFields, CustomFields => \@UnassignedCFs, id => $id, SubType => $SubType &>
+
+<& /Elements/Submit, CheckAll => 1, ClearAll => 1 &>
+</form>
+
+
+<%INIT>
+my $CustomFields = RT::CustomFields->new($session{'CurrentUser'});
+my @results;
+my (@GlobalCFs, @UnassignedCFs);
+
+my $id = $Object->Id;
+if ($id and !$Object->CurrentUserHasRight('AssignCustomFields')) {
+ $m->out('<p><i>', loc('(No custom fields)'), '</i></p>');
+ return;
+}
+
+my $lookup = $ObjectType;
+$lookup .= "-$SubType" if $SubType;
+
+$CustomFields->LimitToLookupType($lookup);
+$CustomFields->OrderBy( FIELD => 'Name' );
+
+
+my ($GlobalCFs, $ObjectCFs);
+$ObjectCFs = RT::ObjectCustomFields->new($session{'CurrentUser'});
+$ObjectCFs->UnLimit;
+$ObjectCFs->LimitToObjectId($id);
+$ObjectCFs->LimitToLookupType($lookup);
+
+# Check sanity of SortOrders
+my %SortOrders;
+$SortOrders{$_->SortOrder}++
+ while ($_ = $ObjectCFs->Next);
+
+# If there are duplicates, run though and squash them
+if (grep {$_ > 1} values %SortOrders) {
+ my $i = 1;
+ while (my $ObjectCF = $ObjectCFs->Next) {
+ $ObjectCF->SetSortOrder($i++);
+ }
+ $ObjectCFs->GotoFirstItem;
+}
+
+# {{{ deal with moving sortorder of custom fields
+if ($CustomField and $Move) {
+ my $SourceObj = RT::ObjectCustomField->new($session{'CurrentUser'});
+ $SourceObj->LoadByCols( ObjectId => $id, CustomField => $CustomField );
+
+ my $TargetObj;
+ my $target_order = $SourceObj->SortOrder + $Move;
+ while (my $ObjectCF = $ObjectCFs->Next) {
+ my $this_order = $ObjectCF->SortOrder;
+
+ # if we have an exact match, finish the loop now
+ ($TargetObj = $ObjectCF, last) if $this_order == $target_order;
+
+ # otherwise, we need to apropos toward the general direction
+ # ... first, check the sign is correct
+ next unless ($this_order - $SourceObj->SortOrder) * $Move > 0;
+
+ # ... next, see if we already have a candidate
+ if ($TargetObj) {
+ # ... if yes, compare the delta and choose the smaller one
+ my $orig_delta = abs($TargetObj->SortOrder - $target_order);
+ my $this_delta = abs($this_order - $target_order);
+ next if $orig_delta < $this_delta;
+ }
+
+ $TargetObj = $ObjectCF;
+ }
+
+ if ($TargetObj) {
+ # swap their sort order
+ my ($s, $t) = ($SourceObj->SortOrder, $TargetObj->SortOrder);
+ $TargetObj->SetSortOrder($s);
+ $SourceObj->SetSortOrder($t);
+ # because order changed, we must redo search for subsequent uses
+ }
+
+ $ObjectCFs->GotoFirstItem;
+}
+# }}}
+
+if ($id) {
+ $GlobalCFs = RT::ObjectCustomFields->new($session{'CurrentUser'});
+ $GlobalCFs->LimitToObjectId(0);
+ $GlobalCFs->LimitToLookupType($lookup);
+}
+
+while (my $cf = $CustomFields->Next) {
+ my $cf_id = $cf->Id;
+
+ if ($GlobalCFs and $GlobalCFs->HasEntryForCustomField($cf_id)) {
+ push @GlobalCFs, $cf;
+ next;
+ }
+
+ if ($UpdateCFs) {
+ # Go through and delete all the custom field relationships that this object
+ # no longer has
+ my $key = "Object-$id-CF-$cf_id";
+ if ($ARGS{$key}) {
+ if (!$ObjectCFs->HasEntryForCustomField($cf_id)) {
+ my ($val, $msg) = $cf->AddToObject($Object);
+ push (@results, $msg);
+ push @UnassignedCFs, $cf if !$val;
+ }
+ }
+ else {
+ push @UnassignedCFs, $cf;
+ if ($ObjectCFs->HasEntryForCustomField($cf_id)) {
+ my ($val, $msg) = $cf->RemoveFromObject($Object);
+ push (@results, $msg);
+ pop @UnassignedCFs if !$val;
+ }
+ }
+ }
+ elsif (!$ObjectCFs->HasEntryForCustomField($cf_id)) {
+ push @UnassignedCFs, $cf;
+ }
+ else {
+ }
+}
+
+# redo search...
+$ObjectCFs = RT::ObjectCustomFields->new($session{'CurrentUser'});
+$ObjectCFs->UnLimit;
+$ObjectCFs->LimitToObjectId($id);
+$ObjectCFs->LimitToLookupType($lookup);
+
+</%INIT>
+<%ARGS>
+$title => undef
+$Move => undef
+$Source => undef
+$CustomField => undef
+$FindDisabledCustomFields => undef
+$UpdateCFs => 0
+$Object
+$ObjectType
+$SubType => ''
+</%ARGS>
diff --git a/rt/html/Admin/Elements/EditQueueWatchers b/rt/html/Admin/Elements/EditQueueWatchers
new file mode 100644
index 000000000..dc076f58a
--- /dev/null
+++ b/rt/html/Admin/Elements/EditQueueWatchers
@@ -0,0 +1,78 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%if ($Members->Count == 0 ) {
+<ul>
+<li><i><&|/l&>none</&></i>
+% } else {
+<i><&|/l&>(Check box to delete)</&></i><br /><br />
+<ul>
+% while (my $watcher=$Members->Next) {
+<li>
+<input type="checkbox" class="checkbox" name="Queue-<%$QueueObj->Id%>-DeleteWatcher-Type-<%$Watchers->Type%>-Principal-<%$watcher->MemberId%>" value="1"
+ unchecked />
+% if ($watcher->MemberObj->IsUser) {
+<a href="<%$RT::WebPath%>/Admin/Users/Modify.html?id=<%$watcher->MemberObj->ObjectId%>">
+% } else {
+<a href="<%$RT::WebPath%>/Admin/Groups/Modify.html?id=<%$watcher->MemberObj->ObjectId%>">
+% }
+<%$watcher->MemberObj->Object->Name%></a>
+% }
+% }
+</ul>
+
+<%INIT>
+my $Members = $Watchers->MembersObj;
+</%INIT>
+
+<%ARGS>
+$QueueObj => undef
+$Watchers => undef
+</%ARGS>
+
+
+
diff --git a/rt/html/Admin/Elements/EditScrip b/rt/html/Admin/Elements/EditScrip
new file mode 100644
index 000000000..edf949ba3
--- /dev/null
+++ b/rt/html/Admin/Elements/EditScrip
@@ -0,0 +1,183 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/ListActions, actions => \@actions &>
+
+<form method="post" action="Scrip.html">
+<input type="hidden" class="hidden" name="id" value="<% $id %>" />
+<input type="hidden" class="hidden" name="Queue" value="<% $Queue %>" />
+
+<&| /Widgets/TitleBox, title => loc('Scrip Fields') &>
+<table>
+
+<tr><td align="right"><&|/l&>Description</&>:</td><td>
+<input name="Scrip-<% $id %>-Description" value="<% $ARGS{"Scrip-$id-Description"} || $scrip->Description %>" />
+</td></tr>
+
+<tr><td align="right"><&|/l&>Condition</&>:</td><td>
+<& /Admin/Elements/SelectScripCondition,
+ Name => "Scrip-$id-ScripCondition",
+ Default => $ARGS{"Scrip-$id-ScripCondition"} || $scrip->ConditionObj->Id,
+&></td></tr>
+
+<tr><td align="right"><&|/l&>Action</&>:</td><td>
+<& /Admin/Elements/SelectScripAction,
+ Name => "Scrip-$id-ScripAction",
+ Default => $ARGS{"Scrip-$id-ScripAction"} || $scrip->ActionObj->Id,
+&></td></tr>
+
+<tr><td align="right"><&|/l&>Template</&>:</td><td>
+<& /Admin/Elements/SelectTemplate,
+ Name => "Scrip-$id-Template",
+ Default => $ARGS{"Scrip-$id-Template"} || $scrip->TemplateObj->Id,
+ Queue => $Queue,
+&></td></tr>
+
+<tr><td align="right"><&|/l&>Stage</&>:</td><td>
+<& /Admin/Elements/SelectStage,
+ Name => "Scrip-$id-Stage",
+ Default => $ARGS{"Scrip-$id-Stage"} || $scrip->Stage,
+&></td></tr>
+
+</table>
+</&>
+
+<& /Elements/Submit,
+ Label => $SubmitLabel,
+ Caption => loc("Be sure to save your changes"),
+ Reset => 1,
+&><br />
+
+<&| /Widgets/TitleBox, title => loc('User Defined conditions and actions') &>
+<table>
+<tr><td colspan="2">
+<i><&|/l&>(Use these fields when you choose 'User Defined' for a condition or action)</&></i>
+</td></tr>
+
+<tr><td class="labeltop"><&|/l&>Custom condition</&>:</td><td>
+<textarea cols="80" rows="5" name="Scrip-<% $id %>-CustomIsApplicableCode"><% $ARGS{"Scrip-$id-CustomIsApplicableCode"} || $scrip->CustomIsApplicableCode %></textarea>
+</td></tr>
+
+<tr><td class="labeltop"><&|/l&>Custom action preparation code</&>:</td><td>
+<textarea cols="80" rows="5" name="Scrip-<% $id %>-CustomPrepareCode"><% $ARGS{"Scrip-$id-CustomPrepareCode"} || $scrip->CustomPrepareCode %></textarea>
+</td></tr>
+
+<tr><td class="labeltop"><&|/l&>Custom action cleanup code</&>:</td><td>
+<textarea cols="80" rows="5" name="Scrip-<% $id %>-CustomCommitCode"><% $ARGS{"Scrip-$id-CustomCommitCode"} || $scrip->CustomCommitCode %></textarea>
+</td></tr>
+
+</table>
+</&>
+
+<& /Elements/Submit, Label => $SubmitLabel, Reset => 1 &>
+
+</form>
+<%init>
+
+my (@actions, $SubmitLabel);
+
+my $scrip = RT::Scrip->new( $session{'CurrentUser'} );
+
+if ( $id ) {
+ $scrip->Load( $id );
+ unless ( $id = $scrip->id ) {
+ push @actions, loc("Couldn't load scrip #[_1]", $id);
+ }
+ $SubmitLabel = loc('Update');
+}
+
+unless ( $id ) {
+ $id = 'new';
+ $SubmitLabel = loc('Create');
+}
+
+</%init>
+
+<%ARGS>
+$id => undef
+$title => undef
+$Queue => 0
+</%ARGS>
+
+<%METHOD Process>
+<%ARGS>
+$id => undef
+$Queue => undef
+</%ARGS>
+<%INIT>
+return ($id) unless $id;
+
+my $scrip = RT::Scrip->new( $session{'CurrentUser'} );
+if ( $id eq 'new' ) {
+ return $scrip->Create(
+ Queue => $Queue,
+ ScripAction => $ARGS{"Scrip-new-ScripAction"},
+ ScripCondition => $ARGS{"Scrip-new-ScripCondition"},
+ Template => $ARGS{"Scrip-new-Template"},
+ Description => $ARGS{"Scrip-new-Description"},
+ CustomPrepareCode => $ARGS{"Scrip-new-CustomPrepareCode"},
+ CustomCommitCode => $ARGS{"Scrip-new-CustomCommitCode"},
+ CustomIsApplicableCode => $ARGS{"Scrip-new-CustomIsApplicableCode"},
+ );
+}
+else {
+ $scrip->Load( $id );
+ return (undef, loc("Couldn't load scrip #[_1]", $id))
+ unless $scrip->id;
+
+ my @attribs = qw(Queue ScripAction ScripCondition Template Stage
+ Description CustomPrepareCode CustomCommitCode CustomIsApplicableCode);
+ my @results = UpdateRecordObject(
+ AttributesRef => \@attribs,
+ AttributePrefix => 'Scrip-'.$scrip->Id,
+ Object => $scrip,
+ ARGSRef => \%ARGS
+ );
+ return ($scrip->id, @results);
+}
+</%INIT>
+</%METHOD>
diff --git a/rt/html/Admin/Elements/EditScrips b/rt/html/Admin/Elements/EditScrips
new file mode 100644
index 000000000..f3ef8fbe5
--- /dev/null
+++ b/rt/html/Admin/Elements/EditScrips
@@ -0,0 +1,125 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/ListActions, actions => \@actions &>
+
+<form action="Scrips.html" method="post">
+<input type="hidden" class="hidden" name="id" value="<%$id%>" />
+
+<h2><&|/l&>Current Scrips</&></h2>
+% if ($Scrips->Count == 0 ) {
+<p><i><&|/l&>(No scrips)</&></i></p>
+% } else {
+<table width="100%">
+<p><i><&|/l&>(Check box to delete)</&></i></p>
+
+% while (my $scrip = $Scrips->Next ) {
+<tr>
+<td>
+<input type="checkbox" class="checkbox" name="DeleteScrip-<%$scrip->Id%>" value="1" />
+</td>
+<td>
+<a href="Scrip.html?id=<%$scrip->Id%>&Queue=<%$id%>"><% $scrip->Description || "<i>(".loc('no value').")</i>" |n %></a><br />
+<small><&|/l, loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name) &>[_1] [_2] with template [_3]</&></small>
+</td>
+</tr>
+% }
+
+</table>
+
+% }
+<& /Elements/Submit,
+ Caption => loc("Delete selected scrips"),
+ Label => loc("Delete") &>
+</form>
+
+<%init>
+my (@actions);
+
+my $Scrips = RT::Scrips->new($session{'CurrentUser'});
+
+
+my $QueueObj = RT::Queue->new($session{'CurrentUser'});
+if ($id) {
+ $QueueObj->Load($id);
+}
+
+if ($QueueObj->id) {
+ $Scrips->LimitToQueue($id);
+}
+else {
+ $Scrips->LimitToGlobal();
+}
+
+$Scrips->OrderBy( FIELD => 'description' );
+
+
+
+# {{{ deal with modifying and deleting existing scrips
+foreach my $key (keys %ARGS) {
+ # {{{ if we're trying to delete the scrip
+ if ($key =~ /^DeleteScrip-(\d+)/) {
+ my $id = $1;
+ my $scrip = new RT::Scrip($session{'CurrentUser'});
+ $scrip->Load($id);
+ my ($retval, $msg) = $scrip->Delete;
+ if ($retval) {
+ push @actions, loc("Scrip deleted");
+ }
+ else {
+ push @actions, $msg;
+ }
+ }
+ # }}}
+}
+# }}}
+</%init>
+
+<%ARGS>
+$id => undef
+$title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/EditTemplates b/rt/html/Admin/Elements/EditTemplates
new file mode 100644
index 000000000..5d770ef75
--- /dev/null
+++ b/rt/html/Admin/Elements/EditTemplates
@@ -0,0 +1,128 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/ListActions, actions => \@actions &>
+
+<form method="get" action="Templates.html">
+<input type="hidden" class="hidden" name="id" value="<%$id%>" />
+
+% if ($Templates->Count == 0 ) {
+<p><i><&|/l&>(No templates)</&></i></p>
+% } else {
+<table width="100%">
+<tr>
+<th>
+<i><&|/l&>(Check box to delete)</&></i>
+</th>
+<th>
+</th>
+</tr>
+% my $count;
+% while (my $TemplateObj = $Templates->Next) {
+<tr>
+<td>
+<input type="checkbox" class="checkbox" name="DeleteTemplate-<%$TemplateObj->Id%>" value="1" />
+</td>
+<td>
+<a href="Template.html?Queue=<%$id%>&Template=<%$TemplateObj->id()%>">
+<strong><% loc($TemplateObj->Name) %></strong></a>
+<br /><% loc($TemplateObj->Description) %>
+</td>
+</tr>
+
+% }
+</table>
+% }
+
+<& /Elements/Submit, Label => loc('Delete Template') &>
+</form>
+
+<%INIT>
+my $Templates = RT::Templates->new($session{'CurrentUser'});
+my $QueueObj = RT::Queue->new($session{'CurrentUser'});
+my @actions;
+
+if ($id) {
+ $QueueObj->Load($id);
+}
+
+if ($QueueObj->id) {
+ $Templates->LimitToQueue($id);
+}
+else {
+ $Templates->LimitToGlobal();
+}
+
+# Now let callbacks add their extra limits
+$m->comp('/Elements/Callback', Templates => $Templates, %ARGS);
+
+# {{{ deal with deleting existing templates
+foreach my $key (keys %ARGS) {
+ # {{{ if we're trying to delete the template
+ if ($key =~ /^DeleteTemplate-(\d+)/) {
+ my $id = $1;
+ my $TemplateObj = RT::Template->new($session{'CurrentUser'});
+ $TemplateObj->Load($id);
+ my ($retval, $msg) = $TemplateObj->Delete;
+ if ($retval) {
+ push @actions, loc("Template deleted");
+ }
+ else {
+ push @actions, $msg;
+ }
+ }
+ # }}}
+}
+# }}}
+</%INIT>
+<%ARGS>
+$id => 0
+$title => undef
+$Move => undef
+$Source => undef
+$Template => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/EditUserComments b/rt/html/Admin/Elements/EditUserComments
new file mode 100644
index 000000000..5035189da
--- /dev/null
+++ b/rt/html/Admin/Elements/EditUserComments
@@ -0,0 +1,56 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => "Comments about $name" &>
+<&|/l&>These comments aren't generally visible to the user</&>:<br />
+<input type="hidden" class="hidden" name="id" value="<%$id%>" />
+<textarea cols="60" rows="15" wrap="soft" name="Comments"><% $UserObj->Comments %></textarea>
+</form>
+
+<%ARGS>
+$UserObj => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/GlobalCustomFieldTabs b/rt/html/Admin/Elements/GlobalCustomFieldTabs
new file mode 100755
index 000000000..db69df817
--- /dev/null
+++ b/rt/html/Admin/Elements/GlobalCustomFieldTabs
@@ -0,0 +1,95 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/SystemTabs, subtabs => $tabs,
+ current_tab => 'Admin/Global/CustomFields/index.html',
+ current_subtab => $current_tab,
+ Title => $Title &>
+<%INIT>
+
+
+ my $tabs = {
+
+ A => { title => loc('Users'),
+ text => loc('Modify scrips which apply to all queues'),
+ path => 'Admin/Global/CustomFields/Users.html',
+ },
+ B => { title => loc('Groups'),
+ text => loc('Edit system templates'),
+ path => 'Admin/Global/CustomFields/Groups.html',
+ },
+
+ F => { title => loc('Tickets'),
+ text => loc('Modify global custom fields'),
+ path => 'Admin/Global/CustomFields/Queue-Tickets.html',
+ },
+
+ G => { title => loc('Ticket Transactions'),
+ text => loc('Modify global group rights'),
+ path => 'Admin/Global/CustomFields/Queue-Transactions.html',
+ },
+
+};
+ # Now let callbacks add their extra tabs
+ $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+ foreach my $tab (sort keys %{$tabs}) {
+ if ($tabs->{$tab}->{'path'} eq $current_tab) {
+ $tabs->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{$tab}->{"current_subtab"} = $current_subtab;
+ }
+ }
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+$current_tab => undef
+$subtabs => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/GroupTabs b/rt/html/Admin/Elements/GroupTabs
new file mode 100644
index 000000000..bf6a1cfa5
--- /dev/null
+++ b/rt/html/Admin/Elements/GroupTabs
@@ -0,0 +1,102 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Tabs,
+ subtabs => $tabs,
+ current_tab => 'Admin/Groups/',
+ current_subtab => $current_tab,
+ Title => $Title &>
+<%INIT>
+my $tabs;
+
+if ( $GroupObj and $GroupObj->id ) {
+$tabs->{"this"} = { class => "currentnav",
+ path => "Admin/Groups/Modify.html?id=" . $GroupObj->id,
+ title => $GroupObj->Name,
+ current_subtab => $current_subtab,
+ subtabs => {
+ C => { title => loc('Basics'),
+ path => "Admin/Groups/Modify.html?id=" . $GroupObj->id },
+
+ D => { title => loc('Members'),
+ path => "Admin/Groups/Members.html?id=" . $GroupObj->id },
+
+ F => { title => loc('Group Rights'),
+ path => "Admin/Groups/GroupRights.html?id=" . $GroupObj->id, },
+ G => { title => loc('User Rights'),
+ path => "Admin/Groups/UserRights.html?id=" . $GroupObj->id, },
+ H => { title => loc('History'),
+ path => "Admin/Groups/History.html?id=" . $GroupObj->id },
+ }
+}
+}
+$tabs->{"A"} = { title => loc('Select group'),
+ path => "Admin/Groups/", };
+$tabs->{"B"} = { title => loc('New group'),
+ path => "Admin/Groups/Modify.html?Create=1",
+ separator => 1, };
+
+# Now let callbacks add their extra tabs
+$m->comp( '/Elements/Callback', tabs => $tabs, %ARGS );
+foreach my $tab ( sort keys %{$tabs->{'this'}->{'subtabs'}} ) {
+ if ( $tabs->{'this'}->{'subtabs'}->{$tab}->{'path'} eq $current_tab ) {
+ $tabs->{'this'}->{'subtabs'}->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{'this'}->{'subtabs'}->{$tab}->{"current_subtab"} = $current_subtab;
+ }
+}
+ $tabs->{'this'}->{"current_subtab"} = $current_tab;
+ $current_tab = "Admin/Groups/Modify.html?id=".$GroupObj->id if $GroupObj;
+
+</%INIT>
+<%ARGS>
+$GroupObj => undef
+$subtabs => undef
+$current_subtab => undef
+$current_tab => undef
+$Title => undef
+</%ARGS>
+
diff --git a/rt/html/Admin/Elements/Header b/rt/html/Admin/Elements/Header
new file mode 100644
index 000000000..e9b0356a1
--- /dev/null
+++ b/rt/html/Admin/Elements/Header
@@ -0,0 +1,52 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, %ARGS &>
+
+<%ARGS>
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/ListGlobalCustomFields b/rt/html/Admin/Elements/ListGlobalCustomFields
new file mode 100644
index 000000000..24308fcd8
--- /dev/null
+++ b/rt/html/Admin/Elements/ListGlobalCustomFields
@@ -0,0 +1,61 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% my $count = 0;
+% while (my $CustomFieldObj = $CustomFields->Next) {
+% $count++;
+<font size="-1"><%$CustomFieldObj->id%>/<% loc($CustomFieldObj->Type) %>/<%$CustomFieldObj->Name%>: <%$CustomFieldObj->Description%></font>
+<br />
+% }
+% if (!$count) {
+<font size="-1"><&|/l&>(No custom fields)</&></font>
+% }
+
+<%init>
+my $CustomFields = new RT::CustomFields ($session{'CurrentUser'});
+$CustomFields->LimitToGlobal();
+</%INIT>
diff --git a/rt/html/Admin/Elements/ListGlobalScrips b/rt/html/Admin/Elements/ListGlobalScrips
new file mode 100644
index 000000000..e2e8b15aa
--- /dev/null
+++ b/rt/html/Admin/Elements/ListGlobalScrips
@@ -0,0 +1,76 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% if ($Scrips->Count == 0) {
+
+<p><i><&|/l&>(No scrips)</&></i></p>
+
+% } else {
+
+<ul>
+
+% while (my $scrip = $Scrips->Next ) {
+<li>
+<a href="<%$RT::WebPath%>/Admin/Global/Scrip.html?id=<%$scrip->Id%>&Queue=<%0%>">
+% if ($scrip->Description) {
+<% $scrip->Description %>
+% } else {
+<i>(<&|/l, $scrip->Id&>Scrip #[_1]</&>)</i>
+% }
+</a><br />
+<small><&|/l, loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name) &>[_1] [_2] with template [_3]</&></small>
+</li>
+% }
+
+</ul>
+
+% }
+
+<%init>
+my $Scrips = new RT::Scrips ($session{'CurrentUser'});
+$Scrips->LimitToGlobal();
+</%INIT>
diff --git a/rt/html/Admin/Elements/ModifyTemplate b/rt/html/Admin/Elements/ModifyTemplate
new file mode 100644
index 000000000..b667e056b
--- /dev/null
+++ b/rt/html/Admin/Elements/ModifyTemplate
@@ -0,0 +1,84 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table>
+<tr>
+<td align="right">
+<&|/l&>Name</&>:
+</td>
+<td>
+<input name="Name" value="<%$Name%>" size="20" /><br />
+</td>
+</tr>
+<tr>
+<td align="right">
+<&|/l&>Description</&>:
+</td>
+<td>
+<input name="Description" value="<%$Description%>" size="80" /><br />
+</td>
+</tr>
+<tr>
+<td align="right" valign="top">
+<&|/l&>Content</&>:<br />
+</td>
+<td>
+<textarea name="Content" rows="25" cols="80" wrap="soft">
+<%$Content%></textarea>
+</td>
+</tr>
+</table>
+
+<%INIT>
+
+</%INIT>
+
+<%ARGS>
+$Name => undef
+$Description => undef
+$Content => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/ObjectCustomFields b/rt/html/Admin/Elements/ObjectCustomFields
new file mode 100644
index 000000000..61a10cd2b
--- /dev/null
+++ b/rt/html/Admin/Elements/ObjectCustomFields
@@ -0,0 +1,111 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& $ObjectTabs,
+$id ? (
+ id => $Object->id,
+ current_tab => "Admin/$Types/CustomFields.html?$sub_type_url&id=".$id,
+ current_subtab => "Admin/$Types/CustomFields.html?$sub_type_url&id=".$id,
+ "${Type}Obj" => $Object,
+) : (
+ current_tab => "Admin/Global/CustomFields/${QualifiedType}s.html",
+),
+ Title => $title
+ &>
+
+<& /Admin/Elements/EditCustomFields, %ARGS, title => $title, Object => $Object &>
+<%INIT>
+# XXX TODO: Validate here?
+#$ObjectType =~ /^RT::(Queue|User|Group)$/
+# or Abort(loc("Object of type [_1] cannot take custom fields", $ObjectType));
+
+
+
+my $Type = $1;
+my $Types = $Type.'s';
+my $ObjectTabs;
+my $Object = $ObjectType->new($session{'CurrentUser'});
+
+
+my $QualifiedType;
+my $FriendlySubTypes;
+if ($SubType =~/^RT::(.*)$/) {
+ $FriendlySubTypes = RT::CustomField->new($session{'CurrentUser'})->FriendlyLookupType($Object->CustomFieldLookupType);
+ $QualifiedType = "$Type-$1";
+} else {
+ $QualifiedType = $Type;
+}
+
+if ($id) {
+ $Object->Load($id) || Abort(loc("Couldn't load object [_1]", $id));
+ $ObjectTabs = "/Admin/Elements/${Type}Tabs";
+} else {
+ $ObjectTabs = "/Admin/Elements/GlobalCustomFieldTabs";
+
+}
+
+my $title;
+if ($id) {
+$title = loc('Edit Custom Fields for [_1]', $Object->Name);
+}
+elsif ($SubType) {
+
+ $title= loc("Modify Custom Fields which apply to [_1] for all [_2]", loc(lc($FriendlySubTypes)), loc(lc($Types)));
+} else {
+ $title =loc("Modify Custom Fields which apply to all [_1]", loc(lc($Types)));
+
+}
+my $sub_type_url;
+$sub_type_url = "SubType=$SubType" if $SubType;
+
+</%INIT>
+<%ARGS>
+$id => undef
+$ObjectType
+$SubType => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/PickCustomFields b/rt/html/Admin/Elements/PickCustomFields
new file mode 100644
index 000000000..7b88433f1
--- /dev/null
+++ b/rt/html/Admin/Elements/PickCustomFields
@@ -0,0 +1,98 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% if (@CustomFields == 0) {
+<p><i><&|/l&>(None)</&></i></p>
+% } else {
+<table cellspacing="0" cellpadding="2">
+% my $count;
+% foreach my $CustomFieldObj (@CustomFields) {
+<tr>
+% if (!$ReadOnly) {
+ <td valign="top">
+<input type="checkbox" class="checkbox" name="Object-<%$id%>-CF-<%$CustomFieldObj->Id%>" value="1" <% $Checked ? 'CHECKED' : '' %>
+/>
+ </td>
+% }
+ <td valign="top">
+ <a href="<%$RT::WebPath%>/Admin/CustomFields/Modify.html?id=<%$CustomFieldObj->id()%>">
+% if ($CustomFieldObj->Name) {
+<b><%$CustomFieldObj->Name%></b>
+% } else {
+<i>(<&|/l&>no name</&>)</i>
+% }
+</a><br />
+ <%$CustomFieldObj->Description%>
+ </td>
+ <td valign="top">
+ <i><% $CustomFieldObj->FriendlyTypeComposite %></i>
+ </td>
+% # show 'move up' unless it's the first item
+% if ($count++ and $Checked) {
+ <td valign="top">
+ [<a href="<%$RT::WebPath%><% $m->request_comp->path |n %>?id=<%$id%>&SubType=<%$SubType%>&CustomField=<%$CustomFieldObj->id%>&Move=-1"><&|/l&>Move up</&></a>]
+% } else {
+ <td valign="top" align="right">
+% }
+
+% # show 'move down' unless it's the last item
+% if ($count != @CustomFields and $Checked) {
+% $m->print(' | ') if $count > 1;
+ [<a href="<%$RT::WebPath%><% $m->request_comp->path |n %>?id=<%$id%>&SubType=<%$SubType%>&CustomField=<%$CustomFieldObj->id%>&Move=1"><&|/l&>Move down</&></a>]
+% }
+ </td>
+</tr>
+% }
+</table>
+% }
+<%ARGS>
+@CustomFields
+$id
+$ReadOnly => 0
+$Checked => 0
+$SubType
+</%ARGS>
diff --git a/rt/html/Admin/Elements/PickObjects b/rt/html/Admin/Elements/PickObjects
new file mode 100644
index 000000000..5fc086350
--- /dev/null
+++ b/rt/html/Admin/Elements/PickObjects
@@ -0,0 +1,81 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% if (@Objects == 0) {
+<p><i><&|/l&>(None)</&></i></p>
+% } else {
+<table cellspacing="0" cellpadding="2">
+% my $count;
+% foreach my $Object (@Objects) {
+<tr>
+% my $id = "Object-".$Object->id."-CF-".$id;
+% if (!$ReadOnly) {
+ <td valign="top">
+<input type="checkbox" id="<% $id %>" name="<% $id %>" value="1" <% $Checked ? 'CHECKED' : ''%>
+/>
+ </td>
+% }
+ <td valign="top">
+ <label for="<% $id %>">
+% if ($Object->Name) {
+ <b><%$Object->Name%></b><br />
+% } else {
+ <i>(<%loc("no name")%>)</i><br />
+% }
+ <%$Object->can('Description') && $Object->Description%>
+ </label>
+ </td>
+</tr>
+% }
+</table>
+% }
+<%ARGS>
+@Objects
+$id
+$ReadOnly => 0
+$Checked => 0
+</%ARGS>
diff --git a/rt/html/Admin/Elements/QueueRightsForUser b/rt/html/Admin/Elements/QueueRightsForUser
new file mode 100644
index 000000000..15af78464
--- /dev/null
+++ b/rt/html/Admin/Elements/QueueRightsForUser
@@ -0,0 +1,64 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<ul>
+%while(my $ACE = $ACL->Next) {
+
+<li><checkbox name="delete_ace_<%$ACE->id%>" value="1"> <% loc($ACE->RightName) %> (<%$ACE->UserObj->RealName%>)
+
+%}
+</ul>
+
+<%INIT>
+my $ACL = new RT::ACL($session{'CurrentUser'});
+$ACL->LimitToQueue($QueueObj->id);
+$ACL->LimitPrincipalToUser($PrincipalId);
+</%INIT>
+<%ARGS>
+$PrincipalId => undef
+$QueueObj => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/QueueTabs b/rt/html/Admin/Elements/QueueTabs
new file mode 100644
index 000000000..0d0670468
--- /dev/null
+++ b/rt/html/Admin/Elements/QueueTabs
@@ -0,0 +1,120 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Tabs,
+ subtabs => $tabs,
+ current_tab => 'Admin/Queues/',
+ current_subtab => $current_tab,
+ Title => $Title &>
+
+<%INIT>
+my $tabs;
+if ($id) {
+ $tabs->{'this'} = {
+ title => $QueueObj->Name,
+ path => "Admin/Queues/Modify.html?id=".$id,
+ current_subtab => $current_tab,
+ subtabs => {
+ C => { title => loc('Basics'),
+ path => "Admin/Queues/Modify.html?id=".$id,
+ },
+ D => { title => loc('Watchers'),
+ path => "Admin/Queues/People.html?id=".$id,
+ },
+
+ E => { title => loc('Scrips'),
+ path => "Admin/Queues/Scrips.html?id=".$id,
+ },
+ F => { title => loc('Templates'),
+ path => "Admin/Queues/Templates.html?id=".$id,
+ },
+
+ G1 => { title => loc('Ticket Custom Fields'),
+ path => 'Admin/Queues/CustomFields.html?SubType=RT::Ticket&id='.$id,
+ },
+
+ G2 => { title => loc('Transaction Custom Fields'),
+ path => 'Admin/Queues/CustomFields.html?SubType=RT::Ticket-RT::Transaction&id='.$id,
+ },
+
+ H => { title => loc('Group Rights'),
+ path => "Admin/Queues/GroupRights.html?id=".$id,
+ },
+ I => { title => loc('User Rights'),
+ path => "Admin/Queues/UserRights.html?id=".$id,
+ }
+ }
+ };
+}
+if ($session{'CurrentUser'}->HasRight( Object => $RT::System, Right => 'AdminQueue')) {
+ $tabs->{"A"} = { title => loc('Select queue'),
+ path => "Admin/Queues/",
+ };
+ $tabs->{"B"} = { title => loc('New queue'),
+ path => "Admin/Queues/Modify.html?Create=1",
+ separator => 1, };
+}
+
+ # Now let callbacks add their extra tabs
+ $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+foreach my $tab ( sort keys %{$tabs->{'this'}->{'subtabs'}} ) {
+ if ( $tabs->{'this'}->{'subtabs'}->{$tab}->{'path'} eq $current_tab ) {
+ $tabs->{'this'}->{'subtabs'}->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{'this'}->{'subtabs'}->{$tab}->{"current_subtab"} = $current_subtab;
+ }
+}
+ $current_tab = "Admin/Queues/Modify.html?id=".$id if $id;
+</%INIT>
+
+<%ARGS>
+$QueueObj => undef
+$id => undef
+$subtabs => undef
+$current_subtab => undef
+$current_tab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectCustomFieldLookupType b/rt/html/Admin/Elements/SelectCustomFieldLookupType
new file mode 100644
index 000000000..ff8bfdb3b
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectCustomFieldLookupType
@@ -0,0 +1,60 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select NAME ="<%$Name%>">
+%for my $option ($cf->LookupTypes) {
+<option value="<%$option%>" <%$option eq $Default && "SELECTED"%>><% $cf->FriendlyLookupType($option) %></option>
+%}
+</select>
+<%INIT>
+my $cf = RT::CustomField->new($session{'CurrentUser'});
+
+</%INIT>
+<%ARGS>
+$Default=>undef
+$Name => 'LookupType'
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectCustomFieldType b/rt/html/Admin/Elements/SelectCustomFieldType
new file mode 100644
index 000000000..c913979e9
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectCustomFieldType
@@ -0,0 +1,60 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select NAME ="<%$Name%>">
+%for my $option ($cf->TypeComposites) {
+<option value="<%$option%>" <%$option eq $Default && "SELECTED"%>><% $cf->FriendlyTypeComposite($option) %></option>
+%}
+</select>
+<%INIT>
+my $cf = RT::CustomField->new($session{'CurrentUser'});
+
+</%INIT>
+<%ARGS>
+$Default=>undef
+$Name => 'TypeComposite'
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectGroups b/rt/html/Admin/Elements/SelectGroups
new file mode 100644
index 000000000..662273a0a
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectGroups
@@ -0,0 +1,62 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select multiple name="<%$Name%>" size="10">
+%while (my $group = $groups->Next) {
+<option value="<%$group->id%>"><%$group->Name%>
+%}
+</select>
+
+<%INIT>
+my $groups = new RT::Groups($session{'CurrentUser'});
+$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain);
+
+</%INIT>
+<%ARGS>
+$Name => 'groups'
+$Domain => 'UserDefined';
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectModifyGroup b/rt/html/Admin/Elements/SelectModifyGroup
new file mode 100644
index 000000000..4db67c53a
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectModifyGroup
@@ -0,0 +1,57 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%while ( $Group = $Groups->Next) {
+<a href="Modify.html?id=<%$Group->id%>"><%$Group->id%>: <%$Group->Name%></a><br />
+%}
+<%INIT>
+my ($Group);
+my $Groups = new RT::Groups($session{'CurrentUser'});
+$Groups->UnLimit;
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectModifyQueue b/rt/html/Admin/Elements/SelectModifyQueue
new file mode 100644
index 000000000..c3e6a98e4
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectModifyQueue
@@ -0,0 +1,57 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%while ( $queue = $queues->Next) {
+<a href="Modify.html?id=<%$queue->id%>"><%$queue->id%>: <%$queue->Name%></a><br />
+%}
+<%INIT>
+my ($queue);
+my $queues = new RT::Queues($session{'CurrentUser'});
+$queues->UnLimit;
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectModifyUser b/rt/html/Admin/Elements/SelectModifyUser
new file mode 100644
index 000000000..2b28402f9
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectModifyUser
@@ -0,0 +1,73 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%while ( $user = $users->Next) {
+<a href="Modify.html?id=<%$user->id%>"><%$user->id%>: <%$user->Name%></a><br />
+%}
+<%INIT>
+my ($user);
+my $users = new RT::Users($session{'CurrentUser'});
+$users->Limit(FIELD => 'id',
+ VALUE => $RT::SystemUser->id,
+ OPERATOR => '!=' );
+
+if (defined $IdLike) {
+$users->Limit(FIELD => 'Name',
+ VALUE => $IdLike,
+ OPERATOR => 'LIKE' );
+}
+if (defined $EmailLike) {
+$users->Limit(FIELD => 'EmailAddress',
+ VALUE => $EmailLike,
+ OPERATOR => 'LIKE');
+
+}
+</%INIT>
+<%ARGS>
+$IdLike => undef
+$EmailLike => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectNewGroupMembers b/rt/html/Admin/Elements/SelectNewGroupMembers
new file mode 100644
index 000000000..34d711fd0
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectNewGroupMembers
@@ -0,0 +1,99 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% if ($Show ne 'Groups') {
+<b><&|/l&>Users</&></b>
+<select multiple name="<%$Name%>Users" size="10">
+%while (my $user = $users->Next) {
+%next if $SkipUsers->{$user->id};
+<option value="User-<%$user->id%>"><%$user->Name%></option>
+%}
+</select>
+<br />
+% }
+% if ($Show ne 'Users') {
+<b><&|/l&>Groups</&></b>
+<select multiple name="<%$Name%>Groups" size="10">
+%while (my $group = $groups->Next) {
+%next if $SkipGroups->{$group->id};
+<option value="Group-<%$group->id%>"><%$group->Name%></option>
+%}
+</select>
+% }
+
+<%INIT>
+my $users = new RT::Users($session{'CurrentUser'});
+
+$users->Limit(
+ FIELD => 'id',
+ VALUE => $RT::SystemUser->id,
+ OPERATOR => '!=',
+ ENTRYAGGREGATOR => 'AND'
+);
+$users->Limit(
+ FIELD => 'id',
+ VALUE => $RT::Nobody->id,
+ OPERATOR => '!=',
+ ENTRYAGGREGATOR => 'AND'
+);
+$users->LimitToPrivileged();
+
+my $groups = new RT::Groups($session{'CurrentUser'});
+
+# self-recursive group membership considered harmful!
+$groups->Limit(FIELD => 'id', VALUE => $Group->id, OPERATOR => '!=' );
+$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined');
+
+
+</%INIT>
+<%ARGS>
+$Name => 'Users'
+$Show => 'All'
+$Group
+$SkipUsers => {}
+$SkipGroups => {}
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectRights b/rt/html/Admin/Elements/SelectRights
new file mode 100644
index 000000000..a0a5736f0
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectRights
@@ -0,0 +1,118 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<input type="hidden" class="hidden" name="CheckACL" value="<%$ACLDesc%>" />
+ <table border="0">
+<tr>
+<td valign="top" width="180" align="left">
+% my %current_rights;
+<h3><&|/l&>Current rights</&></h3>
+% if ($ACLObj->Count() == 0) {
+<i><&|/l&>No rights granted.</&></i> <br />
+% } else {
+<i>(<&|/l&>Check box to revoke right</&>)</i> <br />
+% while (my $right = $ACLObj->Next()) {
+% if ($right->RightName) {
+% $current_rights{$right->RightName} = 1;
+<input type="checkbox" class="checkbox" value="<%$right->Id%>" name="RevokeRight-<%$ACLDesc%>-<%$right->RightName%>" /> <% loc($right->RightName) %><br />
+% }
+% }
+% }
+</td>
+<td valign="top">
+<h3><&|/l&>New rights</&></h3>
+<select size="5" multiple name="GrantRight-<%$ACLDesc%>">
+% foreach $right (sort keys %Rights) {
+% next if $current_rights{$right};
+ <option value="<%$right%>"
+ ><% loc($right) %></option>
+% }
+<option value="" selected><&|/l&>(no value)</&></option>
+</select>
+</td>
+</tr>
+</table>
+<%INIT>
+ my ($right, $ACLDesc, $AppliesTo, %Rights);
+
+ # if the principal id points to a user, we really want to point
+ # to their ACL equivalence group. The machinations we're going through
+ # lead me to start to suspect that we really want users and groups
+ # to just be the same table. or _maybe_ that we want an object db.
+ my $princ = RT::Principal->new($RT::SystemUser);
+ $princ->Load($PrincipalId);
+ if ($princ->PrincipalType eq 'User') {
+ my $group = RT::Group->new($RT::SystemUser);
+ $group->LoadACLEquivalenceGroup($princ);
+ $PrincipalId = $group->PrincipalId;
+ }
+
+
+ my $ACLObj = new RT::ACL($session{'CurrentUser'});
+ my $ACE = new RT::ACE($session{'CurrentUser'});
+
+
+ $ACLObj->LimitToObject( $Object);
+ $ACLObj->LimitToPrincipal( Id => $PrincipalId);
+ $ACLObj->OrderBy(FIELD=>'RightName');
+
+ if (ref($Object) && UNIVERSAL::can($Object, 'AvailableRights')) {
+ %Rights = %{$Object->AvailableRights};
+ }
+
+ else {
+ %Rights = ( loc('System Error') => loc("No rights found") );
+ }
+
+ $ACLDesc = "$PrincipalId-".ref($Object)."-".$Object->Id;
+</%INIT>
+
+<%ARGS>
+$PrincipalType => undef
+$PrincipalId => undef
+$Object =>undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectScrip b/rt/html/Admin/Elements/SelectScrip
new file mode 100644
index 000000000..027efba3f
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectScrip
@@ -0,0 +1,72 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+<option value=""
+<% $Default eq undef && 'SELECTED' %>
+>-</option>
+%while (my $Scrip = $Scrips->Next) {
+<option value="<% $Scrip->Id %>"
+<% $Scrip->Id == $Default && 'SELECTED' %>
+><% loc($Scrip->Name) %>
+</option>
+%}
+</select>
+
+<%INIT>
+my $Scrips = RT::Scrips->new($session{'CurrentUser'});
+$Scrips->UnLimit;
+
+
+
+</%INIT>
+<%ARGS>
+
+$Default => undef
+$Name => 'Scrip'
+
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectScripAction b/rt/html/Admin/Elements/SelectScripAction
new file mode 100644
index 000000000..3bf2f174e
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectScripAction
@@ -0,0 +1,73 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+<option value=""
+<% ! defined $Default && 'SELECTED' %>
+>-</option>
+%while (my $ScripAction = $ScripActions->Next) {
+<option value="<%$ScripAction->Id%>"
+<% defined $Default && $ScripAction->Id == $Default && 'SELECTED' %>
+><% loc($ScripAction->Name) %>
+</option>
+%}
+</select>
+
+<%INIT>
+my $ScripActions = RT::ScripActions->new($session{'CurrentUser'});
+$ScripActions->UnLimit;
+$ScripActions->OrderBy(FIELD => 'Name');
+
+
+
+</%INIT>
+<%ARGS>
+
+$Default => undef
+$Name => 'ScripAction'
+
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectScripCondition b/rt/html/Admin/Elements/SelectScripCondition
new file mode 100644
index 000000000..3068730b8
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectScripCondition
@@ -0,0 +1,72 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+<option value=""
+<% ! defined $Default && 'SELECTED' %>
+>-</option>
+%while (my $ScripCondition = $ScripConditions->Next) {
+<option value="<%$ScripCondition->Id%>"
+<% defined $Default && $ScripCondition->Id == $Default && 'SELECTED' %>
+><% loc($ScripCondition->Name) %>
+</option>
+%}
+</select>
+
+<%INIT>
+my $ScripConditions = RT::ScripConditions->new($session{'CurrentUser'});
+$ScripConditions->UnLimit;
+$ScripConditions->OrderBy(FIELD => 'Name');
+
+
+</%INIT>
+<%ARGS>
+
+$Default => undef
+$Name => 'ScripCondition'
+
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectSingleOrMultiple b/rt/html/Admin/Elements/SelectSingleOrMultiple
new file mode 100644
index 000000000..4844b8dc5
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectSingleOrMultiple
@@ -0,0 +1,67 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+ <select name="<%$Name%>">
+ <option value="1" <%$SingleDefault%>><&|/l&>Single</&></option>
+ <option value="0" <%$MultipleDefault%>><&|/l&>Multiple</&></option>
+ </select>
+
+
+<%INIT>
+my ($SingleDefault, $MultipleDefault);
+if ($Default == 1) {
+ $SingleDefault = "SELECTED";
+}
+elsif ($Default == 0 ) {
+ $MultipleDefault = "SELECTED";
+}
+
+</%INIT>
+<%ARGS>
+$Name => 'Single'
+$Default => 1
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectStage b/rt/html/Admin/Elements/SelectStage
new file mode 100644
index 000000000..68bf48511
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectStage
@@ -0,0 +1,66 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+% foreach my $stage (@stages) {
+<option value="<%$stage%>"
+<% ($stage eq $Default) && 'SELECTED' %>
+><% loc($stage) %>
+</option>
+% }
+<%INIT>
+if ($Default eq '') {
+ $Default = 'TransactionCreate';
+}
+my @stages = 'TransactionCreate';
+push @stages, 'TransactionBatch' if $RT::UseTransactionBatch;
+push @stages, 'Disabled';
+</%INIT>
+<%ARGS>
+$Default => 'TransactionCreate'
+$Name => 'Stage'
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectTemplate b/rt/html/Admin/Elements/SelectTemplate
new file mode 100644
index 000000000..4f002c73a
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectTemplate
@@ -0,0 +1,87 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+<option value=""
+<% $Default eq 'none' && 'SELECTED' %>
+>-</option>
+%while (my $Template = $PrimaryTemplates->Next) {
+<option value="<%$Template->Id%>"
+<% ($Template->Id == $Default) && 'SELECTED' %>
+><% loc($Template->Name) %>
+</option>
+%}
+%while (my $Template = $OtherTemplates->Next) {
+<option value="<%$Template->Id%>"
+<% ($Template->Id == $Default) && 'SELECTED'%>
+><&|/l, loc($Template->Name) &>Global template: [_1]</&>
+</option>
+%}
+</select>
+
+<%INIT>
+
+
+my $PrimaryTemplates = RT::Templates->new($session{'CurrentUser'});
+if ($Queue != 0) {
+$PrimaryTemplates->LimitToQueue($Queue);
+$PrimaryTemplates->OrderBy(FIELD => 'Name');
+}
+
+my $OtherTemplates = RT::Templates->new($session{'CurrentUser'});
+$OtherTemplates->LimitToGlobal($DefaultQueue);
+$OtherTemplates->OrderBy(FIELD => 'Name');
+
+</%INIT>
+<%ARGS>
+
+$Queue => undef
+$Default => 'none'
+$DefaultQueue => undef
+$Name => 'Template'
+
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SelectUsers b/rt/html/Admin/Elements/SelectUsers
new file mode 100644
index 000000000..103ab30fc
--- /dev/null
+++ b/rt/html/Admin/Elements/SelectUsers
@@ -0,0 +1,64 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select multiple name="<%$Name%>" size="10">
+%while (my $user = $users->Next) {
+<option value="<%$user->id%>"><%$user->Name%>
+%}
+</select>
+
+<%INIT>
+my $users = new RT::Users($session{'CurrentUser'});
+
+$users->Limit(FIELD => 'id', VALUE => $RT::SystemUser->id, OPERATOR => '!=' );
+$users->Limit(FIELD => 'id', VALUE => $RT::Nobody->id, OPERATOR => '!=' );
+$users->LimitToPrivileged();
+
+</%INIT>
+<%ARGS>
+$Name => 'Users'
+</%ARGS>
diff --git a/rt/html/Admin/Elements/SystemTabs b/rt/html/Admin/Elements/SystemTabs
new file mode 100644
index 000000000..fd317c4fb
--- /dev/null
+++ b/rt/html/Admin/Elements/SystemTabs
@@ -0,0 +1,97 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Tabs, subtabs => $tabs,
+ current_tab => 'Admin/Global/',
+ current_subtab => $current_tab,
+ Title => $Title &>
+
+<%INIT>
+ my $tabs = {
+
+ A => { title => loc('Scrips'),
+ path => 'Admin/Global/Scrips.html',
+ },
+ B => { title => loc('Templates'),
+ path => 'Admin/Global/Templates.html',
+ },
+
+ F => { title => loc('Custom Fields'),
+ path => 'Admin/Global/CustomFields/index.html',
+ },
+
+ G => { title => loc('Group Rights'),
+ path => 'Admin/Global/GroupRights.html',
+ },
+ H => { title => loc('User Rights'),
+ path => 'Admin/Global/UserRights.html',
+ },
+ I => { title => loc('RT at a glance'),
+ path => 'Admin/Global/MyRT.html',
+ },
+
+};
+
+ # Now let callbacks add their extra tabs
+ $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+ foreach my $tab (sort keys %{$tabs}) {
+ if ($tabs->{$tab}->{'path'} eq $current_tab) {
+ $tabs->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{$tab}->{"current_subtab"} = $current_subtab;
+ }
+ }
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+$current_tab => undef
+$subtabs => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/Tabs b/rt/html/Admin/Elements/Tabs
new file mode 100644
index 000000000..40df82ac3
--- /dev/null
+++ b/rt/html/Admin/Elements/Tabs
@@ -0,0 +1,93 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Tabs,
+ tabs => $tabs,
+ current_toptab => 'Admin/',
+ current_tab => $current_tab,
+ Title => $Title &>
+
+<%INIT>
+ my $tabs = { A => { title => loc('Users'),
+ path => 'Admin/Users/',
+ },
+ B => { title => loc('Groups'),
+ path => 'Admin/Groups/',
+ },
+ C => { title => loc('Queues'),
+ path => 'Admin/Queues/',
+ },
+ D => { 'title' => loc('Custom Fields'),
+ path => 'Admin/CustomFields/',
+ },
+ E => { 'title' => loc('Global'),
+ path => 'Admin/Global/',
+ },
+ F => { 'title' => loc('Tools'),
+ path => 'Admin/Tools/',
+ },
+ };
+
+ # Now let callbacks add their extra tabs
+ $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+ foreach my $tab (sort keys %{$tabs}) {
+ if ($tabs->{$tab}->{'path'} eq $current_tab) {
+ $tabs->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{$tab}->{"current_subtab"} = $current_subtab;
+ }
+ }
+
+</%INIT>
+
+
+<%ARGS>
+$subtabs => undef
+$current_tab => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/ToolTabs b/rt/html/Admin/Elements/ToolTabs
new file mode 100755
index 000000000..37ba33e8e
--- /dev/null
+++ b/rt/html/Admin/Elements/ToolTabs
@@ -0,0 +1,80 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Tabs, subtabs => $tabs,
+ current_tab => 'Admin/Tools/',
+ current_subtab => $current_tab,
+ Title => $Title &>
+
+<%INIT>
+ my $tabs = {
+
+ A => { title => loc('System Configuration'),
+ path => 'Admin/Tools/Configuration.html',
+ }
+
+};
+
+ # Now let callbacks add their extra tabs
+ $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+ foreach my $tab (sort keys %{$tabs}) {
+ if ($tabs->{$tab}->{'path'} eq $current_tab) {
+ $tabs->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{$tab}->{"current_subtab"} = $current_subtab;
+ }
+ }
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+$current_tab => undef
+$subtabs => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Elements/UserTabs b/rt/html/Admin/Elements/UserTabs
new file mode 100644
index 000000000..f5f8d0e68
--- /dev/null
+++ b/rt/html/Admin/Elements/UserTabs
@@ -0,0 +1,113 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Tabs,
+ subtabs => $tabs,
+ current_tab => 'Admin/Users/',
+ current_subtab => $current_tab,
+ Title => $Title &>
+<%INIT>
+my $tabs;
+if ($id) {
+$tabs->{'this'} = { title => eval { $UserObj->Name },
+
+ path => "Admin/Users/Modify.html?id=".$id,
+subtabs => {
+ Basics => { title => loc('Basics'),
+ path => "Admin/Users/Modify.html?id=".$id
+ },
+ Memberships => { title => loc('Memberships'),
+ path => "Admin/Users/Memberships.html?id=".$id
+ },
+ History => { title => loc('History'),
+ path => "Admin/Users/History.html?id=".$id
+ },
+ 'MyRT' => { title => loc('RT at a glance'),
+ path => "Admin/Users/MyRT.html?id=".$id
+ },
+# Scrips => { title => loc('Rights'),
+# path => "Admin/Users/Rights.html?id=".$id
+# }
+
+ }
+}
+}
+if ($session{'CurrentUser'}->HasRight( Object => $RT::System, Right => 'AdminUsers')) {
+ $tabs->{"A"} = { title => loc('Select user'),
+ path => "Admin/Users/",
+ };
+ $tabs->{"B"} = { title => loc('New user'),
+ path => "Admin/Users/Modify.html?Create=1",
+ separator => 1,
+ };
+}
+
+ # Now let callbacks add their extra tabs
+ $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+#foreach my $tab ( sort keys %{$tabs} ) {
+# if ( $tabs->{$tab}->{'path'} eq $current_subtab ) {
+# $tabs->{$tab}->{"current_subtab"} = $current_subtab;
+# }
+#}
+foreach my $tab ( sort keys %{$tabs->{'this'}->{'subtabs'}} ) {
+ if ( $tabs->{'this'}->{'subtabs'}->{$tab}->{'path'} eq $current_tab ) {
+ $tabs->{'this'}->{'subtabs'}->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{'this'}->{'subtabs'}->{$tab}->{"current_subtab"} = $current_subtab;
+ }
+}
+$tabs->{'this'}->{"current_subtab"} = $current_tab;
+$current_tab = "Admin/Users/Modify.html?id=".$id if $id;
+</%INIT>
+<%ARGS>
+$UserObj => undef
+$id => undef
+$current_tab => undef
+$subtabs => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Admin/Global/CustomFields/Groups.html b/rt/html/Admin/Global/CustomFields/Groups.html
new file mode 100644
index 000000000..62bd31cb2
--- /dev/null
+++ b/rt/html/Admin/Global/CustomFields/Groups.html
@@ -0,0 +1,58 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/GlobalCustomFieldTabs,
+ current_tab => "Admin/Global/CustomFields/Groups.html",
+ current_subtab => "Admin/Global/CustomFields/Groups.html",
+ Title => $title
+ &>
+ <& /Admin/Elements/EditCustomFields, %ARGS, title => $title, ObjectType => 'RT::Group', Object=> $object &>
+<%INIT>
+ my $title = loc( 'Edit Custom Fields for all groups');
+ my $object = RT::Group->new($session{'CurrentUser'});
+</%INIT>
diff --git a/rt/html/Admin/Global/CustomFields/Queue-Tickets.html b/rt/html/Admin/Global/CustomFields/Queue-Tickets.html
new file mode 100755
index 000000000..3feb4242f
--- /dev/null
+++ b/rt/html/Admin/Global/CustomFields/Queue-Tickets.html
@@ -0,0 +1,58 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/GlobalCustomFieldTabs,
+ current_tab => "Admin/Global/CustomFields/Queue-Tickets.html",
+ current_subtab => "Admin/Global/CustomFields/Queue-Tickets.html",
+ Title => $title
+ &>
+ <& /Admin/Elements/EditCustomFields, %ARGS, title => $title, ObjectType => 'RT::Queue', Object=> $object, SubType => 'RT::Ticket' &>
+<%INIT>
+ my $title = loc( 'Edit Custom Fields for tickets in all queues');
+ my $object = RT::Queue->new($session{'CurrentUser'});
+</%INIT>
diff --git a/rt/html/Admin/Global/CustomFields/Queue-Transactions.html b/rt/html/Admin/Global/CustomFields/Queue-Transactions.html
new file mode 100755
index 000000000..5f58a1833
--- /dev/null
+++ b/rt/html/Admin/Global/CustomFields/Queue-Transactions.html
@@ -0,0 +1,58 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/GlobalCustomFieldTabs,
+ current_tab => "Admin/Global/CustomFields/Queue-Transactions.html",
+ current_subtab => "Admin/Global/CustomFields/Queue-Transactions.html",
+ Title => $title
+ &>
+ <& /Admin/Elements/EditCustomFields, %ARGS, title => $title, ObjectType => 'RT::Queue', Object=> $object, SubType => 'RT::Ticket-RT::Transaction' &>
+<%INIT>
+ my $title = loc( 'Edit Custom Fields for tickets in all queues');
+ my $object = RT::Queue->new($session{'CurrentUser'});
+</%INIT>
diff --git a/rt/html/Admin/Global/CustomFields/Users.html b/rt/html/Admin/Global/CustomFields/Users.html
new file mode 100644
index 000000000..6f965b755
--- /dev/null
+++ b/rt/html/Admin/Global/CustomFields/Users.html
@@ -0,0 +1,58 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/GlobalCustomFieldTabs,
+ current_tab => "Admin/Global/CustomFields/Users.html",
+ current_subtab => "Admin/Global/CustomFields/Users.html",
+ Title => $title
+ &>
+ <& /Admin/Elements/EditCustomFields, %ARGS, title => $title, ObjectType => 'RT::User', Object=> $object &>
+<%INIT>
+ my $title = loc( 'Edit Custom Fields for all users');
+ my $object = RT::User->new($session{'CurrentUser'});
+</%INIT>
diff --git a/rt/html/Admin/Global/CustomFields/index.html b/rt/html/Admin/Global/CustomFields/index.html
new file mode 100644
index 000000000..b5c9fe8f3
--- /dev/null
+++ b/rt/html/Admin/Global/CustomFields/index.html
@@ -0,0 +1,93 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Callback, tabs => $tabs, %ARGS &>
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/GlobalCustomFieldTabs, Title => $title &>
+
+<ul>
+% foreach my $key (sort keys %$tabs) {
+<li><span><a href="<% $tabs->{$key}{path} %>"><% $tabs->{$key}{title} %></a></span><br />
+<% $tabs->{$key}{text} %>
+</li>
+% }
+</ul>
+
+<%INIT>
+my $title = loc("Global custom field configuration");
+
+my $tabs = {
+
+ A => {
+ title => loc('Users'),
+ text => loc('Select custom fields for all users'),
+ path => 'Users.html',
+ },
+ B => {
+ title => loc('Groups'),
+ text => loc('Select custom fields for all user groups'),
+ path => 'Groups.html',
+ },
+
+ F => {
+ title => loc('Tickets'),
+ text => loc('Select custom fields for tickets in all queues'),
+ path => 'Queue-Tickets.html',
+ },
+
+ G => {
+ title => loc('Ticket Transactions'),
+ text =>
+ loc('Select custom fields for transactions on tickets in all queues'),
+ path => 'Queue-Transactions.html',
+ },
+
+};
+
+
+$m->comp('/Elements/Callback', tabs => $tabs);
+</%INIT>
diff --git a/rt/html/Admin/Global/GroupRights.html b/rt/html/Admin/Global/GroupRights.html
new file mode 100644
index 000000000..7c863d53a
--- /dev/null
+++ b/rt/html/Admin/Global/GroupRights.html
@@ -0,0 +1,123 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => loc('Modify global group rights') &>
+<& /Admin/Elements/SystemTabs,
+ current_tab => 'Admin/Global/GroupRights.html',
+ Title => loc('Modify global group rights') &>
+<& /Elements/ListActions, actions => \@results &>
+
+ <form method="post" action="GroupRights.html">
+
+<&| /Widgets/TitleBox, title => loc('Modify global group rights.')&>
+
+<h1><&|/l&>System groups</&></h1>
+<table>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToSystemInternalGroups();
+% while (my $Group = $Groups->Next()) {
+ <tr align="right">
+ <td valign="top">
+ <% loc($Group->Type) %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+ Object =>$RT::System &>
+ </td>
+ </tr>
+% }
+</table>
+<h1><&|/l&>Roles</&></h1>
+<table>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToRolesForSystem();
+% while (my $Group = $Groups->Next()) {
+ <tr align="right">
+ <td valign="top">
+ <% loc($Group->Type) %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+ Object => $RT::System &>
+ </td>
+ </tr>
+% }
+</table>
+<h1><&|/l&>User defined groups</&></h1>
+<table>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToUserDefinedGroups();
+% while (my $Group = $Groups->Next()) {
+ <tr align="right">
+ <td valign="top">
+ <% $Group->Name %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+ Object => $RT::System &>
+ </td>
+ </tr>
+% }
+</table>
+
+ </&>
+ <& /Elements/Submit, Label => loc('Modify Group Rights'), Reset => 1 &>
+
+ </form>
+
+<%INIT>
+
+ #Update the acls.
+ my @results = ProcessACLChanges(\%ARGS);
+
+
+my $Groups;
+
+</%INIT>
+
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/Admin/Global/MyRT.html b/rt/html/Admin/Global/MyRT.html
new file mode 100644
index 000000000..8bbcb5d34
--- /dev/null
+++ b/rt/html/Admin/Global/MyRT.html
@@ -0,0 +1,104 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => loc("RT at a glance") &>
+<& /Admin/Elements/SystemTabs,
+ current_tab => 'Admin/Global/MyRT.html',
+ Title => loc("RT at a glance"),
+&>
+
+<& /Widgets/SelectionBox:header, nojs => 1 &>
+
+<& /Elements/ListActions, actions => \@actions &>
+<br />
+% for my $pane (@panes) {
+<&|/Widgets/TitleBox, title => loc('RT at a glance').': '.loc($pane->{Name}), bodyclass => "" &>
+<& /Widgets/SelectionBox:show, self => $pane, nojs => 1 &></&>
+<br />
+% }
+<%init>
+my @actions;
+
+my @items = map { [ "component-$_", $_ ] } sort @{$RT::HomepageComponents};
+my $sys = RT::System->new( $session{'CurrentUser'} );
+# XXX: put this in savedsearches_to_portlet_items
+for ( $m->comp( "/Search/Elements/SearchesForObject",
+ Object => $sys )) {
+ my ( $desc, $search ) = @$_;
+ my $SearchType = $search->Content->{'SearchType'} || 'Ticket';
+ if ( $SearchType eq 'Ticket' ) {
+ push @items, [ "system-$desc", $desc ];
+ } else {
+ my $oid = ref($sys) . '-' . $sys->Id . '-SavedSearch-' . $search->Id;
+ my $type =
+ ( $SearchType eq 'Ticket' )
+ ? 'Saved Search' : $SearchType; # loc
+ push @items, [ "saved-$oid", loc($type) . ": $desc" ];
+ }
+}
+
+my ($default_portlets) = $sys->Attributes->Named('HomepageSettings');
+
+my @panes = $m->comp(
+ '/Admin/Elements/ConfigureMyRT',
+ panes => ['body', 'summary'],
+ Action => 'MyRT.html',
+ items => \@items,
+ current_portlets => $default_portlets->Content,
+ OnSave => sub {
+ my ( $conf, $pane ) = @_;
+ $default_portlets->SetContent( $conf );
+ push @actions, loc( 'Global portlet [_1] saved.', $pane );
+ }
+);
+
+$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_, nojs => 1 )
+ for @panes;
+
+
+</%init>
+
diff --git a/rt/html/Admin/Global/Scrip.html b/rt/html/Admin/Global/Scrip.html
new file mode 100644
index 000000000..fc72ca969
--- /dev/null
+++ b/rt/html/Admin/Global/Scrip.html
@@ -0,0 +1,87 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/SystemTabs,
+ current_tab => 'Admin/Global/Scrips.html',
+ current_subtab => $current_subtab,
+ subtabs => $subtabs,
+ Title => $title &>
+
+<& /Elements/ListActions, actions => \@results &>
+<& /Admin/Elements/EditScrip, title => $title, %ARGS, id => $id &>
+
+<%init>
+my $subtabs = {
+ A => {
+ title => loc('Select scrip'),
+ path => "Admin/Global/Scrips.html",
+ },
+ B => {
+ title => loc('New scrip'),
+ path => "Admin/Global/Scrip.html?create=1&Queue=0",
+ separator => 1,
+ },
+};
+
+my $scrip = RT::Scrip->new( $session{'CurrentUser'} );
+my ($id, @results) = $m->comp( '/Admin/Elements/EditScrip:Process', %ARGS );
+
+my ($title, $current_subtab);
+if ( $id ) {
+ $current_subtab = "Admin/Global/Scrip.html?id=$id&Queue=0";
+ $title = loc("Modify a scrip which applies to all queues");
+ $subtabs->{"C"} = {
+ title => loc('Scrip #[_1]', $id),
+ path => "Admin/Global/Scrip.html?id=$id&Queue=0",
+ };
+}
+else {
+ $current_subtab = "Admin/Global/Scrip.html?create=1&Queue=0";
+ $title = loc("Add a scrip which will apply to all queues");
+}
+</%init>
diff --git a/rt/html/Admin/Global/Scrips.html b/rt/html/Admin/Global/Scrips.html
new file mode 100644
index 000000000..a5fe26757
--- /dev/null
+++ b/rt/html/Admin/Global/Scrips.html
@@ -0,0 +1,77 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/SystemTabs,
+ current_tab => 'Admin/Global/Scrips.html',
+ current_subtab => 'Admin/Global/Scrips.html',
+ subtabs => $subtabs,
+ Title => $title &>
+<& /Admin/Elements/EditScrips, title => $title, id => $id, %ARGS &>
+</form>
+<%init>
+
+my $subtabs = {
+ A => { title => loc('Select scrip'),
+ path => "Admin/Global/Scrips.html",
+ },
+ B => { title => loc('New scrip'),
+ path => "Admin/Global/Scrip.html?create=1&Queue=0",
+ separator => 1,
+ }
+ };
+my $title = loc("Modify scrips which apply to all queues");
+
+my (@actions);
+
+</%init>
+
+
+
+<%ARGS>
+$id => 0
+</%ARGS>
diff --git a/rt/html/Admin/Global/Template.html b/rt/html/Admin/Global/Template.html
new file mode 100644
index 000000000..9d5a40916
--- /dev/null
+++ b/rt/html/Admin/Global/Template.html
@@ -0,0 +1,125 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => loc("Modify template [_1]", $TemplateObj->id) &>
+<& /Admin/Elements/SystemTabs,
+ current_tab => 'Admin/Global/Templates.html',
+ current_subtab => $current_subtab,
+ subtabs => $subtabs,
+ Title => loc("Modify template [_1]", $TemplateObj->id) &>
+<& /Elements/ListActions, actions => \@results &>
+
+
+<form method="post" action="Template.html">
+%if ($Create ) {
+<input type="hidden" class="hidden" name="Template" value="new" />
+% } else {
+<input type="hidden" class="hidden" name="Template" value="<%$TemplateObj->Id%>" />
+% }
+
+%# hang onto the queue id
+<input type="hidden" class="hidden" name="Queue" value="<%$Queue%>" />
+
+<& /Admin/Elements/ModifyTemplate, Name => $TemplateObj->Name, Description => $TemplateObj->Description, Content => $TemplateObj->Content &>
+
+<& /Elements/Submit, Label => loc('Save Changes'), Reset => 1 &>
+</form>
+
+
+
+<%INIT>
+
+my $TemplateObj = new RT::Template($session{'CurrentUser'});
+my ($title, @results, $current_subtab);
+
+my $subtabs = {
+ A => { title => loc('Select template'),
+ path => "Admin/Global/Templates.html"
+ },
+ B => { title => loc('New template'),
+ path => "Admin/Global/Template.html?Create=1&Queue=0",
+ separator => 1,
+ }
+ };
+
+
+if ($Create) {
+ $current_subtab = "Admin/Global/Template.html?Create=1&Queue=0";
+ $title = loc("Create a template");
+}
+
+else {
+ if ($Template eq 'new') {
+ my ($val, $msg) = $TemplateObj->Create(Queue => $Queue, Name => $Name);
+ Abort(loc("Could not create template: [_1]", $msg)) unless ($val);
+ push @results, $msg;
+ }
+ else {
+ $TemplateObj->Load($Template) || Abort(loc('No Template'));
+ }
+ $title = loc('Modify template [_1]', loc($TemplateObj->Name()));
+
+
+}
+if ($TemplateObj->Id()) {
+ my @attribs = qw( Description Content Queue Name);
+ my @aresults = UpdateRecordObject( AttributesRef => \@attribs,
+ Object => $TemplateObj,
+ ARGSRef => \%ARGS);
+ $current_subtab = "Admin/Global/Template.html?Queue=0&Template=".$TemplateObj->Id();
+ $subtabs->{"C"} = { title => loc('Template #[_1]', $TemplateObj->Id()),
+ path => "Admin/Global/Template.html?Queue=0&Template=".$TemplateObj->Id(),
+ };
+ push @results, @aresults;
+}
+</%INIT>
+<%ARGS>
+$Queue => undef
+$Template => undef
+$Create => undef
+$Name => undef
+</%ARGS>
diff --git a/rt/html/Admin/Global/Templates.html b/rt/html/Admin/Global/Templates.html
new file mode 100644
index 000000000..afd290d3c
--- /dev/null
+++ b/rt/html/Admin/Global/Templates.html
@@ -0,0 +1,77 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title, FeedURI => 'templates' &>
+<& /Admin/Elements/SystemTabs,
+ current_tab => 'Admin/Global/Templates.html',
+ current_subtab => 'Admin/Global/Templates.html',
+ subtabs => $subtabs,
+ Title => $title &>
+<& /Admin/Elements/EditTemplates, title => $title, %ARGS &>
+</form>
+<%init>
+
+my $subtabs = {
+ A => { title => loc('Select template'),
+ path => "Admin/Global/Templates.html"
+ },
+ B => { title => loc('New template'),
+ path => "Admin/Global/Template.html?Create=1&Queue=0",
+ separator => 1,
+ }
+ };
+my $title = loc("Modify templates which apply to all queues");
+
+my (@actions);
+
+</%init>
+
+
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Global/UserRights.html b/rt/html/Admin/Global/UserRights.html
new file mode 100644
index 000000000..9276b1a19
--- /dev/null
+++ b/rt/html/Admin/Global/UserRights.html
@@ -0,0 +1,101 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => loc('Modify global user rights') &>
+<& /Admin/Elements/SystemTabs,
+ current_tab => 'Admin/Global/UserRights.html',
+ Title => loc('Modify global user rights') &>
+<& /Elements/ListActions, actions => \@results &>
+
+ <form method="post" action="UserRights.html">
+
+<&| /Widgets/TitleBox, title => loc('Modify global user rights.') &>
+
+<table>
+
+% while (my $Member = $Users->Next()) {
+% my $UserObj = $Member->MemberObj->Object();
+% my $group = RT::Group->new($session{'CurrentUser'});
+% $group->LoadACLEquivalenceGroup($Member->MemberObj);
+ <tr align="right">
+ <td valign="top">
+ <% $UserObj->Name %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId => $group->PrincipalId,
+ Object => $RT::System &>
+ </td>
+ </tr>
+% }
+</table>
+
+ </&>
+ <& /Elements/Submit, Label => loc('Modify User Rights'), Reset => 1 &>
+
+ </form>
+
+<%INIT>
+
+ #Update the acls.
+ my @results = ProcessACLChanges(\%ARGS);
+
+# {{{ Deal with setting up the display of current rights.
+
+
+# Find out which users we want to display ACL selects for
+my $Privileged = RT::Group->new($session{'CurrentUser'});
+$Privileged->LoadSystemInternalGroup('Privileged');
+my $Users = $Privileged->MembersObj();
+
+
+
+# }}}
+
+</%INIT>
+
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/Admin/Global/index.html b/rt/html/Admin/Global/index.html
new file mode 100644
index 000000000..77e9caa9c
--- /dev/null
+++ b/rt/html/Admin/Global/index.html
@@ -0,0 +1,94 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Callback, tabs => $tabs, %ARGS &>
+<& /Admin/Elements/Header, Title => loc('Admin/Global configuration') &>
+<& /Admin/Elements/SystemTabs,
+ Title => loc('Admin/Global configuration') &>
+
+<ul>
+% foreach my $key (sort keys %$tabs) {
+<li><span><a href="<% $tabs->{$key}{path} %>"><% $tabs->{$key}{title} %></a></span><br />
+<% $tabs->{$key}{text} %>
+</li>
+% }
+</ul>
+
+<%INIT>
+ my $tabs = {
+
+ A => { title => loc('Scrips'),
+ text => loc('Modify scrips which apply to all queues'),
+ path => 'Scrips.html',
+ },
+ B => { title => loc('Templates'),
+ text => loc('Edit system templates'),
+ path => 'Templates.html',
+ },
+
+ F => { title => loc('Custom Fields'),
+ text => loc('Modify global custom fields'),
+ path => 'CustomFields/index.html',
+ },
+
+ G => { title => loc('Group Rights'),
+ text => loc('Modify global group rights'),
+ path => 'GroupRights.html',
+ },
+ H => { title => loc('User Rights'),
+ text => loc('Modify global user rights'),
+ path => 'UserRights.html',
+ },
+ I => { title => loc('RT at a glance'),
+ text => loc('Modify the default "RT at a glance" view'),
+ path => 'MyRT.html',
+ },
+
+
+
+};
+</%INIT>
diff --git a/rt/html/Admin/Groups/CustomFields.html b/rt/html/Admin/Groups/CustomFields.html
new file mode 100644
index 000000000..8ffa54aab
--- /dev/null
+++ b/rt/html/Admin/Groups/CustomFields.html
@@ -0,0 +1,48 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/ObjectCustomFields, %ARGS, ObjectType => 'RT::Group' &>
diff --git a/rt/html/Admin/Groups/GroupRights.html b/rt/html/Admin/Groups/GroupRights.html
new file mode 100644
index 000000000..b81b6a938
--- /dev/null
+++ b/rt/html/Admin/Groups/GroupRights.html
@@ -0,0 +1,119 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => loc('Modify group rights for group [_1]', $GroupObj->Name) &>
+<& /Admin/Elements/GroupTabs,
+ GroupObj => $GroupObj,
+ current_tab => 'Admin/Groups/GroupRights.html?id='.$id,
+ Title => loc('Modify group rights for group [_1]', $GroupObj->Name) &>
+<& /Elements/ListActions, actions => \@results &>
+
+ <form method="post" action="GroupRights.html">
+ <input type="hidden" class="hidden" name="id" value="<% $GroupObj->id %>" />
+
+<&| /Widgets/TitleBox, title => loc('Modify group rights for group [_1]', $GroupObj->Name) &>
+
+<h1><&|/l&>System groups</&></h1>
+<table>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToSystemInternalGroups();
+% while (my $Group = $Groups->Next()) {
+ <tr align="right">
+ <td valign="top">
+ <% loc($Group->Type) %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+ PrincipalType => 'Group',
+ Object => $GroupObj &>
+ </td>
+ </tr>
+% }
+</table>
+<h1><&|/l&>User defined groups</&></h1>
+<table>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToUserDefinedGroups();
+% while (my $Group = $Groups->Next()) {
+ <tr align="right">
+ <td valign="top">
+ <% $Group->Name %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+ PrincipalType => 'Group',
+ Object => $GroupObj &>
+ </td>
+ </tr>
+% }
+</table>
+
+ </&>
+ <& /Elements/Submit, Label => loc('Modify Group Rights'), Reset => 1 &>
+
+ </form>
+
+<%INIT>
+
+ #Update the acls.
+ my @results = ProcessACLChanges(\%ARGS);
+
+
+if (!defined $id) {
+ Abort(loc("No Group defined"));
+}
+
+my $GroupObj = RT::Group->new($session{'CurrentUser'});
+$GroupObj->Load($id) || Abort(loc("Couldn't load group [_1]",$id));
+
+my $Groups;
+
+</%INIT>
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Groups/History.html b/rt/html/Admin/Groups/History.html
new file mode 100644
index 000000000..ee1d5539c
--- /dev/null
+++ b/rt/html/Admin/Groups/History.html
@@ -0,0 +1,68 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/GroupTabs,
+ id => $id,
+ GroupObj => $GroupObj,
+ current_subtab => $current_tab,
+ Title => $title &>
+
+<& /Ticket/Elements/ShowHistory,
+ Ticket => $GroupObj,
+ ShowDisplayModes => 0,
+&>
+
+<%INIT>
+my $current_tab = 'Admin/Groups/History.html?id='.$id;
+my $GroupObj = new RT::Group($session{'CurrentUser'});
+$GroupObj->Load($id) || Abort("Couldn't load group '$id'");
+my $title = loc("History of the group [_1]", $GroupObj->Name);
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Groups/Members.html b/rt/html/Admin/Groups/Members.html
new file mode 100644
index 000000000..77c3fb09f
--- /dev/null
+++ b/rt/html/Admin/Groups/Members.html
@@ -0,0 +1,168 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => "RT/Admin/Edit the group ". $Group->Name &>
+<& /Admin/Elements/GroupTabs, GroupObj => $Group,
+ current_tab => 'Admin/Groups/Members.html?id='.$id,
+ Title => "RT/Admin/Edit the group ". $Group->Name &>
+<& /Elements/ListActions, actions => \@results &>
+
+
+<&| /Widgets/TitleBox, title => loc('Editing membership for group [_1]', $Group->Name) &>
+
+<form action="<%$RT::WebPath%>/Admin/Groups/Members.html" method="post">
+<input type="hidden" class="hidden" name="id" value="<%$Group->Id%>" />
+<table width="100%">
+<tr>
+<td>
+<h3><&|/l&>Current members</&></h3>
+</td>
+<td>
+<h3><&|/l&>Add members</&></h3>
+</td>
+</tr>
+
+<tr>
+<td valign="top">
+
+% if ($Group->MembersObj->Count == 0 ) {
+<em><&|/l&>(No members)</&></em>
+% } else {
+<em><&|/l&>(Check box to delete)</&></em>
+<br />
+<br />
+<&|/l&>Users</&>
+% my $Users = $Group->UserMembersObj;
+% $Users->OrderBy( FIELD => $UserOrderBy, ORDER => $UserOrder );
+<ul>
+% while (my $user = $Users->Next()) {
+% $UsersSeen{$user->id} = 1 if $SkipSeenUsers;
+<li><input type="checkbox" class="checkbox" name="DeleteMember-<%$user->PrincipalObj->Id%>" value="1" />
+<%$user->Name%> (<%$user->RealName%>)
+% }
+</ul>
+<&|/l&>Groups</&>
+<ul>
+% my $GroupMembers = $Group->MembersObj;
+% $GroupMembers->LimitToGroups();
+% while (my $member = $GroupMembers->Next()) {
+% $GroupsSeen{$member->MemberId} = 1 if $SkipSeenGroups;
+<li><input type="checkbox" class="checkbox" name="DeleteMember-<%$member->MemberId%>" value="1" />
+<%$member->MemberObj->Object->Name%>
+% }
+</ul>
+% }
+</td>
+<td valign="top">
+<& /Admin/Elements/SelectNewGroupMembers, Name => "AddMembers", Group => $Group,
+ SkipUsers => \%UsersSeen, SkipGroups => \%GroupsSeen &>
+</td>
+</tr>
+</table>
+</&>
+<& /Elements/Submit, Label => loc('Modify Members'), Reset => 1 &>
+</form>
+
+
+<%INIT>
+
+my $Group = new RT::Group($session{'CurrentUser'});
+$Group->Load($id) || Abort(loc('Could not load group'));
+
+my (@results);
+
+my $key;
+foreach $key (keys %ARGS) {
+
+if ($key =~ /^DeleteMember-(\d+)$/) {
+ my $id = $1;
+ my ($val,$msg) = $Group->DeleteMember($id);
+ push (@results, $msg);
+}
+}
+
+# Make sure AddMembers is always an array
+my @AddMembers = (
+ ((ref $AddMembersUsers eq 'ARRAY') ? @{$AddMembersUsers} : ($AddMembersUsers)),
+ ((ref $AddMembersGroups eq 'ARRAY') ? @{$AddMembersGroups} : ($AddMembersGroups)),
+);
+
+foreach my $member (@AddMembers) {
+ next unless ($member);
+
+ my $principal;
+
+ if ($member =~ /^Group-(\d+)$/) {
+ $principal = RT::Group->new($session{'CurrentUser'});
+ $principal->Load($1);
+ } elsif ($member =~ /^User-(\d+)$/) {
+ $principal = RT::User->new($session{'CurrentUser'});
+ $principal->Load($1);
+ } else {
+ next;
+ }
+
+
+ my ($val, $msg) = $Group->AddMember($principal->PrincipalId);
+ push (@results, $msg);
+}
+
+my %UsersSeen;
+my %GroupsSeen;
+$GroupsSeen{$Group->id} = 1; # can't be a member of ourself
+
+</%INIT>
+
+<%ARGS>
+$AddMembersUsers => undef
+$AddMembersGroups => undef
+$id => undef
+$UserOrderBy => 'Name'
+$UserOrder => 'ASC'
+$SkipSeenUsers => 1
+$SkipSeenGroups => 1
+</%ARGS>
diff --git a/rt/html/Admin/Groups/Modify.html b/rt/html/Admin/Groups/Modify.html
new file mode 100644
index 000000000..f3c13fe6f
--- /dev/null
+++ b/rt/html/Admin/Groups/Modify.html
@@ -0,0 +1,174 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+
+<& /Admin/Elements/GroupTabs,
+ GroupObj => $Group,
+ current_tab => $current_tab,
+ Title => $title &>
+<& /Elements/ListActions, actions => \@results &>
+
+
+
+<form action="<%$RT::WebPath%>/Admin/Groups/Modify.html" method="post" enctype="multipart/form-data">
+
+%unless ($Group->Id) {
+<input type="hidden" class="hidden" name="id" value="new" />
+% } else {
+<input type="hidden" class="hidden" name="id" value="<%$Group->Id%>" />
+% }
+<table>
+<tr><td align="right">
+<&|/l&>Name</&>:
+</td>
+<td><input name="Name" value="<%$Group->Name%>" /></td>
+</tr>
+<tr>
+<td align="right">
+<&|/l&>Description</&>:</td><td colspan="3"><input name="Description" value="<%$Group->Description%>" size="60" /></td>
+</tr>
+% my $CFs = $Group->CustomFields;
+% while (my $CF = $CFs->Next) {
+<tr valign="top"><td align="right">
+<% $CF->Name %>:
+</td><td>
+<& /Elements/EditCustomField, CustomField => $CF,
+ Object => $Group,
+ ($Create ? (NamePrefix => 'Object-RT::Group--CustomField-')
+ : () )&>
+</td></tr>
+% }
+<tr>
+<td colspan="2">
+<input type="hidden" class="hidden" name="SetEnabled" value="1" />
+<input type="checkbox" class="checkbox" name="Enabled" value="1" <%$EnabledChecked%> /> <&|/l&>Enabled (Unchecking this box disables this group)</&><br />
+</td>
+</tr>
+<& /Elements/Callback, GroupObj => $Group, results => \@results, %ARGS &>
+</table>
+<& /Elements/Submit, Label => loc('Save Changes'), Reset => 1 &>
+</form>
+<%INIT>
+
+my $current_tab;
+my ($title, @results, $Disabled, $EnabledChecked);
+
+my $Group = RT::Group->new($session{'CurrentUser'});
+
+if ($Create) {
+ $current_tab = 'Admin/Groups/Modify.html?Create=1';
+ $title = loc("Create a new group");
+}
+
+else {
+ $current_tab = 'Admin/Groups/Modify.html?id='.$id;
+ if ($id eq 'new' ) {
+
+ my ($create_id, $create_msg) = $Group->CreateUserDefinedGroup(Name =>
+ "$Name");
+ unless ($create_id) {
+ Abort (loc("Group could not be created: [_1]", $create_msg));
+ }
+ $id = $Group->Id;
+ }
+ else {
+ $Group->Load($id) || Abort('Could not load group');
+ }
+
+
+ if ($id) {
+ $title = loc("Modify the group [_1]", $Group->Name);
+
+ }
+
+ # If the create failed
+ else {
+ $title = loc("Create a new group");
+ $Create = 1;
+ }
+
+}
+
+if ($id) {
+
+ my @fields = qw(Description Name );
+ my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields,
+ Object => $Group,
+ ARGSRef => \%ARGS );
+ push (@results,@fieldresults);
+ push @results, ProcessObjectCustomFieldUpdates( ARGSRef => \%ARGS, Object => $Group );
+}
+
+#we're asking about enabled on the web page but really care about disabled.
+if ($Enabled == 1) {
+ $Disabled = 0;
+}
+else {
+ $Disabled = 1;
+}
+if ( ($SetEnabled) and ( $Disabled != $Group->Disabled) ) {
+ my ($code, $msg) = $Group->SetDisabled($Disabled);
+ push @results, loc('Enabled status [_1]', loc_fuzzy($msg));
+}
+
+unless ($Group->Disabled()) {
+ $EnabledChecked ="CHECKED";
+}
+
+
+</%INIT>
+
+
+<%ARGS>
+$Create => undef
+$Name => undef
+$Description => undef
+$SetEnabled => undef
+$Enabled => undef
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Groups/UserRights.html b/rt/html/Admin/Groups/UserRights.html
new file mode 100644
index 000000000..b77edb011
--- /dev/null
+++ b/rt/html/Admin/Groups/UserRights.html
@@ -0,0 +1,116 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => loc('Modify user rights for group [_1]', $GroupObj->Name) &>
+<& /Admin/Elements/GroupTabs,
+ GroupObj => $GroupObj,
+ current_tab => 'Admin/Groups/UserRights.html?id='.$id,
+ Title => loc('Modify user rights for group [_1]', $GroupObj->Name) &>
+<& /Elements/ListActions, actions => \@results &>
+
+ <form method="post" action="UserRights.html">
+ <input type="hidden" class="hidden" name="id" value="<% $GroupObj->id %>" />
+
+<&| /Widgets/TitleBox, title => loc('Modify user rights for group [_1]', $GroupObj->Name) &>
+
+<table>
+
+% while (my $Member = $Users->Next()) {
+% my $UserObj = $Member->MemberObj->Object();
+ <tr align="right">
+ <td valign="top">
+ <% $UserObj->Name %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId => $Member->MemberObj->Id,
+ PrincipalType => 'User',
+ Object => $GroupObj &>
+ </td>
+ </tr>
+% }
+ </table>
+
+ </&>
+ <& /Elements/Submit, Label => loc('Modify User Rights'), Reset => 1 &>
+
+ </form>
+
+<%INIT>
+
+ #Update the acls.
+ my @results = ProcessACLChanges(\%ARGS);
+
+# {{{ Deal with setting up the display of current rights.
+
+
+#Define vars used in html above
+
+
+if (!defined $id) {
+ Abort(loc("No Group defined"));
+}
+
+my $GroupObj = RT::Group->new($session{'CurrentUser'});
+$GroupObj->Load($id) || Abort(loc("Couldn't load group [_1]",$id));
+
+# Find out which users we want to display ACL selects for
+my $Privileged = RT::Group->new($session{'CurrentUser'});
+$Privileged->LoadSystemInternalGroup('Privileged');
+my $Users = $Privileged->MembersObj();
+
+
+
+# }}}
+
+</%INIT>
+
+<%ARGS>
+$id => undef
+$UserString => undef
+$UserOp => undef
+$UserField => undef
+</%ARGS>
diff --git a/rt/html/Admin/Groups/index.html b/rt/html/Admin/Groups/index.html
new file mode 100644
index 000000000..384092bdf
--- /dev/null
+++ b/rt/html/Admin/Groups/index.html
@@ -0,0 +1,113 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/GroupTabs, current_tab => 'Admin/Groups/',
+ current_subtab => 'Admin/Groups/',
+ Title => $title &>
+<%$caption%>:<br /> <ul>
+%if ($Groups->Count == 0) {
+<li> <em><&|/l&>No groups matching search criteria found.</&></em>
+% }
+%my @ids;
+%while ( my $Group = $Groups->Next) {
+% push @ids, $Group->Id;
+<li><a href="Modify.html?id=<%$Group->id%>"><%$Group->Name || loc('(empty)')%></a><br />
+%}
+</ul>
+%if (my $ids = join(',', @ids)) {
+<em>(<a href="<%$RT::WebPath%>/Download/Tabular/Group/<% $ids %>/Groups.tsv"><&|/l&>Download as a tab-delimited file</&></a>)</em><br />
+%}
+<br /><br />
+<form method="post" action="<% $RT::WebPath %>/Admin/Groups/index.html">
+<input type="checkbox" class="checkbox" name="FindDisabledGroups" value="1" /> <&|/l&>Include disabled groups in listing.</&>
+<br />
+<div align="right"><input type="submit" class="button" value="<&|/l&>Go!</&>" /></div>
+</form>
+
+<br /><br />
+<form method="post" action="<% $RT::WebPath %>/Admin/Groups/index.html">
+<&|/l&>Find groups whose</&> <& /Elements/SelectGroups &><br />
+<div align="right"><input type="submit" class="button" value="<&|/l&>Go!</&>" /></div>
+</form>
+<%INIT>
+my $Groups = RT::Groups->new($session{'CurrentUser'});
+$Groups->LimitToUserDefinedGroups();
+my $title = loc('Select a group');
+my $caption;
+
+if ($FindDisabledGroups) {
+ $Groups->FindAllRows();
+}
+
+if (length $GroupString) {
+ $caption = loc("Groups matching search criteria");
+ if ($GroupField =~ /^CustomField-(\d+)/) {
+ $Groups->LimitCustomField(
+ CUSTOMFIELD => $1,
+ OPERATOR => $GroupOp,
+ VALUE => $GroupString,
+ );
+ }
+ else {
+ $Groups->Limit(
+ FIELD => $GroupField,
+ OPERATOR => $GroupOp,
+ VALUE => $GroupString,
+ );
+ }
+}
+else {
+ $caption = loc("User-defined groups");
+}
+</%INIT>
+<%ARGS>
+$GroupString => undef
+$GroupOp => '='
+$GroupField => 'Name'
+$FindDisabledGroups => 0
+</%ARGS>
diff --git a/rt/html/Admin/Queues/CustomField.html b/rt/html/Admin/Queues/CustomField.html
new file mode 100644
index 000000000..52829277e
--- /dev/null
+++ b/rt/html/Admin/Queues/CustomField.html
@@ -0,0 +1,87 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs, id => $QueueObj->Id,
+ QueueObj => $QueueObj,
+ current_tab => 'Admin/Queues/CustomFields.html?id='.$QueueObj->id,
+ current_subtab => $current_subtab,
+ subtabs => $subtabs,
+ Title => $title &>
+
+<& /Admin/Elements/EditCustomField, title => $title, %ARGS &>
+
+<%INIT>
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($Queue);
+
+my ($title, $current_subtab);
+
+unless($QueueObj->id) {
+ Abort(loc("Queue [_1] not found", $Queue));
+}
+if ($CustomField) {
+ $title = loc('Modify a CustomField for queue [_1]', $QueueObj->Name());
+}else {
+ $current_subtab = "Admin/Queues/CustomField.html?create=1&Queue=".$QueueObj->id;
+ $title = loc('Create a CustomField for queue [_1]', $QueueObj->Name());
+}
+
+my $subtabs = {
+ A => { title => loc('New custom field'),
+ path => "Admin/Queues/CustomField.html?create=1&Queue=".$QueueObj->id
+ }
+ };
+
+</%INIT>
+<%ARGS>
+$CustomField => undef
+$Queue => 0
+</%ARGS>
+<%ATTR>
+AutoFlush => 0
+</%ATTR>
diff --git a/rt/html/Admin/Queues/CustomFields.html b/rt/html/Admin/Queues/CustomFields.html
new file mode 100644
index 000000000..8ce4f525d
--- /dev/null
+++ b/rt/html/Admin/Queues/CustomFields.html
@@ -0,0 +1,72 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs,
+ id => $Object->id,
+ current_tab => "Admin/Queues/CustomFields.html?SubType=$SubType&id=$id",
+ current_subtab => "Admin/Queues/CustomFields.html?SubType=$SubType&id=$id",
+ QueueObj => $Object,
+ Title => $title
+ &>
+
+ <& /Admin/Elements/EditCustomFields, %ARGS, title => $title, Object => $Object, ObjectType => 'RT::Queue' &>
+<%INIT>
+my $Object = RT::Queue->new( $session{'CurrentUser'} );
+
+$Object->Load($id) || Abort( loc( "Couldn't load object [_1]", $id ) );
+my $FriendlySubTypes =
+ RT::CustomField->new( $session{'CurrentUser'} )
+ ->FriendlyLookupType( $Object->CustomFieldLookupType );
+
+my $title = loc( 'Edit Custom Fields for [_1]', $Object->Name );
+
+</%INIT>
+<%ARGS>
+$id => undef
+$SubType => 'RT::Queue-RT::Ticket'
+</%ARGS>
diff --git a/rt/html/Admin/Queues/GroupRights.html b/rt/html/Admin/Queues/GroupRights.html
new file mode 100644
index 000000000..85075bdea
--- /dev/null
+++ b/rt/html/Admin/Queues/GroupRights.html
@@ -0,0 +1,134 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => loc('Modify group rights for queue [_1]', $QueueObj->Name) &>
+<& /Admin/Elements/QueueTabs, id => $id,
+ QueueObj => $QueueObj,
+ current_tab => $current_tab,
+ Title => loc('Modify group rights for queue [_1]', $QueueObj->Name) &>
+<& /Elements/ListActions, actions => \@results &>
+
+ <form method="post" action="GroupRights.html">
+ <input type="hidden" class="hidden" name="id" value="<% $QueueObj->id %>" />
+
+
+<h1><&|/l&>System groups</&></h1>
+<table>
+<& /Elements/Callback, QueueObj => $QueueObj, results => \@results, %ARGS &>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToSystemInternalGroups();
+% while (my $Group = $Groups->Next()) {
+ <tr align="right">
+ <td valign="top">
+ <% loc($Group->Type) %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+ Object => $QueueObj &>
+ </td>
+ </tr>
+% }
+</table>
+<h1><&|/l&>Roles</&></h1>
+<table>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToRolesForQueue($QueueObj->Id);
+% while (my $Group = $Groups->Next()) {
+ <tr align="right">
+ <td valign="top">
+ <% loc($Group->Type) %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+ Object => $QueueObj &>
+ </td>
+ </tr>
+% }
+</table>
+<h1><&|/l&>User defined groups</&></h1>
+<table>
+% $Groups = RT::Groups->new($session{'CurrentUser'});
+% $Groups->LimitToUserDefinedGroups();
+% while (my $Group = $Groups->Next()) {
+ <tr align="right">
+ <td valign="top">
+ <% $Group->Name %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId => $Group->PrincipalId,
+ Object => $QueueObj &>
+ </td>
+ </tr>
+% }
+</table>
+
+ <& /Elements/Submit, Label => loc('Modify Group Rights'), Reset => 1 &>
+
+ </form>
+
+<%INIT>
+
+ #Update the acls.
+ my @results = ProcessACLChanges(\%ARGS);
+
+
+if (!defined $id) {
+ Abort(loc("No Queue defined"));
+}
+
+my $QueueObj = RT::Queue->new($session{'CurrentUser'});
+$QueueObj->Load($id) || Abort(loc("Couldn't load queue [_1]",$id));
+
+my $Groups;
+my $current_tab;
+$current_tab = 'Admin/Queues/GroupRights.html?id='.$QueueObj->id;
+
+</%INIT>
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Queues/Modify.html b/rt/html/Admin/Queues/Modify.html
new file mode 100644
index 000000000..e84d14fa4
--- /dev/null
+++ b/rt/html/Admin/Queues/Modify.html
@@ -0,0 +1,193 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs, id => $QueueObj->id,
+ QueueObj => $QueueObj,
+ current_tab => $current_tab,
+ Title => $title &>
+<& /Elements/ListActions, actions => \@results &>
+
+
+
+<form action="<%$RT::WebPath%>/Admin/Queues/Modify.html" method="post">
+%if ($Create ) {
+<input type="hidden" class="hidden" name="id" value="new" />
+% } else {
+<input type="hidden" class="hidden" name="id" value="<%$QueueObj->Id%>" />
+% }
+
+<table>
+<tr><td align="right">
+<&|/l&>Queue Name</&>:
+</td>
+<td><input name="Name" value="<% ($Create) ? "" : $QueueObj->Name %>" /></td>
+</tr><tr>
+<td align="right">
+<&|/l&>Description</&>:</td><td colspan="3"><input name="Description" value="<% ($Create) ? "" : $QueueObj->Description %>" size="60" /></td></tr>
+<tr>
+<td align="right">
+<&|/l&>Reply Address</&>:
+</td><td>
+<input name="CorrespondAddress" value="<% ($Create) ? "" : $QueueObj->CorrespondAddress %>" />
+<br /><span><em><&|/l , $RT::CorrespondAddress&>(If left blank, will default to [_1])</&></em></span>
+</td>
+<td align="right">
+
+<&|/l&>Comment Address</&>: </td><td>
+<input name="CommentAddress" value="<% ($Create) ? "" : $QueueObj->CommentAddress %>" />
+<br /><span><em><&|/l , $RT::CommentAddress&>(If left blank, will default to [_1])</&></em></span>
+</td>
+</tr><tr>
+
+<td align="right">
+<&|/l&>Priority starts at</&>:
+</td><td><input name="InitialPriority" value="<% ($Create) ? "" : $QueueObj->InitialPriority %>" />
+</td>
+<td align="right">
+<&|/l&>Over time, priority moves toward</&>:
+</td><td><input name="FinalPriority" value="<% ($Create) ? "" : $QueueObj->FinalPriority %>" />
+</td>
+</tr>
+<tr>
+<td align="right">
+<&|/l&>Requests should be due in</&>:
+</td><td>
+<input name="DefaultDueIn" value="<% ($Create) ? "" : $QueueObj->DefaultDueIn%>" /> <&|/l&>days</&>.
+</td>
+</tr>
+<tr>
+<td>
+</td>
+<td colspan="4"><input type="hidden" class="hidden" name="SetEnabled" value="1" />
+<input type="checkbox" class="checkbox" name="Enabled" value="1" <%$EnabledChecked%> /> <&|/l&>Enabled (Unchecking this box disables this queue)</&><br />
+<& /Elements/Callback, QueueObj => $QueueObj, results => \@results, %ARGS &>
+</td>
+</tr>
+
+</table>
+<& /Elements/Submit, Label => loc('Save Changes') &>
+</form>
+
+
+
+<%INIT>
+my $current_tab;
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($id);
+my ($title, @results, $Disabled, $EnabledChecked);
+$EnabledChecked = "CHECKED";
+
+if ($Create) {
+ $current_tab = 'Admin/Queues/Modify.html?Create=1';
+ $title = loc("Create a queue");
+} else {
+ if ($id eq 'new') {
+ my ($val, $msg) = $QueueObj->Create(Name => $Name);
+ delete $session{'create_in_queues'};
+ if ($val == 0 ) {
+ Abort("$msg");
+ }
+ else {
+ push @results, $msg;
+ }
+ }
+ else {
+ $QueueObj->Load($id) || $QueueObj->Load($Name) || Abort("Couldn't load queue '$Name'");
+ }
+ $title = loc('Editing Configuration for queue [_1]', $QueueObj->Name);
+
+ $current_tab = 'Admin/Queues/Modify.html?id='.$QueueObj->id;
+}
+if ($QueueObj->Id()) {
+ delete $session{'create_in_queues'};
+my @attribs= qw(Description CorrespondAddress CommentAddress Name
+ InitialPriority FinalPriority DefaultDueIn);
+
+ @results = UpdateRecordObject( AttributesRef => \@attribs,
+ Object => $QueueObj,
+ ARGSRef => \%ARGS);
+
+ #we're asking about enabled on the web page but really care about disabled.
+ if ($Enabled == 1) {
+ $Disabled = 0;
+ }
+ else {
+ $Disabled = 1;
+ }
+ if ( ($SetEnabled) and ( $Disabled != $QueueObj->Disabled) ) {
+ my ($code, $msg) = $QueueObj->SetDisabled($Disabled);
+ push @results, loc('Enabled status: [_1]', loc_fuzzy($msg));
+ }
+
+ if ($QueueObj->Disabled()) {
+ $EnabledChecked ="";
+ }
+
+ my @linkresults;
+ $m->comp('/Elements/Callback', results => \@linkresults,
+ RecordObj => $QueueObj, ARGSRef => \%ARGS,
+ _CallbackName => 'ProcessLinks');
+ push @results, @linkresults;
+}
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+$result => undef
+$Name => undef
+$Create => undef
+$Description => undef
+$CorrespondAddress => undef
+$CommentAddress => undef
+$InitialPriority => undef
+$FinalPriority => undef
+$DefaultDueIn => undef
+$SetEnabled => undef
+$Enabled => undef
+</%ARGS>
diff --git a/rt/html/Admin/Queues/People.html b/rt/html/Admin/Queues/People.html
new file mode 100644
index 000000000..4eeda3c4f
--- /dev/null
+++ b/rt/html/Admin/Queues/People.html
@@ -0,0 +1,210 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc('Modify people related to queue [_1]', $QueueObj->Name) &>
+<& /Admin/Elements/QueueTabs, id => $id,
+ QueueObj => $QueueObj,
+ current_tab => $current_tab,
+ Title => loc('Modify people related to queue [_1]', $QueueObj->Name) &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+
+<form method="post" action="People.html">
+<input type="hidden" class="hidden" name="id" value="<%$QueueObj->Id%>" />
+
+<table width="100%">
+<tr>
+<td valign="top" >
+
+<h3><&|/l&>Current watchers</&></h3>
+
+
+<&|/l&>Cc</&>:
+
+<& /Admin/Elements/EditQueueWatchers, QueueObj => $QueueObj, Watchers => $QueueObj->Cc &>
+
+<&|/l&>Administrative Cc</&>:
+
+<& /Admin/Elements/EditQueueWatchers, QueueObj => $QueueObj, Watchers => $QueueObj->AdminCc &>
+
+
+</td>
+<td valign="top">
+<h3><&|/l&>New watchers</&></h3>
+
+<&|/l&>Find people whose</&><br />
+<& /Elements/SelectUsers &>
+<input type="submit" class="button" name="OnlySearchForPeople" value="<&|/l&>Go!</&>" />
+<br />
+<&|/l&>Find groups whose</&><br />
+<& /Elements/SelectGroups &>
+<input type="submit" class="button" name="OnlySearchForGroup" value="<&|/l&>Go!</&>" />
+
+<p>
+<&|/l&>Add new watchers</&>:<br />
+<p>
+<strong><&|/l&>Users</&></strong>
+% if ($user_msg) {
+<br />
+<em><%$user_msg%></em>
+% } elsif ($Users) {
+<ul>
+% while (my $u = $Users->Next ) {
+<li><&/Elements/SelectWatcherType, Scope=>'queue', Name =>
+"Queue-AddWatcher-Principal-".$u->PrincipalId &> <%$u->Name%>
+(<%$u->RealName%>)
+% }
+</ul>
+% }
+
+<p>
+<strong><&|/l&>Groups</&></strong>
+
+% if ($group_msg) {
+<br />
+<em><%$group_msg%></em>
+% } elsif ($Groups) {
+<ul>
+% while (my $g = $Groups->Next ) {
+<li><&/Elements/SelectWatcherType, Scope=>'queue', Name =>
+"Queue-AddWatcher-Principal-".$g->PrincipalId &> <%$g->Name%>
+(<%$g->Description%>)
+% }
+</ul>
+% }
+
+</td>
+</tr>
+</table>
+
+
+
+
+<& /Elements/Submit, Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), Reset => 1 &>
+</form>
+
+<%INIT>
+
+my $current_tab;
+my ($field, @results, $User, $Users, $Groups, $watcher, $user_msg, $group_msg);
+
+# {{{ Load the queue
+#If we get handed two ids, mason will make them an array. bleck.
+# We want teh first one. Just because there's no other sensible way
+# to deal
+
+
+
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($id) || Abort(loc("Couldn't load queue", $id));
+# }}}
+
+# {{{ Delete deletable watchers
+
+foreach my $key (keys %ARGS) {
+ my $id = $QueueObj->Id;
+
+ if (($key =~ /^Queue-$id-DeleteWatcher-Type-(.*?)-Principal-(\d*)$/)) {;
+ my ($code, $msg) = $QueueObj->DeleteWatcher(Type => $1,
+ PrincipalId => $2);
+ push @results, $msg;
+ }
+}
+# }}}
+
+# {{{ Add new watchers
+foreach my $key (keys %ARGS) {
+ #They're in this order because otherwise $1 gets clobbered :/
+ if ( ($ARGS{$key} =~ /^(AdminCc|Cc)$/) and
+ ($key =~ /^Queue-AddWatcher-Principal-(\d*)$/) ) {
+ $RT::Logger->debug("Adding a watcher $1 to ".$ARGS{$key}."\n");
+ my ($code, $msg) = $QueueObj->AddWatcher(Type => $ARGS{$key},
+ PrincipalId => $1);
+ push @results, $msg;
+ }
+}
+
+# }}}
+
+
+
+if (!length $ARGS{'UserString'}) {
+$user_msg = loc("No principals selected.");
+ }
+else {
+ $Users = new RT::Users($session{'CurrentUser'});
+ $Users->Limit(FIELD => $ARGS{'UserField'},
+ VALUE => $ARGS{'UserString'},
+ OPERATOR => $ARGS{'UserOp'});
+ }
+
+if (!length $ARGS{'GroupString'}) {
+$group_msg = loc("No principals selected.");
+ }
+else {
+$Groups = new RT::Groups($session{'CurrentUser'});
+$Groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined');
+$Groups->Limit(FIELD => $ARGS{'GroupField'},
+ VALUE => $ARGS{'GroupString'},
+ OPERATOR => $ARGS{'GroupOp'});
+ }
+
+$current_tab = 'Admin/Queues/People.html?id='.$QueueObj->id;
+</%INIT>
+
+<%ARGS>
+$UserField => 'Name'
+$UserOp => '='
+$UserString => undef
+$GroupField => 'Name'
+$GroupOp => '='
+$GroupString => undef
+$Type => undef
+$id => undef
+</%ARGS>
+
diff --git a/rt/html/Admin/Queues/Scrip.html b/rt/html/Admin/Queues/Scrip.html
new file mode 100644
index 000000000..190be8b48
--- /dev/null
+++ b/rt/html/Admin/Queues/Scrip.html
@@ -0,0 +1,100 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs, id => $QueueObj->Id,
+ QueueObj => $QueueObj,
+ current_tab => 'Admin/Queues/Scrips.html?id='.$QueueObj->id,
+ current_subtab => $current_subtab,
+ subtabs => $subtabs,
+ Title => $title &>
+
+<& /Elements/ListActions, actions => \@results &>
+<& /Admin/Elements/EditScrip, title => $title, %ARGS, id => $id &>
+
+<%init>
+my $QueueObj = RT::Queue->new( $session{'CurrentUser'} );
+$QueueObj->Load( $Queue );
+unless( $QueueObj->id ) {
+ Abort(loc("Queue [_1] not found", $id));
+}
+
+my ($title, $current_subtab);
+my $subtabs = {
+ A => {
+ title => loc('Select scrip'),
+ path => "Admin/Queues/Scrips.html?id=".$QueueObj->id,
+ },
+ B => {
+ title => loc('New scrip'),
+ path => "Admin/Queues/Scrip.html?create=1&Queue=".$QueueObj->id,
+ separator => 1,
+ },
+};
+
+my $scrip = RT::Scrip->new( $session{'CurrentUser'} );
+($id, my @results) = $m->comp( '/Admin/Elements/EditScrip:Process', %ARGS );
+
+if ( $id ) {
+ $current_subtab = "Admin/Queues/Scrip.html?id=$id&Queue=". $QueueObj->id;
+ $title = loc("Modify a scrip for queue [_1]", $QueueObj->Name);
+ $subtabs->{"C"} = {
+ title => loc("Scrip #[_1]",$id),
+ path => "Admin/Queues/Scrip.html?id=$id&Queue=".$QueueObj->id
+ };
+} else {
+ $current_subtab = "Admin/Queues/Scrip.html?create=1&Queue=".$QueueObj->id;
+ $title = loc("Create a scrip for queue [_1]", $QueueObj->Name);
+}
+
+
+</%init>
+
+<%ARGS>
+$id => undef
+$Queue => undef
+</%ARGS>
diff --git a/rt/html/Admin/Queues/Scrips.html b/rt/html/Admin/Queues/Scrips.html
new file mode 100644
index 000000000..8fb0db400
--- /dev/null
+++ b/rt/html/Admin/Queues/Scrips.html
@@ -0,0 +1,87 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs, id => $QueueObj->id,
+ QueueObj => $QueueObj,
+ current_tab => 'Admin/Queues/Scrips.html?id='.$id,
+ current_subtab => 'Admin/Queues/Scrips.html?id='.$id,
+ subtabs => $subtabs,
+ Title => $title &>
+
+% if (!$QueueObj->Disabled) { # Global scrips does not apply to disabled queues
+<h2><&|/l&>Scrips which apply to all queues</&></h2>
+<& /Admin/Elements/ListGlobalScrips &>
+<br />
+% }
+<& /Admin/Elements/EditScrips, title => $title, %ARGS &>
+<%init>
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($id);
+
+my $title;
+
+if ($QueueObj->id) {
+ $title = loc("Modify scrips for queue [_1]", $QueueObj->Name);
+} else {
+ Abort(loc("Queue [_1] not found",$id));
+}
+
+my $subtabs = {
+ A => { title => loc('Select scrip'),
+ path => "Admin/Queues/Scrips.html?id=".$id,
+ },
+ B => { title => loc('New scrip'),
+ path => "Admin/Queues/Scrip.html?create=1&Queue=".$id,
+ separator => 1,
+ }
+ };
+</%init>
+
+<%ARGS>
+$id => undef #some identifier that a Queue could
+</%ARGS>
diff --git a/rt/html/Admin/Queues/Template.html b/rt/html/Admin/Queues/Template.html
new file mode 100644
index 000000000..2d6343f99
--- /dev/null
+++ b/rt/html/Admin/Queues/Template.html
@@ -0,0 +1,130 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs, id => $Queue,
+ QueueObj => $QueueObj,
+ current_tab => 'Admin/Queues/Templates.html?id='.$Queue,
+ current_subtab => $current_subtab,
+ subtabs => $subtabs,
+ Title => $title &>
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" action="Template.html">
+%if ($Create ) {
+<input type="hidden" class="hidden" name="Template" value="new" />
+% } else {
+<input type="hidden" class="hidden" name="Template" value="<%$TemplateObj->Id%>" />
+% }
+
+%# hang onto the queue id
+<input type="hidden" class="hidden" name="Queue" value="<%$Queue%>" />
+<& /Admin/Elements/ModifyTemplate, Name => $TemplateObj->Name, Description =>
+$TemplateObj->Description, Content => $TemplateObj->Content &>
+<& /Elements/Submit, Label => loc('Create'), Reset => 1 &>
+</form>
+
+
+<%INIT>
+
+my $TemplateObj = new RT::Template($session{'CurrentUser'});
+my ($title, @results, $current_subtab);
+
+my $subtabs = {
+ A => { title => loc('Select template'),
+ path => "Admin/Queues/Templates.html?id=$Queue"
+ },
+ B => { title => loc('New template'),
+ path => "Admin/Queues/Template.html?Create=1&Queue=$Queue",
+ separator => 1,
+ }
+ };
+
+if ($Create) {
+ $title = loc("Create a template");
+ $current_subtab = "Admin/Queues/Template.html?Create=1&Queue=".$Queue;
+}
+
+else {
+ if ($Template eq 'new') {
+ my ($val, $msg) = $TemplateObj->Create(Queue => $Queue, Name => $Name);
+ Abort(loc("Could not create template: [_1]", $msg)) unless ($val);
+ push @results, $msg;
+ }
+ else {
+ $TemplateObj->Load($Template) || Abort(loc('No Template'));
+ }
+ $title = loc('Modify template [_1]', loc($TemplateObj->Name()));
+
+
+}
+my $QueueObj;
+if ($TemplateObj->Id()) {
+ $Queue = $TemplateObj->Queue;
+ $QueueObj = $TemplateObj->QueueObj;
+
+ my @attribs = qw( Description Content Queue Name);
+ my @aresults = UpdateRecordObject( AttributesRef => \@attribs,
+ Object => $TemplateObj,
+ ARGSRef => \%ARGS);
+ $current_subtab = "Admin/Queues/Template.html?Queue=$Queue&Template=".$TemplateObj->Id();
+ $subtabs->{"C"} = { title => loc('Template #[_1]', $TemplateObj->Id()),
+ path => "Admin/Queues/Template.html?Queue=$Queue&Template=".$TemplateObj->Id(),
+ };
+ push @results, @aresults;
+} else {
+ $QueueObj = RT::Queue->new($session{'CurrentUser'});
+ $QueueObj->Load($Queue);
+}
+
+</%INIT>
+<%ARGS>
+$Queue => undef
+$Template => undef
+$Create => undef
+$Name => undef
+</%ARGS>
diff --git a/rt/html/Admin/Queues/Templates.html b/rt/html/Admin/Queues/Templates.html
new file mode 100644
index 000000000..d62b4971c
--- /dev/null
+++ b/rt/html/Admin/Queues/Templates.html
@@ -0,0 +1,81 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/QueueTabs, id => $QueueObj->id,
+ current_tab => 'Admin/Queues/Templates.html?id='.$id,
+ current_subtab => 'Admin/Queues/Templates.html?id='.$id,
+ QueueObj => $QueueObj,
+ subtabs => $subtabs,
+ Title => $title &>
+
+<& /Admin/Elements/EditTemplates, title => $title, %ARGS &>
+
+<%INIT>
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($id);
+
+my ($title, $current_subtab);
+
+if ($QueueObj->id) {
+ $title = loc("Edit Templates for queue [_1]", $QueueObj->Name);
+} else {
+ Abort(loc("Queue [_1] not found",$id));
+}
+my $subtabs = {
+ A => { title => loc('Select template'),
+ path => "Admin/Queues/Templates.html?id=".$id,
+ },
+ B => { title => loc('New template'),
+ path => "Admin/Queues/Template.html?Create=1&Queue=".$id,
+ }
+ };
+
+</%INIT>
+<%ARGS>
+$id => undef #some identifier that a Queue could
+</%ARGS>
diff --git a/rt/html/Admin/Queues/UserRights.html b/rt/html/Admin/Queues/UserRights.html
new file mode 100644
index 000000000..c277f1797
--- /dev/null
+++ b/rt/html/Admin/Queues/UserRights.html
@@ -0,0 +1,114 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => loc('Modify user rights for queue [_1]', $QueueObj->Name) &>
+<& /Admin/Elements/QueueTabs, id => $id,
+ QueueObj => $QueueObj,
+ current_tab => $current_tab,
+ Title => loc('Modify user rights for queue [_1]', $QueueObj->Name) &>
+<& /Elements/ListActions, actions => \@results &>
+
+ <form method="post" action="UserRights.html">
+ <input type="hidden" class="hidden" name="id" value="<% $QueueObj->id %>" />
+
+
+<table>
+<& /Elements/Callback, QueueObj => $QueueObj, results => \@results, %ARGS &>
+% while (my $Member = $Users->Next()) {
+% my $UserObj = $Member->MemberObj->Object();
+% my $group = RT::Group->new($session{'CurrentUser'});
+% $group->LoadACLEquivalenceGroup($Member->MemberObj);
+ <tr align="right">
+ <td valign="top">
+ <% $UserObj->Name %>
+ </td>
+ <td>
+ <& /Admin/Elements/SelectRights, PrincipalId=> $group->PrincipalId,
+ Object => $QueueObj &>
+ </td>
+ </tr>
+% }
+ </table>
+
+ <& /Elements/Submit, Label => loc('Modify User Rights'), Reset => 1 &>
+
+ </form>
+
+<%INIT>
+
+ #Update the acls.
+ my @results = ProcessACLChanges(\%ARGS);
+
+# {{{ Deal with setting up the display of current rights.
+
+
+
+if (!defined $id) {
+ Abort(loc("No Queue defined"));
+}
+
+my $QueueObj = RT::Queue->new($session{'CurrentUser'});
+$QueueObj->Load($id) || Abort(loc("Couldn't load queue [_1]",$id));
+
+# Find out which users we want to display ACL selects for
+my $Privileged = RT::Group->new($session{'CurrentUser'});
+$Privileged->LoadSystemInternalGroup('Privileged');
+my $Users = $Privileged->MembersObj();
+
+
+
+# }}}
+my $current_tab;
+$current_tab = 'Admin/Queues/UserRights.html?id='.$QueueObj->id;
+</%INIT>
+
+<%ARGS>
+$id => undef
+$UserString => undef
+$UserOp => undef
+$UserField => undef
+</%ARGS>
diff --git a/rt/html/Admin/Queues/index.html b/rt/html/Admin/Queues/index.html
new file mode 100644
index 000000000..bfa760409
--- /dev/null
+++ b/rt/html/Admin/Queues/index.html
@@ -0,0 +1,86 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => loc("Admin queues") &>
+<& /Admin/Elements/QueueTabs, current_tab => 'Admin/Queues/',
+ current_subtab => 'Admin/Queues/',
+ Title => loc("Admin queues") &>
+
+
+
+<h1><%$caption%></h1>
+<p><&|/l&>Select a queue</&>:</p>
+<ul>
+%if ($queues->Count == 0) {
+<li><em><&|/l&>No queues matching search criteria found.</&></em></li>
+% }
+%while ( $queue = $queues->Next) {
+<li><a href="Modify.html?id=<%$queue->id%>"><%$queue->Name%></a></li>
+%}
+</ul>
+<br />
+<form method="post" action="<% $RT::WebPath %>/Admin/Queues/index.html">
+<input type="checkbox" class="checkbox" name="FindDisabledQueues" value="1" /> <&|/l&>Include disabled queues in listing.</&>
+<div align="right"><input type="submit" class="button" value="<&|/l&>Go!</&>" /></div>
+</form>
+
+<%INIT>
+my ($queue, $caption);
+my $queues = new RT::Queues($session{'CurrentUser'});
+$queues->UnLimit();
+
+if ($FindDisabledQueues) {
+ $caption = loc("All Queues");
+ $queues->{'find_disabled_rows'} = 1;
+} else {
+ $caption = loc("Enabled Queues");
+}
+
+</%INIT>
+<%ARGS>
+$FindDisabledQueues => 0
+</%ARGS>
diff --git a/rt/html/Admin/Tools/Configuration.html b/rt/html/Admin/Tools/Configuration.html
new file mode 100644
index 000000000..205b9a0b2
--- /dev/null
+++ b/rt/html/Admin/Tools/Configuration.html
@@ -0,0 +1,100 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+require Module::Versions::Report;
+my $title = loc('System Configuration');
+unless ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'SuperUser')) {
+ Abort(loc('This feature is only available to system administrators'));
+}
+
+
+</%init>
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/ToolTabs,
+ current_tab => 'Admin/Tools/Configuration.html',
+ current_subtab => 'Admin/Tools/Configuration.html',
+ Title => $title &>
+
+
+
+
+<h2><&|/l&>Loaded perl modules</&></h2>
+<pre>
+% my $report = Module::Versions::Report::report();
+% my @report = grep { /v\d/ } split("\n",$report);
+<%join('<br />', @report)|n%>
+
+
+</pre>
+
+<h2><&|/l&>RT Variables</&></h2>
+<table>
+%{
+%no strict qw/refs/;
+
+%foreach my $key (sort keys %{*RT::}) {
+% next unless (${'RT::'.$key} );
+% next if (ref ${'RT::'.$key} );
+<tr><td>RT::<%$key%></td>
+<td>
+% if ($key =~ /Password(?!Length)/i) {
+<em>Password not printed</em>
+% } else {
+<%${'RT::'.$key} %>
+% }
+</td>
+</tr>
+% }
+%}
+</table>
+
+<h2><&|/l&>Perl configuration</&></h2>
+% require Config;
+<pre>
+<%Config::myconfig()%>
+</pre>
diff --git a/rt/html/Admin/Tools/index.html b/rt/html/Admin/Tools/index.html
new file mode 100644
index 000000000..3b4ec62c6
--- /dev/null
+++ b/rt/html/Admin/Tools/index.html
@@ -0,0 +1,55 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+my $title = loc('System Tools');
+</%init>
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/ToolTabs,
+ current_tab => 'Admin/Tools/index.html',
+ current_subtab => 'Admin/Tools/Configuration.html',
+ Title => $title &>
diff --git a/rt/html/Admin/Users/CustomFields.html b/rt/html/Admin/Users/CustomFields.html
new file mode 100644
index 000000000..1455c1de6
--- /dev/null
+++ b/rt/html/Admin/Users/CustomFields.html
@@ -0,0 +1,71 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/UserTabs,
+ id => $Object->id,
+ current_tab => "Admin/Users/CustomFields.html?$id=".$id,
+ current_subtab => "Admin/Users/CustomFields.html?id=".$id,
+ UserObj => $Object,
+ Title => $title
+ &>
+
+ <& /Admin/Elements/EditCustomFields, %ARGS, title => $title, Object => $Object, ObjectType => 'RT::User' &>
+<%INIT>
+my $Object = RT::User->new( $session{'CurrentUser'} );
+
+$Object->Load($id) || Abort( loc( "Couldn't load object [_1]", $id ) );
+my $FriendlySubTypes =
+ RT::CustomField->new( $session{'CurrentUser'} )
+ ->FriendlyLookupType( $Object->CustomFieldLookupType );
+
+my $title = loc( 'Edit Custom Fields for [_1]', $Object->Name );
+
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Users/History.html b/rt/html/Admin/Users/History.html
new file mode 100644
index 000000000..e47f67e78
--- /dev/null
+++ b/rt/html/Admin/Users/History.html
@@ -0,0 +1,68 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/UserTabs,
+ id => $id,
+ UserObj => $UserObj,
+ current_tab => $current_tab,
+ Title => $title &>
+
+<& /Ticket/Elements/ShowHistory,
+ Ticket => $UserObj,
+ ShowDisplayModes => 0,
+&>
+
+<%INIT>
+my $current_tab = 'Admin/Users/History.html?id='.$id;
+my $UserObj = new RT::User($session{'CurrentUser'});
+$UserObj->Load($id) || Abort("Couldn't load user '$id'");
+my $title = loc("History of the user [_1]", $UserObj->Name);
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Users/Memberships.html b/rt/html/Admin/Users/Memberships.html
new file mode 100644
index 000000000..493cb0f12
--- /dev/null
+++ b/rt/html/Admin/Users/Memberships.html
@@ -0,0 +1,67 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/UserTabs,
+ id => $id,
+ UserObj => $UserObj,
+ current_tab => $current_tab,
+ Title => $title &>
+
+<h2><&|/l&>Groups</&></h2>
+
+<& /Elements/ShowMemberships, UserObj => $UserObj &>
+
+<%INIT>
+my $UserObj = RT::User->new($session{'CurrentUser'});
+$UserObj->Load($id) || Abort("Couldn't load user '$id'");
+my $title = loc("Memberships of the user [_1]", $UserObj->Name);
+my $current_tab = 'Admin/Users/Memberships.html?id='.$id;
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Users/Modify.html b/rt/html/Admin/Users/Modify.html
new file mode 100644
index 000000000..be50dca0f
--- /dev/null
+++ b/rt/html/Admin/Users/Modify.html
@@ -0,0 +1,445 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/UserTabs,
+ id => $id,
+ UserObj => $UserObj,
+ current_tab => $current_tab,
+ Title => $title &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<form action="<%$RT::WebPath%>/Admin/Users/Modify.html" method="post" enctype="multipart/form-data">
+%if ($Create) {
+<input type="hidden" class="hidden" name="id" value="new" />
+% } else {
+<input type="hidden" class="hidden" name="id" value="<%$UserObj->Id%>" />
+% }
+<table width="100%" border="0">
+<tr>
+
+<td valign="top" class="boxcontainer">
+<&| /Widgets/TitleBox, title => loc('Identity') &>
+
+<table>
+<tr><td align="right">
+<&|/l&>Username</&>:
+</td><td>
+<input name="Name" value="<%$UserObj->Name%>" /> <strong><&|/l&>(required)</&></strong>
+</td></tr>
+<tr><td align="right">
+<&|/l&>Email</&>:
+</td><td>
+<input name="EmailAddress" value="<%$UserObj->EmailAddress%>" />
+</td></tr>
+<tr><td align="right">
+<&|/l&>Real Name</&>:
+</td><td>
+<input name="RealName" value="<%$UserObj->RealName%>" />
+</td></tr>
+<tr><td align="right">
+<&|/l&>Nickname</&>:
+</td><td>
+<input name="NickName" value="<%$UserObj->NickName%>" />
+</td></tr>
+<tr><td align="right">
+<&|/l&>Unix login</&>:
+</td><td>
+<input name="Gecos" value="<%$UserObj->Gecos%>" />
+</td></tr>
+<tr><td align="right">
+<&|/l&>Language</&>:
+</td><td>
+<& /Elements/SelectLang, Name => 'Lang', Default => $UserObj->Lang &>
+</td></tr>
+<tr><td align="right">
+<&|/l&>Extra info</&>:
+</td><td>
+<textarea name="FreeformContactInfo" cols="20" rows="5"><%$UserObj->FreeformContactInfo%></textarea>
+</td></tr>
+</table>
+</&>
+<br />
+
+<&| /Widgets/TitleBox, title => loc('Customers') &>
+<& /Elements/EditCustomers, Object => $UserObj, CustomerString=> $CustomerString, ServiceString => $ServiceString &>
+</&>
+<br />
+
+<&| /Widgets/TitleBox, title => loc('Access control') &>
+<input type="hidden" class="hidden" name="SetEnabled" value="1" />
+<input type="checkbox" class="checkbox" name="Enabled" value="1" <%$EnabledChecked%> />
+<&|/l&>Let this user access RT</&><br />
+
+
+<input type="hidden" class="hidden" name="SetPrivileged" value="1" />
+<input type="checkbox" class="checkbox" name="Privileged" value="1" <%$PrivilegedChecked%> /> <&|/l&>Let this user be granted rights</&><br />
+
+% unless ($RT::WebExternalAuth and !$RT::WebFallbackToInternalAuth) {
+<table>
+<tr>
+<td align="right">
+<&|/l&>New Password</&>:
+</td>
+<td align="left">
+<input type="password" name="Pass1" />
+</td>
+</tr>
+<tr><td align="right">
+<&|/l&>Retype Password</&>:
+</td>
+<td>
+<input type="password" name="Pass2" />
+</td>
+</tr>
+</table>
+% }
+</&>
+<& /Elements/Callback, _CallbackName => 'LeftColumnBottom', UserObj => $UserObj, %ARGS &>
+</td>
+
+<td valign="top" class="boxcontainer">
+<&| /Widgets/TitleBox, title => loc('Location') &>
+<table>
+<tr><td align="right">
+<&|/l&>Organization</&>:
+</td><td>
+<input name="Organization" value="<%$UserObj->Organization%>" />
+</td></tr>
+<tr><td align="right">
+<&|/l&>Address1</&>:
+</td><td>
+<input name="Address1" value="<%$UserObj->Address1%>" />
+</td></tr>
+<tr><td align="right">
+<&|/l&>Address2</&>:
+</td><td>
+<input name="Address2" value="<%$UserObj->Address2%>" />
+</td></tr>
+<tr><td align="right">
+<&|/l&>City</&>:
+</td><td>
+<input name="City" value="<%$UserObj->City%>" size="14" />
+
+</td></tr>
+<tr><td align="right">
+<&|/l&>State</&>:
+</td><td>
+<input name="State" value="<%$UserObj->State%>" size="3" />
+
+</td></tr>
+<tr><td align="right">
+<&|/l&>Zip</&>:
+</td><td>
+<input name="Zip" value="<%$UserObj->Zip%>" size="9" />
+</td></tr>
+<tr><td align="right">
+<&|/l&>Country</&>:
+</td><td>
+<input name="Country" value="<%$UserObj->Country%>" />
+</td></tr>
+</table>
+</&>
+<br />
+<&| /Widgets/TitleBox, title => loc('Phone numbers') &>
+<table>
+<tr><td align="right">
+<&|/l&>Residence</&>:
+</td><td>
+<input name="HomePhone" value="<%$UserObj->HomePhone%>" size="13" /><br />
+</td></tr>
+<tr><td align="right">
+<&|/l&>Work</&>:
+</td><td>
+<input name="WorkPhone" value="<%$UserObj->WorkPhone%>" size="13" /><br />
+</td></tr>
+<tr><td align="right">
+<&|/l&>Mobile</&>:
+</td><td>
+<input name="MobilePhone" value="<%$UserObj->MobilePhone%>" size="13" /><br />
+</td></tr>
+<tr><td align="right">
+<&|/l&>Pager</&>:
+</td><td>
+<input name="PagerPhone" value="<%$UserObj->PagerPhone%>" size="13" /><br />
+</td>
+</tr>
+</table>
+</&>
+<br />
+<&| /Widgets/TitleBox, title => loc('Custom Fields') &>
+<table>
+% my $CFs = $UserObj->CustomFields;
+% while (my $CF = $CFs->Next) {
+<tr valign="top"><td align="right">
+<% $CF->Name %>:
+</td><td>
+% if ($UserObj->id) {
+<& /Elements/EditCustomField, %ARGS, Object => $UserObj, CustomField => $CF &>
+% } else {
+<& /Elements/EditCustomField, %ARGS, NamePrefix => 'Object-RT::User-new-CustomField-', CustomField => $CF &>
+% }
+</td></tr>
+% }
+</table>
+</&>
+<& /Elements/Callback, _CallbackName => 'RightColumnBottom', UserObj => $UserObj, %ARGS &>
+</td></tr>
+<tr>
+<td colspan="2">
+<&| /Widgets/TitleBox, title => loc('Comments about this user') &>
+<textarea class="comments" name="Comments" cols="80" rows="5" wrap="virtual"><%$UserObj->Comments%></textarea>
+</&>
+%if ($UserObj->Privileged) {
+<br />
+<&| /Widgets/TitleBox, title => loc('Signature') &>
+<textarea class="signature" cols="80" rows="5" name="Signature" wrap="hard"><%$UserObj->Signature%></textarea>
+</&>
+% }
+
+</td>
+</tr>
+</table>
+
+<& /Elements/Submit, Label => loc('Save Changes') &>
+</form>
+
+<%INIT>
+
+my $current_tab;
+my $UserObj = new RT::User($session{'CurrentUser'});
+my ($title, $PrivilegedChecked, $EnabledChecked, $Disabled, $result, @results);
+
+my ($val, $msg);
+
+if ($Create) {
+ $current_tab = 'Admin/Users/Modify.html?Create=1';
+ $title = loc("Create a new user");
+}
+else {
+
+ $current_tab = 'Admin/Users/Modify.html?id='.$id;
+ if ($id eq 'new') {
+ ( $val, $msg ) = $UserObj->Create(
+ Name => $Name,
+ EmailAddress => $ARGS{'EmailAddress'},
+ Name => $ARGS{'Name'},
+ Comments => $ARGS{'Comments'},
+ Signature => $ARGS{'Signature'},
+ EmailAddress => $ARGS{'EmailAddress'},
+ FreeformContactInfo => $ARGS{'FreeformContactInfo'},
+ Organization => $ARGS{'Organization'},
+ RealName => $ARGS{'RealName'},
+ NickName => $ARGS{'NickName'},
+ Lang => $ARGS{'Lang'},
+ EmailEncoding => $ARGS{'EmailEncoding'},
+ WebEncoding => $ARGS{'WebEncoding'},
+ ExternalContactInfoId => $ARGS{'ExternalContactInfoId'},
+ ContactInfoSystem => $ARGS{'ContactInfoSystem'},
+ Gecos => $ARGS{'Gecos'},
+ ExternalAuthId => $ARGS{'ExternalAuthId'},
+ AuthSystem => $ARGS{'AuthSystem'},
+ HomePhone => $ARGS{'HomePhone'},
+ WorkPhone => $ARGS{'WorkPhone'},
+ MobilePhone => $ARGS{'MobilePhone'},
+ PagerPhone => $ARGS{'PagerPhone'},
+ Address1 => $ARGS{'Address1'},
+ Address2 => $ARGS{'Address2'},
+ City => $ARGS{'City'},
+ State => $ARGS{'State'},
+ Zip => $ARGS{'Zip'},
+ Country => $ARGS{'Country'},
+ Privileged => $ARGS{'Privileged'},
+ Disabled => ($ARGS{'Enabled'} ? 0 : 1)
+ );
+
+ if ($val) {
+ push @results, $msg;
+ foreach my $key ( keys %ARGS) {
+ # Convert custom fields on the "new" object to custom fields on the one we've just created
+ if ($key =~ /^Object-RT::User-new-CustomField-(.*)$/) {
+ $ARGS{'Object-RT::User-'.$val.'-CustomField-'.$1} = delete $ARGS{$key};
+ }
+ }
+ push @results, ProcessObjectCustomFieldUpdates( ARGSRef => \%ARGS, Object => $UserObj );
+ } else {
+ push @results, loc('User could not be created: [_1]', $msg);
+ }
+ } else {
+ $UserObj->Load($id) || $UserObj->Load($Name) || Abort("Couldn't load user '$Name'");
+ $val = $UserObj->Id();
+ }
+
+ if ($val) {
+ $title = loc("Modify the user [_1]", $UserObj->Name);
+ }
+
+ # If the create failed
+ else {
+ $title = loc("Create a new user");
+ $Create = 1;
+ }
+}
+
+
+
+
+# If we have a user to modify, lets try.
+if ($UserObj->Id && $id ne 'new') {
+
+ my @fields = qw(Name Comments Signature EmailAddress FreeformContactInfo
+ Organization RealName NickName Lang EmailEncoding WebEncoding
+ ExternalContactInfoId ContactInfoSystem Gecos ExternalAuthId
+ AuthSystem HomePhone WorkPhone MobilePhone PagerPhone Address1
+ Address2 City State Zip Country
+ );
+
+ my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields,
+ Object => $UserObj,
+ ARGSRef => \%ARGS );
+ push (@results,@fieldresults);
+ push @results, ProcessObjectCustomFieldUpdates( ARGSRef => \%ARGS, Object => $UserObj );
+
+ #deal with freeside customer links
+ push @results, ProcessObjectCustomers( ARGSRef => \%ARGS, Object => $UserObj );
+
+ # {{{ Deal with special fields: Privileged, Enabled
+ if ( $SetPrivileged and $Privileged != $UserObj->Privileged ) {
+ my ($code, $msg) = $UserObj->SetPrivileged($Privileged);
+ push @results, loc('Privileged status: [_1]', loc_fuzzy($msg));
+ }
+
+ #we're asking about enabled on the web page but really care about disabled.
+ $Disabled = $Enabled ? 0 : 1;
+
+ if ( ($SetEnabled) and ( $Disabled != $UserObj->Disabled) ) {
+ my ($code, $msg) = $UserObj->SetDisabled($Disabled);
+ push @results, loc('Enabled status [_1]', loc_fuzzy($msg));
+ }
+
+
+ # }}}
+}
+
+if ( $UserObj->Id ) {
+ my $password_not_set;
+ # Deal with Password field
+ if ( !$Pass1 and !$Pass2 ) {
+ $password_not_set = 1;
+ } elsif ( $Pass1 ne $Pass2 ) {
+ $password_not_set = 1;
+ push @results, loc("Passwords do not match.");
+ } elsif ( $Pass1 eq $Pass2 and !$UserObj->IsPassword($Pass1) ) {
+ my ($code, $msg) = $UserObj->SetPassword($Pass1);
+ push @results, loc_fuzzy($msg);
+ $password_not_set = 1 unless $code;
+ }
+ if ($id eq 'new' and $password_not_set) {
+ push @results, loc("A password was not set, so user won't be able to login.");
+ }
+}
+
+
+# {{{ Do some setup for the ui
+unless ($UserObj->Disabled()) {
+ $EnabledChecked ="CHECKED";
+}
+
+if ($UserObj->Privileged()) {
+ $PrivilegedChecked = "CHECKED";
+}
+
+# }}}
+
+# set the id, so the the menu will have the right info, this needs to
+# be done here to avoid creating and then modifying a user
+$id = $UserObj->Id;
+
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+$Name => undef
+$Comments => undef
+$Signature => undef
+$EmailAddress => undef
+$FreeformContactInfo => undef
+$Organization => undef
+$RealName => undef
+$NickName => undef
+$Privileged => undef
+$SetPrivileged => undef
+$Enabled => undef
+$SetEnabled => undef
+$Lang => undef
+$EmailEncoding => undef
+$WebEncoding => undef
+$ExternalContactInfoId => undef
+$ContactInfoSystem => undef
+$Gecos => undef
+$ExternalAuthId => undef
+$AuthSystem => undef
+$HomePhone => undef
+$WorkPhone => undef
+$MobilePhone => undef
+$PagerPhone => undef
+$Address1 => undef
+$Address2 => undef
+$City => undef
+$State => undef
+$Zip => undef
+$Country => undef
+$Pass1 => undef
+$Pass2=> undef
+$Create=> undef
+$OnlySearchForCustomers => undef
+$OnlySearchForServices => undef
+$CustomerString => undef
+$ServiceString => undef
+</%ARGS>
diff --git a/rt/html/Admin/Users/MyRT.html b/rt/html/Admin/Users/MyRT.html
new file mode 100644
index 000000000..6eed0ab68
--- /dev/null
+++ b/rt/html/Admin/Users/MyRT.html
@@ -0,0 +1,132 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => $title &>
+<& /Admin/Elements/UserTabs,
+ id => $id,
+ UserObj => $UserObj,
+ current_tab => $current_tab,
+ Title => $title &>
+
+<& /Widgets/SelectionBox:header, nojs => 1 &>
+
+<& /Elements/ListActions, actions => \@actions &>
+
+<form method="post" action="MyRT.html">
+<input type="hidden" name="id" value="<% $id %>" />
+<input type="hidden" name="Reset" value="1" />
+<input type="submit" class="button" value="<%loc('Reset to default')%>">
+</form>
+
+<br />
+
+% for my $pane (@panes) {
+<&|/Widgets/TitleBox, title => loc('RT at a glance').': '.loc($pane->{Name}), bodyclass => "" &>
+<& /Widgets/SelectionBox:show, self => $pane, nojs => 1 &></&>
+<br />
+% }
+
+<%init>
+my $current_tab = 'Admin/Users/MyRT.html?id='.$id;
+my $UserObj = new RT::User($session{'CurrentUser'});
+$UserObj->Load($id) || Abort("Couldn't load user '$id'");
+my $title = loc("RT at a glance for the user [_1]", $UserObj->Name);
+
+if ($ARGS{Reset}) {
+ $UserObj->SetPreferences('HomepageSettings', {});
+}
+
+my ($default_portlets) = RT::System->new($session{'CurrentUser'})->Attributes->Named('HomepageSettings');
+my $portlets = $UserObj->Preferences('HomepageSettings', $default_portlets ? $default_portlets->Content : {});
+
+my %allowed_components = map {$_ => 1} @{$RT::HomepageComponents};
+my @items;
+
+push @items, map {["component-$_", $_]} sort keys %allowed_components;
+
+my $sys = RT::System->new( RT::CurrentUser->new($UserObj) );
+my @objs = ($sys);
+
+push @objs, RT::SavedSearches->new( RT::CurrentUser->new( $UserObj ) )->_PrivacyObjects;
+my @actions;
+
+for my $object (@objs) {
+ for ($m->comp("/Search/Elements/SearchesForObject", Object => $object)) {
+ my ($desc, $search) = @$_;
+ my $SearchType = $search->Content->{'SearchType'} || 'Ticket';
+ if ($object eq $sys && $SearchType eq 'Ticket') {
+ push @items, ["system-$desc", $desc];
+ }
+ else {
+ my $oid = ref($object).'-'.$object->Id.'-SavedSearch-'.$search->Id;
+ my $type = ($SearchType eq 'Ticket')
+ ? 'Saved Search' : $SearchType; # loc
+ push @items, ["saved-$oid", loc($type).": $desc"];
+ }
+ }
+}
+
+my @panes = $m->comp(
+ '/Admin/Elements/ConfigureMyRT',
+ panes => ['body', 'summary'],
+ Action => "MyRT.html?id=$id",
+ items => \@items,
+ current_portlets => $portlets,
+ OnSave => sub {
+ my ( $conf, $pane ) = @_;
+ $UserObj->SetPreferences( 'HomepageSettings', $conf );
+ push @actions, loc( 'Preferences [_1] for user [_2] .', $pane, $UserObj->Name );
+ }
+);
+
+$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_, nojs => 1 )
+ for @panes;
+
+</%init>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Admin/Users/index.html b/rt/html/Admin/Users/index.html
new file mode 100644
index 000000000..bc47d4fef
--- /dev/null
+++ b/rt/html/Admin/Users/index.html
@@ -0,0 +1,115 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => loc('Select a user') &>
+<& /Admin/Elements/UserTabs, current_tab => 'Admin/Users/',
+ current_subtab => 'Admin/Users/',
+ Title => loc('Select a user') &>
+
+<h1><%$caption%></h1>
+<p><&|/l&>Select a user</&>:</p>
+<ul>
+%if ($users->Count == 0) {
+<li><em><&|/l&>No users matching search criteria found.</&></em></li>
+% }
+%my @ids;
+%while ( $user = $users->Next) {
+% push @ids, $user->Id;
+<li><a href="Modify.html?id=<%$user->id%>"><%$user->Name || loc('(no name listed)')%></a></li>
+%}
+</ul>
+%if (my $ids = join(',', @ids)) {
+<em>(<a href="<%$RT::WebPath%>/Download/Tabular/User/<% $ids %>/Users.tsv"><&|/l&>Download as a tab-delimited file</&></a>)</em><br />
+%}
+
+<br /><br />
+<form method="post" action="<% $RT::WebPath %>/Admin/Users/index.html">
+
+<&|/l&>Find people whose</&> <& /Elements/SelectUsers &><br />
+<input type="checkbox" class="checkbox" name="FindDisabledUsers" value="1" /> <&|/l&>Include disabled users in search.</&>
+<br />
+<div align="right"><input type="submit" class="button" value="<&|/l&>Go!</&>" /></div>
+</form>
+
+<%INIT>
+my ($user, $caption);
+my $users = new RT::Users($session{'CurrentUser'});
+
+if ($FindDisabledUsers) {
+ $users->{'find_disabled_rows'} = 1;
+}
+
+if (length $UserString) {
+ $caption = loc("Users matching search criteria");
+ if ($UserField =~ /^CustomField-(\d+)/) {
+ $users->LimitCustomField(
+ CUSTOMFIELD => $1,
+ OPERATOR => $UserOp,
+ VALUE => $UserString,
+ );
+ }
+ else {
+ $users->Limit(
+ FIELD => $UserField,
+ OPERATOR => $UserOp,
+ VALUE => $UserString,
+ );
+ }
+}
+else {
+ $caption = loc("Privileged users");
+ $users->LimitToPrivileged;
+}
+</%INIT>
+<%ARGS>
+$UserString => undef
+$UserOp => '='
+$UserField => 'Name'
+$IdLike => undef
+$EmailLike => undef
+$FindDisabledUsers => 0
+</%ARGS>
diff --git a/rt/html/Admin/autohandler b/rt/html/Admin/autohandler
new file mode 100644
index 000000000..b346cbc20
--- /dev/null
+++ b/rt/html/Admin/autohandler
@@ -0,0 +1,53 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+$m->call_next(%ARGS) if $session{'CurrentUser'}->UserObj->HasRight(
+ Right => 'ShowConfigTab',
+ Object => $RT::System,
+);
+</%init> \ No newline at end of file
diff --git a/rt/html/Admin/index.html b/rt/html/Admin/index.html
new file mode 100644
index 000000000..c89a88350
--- /dev/null
+++ b/rt/html/Admin/index.html
@@ -0,0 +1,101 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Admin/Elements/Header, Title => loc('RT Administration') &>
+<& /Admin/Elements/Tabs, Title => loc('RT Administration') &>
+
+<ul>
+% foreach my $key (sort keys %$tabs) {
+<li><span><a href="<%$RT::WebPath%>/<%$tabs->{$key}->{'path'}|n %>"><%$tabs->{$key} ->{'title'}%></a></span><br />
+<%$tabs->{$key}->{description}%>
+</li>
+%}
+</ul>
+<%init>
+
+
+
+my $tabs = {
+ A => {
+ title => loc('Users'),
+ path => 'Admin/Users/index.html',
+ description => loc('Manage users and passwords'),
+ },
+ B => {
+ title => loc('Groups'),
+ path => 'Admin/Groups/index.html',
+ description => loc('Manage groups and group membership'),
+ },
+ C => {
+ title => loc('Queues'),
+ path => 'Admin/Queues/index.html',
+ description => loc('Manage queues and queue-specific properties'),
+ },
+ D => {
+ 'title' => loc('Custom Fields'),
+ description => loc('Manage custom fields and custom field values'),
+ path => 'Admin/CustomFields/index.html',
+ },
+ E => {
+ 'title' => loc('Global'),
+ path => 'Admin/Global/index.html',
+ description =>
+ loc('Manage properties and configuration which apply to all queues'),
+ },
+ F => {
+ 'title' => loc('Tools'),
+ path => 'Admin/Tools/index.html',
+ description => loc('Use other RT administrative tools')
+ },
+};
+
+ $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+
+
+
+</%init>
diff --git a/rt/html/Approvals/Display.html b/rt/html/Approvals/Display.html
new file mode 100644
index 000000000..477959798
--- /dev/null
+++ b/rt/html/Approvals/Display.html
@@ -0,0 +1,72 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title &>
+
+<& Elements/Tabs,
+ current_tab => "Approvals/Display.html",
+ Title => $title &>
+<form method="post" action="<%$RT::WebPath%>/Approvals/index.html">
+
+<&| /Widgets/TitleBox, title => $title &>
+<& /Ticket/Elements/ShowHistory , Ticket => $Ticket, Collapsed => 0, ShowTitle => 0, ShowHeaders => 0, ShowDisplayModes => 0, ShowTitleBarCommands => 0 &>
+<hr>
+<& Elements/Approve, ticket => $Ticket, ShowApproving => 0 &>
+</&>
+<& /Elements/Submit&>
+</form>
+<& Elements/ShowDependency, Ticket => $Ticket &>
+
+<%init>
+my $Ticket = LoadTicket($id);
+
+my $title = loc("Approval #[_1]: [_2]", $Ticket->Id, $Ticket->Subject);
+
+</%init>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Approvals/Elements/Approve b/rt/html/Approvals/Elements/Approve
new file mode 100644
index 000000000..6dd562a32
--- /dev/null
+++ b/rt/html/Approvals/Elements/Approve
@@ -0,0 +1,94 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<div class="approval">
+ <div class="name">
+ <a href="<%$RT::WebPath%>/Approvals/Display.html?id=<%$ticket->Id%>"><% loc("#[_1]: [_2]", $ticket->Id, $ticket->Subject) %></a> (<%loc($ticket->Status)%>)
+ </div>
+% if ($ShowApproving) {
+% foreach my $approving ( $ticket->AllDependedOnBy( Type => 'ticket' ) ) {
+ <div class="originating-ticket">
+ <span class="link"><a href="<%$RT::WebPath%>/Ticket/Display.html?id=<% $approving->Id %>"><&|/l, $approving->Id, $approving->Subject &>Originating ticket: #[_1]</&></a></span>
+ <div class="info">
+% if ($ShowCustomFields) {
+ <& /Ticket/Elements/ShowCustomFields, Ticket => $approving &>
+% }
+% if ($ShowHistory) {
+ <& /Ticket/Elements/ShowHistory, Ticket => $approving, Collapsed => 0, ShowTitle => 0, ShowHeaders => 0, ShowDisplayModes => 0, ShowTitleBarCommands => 0 &>
+% }
+ </div>
+ </div>
+% }
+% }
+ <div class="form">
+ <div class="action">
+ <div>
+ <input type="radio" class="radio" id="Approval-<%$ticket->Id%>-Action-approve" name="Approval-<%$ticket->Id%>-Action" value="approve" />
+ <label for="Approval-<%$ticket->Id%>-Action-approve"><&|/l&>Approve</&></label>
+ </div>
+ <div>
+ <input type="radio" class="radio" id="Approval-<%$ticket->Id%>-Action-deny" name="Approval-<%$ticket->Id%>-Action" value="deny" />
+ <label for="Approval-<%$ticket->Id%>-Action-deny"><&|/l&>Deny</&></label>
+ </div>
+ <div>
+ <input type="radio" class="radio" id="Approval-<%$ticket->Id%>-Action-none" name="Approval-<%$ticket->Id%>-Action" value="none" checked="checked" />
+ <label for="Approval-<%$ticket->Id%>-Action-none"><&|/l&>No action</&></label>
+ </div>
+ </div>
+ <div class="notes">
+ <label for="Approval-<%$ticket->Id%>-Notes"><&|/l&>Notes</&></label>
+ <textarea name="Approval-<%$ticket->Id%>-Notes" id="Approval-<%$ticket->Id%>-Notes" rows="2" cols="70"></textarea>
+ </div>
+ <div class="clear"></div>
+ </div>
+</div>
+<%ARGS>
+$ShowApproving => 1
+$ShowCustomFields => 1
+$ShowHistory => 1
+$ticket => undef
+</%ARGS>
diff --git a/rt/html/Approvals/Elements/PendingMyApproval b/rt/html/Approvals/Elements/PendingMyApproval
new file mode 100644
index 000000000..e03145e18
--- /dev/null
+++ b/rt/html/Approvals/Elements/PendingMyApproval
@@ -0,0 +1,111 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<script type="text/javascript"><!--
+ onLoadHook('createCalendarLink("CreatedBefore");');
+ onLoadHook('createCalendarLink("CreatedAfter");');
+--></script>
+% my %done;
+% foreach ($tickets, $group_tickets) {
+% while (my $ticket = $_->Next() ) {
+% next if !$ARGS{'ShowDependent'} and $ticket->HasUnresolvedDependencies( Type => 'approval' );
+% next if $done{$ticket->Id}++; # don't show duplicate tickets
+<& Approve, ticket => $ticket &>
+% }
+% }
+
+<&| /Widgets/TitleBox, title => loc("Search for approvals") &>
+<input type="checkbox" class="checkbox" value="1" name="ShowPending"
+ <%((!$ARGS{'ShowRejected'} && !$ARGS{'ShowResolved'}) ||
+ $ARGS{'ShowPending'})
+ && "checked"%> /> <&|/l&>Show pending requests</&><br />
+<input type="checkbox" class="checkbox" value="1" name="ShowResolved" <%$ARGS{'ShowResolved'} && "checked"%> /> <&|/l&>Show approved requests</&><br />
+<input type="checkbox" class="checkbox" value="1" name="ShowRejected" <%$ARGS{'ShowRejected'} && "checked"%> /> <&|/l&>Show denied requests</&><br />
+<input type="checkbox" class="checkbox" value="1" name="ShowDependent" <%$ARGS{'ShowDependent'} && "checked"%> /> <&|/l&>Show requests awaiting other approvals</&><br />
+
+<&|/l,"<input size='15' value='".($created_before->Unix > 0 &&$created_before->ISO)."' name='CreatedBefore' id='CreatedBefore' />"&>Only show approvals for requests created before [_1]</&><br />
+
+<&|/l, "<input size='15' value='".( $created_after->Unix >0 && $created_after->ISO)."' name='CreatedAfter' id='CreatedAfter' />"&>Only show approvals for requests created after [_1]</&>
+</&>
+
+<%init>
+my $tickets = RT::Tickets->new( $session{'CurrentUser'} );
+$tickets->LimitOwner( VALUE => $session{'CurrentUser'}->Id );
+
+# also consider AdminCcs as potential approvers.
+my $group_tickets = RT::Tickets->new( $session{'CurrentUser'} );
+$group_tickets->LimitWatcher( VALUE => $session{'CurrentUser'}->UserObj->EmailAddress, TYPE => 'AdminCc' );
+
+my $created_before = RT::Date->new( $session{'CurrentUser'} );
+my $created_after = RT::Date->new( $session{'CurrentUser'} );
+
+foreach ($tickets, $group_tickets) {
+ $_->Limit( FIELD => 'Type', VALUE => 'approval' );
+
+ if ( $ARGS{'ShowResolved'} ) {
+ $_->LimitStatus( VALUE => 'resolved' );
+ }
+ if ( $ARGS{'ShowRejected'} ) {
+ $_->LimitStatus( VALUE => 'rejected' );
+ }
+ if ( $ARGS{'ShowPending'} || ( !$ARGS{'ShowRejected'} && !$ARGS{'Resolved'} ) ) {
+ $_->LimitStatus( VALUE => 'open' );
+ $_->LimitStatus( VALUE => 'new' );
+ $_->LimitStatus( VALUE => 'stalled' );
+ }
+
+ if ( $ARGS{'CreatedBefore'} ) {
+ $created_before->Set( Format => 'unknown', Value => $ARGS{'CreatedBefore'} );
+ $_->LimitCreated( OPERATOR => "<=", VALUE => $created_before->ISO );
+ }
+ if ( $ARGS{'CreatedAfter'} ) {
+ $created_after->Set( Format => 'unknown', Value => $ARGS{'CreatedAfter'} );
+ $_->LimitCreated( OPERATOR => ">=", VALUE => $created_after->ISO );
+ }
+}
+
+</%init>
diff --git a/rt/html/Approvals/Elements/ShowDependency b/rt/html/Approvals/Elements/ShowDependency
new file mode 100644
index 000000000..6da28f180
--- /dev/null
+++ b/rt/html/Approvals/Elements/ShowDependency
@@ -0,0 +1,109 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% my $approving = $Ticket->DependedOnBy();
+% if ($approving->Count) {
+<h3><&|/l&>Tickets which depend on this approval:</&></h3>
+
+<table width="100%">
+<tr>
+<td width="25" bgcolor="#999999">&nbsp;</td><td>
+<%PERL>
+my %show;
+while (my $link = $approving->Next()) {
+ next unless ($link->BaseURI->IsLocal());
+ my $text = '<a name="' . $link->BaseObj->Id . '">';
+ my $head = '';
+ my $type = $link->BaseObj->Type;
+ my $dep = $m->scomp('ShowDependency', Ticket => $link->BaseObj, _seen => $_seen);
+
+ if ($type eq 'approval') {
+ $head .= $m->scomp('/Widgets/TitleBoxStart', title => loc("Approval #[_1]: [_2]", $link->BaseObj->Id, $link->BaseObj->Subject));
+ $text .= $head;
+ $text .= $m->scomp('/Ticket/Elements/ShowCustomFields', Ticket => $link->BaseObj);
+ } elsif ($type eq 'ticket') {
+ $head .= $m->scomp('/Widgets/TitleBoxStart', title => loc("Ticket #[_1]: [_2]", $link->BaseObj->Id, $link->BaseObj->Subject));
+ $text .= $head;
+ $text .= $m->scomp('/Ticket/Elements/ShowSummary', Ticket => $link->BaseObj);
+ } else {
+ $head .= $m->scomp('/Widgets/TitleBoxStart', title => loc("#[_1]: [_2]", $link->BaseObj->Id, $link->BaseObj->Subject));
+ $text .= $head;
+ }
+
+ $text .= $m->scomp('/Ticket/Elements/ShowHistory' , Ticket => $link->BaseObj, Collapsed => ($type ne 'ticket'), ShowTitle => 0, ShowHeaders => 0, ShowDisplayModes => 0, ShowTitleBarCommands => 0);
+
+ $head .= $m->scomp('/Widgets/TitleBoxEnd');
+ $text .= $m->scomp('/Widgets/TitleBoxEnd');
+ $text .= $dep;
+ $text .= '</a>';
+ $show{$link->BaseObj->Id} = {
+ text => $text,
+ head => $head,
+ };
+}
+
+my $refer;
+foreach my $id (sort keys %show) {
+ if ($_seen->{$id}++) {
+ $refer .= "<a href='#txn-$id'>" . $show{$id}{head} . "</a>";
+ next;
+ }
+
+ $m->print($show{$id}{text});
+}
+$m->print($refer);
+
+</%PERL>
+</td>
+</tr>
+</table>
+
+% }
+<%ARGS>
+$Ticket
+$_seen => {}
+</%ARGS>
diff --git a/rt/html/Approvals/Elements/Tabs b/rt/html/Approvals/Elements/Tabs
new file mode 100644
index 000000000..9ba425059
--- /dev/null
+++ b/rt/html/Approvals/Elements/Tabs
@@ -0,0 +1,58 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Tabs,
+ tabs => $tabs,
+ current_toptab => 'Approvals/',
+ current_tab => $current_tab,
+ Title => $Title &>
+
+<%ARGS>
+$tabs => undef
+$current_tab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Approvals/index.html b/rt/html/Approvals/index.html
new file mode 100644
index 000000000..ab91ffe97
--- /dev/null
+++ b/rt/html/Approvals/index.html
@@ -0,0 +1,90 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc("My approvals") &>
+<& /Approvals/Elements/Tabs, Title => loc("My approvals") &>
+
+<& /Elements/ListActions, actions => \@actions &>
+<form method="post">
+<& Elements/PendingMyApproval, %ARGS &>
+<& /Elements/Submit, Label => loc('Go!') &>
+</form>
+<%init>
+
+my (@actions);
+foreach my $arg ( keys %ARGS ) {
+
+ next unless ( $arg =~ /Approval-(\d+)-Action/ );
+
+ my ( $notesval, $notesmsg );
+
+ my $ticket = LoadTicket($1);
+
+ if ( $ARGS{ "Approval-" . $ticket->Id . "-Notes" } ) {
+ my $notes = MIME::Entity->build(
+ Data => [ $ARGS{ "Approval-" . $ticket->Id . "-Notes" } ]
+ );
+ RT::I18N::SetMIMEEntityToUTF8($notes); # convert text parts into utf-8
+
+ my ( $notesval, $notesmsg ) = $ticket->Correspond( MIMEObj => $notes );
+ if ($notesval) {
+ push ( @actions, loc("Approval #[_1]: Notes recorded",$ticket->Id ));
+ } else {
+ push ( @actions, loc("Approval #[_1]: Notes not recorded due to a system error",$ticket->Id ));
+ }
+ }
+
+ my ($val, $msg);
+ if ( $ARGS{$arg} eq 'deny' ) {
+ ( $val, $msg ) = $ticket->SetStatus('rejected');
+ }
+ elsif ( $ARGS{$arg} eq 'approve' ) {
+ ( $val, $msg ) = $ticket->SetStatus('resolved');
+ }
+ push ( @actions, loc("Approval #[_1]: [_2]",$ticket->id, $msg )) if ($msg);
+}
+</%init>
diff --git a/rt/html/Callbacks/ActivityReports/Elements/Tabs/Default b/rt/html/Callbacks/ActivityReports/Elements/Tabs/Default
new file mode 100644
index 000000000..f85d2e010
--- /dev/null
+++ b/rt/html/Callbacks/ActivityReports/Elements/Tabs/Default
@@ -0,0 +1,7 @@
+<%init>
+if ($ARGS{current_toptab} eq "Tools/Offline.html") {
+ $ARGS{tabs}{r} ||= { path => 'Reports/Activity/index.html',
+ title => 'Reports',
+ };
+}
+</%init> \ No newline at end of file
diff --git a/rt/html/Callbacks/ActivityReports/NoAuth/webrt.css/Default b/rt/html/Callbacks/ActivityReports/NoAuth/webrt.css/Default
new file mode 100644
index 000000000..30480f7b6
--- /dev/null
+++ b/rt/html/Callbacks/ActivityReports/NoAuth/webrt.css/Default
@@ -0,0 +1,71 @@
+table.miniplot {
+ width: 100%;
+ border-collapse: collapse;
+}
+table.miniplot td {
+ margin: 0;
+ padding: 0;
+ border-bottom: 1px solid black;
+}
+table.miniplot .graph {
+ margin-left: auto;
+ margin-right: auto;
+ position: relative;
+ width: 60px;
+}
+table.miniplot .graph ul {
+ height: 100px;
+ margin: 0;
+ padding: 0;
+}
+table.miniplot .graph ul li {
+ list-style: none;
+ position: absolute;
+ bottom: 0px;
+ padding: 0 !important;
+ margin: 0 !important;
+ border-bottom: none;
+}
+table.miniplot .graph ul li .data {
+ display: none;
+}
+
+.miniplot .demoblock { margin: 0 10px; padding: 0 30px; }
+
+.miniplot .c1 { border: 2px solid #990000; background: #ff0000; }
+.miniplot .c2 { border: 2px solid #996600; background: #ff9900; }
+.miniplot .c3 { border: 2px solid #009900; background: #00ff00; }
+.miniplot .c4 { border: 2px solid #009999; background: #00ffff; }
+.miniplot .c5 { border: 2px solid #000099; background: #0000ff; }
+.miniplot .c6 { border: 2px solid #990099; background: #ff00ff; }
+graph .c5 { border: 2px solid #000099; background: #0000ff; }
+.graph .c6 { border: 2px solid #990099; background: #ff00ff; }
+
+tr.titlerow th {
+
+ border-bottom: solid black 1px;
+ margin: 0;
+ font-size:80%;
+ text-wrap: none;
+
+}
+
+tr.grandtotal td{
+ border-top: 1px solid black;
+}
+
+tr.grandtotal th{
+ border-top: 1px solid black;
+}
+
+th.label {
+ align: left;
+
+}
+
+table.miniplot th.legend {
+ font-style: normal;
+ font-size: 80%;
+
+}
+
diff --git a/rt/html/Callbacks/ActivityReports/Search/Results.html/SearchActions b/rt/html/Callbacks/ActivityReports/Search/Results.html/SearchActions
new file mode 100644
index 000000000..4775a9af3
--- /dev/null
+++ b/rt/html/Callbacks/ActivityReports/Search/Results.html/SearchActions
@@ -0,0 +1,7 @@
+<a href="<% $RT::WebPath %>/Reports/Activity/index.html?<% $QueryString %>">Generate reports</a>
+<%init>
+use YAML;
+my %args = $m->caller_args(2);
+
+my $QueryString = $m->comp('/Elements/QueryString', query => $args{Query});
+</%init> \ No newline at end of file
diff --git a/rt/html/Callbacks/RT-WebCronTool/Elements/Tabs/Default b/rt/html/Callbacks/RT-WebCronTool/Elements/Tabs/Default
new file mode 100644
index 000000000..db74ced2d
--- /dev/null
+++ b/rt/html/Callbacks/RT-WebCronTool/Elements/Tabs/Default
@@ -0,0 +1,13 @@
+%# The day after tomorrow is the third day of the rest of your life.
+<%INIT>
+if ($session{'CurrentUser'}->UserObj->HasRight(
+ Right => 'SuperUser',
+ Object => $RT::System,
+)) {
+ $toptabs->{'ZZ-RT-WebCronTool'} = { title =>loc("Web CronTool"),
+ path => "Developer/CronTool/index.html" };
+}
+</%init>
+<%args>
+$toptabs =>undef
+</%args>
diff --git a/rt/html/Callbacks/kStatistics/Elements/Tabs/Default b/rt/html/Callbacks/kStatistics/Elements/Tabs/Default
new file mode 100644
index 000000000..d4ca2b95e
--- /dev/null
+++ b/rt/html/Callbacks/kStatistics/Elements/Tabs/Default
@@ -0,0 +1,11 @@
+<%init>
+use RTx::Statistics;
+if (($Statistics::RestrictAccess == 0) || ($session{'CurrentUser'}->HasRight( Right => 'ShowConfigTab',
+ Object => $RT::System ))) {
+ $toptabs->{'ZZ-RTx-STATS'} = { title => 'RTx-Statistics',
+ path => "RTx/Statistics/index.html" };
+}
+</%init>
+<%args>
+ $toptabs =>undef
+</%args>
diff --git a/rt/html/Developer/CronTool/autohandler b/rt/html/Developer/CronTool/autohandler
new file mode 100644
index 000000000..7daa09e8d
--- /dev/null
+++ b/rt/html/Developer/CronTool/autohandler
@@ -0,0 +1,9 @@
+%# All theoretical chemistry is really physics;
+%# and all theoretical chemists know it.
+%# -- Richard P. Feynman
+<%INIT>
+$m->call_next(%ARGS) if $session{'CurrentUser'}->UserObj->HasRight(
+ Right => 'SuperUser',
+ Object => $RT::System,
+);
+</%INIT>
diff --git a/rt/html/Developer/CronTool/index.html b/rt/html/Developer/CronTool/index.html
new file mode 100644
index 000000000..67c9e5634
--- /dev/null
+++ b/rt/html/Developer/CronTool/index.html
@@ -0,0 +1,116 @@
+% if ($@) {
+<P><FONT Color="red"><% $@ %></FONT></P>
+% }
+% if (!$NoUI) {
+<HR>
+<FORM Action="index.html" Method="POST">
+<TABLE>
+% foreach my $class (qw( Search Condition Action )) {
+<TR><TH>
+<% loc($class) %>
+</TH><TD>
+<SELECT NAME="<% $class %>">
+% require File::Find;
+% my @modules;
+% File::Find::find(sub {
+% push @modules, $1 if /^(?!Generic|UserDefined)(\w+)\.pm$/i;
+% }, grep -d, map "$_/RT/$class", @INC);
+<OPTION <% $ARGS{$class} ? '' : 'SELECTED' %>></OPTION>
+% foreach my $module (sort @modules) {
+% my $fullname = "RT::$class\::$module";
+ <OPTION VALUE="<% $fullname %>" <% ($fullname eq $ARGS{$class}) ? 'SELECTED' : '' %>><% $module %></OPTION>
+% }
+</SELECT>
+</TD><TH>
+<&|/l&>Parameter</&>
+</TH><TD>
+<INPUT NAME="<% $class %>Arg" VALUE="<% $ARGS{$class.'Arg'} %>">
+</TD></TR>
+% }
+<TR>
+<TD COLSPAN="4" ALIGN="Right">
+<LABEL>
+<INPUT TYPE="CheckBox" NAME="Verbose" <% $Verbose ? 'CHECKED' : '' %>><&|/l&>Verbose</&>
+</LABEL>
+<INPUT TYPE="Submit" VALUE="<&|/l&>Run</&>">
+</TD>
+</TABLE>
+</FORM>
+<HR>
+% }
+<%INIT>
+$m->print("<H1>", loc("Web CronTool"), "</H1>");
+if ($Search) {
+ my $load_module = sub {
+ my $modname = $_[0];
+ $modname =~ s{::}{/}g;
+ require "$modname.pm" or die (
+ loc( "Failed to load module [_1]. ([_2])", $_[0], $@ ) . "\n"
+ );
+ };
+ $m->print(loc("Starting..."), "<UL>");
+ eval {
+ $load_module->($Search);
+ $load_module->($Action) if $Action;
+ $load_module->($Condition) if $Condition;
+
+ if ($TemplateId and !$TemplateObj) {
+ $TemplateObj = RT::Template->new($RT::Nobody);
+ $TemplateObj->LoadById($TemplateId);
+ }
+
+ my $tickets = RT::Tickets->new($RT::SystemUser);
+ my $search = $Search->new( TicketsObj => $tickets, Argument => $SearchArg );
+ $search->Prepare;
+ my $tickets_found = $search->TicketsObj;
+
+ #for each ticket we've found
+ while ( my $ticket = $tickets_found->Next ) {
+ $m->print("<LI>" . $ticket->Id . ": ") if $Verbose;
+ $m->print(loc("Checking...")) if $Verbose;
+
+ # perform some more advanced check
+ if ($Condition) {
+ my $ConditionObj = $Condition->new(
+ TicketObj => $ticket,
+ Argument => $ConditionArg
+ );
+
+ # if the condition doesn't apply, get out of here
+ next unless ( $ConditionObj->IsApplicable );
+ $m->print(loc("Condition matches...")) if $Verbose;
+ }
+
+ if ($Action) {
+ #prepare our action
+ my $ActionObj = $Action->new(
+ TicketObj => $ticket,
+ TemplateObj => $TemplateObj,
+ Argument => $ActionArg
+ );
+
+ #if our preparation, move onto the next ticket
+ next unless ( $ActionObj->Prepare );
+ $m->print(loc("Action prepared...")) if $Verbose;
+
+ #commit our action.
+ next unless ( $ActionObj->Commit );
+ $m->print(loc("Action committed.")) if $Verbose;
+ }
+ }
+ };
+ $m->print('</UL>', loc("Finished."));
+}
+</%INIT>
+<%ARGS>
+$Search => undef
+$SearchArg => undef
+$Condition => undef
+$ConditionArg => undef
+$Action => undef
+$ActionArg => undef
+$TemplateId => undef
+$TemplateObj => undef
+$Verbose => 1
+$NoUI => 0
+</%ARGS>
diff --git a/rt/html/Download/CustomFieldValue/dhandler b/rt/html/Download/CustomFieldValue/dhandler
new file mode 100644
index 000000000..461267e00
--- /dev/null
+++ b/rt/html/Download/CustomFieldValue/dhandler
@@ -0,0 +1,77 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%perl>
+my $id;
+my $arg = $m->dhandler_arg; # get rest of path
+if ($arg =~ /^(\d+)\//) {
+ $id = $1;
+}
+else {
+ Abort("Corrupted customfieldvalue URL.");
+}
+my $OCFV = RT::ObjectCustomFieldValue->new($session{'CurrentUser'});
+$OCFV->Load($id) || Abort("OCFV '$id' could not be loaded");
+
+unless ($OCFV->id) {
+ Abort("Bad OCFV id. Couldn't find OCFV '$id'\n");
+}
+
+my $content_type = $OCFV->ContentType || 'text/plain';
+
+unless ($RT::TrustHTMLAttachments) {
+ $content_type = 'text/plain' if ($content_type =~ /^text\/html/i);
+}
+
+$r->content_type( $content_type );
+$m->clear_buffer();
+$m->out($OCFV->LargeContent);
+$m->abort;
+</%perl>
+<%attr>
+AutoFlush => 0
+</%attr>
diff --git a/rt/html/Download/Tabular/dhandler b/rt/html/Download/Tabular/dhandler
new file mode 100644
index 000000000..0abb8f9db
--- /dev/null
+++ b/rt/html/Download/Tabular/dhandler
@@ -0,0 +1,76 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%perl>
+my ($class, $filename, @ids);
+my $arg = $m->dhandler_arg; # get rest of path
+if ($arg =~ /^(\w+)\/([,\d]+)(?:\/([^\/]+))?/) {
+ $class = "RT::$1";
+ $filename = $3 || "$1s.tsv";
+ @ids = sort split(/,+/, $2);
+}
+else {
+ Abort("Corrupted tabular URL.");
+}
+
+my @cols = $class->BasicColumns or return;
+
+#$r->content_type( 'application/octet-stream' );
+$r->content_type( 'text/plain' );
+$r->headers_out->{'Content-Disposition'} = "attachment; filename=$filename";
+$m->clear_buffer();
+$m->out(join("\t", "Id", map $_->[1], @cols), "\n");
+foreach my $id (@ids) {
+ my $obj = $class->new;
+ $obj->Load($id) or next;
+ $m->out(join("\t", map $obj->$_, "Id", map $_->[0], @cols), "\n");
+}
+$m->abort;
+</%perl>
+<%attr>
+AutoFlush => 0
+</%attr>
diff --git a/rt/html/Elements/AddCustomers b/rt/html/Elements/AddCustomers
new file mode 100644
index 000000000..aaf8ca8ba
--- /dev/null
+++ b/rt/html/Elements/AddCustomers
@@ -0,0 +1,59 @@
+%# Copyright (c) 2004 Ivan Kohler <ivan-rt@420.am>
+%# Copyright (c) 2008 Freeside Internet Services, Inc.
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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.
+<BR>
+<%$msg%><br>
+
+% if (@Customers) {
+
+<br><i>(Check box to link)<i>
+<table>
+% foreach my $customer (@Customers) {
+<tr>
+ <td>
+ <input type="checkbox" name="Object-AddCustomer-<% $customer->{'custnum'} %>" VALUE="1" <% scalar(@Customers) == 1 ? 'CHECKED' : '' %>>
+ <A HREF="<%$freeside_url%>/view/cust_main.cgi?<% $customer->{'custnum'} %>"><% &RT::URI::freeside::small_custview($customer->{'custnum'}, &RT::URI::freeside::FreesideGetConfig('countrydefault'), 1) |n %>
+ </td>
+</tr>
+% }
+</table>
+
+% }
+
+<%INIT>
+my ($msg);
+
+my $freeside_url = &RT::URI::freeside::FreesideURL();
+
+warn "/Elements/AddCustomers called with CustomerString $CustomerString\n"
+ if $Debug;
+
+my @Customers = ();
+if ( $CustomerString ) {
+ @Customers = &RT::URI::freeside::smart_search( 'search' => $CustomerString );
+}
+
+my @Services = ();
+if ($ServiceString) {
+ @Services = (); #service_search();
+}
+
+warn "/Elements/AddCustomers displaying ". scalar(@Customers). " customers\n"
+ if $Debug;
+
+</%INIT>
+
+<%ARGS>
+$CustomerString => undef
+$ServiceString => undef
+$Debug => 0
+</%ARGS>
diff --git a/rt/html/Elements/BevelBoxRaisedEnd b/rt/html/Elements/BevelBoxRaisedEnd
new file mode 100644
index 000000000..b1ba8f69b
--- /dev/null
+++ b/rt/html/Elements/BevelBoxRaisedEnd
@@ -0,0 +1,50 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+ </td>
+</tr>
+</table>
diff --git a/rt/html/Elements/BevelBoxRaisedStart b/rt/html/Elements/BevelBoxRaisedStart
new file mode 100644
index 000000000..b690c1d74
--- /dev/null
+++ b/rt/html/Elements/BevelBoxRaisedStart
@@ -0,0 +1,50 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table cellspacing="0" cellpadding="0" width="100%" height="100%">
+ <tr>
+ <td width="100%" height="100%">
diff --git a/rt/html/Elements/Callback b/rt/html/Elements/Callback
new file mode 100644
index 000000000..b498f2816
--- /dev/null
+++ b/rt/html/Elements/Callback
@@ -0,0 +1,92 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%once>
+my %cache;
+</%once>
+<%init>
+$Page = $m->callers(1)->path unless ($Page);
+
+my $CacheKey = "Callback--$Page--$_CallbackName";
+my $callbacks = $cache{$CacheKey} || $m->notes($CacheKey);
+
+if (!$callbacks) {
+ my $path = "/Callbacks/*$Page/$_CallbackName";
+
+ # Due to API changes after Mason 1.28, we have to check for which
+ # version we're running when getting the component roots
+ my @roots = map { $_->[1] }
+ $HTML::Mason::VERSION <= 1.28
+ ? $m->interp->resolver->comp_root_array
+ : $m->interp->comp_root_array;
+
+ my %seen;
+
+ for my $root (@roots) {
+ push @$callbacks,
+ # Skip backup files, files without a leading package name,
+ # and files we've already seen
+ grep { !/\/\.|~$/
+ and $_ ne "/Callbacks/$Page/$_CallbackName"
+ and not $seen{$_}++ }
+ $m->interp->resolver->glob_path($path, $root);
+ }
+
+ $m->notes($CacheKey => $callbacks);
+ $cache{$CacheKey} = $callbacks if !$RT::DevelMode;
+}
+
+my @rv;
+foreach my $comp (sort @$callbacks) {
+ push @rv, $m->comp($comp, %ARGS);
+}
+return @rv;
+</%init>
+<%args>
+$_CallbackName => 'Default'
+$Page => undef
+</%args>
diff --git a/rt/html/Elements/Checkbox b/rt/html/Elements/Checkbox
new file mode 100644
index 000000000..5593c7a71
--- /dev/null
+++ b/rt/html/Elements/Checkbox
@@ -0,0 +1,63 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<input type="checkbox" class="checkbox" name="<%$Name%>" value="1" <%$IsChecked%> />
+
+<%ARGS>
+$Name => undef
+$Default => undef
+$True => undef
+$False => undef
+$IsChecked => undef
+</%ARGS>
+
+<%INIT>
+$IsChecked =
+ ($Default && $Default =~ /checked/i)
+ ? " CHECKED " : "";
+1;
+</%INIT>
diff --git a/rt/html/Elements/CollectionAsTable/Header b/rt/html/Elements/CollectionAsTable/Header
new file mode 100644
index 000000000..a3277b317
--- /dev/null
+++ b/rt/html/Elements/CollectionAsTable/Header
@@ -0,0 +1,125 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+@Format => undef
+$FormatString => undef
+$AllowSorting => undef
+$Order=>undef
+$BaseURL => undef
+$Query => undef
+$Rows => undef
+$Page => undef
+$maxitems => undef
+</%ARGS>
+<tr class="collection-as-table">
+<%perl>
+
+my %generic_query_args = ( Query => $Query, Rows => $Rows, Page => $Page, Format => $FormatString );
+
+my $item = 0;
+foreach my $col (@Format) {
+ $item++;
+ if ( $col->{title} && ($col->{title} eq 'NEWLINE') ) {
+ while ( $item < $maxitems ) {
+ $m->out(qq{<th class="collection-as-table">&nbsp;</th>\n});
+ $item++;
+ }
+
+ $item = 0;
+ $m->out(qq{</tr>\n<tr class="collection-as-table">});
+ }
+ else {
+ $m->out('<th class="collection-as-table">');
+ my $title = $col->{title} || '';
+ $title =~ s/^__(.*)__$/$1/o;
+ $title = (
+ $m->comp(
+ '/Elements/RT__Ticket/ColumnMap',
+ Name => $title,
+ Attr => 'title'
+ )
+ || $title
+ );
+ if (
+ $AllowSorting
+ && $col->{'attribute'}
+ && $m->comp(
+ '/Elements/RT__Ticket/ColumnMap',
+ Name => $col->{'attribute'},
+ Attr => 'attribute'
+ )
+ )
+ {
+
+ $m->out(
+ '<a href="' . $BaseURL
+ . $m->comp(
+ '/Elements/QueryString',
+ %generic_query_args,
+ OrderBy => (
+ $m->comp(
+ '/Elements/RT__Ticket/ColumnMap',
+ Name => $col->{'attribute'},
+ Attr => 'attribute'
+ )
+ || $col->{'attribute'}
+ ),
+ Order => ( $ARGS{'Order'} eq 'ASC' ? 'DESC' : 'ASC' )
+ )
+ . '">'
+ . loc($title) . '</a>'
+ );
+ }
+ else {
+ $m->out( loc($title) );
+ }
+ $m->out('</th>');
+ }
+}
+</%perl>
+</tr>
diff --git a/rt/html/Elements/CollectionAsTable/ParseFormat b/rt/html/Elements/CollectionAsTable/ParseFormat
new file mode 100644
index 000000000..227076093
--- /dev/null
+++ b/rt/html/Elements/CollectionAsTable/ParseFormat
@@ -0,0 +1,106 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+$Format
+</%ARGS>
+
+<%init>
+use Regexp::Common qw/delimited/;
+my @Columns;
+
+while ($Format =~ /($RE{delimited}{-delim=>qq{\'"}}|[{}\w.]+)/go) {
+ my $col = $1;
+
+ if ($col =~ /^$RE{quoted}$/o) {
+ substr($col,0,1) = "";
+ substr($col,-1,1) = "";
+ }
+
+ my $colref = {
+ title => '',
+ };
+
+ if ( $col =~ s!/STYLE:([^/]+)!!io ) {
+ $colref->{'style'} = $1;
+ }
+ if ( $col =~ s!/CLASS:([^/]+)!!io ) {
+ $colref->{'class'} = $1;
+ }
+ if ( $col =~ s!/TITLE:([^/]+)!!io ) {
+ $colref->{'title'} = $1;
+ }
+ if ( $col =~ s!/ALIGN:([^\/]+)!!io ) {
+ $colref->{'align'} = $1;
+ }
+ if ( $col =~ /__(.*?)__/gio ) {
+ my @subcols;
+ while ( $col =~ s/^(.*?)__(.*?)__//o ) {
+ push ( @subcols, $1 ) if ($1);
+ push ( @subcols, "__$2__" );
+ $colref->{'attribute'} = $2;
+ }
+ push ( @subcols, $col );
+ @{ $colref->{'output'} } = @subcols;
+ }
+ else {
+ @{ $colref->{'output'} } = ( "__" . $col . "__" );
+ $colref->{'attribute'} = $col;
+ }
+
+ if ( !$colref->{'title'} && grep { /^__(.+?)__$/io }
+ @{ $colref->{'output'} } )
+ {
+ $colref->{'title'} = $1;
+ $colref->{'attribute'} = $1;
+ }
+
+
+ push @Columns, $colref;
+}
+ return(@Columns);
+</%init>
diff --git a/rt/html/Elements/CollectionAsTable/Row b/rt/html/Elements/CollectionAsTable/Row
new file mode 100644
index 000000000..d8492265e
--- /dev/null
+++ b/rt/html/Elements/CollectionAsTable/Row
@@ -0,0 +1,117 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+$i => undef
+@Format => undef
+$record => undef
+$maxitems => undef
+$Depth => undef
+$Warning => undef
+</%ARGS>
+
+<%PERL>
+use HTML::Entities;
+$m->out('<tr class="' . ( $Warning ? 'warnline' : $i % 2 ? 'oddline' : 'evenline' ) . '" >' );
+my $item;
+foreach my $column (@Format) {
+ if ( defined $column->{title} && $column->{title} eq 'NEWLINE' ) {
+ while ( $item < $maxitems ) {
+ $m->out(qq{<td class="collection-as-table">&nbsp;</td>\n});
+ $item++;
+ }
+ $item = 0;
+ $m->out('</tr>');
+ $m->out('<tr class="'
+ . ( $Warning ? 'warnline' : $i % 2 ? 'oddline' : 'evenline' )
+ . '" >' );
+ next;
+ }
+ $item++;
+ my $class = $column->{class}
+ ? encode_entities($column->{class}, q{'"&<>}) : 'collection-as-table';
+ $m->out(qq{<td class="$class" });
+ $m->out( 'align="' . $column->{align} . '"' ) if ( $column->{align} );
+ $m->out( 'style="' . $column->{style} . '"' ) if ( $column->{style} );
+ $m->out('>');
+ foreach my $subcol ( @{ $column->{output} } ) {
+ if ( $subcol =~ /^__(.*?)__$/o ) {
+ my $col = $1;
+ my $value = $m->comp(
+ '/Elements/RT__Ticket/ColumnMap',
+ Name => $col,
+ Attr => 'value'
+ );
+ my @out;
+
+ if ( $value && ref($value) ) {
+
+ # All HTML snippets are returned by the callback function
+ # as scalar references. Data fetched from the objects are
+ # plain scalars, and needs to be escaped properly.
+ @out =
+ map {
+ ref($_) ? $$_ : $m->interp->apply_escapes( $_ => 'h' )
+ } &{$value}( $record, $i )
+ ;
+ }
+ else {
+
+ # Simple value; just escape it.
+ @out = $m->interp->apply_escapes( $value => 'h' );
+ }
+ s/\n/<br \/>/gs for @out;
+ $m->out( @out );
+ }
+ else {
+ $m->out($subcol);
+ }
+ }
+ $m->out('</td>');
+}
+$m->out('</tr>');
+</%PERL>
diff --git a/rt/html/Elements/CreateTicket b/rt/html/Elements/CreateTicket
new file mode 100644
index 000000000..644df223a
--- /dev/null
+++ b/rt/html/Elements/CreateTicket
@@ -0,0 +1,50 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<form action="<% $RT::WebPath %>/Ticket/Create.html" name="CreateTicketInQueue">
+<&|/l, $m->scomp('/Elements/SelectNewTicketQueue')&><input type="submit" class="button" value="New ticket in" />&nbsp;[_1]</&>
+</form>
diff --git a/rt/html/Elements/EditCustomField b/rt/html/Elements/EditCustomField
new file mode 100644
index 000000000..d247c63f1
--- /dev/null
+++ b/rt/html/Elements/EditCustomField
@@ -0,0 +1,99 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%INIT>
+my $Values;
+if ($Object and $Object->id) {
+ $Values = $Object->CustomFieldValues($CustomField->id);
+ $Values->Columns( qw( id CustomField ObjectType ObjectId Disabled Content ContentType ContentEncoding ) );
+ $NamePrefix ||= join('-', 'Object', ref($Object), $Object->Id, 'CustomField', '');
+} elsif (not $Default) {
+ my %TOP = $m->request_args;
+ $Default = $TOP{ $NamePrefix .$CustomField->Id . '-Values' }
+ || $TOP{ $NamePrefix .$CustomField->Id . '-Value' };
+}
+my $Type = $CustomField->Type;
+
+return unless ($Type); # if we can't see the type, all hell will break loose.
+
+my $MaxValues = $CustomField->MaxValues;
+if ($MaxValues == 1 and $Object and $Values) {
+ # what exactly is this doing? Without the "unless" it breaks RTFM
+ # transaction extraction into articles.
+ $Default = ($Values->First ? $Values->First->Content : '') unless $Default;
+ $Values->GotoFirstItem;
+}
+# The "Magic" hidden input causes RT to know that we were trying to edit the field, even if
+# we don't see a value later, since browsers aren't compelled to submit empty form fields
+$m->out("\n".'<input type="hidden" class="hidden" name="'.$NamePrefix.$CustomField->Id.'-Values-Magic" value="1" />'."\n");
+
+my $EditComponent = "EditCustomField$Type";
+$m->comp('/Elements/Callback', _CallbackName => 'EditComponentName', Name => \$EditComponent, CustomField => $CustomField, Object => $Object );
+$EditComponent = "EditCustomField$Type" unless $m->comp_exists($EditComponent);
+
+return $m->comp(
+ $EditComponent,
+ %ARGS,
+ Rows => $Rows,
+ Cols => $Cols,
+ Default => $Default,
+ Object => $Object,
+ Values => $Values,
+ MaxValues => $MaxValues,
+ Multiple => ($MaxValues != 1),
+ NamePrefix => $NamePrefix,
+ CustomField => $CustomField,
+);
+</%INIT>
+<%ARGS>
+$Object => undef
+$CustomField => undef
+$NamePrefix => undef
+$Rows => 5
+$Cols => 15
+$Default => undef
+</%ARGS>
diff --git a/rt/html/Elements/EditCustomFieldBinary b/rt/html/Elements/EditCustomFieldBinary
new file mode 100644
index 000000000..485457c25
--- /dev/null
+++ b/rt/html/Elements/EditCustomFieldBinary
@@ -0,0 +1,62 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% while ($Values and my $value = $Values->Next ) {
+%# XXX - let user download the file(s) here?
+<input type="checkbox" class="checkbox" name="<%$NamePrefix%><%$CustomField->Id%>-DeleteValueIds" value="<% $value->Id %>" /><a href="<%$RT::WebPath%>/Download/CustomFieldValue/<% $value->Id %>/<% $value->Content %>"><% $value->Content %></a><br />
+% }
+% if (!$MaxValues or !$Values or $Values->Count < $MaxValues) {
+<input type="file" name="<%$NamePrefix%><%$CustomField->Id%>-Upload" />
+% }
+<%ARGS>
+$Object => undef
+$CustomField => undef
+$NamePrefix => undef
+$Default => undef
+$Values => undef
+$MaxValues => undef
+</%ARGS>
diff --git a/rt/html/Elements/EditCustomFieldCombobox b/rt/html/Elements/EditCustomFieldCombobox
new file mode 100644
index 000000000..071ef0772
--- /dev/null
+++ b/rt/html/Elements/EditCustomFieldCombobox
@@ -0,0 +1,68 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% while ($Values and my $value = $Values->Next and $Multiple) {
+<input type="checkbox" class="checkbox" name="<%$NamePrefix%><%$CustomField->Id%>-DeleteValueIds" value="<% $value->Id %>" /><% $value->Content %>
+<br />
+% }
+% (!$Multiple or !$MaxValues or !$Values or $Values->Count < $MaxValues) or return;
+<& /Widgets/ComboBox,
+ Name => $NamePrefix . $CustomField->Id . "-Value",
+ Default => $Default,
+ Rows => $Rows,
+ Values => [map {$_->Name} @{$CustomField->Values->ItemsArrayRef}],
+&>
+<%ARGS>
+$Object => undef
+$CustomField => undef
+$NamePrefix => undef
+$Default => undef
+$Values => undef
+$Multiple => 0
+$Rows => undef
+$MaxValues => undef
+</%ARGS>
diff --git a/rt/html/Elements/EditCustomFieldFreeform b/rt/html/Elements/EditCustomFieldFreeform
new file mode 100644
index 000000000..279632dcc
--- /dev/null
+++ b/rt/html/Elements/EditCustomFieldFreeform
@@ -0,0 +1,74 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% my $name = $NamePrefix . $CustomField->Id . '-Value';
+% if ($Multiple) {
+<textarea cols="<%$Cols%>" rows="<%$Rows%>" name="<%$name%>s" id="<%$name%>s" ><%$Default%></textarea>
+% } else {
+<input name="<%$name%>" id="<%$name%>" size="<%$Cols%>" value="<%$Default ? $Default : ''%>" />
+% }
+<%INIT>
+if ($Multiple and $Values) {
+ $Default = '';
+ while (my $value = $Values->Next ) {
+ $Default .= $value->Content."\n";
+ }
+}
+elsif ( ! $Multiple ) {
+ $Default =~ s/\s*\n\s*/ /g if $Default;
+}
+</%INIT>
+<%ARGS>
+$Object => undef
+$CustomField => undef
+$NamePrefix => undef
+$Default => undef
+$Values => undef
+$Multiple => undef
+$Cols
+$Rows
+</%ARGS>
diff --git a/rt/html/Elements/EditCustomFieldImage b/rt/html/Elements/EditCustomFieldImage
new file mode 100644
index 000000000..b6a30c659
--- /dev/null
+++ b/rt/html/Elements/EditCustomFieldImage
@@ -0,0 +1,62 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% while ($Values and my $value = $Values->Next ) {
+<input type="checkbox" class="checkbox" name="<%$NamePrefix%><%$CustomField->Id%>-DeleteValueIds" value="<% $value->Id %>" /><& ShowCustomFieldImage, Object => $value &>
+<br />
+% }
+% if (!$MaxValues or !$Values or $Values->Count < $MaxValues) {
+<input type="file" name="<%$NamePrefix%><%$CustomField->Id%>-Upload" />
+% }
+<%ARGS>
+$Object => undef
+$CustomField => undef
+$NamePrefix => undef
+$Default => undef
+$Values => undef
+$MaxValues => undef
+</%ARGS>
diff --git a/rt/html/Elements/EditCustomFieldSelect b/rt/html/Elements/EditCustomFieldSelect
new file mode 100644
index 000000000..815e977a0
--- /dev/null
+++ b/rt/html/Elements/EditCustomFieldSelect
@@ -0,0 +1,128 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# Build up the set of cascading select boxes as "guides"
+%# each one limits the options of the final one a bit
+%# (perhaps by tweaking the .display style?)
+% my $selected = 0;
+% my @category;
+% my $id = $NamePrefix . $CustomField->Id;
+% my $out = $m->scomp('SELF:options', %ARGS, SelectedRef => \$selected, CategoryRef => \@category);
+% if (@category) {
+<script type="text/javascript" src="<%$RT::WebPath%>/NoAuth/js/cascaded.js"></script>
+%# XXX - Hide this select from w3m?
+ <select onchange="filter_cascade('<% $id %>-Values', this.value)" name="<%$id%>-Category">
+ <option value="" <% !$selected && 'SELECTED' %>><&|/l&>-</&></option>
+% foreach my $cat (@category) {
+% my ($depth, $name) = @$cat;
+ <option value="<% $name %>"><% '&nbsp;' x $depth |n %><%$name%></option>
+% }
+ </select><br />
+% }
+ <select name="<%$id%>-Values" id="<%$id%>-Values"
+% if ($Multiple or !@category) {
+ size="<%$Rows%>"
+% }
+ <% $Multiple && 'MULTIPLE' %>>
+ <option value="" <% !$selected && 'SELECTED' %>><&|/l&>(no value)</&></option>
+% $m->out($out);
+ </select>
+<%ARGS>
+$Object => undef
+$CustomField => undef
+$NamePrefix => undef
+$Default => undef
+$Values => undef
+$Multiple => 0
+$Rows => undef
+</%ARGS>
+
+<%method options>
+% my $selected;
+% my $CFVs = $CustomField->Values;
+% my @levels;
+% while ($CFVs and my $value = $CFVs->Next ) {
+% my $category = $value->Category;
+% if (1) { # length $category) {
+% my $level = (split(/:/, $category || ''))[0];
+% while (@levels) {
+% if ($levels[-1] eq $level) {
+% undef $level;
+% last;
+% } elsif (index($level, $levels[-1]) != 0) {
+ </optgroup>
+% pop @levels;
+% } else {
+% last;
+% }
+% }
+% if ($level) {
+% push @$CategoryRef, [0+@levels, $level];
+ <optgroup style="padding-left: <% @levels/2 %>em" label="<%$category%>">
+% push @levels, $level;
+% }
+% }
+ <option value="<%$value->Name%>"
+% if ($Values) {
+ <% ($Values->HasEntry($value->Name)||'') && ($$SelectedRef = 1) && 'SELECTED' %>
+% } elsif ($Default) {
+ <% (ref $Default ? (grep {$_ eq $value->Name} @{$Default}) : ($Default eq $value->Name))
+ && ($$SelectedRef = 1) && 'SELECTED' %>
+% }
+ ><% $value->Name%></option>
+% }
+% for (@levels) {
+ </optgroup>
+% }
+<%args>
+$CustomField => undef
+$Default => undef
+$Values => undef
+$SelectedRef => undef
+$CategoryRef => undef
+</%args>
+</%method>
diff --git a/rt/html/Elements/EditCustomFieldText b/rt/html/Elements/EditCustomFieldText
new file mode 100644
index 000000000..b7569b003
--- /dev/null
+++ b/rt/html/Elements/EditCustomFieldText
@@ -0,0 +1,67 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% while ($Values and my $value = $Values->Next ) {
+<textarea cols="<%$Cols%>" rows="<%$Rows%>" name="<%$NamePrefix%><%$CustomField->Id%>-Values"><% $value->Content %></textarea><br />
+% }
+% if (!$MaxValues or !$Values or $Values->Count < $MaxValues) {
+<textarea cols="<%$Cols%>" rows="<%$Rows%>" name="<%$NamePrefix%><%$CustomField->Id%>-Values"><% $Default %></textarea>
+% }
+<%INIT>
+# XXX - MultiValue textarea is for now outlawed.
+$MaxValues = 1;
+</%INIT>
+<%ARGS>
+$Object => undef
+$CustomField => undef
+$NamePrefix => undef
+$Default => undef
+$Values => undef
+$MaxValues => undef
+$Cols
+$Rows
+</%ARGS>
diff --git a/rt/html/Elements/EditCustomFieldWikitext b/rt/html/Elements/EditCustomFieldWikitext
new file mode 100644
index 000000000..b7569b003
--- /dev/null
+++ b/rt/html/Elements/EditCustomFieldWikitext
@@ -0,0 +1,67 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% while ($Values and my $value = $Values->Next ) {
+<textarea cols="<%$Cols%>" rows="<%$Rows%>" name="<%$NamePrefix%><%$CustomField->Id%>-Values"><% $value->Content %></textarea><br />
+% }
+% if (!$MaxValues or !$Values or $Values->Count < $MaxValues) {
+<textarea cols="<%$Cols%>" rows="<%$Rows%>" name="<%$NamePrefix%><%$CustomField->Id%>-Values"><% $Default %></textarea>
+% }
+<%INIT>
+# XXX - MultiValue textarea is for now outlawed.
+$MaxValues = 1;
+</%INIT>
+<%ARGS>
+$Object => undef
+$CustomField => undef
+$NamePrefix => undef
+$Default => undef
+$Values => undef
+$MaxValues => undef
+$Cols
+$Rows
+</%ARGS>
diff --git a/rt/html/Elements/EditCustomers b/rt/html/Elements/EditCustomers
new file mode 100644
index 000000000..68efb5f40
--- /dev/null
+++ b/rt/html/Elements/EditCustomers
@@ -0,0 +1,63 @@
+%# Copyright (c) 2004 Ivan Kohler <ivan-rt@420.am>
+%# Copyright (c) 2008 Freeside Internet Services, Inc.
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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.
+<TABLE width=100%>
+ <TR>
+ <TD VALIGN=TOP WIDTH=50%>
+ <h3><&|/l&>Current Customers</&></h3>
+
+<table>
+ <tr>
+ <td><i><&|/l&>(Check box to disassociate)</&></i></td>
+ </tr>
+ <tr>
+ <td class="value">
+% foreach my $link ( @{ $Object->Customers->ItemsArrayRef } ) {
+
+ <INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>">
+%# <& ShowLink, URI => $link->TargetURI &><br>
+ <A HREF="<% $link->TargetURI->Resolver->HREF %>"><% $link->TargetURI->Resolver->AsStringLong |n %></A>
+ <BR>
+% }
+ </td>
+ </tr>
+</table>
+
+</TD>
+
+<TD VALIGN=TOP>
+<h3><&|/l&>New Customer Links</&></h3>
+<&|/l&>Find customer</&><BR>
+<input name="CustomerString">
+<input type=submit name="OnlySearchForCustomers" value="<&|/l&>Go!</&>">
+<br><i>cust #, name, company or phone</i>
+<BR>
+%#<BR>
+%#<&|/l&>Find service</&><BR>
+%#<input name="ServiceString">
+%#<input type=submit name="OnlySearchForServices" value="<&|/l&>Go!</&>">
+%#<br><i>username, username@domain, domain, or IP address</i>
+%#<BR>
+
+<& AddCustomers, Object => $Object,
+ CustomerString => $CustomerString,
+ ServiceString => $ServiceString, &>
+
+</TD>
+</TR>
+</TABLE>
+
+<%ARGS>
+$CustomerString => undef
+$ServiceString => undef
+$Object => undef
+</%ARGS>
diff --git a/rt/html/Elements/EditLinks b/rt/html/Elements/EditLinks
new file mode 100755
index 000000000..7670ffa24
--- /dev/null
+++ b/rt/html/Elements/EditLinks
@@ -0,0 +1,177 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table width="100%">
+ <tr>
+ <td valign="top" width="50%">
+ <h3><&|/l&>Current Links</&></h3>
+
+<table>
+ <tr>
+ <td></td>
+ <td><i><&|/l&>(Check box to delete)</&></i></td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Depends on</&>:</td>
+ <td class="value">
+% while (my $link = $Object->DependsOn->Next) {
+ <input type="checkbox" class="checkbox" name="DeleteLink--<%$link->Type%>-<%$link->Target%>" value="1" />
+ <& ShowLink, URI => $link->TargetURI &><br />
+% }
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Depended on by</&>:</td>
+ <td class="value">
+% while (my $link = $Object->DependedOnBy->Next) {
+ <input type="checkbox" class="checkbox" name="DeleteLink-<%$link->Base%>-<%$link->Type%>-" value="1" />
+ <& ShowLink, URI => $link->BaseURI &><br />
+% }
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Parents</&>:</td>
+ <td class="value">
+% while (my $link = $Object->MemberOf->Next) {
+ <input type="checkbox" class="checkbox" name="DeleteLink--<%$link->Type%>-<%$link->Target%>" value="1" />
+ <& ShowLink, URI => $link->TargetURI &><br />
+% }
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Children</&>:</td>
+ <td class="value">
+% while (my $link = $Object->Members->Next) {
+ <input type="checkbox" class="checkbox" name="DeleteLink-<%$link->Base%>-<%$link->Type%>-" value="1" />
+ <& ShowLink, URI => $link->BaseURI &><br />
+% }
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Refers to</&>:</td>
+ <td class="value">
+% while (my $link = $Object->RefersTo->Next) {
+ <input type="checkbox" class="checkbox" name="DeleteLink--<%$link->Type%>-<%$link->Target%>" value="1" />
+ <& ShowLink, URI => $link->TargetURI &><br />
+%}
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Referred to by</&>:</td>
+ <td class="value">
+% while (my $link = $Object->ReferredToBy->Next) {
+% # Skip reminders
+% next if (UNIVERSAL::isa($link->BaseObj, 'RT::Ticket') && $link->BaseObj->Type eq 'reminder');
+ <input type="checkbox" class="checkbox" name="DeleteLink-<%$link->Base%>-<%$link->Type%>-" value="1" />
+ <& ShowLink, URI => $link->BaseURI &><br />
+% }
+ </td>
+ </tr>
+</table>
+
+</td>
+<td valign="top">
+<h3><&|/l&>New Links</&></h3>
+% if (ref($Object) eq 'RT::Ticket') {
+<i><&|/l&>Enter tickets or URIs to link tickets to. Separate multiple entries with spaces.</&>
+<& /Elements/Callback, _CallbackName => 'ExtraLinkInstructions' &>
+</i><br />
+% } elsif (ref($Object) eq 'RT::Queue') {
+<i><&|/l&>Enter queues or URIs to link queues to. Separate multiple entries with spaces.</&>
+</i><br />
+% } else {
+<i><&|/l&>Enter objects or URIs to link objects to. Separate multiple entries with spaces.</&></i><br />
+% }
+<table>
+% if ($Merge) {
+ <tr>
+ <td class="label"><&|/l&>Merge into</&>:</td>
+ <td class="entry"><input name="<%$id%>-MergeInto" /> <i><&|/l&>(only one ticket)</&></i></td>
+ </tr>
+% }
+ <tr>
+ <td class="label"><&|/l&>Depends on</&>:</td>
+ <td class="entry"><input name="<%$id%>-DependsOn" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Depended on by</&>:</td>
+ <td class="entry"><input name="DependsOn-<%$id%>" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Parents</&>:</td>
+ <td class="entry"><input name="<%$id%>-MemberOf" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Children</&>:</td>
+ <td class="entry"> <input name="MemberOf-<%$id%>" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Refers to</&>:</td>
+ <td class="entry"><input name="<%$id%>-RefersTo" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Referred to by</&>:</td>
+ <td class="entry"> <input name="RefersTo-<%$id%>" /></td>
+ </tr>
+</table>
+</td>
+</tr>
+</table>
+
+<%INIT>
+my $id;
+if ($Object && $Object->Id) {
+ $id = $Object->Id;
+} else {
+ $id = 'new';
+}
+</%INIT>
+
+<%ARGS>
+$Object => undef
+$Merge => 0
+</%ARGS>
diff --git a/rt/html/Elements/EmailInput b/rt/html/Elements/EmailInput
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/rt/html/Elements/EmailInput
diff --git a/rt/html/Elements/Error b/rt/html/Elements/Error
new file mode 100644
index 000000000..369327406
--- /dev/null
+++ b/rt/html/Elements/Error
@@ -0,0 +1,86 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Callback, %ARGS, error => $error &>
+<& /Elements/Header, Code => $Code, Why => $Why, Title => $Title &>
+<& /Elements/Tabs, Title => $Title &>
+<div class="error">
+<%$Why%>
+<br />
+<%$Details%>
+</div>
+
+<%cleanup>
+$m->comp('/Elements/Footer');
+$m->abort();
+</%cleanup>
+
+<%args>
+$Code => undef
+$Details =>''
+$Title => loc("RT Error")
+$Why => loc("the calling component did not specify why")
+</%args>
+
+<%INIT>
+my $error = "WebRT: $Why ($Details)";
+
+# TODO: Log::Dispatch isn't UTF-8 safe. Autrijus needs to talk to dave rolsky about getting this fixed
+if ($] >= 5.007001) {
+ require Encode;
+ Encode::_utf8_off($error);
+}
+
+$RT::Logger->error($error);
+
+if ( defined ($session{'SessionType'}) && $session{'SessionType'} eq 'REST' ) {
+ $r->content_type('text/plain');
+ $m->out( "Error: " . $Why . "\n" );
+ $m->out( $Details . "\n" );
+ $m->abort();
+}
+</%INIT>
diff --git a/rt/html/Elements/Footer b/rt/html/Elements/Footer
new file mode 100644
index 000000000..0cb528f19
--- /dev/null
+++ b/rt/html/Elements/Footer
@@ -0,0 +1,94 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# End of div#body from /Elements/PageLayout
+</div>
+</td>
+</tr>
+<tr>
+<td>
+<& /Elements/Callback, %ARGS &>
+<div id="footer">
+ <p id="time">
+ <span><&|/l&>Time to display</&>: <%Time::HiRes::tv_interval( $m->{'rt_base_time'} )%></span>
+ </p>
+
+<!--
+ <p id="bpscredits">
+ <span>
+<&|/l, '&#187;&#124;&#171;', $RT::VERSION, '2006', '<a href="http://www.bestpractical.com?rt='.$RT::VERSION.'">Best Practical Solutions, LLC</a>', &>[_1] RT [_2] Copyright 1996-[_3] [_4].</&>
+</span>
+</p>
+% if (!$Menu) {
+ <p id="legal">
+<&|/l&>Distributed under version 2 <a href="http://www.gnu.org/copyleft/gpl.html"> of the GNU GPL.</a></&><br />
+<&|/l, '<a href="mailto:sales@bestpractical.com">sales@bestpractical.com</a>' &>To inquire about support, training, custom development or licensing, please contact [_1].</&><br />
+ </p>
+% }
+
+</div>
+-->
+% if ($Debug >= 2 ) {
+% require Data::Dumper;
+% my $d = Data::Dumper->new([\%ARGS], [qw(%ARGS)]);
+<pre>
+<%$d->Dump() %>
+</pre>
+% }
+
+</TD>
+</TR>
+</TABLE>
+
+ </body>
+</html>
+% $m->abort();
+
+<%ARGS>
+$Debug => 0
+$Menu => 1
+</%ARGS>
diff --git a/rt/html/Elements/FreesideInvoiceSearch b/rt/html/Elements/FreesideInvoiceSearch
new file mode 100644
index 000000000..3842b2ff9
--- /dev/null
+++ b/rt/html/Elements/FreesideInvoiceSearch
@@ -0,0 +1,20 @@
+% if ( $FS::CurrentUser::CurrentUser->access_right('View invoices') ) {
+
+ <form action="<% $RT::URI::freeside::URL %>/search/cust_bill.html" STYLE="margin:0">
+ <SCRIPT TYPE="text/javascript">
+ function clearhint_search_invoice (what) {
+ if ( what.value == '(inv #)' )
+ what.value = '';
+ }
+ </SCRIPT>
+ <input name="invnum" accesskey="0" VALUE="(inv #)" SIZE="4" onFocus="clearhint_search_invoice(this);" onClick="clearhint_search_invoice(this);" STYLE="text-align:right; margin-bottom:1px; font-family: Arial, Verdana, Helvetica, sans-serif;">
+
+% if ( $FS::CurrentUser::CurrentUser->access_right('List invoices') ) {
+ <A HREF="<% $RT::URI::freeside::URL %>search/report_cust_bill.html" STYLE="color: #ffffff; font-size: 70%; font-weight:normal">Advanced</A>
+% }
+ <BR>
+
+ <input type="submit" value="<&|/l&>Search invoices</&>" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%">
+ </form>
+
+% }
diff --git a/rt/html/Elements/FreesideNewCust b/rt/html/Elements/FreesideNewCust
new file mode 100644
index 000000000..f60e99559
--- /dev/null
+++ b/rt/html/Elements/FreesideNewCust
@@ -0,0 +1,3 @@
+<form action="<% $RT::URI::freeside::URL %>/edit/cust_main.cgi" STYLE="margin:0">
+<INPUT TYPE="submit" VALUE="<&|/l&>New customer</&>" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="vertical-align:bottom; font-size:100%">&nbsp;
+</FORM>
diff --git a/rt/html/Elements/FreesideSearch b/rt/html/Elements/FreesideSearch
new file mode 100644
index 000000000..8e609bb4b
--- /dev/null
+++ b/rt/html/Elements/FreesideSearch
@@ -0,0 +1,13 @@
+% if ( $FS::CurrentUser::CurrentUser->access_right('List customers') ) {
+<form action="<% $RT::URI::freeside::URL %>/search/cust_main.cgi" STYLE="margin:0">
+ <SCRIPT TYPE="text/javascript">
+ function clearhint_search_cust (what) {
+ if ( what.value == '(cust #, name, company or phone)' )
+ what.value = '';
+ }
+ </SCRIPT>
+<input name="search_cust" accesskey="0" VALUE="(cust #, name, company or phone)" SIZE="28" onFocus="clearhint_search_cust(this);" onClick="clearhint_search_cust(this);" STYLE="text-align:right; font-family: Arial, Verdana, Helvetica, sans-serif;"><BR>
+<A HREF="<% $RT::URI::freeside::URL %>/search/report_cust_main.html" STYLE="color: #ffffff; font-size: 70%; font-weight:normal">Advanced</A>
+<input type="submit" value="<&|/l&>Search customers</&>" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%">
+</form>
+% }
diff --git a/rt/html/Elements/FreesideSvcSearch b/rt/html/Elements/FreesideSvcSearch
new file mode 100644
index 000000000..4a5942421
--- /dev/null
+++ b/rt/html/Elements/FreesideSvcSearch
@@ -0,0 +1,11 @@
+<form action="<% $RT::URI::freeside::URL %>/search/cust_svc.html" STYLE="margin:0">
+ <SCRIPT TYPE="text/javascript">
+ function clearhint_search_svc (what) {
+ if ( what.value == '(user, user@domain or domain)' )
+ what.value = '';
+ }
+ </SCRIPT>
+<input name="search_svc" accesskey="0" VALUE="(user, user@domain or domain)" SIZE="26" onFocus="clearhint_search_svc(this);" onClick="clearhint_search_svc(this);" STYLE="text-align:right; font-family: Arial, Verdana, Helvetica, sans-serif;"><BR>
+ <A NOTYET="<% $RT::URI::freeside::URL %>search/svc_Smarter.html" STYLE="color: #000000; font-size: 70%; font-weight:normal">Advanced</A>
+<input type="submit" value="<&|/l&>Search services</&>" CLASS="fsblackbutton" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%">
+</form>
diff --git a/rt/html/Elements/GotoTicket b/rt/html/Elements/GotoTicket
new file mode 100644
index 000000000..ad6ad1b15
--- /dev/null
+++ b/rt/html/Elements/GotoTicket
@@ -0,0 +1,48 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<form action="<%$RT::WebPath%>/Ticket/Display.html"><input type="submit" class="button" value="<&|/l&>Goto ticket</&>" />&nbsp;<input size="5" name="id" accesskey="0" /></form>
diff --git a/rt/html/Elements/Header b/rt/html/Elements/Header
new file mode 100644
index 000000000..bf6fa46fa
--- /dev/null
+++ b/rt/html/Elements/Header
@@ -0,0 +1,172 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
+
+<title><%$Title%></title>
+
+% if ($Refresh && $Refresh > 0) {
+ <meta http-equiv="refresh" content="<%$Refresh%>" />
+% }
+
+<link rel="shortcut icon" href="<%$RT::WebImagesURL%>/favicon.png" type="image/png" />
+<link rel="stylesheet" href="<%$RT::WebPath%>/NoAuth/css/<% $RT::WebDefaultStylesheet %>/main-squished.css" type="text/css" media="all" />
+<link rel="stylesheet" href="<%$RT::WebPath%>/NoAuth/css/print.css" type="text/css" media="print" />
+
+% if ( $RSSAutoDiscovery ) {
+ <link rel="alternate" href="<%$RSSAutoDiscovery%>" type="application/rss+xml" title="RSS RT Search" />
+% }
+
+<script type="text/javascript" src="<%$RT::WebPath%>/NoAuth/js/util.js"></script>
+<script type="text/javascript" src="<%$RT::WebPath%>/NoAuth/js/ahah.js"></script>
+<script type="text/javascript" src="<%$RT::WebPath%>/NoAuth/js/titlebox-state.js"></script>
+<script type="text/javascript"><!--
+ onLoadHook("loadTitleBoxStates()");
+% if ( $Focus ) {
+ onLoadHook("focusElementById('<% $Focus %>')");
+% }
+% if ( $onload ) {
+ onLoadHook("<% $onload |n %>");
+% }
+--></script>
+
+<& /Elements/Callback, _CallbackName => 'Head', %ARGS &>
+
+</head>
+ <body NOTBACKGROUND="<% $RT::URI::freeside::URL %>/images/background-cheat.png"
+ STYLE="margin-top:0; margin-bottom:0; margin-left:0; margin-right:0"
+ <% $id && qq[ id="comp-$id"] |n %>
+ >
+
+% if ($ShowBar) {
+
+<table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" STYLE="padding-left:0; padding-right:4">
+ <tr>
+ <td colspan=2 rowspan=2><img border=0 alt="freeside" src="<%$RT::WebImagesURL%>/small-logo.png" width="92" height="62"></td>
+ <td align="left" rowspan=2><font size=6><% &RT::URI::freeside::FreesideGetConfig('company_name') || 'ExampleCo' %></font></td>
+ <td align="right" valign="top">
+
+<div id="quickbar">
+ <div id="quick-personal">
+ <span class="hide"><a href="#skipnav"><&|/l&>Skip Menu</&></a> | </span>
+% if ($session{'CurrentUser'}->Name) {
+ <&|/l, "<span>".$session{'CurrentUser'}->Name."</span>" &>Logged in as [_1]</&>
+% if ($session{'CurrentUser'}->HasRight( Right => 'ModifySelf', Object => $RT::System )) {
+ | <a href="<%$RT::WebPath%><%$Prefs%>"><&|/l&>Preferences</&></a>
+% }
+% } else {
+ <&|/l&>Not logged in.</&>
+% }
+ <& /Elements/Callback, %ARGS &>
+% unless (!$session{'CurrentUser'}->Name
+% or ($RT::WebExternalAuth and !$RT::WebFallbackToInternalAuth)) {
+ | <a href="<%$RT::WebPath%>/NoAuth/Logout.html<%$URL ? "?URL=".$URL : ''%>"><&|/l&>Logout</&></a>
+% }
+ </div>
+% }
+
+ </td>
+
+ </tr>
+ <tr>
+
+ <td align=right valign=bottom>
+ <table>
+ <tr>
+ <td align=right>
+ <FONT SIZE="-3">
+ <A HREF="http://www.sisd.com/freeside">Freeside</A>&nbsp;v<% &RT::URI::freeside::FreesideVersion() %><BR>
+ <A HREF="<% FS::Conf->new->config('support-key') ? "http://www.sisd.com/mediawiki/index.php/Supported:Documentation" : "http://www.sisd.com/mediawiki/index.php/Freeside:1.9:Documentation" %>">Documentation</A><BR>
+ </FONT>
+ </td>
+ <td bgcolor=#000000></td>
+ <td align=left>
+ <FONT SIZE="-3">
+ <A HREF="http://www.bestpractical.com/rt">RT</A>&nbsp;v<% $RT::VERSION %><BR>
+ <A HREF="http://wiki.bestpractical.com/">Documentation</A><BR>
+ </FONT>
+ </td>
+
+ </tr>
+ </table>
+ </td>
+
+ </tr>
+</table>
+
+<%INIT>
+$r->headers_out->{'Pragma'} = 'no-cache';
+$r->headers_out->{'Cache-control'} = 'no-cache';
+
+require RT::URI::freeside;
+
+my $id = $m->request_comp->path;
+$id =~ s|^/||g;
+$id =~ s|/|-|g;
+$id =~ s|\.html$||g;
+$id =~ s|index$||g
+ if $id ne 'index';
+$id =~ s|-$||g;
+</%INIT>
+
+<%ARGS>
+$Prefs => '/User/Prefs.html'
+#$Focus => 'focus'
+$Focus => ''
+$Title => 'RT'
+$Code => undef
+$Refresh => 0
+$Why => undef
+$ShowBar => 1
+$URL => undef
+$RSSAutoDiscovery => undef
+$onload => undef
+</%ARGS>
diff --git a/rt/html/Elements/ListActions b/rt/html/Elements/ListActions
new file mode 100644
index 000000000..24f923a8a
--- /dev/null
+++ b/rt/html/Elements/ListActions
@@ -0,0 +1,65 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<&| /Widgets/TitleBox, title => loc('Results') &>
+ <ul class="action-results">
+% foreach my $action (@actions) {
+% next unless $action;
+% my $skip = 0;
+% $m->comp('/Elements/Callback', _CallbackName => 'ModifyRow', row => \$action, skip => \$skip, %ARGS);
+% next if $skip;
+ <li><%$action%></li>
+% }
+ </ul>
+</&>
+<%init>
+@actions = grep $_, @actions;
+return unless @actions;
+</%init>
+<%ARGS>
+@actions => undef
+</%ARGS>
diff --git a/rt/html/Elements/Login b/rt/html/Elements/Login
new file mode 100644
index 000000000..cd39b87d8
--- /dev/null
+++ b/rt/html/Elements/Login
@@ -0,0 +1,138 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%INIT>
+if ($m->request_comp->path =~ '^/REST/\d+\.\d+/') {
+ $r->content_type("text/plain");
+ $m->error_format("text");
+ $m->out("RT/$RT::VERSION 401 Credentials required\n");
+ $m->out("\n$Error\n") if $Error;
+ $m->abort;
+}
+
+my $req_uri;
+
+if (UNIVERSAL::can($r, 'uri') and $r->uri =~ m{.*/(.*)}) {
+ $req_uri = $1;
+}
+
+my $form_action = defined $goto ? $goto
+ : defined $req_uri ? $req_uri
+ : $RT::WebPath
+ ;
+</%INIT>
+
+<& /Elements/Callback, %ARGS, _CallbackName => 'Header' &>
+<& /Elements/Header, Title => loc('Login'), Focus => 'user' &>
+
+%# End of div#quickbar from /Elements/Header
+</div>
+
+<div id="body" class="login-body">
+
+% if ($Error) {
+<&| "/Widgets/TitleBox", title => loc('Error'), hideable => 0 &>
+<% $Error %>
+</&>
+% }
+
+<& /Elements/Callback, %ARGS, _CallbackName => 'BeforeForm' &>
+
+<div id="login-box">
+<&| /Widgets/TitleBox, title => loc('Login'), titleright => $RT::VERSION, hideable => 0 &>
+
+% unless ($RT::WebExternalAuth and !$RT::WebFallbackToInternalAuth) {
+<form id="login" name="login" method="post" action="<% $form_action %>">
+
+<div class="input-row">
+ <span class="label"><&|/l&>Username</&>:</span>
+ <span class="input"><input name="user" value="<%$user%>" id="user" /></span>
+</div>
+
+<div class="input-row">
+ <span class="label"><&|/l&>Password</&>:</span>
+ <span class="input"><input type="password" name="pass" /></span>
+</div>
+
+<div class="button-row">
+ <span class="input"><input type="submit" class="button" value="<&|/l&>Login</&>" /></span>
+</div>
+
+%# Give callbacks a chance to add more control elements
+<& /Elements/Callback, %ARGS &>
+
+% # From mason 1.0.1 forward, this doesn't work. in fact, it breaks things.
+% # But on Mason 1.15 it's fixed again, so we still use it.
+% # The code below iterates through everything in the passed in arguments
+% # Preserving all the old parameters
+% # This would be easier, except mason is 'smart' and calls multiple values
+% # arrays rather than multiple hash keys
+% my $key; my $val;
+% foreach $key (keys %ARGS) {
+% if (($key ne 'user') and ($key ne 'pass')) {
+% if (ref($ARGS{$key}) =~ /ARRAY/) {
+% foreach $val (@{$ARGS{$key}}) {
+<input type="hidden" class="hidden" name="<%$key %>" value="<% $val %>" />
+% }
+% }
+% else {
+<input type="hidden" class="hidden" name="<% $key %>" value="<% $ARGS{$key} %>" />
+% }
+% }
+% }
+</form>
+% }
+</&>
+</div><!-- #login-box -->
+<& /Elements/Callback, %ARGS, _CallbackName => 'AfterForm' &>
+<& /Elements/Footer, Menu => 0 &>
+<%ARGS>
+$user => ""
+$pass => undef
+$goto => undef
+$Error => undef
+</%ARGS>
diff --git a/rt/html/Elements/Logo b/rt/html/Elements/Logo
new file mode 100644
index 000000000..157f7bece
--- /dev/null
+++ b/rt/html/Elements/Logo
@@ -0,0 +1,56 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+ <div id="logo">
+ <a href="http://bestpractical.com"><img src="<%$RT::WebImagesURL%>/bplogo.gif" alt="<%loc("Best Practical Solutions, LLC corporate logo")%>" width="177" height="33" /></a>
+% if ($show_name) {
+ <div class="rtname"><% loc("RT for [_1]", $RT::rtname) %></div>
+% }
+ </div>
+<%args>
+ $show_name => 1
+</%args>
diff --git a/rt/html/Elements/Menu b/rt/html/Elements/Menu
new file mode 100644
index 000000000..b5b2bdad5
--- /dev/null
+++ b/rt/html/Elements/Menu
@@ -0,0 +1,134 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<ul<% !$level ? ' id="system-menu"' : ''|n %><% $menu_class ? qq[ class="$menu_class"] : ''|n %>>
+<div<% $menu_class ? qq[ class="$menu_class"] : ''|n %>><div class="wrapper">
+% my $sep = 0;
+% my $postsep = 0;
+% my $accesskey = 1;
+%
+% $count = 0;
+% $class = {};
+%
+% foreach $tab (sort keys %{$toptabs}) {
+% $count++;
+%
+% my $current = $current_toptab || "";
+% my $path = $toptabs->{$tab}->{'path'} || "";
+%
+% $path =~ s#/index.html$##gi;
+% $current =~ s#/index.html$##gi;
+%
+% $sep = $toptabs->{$tab}->{'separator'} ? 1 : 0;
+%
+% my @aclass;
+% push @aclass, 'selected'
+% if $path eq $current;
+%
+% push @aclass, 'odd'
+% if $level % 2;
+%
+% $class->{a} = join ' ', @aclass;
+%
+% my @li;
+% push @li, 'first'
+% if $count == 1;
+%
+% push @li, 'pre-separator'
+% if $sep;
+%
+% push @li, 'post-separator'
+% if $postsep;
+%
+% $class->{li} = join ' ', @li;
+%
+% my $url = ($toptabs->{$tab}->{'path'}||'') =~ /^https?:/i
+% ? $toptabs->{$tab}->{'path'} || ''
+% : $RT::WebPath . "/" . $toptabs->{$tab}->{'path'};
+%
+ <li<% $class->{li} ? qq[ class="$class->{li}"] : ''|n %>>
+ <% $count > 1 && !$postsep && qq[<span class="bullet">&#183; </span>]|n%>
+ <a href="<% $url %>"
+ <% $class->{a} && qq[ class="$class->{a}"] |n%>
+ <% !$level && " accesskey='".$accesskey++."'" |n%>>
+ <% $toptabs->{$tab}->{'title'} || ''%></a>
+%# Second-level items
+% if ($toptabs->{$tab}->{'subtabs'}
+% and keys %{$toptabs->{$tab}->{'subtabs'}})
+% {
+ <& /Elements/Menu, level => $level+1,
+ current_toptab => $toptabs->{$tab}->{'current_subtab'},
+ toptabs => $toptabs->{$tab}->{'subtabs'},
+ last_level => $toptabs->{$tab}->{last_system_menu_level} &>
+% }
+ </li>
+% if ($sep) {
+ <li class="separator">&#183;&#183;&#183;</li>
+% }
+%
+% $postsep = $sep;
+% }
+</div></div>
+</ul>
+
+<%INIT>
+my ($tab, $class, $count);
+
+my @ul;
+push @ul, 'last-menu-level'
+ if $last_level;
+push @ul, 'odd'
+ if $level % 2;
+my $menu_class = join ' ', @ul;
+</%INIT>
+
+<%ARGS>
+$current_toptab => ""
+$toptabs => undef
+$level => 0
+$last_level => 0
+</%ARGS>
diff --git a/rt/html/Elements/MessageBox b/rt/html/Elements/MessageBox
new file mode 100644
index 000000000..0149e1b30
--- /dev/null
+++ b/rt/html/Elements/MessageBox
@@ -0,0 +1,74 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<textarea class="messagebox" cols="<%$Width%>" rows="<%$Height%>" wrap="<%$Wrap%>" name="<%$Name%>"><& /Elements/Callback, %ARGS &><% $Default %><%$message%><%$IncludeSignature ? $signature : ''%></textarea>
+<%INIT>
+
+my $message = '';
+
+if ($QuoteTransaction) {
+ my $transaction=RT::Transaction->new($session{'CurrentUser'});
+ $transaction->Load($QuoteTransaction);
+ $message=$transaction->Content(Quote => 1);
+}
+
+my $signature = '';
+if ($IncludeSignature && $session{'CurrentUser'}->UserObj->Signature) {
+ $signature = "-- \n".$session{'CurrentUser'}->UserObj->Signature;
+}
+
+</%INIT>
+<%ARGS>
+$QuoteTransaction => undef
+$Name => 'Content'
+$Default => ''
+$Width => $RT::MessageBoxWidth || 72
+$Height => $RT::MessageBoxHeight || 15
+$Wrap => $RT::MessageBoxWrap || 'HARD'
+$IncludeSignature => 1
+</%ARGS>
+
diff --git a/rt/html/Elements/MyAdminQueues b/rt/html/Elements/MyAdminQueues
new file mode 100644
index 000000000..7e720ad71
--- /dev/null
+++ b/rt/html/Elements/MyAdminQueues
@@ -0,0 +1,54 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<&|/Widgets/TitleBox, title => loc("Queues I administer"), bodyclass => "" &>
+<& /Elements/QueueSummary,
+ cache => 'my_admin_queues',
+ queue_filter => sub { $_->CurrentUserHasRight('AdminQueue') },
+ conditions => [ {cond => "Status = 'new'", name => loc ('new') },
+ {cond => "Status = 'open'", name => loc ('open') }] &>
+</&>
diff --git a/rt/html/Elements/MyRT b/rt/html/Elements/MyRT
new file mode 100644
index 000000000..3fde555c2
--- /dev/null
+++ b/rt/html/Elements/MyRT
@@ -0,0 +1,100 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table border="0" width="100%">
+<tr valign="top">
+
+<td class="boxcontainer" <% $summary? 'width="70%"': '' |n %>>
+% $show_cb->($_) foreach @$body;
+</td>
+
+% if ( $summary ) {
+<td class="boxcontainer">
+% $show_cb->($_) foreach @$summary;
+</td>
+% }
+
+</tr>
+</table>
+
+<%INIT>
+
+my $user = $session{'CurrentUser'}->UserObj;
+unless (exists $session{'my_rt_portlets'}) {
+ my ($default_portlets) = RT::System->new($session{'CurrentUser'})->Attributes->Named('HomepageSettings');
+ $session{'my_rt_portlets'} = $user->Preferences(
+ HomepageSettings => $default_portlets? $default_portlets->Content: {},
+ );
+}
+
+my ($body, $summary) = @{$session{'my_rt_portlets'}}{qw(body summary)};
+unless( $body && @$body ) {
+ $body = $summary || [];
+ $summary = undef;
+}
+$summary = undef unless $summary && @$summary;
+
+my $Rows = $user->Preferences( 'SummaryRows', ( $RT::DefaultSummaryRows || 10 ) );
+
+my $show_cb = sub {
+ my $entry = shift;
+ my $type = $entry->{type};
+ if ( $type eq 'component' ) {
+ my $name = $entry->{name};
+
+ # security check etc.
+ $m->comp( $name, %{ $entry->{arguments} || {} } );
+ } elsif ( $type eq 'system' ) {
+ $m->comp( '/Elements/ShowSearch', Name => $entry->{name}, Override => { Rows => $Rows } );
+ } elsif ( $type eq 'saved' ) {
+ $m->comp( '/Elements/ShowSearch', SavedSearch => $entry->{name}, Override => { Rows => $Rows } );
+ } else {
+ $RT::Logger->error("unknown portlet type $type");
+ }
+};
+
+</%INIT>
diff --git a/rt/html/Elements/MyReminders b/rt/html/Elements/MyReminders
new file mode 100755
index 000000000..1e962bd61
--- /dev/null
+++ b/rt/html/Elements/MyReminders
@@ -0,0 +1,73 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# DEPRECATED
+<&|/Widgets/TitleBox,
+ title => loc("Reminders") &>
+<table width="100%">
+% my $i =0;
+% while (my $reminder = $reminders->Next) {
+% $i++;
+% if ($reminder->RefersTo->First) {
+% my $ticket= $reminder->RefersTo->First->TargetObj;
+<tr class="<%$i%2 ? 'evenline' : 'oddline'%>"><td><a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$ticket->id%>"><%$reminder->Subject%></a><br />
+<blockquote>
+#<%$ticket->id%>: <%$ticket->Subject%><br />
+<%$reminder->OwnerObj->Name %> <%$reminder->DueObj->Unix >0 ? '&bull; '.$reminder->DueObj->AgeAsString : '' |n %>
+</blockquote>
+</td>
+</tr>
+% }}
+</table>
+</&>
+
+<%init>
+my $reminders = RT::Tickets->new($session{'CurrentUser'});
+$reminders->FromSQL('(Owner = "Nobody" OR Owner = "'.$session{'CurrentUser'}->Name.'")' .
+ ' AND Type = "reminder" AND (Status = "new" OR Status = "open") AND Due > "1970-01-01"');
+$reminders->OrderBy(FIELD => 'Due', ORDER => 'DESC');
+</%init>
diff --git a/rt/html/Elements/MyRequests b/rt/html/Elements/MyRequests
new file mode 100644
index 000000000..fc1e27095
--- /dev/null
+++ b/rt/html/Elements/MyRequests
@@ -0,0 +1,49 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# DEPRECATED
+<& /Elements/ShowSearch, Name => 'My Requests' &>
diff --git a/rt/html/Elements/MySupportQueues b/rt/html/Elements/MySupportQueues
new file mode 100644
index 000000000..f9e18a09a
--- /dev/null
+++ b/rt/html/Elements/MySupportQueues
@@ -0,0 +1,54 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<&|/Widgets/TitleBox, title => loc("Queues I'm an AdminCc for"), bodyclass => "" &>
+<& /Elements/QueueSummary,
+ cache => 'my_support_queues',
+ queue_filter => sub { $_->IsAdminCc($session{'CurrentUser'}->Id) },
+ conditions => [ {cond => "Status = 'new'", name => loc ('new') },
+ {cond => "Status = 'open'", name => loc ('open') }] &>
+</&>
diff --git a/rt/html/Elements/MyTickets b/rt/html/Elements/MyTickets
new file mode 100644
index 000000000..8d657db3d
--- /dev/null
+++ b/rt/html/Elements/MyTickets
@@ -0,0 +1,49 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# DEPRECATED
+<& /Elements/ShowSearch, Name => 'My Tickets' &>
diff --git a/rt/html/Elements/PageLayout b/rt/html/Elements/PageLayout
new file mode 100644
index 000000000..b9fd31f71
--- /dev/null
+++ b/rt/html/Elements/PageLayout
@@ -0,0 +1,256 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+
+<table class="black" border=0 cellspacing=0 cellpadding=0 width="100%">
+<tr>
+ <TD colspan=5 WIDTH="100%" STYLE="padding:0"><IMG BORDER=0 ALT="" SRC="<% $RT::URI::freeside::URL %>/images/black-gradient.png" HEIGHT="13" WIDTH="100%"></TD>
+</tr>
+<tr>
+
+ <div id="topactions">
+% my $notfirst = 0; foreach my $action (sort keys %{$topactions}) {
+ <span class="topaction">
+ <td class="blackright" ALIGN="right" VALIGN="center">
+% $m->out($topactions->{"$action"}->{'html'});
+ </td>
+ </span>
+% }
+ </div>
+
+</tr>
+</table>
+
+%# End of div#quickbar from /Elements/Header
+</div>
+
+<table border=0 cellspacing=0 cellpadding=0 width="100%" height="100%">
+ <TR>
+ <TD STYLE="padding:0" WIDTH="100%"><IMG BORDER=0 ALT="" SRC="<% $RT::URI::freeside::URL %>/images/black-gray-top.png" HEIGHT="13" WIDTH="100%"></TD>
+ </TR>
+ <TR HEIGHT="100%">
+ <TD>
+
+% if ( $show_menu ) {
+<div id="nav">
+<& /Elements/Menu, toptabs => $toptabs, current_toptab => $current_toptab &>
+</div>
+% }
+
+<div id="header">
+ <h1><%$title%></h1>
+
+% my $sep = 0;
+% my $postsep = 0;
+% my $count = 0;
+% my $class = { };
+%
+ <ul id="page-menu"<% (($actions && %$actions) || ($subactions && %$subactions)) && q[ class="actions-present"] | n %>>
+ <div><div><div>
+% if ($page_tabs) {
+% foreach my $tab (sort keys %{$page_tabs}) {
+% next if $tab =~ /^(?:current_toptab|this)$/;
+% $count++;
+%
+% my $current = $page_tabs->{current_toptab} || "";
+% my $path = $page_tabs->{$tab}->{'path'} || "";
+%
+% $path =~ s#/index.html$##gi;
+% $current =~ s#/index.html$##gi;
+%
+% $sep = $toptabs->{$tab}->{'separator'} ? 1 : 0;
+%
+% $class->{a} = $path eq $current ? ' class="selected"' : undef;
+%
+% my @li;
+% push @li, 'first'
+% if $count == 1;
+%
+% push @li, 'pre-separator'
+% if $sep;
+%
+% push @li, 'post-separator'
+% if $postsep;
+%
+% $class->{li} = join ' ', @li;
+%
+%
+ <li<% $class->{li} ? qq[ class="$class->{li}"] : ''|n %>><% $count > 1 && !$postsep && "&#183; "|n%><a href="<%$RT::WebPath%>/<%$page_tabs->{$tab}->{'path'}%>"<%$class->{a}|n%><% $class->{a} ? ' name="focus"' : ''|n %>><% $page_tabs->{$tab}->{'title'} %></a></li>
+%
+% if ($sep) {
+ <li class="separator">&#183;&#183;&#183;</li>
+% }
+% $postsep = $sep;
+% }
+% } else {
+&nbsp;
+% }
+ </div></div></div>
+ </ul>
+
+% if (($actions && %$actions) || ($subactions && %$subactions)) {
+ <ul id="actions-menu">
+ <div><div><div>
+% $sep = 0;
+% $postsep = 0;
+% $count = 0;
+% $class = { };
+%
+% for my $type ($actions, $subactions) {
+%
+% if ($type && %$type) {
+% foreach my $action (sort keys %{$type}) {
+% $count++;
+%
+% $sep = $type->{$action}->{'separator'} ? 1 : 0;
+%
+% my @li;
+% push @li, 'first'
+% if $count == 1;
+%
+% push @li, 'pre-separator'
+% if $sep;
+%
+% push @li, 'post-separator'
+% if $postsep;
+%
+% $class->{li} = join ' ', @li;
+%
+ <li<% $class->{li} ? qq[ class="$class->{li}"] : ''|n %>><% $count > 1 && !$postsep && qq[<span class="bullet">&#183; </span>]|n%>
+% if ($type->{"$action"}->{'html'}) {
+ <% $type->{"$action"}->{'html'} | n %>
+% } else {
+ <a href="<%$RT::WebPath%>/<%$type->{$action}->{'path'}%>"<% $type->{$action}->{class} && ' class="'.$type->{$action}->{class}.'"' |n %><% $type->{$action}->{id} && ' id="'.$type->{$action}->{id}.'"' |n %>><%$type->{$action}->{'title'}%></a>
+% }
+ </li>
+% if ($sep) {
+ <li class="separator">&#183;&#183;&#183;</li>
+% }
+% $postsep = $sep;
+% }
+% }
+% }
+ </div></div></div>
+ </ul>
+% }
+</div>
+
+<div id="body">
+<& /Elements/Callback, _CallbackName => 'BeforeBody', %ARGS &>
+%$m->flush_buffer(); # we've got the page laid out, let's flush the buffer;
+
+<%INIT>
+ foreach my $tab (sort keys %{$toptabs}) {
+ if ($current_toptab && $toptabs->{$tab}->{'path'} eq $current_toptab) {
+ $toptabs->{$tab}->{"subtabs"} = $tabs;
+ $toptabs->{$tab}->{"current_subtab"} = $current_tab;
+ }
+ }
+
+if (! defined($AppName)) {
+ $AppName = loc("RT for [_1]", $RT::rtname);
+}
+
+my ($menu_depth, $almost_last, $page_tabs);
+
+if ($RT::WebDefaultStylesheet ne '3.4-compat') {
+ ($menu_depth, $almost_last) = @{$m->comp('.menu_recurse', data => $toptabs)};
+
+ if (defined $almost_last->{subtabs} and %{$almost_last->{subtabs}}) {
+ $page_tabs = {
+ current_toptab => $almost_last->{current_subtab},
+ %{$almost_last->{subtabs}},
+ };
+
+ delete $almost_last->{subtabs};
+ delete $almost_last->{current_subtab};
+ }
+}
+</%INIT>
+
+%# There's probably a better way to do this that involves three times as
+%# much work and redoing the whole menu/tab system... which would seem a
+%# bit out of scope.
+%#
+%# This function recurses through the menu and returns the second to
+%# last menu, that is, the menu holding the last reference to
+%# and submenu. It also returns the number of menu levels minus
+%# the last submenu.
+<%def .menu_recurse>
+ <%args>
+ $data => { }
+ $pdata => { }
+ $ppdata => { }
+ $level => 0
+ </%args>
+ <%init>
+ for my $key (keys %$data) {
+ return $m->comp('.menu_recurse', data => $data->{$key}->{subtabs},
+ pdata => $data->{$key},
+ ppdata => $pdata,
+ level => $level+1)
+ if ref($data->{$key}) eq 'HASH'
+ and defined $data->{$key}->{subtabs}
+ and %{$data->{$key}->{subtabs}};
+ }
+ $ppdata->{last_system_menu_level}++;
+ return [$level, $pdata];
+ </%init>
+</%def>
+
+<%ARGS>
+$current_toptab => undef
+$current_tab => undef
+$toptabs => undef
+$topactions => undef
+$tabs => undef
+$actions => undef
+$subactions => undef
+$title => $m->callers(-1)->path
+$AppName => undef
+$show_menu => 1
+</%ARGS>
diff --git a/rt/html/Elements/QueryString b/rt/html/Elements/QueryString
new file mode 100644
index 000000000..0176180d2
--- /dev/null
+++ b/rt/html/Elements/QueryString
@@ -0,0 +1,63 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+my @params;
+while ( my ($key, $value) = each %ARGS ){
+ if( UNIVERSAL::isa( $value, 'ARRAY' ) ) {
+ push @params, map $key."=".$m->interp->apply_escapes($_,'u'), @$value;
+ } else {
+ if (ref $value eq "ARRAY") {
+ push @params, $key."=".$m->interp->apply_escapes($_, 'u')
+ for @{$value};
+ } else {
+ push @params, $key."=".$m->interp->apply_escapes($value||"",'u');
+ }
+ }
+}
+return(join('&',@params));
+</%init>
diff --git a/rt/html/Elements/QueueSummary b/rt/html/Elements/QueueSummary
new file mode 100644
index 000000000..133539cc0
--- /dev/null
+++ b/rt/html/Elements/QueueSummary
@@ -0,0 +1,92 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table border="0" cellspacing="0" cellpadding="1" width="100%">
+<tr>
+ <th class="collection-as-table"><&|/l&>Queue</&></th>
+% for my $condition (@$conditions) {
+ <th class="collection-as-table"><% $condition->{name} %></th>
+% }
+</tr>
+% my $i;
+% for my $queue (@queues) {
+% $i++;
+% my $queue_cond = "Queue = '$queue->{Name}' AND ";
+% my $all_q = $queue_cond . "(Status = 'open' OR Status = 'new' OR Status = 'stalled')";
+<tr class="<% $i%2 ? 'oddline' : 'evenline'%>" >
+<td><a href="<% $RT::WebPath%>/Search/Results.html?Query=<% $all_q |u,n %>" title="<% $queue->{Description} %>"><% $queue->{Name} %></a></td>
+% for my $condition (@$conditions) {
+% $Tickets->FromSQL( "Queue = $queue->{id} AND ". $condition->{cond} );
+<td align="right"><a href="<% $RT::WebPath%>/Search/Results.html?Query=<% $queue_cond.$condition->{cond} |u,n %>"><% $Tickets->Count %></a></td>
+% }
+</tr>
+% }
+</table>
+<%INIT>
+my @queues;
+
+if ($cache && exists $session{$cache}) {
+ @queues = @{$session{$cache}};
+}
+else {
+ my $Queues = RT::Queues->new($session{'CurrentUser'});
+ $Queues->UnLimit();
+ @queues = map {
+ { Name => $_->Name, Description => $_->Description,
+ id => $_->Id } }
+ grep $queue_filter->($_), @{$Queues->ItemsArrayRef};
+
+ $session{$cache} = \@queues if $cache;
+}
+
+my $Tickets = RT::Tickets->new($session{'CurrentUser'});
+</%INIT>
+<%ARGS>
+$cache => undef
+$queue_filter => undef
+$conditions => ()
+</%ARGS>
diff --git a/rt/html/Elements/QuickCreate b/rt/html/Elements/QuickCreate
new file mode 100644
index 000000000..75b3a4598
--- /dev/null
+++ b/rt/html/Elements/QuickCreate
@@ -0,0 +1,71 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<div class="quick-create">
+<&| /Widgets/TitleBox, title => loc('Quick ticket creation') &>
+<form method="post" action="<%$RT::WebPath%>/<% $RT::QuickCreateLong ? 'Ticket/Create.html' : 'index.html' %>">
+<input type="hidden" class="hidden" name="QuickCreate" value="1" />
+<table>
+<tr><td>
+<&|/l&>Subject</&>:<br /><input size="30" name="Subject" />
+</td><td>
+<&|/l&>Queue</&>:<br /><& /Elements/SelectNewTicketQueue, Name => 'Queue', ShowNullOption => 0 &>
+</td><td>
+<&|/l&>Owner</&>:<br />
+<select type="select" name="Owner">
+<option value="<%$session{'CurrentUser'}->id%>" selected><%$session{'CurrentUser'}->Name %></option>
+<option value="<%$RT::Nobody->id%>"><%loc('Nobody')%></option>
+</select>
+</td>
+</tr>
+%#<tr><td colspan="3"><textarea cols="50" rows="3"></textarea></td></tr>
+</table>
+<div align="right"><input type="submit" class="button" value="<%loc('Create')%>" /></div>
+</form>
+</&>
+</div>
+
diff --git a/rt/html/Elements/Quicksearch b/rt/html/Elements/Quicksearch
new file mode 100644
index 000000000..4acbc204d
--- /dev/null
+++ b/rt/html/Elements/Quicksearch
@@ -0,0 +1,61 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<div class="ticket-overview">
+<&|/Widgets/TitleBox, title => loc("Quick search"), bodyclass => "",
+ titleright => loc("Edit"), titleright_href => $RT::WebPath.'/Prefs/Quicksearch.html' &>
+<& /Elements/QueueSummary,
+ cache => 'quick_search_queues',
+ queue_filter => sub { $_->CurrentUserHasRight('ShowTicket') && !exists $unwanted->{$_->Name} },
+ conditions => [ {cond => "Status = 'new'", name => loc ('new') },
+ {cond => "Status = 'open'", name => loc ('open') },
+ {cond => "Status = 'stalled'", name => loc ('stalled') }] &>
+</&>
+</div>
+<%INIT>
+my $unwanted = $session{'CurrentUser'}->UserObj->Preferences('QuickSearch', {});
+</%INIT>
diff --git a/rt/html/Elements/RT__Ticket/ColumnMap b/rt/html/Elements/RT__Ticket/ColumnMap
new file mode 100644
index 000000000..21dc2a753
--- /dev/null
+++ b/rt/html/Elements/RT__Ticket/ColumnMap
@@ -0,0 +1,314 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+$Name => undef
+$Attr => undef
+</%ARGS>
+
+
+<%ONCE>
+our ( $COLUMN_MAP );
+
+my $ColumnMap = sub {
+ my $name = shift;
+ my $attr = shift;
+
+ # First deal with the simple things from the map
+ if ( $COLUMN_MAP->{$name} ) {
+ return ( $COLUMN_MAP->{$name}->{$attr} );
+ }
+
+ # now, let's deal with harder things, like Custom Fields
+
+ elsif ( $name =~ /^(?:CF|CustomField)\.\{(.+)\}$/ ) {
+ my $field = $1;
+
+ if ( $attr eq 'attribute' ) {
+ return (undef);
+ }
+ elsif ( $attr eq 'title' ) {
+ return ( $field );
+ }
+ elsif ( $attr eq 'value' ) {
+ # Display custom field contents, separated by newlines.
+ # For Image custom fields we also show a thumbnail here.
+ return sub {
+ my $values = $_[0]->CustomFieldValues($field);
+ my @values = map {
+ (
+ ($_->CustomFieldObj->Type eq 'Image')
+ ? \($m->scomp( '/Elements/ShowCustomFieldImage', Object => $_ ))
+ : $_->Content
+ ),
+ \'<br />',
+ } @{ $values->ItemsArrayRef };
+ pop @values; # Remove that last <br />
+ return @values;
+ };
+ }
+ }
+};
+
+my $LinkCallback = sub {
+ my $method = shift;
+
+ my $mode = $RT::Ticket::LINKTYPEMAP{$method}{Mode};
+ my $type = $RT::Ticket::LINKTYPEMAP{$method}{Type};
+ my $other_mode = ($mode eq "Target" ? "Base" : "Target");
+ my $mode_uri = $mode.'URI';
+ my $local_type = 'Local'.$mode;
+
+ return sub {
+ map {
+ \'<a href="',
+ $_->$mode_uri->Resolver->HREF,
+ \'">',
+ ( $_->$mode_uri->IsLocal ? $_->$local_type : $_->$mode ),
+ \'</a><br />',
+ } @{ $_[0]->Links($other_mode,$type)->ItemsArrayRef }
+ }
+};
+
+$COLUMN_MAP = {
+ QueueName => {
+ attribute => 'Queue',
+ title => 'Queue',
+ value => sub { return $_[0]->QueueObj->Name }
+ },
+ OwnerName => {
+ title => 'Owner',
+ attribute => 'Owner',
+ value => sub { return $_[0]->OwnerObj->Name }
+ },
+ id => {
+ attribute => 'id',
+ align => 'right',
+ value => sub { return $_[0]->id }
+ },
+ Status => {
+ attribute => 'Status',
+ value => sub { return loc($_[0]->Status) }
+ },
+ Subject => {
+ attribute => 'Subject',
+ value => sub { return $_[0]->Subject || "(" . loc('No subject') . ")" }
+ },
+ ExtendedStatus => {
+ title => 'Status',
+ attribute => 'Status',
+ value => sub {
+ my $Ticket = shift;
+
+ if ( $Ticket->HasUnresolvedDependencies ) {
+ if ( $Ticket->HasUnresolvedDependencies( Type => 'approval' )
+ or $Ticket->HasUnresolvedDependencies( Type => 'code' ) )
+ {
+ return \'<em>', loc('(pending approval)'), \'</em>';
+ }
+ else {
+ return \'<em>', loc('(pending other Collection)'), \'</em>';
+ }
+ }
+ else {
+ return loc( $Ticket->Status );
+ }
+
+ }
+ },
+ Priority => {
+ attribute => 'Priority',
+ value => sub { return $_[0]->Priority }
+ },
+ InitialPriority => {
+ attribute => 'InitialPriority',
+ name => 'Initial Priority',
+ value => sub { return $_[0]->InitialPriority }
+ },
+ FinalPriority => {
+ attribute => 'FinalPriority',
+ name => 'Final Priority',
+ value => sub { return $_[0]->FinalPriority }
+ },
+ EffectiveId => {
+ attribute => 'EffectiveId',
+ value => sub { return $_[0]->EffectiveId }
+ },
+ Type => {
+ attribute => 'Type',
+ value => sub { return $_[0]->Type }
+ },
+ TimeWorked => {
+ attribute => 'TimeWorked',
+ title => 'Time Worked',
+ value => sub { return $_[0]->TimeWorked }
+ },
+ TimeLeft => {
+ attribute => 'TimeLeft',
+ title => 'Time Left',
+ value => sub { return $_[0]->TimeLeft }
+ },
+ TimeEstimated => {
+ attribute => 'TimeEstimated',
+ title => 'Time Estimated',
+ value => sub { return $_[0]->TimeEstimated }
+ },
+ Requestors => {
+ attribute => 'Requestor.EmailAddress',
+ value => sub { return $_[0]->Requestors->MemberEmailAddressesAsString }
+ },
+ Cc => {
+ attribute => 'Cc.EmailAddress',
+ value => sub { return $_[0]->Cc->MemberEmailAddressesAsString }
+ },
+ AdminCc => {
+ attribute => 'AdminCc.EmailAddress',
+ value => sub { return $_[0]->AdminCc->MemberEmailAddressesAsString }
+ },
+ StartsRelative => {
+ title => 'Starts',
+ attribute => 'Starts',
+ value => sub { return $_[0]->StartsObj->AgeAsString }
+ },
+ StartedRelative => {
+ title => 'Started',
+ attribute => 'Started',
+ value => sub { return $_[0]->StartedObj->AgeAsString }
+ },
+ CreatedRelative => {
+ title => 'Created',
+ attribute => 'Created',
+ value => sub { return $_[0]->CreatedObj->AgeAsString }
+ },
+ LastUpdatedRelative => {
+ title => 'Last Updated',
+ attribute => 'LastUpdated',
+ value => sub { return $_[0]->LastUpdatedObj->AgeAsString }
+ },
+ ToldRelative => {
+ title => 'Told',
+ attribute => 'Told',
+ value => sub { return $_[0]->ToldObj->AgeAsString }
+ },
+ DueRelative => {
+ title => 'Due',
+ attribute => 'Due',
+ value => sub {
+ my $date = $_[0]->DueObj;
+ if ($date && $date->Unix > 0 && $date->Unix < time()) {
+ return (\'<span class="overdue">' , $date->AgeAsString , \'</span>');
+ } else {
+ return $date->AgeAsString;
+ }
+ }
+ },
+ ResolvedRelative => {
+ title => 'Resolved',
+ attribute => 'Resolved',
+ value => sub { return $_[0]->ResolvedObj->AgeAsString }
+ },
+ Starts => {
+ attribute => 'Starts',
+ value => sub { return $_[0]->StartsObj->AsString }
+ },
+ Started => {
+ attribute => 'Started',
+ value => sub { return $_[0]->StartedObj->AsString }
+ },
+ Created => {
+ attribute => 'Created',
+ value => sub { return $_[0]->CreatedObj->AsString }
+ },
+ CreatedBy => {
+ attribute => 'CreatedBy',
+ title => 'Created By',
+ value => sub { return $_[0]->CreatorObj->Name }
+ },
+ LastUpdated => {
+ attribute => 'LastUpdated',
+ title => 'Last Updated',
+ value => sub { return $_[0]->LastUpdatedObj->AsString }
+ },
+ LastUpdatedBy => {
+ attribute => 'LastUpdatedBy',
+ title => 'Last Updated By',
+ value => sub { return $_[0]->LastUpdatedByObj->Name }
+ },
+ Told => {
+ attribute => 'Told',
+ value => sub { return $_[0]->ToldObj->AsString }
+ },
+ Due => {
+ attribute => 'Due',
+ value => sub { return $_[0]->DueObj->AsString }
+ },
+ Resolved => {
+ attribute => 'Resolved',
+ value => sub { return $_[0]->ResolvedObj->AsString }
+ },
+
+ # Everything from LINKTYPEMAP
+ (map {
+ $_ => { value => $LinkCallback->( $_ ) }
+ } keys %RT::Ticket::LINKTYPEMAP),
+
+ '_CLASS' => {
+ value => sub { return $_[1] % 2 ? 'oddline' : 'evenline' }
+ },
+ '_CHECKBOX' => {
+ attribute => 'checkbox',
+ title => loc('Update'),
+ align => 'right',
+ value => sub { return \('<input type="checkbox" class="checkbox" name="UpdateTicket'.$_[0]->id.'" value="1" checked />') }
+ },
+
+};
+</%ONCE>
+<%init>
+$m->comp( '/Elements/Callback', COLUMN_MAP => $COLUMN_MAP, _CallbackName => 'ColumnMap');
+return $ColumnMap->( $Name, $Attr );
+</%init>
diff --git a/rt/html/Elements/Refresh b/rt/html/Elements/Refresh
new file mode 100644
index 000000000..6edec0967
--- /dev/null
+++ b/rt/html/Elements/Refresh
@@ -0,0 +1,69 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+<option value="-1"
+%unless ($Default) {
+ selected
+%}
+><&|/l&>Don't refresh this page.</&></option>
+%foreach my $value (@refreshevery) {
+<option value="<%$value%>"
+% if ( $Default && ($value == $Default)) {
+selected
+% }
+><&|/l, $value/60 &>Refresh this page every [_1] minutes.</&></option>
+%}
+</select>
+
+<%INIT>
+my @refreshevery = qw(120 300 600 1200 3600 7200);
+</%INIT>
+<%ARGS>
+$Name => undef
+$Default => 0
+</%ARGS>
diff --git a/rt/html/Elements/RefreshHomepage b/rt/html/Elements/RefreshHomepage
new file mode 100644
index 000000000..167a48cab
--- /dev/null
+++ b/rt/html/Elements/RefreshHomepage
@@ -0,0 +1,51 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<form method="get" action="<%$RT::WebPath%>/index.html">
+<& /Elements/Refresh, Name => 'HomeRefreshInterval', Default => $session {'home_refresh_interval'} &>
+<div align="right"><input type="submit" class="button" value="<&|/l&>Go!</&>" /></div>
+</form>
diff --git a/rt/html/Elements/ScrubHTML b/rt/html/Elements/ScrubHTML
new file mode 100644
index 000000000..f382cc273
--- /dev/null
+++ b/rt/html/Elements/ScrubHTML
@@ -0,0 +1,73 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+my $scrubber = HTML::Scrubber->new();
+
+$scrubber->default(
+ 0,
+ {
+ '*' => 0,
+ id => 1,
+ class => 1,
+ # Match http, ftp and relative urls
+ href => qr{^(?:http:|ftp:|https:|/|__Web(?:Path|BaseURL|URL)__)}i,
+ face => 1,
+ size => 1,
+ target => 1
+ }
+);
+
+$scrubber->deny(qw[*]);
+$scrubber->allow(
+ qw[A B U P BR I HR BR SMALL EM FONT SPAN DIV UL OL LI DL DT DD PRE]);
+$scrubber->comment(0);
+return ( $scrubber->scrub($Content) );
+</%init>
+<%args>
+$Content => undef
+</%args>
diff --git a/rt/html/Elements/Section b/rt/html/Elements/Section
new file mode 100644
index 000000000..befe2475f
--- /dev/null
+++ b/rt/html/Elements/Section
@@ -0,0 +1,51 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<h1><%$title%></h1>
+<%ARGS>
+$title => undef
+</%ARGS>
diff --git a/rt/html/Elements/SelectAttachmentField b/rt/html/Elements/SelectAttachmentField
new file mode 100644
index 000000000..8a37ca504
--- /dev/null
+++ b/rt/html/Elements/SelectAttachmentField
@@ -0,0 +1,56 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+<option value="Subject"><&|/l&>Subject</&></option>
+<option value="Content"><&|/l&>Content</&></option>
+<option value="ContentType"><&|/l&>Content-Type</&></option>
+<option value="Filename"><&|/l&>Filename</&></option>
+</select>
+<%ARGS>
+$Name => 'AttachmentField'
+</%ARGS>
diff --git a/rt/html/Elements/SelectBoolean b/rt/html/Elements/SelectBoolean
new file mode 100644
index 000000000..b34e07a14
--- /dev/null
+++ b/rt/html/Elements/SelectBoolean
@@ -0,0 +1,71 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select NAME ="<%$Name%>">
+<option value="<%$TrueVal%>" <%$TrueDefault%>><%$True%></option>
+<option value="<%$FalseVal%>" <%$FalseDefault%>><%$False%></option>
+</select>
+
+<%ARGS>
+$Name => undef
+$True => loc("is")
+$Default => 'true'
+$TrueVal => 1
+$FalseVal => 0
+$False => loc("isn't")
+</%ARGS>
+
+<%INIT>
+my $TrueDefault = '';
+my $FalseDefault ='';
+if ($Default && $Default !~ /true/i) {
+ $FalseDefault = "SELECTED";
+}
+else {
+ $TrueDefault = "SELECTED";
+}
+</%INIT>
diff --git a/rt/html/Elements/SelectCustomFieldOperator b/rt/html/Elements/SelectCustomFieldOperator
new file mode 100644
index 000000000..ecb306c58
--- /dev/null
+++ b/rt/html/Elements/SelectCustomFieldOperator
@@ -0,0 +1,64 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select NAME ="<%$Name%>">
+% while (my $option = shift @Options) {
+% my $value = shift @Values;
+<option value="<%$value%>"
+% if ($Default eq $value) {
+selected
+% }
+><%$option%></option>
+% }
+</select>
+
+<%ARGS>
+$Name => undef
+@Options => ( loc('contains'), loc("doesn't contain"), loc('is'), loc("isn't"), loc('less than'), loc('greater than'))
+@Values => ('LIKE', 'NOT LIKE', '=', '!=', '<', '>')
+$Default => ''
+</%ARGS>
diff --git a/rt/html/Elements/SelectCustomFieldValue b/rt/html/Elements/SelectCustomFieldValue
new file mode 100644
index 000000000..2bcb35e9a
--- /dev/null
+++ b/rt/html/Elements/SelectCustomFieldValue
@@ -0,0 +1,65 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Callback, %ARGS &>
+% if ($CustomField->Type =~ /Select/i) {
+% my $values = $CustomField->Values;
+<select name="<%$Name%>">
+<option value="" selected>-</option>
+<option value="NULL"><&|/l&>(no value)</&></option>
+% while (my $value = $values->Next) {
+<option value="<%$value->Name%>"><%$value->Name%></option>
+% }
+</select>
+% }
+% else {
+<input name="<%$Name%>" size="20" />
+% }
+<%args>
+$Name => undef
+$CustomField =>undef
+</%args>
diff --git a/rt/html/Elements/SelectDate b/rt/html/Elements/SelectDate
new file mode 100644
index 000000000..b43f324ac
--- /dev/null
+++ b/rt/html/Elements/SelectDate
@@ -0,0 +1,75 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<script type="text/javascript"><!--
+ onLoadHook('createCalendarLink("<% $Name %>");');
+--></script>
+<input type="text" id="<% $Name %>" name="<% $Name %>" value="<% $Default %>" size="<% $Size %>" />
+<%init>
+unless ((defined $Default) or
+ ($current <= 0)) {
+ my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
+ localtime($current);
+ $Default = sprintf("%04d-%02d-%02d %02d:%02d",
+ $year+1900,$mon+1,$mday,
+ $hour,$min);
+}
+
+unless ($Name) {
+ $Name = $menu_prefix. "_Date";
+}
+</%init>
+
+<%args>
+
+$ShowTime => undef
+$menu_prefix=>''
+$current=>time
+$Default => ''
+$Name => undef
+$Size => 16
+</%args>
diff --git a/rt/html/Elements/SelectDateRelation b/rt/html/Elements/SelectDateRelation
new file mode 100644
index 000000000..9c80be4d7
--- /dev/null
+++ b/rt/html/Elements/SelectDateRelation
@@ -0,0 +1,60 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select NAME ="<%$Name%>">
+<option value="&lt;"><%$Before%></option>
+<option value="="><%$On%></option>
+<option value="&gt;"><%$After%></option>
+</select>
+
+<%ARGS>
+$Name => undef
+$Default => undef
+$Before => loc('Before')
+$On => loc('On')
+$After => loc('After')
+</%ARGS>
diff --git a/rt/html/Elements/SelectDateType b/rt/html/Elements/SelectDateType
new file mode 100644
index 000000000..653949a83
--- /dev/null
+++ b/rt/html/Elements/SelectDateType
@@ -0,0 +1,60 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+<option value="Created"><&|/l&>Created</&></option>
+<option value="Started"><&|/l&>Started</&></option>
+<option value="Resolved"><&|/l&>Resolved</&></option>
+<option value="Told"><&|/l&>Last Contacted</&></option>
+<option value="LastUpdated"><&|/l&>Last Updated</&></option>
+<option value="Starts"><&|/l&>Starts</&></option>
+<option value="Due"><&|/l&>Due</&></option>
+<option value="Updated"><&|/l&>Updated</&></option>
+</select>
+<%ARGS>
+$Name => 'DateType'
+</%ARGS>
diff --git a/rt/html/Elements/SelectEqualityOperator b/rt/html/Elements/SelectEqualityOperator
new file mode 100644
index 000000000..851add309
--- /dev/null
+++ b/rt/html/Elements/SelectEqualityOperator
@@ -0,0 +1,64 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select NAME ="<%$Name%>">
+% while (my $option = shift @Options) {
+% my $value = shift @Values;
+<option value="<%$value%>"
+% if ($Default eq $value) {
+selected
+% }
+><%$option%></option>
+% }
+</select>
+
+<%ARGS>
+$Name => undef
+@Options => (loc('less than'), loc('equal to'), loc('greater than'), loc('not equal to'))
+@Values => qw(< = > !=)
+$Default =>''
+</%ARGS>
diff --git a/rt/html/Elements/SelectGroups b/rt/html/Elements/SelectGroups
new file mode 100644
index 000000000..c1fb9df2a
--- /dev/null
+++ b/rt/html/Elements/SelectGroups
@@ -0,0 +1,62 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="GroupField">
+% foreach my $col (RT::Group->BasicColumns) {
+<option value="<% $col->[0] %>"><% loc($col->[1]) %></option>
+% }
+% while (my $CF = $CFs->Next) {
+<option value="CustomField-<% $CF->Id %>"><&|/l&>CustomField</&>: <% $CF->Name %></option>
+% }
+</select>
+<& /Elements/SelectMatch, Name=> 'GroupOp' &>
+<input size="8" name="GroupString" />
+<%INIT>
+my $CFs = RT::CustomFields->new($session{'CurrentUser'});
+$CFs->LimitToChildType('RT::Group');
+$CFs->OrderBy( FIELD => 'Name' );
+</%INIT>
diff --git a/rt/html/Elements/SelectLang b/rt/html/Elements/SelectLang
new file mode 100644
index 000000000..7640744c9
--- /dev/null
+++ b/rt/html/Elements/SelectLang
@@ -0,0 +1,80 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select NAME ="<%$Name%>">
+% if ($ShowNullOption) {
+<option value="">-</option>
+% }
+% foreach my $lang (@lang) {
+<option value="<%$lang%>" <%($Default && ($lang eq $Default)) && 'SELECTED'%>><% $lang_to_desc{$lang} %>
+% if (($Verbose) and (my $description = I18N::LangTags::List::native_name($lang)) ){
+(<%$description%>)
+% }
+</option>
+% }
+</select>
+<%ARGS>
+$ShowNullOption => 1
+$ShowAllQueues => 1
+$Name => undef
+$Verbose => undef
+$Default => 0
+$Lite => 0
+</%ARGS>
+
+<%ONCE>
+use I18N::LangTags::List;
+my (@lang, %lang_to_desc);
+foreach my $lang (map { s/:://; s/_/-/g; $_ } grep { /^\w+::$/ } keys %RT::I18N::) {
+ next if $lang =~ /i-default|en-us/;
+ my $desc = I18N::LangTags::List::name($lang);
+ next unless ($desc);
+ $desc =~ s/(.*) (.*)/$2 ($1)/;
+ $lang_to_desc{$lang} = $desc;
+}
+@lang = sort { $lang_to_desc{$a} cmp $lang_to_desc{$b} } keys %lang_to_desc;
+</%ONCE>
diff --git a/rt/html/Elements/SelectLinkType b/rt/html/Elements/SelectLinkType
new file mode 100644
index 000000000..4617e7c1c
--- /dev/null
+++ b/rt/html/Elements/SelectLinkType
@@ -0,0 +1,61 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select NAME ="<%$Name%>">
+<option value="MemberOf"><&|/l&>Member of</&></option>
+<option value="DependsOn"><&|/l&>Depends on</&></option>
+<option value="RefersTo"><&|/l&>Refers to</&></option>
+</select>
+
+<%ARGS>
+$Name => "LinkType"
+$Default => undef
+</%ARGS>
+
+<%INIT>
+# TODO handle Default
+</%INIT>
diff --git a/rt/html/Elements/SelectMatch b/rt/html/Elements/SelectMatch
new file mode 100644
index 000000000..646ad4e31
--- /dev/null
+++ b/rt/html/Elements/SelectMatch
@@ -0,0 +1,82 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select NAME ="<%$Name%>">
+<option value="LIKE" <%$LikeDefault%>><%$Like%></option>
+<option value="NOT LIKE" <%$NotLikeDefault%>><%$NotLike%></option>
+<option value="=" <%$TrueDefault%>><%$True%></option>
+<option value="!=" <%$FalseDefault%>><%$False%></option>
+</select>
+
+<%ARGS>
+$Name => undef
+$Like => loc('contains')
+$NotLike => loc("doesn't contain")
+$True => loc('is')
+$False => loc("isn't")
+$Default => undef
+</%ARGS>
+<%INIT>
+
+my $TrueDefault = '';
+my $FalseDefault='';
+my $LikeDefault='';
+my $NotLikeDefault ='';
+
+if ($Default && $Default =~ /false/i) {
+ $FalseDefault = "SELECTED";
+}
+elsif ($Default && $Default =~ /true/i) {
+ $TrueDefault = "SELECTED";
+}
+elsif ($Default && $Default =~ /notlike/i) {
+ $NotLikeDefault = "SELECTED";
+}
+else {
+ $LikeDefault = "SELECTED";
+}
+</%INIT>
diff --git a/rt/html/Elements/SelectNewTicketQueue b/rt/html/Elements/SelectNewTicketQueue
new file mode 100644
index 000000000..55dc7d2ea
--- /dev/null
+++ b/rt/html/Elements/SelectNewTicketQueue
@@ -0,0 +1,50 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<label accesskey="9">
+ <& /Elements/SelectQueue, Name => 'Queue', %ARGS, ShowNullOption => 0, ShowAllQueues => 0 &>
+</label>
diff --git a/rt/html/Elements/SelectOwner b/rt/html/Elements/SelectOwner
new file mode 100644
index 000000000..f33b346dc
--- /dev/null
+++ b/rt/html/Elements/SelectOwner
@@ -0,0 +1,110 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+%if ($DefaultValue) {
+<option <% !$Default ? "SELECTED" : '' %> value=""><%$DefaultLabel%></option>
+%}
+%foreach my $User ( @users) {
+<option <% ($User->Id == $Default) ? "SELECTED" : ''%>
+%if ($ValueAttribute eq 'id') {
+ value="<%$User->id%>"
+%} elsif ($ValueAttribute eq 'Name') {
+ value="<%$User->Name%>"
+%}
+><%$User->Name()%></option>
+%}
+</select>
+<%INIT>
+my @objects;
+my @users;
+
+if ($TicketObj) {
+ @objects = ($TicketObj);
+}
+elsif ($QueueObj) {
+ @objects = ($QueueObj);
+}
+elsif ($cfqueues) {
+ @objects = keys %{$cfqueues};
+}
+else {
+ # Let's check rights on an empty queue object. that will do a search for any queue.
+ my $queue = RT::Queue->new($session{'CurrentUser'});
+ push( @objects, $queue );
+}
+
+my %user_uniq_hash;
+
+
+foreach my $object (@objects) {
+ my $Users = RT::Users->new($session{CurrentUser});
+ $Users->WhoHaveRight(Right => 'OwnTicket', Object => $object, IncludeSystemRights => 1, IncludeSuperusers => 0);
+ while (my $User = $Users->Next()) {
+ next if ($User->id == $RT::Nobody->id); # skip nobody here, so we can make them first later
+ $user_uniq_hash{$User->Id()} = $User;
+ }
+}
+
+@users = sort { uc($a->Name) cmp uc($b->Name) } values %user_uniq_hash;
+unshift(@users, $RT::Nobody);
+
+
+
+</%INIT>
+
+<%ARGS>
+$QueueObj => undef
+$Name => undef
+$Default => 0
+$User => undef
+$TicketObj => undef
+$DefaultValue => 1
+$DefaultLabel => "-"
+$ValueAttribute => 'id'
+$cfqueues => undef
+</%ARGS>
diff --git a/rt/html/Elements/SelectQueue b/rt/html/Elements/SelectQueue
new file mode 100644
index 000000000..0decb5bc9
--- /dev/null
+++ b/rt/html/Elements/SelectQueue
@@ -0,0 +1,97 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% if ($Lite) {
+% my $d = new RT::Queue($session{'CurrentUser'});
+% $d->Load($Default);
+<input name="<%$Name%>" size="25" value="<%$d->Name%>" />
+% }
+% else {
+<select name="<%$Name%>">
+% if ($ShowNullOption) {
+ <option value="">-</option>
+% }
+% for my $queue (@{$session{$cache_key}}) {
+ <option value="<% ($NamedValues ? $queue->{Name} : $queue->{Id}) %>" <% ($queue->{Id} eq $Default ? 'selected="selected"' : '') |n %>>
+ <%$queue->{Name}%>
+% if ($Verbose and $queue->{Description}) {
+ (<%$queue->{Description}%>)
+% }
+ </option>
+% }
+</select>
+% }
+<%args>
+$CheckQueueRight => 'CreateTicket'
+$ShowNullOption => 1
+$ShowAllQueues => 1
+$Name => undef
+$Verbose => undef
+$NamedValues => 0
+$Default => 0
+$Lite => 0
+</%args>
+<%init>
+my $cache_key = "SelectQueue---"
+ . $session{'CurrentUser'}->Id
+ . "---$CheckQueueRight---$ShowAllQueues";
+
+if (not defined $session{$cache_key} and not $Lite) {
+ my $q = new RT::Queues($session{'CurrentUser'});
+ $q->UnLimit;
+
+ while (my $queue = $q->Next) {
+ if ($ShowAllQueues || $queue->CurrentUserHasRight($CheckQueueRight)) {
+ push @{$session{$cache_key}}, {
+ Id => $queue->Id,
+ Name => $queue->Name,
+ Description => $queue->Description,
+ };
+ }
+ }
+}
+</%init>
diff --git a/rt/html/Elements/SelectResultsPerPage b/rt/html/Elements/SelectResultsPerPage
new file mode 100644
index 000000000..a83cfaab7
--- /dev/null
+++ b/rt/html/Elements/SelectResultsPerPage
@@ -0,0 +1,68 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# TODO: Better default handling
+
+<select name="<% $Name %>">
+% foreach my $value ( @values ) {
+<option value="<% $value %>" <% $value == $Default? 'selected': '' %>>
+<% shift @labels %>
+</option>
+% }
+</select>
+
+<%INIT>
+my @values = qw(0 10 25 50 100);
+my @labels = (loc('Unlimited'), qw(10 25 50 100));
+$Default = 50 unless defined $Default;
+</%INIT>
+<%ARGS>
+
+$Name => undef
+$Default => 50
+
+</%ARGS>
diff --git a/rt/html/Elements/SelectSortOrder b/rt/html/Elements/SelectSortOrder
new file mode 100644
index 000000000..2a2771777
--- /dev/null
+++ b/rt/html/Elements/SelectSortOrder
@@ -0,0 +1,65 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+%foreach my $order (@orders) {
+<option value="<%$order%>" <%$order eq $Default && 'SELECTED' %>>
+<% shift @order_names %>
+</option>
+% }
+</select>
+
+<%INIT>
+my @orders = qw (ASC DESC);
+my @order_names = (loc('Ascending'), loc('Descending'));
+
+</%INIT>
+
+<%ARGS>
+$Name => 'SortOrder'
+$Default => 'ASC'
+</%ARGS>
diff --git a/rt/html/Elements/SelectStatus b/rt/html/Elements/SelectStatus
new file mode 100644
index 000000000..5f861af4f
--- /dev/null
+++ b/rt/html/Elements/SelectStatus
@@ -0,0 +1,67 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select NAME ="<%$Name%>">
+%if ($DefaultValue) {
+<option <% !$Default && "SELECTED" %> value=""><%$DefaultLabel%></option>
+%}
+%foreach my $status (@status) {
+%next if ($SkipDeleted && $status eq 'deleted');
+<option <% ($status eq $Default) && "SELECTED" %> value="<%$status%>"><%loc($status)%></option>
+% }
+</select>
+<%ONCE>
+my $queue = new RT::Queue($session{'CurrentUser'});
+my @status = $queue->StatusArray();
+</%ONCE>
+<%ARGS>
+$Name => undef
+$Default => ''
+$SkipDeleted => 0
+$DefaultValue => 1
+$DefaultLabel => "-"
+</%ARGS>
diff --git a/rt/html/Elements/SelectTicketSortBy b/rt/html/Elements/SelectTicketSortBy
new file mode 100644
index 000000000..aca98f878
--- /dev/null
+++ b/rt/html/Elements/SelectTicketSortBy
@@ -0,0 +1,62 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+% foreach my $field (@sortfields) {
+<option value="<%$field%>" <% $field eq $Default && 'SELECTED'%>><% loc($field) %></option>
+% }
+</select>
+
+<%INIT>
+my $tickets = new RT::Tickets($session{'CurrentUser'});
+my @sortfields = $tickets->SortFields();
+
+</%INIT>
+<%ARGS>
+$Name => 'SortTicketsBy'
+$Default => 'id'
+</%ARGS>
diff --git a/rt/html/Elements/SelectTicketTypes b/rt/html/Elements/SelectTicketTypes
new file mode 100644
index 000000000..5bacccf6c
--- /dev/null
+++ b/rt/html/Elements/SelectTicketTypes
@@ -0,0 +1,58 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+%foreach (@Types) {
+<option value="<% $_ %>" <% ($_ eq $Default) && "SELECTED" %>><&|/l&><% $_ %></&>
+%}
+</select>
+
+<%ARGS>
+$Name => 'TickType'
+$Default => undef
+@Types => qw(Approval Ticket)
+</%ARGS>
diff --git a/rt/html/Elements/SelectTimeUnits b/rt/html/Elements/SelectTimeUnits
new file mode 100755
index 000000000..e1656f113
--- /dev/null
+++ b/rt/html/Elements/SelectTimeUnits
@@ -0,0 +1,57 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<% $Name %>">
+<option value="minutes" selected><% loc('Minutes') %></option>
+<option value="hours"><% loc('Hours') %></option>
+</select>
+<%INIT>
+$Name .= '-TimeUnits' unless $Name =~ /-TimeUnits$/io;
+</%INIT>
+<%ARGS>
+$Name => ''
+</%ARGS>
diff --git a/rt/html/Elements/SelectUsers b/rt/html/Elements/SelectUsers
new file mode 100644
index 000000000..52febb837
--- /dev/null
+++ b/rt/html/Elements/SelectUsers
@@ -0,0 +1,62 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="UserField">
+% foreach my $col (RT::User->BasicColumns) {
+<option value="<% $col->[0] %>"><% loc($col->[1]) %></option>
+% }
+% while (my $CF = $CFs->Next) {
+<option value="CustomField-<% $CF->Id %>"><&|/l&>CustomField</&>: <% $CF->Name %></option>
+% }
+</select>
+<& /Elements/SelectMatch, Name=> 'UserOp' &>
+<input size="8" name="UserString" />
+<%INIT>
+my $CFs = RT::CustomFields->new($session{'CurrentUser'});
+$CFs->LimitToChildType('RT::User');
+$CFs->OrderBy( FIELD => 'Name' );
+</%INIT>
diff --git a/rt/html/Elements/SelectWatcherType b/rt/html/Elements/SelectWatcherType
new file mode 100644
index 000000000..26854a782
--- /dev/null
+++ b/rt/html/Elements/SelectWatcherType
@@ -0,0 +1,71 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select NAME ="<%$Name%>">
+% if ($AllowNull) {
+<option value="">-</option>
+% }
+%for my $option (@types) {
+<option value="<%$option%>" <%defined($Default) && $option eq $Default && "SELECTED"%>><%loc($option)%></option>
+%}
+</select>
+
+<%INIT>
+my @types;
+if ($Scope =~ 'queue') {
+ @types = qw(Cc AdminCc);
+}
+else {
+ @types = qw(Requestor Cc AdminCc);
+}
+</%INIT>
+<%ARGS>
+$AllowNull => 1
+$Default=>undef
+$Scope => 'ticket'
+$Name => 'WatcherType'
+</%ARGS>
diff --git a/rt/html/Elements/SetupSessionCookie b/rt/html/Elements/SetupSessionCookie
new file mode 100644
index 000000000..63101af5a
--- /dev/null
+++ b/rt/html/Elements/SetupSessionCookie
@@ -0,0 +1,126 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+return if $m->is_subrequest; # avoid reentrancy, as suggested by masonbook
+
+my %cookies = CGI::Cookie->fetch();
+my $cookiename = "RT_SID_" . $RT::rtname . "." . $ENV{'SERVER_PORT'};
+$SessionCookie ||= $cookies{$cookiename} ? $cookies{$cookiename}->value : undef;
+
+my %backends = (
+ mysql => 'Apache::Session::MySQL',
+ Pg => 'Apache::Session::Postgres',
+
+ # Oracle => 'Apache::Session::Oracle',
+);
+
+my $session_class = $RT::WebSessionClass
+ || $backends{$RT::DatabaseType}
+ || 'Apache::Session::File';
+my $pm = "$session_class.pm";
+$pm =~ s|::|/|g;
+require $pm;
+
+# morning bug avoidance attempt -- pdh 20030815
+unless ( $RT::Handle->dbh && $RT::Handle->dbh->ping ) {
+ $RT::Handle->Connect();
+}
+
+my $session_properties;
+if ( $session_class eq 'Apache::Session::File' ) {
+ $session_properties = {
+ Directory => $RT::MasonSessionDir,
+ LockDirectory => $RT::MasonSessionDir,
+ Transaction => 1
+ };
+} else {
+ $session_properties = {
+ Handle => $RT::Handle->dbh,
+ LockHandle => $RT::Handle->dbh,
+ Transaction => 1
+ };
+}
+
+eval {
+ tie %session, $session_class, $SessionCookie, $session_properties
+};
+if ($@) {
+
+ # If the session is invalid, create a new session.
+ eval {
+ tie %session, $session_class, undef, $session_properties;
+ undef $cookies{$cookiename};
+ };
+}
+
+if ($@) {
+ die loc("RT couldn't store your session.") . "\n"
+ . loc(
+ "This may mean that that the directory '[_1]' isn't writable or a database table is missing or corrupt.",
+ $RT::MasonSessionDir
+ )
+ . "\n\n"
+ . $@;
+}
+
+if ( !$cookies{$cookiename} ) {
+ my $cookie = new CGI::Cookie(
+ -name => $cookiename,
+ -value => $session{_session_id},
+ -path => $RT::WebPath,
+ -secure => ($RT::WebSecureCookies ? 1 :0)
+ );
+ $r->headers_out->{'Set-Cookie'} = $cookie->as_string;
+
+}
+
+return ();
+</%init>
+<%args>
+$SessionCookie => undef
+</%args>
diff --git a/rt/html/Elements/ShowCustomFieldBinary b/rt/html/Elements/ShowCustomFieldBinary
new file mode 100644
index 000000000..9dd5faaf1
--- /dev/null
+++ b/rt/html/Elements/ShowCustomFieldBinary
@@ -0,0 +1,51 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<a href="<%$RT::WebPath%>/Download/CustomFieldValue/<% $Object->Id %>/<% $Object->Content %>"><% $Object->Content %></a>
+<%ARGS>
+$Object => undef
+</%ARGS>
diff --git a/rt/html/Elements/ShowCustomFieldImage b/rt/html/Elements/ShowCustomFieldImage
new file mode 100644
index 000000000..c49ae0ecf
--- /dev/null
+++ b/rt/html/Elements/ShowCustomFieldImage
@@ -0,0 +1,53 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% my $url = $RT::WebPath . "/Download/CustomFieldValue/".$Object->Id.'/'.$Object->Content;
+<a href="<% $url %>"><% $Object->Content %></a>
+<img type="<% $Object->ContentType %>" height="64" src="<% $url %>" align="middle" />
+<%ARGS>
+$Object
+</%ARGS>
diff --git a/rt/html/Elements/ShowCustomFieldWikitext b/rt/html/Elements/ShowCustomFieldWikitext
new file mode 100644
index 000000000..1ddd7da1f
--- /dev/null
+++ b/rt/html/Elements/ShowCustomFieldWikitext
@@ -0,0 +1,58 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% my $content = $Object->LargeContent || $Object->Content;
+% $content = $m->comp('/Elements/ScrubHTML', Content => $content);
+% my $base = $Object->Object->WikiBase;
+% my $wiki_content = Text::WikiFormat::format( $content."\n" , {}, { extended => 1, absolute_links => 1, implicit_links => $RT::WikiImplicitLinks, prefix => $base} );
+<%$wiki_content|n%>
+<%init>
+use Text::WikiFormat;
+</%init>
+<%ARGS>
+$Object
+</%ARGS>
diff --git a/rt/html/Elements/ShowCustomFields b/rt/html/Elements/ShowCustomFields
new file mode 100644
index 000000000..743c9999b
--- /dev/null
+++ b/rt/html/Elements/ShowCustomFields
@@ -0,0 +1,115 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table>
+% while ( my $CustomField = $CustomFields->Next ) {
+% my $Values = $Object->CustomFieldValues( $CustomField->Id );
+% my $count = $Values->Count;
+ <tr id="CF-<%$CustomField->id%>-ShowRow">
+ <td class="label"><% $CustomField->Name %>:</td>
+ <td class="value">
+% unless ( $count ) {
+<i><&|/l&>(no value)</&></i>
+% } elsif ( $count == 1 ) {
+% $print_value->( $CustomField, $Values->First );
+% } else {
+<ul>
+% while ( my $Value = $Values->Next ) {
+<li>
+% $print_value->( $CustomField, $Value );
+</li>
+% }
+</ul>
+% }
+ </td>
+ </tr>
+% }
+</table>
+<%INIT>
+my $CustomFields = $Object->CustomFields;
+$m->comp('/Elements/Callback', _CallbackName => 'MassageCustomFields',
+ CustomFields => $CustomFields);
+
+my $print_value = sub {
+ my ($cf, $value) = @_;
+ my $linked = $cf->LinkValueTo;
+ if ( $linked ) {
+ $m->out('<a href="'. $value->LinkValueTo .'" target="_new">');
+ }
+ my $comp = "ShowCustomField". $cf->Type;
+ $m->comp('/Elements/Callback',
+ _CallbackName => 'ShowComponentName',
+ Name => \$comp,
+ CustomField => $cf,
+ Object => $Object
+ );
+ if ( $m->comp_exists( $comp ) ) {
+ $m->comp( $comp, Object => $value );
+ } else {
+ $m->print( $value->Content );
+ }
+ $m->out('</a>') if $linked;
+
+ # This section automatically populates a div with the "IncludeContentForValue" for this custom
+ # field if it's been defined
+ if ( $cf->IncludeContentForValue ) {
+ my $vid = $value->id;
+ $m->out( '<div class="object_cf_value_include" id="object_cf_value_'. $vid .'">' );
+ $m->print( loc("See also:") );
+ $m->out( '<a href="'. $value->IncludeContentForValue .'">' );
+ $m->print( $value->IncludeContentForValue );
+ $m->out( qq{</a></div>\n} );
+ $m->out( qq{<script><!--\nahah('} );
+ $m->print( $value->IncludeContentForValue );
+ $m->out( qq{', 'object_cf_value_$vid');\n--></script>\n} );
+ }
+};
+
+</%INIT>
+<%ARGS>
+$Object => undef
+</%ARGS>
diff --git a/rt/html/Elements/ShowLink b/rt/html/Elements/ShowLink
new file mode 100644
index 000000000..a1d6bdf97
--- /dev/null
+++ b/rt/html/Elements/ShowLink
@@ -0,0 +1,64 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<a href="<%$URI->Resolver->HREF%>">
+% if ($URI->IsLocal) {
+% my $member = $URI->Object;
+% if (UNIVERSAL::isa($member, "RT::Ticket")) {
+<%$member->Id%>: (<%$member->OwnerObj->Name%>) <%$member->Subject%> [<% loc($member->Status) %>]
+% } elsif ( UNIVERSAL::can($member, 'Name')) {
+<%$URI->Resolver->AsString%>: <%$member->Name%>
+% } else {
+<%$URI->Resolver->AsString%>
+% }
+% } else {
+<%$URI->Resolver->AsString%>
+% }
+</a>
+<%ARGS>
+$URI => undef
+</%ARGS>
diff --git a/rt/html/Elements/ShowLinks b/rt/html/Elements/ShowLinks
new file mode 100755
index 000000000..800e82ea2
--- /dev/null
+++ b/rt/html/Elements/ShowLinks
@@ -0,0 +1,112 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table>
+ <tr>
+ <td class="labeltop"><&|/l&>Depends on</&>:</td>
+ <td class="value">
+<ul>
+% while (my $Link = $Ticket->DependsOn->Next) {
+<li><& ShowLink, URI => $Link->TargetURI &></li>
+% }
+</ul>
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Depended on by</&>:</td>
+ <td class="value">
+<ul>
+% while (my $Link = $Ticket->DependedOnBy->Next) {
+<li><& ShowLink, URI => $Link->BaseURI &></li>
+% }
+</ul>
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Parents</&>:</td>
+ <td class="value">
+<ul>
+% while (my $Link = $Ticket->MemberOf->Next) {
+<li><& ShowLink, URI => $Link->TargetURI &></li>
+% }
+</ul>
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Children</&>:</td>
+ <td class="value"><& /Ticket/Elements/ShowMembers, Ticket => $Ticket &></td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Refers to</&>:</td>
+ <td class="value">
+<ul>
+% while (my $Link = $Ticket->RefersTo->Next) {
+<li><& ShowLink, URI => $Link->TargetURI &></li>
+% }
+</ul>
+ </td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Referred to by</&>:</td>
+ <td class="value">
+ <ul>
+% while (my $Link = $Ticket->ReferredToBy->Next) {
+% next if (UNIVERSAL::isa($Link->BaseObj, 'RT::Ticket') && $Link->BaseObj->Type eq 'reminder');
+<li><& ShowLink, URI => $Link->BaseURI &></li>
+% }
+</ul>
+ </td>
+ </tr>
+
+% # Allow people to add more rows to the table
+% $m->comp('/Elements/Callback', %ARGS );
+
+</table>
+
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Elements/ShowMemberships b/rt/html/Elements/ShowMemberships
new file mode 100644
index 000000000..f6b2817d7
--- /dev/null
+++ b/rt/html/Elements/ShowMemberships
@@ -0,0 +1,88 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<ul>
+% while ( my $GroupMember = $GroupMembers->Next ) {
+% my $Group = RT::Group->new($session{'CurrentUser'});
+% $Group->Load($GroupMember->GroupId) or next;
+% if ($Group->Domain eq 'UserDefined') {
+<li><a href="<%$RT::WebPath%>/Admin/Groups/Modify.html?id=<% $Group->Id %>"><% $Group->Name %></a></li>
+% } elsif ($Group->Domain eq 'SystemInternal') {
+<li><em><% loc($Group->Type) %></em></li>
+% }
+% }
+</ul>
+<%INIT>
+my $GroupMembers = RT::GroupMembers->new($session{'CurrentUser'});
+$GroupMembers->Limit( FIELD => 'MemberId', VALUE => $UserObj->Id );
+my $alias = $GroupMembers->Join(
+ TYPE => 'left',
+ ALIAS1 => 'main',
+ FIELD1 => 'GroupId',
+ TABLE2 => 'Groups',
+ FIELD2 => 'id'
+);
+$GroupMembers->Limit(
+ ALIAS => $alias,
+ FIELD => 'Domain',
+ OPERATOR => '=',
+ VALUE => 'SystemInternal',
+);
+$GroupMembers->Limit(
+ ALIAS => $alias,
+ FIELD => 'Domain',
+ OPERATOR => '=',
+ VALUE => 'UserDefined',
+);
+$GroupMembers->OrderByCols(
+ { ALIAS => $alias, FIELD => 'Domain' },
+ { ALIAS => $alias, FIELD => 'Name' },
+);
+</%INIT>
+<%ARGS>
+$UserObj
+</%ARGS>
diff --git a/rt/html/Elements/ShowSearch b/rt/html/Elements/ShowSearch
new file mode 100644
index 000000000..ded865b82
--- /dev/null
+++ b/rt/html/Elements/ShowSearch
@@ -0,0 +1,126 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<&|/Widgets/TitleBox,
+ title => loc($search->Description, $ProcessedSearchArg->{'Rows'}),
+ title_href => $query_link_url.$QueryString,
+ titleright => $customize ? loc('Edit') : '',
+ titleright_href => $customize &>
+<& $query_display_component, %$ProcessedSearchArg, ShowNavigation => 0 &>
+</&>
+<%init>
+my $search;
+my $user = $session{'CurrentUser'}->UserObj;
+my $SearchArg;
+my $customize;
+my $query_display_component = '/Elements/TicketList';
+my $query_link_url = 'Search/Results.html';
+
+if ($SavedSearch) {
+ my ( $container_object, $search_id ) = _parse_saved_search($SavedSearch);
+ $search = $container_object->Attributes->WithId($search_id);
+ unless ( $search->Id && ref( $SearchArg = $search->Content ) eq 'HASH' ) {
+ $m->out("Saved Search $SavedSearch not found");
+ return;
+ }
+ $SearchArg->{'SearchType'} ||= 'Ticket';
+ if ( $SearchArg->{SearchType} ne 'Ticket' ) {
+
+ # XXX: dispatch to different handler here
+ $query_display_component
+ = '/Search/Elements/' . $SearchArg->{SearchType};
+ $query_link_url = "Search/$SearchArg->{SearchType}.html";
+ } else {
+ $customize = $RT::WebPath . '/Search/Build.html?'
+ . $m->comp( '/Elements/QueryString',
+ LoadSavedSearch => $SavedSearch );
+ }
+} else {
+ ($search) = RT::System->new( $session{'CurrentUser'} ) ->Attributes->Named( 'Search - ' . $Name );
+ unless ( $search && $search->Id ) {
+ my (@custom_searches) = RT::System->new( $session{'CurrentUser'} )->Attributes->Named('SavedSearch');
+ foreach my $custom (@custom_searches) {
+ if ($custom->Description eq $Name) { $search = $custom; last }
+ }
+ unless ($search && $search->id) {
+ $m->out("Predefined search $Name not found");
+ return;
+ }
+ }
+
+ $SearchArg = $user->Preferences( $search, $search->Content );
+ $customize = $RT::WebPath . '/Prefs/Search.html?'
+ . $m->comp( '/Elements/QueryString',
+ name => ref($search) . '-' . $search->Id );
+}
+
+# ProcessedSearchArg is a search with overridings, but for link we use
+# orginal search's poperties
+my $ProcessedSearchArg = $SearchArg;
+$ProcessedSearchArg = { %$SearchArg, %Override } if keys %Override;
+
+$m->comp(
+ '/Elements/Callback', %ARGS,
+ _CallbackName => 'ModifySearch',
+ OriginalSearch => $SearchArg,
+ Search => $ProcessedSearchArg,
+);
+
+foreach ( $SearchArg, $ProcessedSearchArg ) {
+ $_->{'Query'} =~ s/__CurrentUser__/$session{'CurrentUser'}->Id/ge;
+ $_->{'Format'} =~ s/__WebPath__/$RT::WebPath/g;
+ $_->{'Format'} =~ s/__loc\(["']?(\w+)["']?\)__/loc("$1")/ge;
+}
+
+my $QueryString = '?' . $m->comp( '/Elements/QueryString', %$SearchArg );
+
+</%init>
+<%ARGS>
+$Name => undef
+$SavedSearch => undef
+%Override => ()
+</%ARGS>
diff --git a/rt/html/Elements/SimpleSearch b/rt/html/Elements/SimpleSearch
new file mode 100644
index 000000000..a4fd7e270
--- /dev/null
+++ b/rt/html/Elements/SimpleSearch
@@ -0,0 +1,58 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<form action="<% $RT::WebPath %>/Search/Simple.html" STYLE="margin:0">
+<SCRIPT TYPE="text/javascript">
+ function clearhint_search_ticket (what) {
+ if ( what.value == '(ticket # or subject string)' )
+ what.value = '';
+ }
+</SCRIPT>
+<input name="q" autocomplete="off" accesskey="0" class="field" VALUE="(ticket # or subject string)" onFocus="clearhint_search_ticket(this);" onClick="clearhint_search_ticket(this);" STYLE="text-align:right; font-family: Arial, Verdana, Helvetica, sans-serif;"><BR>
+<A HREF="<% $RT::WebPath %>/Search/Build.html" STYLE="color: #ffffff; font-size: 70%; font-weight:normal">Advanced</A>
+<input type="submit" class="fsblackbutton" value="<&|/l&>Search tickets</&>" onMouseOver="this.className='fsblackbuttonselected'; return true;" onMouseOut="this.className='fsblackbutton'; return true;" STYLE="font-size:70%;padding-left:2px;padding-right:2px">
+</form>
diff --git a/rt/html/Elements/Submit b/rt/html/Elements/Submit
new file mode 100644
index 000000000..ee3e8b6f6
--- /dev/null
+++ b/rt/html/Elements/Submit
@@ -0,0 +1,86 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<div class="submit">
+ <div class="extra-buttons">
+% if ($CheckAll) {
+ <input type="button" value="<%$CheckAllLabel%>" onclick="setCheckbox(this.form, '<% $CheckboxName %>', true);return false;" class="button" />
+% }
+% if ($ClearAll) {
+ <input type="button" value="<%$ClearAllLabel%>" onclick="setCheckbox(this.form, '<% $CheckboxName %>', false);return false;" class="button" />
+% }
+% if ($Reset) {
+ <input type="reset" value="<%$ResetLabel%>" class="button" />
+% }
+ </div>
+ <div class="buttons">
+% if ($AlternateLabel) {
+ <span class="caption"><%$AlternateCaption%></span>
+ <input type="submit" <% $Name && qq[ name="$Name"] | n %> value="<%$AlternateLabel%>" class="button" />
+% } else {
+ <span class="caption"><%$Caption%></span>
+ <input type="submit" <% $Name && qq[ name="$Name"] | n %> value="<%$Label%>" class="button" />
+% }
+ </div>
+ <div class="submit-clear"></div>
+</div>
+
+<%ARGS>
+$color => undef
+$Caption => ''
+$AlternateCaption => undef
+$AlternateLabel => undef
+$Label => loc('Submit')
+$Name => undef
+$CheckAll => undef
+$CheckAllLabel => loc('Check All')
+$ClearAll => undef
+$ClearAllLabel => loc('Clear All')
+$CheckboxName => ''
+$Reset => undef
+$ResetLabel => loc('Reset')
+</%ARGS>
diff --git a/rt/html/Elements/Tabs b/rt/html/Elements/Tabs
new file mode 100644
index 000000000..9d1eea602
--- /dev/null
+++ b/rt/html/Elements/Tabs
@@ -0,0 +1,137 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/PageLayout,
+ current_toptab => $current_toptab,
+ current_tab => $current_tab,
+ toptabs => $toptabs,
+ topactions => $topactions,
+ tabs => $tabs,
+ actions => $actions,
+ subactions => $subactions,
+ title => $Title,
+ show_menu => $show_menu,
+&>
+<a name="skipnav" id="skipnav" accesskey="8"></a>
+<%INIT>
+my $action;
+my $basetopactions = {
+# A => { html => $m->scomp('/Elements/CreateTicket')
+# },
+ A => { html => $m->scomp('/Elements/FreesideNewCust')
+ },
+ B => { html => $m->scomp('/Elements/FreesideSearch')
+ },
+ C => { html => $m->scomp('/Elements/FreesideInvoiceSearch')
+ },
+ D => { html => $m->scomp('/Elements/FreesideSvcSearch')
+ },
+ E => { html => $m->scomp('/Elements/SimpleSearch')
+ }
+ };
+my $basetabs = {
+ ' A'=> { title => 'Billing Main',
+ path => &RT::URI::freeside::FreesideURL(),
+ },
+ A => { #title => loc('Homepage'),
+ title => 'Ticketing Main',
+ path => '',
+ },
+ Ab => { title => loc('Simple Ticket Search'),
+ path => 'Search/Simple.html'
+ },
+ B => { title => loc('Adv. Ticket Search'),
+ path => 'Search/Build.html'
+ },
+ C => { title => loc('Tools'),
+ path => 'Tools/index.html'
+ },
+ P => { title => loc('Approval'),
+ path => 'Approvals/'
+ },
+ };
+
+if ($session{'CurrentUser'}->HasRight( Right => 'ShowConfigTab',
+ Object => $RT::System )) {
+ $basetabs->{E} = { title => loc('Configuration'),
+ path => 'Admin/',
+ };
+}
+
+if ($session{'CurrentUser'}->HasRight( Right => 'ModifySelf',
+ Object => $RT::System )) {
+ $basetabs->{K} = { title => loc('Preferences'),
+ path => 'User/Prefs.html'
+ };
+}
+
+if (!defined $toptabs) {
+ $toptabs = $basetabs;
+}
+if (!defined $topactions) {
+ $topactions = $basetopactions;
+}
+
+ require RT::URI::freeside;
+
+ # Now let callbacks add their extra tabs
+ $m->comp('/Elements/Callback',
+ topactions => $topactions,
+ toptabs => $toptabs, %ARGS);
+
+</%INIT>
+<%ARGS>
+$current_toptab => undef
+$current_tab => undef
+$toptabs => undef
+$topactions => undef
+$tabs => undef
+$actions => undef
+$subactions => undef
+$Title => undef
+$show_menu => 1
+</%ARGS>
diff --git a/rt/html/Elements/TicketList b/rt/html/Elements/TicketList
new file mode 100644
index 000000000..b36101e73
--- /dev/null
+++ b/rt/html/Elements/TicketList
@@ -0,0 +1,179 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table border="0" cellspacing="0" cellpadding="1" width="100%">
+
+% if ($ShowHeader) {
+<& /Elements/CollectionAsTable/Header,
+ Format => \@Format,
+ FormatString => $Format,
+ AllowSorting => $AllowSorting,
+ Order => $Order,
+ Query => $Query,
+ Rows => $Rows,
+ Page => $Page,
+ OrderBy => $OrderBy ,
+ BaseURL => $BaseURL,
+ maxitems => $maxitems &>
+% }
+
+% my $i;
+% while (my $record = $Collection->Next) {
+% $i++;
+% # Every ten rows, flush the buffer and put something on the page.
+% # hun, this flushes things out out-of-order for me on "RT at a glance"...?
+% # $m->flush_buffer() unless ($i % 10);
+<& /Elements/CollectionAsTable/Row, Format => \@Format, i => $i, record => $record, maxitems => $maxitems &>
+% }
+
+</table>
+
+% if ($Rows && $ShowNavigation) {
+<hr>
+% my $oddRows;
+% if (($TotalFound % $Rows) == 0) {
+% $oddRows = 0;
+% } else { $oddRows = 1; }
+% my $pages = int($TotalFound/$Rows)+$oddRows;
+% $pages = 1 if $pages < 1;
+<&|/l, $Page, $pages &>Page [_1] of [_2]</&>
+
+<%perl>
+my $prev = $m->comp(
+ '/Elements/QueryString',
+ Query => $Query,
+ Format => $Format,
+ Rows => $Rows,
+ OrderBy => $OrderBy,
+ Order => $Order,
+ Page => ( $Page - 1 )
+);
+my $next = $m->comp(
+ '/Elements/QueryString',
+ Query => $Query,
+ Format => $Format,
+ Rows => $Rows,
+ OrderBy => $OrderBy,
+ Order => $Order,
+ Page => ( $Page + 1 )
+);
+</%perl>
+% if ($Page > 1) {
+<a href="<%$BaseURL%><%$prev%>"><&|/l&>Previous Page</&></a>
+% }
+% if (($Page * $Rows) < $TotalFound) {
+<a href="<%$BaseURL%><%$next%>"><&|/l&>Next Page</&></a>
+% }
+% }
+<%INIT>
+my $maxitems = 0;
+
+$Format ||= $RT::DefaultSearchResultFormat;
+
+# DisplayFormat lets us use a "temporary" format for display, while
+# still using our original format for next/prev page links.
+# bulk update uses this feature to add checkboxes
+
+
+$DisplayFormat ||= $Format;
+
+# Scrub the html of the format string to remove any potential nasties.
+$Format = $m->comp('/Elements/ScrubHTML', Content => $Format);
+$DisplayFormat = $m->comp('/Elements/ScrubHTML', Content => $DisplayFormat);
+
+
+unless ($Collection) {
+ $Collection = RT::Tickets->new($session{'CurrentUser'});
+ $Collection->FromSQL($Query);
+}
+
+my (@Format) = $m->comp('/Elements/CollectionAsTable/ParseFormat', Format => $DisplayFormat);
+
+# Find the maximum number of items in any row, so we can pad the table.
+my $item = 0;
+foreach my $col (@Format) {
+ $item++;
+ if ( $col->{title} && ($col->{title} eq 'NEWLINE') ) {
+ $item = 0;
+ }
+ else {
+ $maxitems = $item if $item > $maxitems;
+ }
+}
+
+if ($OrderBy =~ /\|/) {
+ # Multiple Sorts
+ my @OrderBy = split /\|/,$OrderBy;
+ my @Order = split /\|/,$Order;
+ $Collection->OrderByCols(
+ map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } } ( 0
+ .. $#OrderBy ) );;
+} else {
+ $Collection->OrderBy(FIELD => $OrderBy, ORDER => $Order);
+}
+
+$Collection->RowsPerPage($Rows) if ($Rows);
+$Page = 1 unless $Page > 0; # workaround problems with Page = '' or undef
+$Collection->GotoPage( $Page - 1 ); # SB uses page 0 as the first page
+my $TotalFound = $Collection->CountAll();
+
+</%INIT>
+<%ARGS>
+$Query => undef
+$Rows => 50
+$Page => 1
+$Title => 'Ticket Search'
+$Collection => undef
+$AllowSorting => undef
+$Order => undef
+$OrderBy => undef
+$BaseURL => undef
+$Format => $RT::DefaultSearchResultFormat
+$DisplayFormat => undef
+$ShowNavigation => 1
+$ShowHeader => 1
+</%ARGS>
diff --git a/rt/html/Elements/TitleBox b/rt/html/Elements/TitleBox
new file mode 100644
index 000000000..dfab9ea82
--- /dev/null
+++ b/rt/html/Elements/TitleBox
@@ -0,0 +1,51 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+# For compatibility with 3.4
+$m->comp('/Widgets/TitleBox', %ARGS );
+</%init>
diff --git a/rt/html/Elements/TitleBoxEnd b/rt/html/Elements/TitleBoxEnd
new file mode 100644
index 000000000..933d77000
--- /dev/null
+++ b/rt/html/Elements/TitleBoxEnd
@@ -0,0 +1,51 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+# For compatibility with 3.4
+$m->comp('/Widgets/TitleBoxEnd', %ARGS );
+</%init>
diff --git a/rt/html/Elements/TitleBoxStart b/rt/html/Elements/TitleBoxStart
new file mode 100644
index 000000000..ba24fd92e
--- /dev/null
+++ b/rt/html/Elements/TitleBoxStart
@@ -0,0 +1,51 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+# For compatibility with 3.4
+$m->comp('/Widgets/TitleBoxStart', %ARGS );
+</%init>
diff --git a/rt/html/Elements/ValidateCustomFields b/rt/html/Elements/ValidateCustomFields
new file mode 100644
index 000000000..483021952
--- /dev/null
+++ b/rt/html/Elements/ValidateCustomFields
@@ -0,0 +1,81 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%INIT>
+my $valid = 1;
+$CustomFields->GotoFirstItem;
+while (my $CF = $CustomFields->Next) {
+ my $pattern = $CF->Pattern;
+ my $field = $NamePrefix . $CF->Id . "-Value";
+ my $value;
+
+ if ($ARGSRef->{"${field}s-Magic"} and exists $ARGSRef->{"${field}s"}) {
+ $value = $ARGSRef->{"${field}s"};
+
+ # We only validate Single Combos -- multis can never be user input
+ next if ref $value;
+ }
+ else {
+ $value = $ARGSRef->{$field};
+ }
+
+ $m->notes(('Field-' . $CF->Id) => $value);
+ next if $CF->MatchPattern($value);
+ $m->notes(
+ ('InvalidField-' . $CF->Id)
+ => (loc("Input must match [_1]", $CF->FriendlyPattern))
+ );
+ $valid = 0;
+}
+$m->notes('ValidFields', $valid);
+return $valid;
+</%INIT>
+<%ARGS>
+$CustomFields
+$ARGSRef
+$NamePrefix => "Object-RT::Ticket--CustomField-"
+</%ARGS>
diff --git a/rt/html/Helpers/CalPopup.html b/rt/html/Helpers/CalPopup.html
new file mode 100644
index 000000000..9509d13f4
--- /dev/null
+++ b/rt/html/Helpers/CalPopup.html
@@ -0,0 +1,129 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, ShowBar => 0 &>
+%# From /Elements/Header
+</div>
+<div id="body" class="calpopup">
+
+<a href="#" onclick="window.close(); return false;"><&|/l&>Close window</&></a>
+
+<div class="calendar">
+ <table>
+ <caption>
+ <a class="prev" href="CalPopup.html?DisplayedMonth=<%$prev_month%>&DisplayedYear=<%$prev_year%>&field=<%$field%>"><&|/l&>Prev</&></a>
+ <span class="month"><% $months[$DisplayedMonth-1] %> <% $DisplayedYear %></span>
+ <a class="next" href="CalPopup.html?DisplayedMonth=<%$next_month%>&DisplayedYear=<%$next_year%>&field=<%$field%>"><&|/l&>Next</&></a>
+ </caption>
+ <tr>
+% foreach my $wday (@weekdays) {
+ <th><%$wday%></th>
+% }
+ </tr>
+% foreach my $week (@cal) {
+ <tr>
+% foreach my $day (@{$week}) {
+ <td>
+% if ($day) {
+% my $datestr = sprintf('%04d-%02d-%02d', $DisplayedYear, $DisplayedMonth, $day);
+ <a href="#" onclick="updateParentField('<% $field %>','<% $datestr %>'); return false;"><% $day %></a>
+% } else {
+ &nbsp;
+% }
+ </td>
+% } #foreach $day
+ </tr>
+% } # foreach $week
+ </table>
+</div>
+</div>
+</body>
+</html>
+% $m->abort();
+
+<%init>
+use Calendar::Simple;
+my @today = localtime(time());
+
+my @weekdays;
+push @weekdays, loc($_)
+ for qw(Sun Mon Tue Wed Thu Fri Sat);
+
+my @months;
+push @months, loc($_)
+ for qw(January February March April May June July August
+ September October November December);
+
+unless ($DisplayedYear) {
+ $DisplayedMonth = $today[4] + 1;
+ $DisplayedYear = ($today[5] + 1900);
+}
+
+my ($prev_year, $next_year, $prev_month, $next_month);
+$prev_month = $next_month = $DisplayedMonth;
+$prev_year = $next_year = $DisplayedYear;
+
+$next_month++;
+$prev_month--;
+
+if ($DisplayedMonth == 12) {
+ $next_year++;
+ $next_month = 1;
+}
+elsif ($DisplayedMonth == 1) {
+ $prev_month = 12;
+ $prev_year--;
+}
+
+my @cal = calendar($DisplayedMonth, $DisplayedYear);
+</%init>
+
+<%args>
+$field => 'none'
+$DisplayedMonth => undef
+$DisplayedYear => undef
+</%args>
diff --git a/rt/html/Helpers/EmailAutocomplete b/rt/html/Helpers/EmailAutocomplete
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/rt/html/Helpers/EmailAutocomplete
diff --git a/rt/html/NoAuth/Logout.html b/rt/html/NoAuth/Logout.html
new file mode 100644
index 000000000..49b7a4e59
--- /dev/null
+++ b/rt/html/NoAuth/Logout.html
@@ -0,0 +1,74 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<html>
+<head>
+<title>RT: Logout</title>
+ <meta HTTP-EQUIV="Refresh" content="0;URL=<%$URL%>">
+</head>
+<body>
+<p><&|/l&>You have been logged out of RT.</&>
+
+<br />
+<br />
+<a href="<%$URL%>"><&|/l&>You're welcome to login again</&></a>.
+
+% $m->abort();
+
+<%INIT>
+$m->comp('/Elements/Callback', _CallbackName => 'BeforeSessionDelete', %ARGS);
+
+if (defined %session) {
+ tied(%session)->delete;
+}
+
+$m->comp('/Elements/Callback', _CallbackName => 'AfterSessionDelete', %ARGS);
+</%INIT>
+
+<%ARGS>
+$URL => $RT::WebPath."/"
+</%ARGS>
diff --git a/rt/html/NoAuth/Reminder.html b/rt/html/NoAuth/Reminder.html
new file mode 100644
index 000000000..dc935d45e
--- /dev/null
+++ b/rt/html/NoAuth/Reminder.html
@@ -0,0 +1,50 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, title => loc('Password Reminder') &>
+
+<&|/l&>Not yet implemented.</&>
diff --git a/rt/html/NoAuth/css/3.4-compat/body.css b/rt/html/NoAuth/css/3.4-compat/body.css
new file mode 100644
index 000000000..6188951a4
--- /dev/null
+++ b/rt/html/NoAuth/css/3.4-compat/body.css
@@ -0,0 +1,75 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#body {
+ margin: 0.5em 0.5em 0 0.5em;
+ float: left;
+ width: 80%;
+}
+
+#body h1 { font-size: 1.5em; }
+#body h2 { font-size: 1.3em; }
+#body h3 { font-size: 1.1em; }
+#body h4 { font-size: 1em; }
+#body h5 { font-size: 0.9em; }
+#body h6 { font-size: 0.8em; }
+
+#body h1, #body h2, #body h3, #body h4, #body h5, #body h6 {
+ font-weight: bold;
+}
+
+#body :link { color: black; }
+
+#body :link, #body :visited {
+ font-weight: bold;
+ text-decoration: none;
+}
+
+#body :link:hover, #body :visited:hover {
+ text-decoration: underline;
+}
+
diff --git a/rt/html/NoAuth/css/3.4-compat/footer.css b/rt/html/NoAuth/css/3.4-compat/footer.css
new file mode 100644
index 000000000..4e90c507c
--- /dev/null
+++ b/rt/html/NoAuth/css/3.4-compat/footer.css
@@ -0,0 +1,61 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#footer {
+ clear: both;
+ font-size: 0.8em;
+ margin-top: 5em;
+ padding-bottom: 2em;
+ color: #888;
+}
+
+#footer p {
+ text-align: right;
+ padding: 0 0.5em 0 0;
+ margin: 0;
+}
+
diff --git a/rt/html/NoAuth/css/3.4-compat/forms.css b/rt/html/NoAuth/css/3.4-compat/forms.css
new file mode 100644
index 000000000..301f8f3e4
--- /dev/null
+++ b/rt/html/NoAuth/css/3.4-compat/forms.css
@@ -0,0 +1,104 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+form .label, form label {
+ font-weight: bold;
+}
+
+.submit {
+ background: #069;
+%# These borders are needed so the container actually surrounds the floats inside it
+ border-top: 1px solid white;
+ border-bottom: 1px solid white;
+ color: #ffdb00;
+ font-weight: bold;
+}
+
+.submit .buttons { float: right; }
+.submit .extra-buttons { float: left; }
+.submit .button { font-size: 0.9em; }
+
+.submit .submit-clear { clear: right; }
+
+.input-row {
+ clear: both;
+ padding: 0.25em;
+}
+
+%# ComboBox styles... some properties like height and width must be dynamically
+%# set in the JS (at least for now).
+.combobox {
+ border: 2px inset ButtonHighlight;
+ padding-left: 0.5em;
+ padding-bottom: 0.1em;
+}
+
+.combobox .combo-button {
+ padding: 0 2px 0 2px;
+ margin: 0;
+ background: ButtonFace;
+ color: ButtonText;
+ border: 2px outset ButtonHighlight;
+ cursor: default;
+ font-size: 8pt;
+}
+
+.combobox .combo-text {
+ border: none;
+ margin: 0;
+ padding: 0;
+}
+
+.combobox .combo-list {
+ z-index: 200;
+}
+
+#quickbar #topactions form {
+ display: inline;
+ margin-left: 2em;
+}
+
diff --git a/rt/html/NoAuth/css/3.4-compat/header.css b/rt/html/NoAuth/css/3.4-compat/header.css
new file mode 100644
index 000000000..a8e3184ce
--- /dev/null
+++ b/rt/html/NoAuth/css/3.4-compat/header.css
@@ -0,0 +1,88 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#header #page-menu {
+ display: none;
+}
+
+#header {
+ background: #4282b5;
+ margin-top: 0;
+ padding-bottom: 0.2em;
+ float: left;
+ width: 82%;
+}
+
+#header h1 {
+ background: #4282b5;
+ color: white;
+ font-size: 1.7em;
+ margin: 0;
+ padding: 0;
+}
+
+#header #actions-menu {
+ display: block;
+ margin: 0 1em 0 0;
+ padding: 0;
+ color: white;
+ text-align: right;
+ font-size: 1.2em;
+}
+
+#header #actions-menu li {
+ display: inline;
+}
+
+#header #actions-menu :link, #header #actions-menu :visited {
+ color: white;
+ text-decoration: none;
+}
+
+#header #actions-menu :link:hover, #header #actions-menu :visited:hover {
+ text-decoration: underline;
+}
diff --git a/rt/html/NoAuth/css/3.4-compat/login.css b/rt/html/NoAuth/css/3.4-compat/login.css
new file mode 100644
index 000000000..2b967e0f1
--- /dev/null
+++ b/rt/html/NoAuth/css/3.4-compat/login.css
@@ -0,0 +1,54 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#body.login-body {
+ width: 98%;
+}
+
+#login-box {
+ width: 30em;
+}
diff --git a/rt/html/NoAuth/css/3.4-compat/main.css b/rt/html/NoAuth/css/3.4-compat/main.css
new file mode 100644
index 000000000..f2c9ad321
--- /dev/null
+++ b/rt/html/NoAuth/css/3.4-compat/main.css
@@ -0,0 +1,69 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# Import the 3.5 styles we want to build off of...
+@import "../3.5-default/logo.css";
+@import "../3.5-default/misc.css";
+@import "../3.5-default/transactions.css";
+@import "../3.5-default/approvals.css";
+@import "../3.5-default/login.css";
+@import "../3.5-default/quickbar.css";
+@import "../3.5-default/ticket.css";
+
+%# ...and then import the 3.4 compat styles afterwards so they can cascade
+@import "nav.css";
+@import "footer.css";
+@import "body.css";
+@import "titlebox.css";
+@import "header.css";
+@import "forms.css";
+@import "transactions.css";
+@import "ticket.css";
+@import "login.css";
+@import "quickbar.css";
+@import "misc.css";
+
diff --git a/rt/html/NoAuth/css/3.4-compat/misc.css b/rt/html/NoAuth/css/3.4-compat/misc.css
new file mode 100644
index 000000000..09be77a51
--- /dev/null
+++ b/rt/html/NoAuth/css/3.4-compat/misc.css
@@ -0,0 +1,49 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+.oddline { background: white; }
+.evenline { background: #cecfef; }
diff --git a/rt/html/NoAuth/css/3.4-compat/nav.css b/rt/html/NoAuth/css/3.4-compat/nav.css
new file mode 100644
index 000000000..f83c0fd2c
--- /dev/null
+++ b/rt/html/NoAuth/css/3.4-compat/nav.css
@@ -0,0 +1,106 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#nav {
+ clear: left;
+ float: left;
+ width: 18%;
+ font-size: 1.4em;
+ color: #eee;
+ margin: 0;
+ background: #4282b5 url(<%$RT::WebImagesURL%>/css/cbr.gif) no-repeat bottom right;
+}
+
+#nav #system-menu {
+ padding: 0 0.2em 0.2em 0.2em;
+ margin-top: 0;
+/* background: transparent url(<%$RT::WebImagesURL%>/css/ctr.gif) no-repeat top right; */
+}
+
+#nav ul {
+ list-style: none;
+ padding-left: 0.5em;
+ margin-left: 0;
+}
+
+#nav ul .bullet, #nav ul .separator {
+ display: none;
+}
+
+#nav ul li {
+ padding: 0.4em 0 0.4em 0.2em;
+ border-bottom: 1px solid white;
+}
+
+#nav li ul {
+ font-size: 0.9em;
+}
+
+#nav li ul li {
+ border-bottom: none;
+ padding: 0.2em 0 0 0;
+}
+
+#nav :link, #nav :visited {
+ text-decoration: none;
+ color: #eee;
+}
+
+#nav :link:hover,
+#nav :visited:hover,
+#nav :link.selected,
+#nav :visited.selected
+{
+ color: #ff6;
+}
+
+#nav :link.selected,
+#nav :visited.selected
+{
+ text-decoration: underline;
+ font-weight: bold;
+}
diff --git a/rt/html/NoAuth/css/3.4-compat/quickbar.css b/rt/html/NoAuth/css/3.4-compat/quickbar.css
new file mode 100644
index 000000000..d7aac5d51
--- /dev/null
+++ b/rt/html/NoAuth/css/3.4-compat/quickbar.css
@@ -0,0 +1,82 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#quickbar {
+ border: 1px solid transparent;
+}
+
+#quickbar #quick-personal {
+ display: inline;
+ color: #888;
+ padding: 0.5em 1em 0 0;
+ float: right;
+}
+
+#quickbar #quick-personal span {
+ font-weight: bold;
+}
+
+#quickbar #quick-personal :link,
+#quickbar #quick-personal :visited
+{
+ color: #888;
+ font-weight: bold;
+}
+
+#quickbar #quick-personal :link:hover,
+#quickbar #quick-personal :visited:hover
+{
+ color: black;
+}
+
+#quickbar #topactions {
+ color: white;
+ font-size: 0.9em;
+ position: relative;
+ right: 1em;
+ float: right;
+}
diff --git a/rt/html/NoAuth/css/3.4-compat/ticket.css b/rt/html/NoAuth/css/3.4-compat/ticket.css
new file mode 100644
index 000000000..2c808929d
--- /dev/null
+++ b/rt/html/NoAuth/css/3.4-compat/ticket.css
@@ -0,0 +1,50 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+.value {
+ font-weight: bold;
+}
diff --git a/rt/html/NoAuth/css/3.4-compat/titlebox.css b/rt/html/NoAuth/css/3.4-compat/titlebox.css
new file mode 100644
index 000000000..363da69d3
--- /dev/null
+++ b/rt/html/NoAuth/css/3.4-compat/titlebox.css
@@ -0,0 +1,103 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+.titlebox {
+ margin: 0.5em 0;
+}
+
+.titlebox .titlebox-content {
+ padding: 0.05em;
+}
+
+.titlebox .titlebox-title {
+ background: #069;
+ padding: 0.2em 0.5em;
+ color: white;
+ border-top: 1px solid black;
+ border-bottom: 1px solid black;
+ font-weight: bold;
+ position: relative;
+}
+
+.titlebox .titlebox-title .right {
+ position: absolute;
+ right: 1.5em;
+ font-size: 0.9em;
+}
+
+#body .titlebox .titlebox-title :link, #body .titlebox .titlebox-title :visited {
+ color: white;
+}
+
+#body .titlebox .titlebox-title .widget :link, #body .titlebox .titlebox-title .widget :visited {
+ color: black;
+}
+
+.titlebox .titlebox-content hr.clear {
+ visibility: hidden;
+}
+
+%# TRS: I wish there was a more elegant way to do this... I essentially need to
+%# select all elements X that do NOT have element Y as a descendant... which I can
+%# fake with the child selector of CSS2, but IE is stupid and does not support that.
+
+% for (qw(index
+% Search-Build
+% User-Prefs
+% Approvals
+% Admin-Users-Modify
+% SelfService
+% SelfService-Closed
+% Ticket-ModifyAll
+% ))
+% {
+#comp-<%$_%> .titlebox .titlebox-content,
+% }
+.titlebox .titlebox .titlebox-content
+{
+ background: #cecfce;
+}
diff --git a/rt/html/NoAuth/css/3.4-compat/transactions.css b/rt/html/NoAuth/css/3.4-compat/transactions.css
new file mode 100644
index 000000000..2078a3147
--- /dev/null
+++ b/rt/html/NoAuth/css/3.4-compat/transactions.css
@@ -0,0 +1,83 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+.ticket-transaction {
+ margin: 0;
+ border: none;
+}
+
+.ticket-transaction .type {
+ width: 1em;
+}
+
+.ticket-transaction.even {
+ background: #cecfef;
+}
+
+.ticket-transaction.basics { border-color: #9c3031; }
+.ticket-transaction.basics .type { background: #9c3031; }
+.ticket-summary .ticket-info-basics .titlebox-content { border-left: none; }
+.ticket-summary .ticket-info-basics .titlebox-title { background: #9c3031; }
+
+.ticket-transaction.people { border-color: #31309c; }
+.ticket-transaction.people .type { background: #31309c; }
+.ticket-summary .ticket-info-people .titlebox-content { border-left: none; }
+.ticket-summary .ticket-info-people .titlebox-title { background: #31309c; }
+
+.ticket-transaction.links { border-color: #316531; }
+.ticket-transaction.links .type { background: #316531; }
+.ticket-summary .ticket-info-links .titlebox-content { border-left: none; }
+.ticket-summary .ticket-info-links .titlebox-title { background: #316531; }
+
+.ticket-transaction.dates { border-color: #633063; }
+.ticket-transaction.dates .type { background: #633063; }
+.ticket-summary .ticket-info-dates .titlebox-content { border-left: none; }
+.ticket-summary .ticket-info-dates .titlebox-title { background: #633063; }
+
+.ticket-transaction.message { border-color: #069; }
+.ticket-transaction.message .type { background: #069; }
+
diff --git a/rt/html/NoAuth/css/3.5-default/approvals.css b/rt/html/NoAuth/css/3.5-default/approvals.css
new file mode 100644
index 000000000..5bc836aa9
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/approvals.css
@@ -0,0 +1,97 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+.approval {
+ margin-bottom: 3em;
+ padding: 0 0 1em 0;
+ border: 1px solid #069;
+}
+
+.approval .name {
+ background: #069;
+ color: white;
+ font-size: 1.1em;
+ padding: 0.2em 0 0.4em 0.2em;
+}
+
+#body .approval .name :link, #body .approval .name :visited {
+ color: white;
+}
+
+.approval .originating-ticket {
+ margin: 0.5em;
+ border: 1px solid #aaa;
+}
+
+.approval .originating-ticket .link {
+ display: block;
+ background: #aaa;
+ padding: 0.2em 0 0.4em 0.2em;
+}
+
+.approval .originating-ticket .info {
+ padding: 0.5em;
+}
+
+#body .approval .originating-ticket .link :link,
+#body .approval .originating-ticket .link :visited {
+ color: black;
+}
+
+.approval .form {
+ margin: 1em 0.5em 0.5em 0.5em;
+}
+
+.approval .form .action, .approval .form .notes {
+ float: left;
+ margin-left: 1em;
+}
+
+.approval .form .action { padding-top: 1em; }
+
+.approval .form .action label { font-weight: normal; }
+.approval .form .notes label { display: block; }
diff --git a/rt/html/NoAuth/css/3.5-default/body.css b/rt/html/NoAuth/css/3.5-default/body.css
new file mode 100755
index 000000000..d4470343c
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/body.css
@@ -0,0 +1,81 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#body {
+ clear: both;
+ margin: 0 0.75em 0 2em;
+ padding-top: 0.5em;
+}
+
+#body h1 {
+ border-bottom: 1px dotted #069;
+ padding-left: 0.5em;
+}
+
+#body h1 { font-size: 1.5em; }
+#body h2 { font-size: 1.3em; }
+#body h3 { font-size: 1.1em; }
+#body h4 { font-size: 1em; }
+#body h5 { font-size: 0.9em; }
+#body h6 { font-size: 0.8em; }
+
+#body h1, #body h2, #body h3, #body h4, #body h5, #body h6 {
+ color: #930;
+ font-weight: bold;
+}
+
+#body :link { color: #069; }
+
+#body :link, #body :visited {
+ font-weight: bold;
+ text-decoration: none;
+}
+
+#body :link:hover, #body :visited:hover {
+ text-decoration: underline;
+}
+
diff --git a/rt/html/NoAuth/css/3.5-default/footer.css b/rt/html/NoAuth/css/3.5-default/footer.css
new file mode 100644
index 000000000..c46998293
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/footer.css
@@ -0,0 +1,91 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#footer {
+ clear: both;
+ font-size: 0.8em;
+ margin-top: 5em;
+ padding-bottom: 3em;
+}
+
+#footer p { float: left; }
+
+#footer #time {
+ color: white;
+ background: #069 url(<%$RT::WebImagesURL%>/css/ctr-b2g.gif) no-repeat top right;
+ padding: 0.2em 0 0.3em 0;
+ margin: 0;
+ position: relative;
+ z-index: 2;
+}
+
+#footer #time span {
+ padding: 0.2em 2em 0.3em 3em;
+ background: url(<%$RT::WebImagesURL%>/css/cbr-b2g.gif) no-repeat bottom right;
+}
+
+#footer #bpscredits {
+ background: #ccc url(<%$RT::WebImagesURL%>/css/ctr-gray.gif) no-repeat top right;
+ padding: 0.2em 0 0.3em 0;
+ margin: 0;
+ position: relative;
+ left: -10px;
+ z-index: 1;
+}
+
+#footer #bpscredits span {
+ padding: 0.2em 2em 0.3em 3em;
+ background: url(<%$RT::WebImagesURL%>/css/cbr-gray.gif) no-repeat bottom right;
+}
+
+#footer #legal {
+ float: none;
+ color: #888;
+ padding: 1em 0 0 2em;
+ clear: both;
+}
+
diff --git a/rt/html/NoAuth/css/3.5-default/forms.css b/rt/html/NoAuth/css/3.5-default/forms.css
new file mode 100755
index 000000000..e49c45f3a
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/forms.css
@@ -0,0 +1,136 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+form input.button {
+ border: 3px double #069;
+ border-top-color: #08c;
+ border-left-color: #08c;
+ padding: 0.25em;
+ background: white;
+ font-weight: bold;
+ font-size: 1em;
+ margin: 0.5em 0.5em 0 0.5em;
+}
+
+form input.button:active {
+ border: 3px double #08c;
+ border-top-color: #069;
+ border-left-color: #069;
+}
+
+form select {
+ border: 1px solid #069;
+ padding: 1px;
+}
+
+form input.field, form input, form textarea {
+ border: 1px solid #069;
+ padding: 3px;
+}
+
+form input.checkbox, form input.radio {
+ border: none;
+ padding: 0;
+}
+
+/* form .entry input, form .value input */
+
+.label, form label, .labeltop {
+ font-weight: bold;
+}
+
+.labeltop {
+ vertical-align: top;
+}
+
+.submit {
+ font-weight: bold;
+ color: #a00;
+ font-size: 1.1em;
+ padding: 0.3em 1.5em 0 1.5em;
+ border-top: 1px solid #930;
+ margin: 1.5em 0 2.5em 0;
+}
+
+.submit .buttons { float: right; }
+.submit .extra-buttons { float: left; }
+.submit .button { font-size: 0.9em; }
+.submit .submit-clear { display: none; }
+
+.input-row {
+ clear: both;
+ padding: 0.25em;
+}
+
+%# ComboBox styles... some properties like height and width must be dynamically
+%# set in the JS (at least for now).
+.combobox {
+ border: 2px inset #069;
+ padding-left: 0.5em;
+ padding-bottom: 0.1em;
+}
+
+.combobox .combo-button {
+ padding: 0 2px 0 2px;
+ margin: 0;
+ background: ButtonFace;
+ color: ButtonText;
+ border: 2px outset ButtonHighlight;
+ cursor: default;
+ font-size: 8pt;
+}
+
+.combobox .combo-text {
+ border: none;
+ margin: 0;
+ padding: 0;
+}
+
+.combobox .combo-list {
+ z-index: 200;
+}
+
diff --git a/rt/html/NoAuth/css/3.5-default/freeside.css b/rt/html/NoAuth/css/3.5-default/freeside.css
new file mode 100644
index 000000000..a595061b9
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/freeside.css
@@ -0,0 +1,82 @@
+.black {
+ background-color: #000000;
+ color: #ffffff;
+ background-position: left top;
+ vertical-align: top;
+ text-align: left;
+}
+
+.blackright {
+ background-color: #000000;
+ color: #ffffff;
+ background-position: left top;
+ vertical-align: center;
+ text-align: right;
+ font-size:16px;
+ padding-right:4px
+}
+
+input.fsblackbutton {
+ background-color:#333333;
+ color: #ffffff;
+ border:1px solid;
+ border-top-color:#cccccc;
+ border-left-color:#cccccc;
+ border-right-color:#aaaaaa;
+ border-bottom-color:#aaaaaa;
+ font-family: Arial, Verdana, Helvetica, sans-serif;
+ font-weight:bold;
+ padding-left:12px;
+ padding-right:12px;
+ overflow:visible;
+ filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr='#ff333333',EndColorStr='#ff666666')
+}
+
+input.fsblackbuttonselected {
+ background-color:#7e0079;
+ color: #ffffff;
+ border:1px solid;
+ border-top-color:#cccccc;
+ border-left-color:#cccccc;
+ border-right-color:#aaaaaa;
+ border-bottom-color:#aaaaaa;
+ font-family: Arial, Verdana, Helvetica, sans-serif;
+ font-weight:bold;
+ padding-left:12px;
+ padding-right:12px;
+ overflow:visible;
+ filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr='#ff330033',EndColorStr='#ff7e0079')
+}
+
+.darkmediumgray {
+ background-color: #aaaaaa;
+ background-position: left top;
+ vertical-align: top;
+ text-align: left;
+}
+.darkmediumgrayright {
+ background-color: #aaaaaa;
+ background-position: left top;
+ vertical-align: top;
+ text-align: right;
+}
+.bggray {
+ background-color: #e8e8e8;
+ background-position: left top;
+ vertical-align: top;
+ text-align: left;
+}
+.bggrayright {
+ background-color: #e8e8e8;
+ background-position: left top;
+ vertical-align: top;
+ text-align: right;
+}
+
+div.titlebox {
+ background: #d4d4d4;
+}
+
+div.titlebox-title {
+ background: #e8e8e8;
+}
diff --git a/rt/html/NoAuth/css/3.5-default/header.css b/rt/html/NoAuth/css/3.5-default/header.css
new file mode 100644
index 000000000..cc5c9e4b1
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/header.css
@@ -0,0 +1,152 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#header {
+ clear: both;
+ margin: 0 0.75em 0 0.75em;
+ padding-top: 1em;
+}
+
+#header h1 {
+ margin: 0;
+ padding: 0;
+ color: #930;
+ position: relative;
+ font-size: 2em;
+ font-weight: bold;
+ left: 1.3em;
+ top: 0.15em;
+ z-index: 3;
+ width: 95%;
+}
+
+#header ul {
+ margin: 0;
+ padding: 0;
+ color: #eee;
+ float: left;
+}
+
+#header #page-menu {
+ position: relative;
+ z-index: 2;
+ background: #069 url(<%$RT::WebImagesURL%>/css/ct.gif) no-repeat top left;
+ min-width: 65%;
+}
+
+%# This is an interesting bit of CSS. expression() is an IE-only extension to
+%# it's CSS implementation. Just in case other browsers might choke on it,
+%# the rule is enclosed in a selector only IE will (wrongly) match to an element.
+%#
+%# The expression() function takes Javascript, and basically what it's doing here
+%# is checking to see if the width of the menu would be greater than 65% of the body
+%# width. If it is, great, leave it alone to automatically resize. If it is not, set
+%# it to 65% of the body width. This amounts to emulating the min-width rule that
+%# compliant browsers understand above.
+* html #header ul#page-menu {
+ width: expression(document.body.clientWidth*0.65 < document.getElementById('page-menu').clientWidth ? "auto" : "65%");
+ overflow: visible;
+}
+
+#page-menu div {
+ position: relative;
+ z-index: 3;
+}
+
+#page-menu div { background: url(<%$RT::WebImagesURL%>/css/cb.gif) no-repeat bottom left; }
+#page-menu div div { background: url(<%$RT::WebImagesURL%>/css/cbr.gif) no-repeat bottom right; }
+#page-menu div div div {
+ background: url(<%$RT::WebImagesURL%>/css/ctr.gif) no-repeat top right;
+ padding: 0.2em 1em 0.4em 1em;
+}
+
+#page-menu.actions-present div div { background: url(<%$RT::WebImagesURL%>/css/cbr-b2lb.gif) no-repeat bottom right; }
+#page-menu.actions-present div div div { background: url(<%$RT::WebImagesURL%>/css/ctr-b2lb.gif) no-repeat top right; }
+
+#header ul li {
+ display: inline;
+}
+
+#header #actions-menu {
+ position: relative;
+ background: #08c;
+}
+
+#actions-menu div {
+ position: relative;
+ z-index: 2;
+}
+
+/*#actions-menu div { background: url(<%$RT::WebImagesURL%>/css/cb.gif) no-repeat bottom left; }*/
+#actions-menu div div { background: url(<%$RT::WebImagesURL%>/css/cbr.gif) no-repeat bottom right; }
+#actions-menu div div div {
+ background: url(<%$RT::WebImagesURL%>/css/ctr.gif) no-repeat top right;
+ padding: 0.2em 1em 0.4em 1em;
+}
+
+#header :link,
+#header :visited
+{
+ color: white;
+ text-decoration: none;
+}
+
+#header :link.selected,
+#header :visited.selected,
+#header :link:hover,
+#header :visited:hover
+{
+ color: #fc6; /*#ff6;*/
+}
+
+#header :link.selected,
+#header :visited.selected
+{
+ font-weight: bold;
+ text-decoration: underline;
+}
+
diff --git a/rt/html/NoAuth/css/3.5-default/login.css b/rt/html/NoAuth/css/3.5-default/login.css
new file mode 100644
index 000000000..b9e7aeb41
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/login.css
@@ -0,0 +1,85 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#login-box {
+ width: 50%;
+ margin: 0 auto 4em auto;
+}
+
+%# More rules only IE will recognize (but are still valid!) to correct for
+%# IE's incorrect handling of auto margins and the W3C defined behavior.
+%# text-align will affect a block element in IE, therefore centering it, like
+%# left and right auto margins *should*
+* html #login-box {
+ text-align: center;
+}
+
+%# ... and align the text back the way it should be
+* html #login-box .titlebox {
+ text-align: left;
+}
+
+#login-box .input-row {
+ padding: 0.5em;
+}
+
+#login-box .input-row .label {
+ width: 8em;
+ float: left;
+ text-align: right;
+ padding: 0.2em 1em 0 0;
+}
+
+#login-box .input-row .input {
+ float: left;
+}
+
+#login-box .button-row {
+ clear: both;
+ padding: 0.5em;
+ float: right;
+}
diff --git a/rt/html/NoAuth/css/3.5-default/logo.css b/rt/html/NoAuth/css/3.5-default/logo.css
new file mode 100644
index 000000000..e9c079cc0
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/logo.css
@@ -0,0 +1,60 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#logo {
+ float: left;
+ clear: left;
+
+ margin: 0.5em 0 0.5em 10px;
+}
+
+#logo img { border: none; }
+#logo div.rtname {
+ text-align: center;
+ font-weight: bold;
+}
+
diff --git a/rt/html/NoAuth/css/3.5-default/main.css b/rt/html/NoAuth/css/3.5-default/main.css
new file mode 100644
index 000000000..7c4fa5a20
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/main.css
@@ -0,0 +1,62 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+@import "misc.css";
+@import "login.css";
+@import "logo.css";
+@import "quickbar.css";
+@import "body.css";
+@import "approvals.css";
+@import "titlebox.css";
+@import "forms.css";
+@import "ticket.css";
+@import "transactions.css";
+@import "nav.css";
+@import "header.css";
+@import "footer.css";
+@import "freeside.css";
+
diff --git a/rt/html/NoAuth/css/3.5-default/misc.css b/rt/html/NoAuth/css/3.5-default/misc.css
new file mode 100755
index 000000000..ddb2e687b
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/misc.css
@@ -0,0 +1,92 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+body {
+ font-family: Verdana, sans-serif;
+ font-size: 76%;
+ margin: 0;
+ /* background-color: white; */
+ background-color: #e8e8e8;
+}
+
+.hide, .hidden { display: none !important; }
+
+#body.calpopup {
+ margin-left: 2em;
+}
+
+.calendar {
+ text-align: center;
+ margin: 2em 0 0 0;
+}
+
+.calendar td, .calendar th { padding: 0.1em 0.25em 0.1em 0.25em; }
+
+.calendar caption .month {
+ padding: 0 1em 0 1em;
+ font-size: 1.5em;
+}
+
+.evenline { background-color: white; }
+.oddline { background-color: #ddd; }
+
+td {
+ padding: 0.1em 0.5em 0.1em 0.5em;
+}
+
+.clear { clear: both; }
+
+ul.action-results {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+#comp-Search-Build .titlebox-content {
+ padding-left: 0.7em;
+ padding-right: 0.3em;
+}
+
diff --git a/rt/html/NoAuth/css/3.5-default/nav.css b/rt/html/NoAuth/css/3.5-default/nav.css
new file mode 100644
index 000000000..78323aa91
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/nav.css
@@ -0,0 +1,163 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#nav {
+ clear: both;
+ font-size: 1.1em;
+}
+
+#nav #system-menu,
+#nav ul
+{
+ min-width: 85%;
+}
+
+%# This is an interesting bit of CSS. expression() is an IE-only extension to
+%# it's CSS implementation. Just in case other browsers might choke on it,
+%# the rule is enclosed in a selector only IE will (wrongly) match to an element.
+%#
+%# The expression() function takes Javascript, and basically what it's doing here
+%# is checking to see if the width of the menu would be greater than 85% of the body
+%# width. If it is, great, leave it alone to automatically resize. If it is not, set
+%# it to 85% of the body width. This amounts to emulating the min-width rule that
+%# compliant browsers understand above.
+* html #nav #system-menu {
+ width: expression(document.body.clientWidth*0.85 < document.getElementById('page-menu').clientWidth ? "auto" : "85%");
+ overflow: visible;
+}
+
+#nav ul {
+ float: left;
+ clear: left;
+
+ color: #eee;
+ font-weight: bold;
+
+ margin: 0;
+ padding: 0;
+
+ list-style: none;
+}
+
+#nav li ul {
+ margin-top: 0.75em;
+}
+
+/*
+%# We need the extra padding above for browsers where we display the arrows
+%# but those don't work in IE so we don't want as much spacing
+%#
+%# IE wrongly matches the selector below even though there isn't an element
+%# above <html> in the doc tree
+*/
+* html #nav li ul {
+ margin-top: 0.25em;
+}
+
+#nav li {
+ display: inline;
+ margin-bottom: 1em;
+ padding: 0.2em 0 0.4em 0;
+}
+
+#nav li.first { padding-left: 1em; }
+
+#nav ul div div.wrapper {
+ text-align: left;
+ padding: 0.2em 1em 0.4em 0;
+}
+
+/****/
+
+#nav :link,
+#nav :visited
+{
+ color: #ececec;
+ text-decoration: none;
+}
+
+#nav :link.selected,
+#nav :visited.selected,
+#nav :link:hover,
+#nav :visited:hover
+{
+ color: #fc6; /*#ff6;*/
+}
+
+#nav :link.selected,
+#nav :visited.selected
+{
+ text-decoration: underline;
+}
+
+html>body #nav :link.selected,
+html>body #nav :visited.selected
+{
+ padding-bottom: 0.8em;
+ background: transparent url(<%$RT::WebImagesURL%>/css/dark-arrow.png) no-repeat bottom center;
+}
+
+html>body #nav :link.selected.odd,
+html>body #nav :visited.selected.odd
+{
+ padding-bottom: 0.8em;
+ background: transparent url(<%$RT::WebImagesURL%>/css/light-arrow.png) no-repeat bottom center;
+}
+
+/*
+#nav ul { background: #069 url(<%$RT::WebImagesURL%>/css/ctr.gif) no-repeat top right; }
+#nav ul div { background: transparent url(<%$RT::WebImagesURL%>/css/cbr.gif) no-repeat bottom right; }
+#nav ul.odd { background: #08c url(<%$RT::WebImagesURL%>/css/ctr.gif) no-repeat top right; }
+#nav ul.odd div { background: transparent url(<%$RT::WebImagesURL%>/css/cbr.gif) no-repeat bottom right; }
+*/
+
+
+#nav ul div.wrapper { background: transparent url(<%$RT::WebImagesURL%>/css/ctr.gif) no-repeat top right; }
+#nav ul div { background: #069 url(<%$RT::WebImagesURL%>/css/cbr.gif) no-repeat bottom right; }
+#nav ul.odd div.wrapper { background: transparent url(<%$RT::WebImagesURL%>/css/ctr.gif) no-repeat top right; }
+#nav ul div.odd { background: #08c url(<%$RT::WebImagesURL%>/css/cbr.gif) no-repeat bottom right; }
+
diff --git a/rt/html/NoAuth/css/3.5-default/quickbar.css b/rt/html/NoAuth/css/3.5-default/quickbar.css
new file mode 100644
index 000000000..16f83f789
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/quickbar.css
@@ -0,0 +1,98 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+#quickbar #quick-personal {
+ display: inline;
+ color: #888;
+ padding: 0.5em 1em 0 0;
+ float: right;
+}
+
+#quickbar #quick-personal span {
+ font-weight: bold;
+}
+
+#quickbar #quick-personal :link,
+#quickbar #quick-personal :visited
+{
+ color: #888;
+ font-weight: bold;
+}
+
+#quickbar #quick-personal :link:hover,
+#quickbar #quick-personal :visited:hover
+{
+ color: black;
+}
+
+#quickbar #topactions {
+ float: right;
+ clear: right;
+
+ font-size: 0.9em;
+ padding: 1em;
+}
+
+#quickbar #topactions form {
+ display: inline;
+ margin-left: 1em;
+}
+
+#quickbar #topactions form .button {
+ padding: 0 2px 0 2px;
+ font-size: 1em;
+ margin: 0;
+}
+
+#quickbar #topactions form .field {
+ padding: 1px;
+ font-size: 0.9em;
+}
+
+#quickbar #topactions form input.field {
+ padding: 3px;
+}
diff --git a/rt/html/NoAuth/css/3.5-default/ticket.css b/rt/html/NoAuth/css/3.5-default/ticket.css
new file mode 100644
index 000000000..5e8eeb78a
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/ticket.css
@@ -0,0 +1,57 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+.ticket-info-cfs .label {
+ vertical-align: top;
+}
+
+.ticket-info-cfs ul {
+ margin: 0;
+ padding: 0;
+ margin-left: 0.5em;
+ list-style: none;
+}
diff --git a/rt/html/NoAuth/css/3.5-default/titlebox.css b/rt/html/NoAuth/css/3.5-default/titlebox.css
new file mode 100644
index 000000000..79d8040a7
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/titlebox.css
@@ -0,0 +1,179 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+.titlebox {
+ margin-bottom: 1em;
+}
+
+.titlebox .titlebox-content {
+ margin-top: -1px;
+ padding: 1em 2em 0.5em 2em;
+ margin: 0;
+ /*margin: 1em 2em 0.5em 2em;*/
+}
+
+.titlebox th { font-size: 0.8em; }
+
+%# TRS: I wish there was a more elegant way to do this... I essentially need to
+%# select all elements X that do NOT have element Y as a descendant... which I can
+%# fake with the child selector of CSS2, but IE is stupid and does not support that.
+
+% for (qw(index
+% Search-Build
+% User-Prefs
+% Approvals
+% Admin-Users-Modify
+% SelfService
+% SelfService-Closed
+% ))
+% {
+#comp-<%$_%> .titlebox .titlebox-content,
+% }
+.titlebox .titlebox .titlebox-content
+{
+ background: #eee;
+ border-bottom: 1px solid #ccc;
+ border-right: 1px solid #ccc;
+ border-left: 0.5em solid #069;
+}
+
+#login-box .titlebox .titlebox-content
+{
+ background: none;
+ border: none;
+}
+
+.titlebox .titlebox-title {
+ position: relative;
+ font-weight: bold;
+ color: #930;
+ font-size: 1.2em;
+ padding: 0.2em 0 0.2em 4em;
+ border-bottom: 1px solid #069;
+}
+
+.titlebox .titlebox-title .right {
+ position: absolute;
+ top: 0.5em;
+ right: 1.5em;
+ font-size: 0.9em;
+ color: #888;
+}
+
+.titlebox .titlebox-title .right .selected { color: #930; }
+
+#body .titlebox .titlebox-title .right :link,
+#body .titlebox .titlebox-title .right :visited {
+ color: #888;
+}
+
+#body .titlebox .titlebox-title .right :link:hover,
+#body .titlebox .titlebox-title .right :visited:hover {
+ color: #930;
+}
+
+.titlebox .titlebox-title .widget a {
+ display: block;
+ padding-top: 1em;
+ width: 20px;
+
+ background: url(<%$RT::WebImagesURL%>/css/rollup-arrow.gif) no-repeat center center;
+
+ margin: 0;
+ text-indent: -9999px;
+
+ position: absolute;
+ top: 0.4em;
+ left: 0.75em;
+ float: left;
+
+%# Basically IE5 will see those crazy backslashes and prematurely end the rule.
+%# This allows values for IE 5's broken box model to be set before the hack and
+%# the real values to be set after. We also set voice-family back to whatever it
+%# would have been on the off chance it's actually used.
+ /* WIN IE5 hack */
+ height: 7px;
+ voice-family: "\"}\"";
+ voice-family: inherit;
+ height: 0;
+ overflow: hidden;
+}
+
+%# IE also doesn't support the child selector ">", so we can use it to set values
+%# that only other browsers will see (in this case, playing nice with Opera, which
+%# also suffers from the backslash hack above.)
+html>body .titlebox .titlebox-title .widget a {
+ height: 0;
+ overflow: hidden;
+}
+
+%# Compensates for IE's bad box model by hiding this rule from other browsers
+* html .titlebox .titlebox-title .widget a {
+ background-position: center 0.3em;
+ left: -3.5em;
+}
+
+.titlebox.rolled-up .titlebox-title .widget a {
+ background-image: url(<%$RT::WebImagesURL%>/css/rolldown-arrow.gif);
+}
+
+#body .titlebox .titlebox-title :link,
+#body .titlebox .titlebox-title :visited
+{
+ color: #930;
+ text-decoration: none;
+}
+
+#body .titlebox .titlebox-title :link:hover,
+#body .titlebox .titlebox-title :visited:hover
+{
+ text-decoration: underline;
+}
+
+.titlebox .titlebox-content hr.clear {
+ visibility: hidden;
+}
diff --git a/rt/html/NoAuth/css/3.5-default/transactions.css b/rt/html/NoAuth/css/3.5-default/transactions.css
new file mode 100755
index 000000000..e9decf8ee
--- /dev/null
+++ b/rt/html/NoAuth/css/3.5-default/transactions.css
@@ -0,0 +1,150 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+.ticket-transaction {
+ border-bottom: 1px solid #ddd;
+ border-right: 3px solid #069;
+}
+
+#ticket-history .ticket-transaction {
+ border-bottom-color: #ccc;
+}
+
+.ticket-transaction.even {
+ background: #eee;
+}
+.ticket-transaction.odd {
+ background: #fff;
+}
+
+
+.ticket-transaction .date {
+ font-size: 0.9em;
+ width: 10em;
+}
+
+.ticket-transaction .description {
+ font-weight: bold;
+ font-size: 0.9em;
+ text-align: left;
+}
+
+.ticket-transaction .actions {
+ text-align: right;
+ font-weight: bold;
+}
+
+.ticket-transaction .type {
+ background: #888;
+ width: 1.2em;
+ color: white;
+ text-align: center;
+ font-size: 1em;
+}
+
+#body .ticket-transaction .type :link,
+#body .ticket-transaction .type :visited
+{
+ color: white;
+ font-weight: normal;
+}
+
+.ticket-transaction.basics { border-color: #b32; }
+.ticket-transaction.basics .type { background: #b32; }
+.ticket-summary .ticket-info-basics .titlebox-content { border-left: 0.5em solid #b32; }
+
+.ticket-transaction.people { border-color: #48c; }
+.ticket-transaction.people .type { background: #48c; }
+.ticket-summary .ticket-info-people .titlebox-content { border-left: 0.5em solid #48c; }
+
+%# light green - #ad8
+.ticket-transaction.links { border-color: #316531; }
+.ticket-transaction.links .type { background: #316531; }
+.ticket-summary .ticket-info-links .titlebox-content { border-left: 0.5em solid #316531; }
+
+%# orange - #d71
+.ticket-transaction.dates { border-color: #633063; }
+.ticket-transaction.dates .type { background: #633063; }
+.ticket-summary .ticket-info-dates .titlebox-content { border-left: 0.5em solid #633063; }
+
+.ticket-transaction.message { border-color: #069; }
+.ticket-transaction.message .type { background: #069; }
+
+.ticket-transaction.other { border-color: #888; }
+
+.ticket-transaction td .message-header-value {
+ padding: 0;
+}
+
+.ticket-transaction td .message-header-key {
+ padding: 0 1em 0 1.5em;
+ font-weight: bold;
+}
+
+.ticket-transaction .downloadattachment {
+ float: right;
+ font-size: 0.9em;
+ text-align: right;
+}
+
+.ticket-transaction .messagebody {
+ clear: both;
+ padding-left: 3em;
+ padding-bottom: 1em;
+}
+
+%# Message stanza colors
+.message-stanza-depth-0 { color: #000; }
+.message-stanza-depth-1 { color: #600; }
+.message-stanza-depth-2 { color: #060; }
+.message-stanza-depth-3 { color: #006; }
+.message-stanza-depth-4 { color: #c00; }
+.message-stanza-depth-5 { color: #0c0; }
+.message-stanza-depth-6 { color: #00c; }
+.message-stanza-depth-7 { color: #f00; }
+.message-stanza-depth-8 { color: #0f0; }
+.message-stanza-depth-9 { color: #00f; }
diff --git a/rt/html/NoAuth/css/autohandler b/rt/html/NoAuth/css/autohandler
new file mode 100644
index 000000000..980e5f09d
--- /dev/null
+++ b/rt/html/NoAuth/css/autohandler
@@ -0,0 +1,53 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+RT::Interface::Web::StaticFileHeaders();
+$r->content_type('text/css');
+$m->call_next();
+return();
+</%init>
diff --git a/rt/html/NoAuth/css/dhandler b/rt/html/NoAuth/css/dhandler
new file mode 100644
index 000000000..4c8ba3405
--- /dev/null
+++ b/rt/html/NoAuth/css/dhandler
@@ -0,0 +1,30 @@
+<%ONCE>
+my $squisher;
+</%ONCE>
+<%INIT>
+my $arg = $m->dhandler_arg;
+my $path;
+if ( $arg =~ m{^(.*)-squished(\.[^\.]+)$} ) {
+ $path = $m->current_comp->dir_path .'/'. $1 . $2;
+}
+else {
+ return $m->decline;
+}
+
+$squisher = new RT::CSS::Squish unless $squisher;
+$squisher->{'mason'} = $m;
+
+$m->out( $squisher->concatenate( $path ) );
+
+package RT::CSS::Squish;
+use CSS::Squish '0.06';
+use base qw(CSS::Squish);
+sub file_handle {
+ my $self = shift;
+ my $file = shift;
+ my $content = $self->{'mason'}->scomp($file);
+ open my $fh, '<', \$content or die "$!";
+ return $fh;
+}
+
+</%INIT>
diff --git a/rt/html/NoAuth/css/print.css b/rt/html/NoAuth/css/print.css
new file mode 100644
index 000000000..40d23d0d6
--- /dev/null
+++ b/rt/html/NoAuth/css/print.css
@@ -0,0 +1,85 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+* {
+ float: none;
+ position: static;
+}
+
+body {
+ margin: 1em;
+ font-size: 10pt;
+}
+
+#body {
+ margin: 0;
+}
+
+#header h1 {
+ margin-bottom: 2em;
+}
+
+#header {
+ padding: 0 !important;
+}
+
+#quickbar,
+#nav,
+#header #page-menu,
+#header #actions-menu,
+.titlebox .title .widget,
+#footer
+{
+display: none;
+}
+
+a:link, a:visited {
+ background: transparent;
+ font-weight: bold !important;
+ text-decoration: underline !important;
+}
+
diff --git a/rt/html/NoAuth/images/autohandler b/rt/html/NoAuth/images/autohandler
new file mode 100644
index 000000000..720979830
--- /dev/null
+++ b/rt/html/NoAuth/images/autohandler
@@ -0,0 +1,28 @@
+<%INIT>
+&RT::Interface::Web::StaticFileHeaders();
+
+# This autohandler will spit out RT's images if the user hasn't
+# properly configured their webserver to stop RT from passing
+# images through the mason handler.
+my $file = $m->base_comp->source_file;
+
+
+my $type = "application/octet-stream";
+if ($file =~ /\.(gif|png|jpe?g)$/i) {
+ $type = "image/$1";
+ $type =~ s/jpg/jpeg/gi;
+}
+
+die "file not found" unless -f $file && -r _;
+
+$r->content_type($type);
+open my $fh, "<$file" or die "couldn't open file: $!";
+binmode($fh);
+{
+ local $/ = \16384;
+ $m->out($_) while (<$fh>);
+ $m->flush_buffer;
+}
+close $fh;
+$m->abort;
+</%INIT>
diff --git a/rt/html/NoAuth/images/bplogo.gif b/rt/html/NoAuth/images/bplogo.gif
new file mode 100644
index 000000000..1bb0adfb4
--- /dev/null
+++ b/rt/html/NoAuth/images/bplogo.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/cb-light.gif b/rt/html/NoAuth/images/css/cb-light.gif
new file mode 100644
index 000000000..d5e3059b0
--- /dev/null
+++ b/rt/html/NoAuth/images/css/cb-light.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/cb.gif b/rt/html/NoAuth/images/css/cb.gif
new file mode 100644
index 000000000..49a4a97b6
--- /dev/null
+++ b/rt/html/NoAuth/images/css/cb.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/cbr-b2g.gif b/rt/html/NoAuth/images/css/cbr-b2g.gif
new file mode 100644
index 000000000..6bca03d10
--- /dev/null
+++ b/rt/html/NoAuth/images/css/cbr-b2g.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/cbr-b2lb.gif b/rt/html/NoAuth/images/css/cbr-b2lb.gif
new file mode 100644
index 000000000..d207f846b
--- /dev/null
+++ b/rt/html/NoAuth/images/css/cbr-b2lb.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/cbr-gray.gif b/rt/html/NoAuth/images/css/cbr-gray.gif
new file mode 100644
index 000000000..d7327103a
--- /dev/null
+++ b/rt/html/NoAuth/images/css/cbr-gray.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/cbr-trans.gif b/rt/html/NoAuth/images/css/cbr-trans.gif
new file mode 100644
index 000000000..dc272ee5d
--- /dev/null
+++ b/rt/html/NoAuth/images/css/cbr-trans.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/cbr.gif b/rt/html/NoAuth/images/css/cbr.gif
new file mode 100644
index 000000000..eeb7ff444
--- /dev/null
+++ b/rt/html/NoAuth/images/css/cbr.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/ct-light.gif b/rt/html/NoAuth/images/css/ct-light.gif
new file mode 100644
index 000000000..55125b0fa
--- /dev/null
+++ b/rt/html/NoAuth/images/css/ct-light.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/ct.gif b/rt/html/NoAuth/images/css/ct.gif
new file mode 100644
index 000000000..d2ae8d8ae
--- /dev/null
+++ b/rt/html/NoAuth/images/css/ct.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/ctr-b2g.gif b/rt/html/NoAuth/images/css/ctr-b2g.gif
new file mode 100644
index 000000000..540e6d0ef
--- /dev/null
+++ b/rt/html/NoAuth/images/css/ctr-b2g.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/ctr-b2lb.gif b/rt/html/NoAuth/images/css/ctr-b2lb.gif
new file mode 100644
index 000000000..c98b18c9d
--- /dev/null
+++ b/rt/html/NoAuth/images/css/ctr-b2lb.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/ctr-gray.gif b/rt/html/NoAuth/images/css/ctr-gray.gif
new file mode 100644
index 000000000..8d5e5dd32
--- /dev/null
+++ b/rt/html/NoAuth/images/css/ctr-gray.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/ctr-trans.gif b/rt/html/NoAuth/images/css/ctr-trans.gif
new file mode 100644
index 000000000..bb316cf04
--- /dev/null
+++ b/rt/html/NoAuth/images/css/ctr-trans.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/ctr.gif b/rt/html/NoAuth/images/css/ctr.gif
new file mode 100644
index 000000000..d17e647c0
--- /dev/null
+++ b/rt/html/NoAuth/images/css/ctr.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/dark-arrow-up.png b/rt/html/NoAuth/images/css/dark-arrow-up.png
new file mode 100644
index 000000000..443096aa5
--- /dev/null
+++ b/rt/html/NoAuth/images/css/dark-arrow-up.png
Binary files differ
diff --git a/rt/html/NoAuth/images/css/dark-arrow.png b/rt/html/NoAuth/images/css/dark-arrow.png
new file mode 100644
index 000000000..a83500aad
--- /dev/null
+++ b/rt/html/NoAuth/images/css/dark-arrow.png
Binary files differ
diff --git a/rt/html/NoAuth/images/css/fieldbg-autocomplete.gif b/rt/html/NoAuth/images/css/fieldbg-autocomplete.gif
new file mode 100644
index 000000000..aa7eed061
--- /dev/null
+++ b/rt/html/NoAuth/images/css/fieldbg-autocomplete.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/light-arrow-up.png b/rt/html/NoAuth/images/css/light-arrow-up.png
new file mode 100644
index 000000000..c209d4335
--- /dev/null
+++ b/rt/html/NoAuth/images/css/light-arrow-up.png
Binary files differ
diff --git a/rt/html/NoAuth/images/css/light-arrow.png b/rt/html/NoAuth/images/css/light-arrow.png
new file mode 100644
index 000000000..575d4e5ec
--- /dev/null
+++ b/rt/html/NoAuth/images/css/light-arrow.png
Binary files differ
diff --git a/rt/html/NoAuth/images/css/rolldown-arrow.gif b/rt/html/NoAuth/images/css/rolldown-arrow.gif
new file mode 100644
index 000000000..3c296dcae
--- /dev/null
+++ b/rt/html/NoAuth/images/css/rolldown-arrow.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/css/rolldown-arrow.png b/rt/html/NoAuth/images/css/rolldown-arrow.png
new file mode 100644
index 000000000..33d8ab1e2
--- /dev/null
+++ b/rt/html/NoAuth/images/css/rolldown-arrow.png
Binary files differ
diff --git a/rt/html/NoAuth/images/css/rollup-arrow.gif b/rt/html/NoAuth/images/css/rollup-arrow.gif
new file mode 100644
index 000000000..f009ff4c6
--- /dev/null
+++ b/rt/html/NoAuth/images/css/rollup-arrow.gif
Binary files differ
diff --git a/rt/html/NoAuth/images/favicon.png b/rt/html/NoAuth/images/favicon.png
new file mode 100644
index 000000000..ed1ee37ff
--- /dev/null
+++ b/rt/html/NoAuth/images/favicon.png
Binary files differ
diff --git a/rt/html/NoAuth/images/small-logo.png b/rt/html/NoAuth/images/small-logo.png
new file mode 100644
index 000000000..1e415e6d8
--- /dev/null
+++ b/rt/html/NoAuth/images/small-logo.png
Binary files differ
diff --git a/rt/html/NoAuth/js/ahah.js b/rt/html/NoAuth/js/ahah.js
new file mode 100644
index 000000000..03ed12a97
--- /dev/null
+++ b/rt/html/NoAuth/js/ahah.js
@@ -0,0 +1,80 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+/*
+% $r->content_type('application/x-javascript');
+*/
+// Fetched from http://www.opendarwin.org/~drernie/src/ahah.js
+function ahah(url, target, delay) {
+ // document.getElementById(target).innerHTML = 'Loading <a href="'+url+'">'+url +'</a>...';
+ if (window.XMLHttpRequest) {
+ req = new XMLHttpRequest();
+ } else if (window.ActiveXObject) {
+ req = new ActiveXObject("Microsoft.XMLHTTP");
+ }
+ if (req != undefined) {
+ req.onreadystatechange = function() {ahahDone(url, target, delay);};
+ req.open("GET", url, true);
+ req.send("");
+ }
+}
+
+function ahahDone(url, target, delay) {
+ if (req.readyState == 4) { // only if req is "loaded"
+ if (req.status == 200) { // only if "OK"
+ document.getElementById(target).innerHTML = req.responseText;
+ } else {
+ document.getElementById(target).innerHTML="Error loading '"+url+"':\n"+req.statusText;
+ }
+ if (delay != undefined) {
+ setTimeout("ahah(url,target,delay)", delay); // resubmit after delay
+ //server should ALSO delay before responding
+ }
+ }
+}
+
+% $m->abort();
diff --git a/rt/html/NoAuth/js/autohandler b/rt/html/NoAuth/js/autohandler
new file mode 100644
index 000000000..fd1b90075
--- /dev/null
+++ b/rt/html/NoAuth/js/autohandler
@@ -0,0 +1,53 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+&RT::Interface::Web::StaticFileHeaders();
+$r->content_type('application/x-javascript');
+$m->call_next();
+return();
+</%init>
diff --git a/rt/html/NoAuth/js/cascaded.js b/rt/html/NoAuth/js/cascaded.js
new file mode 100644
index 000000000..79da4167f
--- /dev/null
+++ b/rt/html/NoAuth/js/cascaded.js
@@ -0,0 +1,66 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+function filter_cascade (id, val) {
+ var select = document.getElementById(id);
+ if (!select) { return };
+ var i;
+ var children = select.childNodes;
+ for (i in children) {
+ var style = children[i].style;
+ if (!style) { continue };
+ if (val == '') {
+ style.display = 'block';
+ continue;
+ }
+ if (children[i].label.substr(0, val.length) == val) {
+ style.display = 'block';
+ continue;
+ }
+ style.display = 'none';
+ }
+}
diff --git a/rt/html/NoAuth/js/class.js b/rt/html/NoAuth/js/class.js
new file mode 100644
index 000000000..9e4c70ea5
--- /dev/null
+++ b/rt/html/NoAuth/js/class.js
@@ -0,0 +1,62 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+/* by TKirby, released under GPL */
+
+ function _ClassSetup(Object) {
+ this.prototype = Object;
+ return this;
+ }
+
+ function Class(name) {
+ var _newclass_;
+ eval("window."+name+" = new Function('this."+name+".apply(this,arguments);');");
+ eval("window."+name+".define = _ClassSetup;");
+ eval("_newclass_ = window."+name+";");
+ return _newclass_;
+ }
+
diff --git a/rt/html/NoAuth/js/combobox.js b/rt/html/NoAuth/js/combobox.js
new file mode 100644
index 000000000..9225870b6
--- /dev/null
+++ b/rt/html/NoAuth/js/combobox.js
@@ -0,0 +1,265 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+function ComboBox_InitWith(n) {
+ if ( typeof( window.addEventListener ) != "undefined" ) {
+ window.addEventListener("load", ComboBox_Init(n), false);
+ } else if ( typeof( window.attachEvent ) != "undefined" ) {
+ window.attachEvent("onload", ComboBox_Init(n));
+ } else {
+ ComboBox_Init(n)();
+ }
+}
+function ComboBox_Init(n) {
+ return function () {
+ if ( ComboBox_UplevelBrowser( n ) ) {
+ ComboBox_Load( n );
+ }
+ }
+}
+function ComboBox_UplevelBrowser( n ) {
+ if( typeof( document.getElementById ) == "undefined" ) return false;
+ var combo = document.getElementById( n + "_Container" );
+ if( combo == null || typeof( combo ) == "undefined" ) return false;
+ if( typeof( combo.style ) == "undefined" ) return false;
+ if( typeof( combo.innerHTML ) == "undefined" ) return false;
+ return true;
+}
+function ComboBox_Load( comboId ) {
+ var combo = document.getElementById( comboId + "_Container" );
+ var button = document.getElementById( comboId + "_Button" );
+ var list = document.getElementById( comboId + "_List" );
+ var text = document.getElementById( comboId );
+
+
+ combo.List = list;
+ combo.Button = button;
+ combo.Text = text;
+
+ button.Container = combo;
+ button.Toggle = ComboBox_ToggleList;
+ button.onclick = button.Toggle;
+ button.onmouseover = function(e) { this.Container.List.DisableBlur(e); };
+ button.onmouseout = function(e) { this.Container.List.EnableBlur(e); };
+ button.innerHTML = "\u25BC";
+ button.onselectstart = function(e){ return false; };
+ button.style.height = ( list.offsetHeight - 4 ) + "px";
+
+ text.Container = combo;
+ text.TypeDown = ComboBox_TextTypeDown;
+ text.KeyAccess = ComboBox_TextKeyAccess;
+ text.onkeyup = function(e) { this.KeyAccess(e); this.TypeDown(e); };
+ text.style.width = ( list.offsetWidth ) + "px";
+
+ list.Container = combo;
+ list.Show = ComboBox_ShowList;
+ list.Hide = ComboBox_HideList;
+ list.EnableBlur = ComboBox_ListEnableBlur;
+ list.DisableBlur = ComboBox_ListDisableBlur;
+ list.Select = ComboBox_ListItemSelect;
+ list.ClearSelection = ComboBox_ListClearSelection;
+ list.KeyAccess = ComboBox_ListKeyAccess;
+ list.FireTextChange = ComboBox_ListFireTextChange;
+ list.onchange = null;
+ list.onclick = function(e){ this.Select(e); this.ClearSelection(); this.FireTextChange(); };
+ list.onkeyup = function(e) { this.KeyAccess(e); };
+ list.EnableBlur(null);
+ list.style.position = "absolute";
+ list.size = ComboBox_GetListSize( list );
+ list.IsShowing = true;
+ list.Hide();
+
+}
+function ComboBox_InitEvent( e ) {
+ if( typeof( e ) == "undefined" && typeof( window.event ) != "undefined" ) e = window.event;
+ if( e == null ) e = new Object();
+ return e;
+}
+function ComboBox_ListClearSelection() {
+ if ( typeof( this.Container.Text.createTextRange ) == "undefined" ) return;
+ var rNew = this.Container.Text.createTextRange();
+ rNew.moveStart('character', this.Container.Text.value.length) ;
+ rNew.select();
+}
+function ComboBox_GetListSize( theList ) {
+ ComboBox_EnsureListSize( theList );
+ return theList.listSize;
+}
+function ComboBox_EnsureListSize( theList ) {
+ if ( typeof( theList.listSize ) == "undefined" ) {
+ if( typeof( theList.getAttribute ) != "undefined" ) {
+ if( theList.getAttribute( "listSize" ) != null && theList.getAttribute( "listSize" ) != "" ) {
+ theList.listSize = theList.getAttribute( "listSize" );
+ return;
+ }
+ }
+ if( theList.options.length > 0 ) {
+ theList.listSize = theList.options.length;
+ return;
+ }
+ theList.listSize = 4;
+ }
+}
+function ComboBox_ListKeyAccess(e) { //Make enter/space and escape do the right thing :)
+ e = ComboBox_InitEvent( e );
+ if( e.keyCode == 13 || e.keyCode == 32 ) {
+ this.Select();
+ return;
+ }
+ if( e.keyCode == 27 ) {
+ this.Hide();
+ this.Container.Text.focus();
+ return;
+ }
+}
+function ComboBox_TextKeyAccess(e) { //Make alt+arrow expand the list
+ e = ComboBox_InitEvent( e );
+ if( e.altKey && (e.keyCode == 38 || e.keyCode == 40) ) {
+ this.Container.List.Show();
+ }
+}
+function ComboBox_TextTypeDown(e) { //Make the textbox do a type-down on the list
+ e = ComboBox_InitEvent( e );
+ var items = this.Container.List.options;
+ if( this.value == "" ) return;
+ var ctrlKeys = Array( 8, 46, 37, 38, 39, 40, 33, 34, 35, 36, 45, 16, 20 );
+ for( var i = 0; i < ctrlKeys.length; i++ ) {
+ if( e.keyCode == ctrlKeys[i] ) return;
+ }
+ for( var i = 0; i < items.length; i++ ) {
+ var item = items[i];
+ if( item.text.toLowerCase().indexOf( this.value.toLowerCase() ) == 0 ) {
+ this.Container.List.selectedIndex = i;
+ if ( typeof( this.Container.Text.createTextRange ) != "undefined" ) {
+ this.Container.List.Select();
+ }
+ break;
+ }
+ }
+}
+function ComboBox_ListFireTextChange() {
+ var textOnChange = this.Container.Text.onchange;
+ if ( textOnChange != null && typeof(textOnChange) == "function" ) {
+ textOnChange();
+ }
+}
+function ComboBox_ListEnableBlur(e) {
+ this.onblur = this.Hide;
+}
+function ComboBox_ListDisableBlur(e) {
+ this.onblur = null;
+}
+function ComboBox_ListItemSelect(e) {
+ if( this.options.length > 0 ) {
+ var text = this.Container.Text;
+ var oldValue = text.value;
+ var newValue = this.options[ this.selectedIndex ].text;
+ text.value = newValue;
+ if ( typeof( text.createTextRange ) != "undefined" ) {
+ if (newValue != oldValue) {
+ var rNew = text.createTextRange();
+ rNew.moveStart('character', oldValue.length) ;
+ rNew.select();
+ }
+ }
+ }
+ this.Hide();
+ this.Container.Text.focus();
+}
+function ComboBox_ToggleList(e) {
+ if( this.Container.List.IsShowing == true ) {
+ this.Container.List.Hide();
+ } else {
+ this.Container.List.Show();
+ }
+}
+function ComboBox_ShowList(e) {
+ if ( !this.IsShowing && !this.disabled ) {
+ this.style.width = ( this.Container.offsetWidth ) + "px";
+ this.style.top = ( this.Container.offsetHeight + ComboBox_RecursiveOffsetTop(this.Container,true) ) + "px";
+ this.style.left = ( ComboBox_RecursiveOffsetLeft(this.Container,true) + 1 ) + "px";
+ ComboBox_SetVisibility(this,true);
+ this.focus();
+ this.IsShowing = true;
+ }
+}
+function ComboBox_HideList(e) {
+ if( this.IsShowing ) {
+ ComboBox_SetVisibility(this,false);
+ this.IsShowing = false;
+ }
+}
+function ComboBox_SetVisibility(theList, isVisible) {
+ setVisibility(theList, isVisible);
+}
+function ComboBox_RecursiveOffsetTop(thisObject,isFirst) {
+ if(thisObject.offsetParent) {
+ if ( thisObject.style.position == "absolute" && !isFirst && typeof(document.designMode) != "undefined" ) {
+ return 0;
+ }
+ return (thisObject.offsetTop + ComboBox_RecursiveOffsetTop(thisObject.offsetParent,false));
+ } else {
+ return thisObject.offsetTop;
+ }
+}
+function ComboBox_RecursiveOffsetLeft(thisObject,isFirst) {
+ if(thisObject.offsetParent) {
+ if ( thisObject.style.position == "absolute" && !isFirst && typeof(document.designMode) != "undefined" ) {
+ return 0;
+ }
+ return (thisObject.offsetLeft + ComboBox_RecursiveOffsetLeft(thisObject.offsetParent,false));
+ } else {
+ return thisObject.offsetLeft;
+ }
+}
+function ComboBox_SimpleAttach(selectElement,textElement) {
+ textElement.value = selectElement.options[ selectElement.options.selectedIndex ].text;
+ var textOnChange = textElement.onchange;
+ if ( textOnChange != null && typeof( textOnChange ) == "function" ) {
+ textOnChange();
+ }
+}
diff --git a/rt/html/NoAuth/js/list.js b/rt/html/NoAuth/js/list.js
new file mode 100644
index 000000000..9753b9771
--- /dev/null
+++ b/rt/html/NoAuth/js/list.js
@@ -0,0 +1,159 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+/* by TKirby, released under GPL */
+/* Define the "list" Class */
+Class("list").define({
+ name : null,
+ xml : null,
+ sels : null,
+ list : function (src, esrc, name) { this.init(src, esrc, name); },
+ read : function () {
+ var i = 0;
+ if(this.xml.readyState!=4) { setTimeout(this.name+".read()", 100); }
+ else if(this.xml.status!=200) alert("Document not available.");
+ else {
+ var doc = this.xml.responseXML;
+ var nNode = null;
+ if(doc.childNodes[0].nodeName=="parseerror") alert("Parse Error.");
+ doc = doc.getElementsByTagName("list")[0];
+ for(i=0;i<doc.childNodes.length;i++) {
+ if(doc.childNodes[i].childNodes.length>0) {
+ nNode = document.createElement("option");
+ nNode.appendChild(document.createTextNode(doc.childNodes[i].childNodes[0].nodeValue));
+ this.sels[0].appendChild(nNode);
+ }
+ }
+ }
+ },
+
+ init : function (src,esrc,name) {
+ if(!src) return;
+ this.name = name;
+ this.sels = new Array();
+ var i = 0;
+ for(i=0;i<src.childNodes.length;i++) {
+ if(src.childNodes[i].nodeName=="select" || src.childNodes[i].nodeName=="SELECT") {
+ this.sels.push(src.childNodes[i]);
+ }
+
+ if((src.childNodes[i].nodeName=="input" || src.childNodes[i].nodeName=="INPUT")
+ && (src.childNodes[i].name=="fromjs")) {
+ src.childNodes[i].value = 1;
+ }
+
+ if((src.childNodes[i].nodeName=="input" || src.childNodes[i].nodeName=="INPUT")
+ && (src.childNodes[i].type=="submit" || src.childNodes[i].type=="SUBMIT")) {
+
+ if (src.childNodes[i].name.indexOf("Save") < 0) {
+ var tmp = document.createElement("input");
+ tmp.type = "button";
+ tmp.name = src.childNodes[i].name;
+ tmp.value = src.childNodes[i].value;
+ src.replaceChild(tmp,src.childNodes[i]);
+ }
+
+ if(src.childNodes[i].name=="add")
+ src.childNodes[i].onclick = new Function(this.name+".add();");
+ if(src.childNodes[i].name=="remove")
+ src.childNodes[i].onclick = new Function(this.name+".remove();");
+ if(src.childNodes[i].name=="moveup")
+ src.childNodes[i].onclick = new Function(this.name+".moveup();");
+ if(src.childNodes[i].name=="movedown")
+ src.childNodes[i].onclick = new Function(this.name+".movedown();");
+ }
+ }
+ if (esrc) {
+ this.xml = (window.navigator.appName!="Microsoft Internet Explorer"
+ ?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP"));
+ this.xml.open("GET", esrc);
+ this.xml.send("");
+ setTimeout(this.name+".read()", 100);
+ }
+ },
+
+ add : function() {
+ var i, j = 0;
+ var dNode = null;
+ for(i=0;i<this.sels[0].length;i++) if(this.sels[0][i].selected) {
+ for(j=0;j<this.sels[1].length;j++) if(this.sels[1][j].value==this.sels[0][i].value) break;
+ if(j==this.sels[1].length) dNode = this.sels[0][i].cloneNode(true),
+ this.sels[1].appendChild(dNode);
+ }
+ },
+
+ moveup : function() { this.move(-1); },
+ movedown : function() { this.move(1); },
+ move : function(v) {
+ var i = 0;
+ if(v<0) for(i=0;i<this.sels[1].length;i++) this.moveOne(v, i);
+ else if(v>0) for(i=this.sels[1].length-1;i>=0;i--)this.moveOne(v, i);
+ },
+
+ moveOne : function(v, i) {
+ var ins = v + i;
+ if(ins<0 || ins>=this.sels[1].length) return;
+ if(this.sels[1][ins].selected) return;
+ if(this.sels[1][i].selected) {
+ Node = this.sels[1][i];
+ this.sels[1].removeChild(Node);
+ this.sels[1].insertBefore(Node, this.sels[1][ins]);
+ }
+ },
+
+ remove : function() {
+ var i = 0;
+ for(i=this.sels[1].length-1;i>=0;i--) if(this.sels[1][i].selected)
+ this.sels[1].removeChild(this.sels[1][i]);
+ },
+
+ selectAll: function() {
+ var i = 0;
+ for(i=0;i<this.sels[0].length;i++) this.sels[0][i].selected = false;
+ for(i=0;i<this.sels[1].length;i++) this.sels[1][i].selected = true;
+ }
+});
diff --git a/rt/html/NoAuth/js/scriptaculous/controls.js b/rt/html/NoAuth/js/scriptaculous/controls.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/rt/html/NoAuth/js/scriptaculous/controls.js
diff --git a/rt/html/NoAuth/js/scriptaculous/effects.js b/rt/html/NoAuth/js/scriptaculous/effects.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/rt/html/NoAuth/js/scriptaculous/effects.js
diff --git a/rt/html/NoAuth/js/scriptaculous/prototype.js b/rt/html/NoAuth/js/scriptaculous/prototype.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/rt/html/NoAuth/js/scriptaculous/prototype.js
diff --git a/rt/html/NoAuth/js/scriptaculous/scriptaculous.js b/rt/html/NoAuth/js/scriptaculous/scriptaculous.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/rt/html/NoAuth/js/scriptaculous/scriptaculous.js
diff --git a/rt/html/NoAuth/js/titlebox-state.js b/rt/html/NoAuth/js/titlebox-state.js
new file mode 100644
index 000000000..8950f9e62
--- /dev/null
+++ b/rt/html/NoAuth/js/titlebox-state.js
@@ -0,0 +1,83 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+function createCookie(name,value,days) {
+ var path = "<%$RT::WebPath%>" ? "<%$RT::WebPath%>" : "/";
+
+ if (days) {
+ var date = new Date();
+ date.setTime(date.getTime()+(days*24*60*60*1000));
+ var expires = "; expires="+date.toGMTString();
+ }
+ else
+ expires = "";
+
+ document.cookie = name+"="+value+expires+"; path="+path;
+}
+
+function loadTitleBoxStates() {
+ var cookies = document.cookie.split(/;\s*/);
+ var len = cookies.length;
+
+ for (var i = 0; i < len; i++) {
+ var c = cookies[i].split('=');
+
+ if (c[0].match(/^TitleBox--/)) {
+ var e = document.getElementById(c[0]);
+ if (e) {
+ var e2 = e.parentNode;
+
+ if (c[1] != 0) {
+ set_rollup_state(e,e2,'shown');
+ }
+ else {
+ set_rollup_state(e,e2,'hidden');
+ }
+ }
+ }
+ }
+}
diff --git a/rt/html/NoAuth/js/util.js b/rt/html/NoAuth/js/util.js
new file mode 100644
index 000000000..0de071ad3
--- /dev/null
+++ b/rt/html/NoAuth/js/util.js
@@ -0,0 +1,250 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+/* $(...)
+ Returns DOM node or array of nodes (if more then one argument passed).
+ If argument is node object allready then do nothing.
+ // Stolen from Prototype
+*/
+function $() {
+ var elements = new Array();
+
+ for (var i = 0; i < arguments.length; i++) {
+ var element = arguments[i];
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+
+ if (arguments.length == 1)
+ return element;
+
+ elements.push(element);
+ }
+
+ return elements;
+}
+
+/* Visibility */
+
+function show(id) { delClass( id, 'hidden' ) }
+function hide(id) { addClass( id, 'hidden' ) }
+
+function hideshow(id) { return toggleVisibility( id ) }
+function toggleVisibility(id) {
+ var e = $(id);
+
+ if ( e.className.match( /\bhidden\b/ ) )
+ show(e);
+ else
+ hide(e);
+
+ return false;
+}
+
+function setVisibility(id, visibility) {
+ if ( visibility ) show(id);
+ else hide(id);
+}
+
+function switchVisibility(id1, id2) {
+ // Show both and then hide the one we want
+ show(id1);
+ show(id2);
+ hide(id2);
+ return false;
+}
+
+/* Classes */
+
+function addClass(id, value) {
+ var e = $(id);
+ if ( e.className.match( new RegExp('\b'+ value +'\b') ) )
+ return;
+ e.className += e.className? ' '+value : value;
+}
+
+function delClass(id, value) {
+ var e = $(id);
+ e.className = e.className.replace( new RegExp('\\s?\\b'+ value +'\\b', 'g'), '' );
+}
+
+/* Rollups */
+
+function rollup(id) {
+ var e = $(id);
+ var e2 = e.parentNode;
+
+ if (e.className.match(/\bhidden\b/)) {
+ set_rollup_state(e,e2,'shown');
+ createCookie(id,1,365);
+ }
+ else {
+ set_rollup_state(e,e2,'hidden');
+ createCookie(id,0,365);
+ }
+ return false;
+}
+
+function set_rollup_state(e,e2,state) {
+ if (e && e2) {
+ if (state == 'shown') {
+ show(e);
+ delClass( e2, 'rolled-up' );
+ }
+ else if (state == 'hidden') {
+ hide(e);
+ addClass( e2, 'rolled-up' );
+ }
+ }
+}
+
+
+/* onload handlers */
+
+var onLoadStack = new Array();
+var onLoadLastStack = new Array();
+var onLoadExecuted = 0;
+
+function onLoadHook(commandStr) {
+ if(typeof(commandStr) == "string") {
+ onLoadStack[ onLoadStack.length ] = commandStr;
+ return true;
+ }
+ return false;
+}
+
+// some things *really* need to be done after everything else
+function onLoadLastHook(commandStr) {
+ if(typeof(commandStr) == "string"){
+ onLoadLastStack[onLoadLastStack.length] = commandStr;
+ return true;
+ }
+ return false;
+}
+
+function doOnLoadHooks() {
+ if(onLoadExecuted) return;
+
+ var i;
+ for ( i in onLoadStack ) {
+ eval( onLoadStack[i] );
+ }
+ for ( i in onLoadLastStack ) {
+ eval( onLoadLastStack[i] );
+ }
+ onLoadExecuted = 1;
+}
+
+window.onload = doOnLoadHooks;
+
+/* calendar functions */
+
+function openCalWindow(field) {
+ var objWindow = window.open('<%$RT::WebPath%>/Helpers/CalPopup.html?field='+field,
+ 'RT_Calendar',
+ 'height=235,width=285,scrollbars=1');
+ objWindow.focus();
+}
+
+function createCalendarLink(input) {
+ var e = $(input);
+ if (e) {
+ var link = document.createElement('a');
+ link.setAttribute('href', '#');
+
+ clickevent = function clickevent(e) { openCalWindow(input); return false; };
+ if (! addEvent(link, "click", clickevent)) {
+ return false;
+ }
+
+ var text = document.createTextNode('<% loc("Choose a date") %>');
+ link.appendChild(text);
+
+ var space = document.createTextNode(' ');
+
+ e.parentNode.insertBefore(link, e.nextSibling);
+ e.parentNode.insertBefore(space, e.nextSibling);
+
+ return true;
+ }
+ return false;
+}
+
+/* other utils */
+
+function focusElementById(id) {
+ var e = $(id);
+ if (e) e.focus();
+}
+
+function updateParentField(field, value) {
+ if (window.opener) {
+ window.opener.$(field).value = value;
+ window.close();
+ }
+}
+
+function addEvent(obj, sType, fn) {
+ if (obj.addEventListener) {
+ obj.addEventListener(sType, fn, false);
+ } else if (obj.attachEvent) {
+ var r = obj.attachEvent("on"+sType, fn);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+function setCheckbox(form, name, val) {
+ var myfield = form.getElementsByTagName('input');
+ for ( var i = 0; i < myfield.length; i++ ) {
+ if ( name && myfield[i].name != name ) continue;
+ if ( myfield[i].type != 'checkbox' ) continue;
+
+ myfield[i].checked = val;
+ }
+}
+
diff --git a/rt/html/Prefs/Elements/Tabs b/rt/html/Prefs/Elements/Tabs
new file mode 100644
index 000000000..e706d9a73
--- /dev/null
+++ b/rt/html/Prefs/Elements/Tabs
@@ -0,0 +1,72 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /User/Elements/Tabs,
+ subtabs => $tabs,
+ current_tab => 'Prefs/MyRT.html',
+ current_subtab => $current_subtab,
+ Title => $Title &>
+
+<%INIT>
+my $tabs;
+unless ($Searches) {
+ $Searches = [$m->comp("/Search/Elements/SearchesForObject", Object => RT::System->new($session{'CurrentUser'}))];
+}
+
+$tabs->{a} = { title => loc('Quick search'),
+ path => 'Prefs/Quicksearch.html' };
+for my $search (@$Searches) {
+ $tabs->{$search->[0]} = { title => $search->[0],
+ path => "Prefs/Search.html?".$m->comp('/Elements/QueryString', name => ref($search->[1]).'-'.$search->[1]->Id) };
+}
+</%INIT>
+<%ARGS>
+$GroupObj => undef
+$current_subtab => undef
+$Title => undef
+$Searches => undef
+</%ARGS>
diff --git a/rt/html/Prefs/MyRT.html b/rt/html/Prefs/MyRT.html
new file mode 100644
index 000000000..ba35fd214
--- /dev/null
+++ b/rt/html/Prefs/MyRT.html
@@ -0,0 +1,151 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title &>
+<& /Prefs/Elements/Tabs,
+ current_tab => 'Prefs/MyRT.html',
+ Title => $title,
+ Searches => \@sys_searches
+&>
+
+<& /Widgets/SelectionBox:header, nojs => 1 &>
+
+<& /Elements/ListActions, actions => \@actions &>
+<br />
+
+<form method="post" action="MyRT.html">
+<input type="hidden" name="Reset" value="1" />
+<input type="submit" class="button" value="<%loc('Reset to default')%>">
+</form>
+
+<br />
+
+% for my $pane (@panes) {
+<&|/Widgets/TitleBox, title => loc('RT at a glance').': '.loc($pane->{Name}), bodyclass => "" &>
+<& /Widgets/SelectionBox:show, self => $pane, nojs => 1 &></&>
+<br />
+% }
+<&|/Widgets/TitleBox, title => loc('Options'), bodyclass => "" &>
+<form method="post" action="MyRT.html">
+ <&|/l&>Rows per box</&>:<input name="SummaryRows" value="<% $ARGS{SummaryRows} %>" /> <input type="submit" class="button" value="<%loc('Save')%>" />
+</form>
+</&>
+<%INIT>
+my @actions;
+
+my $title = loc("Customize").' '.loc("RT at a glance");
+my $user = $session{'CurrentUser'}->UserObj;
+
+if ($ARGS{Reset}) {
+ $user->SetPreferences('HomepageSettings', {});
+ delete $session{'my_rt_portlets'};
+}
+
+unless (exists $session{'my_rt_portlets'}) {
+ my ($default_portlets) = RT::System->new($session{'CurrentUser'})->Attributes->Named('HomepageSettings');
+ my $portlets = $default_portlets ? $default_portlets->Content : {};
+ $session{'my_rt_portlets'} = $user->Preferences('HomepageSettings', $portlets);
+}
+if ($ARGS{SummaryRows}) {
+ $user->SetPreferences('SummaryRows', $ARGS{SummaryRows});
+ push @actions, loc ('Preferences saved for [_1].', loc('summary rows'));
+}
+else {
+ $ARGS{SummaryRows} = $user->Preferences('SummaryRows', $RT::DefaultSummaryRows);
+}
+
+
+my $portlets = $session{'my_rt_portlets'};
+
+my %allowed_components = map {$_ => 1} @{$RT::HomepageComponents};
+my @items;
+
+push @items, map {["component-$_", $_]} sort keys %allowed_components;
+
+my $sys = RT::System->new($session{'CurrentUser'});
+my @objs = ($sys);
+
+push @objs, RT::SavedSearches->new( $session{CurrentUser} )->_PrivacyObjects
+ if $session{'CurrentUser'}->HasRight( Right => 'LoadSavedSearch',
+ Object => $RT::System );
+
+my @sys_searches;
+for my $object (@objs) {
+ for ($m->comp("/Search/Elements/SearchesForObject", Object => $object)) {
+ my ($desc, $search) = @$_;
+ my $SearchType = $search->Content->{'SearchType'} || 'Ticket';
+ if ($object eq $sys && $SearchType eq 'Ticket') {
+ push @items, ["system-$desc", $desc];
+ push @sys_searches, [$desc, $search];
+ }
+ else {
+ my $oid = ref($object).'-'.$object->Id.'-SavedSearch-'.$search->Id;
+ my $type = ($SearchType eq 'Ticket')
+ ? 'Saved Search' : $SearchType; # loc
+ push @items, ["saved-$oid", loc($type).": $desc"];
+ }
+ }
+}
+
+my @panes = $m->comp(
+ '/Admin/Elements/ConfigureMyRT',
+ panes => ['body', 'summary'],
+ Action => 'MyRT.html',
+ items => \@items,
+ current_portlets => $portlets,
+ OnSave => sub {
+ my ( $conf, $pane ) = @_;
+ $user->SetPreferences( 'HomepageSettings', $conf );
+ push @actions, loc( 'Preferences saved for [_1].', $pane );
+ delete $session{'my_rt_portlets'};
+ }
+);
+
+$m->comp( '/Widgets/SelectionBox:process', %ARGS, self => $_, nojs => 1 )
+ for @panes;
+
+</%INIT>
diff --git a/rt/html/Prefs/Quicksearch.html b/rt/html/Prefs/Quicksearch.html
new file mode 100644
index 000000000..f4becc74a
--- /dev/null
+++ b/rt/html/Prefs/Quicksearch.html
@@ -0,0 +1,96 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title &>
+<& /Prefs/Elements/Tabs,
+ current_tab => 'Prefs/MyRT.html',
+ current_subtab => 'Prefs/Quicksearch.html',
+ Title => $title
+&>
+<& /Elements/ListActions, actions => \@actions &>
+<h1><&|/l&>Select queues to be displayed on the "RT at a glance" page</&></h1>
+<form method="post" action="Quicksearch.html" name="Preferences">
+<ul>
+% for my $queue (@queues) {
+<li><input type="checkbox" class="checkbox" name="Want-<%$queue->Name%>" value="1"
+% unless ($unwanted->{$queue->Name}) {
+checked
+% }
+/><%$queue->Name%>: <%$queue->Description%></li>
+% }
+</ul>
+<& /Elements/Submit, Caption => loc("Save Changes"), Label => loc('Save'), Name => 'Save'&>
+
+</form>
+
+<%INIT>
+my @actions;
+my $title = loc("Customize").' '.loc("Quick search");
+# The queue list is not loaded from cache, so it might be a bit inconsistent
+my $user = $session{'CurrentUser'}->UserObj;
+my $unwanted = $user->Preferences('QuickSearch', {});
+my $Queues = RT::Queues->new($session{'CurrentUser'});
+$Queues->UnLimit;
+my @queues = grep {$_->CurrentUserHasRight('ShowTicket')} @{$Queues->ItemsArrayRef};
+
+if ($ARGS{'Save'}) {
+ for my $queue (@queues) {
+ if ($ARGS{"Want-".$queue->Name}) {
+ delete $unwanted->{$queue->Name};
+ }
+ else {
+ ++$unwanted->{$queue->Name};
+ }
+ }
+
+ $user->SetPreferences('QuickSearch', $unwanted);
+ push @actions, loc ('Preferences saved.');
+ # Let QueueSummary rebuild the cache
+ delete $session{'quick_search_queues'};
+}
+
+</%INIT>
diff --git a/rt/html/Prefs/Search.html b/rt/html/Prefs/Search.html
new file mode 100644
index 000000000..8754d535d
--- /dev/null
+++ b/rt/html/Prefs/Search.html
@@ -0,0 +1,108 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title &>
+<& /Prefs/Elements/Tabs,
+ current_tab => 'Prefs/MyRT.html',
+# current_subtab => 'Prefs/Search.html?name='.$m->comp('/Elements/QueryString', name => $ARGS{name}),
+ current_subtab => 'Prefs/Search.html?name='.$ARGS{name},
+ Title => $title
+&>
+<& /Elements/ListActions, actions => \@actions &>
+% if ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'SuperUser')) {
+<p>
+ <&|/l&>You can also edit the predefined search itself</&>:
+ <a href="<% $RT::WebPath.'/Search/Build.html?'.
+ $m->comp('/Elements/QueryString',
+ LoadSavedSearch => 'RT::System-1-SavedSearch-'.$id) %>"><% $search->Name %></a>
+</p>
+% }
+
+<form method="post" action="Search.html" name="BuildQuery">
+<input type="hidden" name="name" value="<%$ARGS{name}%>" class="hidden" />
+<input type="hidden" name="Format" value="<%$ARGS{Format}%>" class="hidden" />
+
+<& /Search/Elements/DisplayOptions, %$SearchArg, %ARGS,
+ AvailableColumns => $AvailableColumns, CurrentFormat => $CurrentFormat &>
+<& /Elements/Submit, Caption => loc("Save"), Label => loc('Save'), Name => 'Save'&>
+
+</form>
+
+<%INIT>
+my @actions;
+my $title = loc("Customize").' ';
+
+my @fields = qw(Format Order OrderBy RowsPerPage);
+my ($class, $id) = ( $ARGS{name} =~ m/^(.*)-(\d+)$/ );
+
+Abort('No search specified')
+ unless $class eq 'RT::Attribute';
+
+my $search = $class->new ($session{'CurrentUser'});
+$search->LoadById ($id);
+$title .= loc ($search->Description, loc ('"N"'));
+my $user = $session{'CurrentUser'}->UserObj;
+my $SearchArg = $user->Preferences($search, $search->Content);
+for (@fields) {
+ $ARGS{$_} = $SearchArg->{$_} unless defined $ARGS{$_};
+}
+$ARGS{'Order'} = join '|', grep defined && /\S/, (ref $ARGS{'Order'})? @{$ARGS{'Order'}}: $ARGS{'Order'};
+$ARGS{'OrderBy'} = join '|', grep defined && /\S/, (ref $ARGS{'OrderBy'})? @{$ARGS{'OrderBy'}}: $ARGS{'OrderBy'};
+
+my ( $AvailableColumns, $CurrentFormat );
+( $ARGS{Format}, $AvailableColumns, $CurrentFormat ) = $m->comp(
+ '/Search/Elements/BuildFormatString',
+ cfqueues => {}, %ARGS
+);
+
+if ($ARGS{'Save'}) {
+ my $hash = {map { $_ => $ARGS{$_}} @fields};
+ my $pref = $user->SetPreferences ($search, $hash);
+ push @actions, loc ('Preferences saved.');
+}
+
+</%INIT>
diff --git a/rt/html/Prefs/SearchOptions.html b/rt/html/Prefs/SearchOptions.html
new file mode 100644
index 000000000..7cc71b0cd
--- /dev/null
+++ b/rt/html/Prefs/SearchOptions.html
@@ -0,0 +1,114 @@
+
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc("Search Preferences") &>
+<& /User/Elements/Tabs,
+ current_tab => "Prefs/SearchOptions.html",
+ Title => loc("Search Preferences")
+&>
+
+<form method="post" action="SearchOptions.html">
+<input type="hidden" class="hidden" name="Format" value="<%$Format%>" />
+ <& /Search/Elements/DisplayOptions, %ARGS,
+ Format=> $Format,
+ AvailableColumns => $AvailableColumns,
+ CurrentFormat => $CurrentFormat,
+ RowsPerPage => $RowsPerPage,
+ OrderBy => $OrderBy,
+ Order => $Order &>
+
+<& /Elements/Submit, Name => 'SavePreferences', Label => loc('Save Changes') &>
+</form>
+
+<%INIT>
+
+# {{{ If we're saving search preferences, do that now
+$Order = join '|', grep defined && /\S/, (ref $Order)? @{$Order}: $Order;
+$OrderBy = join '|', grep defined && /\S/, (ref $OrderBy)? @{$OrderBy}: $OrderBy;
+
+if ($ARGS{'SavePreferences'}) {
+ $session{'CurrentUser'}->UserObj->SetPreferences("SearchDisplay",
+ {
+ Format => $Format,
+ Order => $Order,
+ OrderBy => $OrderBy,
+ RowsPerPage => $RowsPerPage,
+ });
+}
+
+# }}}
+
+
+
+
+
+
+
+# Read from user preferences
+my $prefs = $session{'CurrentUser'}->UserObj->Preferences("SearchDisplay") || {};
+
+$Format ||= $prefs->{'Format'};
+$Order ||= $prefs->{'Order'} || 'ASC';
+$OrderBy ||= $prefs->{'OrderBy'} || 'id';
+($RowsPerPage = defined( $prefs->{'RowsPerPage'} ) ? $prefs->{'RowsPerPage'} : 50) unless defined ($RowsPerPage);
+
+my ( $AvailableColumns, $CurrentFormat );
+( $Format, $AvailableColumns, $CurrentFormat ) = $m->comp(
+ '/Search/Elements/BuildFormatString',
+ %ARGS, Format => $Format
+);
+</%INIT>
+
+<%ARGS>
+$Format => undef
+$Description => undef
+$Order => undef
+$OrderBy => undef
+$RowsPerPage => undef
+</%ARGS>
+
diff --git a/rt/html/REST/1.0/Forms/queue/default b/rt/html/REST/1.0/Forms/queue/default
new file mode 100644
index 000000000..cfc4b5291
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/queue/default
@@ -0,0 +1,170 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/Forms/queue/default
+%#
+<%ARGS>
+$id
+$format => 's'
+$changes => {}
+</%ARGS>
+<%perl>
+my @comments;
+my ($c, $o, $k, $e) = ("", [], {}, 0);
+my %data = %$changes;
+my $queue = new RT::Queue $session{CurrentUser};
+my @fields = qw(Name Description CorrespondAddress CommentAddress
+ InitialPriority FinalPriority DefaultDueIn);
+my %fields = map { lc $_ => $_ } @fields;
+
+if ($id ne 'new') {
+ $queue->Load($id);
+ if (!$queue->Id) {
+ return [ "# Queue $id does not exist.", [], {}, 1 ];
+ }
+}
+else {
+ if (%data == 0) {
+ return [
+ "# Required: Name",
+ [ "id", @fields ],
+ {
+ id => 'queue/new',
+ Name => '<queue name>',
+ Description => "",
+ CommentAddress => "",
+ CorrespondAddress => "",
+ InitialPriority => "",
+ FinalPriority => "",
+ DefaultDueIn => "",
+ },
+ 0
+ ];
+ }
+ else {
+ my %v;
+ my %create = %fields;
+
+ foreach my $k (keys %data) {
+ if (exists $create{lc $k}) {
+ $v{$create{lc $k}} = delete $data{$k};
+ }
+ }
+
+ if ($v{Name} eq '<queue name>') {
+ my %o = keys %$changes;
+ delete @o{"id", @fields};
+ return [
+ "# Please set the queue name.",
+ [ "id", @fields, keys %o ], $changes, 1
+ ];
+ }
+
+ $queue->Create(%v);
+ unless ($queue->Id) {
+ return [ "# Could not create queue.", [], {}, 1 ];
+ }
+
+ delete $data{id};
+ $id = $queue->Id;
+ push(@comments, "# Queue $id created.");
+ goto DONE if %data == 0;
+ }
+}
+
+if (%data == 0) {
+ my @data;
+
+ push @data, [ id => "queue/".$queue->Id ];
+ foreach my $key (@fields) {
+ push @data, [ $key => $queue->$key ];
+ }
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+}
+else {
+ my ($get, $set, $key, $val, $n, $s);
+
+ foreach $key (keys %data) {
+ $val = $data{$key};
+ $key = lc $key;
+ $n = 1;
+
+ if (exists $fields{$key}) {
+ $key = $fields{$key};
+ $set = "Set$key";
+
+ next if $val eq $queue->$key;
+ ($n, $s) = $queue->$set($val);
+ }
+ elsif ($key ne 'id') {
+ $n = 0;
+ $s = "Unknown field.";
+ }
+
+ SET:
+ if ($n == 0) {
+ $e = 1;
+ push @comments, "# $key: $s";
+ unless (@$o) {
+ my %o = keys %$changes;
+ delete @o{"id", @fields};
+ @$o = ("id", @fields, keys %o);
+ $k = $changes;
+ }
+ }
+ }
+
+ push(@comments, "# Queue $id updated.") unless $n == 0;
+}
+
+DONE:
+$c ||= join("\n", @comments) if @comments;
+return [ $c, $o, $k, $e ];
+</%perl>
diff --git a/rt/html/REST/1.0/Forms/queue/ns b/rt/html/REST/1.0/Forms/queue/ns
new file mode 100644
index 000000000..227318944
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/queue/ns
@@ -0,0 +1,62 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/Forms/queue/ns
+%#
+<%ARGS>
+$id
+</%ARGS>
+<%perl>
+use RT::Queues;
+
+my $queues = new RT::Queues $session{CurrentUser};
+$queues->Limit(FIELD => 'Name', OPERATOR => '=', VALUE => $id);
+if ($queues->Count == 0) {
+ return (0, "No queue named $id exists.");
+}
+return $queues->Next->Id;
+</%perl>
diff --git a/rt/html/REST/1.0/Forms/ticket/attachments b/rt/html/REST/1.0/Forms/ticket/attachments
new file mode 100644
index 000000000..4ee409bdc
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/ticket/attachments
@@ -0,0 +1,135 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/Forms/ticket/attachments
+%#
+<%ARGS>
+$id
+$args => undef
+</%ARGS>
+<%INIT>
+my @data;
+my ($c, $o, $k, $e) = ("", [], {}, "");
+my $ticket = new RT::Ticket $session{CurrentUser};
+
+$ticket->Load($id);
+unless ($ticket->Id) {
+ return [ "# Ticket $id does not exist.", [], {}, 1 ];
+}
+
+my @arglist = split('/', $args);
+my ($aid, $content);
+
+if ($arglist[1] eq 'content') {
+ $aid = $arglist[0];
+ $content = 1;
+} else {
+ $aid = $args;
+ $content = 0;
+}
+
+if ($aid) {
+ unless ($aid =~ /^\d+$/) {
+ return [ "# Invalid attachment id: $aid", [], {}, 1 ];
+ }
+ my $attachment = new RT::Attachment $session{CurrentUser};
+ $attachment->Load($aid);
+ unless ($attachment->Id eq $aid) {
+ return [ "# Invalid attachment id: $aid", [], {}, 1 ];
+ }
+ if ($content) {
+ $c = $attachment->OriginalContent;
+ # if we're sending a binary attachment (and only the attachment)
+ # flag it so bin/rt knows to special case it
+ if ($attachment->ContentType !~ /^text\//) {
+ $r->content_type($attachment->ContentType);
+ }
+ } else {
+ my @data;
+ push @data, [ id => $attachment->Id ];
+ push @data, [ Subject => $attachment->Subject ];
+ push @data, [ Creator => $attachment->Creator ];
+ push @data, [ Created => $attachment->Created ];
+ push @data, [ Transaction => $attachment->TransactionId ];
+ push @data, [ Parent => $attachment->Parent ];
+ push @data, [ MessageId => $attachment->MessageId ];
+ push @data, [ Filename => $attachment->Filename ];
+ push @data, [ ContentType => $attachment->ContentType ];
+ push @data, [ ContentEncoding => $attachment->ContentEncoding ];
+ push @data, [ Headers => $attachment->Headers ];
+ push @data, [ Content => $attachment->Content ];
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+ }
+
+}
+else {
+ my @attachments;
+ my $transactions = $ticket->Transactions;
+ while (my $t = $transactions->Next) {
+ my $attachments = $t->Attachments;
+ while (my $a = $attachments->Next) {
+ my $size = length($a->Content);
+ if ($size > 1024) { $size = int($size/102.4)/10 . "k" }
+ else { $size .= "b" }
+ push @attachments, $a->Id.": ".$a->Filename." (".$a->ContentType . " / ".$size.")";
+ }
+ }
+
+ if (@attachments) {
+ $o = [ "id", "Attachments" ];
+ $k = {
+ id => "ticket/".$ticket->Id."/attachments",
+ Attachments => \@attachments
+ };
+ }
+}
+
+return [ $c, $o, $k, $e ];
+</%INIT>
diff --git a/rt/html/REST/1.0/Forms/ticket/comment b/rt/html/REST/1.0/Forms/ticket/comment
new file mode 100755
index 000000000..4ed2da8af
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/ticket/comment
@@ -0,0 +1,152 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/Forms/ticket/comment
+%#
+<%ARGS>
+$id
+%changes
+</%ARGS>
+<%INIT>
+use MIME::Entity;
+use LWP::MediaTypes;
+use RT::Interface::REST;
+use File::Temp qw(tempfile);
+
+$RT::Logger->debug("Got ticket id=$id for comment");
+$RT::Logger->debug("Got args @{[keys(%changes)]}.");
+
+my $ticket = new RT::Ticket $session{CurrentUser};
+my ($c, $o, $k, $e) = ("", [], {}, 0);
+
+# http://.../REST/1.0/ticket/1/comment
+$ticket->Load($id);
+if (!$ticket->Id) {
+ $e = 1;
+ $c = "# Ticket $id does not exist.";
+ goto OUTPUT;
+}
+
+my $action;
+($action = $changes{Action}) =~ s/^(.)(.*)$/\U$1\L$2\E/;
+unless ($action =~ /^(?:Comment|Correspond)$/) {
+ $e = 1;
+ $c = "# Invalid action: `$action'.";
+ goto OUTPUT;
+}
+
+my $text = $changes{Text};
+my @atts = @{ vsplit($changes{Attachment}) };
+
+if (!$changes{Text} && @atts == 0) {
+ $e = 1;
+ $c = "# Empty comment with no attachments submitted.";
+ goto OUTPUT;
+}
+
+my $cgi = $m->cgi_object;
+my $ent = MIME::Entity->build(Type => "multipart/mixed");
+$ent->attach(Data => $changes{Text}) if $changes{Text};
+
+my $i = 1;
+foreach my $att (@atts) {
+ local $/=undef;
+ my $file = $att;
+ $file =~ s#^.*[\\/]##;
+
+ my $fh = $cgi->upload("attachment_$i");
+ if ($fh) {
+ my $buf;
+ my ($w, $tmp) = tempfile();
+ my $info = $cgi->uploadInfo();
+
+ while (sysread($fh, $buf, 8192)) {
+ syswrite($w, $buf);
+ }
+
+ $ent->attach(
+ Path => $tmp,
+ Type => $info->{'Content-Type'} || guess_media_type($tmp),
+ Filename => $file,
+ Disposition => "attachment"
+ );
+ }
+ else {
+ $e = 1;
+ $c = "# No attachment for $att.";
+ goto OUTPUT;
+ }
+
+ $i++;
+}
+
+unless ($ticket->CurrentUserHasRight('ModifyTicket') ||
+ ($action eq "Comment" &&
+ $ticket->CurrentUserHasRight("CommentOnTicket")) ||
+ ($action eq "Correspond" &&
+ $ticket->CurrentUserHasRight("ReplyToTicket")))
+{
+ $e = 1;
+ $c = "# You are not allowed to $action on ticket $id.";
+ goto OUTPUT;
+}
+
+my $cc = join ", ", @{ vsplit($changes{Cc}) };
+my $bcc = join ", ", @{ vsplit($changes{Bcc}) };
+my ($n, $s) = $ticket->$action(MIMEObj => $ent,
+ CcMessageTo => $cc,
+ BccMessageTo => $bcc,
+ TimeTaken => $changes{TimeWorked} || 0);
+$c = "# ".$s;
+if ($changes{Status}) {
+ my ($status_n, $status_s) = $ticket->SetStatus($changes{'Status'} );
+ $c .= "\n# ".$status_s;
+}
+
+OUTPUT:
+return [ $c, $o, $k, $e ];
+</%INIT>
diff --git a/rt/html/REST/1.0/Forms/ticket/default b/rt/html/REST/1.0/Forms/ticket/default
new file mode 100644
index 000000000..2bfc43d9a
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/ticket/default
@@ -0,0 +1,345 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/Forms/ticket/default
+%#
+<%ARGS>
+$id
+$changes => {}
+$fields => undef
+$args => undef
+</%ARGS>
+<%INIT>
+use MIME::Entity;
+
+my @comments;
+my ($c, $o, $k, $e) = ("", [], {}, 0);
+my %data = %$changes;
+my $ticket = new RT::Ticket $session{CurrentUser};
+my @dates = qw(Created Starts Started Due Resolved Told LastUpdated);
+my @people = qw(Requestors Cc AdminCc);
+my @create = qw(Queue Requestor Subject Cc AdminCc Owner Status Priority
+ InitialPriority FinalPriority TimeEstimated TimeWorked
+ TimeLeft Starts Started Due Resolved);
+my @simple = qw(Subject Status Priority Disabled TimeEstimated TimeWorked
+ TimeLeft InitialPriority FinalPriority);
+my %dates = map {lc $_ => $_} @dates;
+my %people = map {lc $_ => $_} @people;
+my %create = map {lc $_ => $_} @create;
+my %simple = map {lc $_ => $_} @simple;
+
+# Are we dealing with an existing ticket?
+if ($id ne 'new') {
+ $ticket->Load($id);
+ if (!$ticket->Id) {
+ return [ "# Ticket $id does not exist.", [], {}, 1 ];
+ }
+ elsif (!$ticket->CurrentUserHasRight('ShowTicket') ||
+ (%data && !$ticket->CurrentUserHasRight('ModifyTicket')))
+ {
+ my $act = %data ? "modify" : "display";
+ return [ "# You are not allowed to $act ticket $id.", [], {}, 1 ];
+ }
+}
+else {
+ if (!keys(%data)) {
+ # GET ticket/new: Return a suitable default form.
+ # We get defaults from queue/1 (XXX: What if it isn't there?).
+ my $due = new RT::Date $session{CurrentUser};
+ my $queue = new RT::Queue $session{CurrentUser};
+ my $starts = new RT::Date $session{CurrentUser};
+ $queue->Load(1);
+ $due->SetToNow;
+ $due->AddDays($queue->DefaultDueIn) if $queue->DefaultDueIn;
+ $starts->SetToNow;
+
+ return [
+ "# Required: id, Queue",
+ [ qw(id Queue Requestor Subject Cc AdminCc Owner Status Priority
+ InitialPriority FinalPriority TimeEstimated Starts Due Text) ],
+ {
+ id => "ticket/new",
+ Queue => $queue->Name,
+ Requestor => $session{CurrentUser}->Name,
+ Subject => "",
+ Cc => [],
+ AdminCc => [],
+ Owner => "",
+ Status => "new",
+ Priority => $queue->InitialPriority,
+ InitialPriority => $queue->InitialPriority,
+ FinalPriority => $queue->FinalPriority,
+ TimeEstimated => 0,
+ Starts => $starts->ISO,
+ Due => $due->ISO,
+ Text => "",
+ },
+ 0
+ ];
+ }
+ else {
+ # We'll create a new ticket, and fall through to set fields that
+ # can't be set in the call to Create().
+ my (%v, $text);
+
+ foreach my $k (keys %data) {
+ if (exists $create{lc $k}) {
+ $v{$create{lc $k}} = delete $data{$k};
+ }
+ # Set custom field
+ elsif ($k =~ /^CF-/i) {
+ my $cf = RT::CustomField->new( $RT::SystemUser );
+ my $cfk = $k;
+ $cfk =~ s/^CF-//i;
+ unless($cf->LoadByName( Name => $cfk )) {
+ push @comments, "# Invalid custom field name ($cfk)";
+ delete $data{$k};
+ next;
+ }
+ $v{"CustomField-".$cf->Id()} = delete $data{$k};
+ }
+ elsif (lc $k eq 'text') {
+ $text = delete $data{$k};
+ }
+ }
+
+ # people fields allow multiple values
+ $v{$_} = vsplit($v{$_}) foreach ( grep $create{lc $_}, @people );
+
+ if ($text) {
+ $v{MIMEObj} =
+ MIME::Entity->build(
+ From => $session{CurrentUser}->EmailAddress,
+ Subject => $v{Subject},
+ Data => $text
+ );
+ }
+
+ my($tid,$trid,$terr) = $ticket->Create(%v);
+ unless ($tid) {
+ push(@comments, "# Could not create ticket.");
+ push(@comments, "# " . $terr);
+ goto DONE;
+ }
+
+ delete $data{id};
+ $id = $ticket->Id;
+ push(@comments, "# Ticket $id created.");
+ # see if the hash is empty
+ goto DONE if ! keys(%data);
+ }
+}
+
+# Now we know we're dealing with an existing ticket.
+if (!keys(%data)) {
+ my ($time, $key, $val, @data);
+
+ push @data, [ id => "ticket/".$ticket->Id ];
+ push @data, [ Queue => $ticket->QueueObj->Name ]
+ if (!%$fields || exists $fields->{lc 'Queue'});
+ push @data, [ Owner => $ticket->OwnerObj->Name ]
+ if (!%$fields || exists $fields->{lc 'Owner'});
+ push @data, [ Creator => $ticket->CreatorObj->Name ]
+ if (!%$fields || exists $fields->{lc 'Creator'});
+
+ foreach (qw(Subject Status Priority InitialPriority FinalPriority)) {
+ next unless (!%$fields || (exists $fields->{lc $_}));
+ push @data, [$_ => $ticket->$_ ];
+ }
+
+ foreach $key (@people) {
+ next unless (!%$fields || (exists $fields->{lc $key}));
+ push @data, [ $key => [ $ticket->$key->MemberEmailAddresses ] ];
+ }
+
+ $time = new RT::Date ($session{CurrentUser});
+ foreach $key (@dates) {
+ next unless (!%$fields || (exists $fields->{lc $key}));
+ $time->Set(Format => 'sql', Value => $ticket->$key);
+ push @data, [ $key => $time->AsString ];
+ }
+
+ $time = new RT::Date ($session{CurrentUser});
+ foreach $key (qw(TimeEstimated TimeWorked TimeLeft)) {
+ next unless (!%$fields || (exists $fields->{lc $key}));
+ $val = $ticket->$key || 0;
+ $val = "$val minutes" if $val;
+ push @data, [ $key => $val ];
+ }
+
+ # Display custom fields
+ my $CustomFields = $ticket->QueueObj->TicketCustomFields();
+ while (my $cf = $CustomFields->Next()) {
+ next unless (!%$fields || (exists $fields->{"cf-".lc $cf->Name}));
+ my $vals = $ticket->CustomFieldValues($cf->Id());
+ my @out = ();
+ while (my $v = $vals->Next()) {
+ push @out, $v->Content;
+ }
+ push @data, [ 'CF-' . $cf->Name => join ',', @out ];
+ }
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+}
+else {
+ my ($get, $set, $key, $val, $n, $s);
+
+ foreach $key (keys %data) {
+ $val = $data{$key};
+ $key = lc $key;
+ $n = 1;
+
+ if (ref $val eq 'ARRAY') {
+ unless ($key =~ /^(?:Requestors|Cc|AdminCc)$/i) {
+ $n = 0;
+ $s = "$key may have only one value.";
+ goto SET;
+ }
+ }
+
+ if ($key =~ /^queue$/i) {
+ next if $val eq $ticket->QueueObj->Name;
+ ($n, $s) = $ticket->SetQueue($val);
+ }
+ elsif ($key =~ /^owner$/i) {
+ next if $val eq $ticket->OwnerObj->Name;
+ ($n, $s) = $ticket->SetOwner($val);
+ }
+ elsif (exists $simple{$key}) {
+ $key = $simple{$key};
+ $set = "Set$key";
+
+ next if (($val eq $ticket->$key)|| ($ticket->$key =~ /^\d+$/ && $val == $ticket->$key));
+ ($n, $s) = $ticket->$set("$val");
+ }
+ elsif (exists $dates{$key}) {
+ $key = $dates{$key};
+ $set = "Set$key";
+
+ my $time = new RT::Date $session{CurrentUser};
+ $time->Set(Format => 'sql', Value => $ticket->$key);
+ next if ($val =~ /^not set$/i || $val eq $time->AsString);
+ ($n, $s) = $ticket->$set($val);
+ }
+ elsif (exists $people{$key}) {
+ $key = $people{$key};
+ my ($p, @msgs);
+
+ my %new = map {$_=>1} @{ vsplit($val) };
+ my %old = map {$_=>1} $ticket->$key->MemberEmailAddresses;
+ my $type = $key eq 'Requestors' ? 'Requestor' : $key;
+
+ foreach $p (keys %old) {
+ unless (exists $new{$p}) {
+ ($s, $n) = $ticket->DeleteWatcher(Type => $type,
+ Email => $p);
+ push @msgs, [ $s, $n ];
+ }
+ }
+ foreach $p (keys %new) {
+ # XXX: This is a stupid test.
+ unless ($p =~ /^[\w.+-]+\@([\w.-]+\.)*\w+.?$/) {
+ $s = 0;
+ $n = "$p is not a valid email address.";
+ push @msgs, [ $s, $n ];
+ next;
+ }
+ unless ($ticket->IsWatcher(Type => $type, Email => $p)) {
+ ($s, $n) = $ticket->AddWatcher(Type => $type,
+ Email => $p);
+ push @msgs, [ $s, $n ];
+ }
+ }
+
+ $n = 1;
+ if (@msgs = grep {$_->[0] == 0} @msgs) {
+ $n = 0;
+ $s = join "\n", map {"# ".$_->[1]} @msgs;
+ $s =~ s/^# //;
+ }
+ }
+ # Set custom field
+ elsif ($key =~ /^CF-/i) {
+ my $cf = RT::CustomField->new( $RT::SystemUser );
+ $key =~ s/^CF-//i;
+ if (not $cf->LoadByName( Name => $key )) {
+ $n = 0;
+ $s = "Unknown custom field.";
+ }
+ else {
+ ($n, $s) = $ticket->AddCustomFieldValue(
+ Field => $cf, Value => $val );
+ $s =~ s/^# // if defined $s;
+ }
+ }
+ elsif ($key ne 'id' && $key ne 'type' && $key ne 'creator') {
+ $n = 0;
+ $s = "Unknown field.";
+ }
+
+ SET:
+ if ($n == 0) {
+ $e = 1;
+ push @comments, "# $key: $s";
+ unless (@$o) {
+ my %o = keys %$changes;
+ delete $o{id};
+ @$o = ("id", keys %o);
+ $k = $changes;
+ }
+ }
+ }
+ push(@comments, "# Ticket ".$ticket->id." updated.") unless $n == 0;
+}
+
+DONE:
+$c ||= join("\n", @comments) if @comments;
+return [$c, $o, $k, $e];
+
+</%INIT>
diff --git a/rt/html/REST/1.0/Forms/ticket/history b/rt/html/REST/1.0/Forms/ticket/history
new file mode 100644
index 000000000..5dd7417d0
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/ticket/history
@@ -0,0 +1,200 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/Forms/ticket/history
+%#
+<%ARGS>
+$id
+$args => undef
+$format => undef
+$fields => undef
+</%ARGS>
+<%INIT>
+my $ticket = new RT::Ticket $session{CurrentUser};
+my ($c, $o, $k, $e) = ("", [], {}, "");
+
+$ticket->Load($id);
+unless ($ticket->Id) {
+ return [ "# Ticket $id does not exist.", [], {}, 1 ];
+}
+
+my $trans = $ticket->Transactions();
+my $total = $trans->Count();
+
+chomp $args;
+my @arglist = split('/', $args);
+my ($type, $tid);
+
+if ($arglist[0] eq 'type') {
+ $type = $arglist[1];
+} elsif ($arglist[0] eq 'id') {
+ $tid = $arglist[1];
+} else {
+ $type = $args;
+}
+
+if ($type) {
+ # Create, Set, Status, Correspond, Comment, Give, Steal, Take, Told
+ # CustomField, AddLink, DeleteLink, AddWatcher, DelWatcher
+ if ($args =~ /^links?$/) {
+ $trans->Limit(FIELD => 'Type', OPERATOR => 'LIKE', VALUE => '%Link');
+ }
+ elsif ($args =~ /^watchers?$/) {
+ $trans->Limit(FIELD => 'Type', OPERATOR => 'LIKE', VALUE => '%Watcher');
+ }
+ else {
+ $trans->Limit(FIELD => 'Type', OPERATOR => '=', VALUE => $type);
+ }
+} elsif ($tid) {
+ $trans->Limit(FIELD => 'Id', OPERATOR => '=', VALUE => $tid);
+}
+
+if ($tid) {
+ my @data;
+ my $t = new RT::Transaction $session{CurrentUser};
+
+ # this paragraph limits the transaction ID query to transactions on this ticket.
+ # Otherwise you can query any transaction from any ticket, which makes no sense.
+ my $Transactions = $ticket->Transactions;
+ my $tok=0;
+ while (my $T = $Transactions->Next()) {
+ $tok=1 if ($T->Id == $tid)
+ }
+ if ($tok) {
+ $t->Load($tid);
+ } else {
+ return [ "# Transaction $tid is not related to Ticket $id", [], {}, 1 ];
+ }
+
+ push @data, [ id => $t->Id ];
+ push @data, [ Ticket => $t->Ticket ]
+ if (!%$fields || exists $fields->{lc 'Ticket'});
+ push @data, [ TimeTaken => $t->TimeTaken ]
+ if (!%$fields || exists $fields->{lc 'TimeTaken'});
+ push @data, [ Type => $t->Type ]
+ if (!%$fields || exists $fields->{lc 'Type'});
+ push @data, [ Field => $t->Field ]
+ if (!%$fields || exists $fields->{lc 'Field'});
+ push @data, [ OldValue => $t->OldValue ]
+ if (!%$fields || exists $fields->{lc 'OldValue'});
+ push @data, [ NewValue => $t->NewValue ]
+ if (!%$fields || exists $fields->{lc 'NewValue'});
+ push @data, [ Data => $t->Data ]
+ if (!%$fields || exists $fields->{lc 'Data'});
+ push @data, [ Description => $t->Description ]
+ if (!%$fields || exists $fields->{lc 'Description'});
+ push @data, [ Content => $t->Content ]
+ if (!%$fields || exists $fields->{lc 'Content'});
+
+
+ if (!%$fields || exists $fields->{lc 'Content'}) {
+ my $creator = new RT::User $session{CurrentUser};
+ $creator->Load($t->Creator);
+ push @data, [ Creator => $creator->Name ];
+ }
+ push @data, [ Created => $t->Created ]
+ if (!%$fields || exists $fields->{lc 'Created'});
+
+ if (!%$fields || exists $fields->{lc 'Attachments'}) {
+ my $attachlist;
+ my $attachments = $t->Attachments;
+ while (my $a = $attachments->Next) {
+ my $size = length($a->Content);
+ if ($size > 1024) { $size = int($size/102.4)/10 . "k" }
+ else { $size .= "b" }
+ $attachlist .= "\n" . $a->Id.": ".($a->Filename || "untitled")." (".$size.")";
+ }
+
+ push @data, [Attachments => $attachlist];
+ }
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+
+} else {
+ my (@data, $tids);
+ $format ||= "s";
+ $format = "l" if (%$fields);
+
+ while (my $t = $trans->Next) {
+ my $tid = $t->Id;
+
+ if ($format eq "l") {
+ $tids .= "," if $tids;
+ $tids .= $tid;
+ } else {
+ push @$o, $tid;
+ $k->{$tid} = $t->Description;
+ }
+ }
+
+ if ($format eq "l") {
+ my @tid;
+ push @tid, "ticket/$id/history/id/$tids";
+ my $fieldstring;
+ foreach my $key (keys %$fields) {
+ $fieldstring .= "," if $fieldstring;
+ $fieldstring .= $key;
+ }
+ my ($content, $forms);
+ $m->subexec("/REST/1.0/show",
+ id => \@tid,
+ format => $format,
+ fields => $fieldstring);
+ return [ $c, $o, $k, $e ];
+ }
+}
+
+if (!$c) {
+ my $sub = $trans->Count();
+ $c = "# $sub/$total ($args/total)";
+}
+
+return [ $c, $o, $k, $e ];
+
+</%INIT>
diff --git a/rt/html/REST/1.0/Forms/ticket/links b/rt/html/REST/1.0/Forms/ticket/links
new file mode 100644
index 000000000..6b2ed222d
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/ticket/links
@@ -0,0 +1,172 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/Forms/ticket/links
+%#
+<%ARGS>
+$id
+$format => 's'
+$changes => undef
+</%ARGS>
+<%INIT>
+my @data;
+my $ticket = new RT::Ticket $session{CurrentUser};
+
+$ticket->Load($id);
+if (!$ticket->Id) {
+ return [ "# Ticket $id does not exist.", [], {}, 1 ];
+}
+
+my ($c, $o, $k, $e) = ("", [], {}, 0);
+my @fields = qw(DependsOn DependedOnBy RefersTo ReferredToBy Members MemberOf);
+my %fields = map { lc $_ => $_ } @fields;
+
+my %lfields = (
+ Members => { Type => 'MemberOf', Mode => 'Base' },
+ ReferredToBy => { Type => 'RefersTo', Mode => 'Base' },
+ DependedOnBy => { Type => 'DependsOn', Mode => 'Base' },
+ MemberOf => { Type => 'MemberOf', Mode => 'Target' },
+ RefersTo => { Type => 'RefersTo', Mode => 'Target' },
+ DependsOn => { Type => 'DependsOn', Mode => 'Target' },
+);
+
+if ($changes) {
+ my ($get, $set, $key, $val, $n, $s);
+ my %data = %$changes;
+ my @comments;
+
+ foreach $key (keys %data) {
+ $val = $data{$key};
+ $key = lc $key;
+ $n = 1;
+
+ if (exists $fields{$key}) {
+ $key = $fields{$key};
+
+ my %old;
+ my $field = $lfields{$key}->{Mode};
+ while (my $link = $ticket->$key->Next) {
+ $old{$link->$field} = 1;
+ }
+
+ my %new;
+ foreach my $nkey (@{vsplit($val)}) {
+ if ($nkey =~ /^\d+$/) {
+ my $uri = new RT::URI $session{CurrentUser};
+ my $tick = new RT::Ticket $session{CurrentUser};
+ $tick->Load($nkey);
+ if ($tick->Id) {
+ $nkey = $uri->FromObject($tick);
+ }
+ else {
+ $n = 0;
+ $s = "Ticket $nkey does not exist.";
+ goto SET;
+ }
+ }
+ $new{$nkey} = 1;
+ }
+
+ foreach my $u (keys %old) {
+ if (exists $new{$u}) {
+ delete $new{$u};
+ }
+ else {
+ my $type = $lfields{$key}->{Type};
+ my $mode = $lfields{$key}->{Mode};
+ ($n, $s) = $ticket->DeleteLink(Type => $type, $mode => $u);
+ goto SET;
+ }
+ }
+ foreach my $u (keys %new) {
+ my $type = $lfields{$key}->{Type};
+ my $mode = $lfields{$key}->{Mode};
+ ($n, $s) = $ticket->AddLink(Type => $type, $mode => $u);
+ goto SET;
+ }
+ }
+ elsif ($key ne 'id' && $key ne 'type') {
+ $n = 0;
+ $s = "Unknown field: $key";
+ }
+
+ SET:
+ if ($n == 0) {
+ $e = 1;
+ push @comments, "# $key: $s";
+ unless (@$o) {
+ @$o = ("id", @fields);
+ %$k = %data;
+ }
+ }
+ }
+
+ push(@comments, "# Links for ticket $id updated.") unless @comments;
+ $c = join("\n", @comments) if @comments;
+}
+else {
+ my @data;
+
+ push @data, [ id => "ticket/".$ticket->Id."/links" ];
+ foreach my $key (@fields) {
+ my @val;
+
+ my $field = $lfields{$key}->{Mode};
+ while (my $link = $ticket->$key->Next) {
+ push @val, $link->$field;
+ }
+ push(@val, "") if (@val == 0 && $format eq 'l');
+ push @data, [ $key => [ @val ] ] if @val;
+ }
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+}
+
+return [ $c, $o, $k, $e ];
+</%INIT>
diff --git a/rt/html/REST/1.0/Forms/ticket/merge b/rt/html/REST/1.0/Forms/ticket/merge
new file mode 100755
index 000000000..69af6c8e1
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/ticket/merge
@@ -0,0 +1,96 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/Forms/ticket/merge
+%#
+<%ARGS>
+$id
+$args
+</%ARGS>
+<%INIT>
+use RT::Interface::REST;
+
+my $into = $args;
+
+my $ticket = new RT::Ticket $session{CurrentUser};
+my $ticket_into = new RT::Ticket $session{CurrentUser};
+my ($c, $o, $k, $e) = ("", [], {}, 0);
+
+# http://.../REST/1.0/ticket/1/merge/6 (merges ticket 1 into ticket 6)
+
+$ticket->Load($id);
+if (!$ticket->Id) {
+ $e = 1;
+ $c = "# Ticket $id does not exist.";
+ goto OUTPUT;
+}
+$ticket_into->Load($into);
+if (!$ticket_into->Id) {
+ $e = 1;
+ $c = "# Ticket $into does not exist.";
+ goto OUTPUT;
+}
+
+if (!$ticket->CurrentUserHasRight('ModifyTicket')) {
+ $e = 1;
+ $c = "# You are not allowed to modify ticket $id.";
+ goto OUTPUT;
+}
+
+my ($n, $s) = $ticket->MergeInto($into);
+
+if ($n == 0) {
+ $e = 1;
+ $c = "# Could not complete the merge.";
+}
+else {
+ $c = "# Merge completed.";
+}
+
+OUTPUT:
+return [ $c, $o, $k, $e ];
+</%INIT>
diff --git a/rt/html/REST/1.0/Forms/ticket/take b/rt/html/REST/1.0/Forms/ticket/take
new file mode 100755
index 000000000..35ee11fa7
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/ticket/take
@@ -0,0 +1,135 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/Forms/ticket/take
+%#
+<%ARGS>
+$id
+%changes
+</%ARGS>
+<%INIT>
+use RT::Interface::REST;
+
+my $ticket = new RT::Ticket $session{CurrentUser};
+my ($c, $o, $k, $e) = ("", [], {}, 0);
+
+# http://.../REST/1.0/ticket/1/take
+$ticket->Load( $id );
+unless ( $ticket->Id ) {
+ $e = 1;
+ $c = "# Ticket $id does not exist.";
+ goto OUTPUT;
+}
+
+my $action;
+
+my @comments;
+
+($action = $changes{Action}) =~ s/^(.)(.*)$/\U$1\L$2\E/;
+unless ($action =~ /^(?:Take|Steal|Untake)$/) {
+ $e = 1;
+ $c = "# Invalid action: `$action'.";
+ goto OUTPUT;
+}
+
+my ($status, $msg) = $ticket->$action();
+$c = "# $msg";
+$e = 1 unless $status;
+goto OUTPUT;
+
+#unless ($ticket->CurrentUserHasRight('ModifyTicket') ||
+# ( ($action eq "Take" || $action eq 'Untake') &&
+# $ticket->CurrentUserHasRight("TakeTicket")) ||
+# ($action eq "Steal" &&
+# $ticket->CurrentUserHasRight("StealTicket")))
+#{
+# $e = 1;
+# $c = "# You are not allowed to $action ticket $id.";
+# goto OUTPUT;
+#}
+
+#if ( keys %changes ) {
+#}
+#else {
+# # process the form data structure
+# my ($key, $val);
+#
+# foreach $key (keys %data) {
+# $val = $data{$key};
+#
+# if ($key =~ /^force$/i) {
+# if ($val !~ /^(?:0|1)$/) {
+# push(@comments, "# invalid value for 'force': $val");
+# goto DONE;
+# }
+# my ($ret_id, $msg);
+#
+# ### take
+# if ($val == 0) {
+# ($ret_id, $msg) = $ticket->Take;
+# if (!$ret_id) {
+# push(@comments, "# Couldn't take ticket $id: $msg");
+# goto DONE;
+# }
+# push(@comments, "# Ticket $id taken.");
+# }
+# ### steal
+# else {
+# ($ret_id, $msg) = $ticket->Steal;
+# if (!$ret_id) {
+# push(@comments, "# Couldn't steal ticket $id: $msg");
+# goto DONE;
+# }
+# push(@comments, "# Ticket $id stolen.");
+# }
+# }
+# }
+#}
+
+OUTPUT:
+return [ $c, $o, $k, $e ];
+</%INIT>
diff --git a/rt/html/REST/1.0/Forms/transaction/default b/rt/html/REST/1.0/Forms/transaction/default
new file mode 100644
index 000000000..e23098a66
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/transaction/default
@@ -0,0 +1,143 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/Forms/transaction
+%#
+<%ARGS>
+$id
+$args => undef
+$format => undef
+$fields => undef
+</%ARGS>
+<%INIT>
+my $trans = new RT::Transactions $session{CurrentUser};
+my ($c, $o, $k, $e) = ("", [], {} , "");
+
+chomp $args;
+my @arglist = split('/', $args);
+my $tid = $id;
+
+$trans->Limit(FIELD => 'Id', OPERATOR => '=', VALUE => $tid);
+
+if ($tid) {
+ my @data;
+ my $t = new RT::Transaction $session{CurrentUser};
+ $t->Load($tid);
+ if ($format eq "l") {
+ push @data, [ id => $t->Id ];
+ push @data, [ Ticket => $t->Ticket ]
+ if (!%$fields || exists $fields->{lc 'Ticket'});
+ push @data, [ TimeTaken => $t->TimeTaken ]
+ if (!%$fields || exists $fields->{lc 'TimeTaken'});
+ push @data, [ Type => $t->Type ]
+ if (!%$fields || exists $fields->{lc 'Type'});
+ push @data, [ Field => $t->Field ]
+ if (!%$fields || exists $fields->{lc 'Field'});
+ push @data, [ OldValue => $t->OldValue ]
+ if (!%$fields || exists $fields->{lc 'OldValue'});
+ push @data, [ NewValue => $t->NewValue ]
+ if (!%$fields || exists $fields->{lc 'NewValue'});
+ push @data, [ Data => $t->Data ]
+ if (!%$fields || exists $fields->{lc 'Data'});
+ push @data, [ Description => $t->Description ]
+ if (!%$fields || exists $fields->{lc 'Description'});
+ push @data, [ Content => $t->Content ]
+ if (!%$fields || exists $fields->{lc 'Content'});
+
+ if (!%$fields || exists $fields->{lc 'Content'}) {
+ my $creator = new RT::User $session{CurrentUser};
+ $creator->Load($t->Creator);
+ push @data, [ Creator => $creator->Name ];
+ }
+ push @data, [ Created => $t->Created ]
+ if (!%$fields || exists $fields->{lc 'Created'});
+
+ if (!%$fields || exists $fields->{lc 'Attachments'}) {
+ my $attachlist;
+ my $attachments = $t->Attachments;
+ while (my $a = $attachments->Next) {
+ my $size = length($a->Content);
+ if ($size > 1024) {
+ $size = int($size/102.4)/10 . "k";
+ }
+ else {
+ $size .= "b";
+ }
+ $attachlist .= "\n" . $a->Id.": ".($a->Filename || "untitled")." (".$size.")";
+ }
+ push @data, [Attachments => $attachlist];
+ }
+
+ } else {
+ push @data, [ id => $t->Id ];
+ push @data, [ Description => $t->Description ];
+ }
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+}
+#else {
+# my (@data, $tids);
+# $format ||= "s";
+# $format = "l" if (%$fields);
+#
+# while (my $t = $trans->Next) {
+# my $tid = $t->Id;
+# if ($format eq "l") {
+# $tids .= "," if $tids;
+# $tids .= $tid;
+# } else {
+# push @$o, $tid;
+# $k->{$tid} = $t->Description;
+# }
+# }
+#}
+
+return [ $c, $o, $k, $e ];
+
+</%INIT>
diff --git a/rt/html/REST/1.0/Forms/user/default b/rt/html/REST/1.0/Forms/user/default
new file mode 100644
index 000000000..621e96dfa
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/user/default
@@ -0,0 +1,188 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/Forms/user/default
+%#
+<%ARGS>
+$id
+$format => 's'
+$changes => {}
+</%ARGS>
+<%perl>
+my @comments;
+my ($c, $o, $k, $e) = ("", [], {}, 0);
+my %data = %$changes;
+my $user = new RT::User $session{CurrentUser};
+my @fields = qw(RealName NickName Gecos Organization Address1 Address2 City
+ State Zip Country HomePhone WorkPhone MobilePhone PagerPhone
+ FreeformContactInfo Comments Signature Lang EmailEncoding
+ WebEncoding ExternalContactInfoId ContactInfoSystem
+ ExternalAuthId AuthSystem);
+my %fields = map { lc $_ => $_ } @fields;
+
+if ($id ne 'new') {
+ $user->Load($id);
+ if (!$user->Id) {
+ return [ "# User $id does not exist.", [], {}, 1 ];
+ }
+}
+else {
+ if (%data == 0) {
+ return [
+ "# Required: Name, EmailAddress",
+ [ qw(id Name EmailAddress Organization Password Comments) ],
+ {
+ id => "user/new",
+ Name => "",
+ EmailAddress => "",
+ Organization => "",
+ Password => "",
+ Comments => ""
+ },
+ 0
+ ];
+ }
+ else {
+ my %v;
+ my %create = %fields;
+ $create{name} = "Name";
+ $create{password} = "Password";
+ $create{emailaddress} = "EmailAddress";
+ $create{contactinfo} = "FreeformContactInfo";
+ # Do any fields need to be excluded here?
+
+ foreach my $k (keys %data) {
+ if (exists $create{lc $k}) {
+ $v{$create{lc $k}} = delete $data{$k};
+ }
+ }
+
+ $user->Create(%v);
+ unless ($user->Id) {
+ return [ "# Could not create user.", [], {}, 1 ];
+ }
+
+ $id = $user->Id;
+ delete $data{id};
+ push(@comments, "# User $id created.");
+ goto DONE if %data == 0;
+ }
+}
+
+if (%data == 0) {
+ my @data;
+
+ push @data, [ id => "user/".$user->Id ];
+ push @data, [ Name => $user->Name ];
+ push @data, [ Password => '********' ];
+ push @data, [ EmailAddress => $user->EmailAddress ];
+
+ foreach my $key (@fields) {
+ my $val = $user->$key;
+
+ if ($format eq 'l' || (defined $val && $val ne '')) {
+ $key = "ContactInfo" if $key eq 'FreeformContactInfo';
+ push @data, [ $key => $val ];
+ }
+ }
+
+ my %k = map {@$_} @data;
+ $o = [ map {$_->[0]} @data ];
+ $k = \%k;
+}
+else {
+ my ($get, $set, $key, $val, $n, $s);
+
+ foreach $key (keys %data) {
+ $val = $data{$key};
+ $key = lc $key;
+ $n = 1;
+
+ if ($key eq 'name' || $key eq 'emailaddress' ||
+ $key eq 'contactinfo' || exists $fields{$key})
+ {
+ if (exists $fields{$key}) {
+ $key = $fields{$key};
+ }
+ else {
+ $key = "FreeformContactInfo" if $key eq 'contactinfo';
+ $key = "EmailAddress" if $key eq 'emailaddress';
+ $key = "Name" if $key eq 'name';
+ }
+ $set = "Set$key";
+
+ next if $val eq $user->$key;
+ ($n, $s) = $user->$set($val);
+ }
+ elsif ($key eq 'password') {
+ ($n, $s) = $user->SetPassword($val) unless $val =~ /^\**$/;
+ }
+ elsif ($key ne 'id') {
+ $n = 0;
+ $s = "Unknown field.";
+ }
+
+ SET:
+ if ($n == 0) {
+ $e = 1;
+ push @comments, "# $key: $s";
+ unless (@$o) {
+ my %o = keys %$changes;
+ delete @o{"id", @fields};
+ @$o = ("id", @fields, keys %o);
+ $k = $changes;
+ }
+ }
+ }
+
+ push(@comments, "# User $id updated.") unless $n == 0;
+}
+
+DONE:
+$c ||= join("\n", @comments) if @comments;
+return [ $c, $o, $k, $e ];
+</%perl>
diff --git a/rt/html/REST/1.0/Forms/user/ns b/rt/html/REST/1.0/Forms/user/ns
new file mode 100644
index 000000000..3503d8ace
--- /dev/null
+++ b/rt/html/REST/1.0/Forms/user/ns
@@ -0,0 +1,65 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/Forms/user/ns
+%#
+<%ARGS>
+$id
+</%ARGS>
+<%perl>
+use RT::Users;
+
+my $field = "Name";
+$field = "EmailAddress" if $id =~ /\@/;
+
+my $users = new RT::Users $session{CurrentUser};
+$users->Limit(FIELD => $field, OPERATOR => '=', VALUE => $id);
+if ($users->Count == 0) {
+ return (0, "No user named $id exists.");
+}
+return $users->Next->Id;
+</%perl>
diff --git a/rt/html/REST/1.0/NoAuth/mail-gateway b/rt/html/REST/1.0/NoAuth/mail-gateway
new file mode 100644
index 000000000..739dace9d
--- /dev/null
+++ b/rt/html/REST/1.0/NoAuth/mail-gateway
@@ -0,0 +1,84 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%flags>
+inherit => undef # inhibit UTF8 conversion done in /autohandler
+</%flags>
+<%ARGS>
+$queue => 1
+$action => "correspond"
+$ticket => undef
+</%ARGS>
+<%init>
+$m->comp('/Elements/Callback', _CallbackName => 'Pre', %ARGS);
+use RT::Interface::Email (); # It's an exporter, but we don't care
+$r->content_type('text/plain; charset=utf-8');
+$m->error_format('text');
+my ( $status, $error, $Ticket ) = RT::Interface::Email::Gateway( \%ARGS );
+if ( $status == 1 ) {
+ $m->out('ok');
+ if ( $Ticket->Id ) {
+ $m->out( 'Ticket: ' . ($Ticket->Id || '') );
+ $m->out( 'Queue: ' . ($Ticket->QueueObj->Name || '') );
+ $m->out( 'Owner: ' . ($Ticket->OwnerObj->Name || '') );
+ $m->out( 'Status: ' . ($Ticket->Status || '') );
+ $m->out( 'Subject: ' . ($Ticket->Subject || '') );
+ $m->out(
+ 'Requestor: ' . ($Ticket->Requestors->MemberEmailAddressesAsString || '') );
+ }
+}
+else {
+ $RT::Logger->error( "Could not record email: " . $error );
+ if ( $status == -75 ) {
+ $m->out( "temporary failure - " . $error );
+ }
+ else {
+ $m->out( 'not ok - ' . $error );
+ }
+}
+$m->abort();
+</%init>
diff --git a/rt/html/REST/1.0/autohandler b/rt/html/REST/1.0/autohandler
new file mode 100644
index 000000000..e8247b18e
--- /dev/null
+++ b/rt/html/REST/1.0/autohandler
@@ -0,0 +1,56 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/autohandler
+%#
+<%INIT>
+use RT::Interface::REST;
+$r->content_type('text/plain; charset=utf-8');
+$m->error_format('text');
+$m->call_next();
+$m->abort();
+</%INIT>
diff --git a/rt/html/REST/1.0/dhandler b/rt/html/REST/1.0/dhandler
new file mode 100644
index 000000000..7406520bc
--- /dev/null
+++ b/rt/html/REST/1.0/dhandler
@@ -0,0 +1,316 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/dhandler
+%#
+<%ARGS>
+@id => ()
+$fields => undef
+$format => undef
+$content => undef
+</%ARGS>
+<%INIT>
+use RT::Interface::REST;
+
+my $output = "";
+my $status = "200 Ok";
+my $object = $m->dhandler_arg;
+
+my $name = qr{[\w.-]+};
+my $list = '(?:(?:\d+-)?\d+,)*(?:\d+-)?\d+';
+my $label = '[a-zA-Z0-9@_.+-]+';
+my $field = '[a-zA-Z](?:[a-zA-Z0-9_-]|\s+)*';
+my $labels = "(?:$label,)*$label";
+
+# We must handle requests such as the following:
+#
+# 1. http://.../REST/1.0/show (with a list of object specifications).
+# 2. http://.../REST/1.0/edit (with a self-contained list of forms).
+# 3. http://.../REST/1.0/ticket/show (implicit type specification).
+# http://.../REST/1.0/ticket/edit
+# 4. http://.../REST/1.0/ticket/nn (all possibly with a single form).
+# http://.../REST/1.0/ticket/nn/history
+# http://.../REST/1.0/ticket/nn/comment
+# http://.../REST/1.0/ticket/nn/attachment/1
+#
+# Objects are specified by their type, and either a unique numeric ID,
+# or a unique name (e.g. ticket/1, queue/foo). Multiple objects of the
+# same type may be specified by a comma-separated list of identifiers
+# (e.g., user/ams,rai or ticket/1-3,5-7).
+#
+# Ultimately, we want a list of object specifications to operate upon.
+# The URLs in (4) provide enough information to identify an object. We
+# will assemble submitted information into that format in other cases.
+#
+my (@objects, $forms);
+my $utype;
+
+if ($object eq 'show' || # $REST/show
+ (($utype) = ($object =~ m{^($name)/show$}))) # $REST/ticket/show
+{
+ # We'll convert type/range specifications ("ticket/1-3,7-9/history")
+ # into a list of singular object specifications ("ticket/1/history").
+ # If the URL specifies a type, we'll accept only that one.
+ foreach my $id (@id) {
+ $id =~ s|^(?:$utype/)?|$utype/| if $utype;
+ if (my ($type, $oids, $extra) =
+ ($id =~ m#^($name)/($list|$labels)(?:(/.*))?$#o))
+ {
+ foreach my $oid (expand_list($oids)) {
+ if ($extra =~ m{^(?:/($name)(?:/(.*))?)?$}o) {
+ my ($attr, $args) = ($1, $2);
+ # expand transaction and attachment range specifications
+ # (if applicable)
+ my $tids;
+ if ($attr eq 'history' && $args =~ m#id/(\d.*)#o) {
+ $tids = $1;
+ }
+ if ($tids) {
+ push(@objects, "$type/$oid/$attr/id/$_") for expand_list($tids);
+ } else {
+ push(@objects, "$type/$oid$extra");
+ }
+ }
+ }
+ }
+ else {
+ $status = "400 Bad Request";
+ $output = "Invalid object ID specified: '$id'";
+ goto OUTPUT;
+ }
+ }
+}
+elsif ($object eq 'edit' || # $REST/edit
+ (($utype) = ($object =~ m{^($name)/edit$}))) # $REST/ticket/edit
+{
+ # We'll make sure each of the submitted forms is syntactically valid
+ # and sufficiently identifies an object to operate upon, then add to
+ # the object list as above.
+ my @output;
+
+ $forms = form_parse($content);
+ foreach my $form (@$forms) {
+ my ($c, $o, $k, $e) = @$form;
+
+ if ($e) {
+ push @output, [ "# Syntax error.", $o, $k, $e ];
+ }
+ else {
+ my ($type, $id);
+
+ # Look for matching types in the ID, form, and URL.
+ $type = exists $k->{type} ? $k->{type} : $utype;
+ $type =~ s|^(?:$utype)?|$utype/| if $utype;
+ $type =~ s|/$||;
+
+ if (exists $k->{id}) {
+ $id = $k->{id};
+ $id =~ s|^(?:$type/)?|$type/| if $type;
+
+ if ($id =~ m#^$name/(?:$label|\d+)(?:/.*)?#o) {
+ push @objects, $id;
+ }
+ else {
+ push @output, [ "# Invalid object ID: '$id'", $o, $k, $e ];
+ }
+ }
+ else {
+ push @output, [ "# No object ID specified.", $o, $k, $e ];
+ }
+ }
+ }
+ # If we saw any errors at this stage, we won't process any part of
+ # the submitted data.
+ if (@output) {
+ unshift @output, [ "# Please resubmit with errors corrected." ];
+ $status = "409 Syntax Error";
+ $output = form_compose(\@output);
+ goto OUTPUT;
+ }
+}
+else {
+ # We'll assume that this is in the correct format already. Otherwise
+ # it will be caught by the loop below.
+ push @objects, $object;
+
+ if ($content) {
+ $forms = form_parse($content);
+
+ if (@$forms > 1) {
+ $status = "400 Bad Request";
+ $output = "You may submit only one form to this object.";
+ goto OUTPUT;
+ }
+
+ my ($c, $o, $k, $e) = @{ $forms->[0] };
+ if ($e) {
+ $status = "409 Syntax Error";
+ $output = form_compose([ ["# Syntax error.", $o, $k, $e] ]);
+ goto OUTPUT;
+ }
+ }
+}
+
+# Make sure we have something to do.
+unless (@objects) {
+ $status = "400 Bad Request";
+ $output = "No objects specified.";
+ goto OUTPUT;
+}
+
+# Parse and validate any field specifications.
+my (%fields, @fields);
+if ($fields) {
+ unless ($fields =~ /^(?:$field,)*$field$/) {
+ $status = "400 Bad Request";
+ $output = "Invalid field specification: $fields";
+ goto OUTPUT;
+ }
+ @fields = map lc, split /,/, $fields;
+ @fields{@fields} = ();
+ unless (exists $fields{id}) {
+ unshift @fields, "id";
+ $fields{id} = ();
+ }
+}
+
+my (@comments, @output);
+
+foreach $object (@objects) {
+ my ($handler, $type, $id, $attr, $args);
+ my ($c, $o, $k, $e) = ("", ["id"], {id => $object}, 0);
+
+ my $i = 0;
+ if ($object =~ m{^($name)/(\d+|$label)(?:/($name)(?:/(.*))?)?$}o ||
+ $object =~ m{^($name)/(new)$}o)
+ {
+ ($type, $id, $attr, $args) = ($1, $2, ($3 || 'default'), $4);
+ $handler = "Forms/$type/$attr";
+
+ unless ($m->comp_exists($handler)) {
+ $args = "$attr/$args";
+ $handler = "Forms/$type/default";
+
+ unless ($m->comp_exists($handler)) {
+ $i = 2;
+ $c = "# Unknown object type: $type";
+ }
+ }
+ elsif ($id ne 'new' && $id !~ /^\d+$/) {
+ my $ns = "Forms/$type/ns";
+
+ # Can we resolve named objects?
+ unless ($m->comp_exists($ns)) {
+ $i = 3;
+ $c = "# Objects of type $type must be specified by numeric id.";
+ }
+ else {
+ my ($n, $s) = $m->comp("Forms/$type/ns", id => $id);
+ if ($n <= 0) { $i = 4; $c = "# $s"; }
+ else { $i = 0; $id = $n; }
+ }
+ }
+ else {
+ $i = 0;
+ }
+ }
+ else {
+ $i = 1;
+ $c = "# Invalid object specification: '$object'";
+ }
+
+ if ($i != 0) {
+ if ($content) {
+ (undef, $o, $k, $e) = @{ shift @$forms };
+ }
+ push @output, [ $c, $o, $k ];
+ next;
+ }
+
+ unless ($content) {
+ my $d = $m->comp($handler, id => $id, args => $args, format => $format, fields => \%fields);
+ my ($c, $o, $k, $e) = @$d;
+
+ if (!$e && @$o && keys %fields) {
+ my %lk = map { lc $_ => $_ } keys %$k;
+ @$o = map { $lk{$_} } @fields;
+ foreach my $key (keys %$k) {
+ delete $k->{$key} unless exists $fields{lc $key};
+ }
+ }
+ push(@output, [ $c, $o, $k ]) if ($c || @$o || keys %$k);
+ }
+ else {
+ my ($c, $o, $k, $e) = @{ shift @$forms };
+ my $d = $m->comp($handler, id => $id, args => $args, format => $format,
+ changes => $k);
+ ($c, $o, $k, $e) = @$d;
+
+ # We won't pass $e through to compose, trusting instead that the
+ # handler added suitable comments for the user.
+ if ($e) {
+ if (@$o) {
+ $status = "409 Syntax Error";
+ }
+ else {
+ $status = "400 Bad Request";
+ }
+ push @output, [ $c, $o, $k ];
+ }
+ else {
+ push @comments, $c;
+ }
+ }
+}
+
+unshift(@output, [ join "\n", @comments ]) if @comments;
+$output = form_compose(\@output);
+
+OUTPUT:
+$m->out("RT/".$RT::VERSION ." ".$status ."\n\n$output\n") if ($output || $status != 200);
+return;
+</%INIT>
diff --git a/rt/html/REST/1.0/logout b/rt/html/REST/1.0/logout
new file mode 100644
index 000000000..4152a7ee0
--- /dev/null
+++ b/rt/html/REST/1.0/logout
@@ -0,0 +1,51 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%PERL>
+tied(%session)->delete if (defined %session);
+</%PERL>
+RT/<% $RT::VERSION %> 200 Ok
diff --git a/rt/html/REST/1.0/search/dhandler b/rt/html/REST/1.0/search/dhandler
new file mode 100644
index 000000000..3e6b314b7
--- /dev/null
+++ b/rt/html/REST/1.0/search/dhandler
@@ -0,0 +1,56 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/search/dhandler
+%#
+<%INIT>
+my $status = "500 Server Error";
+my $output = "Unsupported object type.";
+</%INIT>
+RT/<% $RT::VERSION %> <% $status %>
+
+<% $output |n %>
diff --git a/rt/html/REST/1.0/search/ticket b/rt/html/REST/1.0/search/ticket
new file mode 100644
index 000000000..37883931d
--- /dev/null
+++ b/rt/html/REST/1.0/search/ticket
@@ -0,0 +1,158 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/search/ticket
+%#
+<%ARGS>
+$query
+$format => undef
+$orderby => undef
+$fields => undef
+</%ARGS>
+<%INIT>
+my $output = "";
+my $status = "200 Ok";
+my $tickets = new RT::Tickets $session{CurrentUser};
+
+# Parse and validate any field specifications.
+my $field = '[a-zA-Z](?:[a-zA-Z0-9_-]|\s+)*';
+my (%fields, @fields);
+if ($fields) {
+ $format ||= "l";
+ unless ($fields =~ /^(?:$field,)*$field$/) {
+ $status = "400 Bad Request";
+ $output = "Invalid field specification: $fields";
+ goto OUTPUT;
+ }
+ @fields = map lc, split /,/, $fields;
+ @fields{@fields} = ();
+ unless (exists $fields{id}) {
+ unshift @fields, "id";
+ $fields{id} = ();
+ }
+}
+
+$format ||= "s";
+if ($format !~ /^[isl]$/) {
+ $status = "400 Bad request";
+ $output = "Unknown listing format: $format. (Use i, s, or l.)\n";
+ goto OUTPUT;
+}
+
+my ($n, $s);
+eval {
+ ($n, $s) = $tickets->FromSQL($query);
+};
+my $sortstring = "";
+if ($orderby) {
+ $sortstring = 'FIELD => ';
+ my $order = substr($orderby, 0, 1);
+ if ($order eq '+' || $order eq '-') {
+ $sortstring .= 'substr($orderby, 1)';
+ if ($order eq '+') {
+ $sortstring .= ", ORDER => 'ASC'";
+ } elsif ($order eq '-') {
+ $sortstring .= ", ORDER => 'DESC'";
+ }
+ } else {
+ $sortstring .= '$orderby';
+ }
+ my $foo = 'FIELD => ';
+ $foo .= '$orderby';
+ $tickets->OrderBy(eval $sortstring);
+}
+if ($@ || $n == 0) {
+ $s ||= $@;
+ $status = "400 Bad request";
+ $output = "Invalid query: '$s'.\n";
+ goto OUTPUT;
+}
+
+$n = 0;
+my @output;
+while (my $ticket = $tickets->Next) {
+ $n++;
+
+ my $id = $ticket->Id;
+ if ($format eq "i") {
+ $output .= "ticket/" . $id . "\n";
+ }
+ elsif ($format eq "s") {
+ if ($fields) {
+ my $result = $m->comp("/REST/1.0/Forms/ticket/default", id => $id, format => $format, fields => \%fields);
+ my ($notes, $order, $key_values, $errors) = @$result;
+ # If it's the first time through, add our header
+ if ($n == 1) {
+ $output .= join("\t",@$order)."\n";
+ }
+ # Cut off the annoying ticket/ before the id;
+ $key_values->{'id'} = $id;
+ $output .= join("\t", map {$key_values->{$_}} @$order)."\n";
+
+
+ } else {
+ $output .= $ticket->Id . ": ". $ticket->Subject . "\n";
+ }
+ }
+ else {
+ my $d = $m->comp("/REST/1.0/Forms/ticket/default", id => $id, format => $format, fields => \%fields);
+ my ($c, $o, $k, $e) = @$d;
+ push @output, [ $c, $o, $k ];
+ }
+}
+if ($n == 0 && $format ne "i") {
+ $output = "No matching results.\n";
+}
+
+$output = form_compose(\@output) if @output;
+
+OUTPUT:
+$m->out("RT/". $RT::VERSION . " " . $status ."\n\n");
+
+$m->out($output );
+return();
+</%INIT>
diff --git a/rt/html/REST/1.0/ticket/comment b/rt/html/REST/1.0/ticket/comment
new file mode 100644
index 000000000..240dd90fb
--- /dev/null
+++ b/rt/html/REST/1.0/ticket/comment
@@ -0,0 +1,177 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/ticket/comment
+%#
+<%ARGS>
+$content
+</%ARGS>
+<%INIT>
+use MIME::Entity;
+use LWP::MediaTypes;
+use RT::Interface::REST;
+use File::Temp qw(tempfile);
+
+my $ticket = new RT::Ticket $session{CurrentUser};
+my $object = $r->path_info;
+my $status = "200 Ok";
+my $output;
+my $action;
+
+# http://.../REST/1.0/ticket/1/comment
+my ($c, $o, $k, $e) = @{ form_parse($content)->[0] };
+if ($e || !$o) {
+ if (!$o) {
+ $output = "Empty form submitted.\n";
+ }
+ else {
+ $c = "# Syntax error.";
+ $output = form_compose([[$c, $o, $k, $e]]);
+ }
+ $status = "400 Bad Request";
+ goto OUTPUT;
+}
+
+$object =~ s#^/##;
+$object ||= $k->{Ticket};
+unless ($object =~ /^\d+/) {
+ $output = "Invalid ticket id: `$object'.\n";
+ $status = "400 Bad Request";
+ goto OUTPUT;
+}
+if ($k->{Ticket} && $object ne $k->{Ticket}) {
+ $output = "The submitted form and URL specify different tickets.\n";
+ $status = "400 Bad Request";
+ goto OUTPUT;
+}
+
+($action = $k->{Action}) =~ s/^(.)(.*)$/\U$1\L$2\E/;
+unless ($action =~ /^(?:Comment|Correspond)$/) {
+ $output = "Invalid action: `$action'.\n";
+ $status = "400 Bad Request";
+ goto OUTPUT;
+}
+
+my $text = $k->{Text};
+my @atts = @{ vsplit($k->{Attachment}) };
+
+if (!$k->{Text} && @atts == 0) {
+ $status = "400 Bad Request";
+ $output = "Empty comment with no attachments submitted.\n";
+ goto OUTPUT;
+}
+
+my $cgi = $m->cgi_object;
+my $ent = MIME::Entity->build(Type => "multipart/mixed");
+$ent->attach(Data => $k->{Text}) if $k->{Text};
+
+my $i = 1;
+foreach my $att (@atts) {
+ local $/=undef;
+ my $file = $att;
+ $file =~ s#^.*[\\/]##;
+
+ my $fh = $cgi->upload("attachment_$i");
+ if ($fh) {
+ my $buf;
+ my ($w, $tmp) = tempfile();
+ my $info = $cgi->uploadInfo();
+
+ while (sysread($fh, $buf, 8192)) {
+ syswrite($w, $buf);
+ }
+
+ $ent->attach(
+ Path => $tmp,
+ Type => $info->{'Content-Type'} || guess_media_type($tmp),
+ Filename => $file,
+ Disposition => "attachment"
+ );
+ }
+ else {
+ $status = "400 Bad Request";
+ $output = "No attachment for $att.\n";
+ goto OUTPUT;
+ }
+
+ $i++;
+}
+
+$ticket->Load($object);
+unless ($ticket->Id) {
+ $output = "Couldn't load ticket id: `$object'.\n";
+ $status = "404 Ticket not found";
+ goto OUTPUT;
+}
+unless ($ticket->CurrentUserHasRight('ModifyTicket') ||
+ ($action eq "Comment" &&
+ $ticket->CurrentUserHasRight("CommentOnTicket")) ||
+ ($action eq "Correspond" &&
+ $ticket->CurrentUserHasRight("ReplyToTicket")))
+{
+ $output = "You are not allowed to $action on ticket $object.\n";
+ $status = "403 Permission denied";
+ goto OUTPUT;
+}
+
+my $cc = join ", ", @{ vsplit($k->{Cc}) };
+my $bcc = join ", ", @{ vsplit($k->{Bcc}) };
+my ($n, $s) = $ticket->$action(MIMEObj => $ent,
+ CcMessageTo => $cc,
+ BccMessageTo => $bcc,
+ TimeTaken => $k->{TimeWorked} || 0);
+$output = $s;
+if ($k->{Status}) {
+ my ($status_n, $status_s) = $ticket->SetStatus($k->{'Status'} );
+ $output .= "\n".$status_s;
+}
+
+OUTPUT:
+</%INIT>
+RT/<% $RT::VERSION %> <% $status %>
+
+<% $output |n %>
diff --git a/rt/html/REST/1.0/ticket/link b/rt/html/REST/1.0/ticket/link
new file mode 100644
index 000000000..766e12624
--- /dev/null
+++ b/rt/html/REST/1.0/ticket/link
@@ -0,0 +1,123 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/ticket/link
+%#
+<%ARGS>
+$id => undef
+$del => 0
+$rel
+$to
+</%ARGS>
+<%INIT>
+use RT::Interface::REST;
+
+my $output;
+my $status = "200 Ok";
+my $ticket = new RT::Ticket $session{CurrentUser};
+my $object = $r->path_info;
+
+my @fields = qw(DependsOn DependedOnBy RefersTo ReferredToBy HasMember MemberOf);
+my %fields = map { lc $_ => $_ } @fields;
+my %lfields = (
+ HasMember => { Type => 'MemberOf', Mode => 'Base' },
+ ReferredToBy => { Type => 'RefersTo', Mode => 'Base' },
+ DependedOnBy => { Type => 'DependsOn', Mode => 'Base' },
+ MemberOf => { Type => 'MemberOf', Mode => 'Target' },
+ RefersTo => { Type => 'RefersTo', Mode => 'Target' },
+ DependsOn => { Type => 'DependsOn', Mode => 'Target' },
+);
+
+# http://.../REST/1.0/ticket/link/1
+
+$object =~ s#^/REST/1.0/ticket/link##;
+if ($id && $object && $id != $object) {
+ $output = "Different ids in URL (`$object') and submitted form (`$id').\n";
+ $status = "400 Bad Request";
+ goto OUTPUT;
+}
+$id ||= $object;
+unless ($id =~ /^\d+$/ && $to =~ /^\d+$/) {
+ my $bad = ($id !~ /^\d+$/) ? $id : $to;
+ $output = $r->path_info. "\n";
+ $output .= "Invalid ticket id: '$bad'.\n";
+ $status = "400 Bad Request";
+ goto OUTPUT;
+}
+unless (exists $fields{lc $rel}) {
+ $output = "Invalid link: '$rel'.\n";
+ $status = "400 Bad Request";
+ goto OUTPUT;
+}
+$rel = $fields{lc $rel};
+
+$ticket->Load($id);
+unless ($ticket->Id) {
+ $output = "Couldn't load ticket id: '$id'.\n";
+ $status = "404 Ticket not found";
+ goto OUTPUT;
+}
+
+my $type = $lfields{$rel}->{Type};
+my $mode = $lfields{$rel}->{Mode};
+
+my $n = 1;
+my $op = $del ? "DeleteLink" : "AddLink";
+
+($n, $output) = $ticket->$op(Type => $type, $mode => $to);
+if ($n == 0) {
+ $status = "500 Error";
+} else {
+ my $action = $del ? "Deleted" : "Created";
+ $output .= " $action link " . $ticket->Id . " $rel $to";
+}
+
+OUTPUT:
+</%INIT>
+RT/<% $RT::VERSION %> <% $status %>
+
+<% $output |n %>
diff --git a/rt/html/REST/1.0/ticket/merge b/rt/html/REST/1.0/ticket/merge
new file mode 100644
index 000000000..d6ae96f83
--- /dev/null
+++ b/rt/html/REST/1.0/ticket/merge
@@ -0,0 +1,102 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# REST/1.0/ticket/merge
+%#
+<%ARGS>
+$id => undef
+$into
+</%ARGS>
+<%INIT>
+use RT::Interface::REST;
+
+my $output;
+my $status = "200 Ok";
+my $ticket = new RT::Ticket $session{CurrentUser};
+my $object = $r->path_info;
+
+# http://.../REST/1.0/ticket/merge/1
+
+$object =~ s#^/##;
+if ($id && $object && $id != $object) {
+ $output = "Different ids in URL (`$object') and submitted form (`$id').\n";
+ $status = "400 Bad Request";
+ goto OUTPUT;
+}
+$id ||= $object;
+unless ($id =~ /^\d+$/ && $into =~ /^\d+$/) {
+ my $bad = ($id !~ /^\d+$/) ? $id : $into;
+ $output = $r->path_info. "\n";
+ $output .= "Invalid ticket id: `$bad'.\n";
+ $status = "400 Bad Request";
+ goto OUTPUT;
+}
+
+$ticket->Load($id);
+unless ($ticket->Id) {
+ $output = "Couldn't load ticket id: `$id'.\n";
+ $status = "404 Ticket not found";
+ goto OUTPUT;
+}
+unless ($ticket->CurrentUserHasRight('ModifyTicket')) {
+ $output = "You are not allowed to modify ticket $id.\n";
+ $status = "403 Permission denied";
+ goto OUTPUT;
+}
+
+my ($n, $s) = $ticket->MergeInto($into);
+
+if ($n == 0) {
+ $status = "500 Error";
+}
+$output = $s;
+
+OUTPUT:
+</%INIT>
+RT/<% $RT::VERSION %> <% $status %>
+
+<% $output |n %>
diff --git a/rt/html/RTx/Statistics/CallsMultiQueue/Elements/Chart b/rt/html/RTx/Statistics/CallsMultiQueue/Elements/Chart
new file mode 100755
index 000000000..02a183b2c
--- /dev/null
+++ b/rt/html/RTx/Statistics/CallsMultiQueue/Elements/Chart
@@ -0,0 +1,39 @@
+<%perl>
+$r->content_type("image/$format");
+print $graph->plot(\@data)->$format();
+$m->abort();
+</%perl>
+<em><&|/l, $#data+1&>[_1] Plot Elements</&></em><p>
+% foreach my $value (@data) {
+<% $value %><p>
+% }
+<em><&|/l&>x_labels</&>:</em><p>
+<% $ARGS{x_labels} %>
+<p>
+<em><&|/l&>legend</&>:</em><p>
+<% $ARGS{set_legend} %>
+<p>
+<em><&|/l, (keys %ARGS) - 2&>[_1] data sets</&>:</em><p>
+
+% for (1..(scalar keys %ARGS)-2) {
+<% $_ %> <% $ARGS{"data$_"} %><p>
+% }
+
+<%INIT>
+use GD::Graph::lines;
+
+my @data;
+my $graph = GD::Graph::lines->new($Statistics::GraphWidth,$Statistics::GraphHeight);
+$graph->set(export_format => "png",
+ x_label => 'Day of Week',
+ y_label => 'Tickets per day');
+$graph->set_legend(split /,/ , $ARGS{set_legend});
+my $format = $graph->export_format;
+push @data, [split /,/ , $ARGS{x_labels}];
+for (1..((scalar keys %ARGS)-2)) {
+ push @data, [split /,/ , $ARGS{"data".$_}];
+}
+
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/RTx/Statistics/CallsMultiQueue/index.html b/rt/html/RTx/Statistics/CallsMultiQueue/index.html
new file mode 100755
index 000000000..abf8aa74a
--- /dev/null
+++ b/rt/html/RTx/Statistics/CallsMultiQueue/index.html
@@ -0,0 +1,330 @@
+<& /Elements/Header, Title => loc('Tickets per day in Multiple queues') &>
+<& /RTx/Statistics/Elements/Tabs, Title => loc('Tickets per day in Multiple Queues by status') &>
+
+<h3>Description</h3>
+<p>This chart shows details of tickets per day by their status. You can select multiple queues to display at the same time, but only one status. You can chose any of the defined status values.
+There is also the option to display all available queues at the same time.
+The default display shows tickets resolved in your default queue (General unless altered locally).
+The line chart below shows the same information in a graphical form.
+
+<br />
+
+<form method="POST" action="index.html">
+
+%# Build Legend
+% my @legend;
+% for (sort keys %queues_to_show) {
+% push @legend, $_;
+% }
+
+%my $title = "Tickets with Status $status in " . join(', ', @queues) . ", per day from " .
+% Statistics::FormatDate($Statistics::PerDayDateFormat, $dates[0]) . " through " .
+% Statistics::FormatDate($Statistics::PerDayDateFormat, $dates[$#dates-1]);
+
+<& /Elements/TitleBoxStart, title => $title, title_href => "/RTx/Statistics/OpenStalled/index.html?$QueryString"&>
+<TABLE BORDER=0 cellspacing=0 cellpadding=1 WIDTH="100%">
+% if ($ShowHeader) {
+<& /RTx/Statistics/Elements/CollectionAsTable/Header,
+ Format => \@RowFormat,
+ FormatString => $RowFormat,
+ AllowSorting => $AllowSorting,
+ Order => $Order,
+ Query => undef,
+ Rows => $Rows,
+ Page => $Page,
+ OrderBy => $OrderBy ,
+ BaseURL => $BaseURL,
+ maxitems => $maxitems &>
+% }
+% my $line = 0;
+% LINE: for my $d (0..$#dates) {
+% if ($d == $#dates ){
+% next LINE;
+% }
+% $line++;
+% my $x = 1;
+% $values{Statistics_Date} = Statistics::FormatDate($dateformat, $dates[$d]);
+% my $row_total=0;
+% foreach my $q (sort keys %queues_to_show) {
+% my $tix = new RT::Tickets($session{'CurrentUser'});
+% if ($status eq "resolved") {
+% $tix->LimitStatus(VALUE => $status);
+% $tix->LimitResolved(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+% if ($dates[$d+1]) {
+% $tix->LimitResolved(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+% }
+% }
+% elsif ($status eq "new") {
+% $tix->LimitCreated(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+% if ($dates[$d+1]) {
+% $tix->LimitCreated(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+% }
+% }
+% elsif ($status eq "deleted") {
+% $tix->LimitStatus(VALUE => $status);
+% $tix->LimitLastUpdated(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+% if ($dates[$d+1]) {
+% $tix->LimitLastUpdated(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+% }
+% }
+% elsif ($status eq "stalled") {
+% $tix->LimitStatus(VALUE => $status);
+% $tix->LimitLastUpdated(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+% if ($dates[$d+1]) {
+% $tix->LimitLastUpdated(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+% }
+% }
+% elsif ($status eq "open") {
+% $tix->LimitStatus(VALUE => $status);
+% $tix->LimitLastUpdated(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+% if ($dates[$d+1]) {
+% $tix->LimitLastUpdated(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+% }
+% }
+% elsif ($status eq "rejected") {
+% $tix->LimitStatus(VALUE => $status);
+% $tix->LimitLastUpdated(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+% if ($dates[$d+1]) {
+% $tix->LimitLastUpdated(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+% }
+% }
+% $tix->LimitQueue (VALUE => $q);
+% $values{$q} = $tix->Count;
+% $row_total += $tix->Count;
+% $data[$x++][$d] = $tix->Count;
+% }
+% $values{Statistics_Totals} = $row_total;
+<& /RTx/Statistics/Elements/CollectionAsTable/Row, Format => \@RowFormat, i => $line, record => $record, maxitems => $maxitems &>
+% }
+</table>
+<& /Elements/TitleBoxEnd&>
+
+<hr>
+
+<BR />
+<BR />
+
+<!-- <td>Show:</td>
+ <td COLSPAN=2><SELECT NAME="status">
+% for (qw(resolved new deleted stalled rejected open)) {
+ <OPTION VALUE="<% $_ %>" <% $_ eq $status && "SELECTED" %>>
+ <% loc($_) %></OPTION>
+% }
+--!>
+
+<%perl>
+# Create the graph URL
+my $url = 'Elements/Chart?x_labels=';
+#$url .= join ",", @{ shift @data } . "&";
+for (0..$max) {
+ $url .= $m->interp->apply_escapes($data[0][$_],'u') . ",";
+}
+chop $url;
+$url .= "&";
+shift @data;
+$url .= 'set_legend='.(join ",", @legend)."&";
+for (0..$#data) {
+ $url .= "data".(1+$_)."=". (join ",", @{$data[$_]})."&";
+}
+chop $url;
+</%perl>
+
+<& /RTx/Statistics/Elements/GraphBox, GraphURL => $url &>
+
+<& /RTx/Statistics/Elements/ControlsAsTable/ControlBox,
+ Title => "Change Status, Queues or Dates",
+ ShowDates => 1, sMonth => \$sMonth, sDay => \$sDay, sYear => \$sYear,
+ eMonth => \$eMonth, eDay => \$eDay, eYear => \$eYear,
+ weekends => $weekends,
+ ShowMultiQueues => 1, queues_ref => \@queues,
+ ShowStatus => 1, Status => $status
+ &>
+
+</form>
+
+<a href="<%$RT::WebPath%>/RTx/Statistics/CallsMultiQueue/index.html?<% $QueryString %>"><&|/l&>Bookmarkable link</&></a>
+%# | <a href="<%$RT::WebPath%>/RTx/Statistics/CallsMultiQueue/Results.tsv?<%$QueryString%>"><&|/l&>spreadsheet</&></a>
+<BR>
+<BR>
+
+<%ARGS>
+$status => $Statistics::MultiQueueStatus
+$max => $Statistics::MultiQueueMaxRows
+@queues => @Statistics::MultiQueueQueueList
+$weekends => $Statistics::PerDayWeekends;
+$sMonth=>undef
+$sDay=>undef
+$sYear=>undef
+$eMonth=>undef
+$eDay=>undef
+$eYear=>undef
+$days=>undef
+$dateformat => $Statistics::MultiQueueDateFormat
+$currentMonth=>undef
+
+$AllowSorting => undef
+$Order => undef
+$OrderBy => undef
+$ShowNavigation => 1
+$ShowHeader => 1
+$Rows => 50
+$Page => 1
+$BaseURL => undef
+$AddAllCheck => undef
+</%ARGS>
+
+<%INIT>
+
+use RTx::Statistics;
+use Time::Local;
+my $n = 0;
+my @data = ([]);
+my @dates;
+my @msgs;
+my $selected;
+my $diff;
+my %queues_to_show;
+my $secsPerDay=86400;
+my $sEpoch;
+my $eEpoch;
+my $QueryString;
+my $maxitems;
+my $RowFormat;
+my $BoldRowFormat;
+my %record;
+my %values;
+my $record = \%record;
+
+$record{values} = \%values;
+
+Statistics::DebugClear();
+Statistics::DebugLog("CallsQueueDay/index.html ARGS:\n");
+for my $key (keys %ARGS) {
+ Statistics::DebugLog("ARG{ $key }=" . $ARGS{$key} . "\n");
+}
+
+
+ # Handle the Add All Checkbox
+ if($AddAllCheck eq "on") {
+ $AddAllCheck = undef;
+ undef (@queues);
+ my $q=new RT::Queues($session{'CurrentUser'});
+ $q->UnLimit;
+ while (my $queue=$q->Next) {
+ next if !$queue->CurrentUserHasRight('SeeQueue');
+ push @queues, $queue->Name;
+ }
+ }
+
+ # If the user has the right to see the queue, put it into the map
+ for my $q (@queues) {
+ my $Queueobj = new RT::Queue($session{'CurrentUser'});
+ $Queueobj->Load($q);
+ next if !$Queueobj->CurrentUserHasRight('SeeQueue');
+ $queues_to_show{$q} = 1;
+ }
+
+ $maxitems = (scalar @queues) + 2;
+
+ # Build the format strings
+ $RowFormat = "'__Statistics_Date__'";
+ $BoldRowFormat = "'<B>__Statistics_Date__</B>'";
+ for my $q (@queues) {
+ $RowFormat .= ",'__Statistics_Dynamic__/KEY:$q/TITLE:$q/STYLE:text-align:right;'";
+ $BoldRowFormat .= ",'<B>__Statistics_Dynamic__</B>/KEY:$q/TITLE:$q/STYLE:text-align:right;'";
+ }
+ $RowFormat .= ",'<B>__Statistics_Totals__</B>/STYLE:text-align:right;'";
+ $BoldRowFormat .= ",'<B>__Statistics_Totals__</B>/STYLE:text-align:right;'";
+ # Parse the formats into structures.
+ my (@RowFormat) = $m->comp('/RTx/Statistics/Elements/CollectionAsTable/ParseFormat', Format => $RowFormat);
+ my (@BoldRowFormat) = $m->comp('/RTx/Statistics/Elements/CollectionAsTable/ParseFormat', Format => $BoldRowFormat);
+
+if ($sDay > $Statistics::monthsMaxDay{$sMonth}) {
+ $sDay = $Statistics::monthsMaxDay{$sMonth};
+}
+
+if ($eDay > $Statistics::monthsMaxDay{$eMonth}) {
+ $eDay = $Statistics::monthsMaxDay{$eMonth};
+}
+
+if ($sYear){
+ $sEpoch = timelocal(0, 0, 0, $sDay, $sMonth, $sYear-1900);
+}
+if ($eYear){
+Statistics::DebugLog("eMonth = " . $eMonth . "\n");
+ $eEpoch = timelocal(0, 0, 0, $eDay, $eMonth, $eYear-1900);
+} else {
+ # This case happens when the page is first loaded
+ my @local = localtime(time);
+ ($eDay, $eMonth, $eYear) = ($local[3], $local[4], $local[5]);
+ $eYear += 1900;
+ $eEpoch = timelocal(0, 0, 0, $local[3], $local[4], $local[5], $local[6], $local[7], $local[8]);
+Statistics::DebugLog("Setting eEpoch=$eEpoch from current time.\n");
+}
+
+if (($eEpoch < $sEpoch) || ($sEpoch == 0)) {
+ # We have an end, but not a start, or, overlapping.
+
+ # if $currentMonth is set, just set the day to 1
+ if($currentMonth) {
+ # set start vars from end, but with day set to 1
+ (undef, undef, undef, $sDay, $sMonth, $sYear) = localtime($eEpoch);
+ $sDay=1;
+ $sEpoch = timelocal(0, 0, 0, $sDay, $sMonth, $sYear);
+ } else {
+ # If the user has specified how many days back to go, use that,
+ # If not, set start to configured default period before end
+ if(defined $days) {
+ $sEpoch = $eEpoch - ($days * $Statistics::secsPerDay);
+ } else {
+ $sEpoch = $eEpoch - ($Statistics::PerDayPeriod * $Statistics::secsPerDay);
+ }
+ (undef, undef, undef, $sDay, $sMonth, $sYear) = localtime($sEpoch);
+ }
+ $sYear += 1900;
+}
+
+# Compute days to chart.
+# The +1 is because we need to generate one more date. If the user
+# selected a 10 day range, we need to generate 11 days.
+$diff = int(($eEpoch - $sEpoch + $Statistics::secsPerDay - 1) / $Statistics::secsPerDay)+1;
+Statistics::DebugLog("Setting diff=$diff\n");
+
+Statistics::DebugLog("sEpoch=$sEpoch, components=" . join(',', localtime($sEpoch)) . "\n");
+Statistics::DebugLog("eEpoch=$eEpoch, components=" . join(',', localtime($eEpoch)) . "\n");
+
+# Build the new query string
+$QueryString = "queues=" . join("&queues=", @queues);
+$QueryString .= "&sDay=$sDay&sMonth=$sMonth&sYear=$sYear&eDay=$eDay&eMonth=$eMonth&eYear=$eYear&weekends=$weekends";
+
+
+
+
+# Set up the end date to be midnight(morning) of the date after the one the user wanted.
+my $endRange = $eEpoch + $Statistics::secsPerDay;
+$n = 0;
+until ($#dates == $diff) {
+ my $date = new RT::Date($session{CurrentUser});
+ $date->Set(Value=>$endRange - $n, Format => 'unix');
+ # Note: we used to adjust the time to local midnight, but
+ # none of the other date entry fields in RT seem to adjust, so we've stopped.
+ #Statistics::DebugLog("Before adjust to midnight date " . Statistics::FormatDate("%c", $date) . "\n");
+ $n+= $Statistics::secsPerDay;
+ # If we aren't showing weekends and this is one, decrement the number
+ # of days to show and skip to the next date.
+ if(!$weekends and Statistics::RTDateIsWeekend($date)) {$diff--; next;}
+ unshift @dates, $date;
+Statistics::DebugLog("pushing date " . Statistics::FormatDate("%c", $date) . "\n");
+ unshift @{ $data[0] }, Statistics::FormatDate($Statistics::PerDayLabelDateFormat, $date);
+}
+
+# We put an extra day into the lists to cover up till midnight of the next day,
+# But we don't want that to appear in the labels, so pop it off.
+pop( @{ $data[0] } );
+
+my $queue = new RT::Queues($session{CurrentUser});
+$queue->UnLimit;
+
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($queue);
+</%INIT>
diff --git a/rt/html/RTx/Statistics/CallsQueueDay/Elements/Chart b/rt/html/RTx/Statistics/CallsQueueDay/Elements/Chart
new file mode 100755
index 000000000..9a3a50574
--- /dev/null
+++ b/rt/html/RTx/Statistics/CallsQueueDay/Elements/Chart
@@ -0,0 +1,29 @@
+<%perl>
+$r->content_type("image/$format");
+print $graph->plot(\@data)->$format();
+$m->abort();
+print $#data+1 . " Elements:<p>";
+for (0..$#data) {
+print $data[$_];
+print "<p>";
+}
+</%perl>
+<%INIT>
+use GD::Graph::lines;
+
+my @data;
+my $graph = GD::Graph::lines->new($Statistics::GraphWidth,$Statistics::GraphHeight);
+$graph->set(export_format => "png",
+ x_label => 'Day of Week',
+ y_label => 'Tickets per Day',
+ x_labels_vertical => 1,
+ );
+my $format = $graph->export_format;
+$graph->set_legend(split /,/ , $ARGS{set_legend});
+push @data, [split /,/ , $ARGS{x_labels}];
+push @data, [split /,/ , $ARGS{data1}];
+push @data, [split /,/ , $ARGS{data2}];
+push @data, [split /,/ , $ARGS{data3}];
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/RTx/Statistics/CallsQueueDay/Results.tsv b/rt/html/RTx/Statistics/CallsQueueDay/Results.tsv
new file mode 100644
index 000000000..23f0c699c
--- /dev/null
+++ b/rt/html/RTx/Statistics/CallsQueueDay/Results.tsv
@@ -0,0 +1,191 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+$Queue => undef
+$weekends => $Statistics::PerDayWeekends;
+$sMonth=>undef
+$sDay=>undef
+$sYear=>undef
+$eMonth=>undef
+$eDay=>undef
+$eYear=>undef
+$days=>undef
+$currentMonth=>undef
+</%ARGS>
+
+<%INIT>
+use RTx::Statistics;
+use Time::Local;
+my @dates;
+my $n = 0;
+my %Totals;
+my $now = new RT::Date($session{CurrentUser});
+my $sEpoch;
+my $eEpoch;
+
+if (!defined $Queue) {
+ $Queue = $Statistics::PerDayQueue;
+}
+
+if ($sDay > $Statistics::monthsMaxDay{$sMonth}) {
+ $sDay = $Statistics::monthsMaxDay{$sMonth};
+}
+
+if ($eDay > $Statistics::monthsMaxDay{$eMonth}) {
+ $eDay = $Statistics::monthsMaxDay{$eMonth};
+}
+
+if ($sYear){
+ $sEpoch = timelocal(0, 0, 0, $sDay, $sMonth, $sYear-1900);
+}
+if ($eYear){
+Statistics::DebugLog("eMonth = " . $eMonth . "\n");
+ $eEpoch = timelocal(0, 0, 0, $eDay, $eMonth, $eYear-1900);
+} else {
+ # This case happens when the page is first loaded
+ my @local = localtime(time);
+ ($eDay, $eMonth, $eYear) = ($local[3], $local[4], $local[5]);
+ $eYear += 1900;
+ $eEpoch = timelocal(0, 0, 0, $local[3], $local[4], $local[5], $local[6], $local[7], $local[8]);
+Statistics::DebugLog("Setting eEpoch=$eEpoch from current time.\n");
+}
+
+if (($eEpoch < $sEpoch) || ($sEpoch == 0)) {
+ # We have an end, but not a start, or, overlapping.
+
+ # if $currentMonth is set, just set the day to 1
+ if($currentMonth) {
+ # set start vars from end, but with day set to 1
+ (undef, undef, undef, $sDay, $sMonth, $sYear) = localtime($eEpoch);
+ $sDay=1;
+ $sEpoch = timelocal(0, 0, 0, $sDay, $sMonth, $sYear);
+ } else {
+ # If the user has specified how many days back to go, use that,
+ # If not, set start to configured default period before end
+ if(defined $days) {
+ $sEpoch = $eEpoch - ($days * $Statistics::secsPerDay);
+ } else {
+ $sEpoch = $eEpoch - ($Statistics::PerDayPeriod * $Statistics::secsPerDay);
+ }
+ (undef, undef, undef, $sDay, $sMonth, $sYear) = localtime($sEpoch);
+ }
+ $sYear += 1900;
+}
+
+# set content type
+$r->content_type('application/vnd.ms-excel');
+
+# Put out some data about the generation of this file
+$m->out("Tickets per day for Queue:\t" . $Queue . "\tGenerated at:\t" . Statistics::FormatDate("%x %X", $now). "\n\n");
+
+
+# Compute days to chart.
+# The +1 is because we need to generate one more date. If the user
+# selected a 10 day range, we need to generate 11 days.
+my $diff = int(($eEpoch - $sEpoch + $Statistics::secsPerDay - 1) / $Statistics::secsPerDay)+1;
+
+# Build array of dates
+my $endRange = $eEpoch + $Statistics::secsPerDay;
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($Queue);
+until ($#dates == $diff) {
+ my $date = new RT::Date($session{CurrentUser});
+ $date->Set(Value=>$endRange - $n, Format => 'unix');
+ # Note: we used to adjust the time to local midnight, but
+ # none of the other date entry fields in RT seem to adjust, so we've stopped.
+ #Statistics::DebugLog("Before adjust to midnight date " . Statistics::FormatDate("%c", $date) . "\n");
+ $n+= $Statistics::secsPerDay;
+ # If we aren't showing weekends and this is one, decrement the number
+ # of days to show and skip to the next date.
+ if(!$weekends and Statistics::RTDateIsWeekend($date)) {$diff--; next;}
+ unshift @dates, $date;
+}
+
+# Output header row
+$m->out("Date\tcreate\tresolved\tdeleted\n");
+
+
+LINE: for my $d (0..$#dates) {
+ if ($d == $#dates){
+ next LINE;
+ }
+ my $x = 1;
+ # Output the date for this row
+ $m->out(Statistics::FormatDate($Statistics::PerDayDateFormat, $dates[$d]));
+
+ # output the 3 columns for this row
+ for my $status (qw(created resolved deleted)) {
+ my $tix = new RT::Tickets($session{'CurrentUser'});
+ if ($status eq "created") {
+ $tix->LimitCreated(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+ if ($dates[$d+1]) {
+ $tix->LimitCreated(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+ }
+ } elsif ($status eq "resolved") {
+ $tix->LimitStatus(VALUE => $status);
+ $tix->LimitResolved(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+ if ($dates[$d+1]) {
+ $tix->LimitResolved(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+ }
+ } elsif ($status eq "deleted") {
+ $tix->LimitStatus(VALUE => $status);
+ $tix->LimitLastUpdated(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+ if ($dates[$d+1]) {
+ $tix->LimitLastUpdated(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+ }
+ }
+ $tix->LimitQueue (VALUE => $Queue);
+ $m->out( "\t" . $tix->Count );
+ $Totals{$status} += $tix->Count;
+ }
+ $m->out("\n");
+}
+
+# Output the totals
+$m->out("Totals\t$Totals{created}\t$Totals{resolved}\t$Totals{deleted}\n");
+
+$m->abort();
+</%INIT>
diff --git a/rt/html/RTx/Statistics/CallsQueueDay/index.html b/rt/html/RTx/Statistics/CallsQueueDay/index.html
new file mode 100755
index 000000000..06fc484d1
--- /dev/null
+++ b/rt/html/RTx/Statistics/CallsQueueDay/index.html
@@ -0,0 +1,275 @@
+<& /Elements/Header, Title => loc("Tickets per day in Queue:" . $QueueObj->Name()) &>
+<& /RTx/Statistics/Elements/Tabs, Title => loc("Tickets by status per day in Queue:" . $QueueObj->Name()) &>
+
+<h3>Description</h3>
+<p>This page displays details about tickets in the selected queue over the date range chosen. It shows how many tickets were created on
+each day in the chosen range, and how many of those were either Resolved or Deleted.</p>
+<p>To always show the current month to date, bookmark this <a href="<%$RT::WebPath%>/RTx/Statistics/CallsQueueDay/index.html?currentMonth=1">link</a>, or
+for a spreadsheet, use this <a href="<%$RT::WebPath%>/RTx/Statistics/CallsQueueDay/Results.tsv?currentMonth=1">link</a>.</p>
+
+<form method="POST" action="index.html">
+
+% Statistics::DebugLog("queue name=" . $QueueObj->Name() . "\n");
+
+%my $title = "Ticket counts in " . $QueueObj->Name() . " by status per day from " .
+% Statistics::FormatDate($Statistics::PerDayDateFormat, $dates[0]) . " through " .
+% Statistics::FormatDate($Statistics::PerDayDateFormat, $dates[$#dates-1]);
+<&|/Elements/TitleBox,
+ title => $title,
+ title_href => "/RTx/Statistics/CallsQueueDay/index.html?$QueryString" &>
+<TABLE BORDER=0 cellspacing=0 cellpadding=1 WIDTH=100%>
+% if ($ShowHeader) {
+<& /RTx/Statistics/Elements/CollectionAsTable/Header,
+ Format => \@Format,
+ FormatString => $Format,
+ AllowSorting => $AllowSorting,
+ Order => $Order,
+ Query => undef,
+ Rows => $Rows,
+ Page => $Page,
+ OrderBy => $OrderBy ,
+ BaseURL => $BaseURL,
+ maxitems => $maxitems &>
+% }
+% my $line = 1;
+% LINE: for my $d (0..$#dates) {
+% if ($d == $#dates){
+% next LINE;
+% }
+% my $x = 1;
+% $values{Statistics_Date} = Statistics::FormatDate($Statistics::PerDayDateFormat, $dates[$d]);
+%# NOTE need to handle all status values here....
+% for my $status (qw(created resolved deleted)) {
+% my $tix = new RT::Tickets($session{'CurrentUser'});
+% $tix->LimitQueue (VALUE => $Queue);
+% if ($status eq "created") {
+% $tix->LimitCreated(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+% if ($dates[$d+1]) {
+% $tix->LimitCreated(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+% }
+% $values{Statistics_Created_Count} = $tix->Count;
+% $Totals{Statistics_Created_Count} += $tix->Count;
+% }
+% elsif ($status eq "resolved") {
+% $tix->LimitStatus(VALUE => $status);
+% $tix->LimitResolved(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+% if ($dates[$d+1]) {
+% $tix->LimitResolved(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+% }
+% $values{Statistics_Resolved_Count} = $tix->Count;
+% $Totals{Statistics_Resolved_Count} += $tix->Count;
+% }
+% elsif ($status eq "deleted") {
+% $tix->LimitStatus(VALUE => $status);
+% $tix->LimitLastUpdated(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+% if ($dates[$d+1]) {
+% $tix->LimitLastUpdated(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+% }
+% $values{Statistics_Deleted_Count} = $tix->Count;
+% $Totals{Statistics_Deleted_Count} += $tix->Count;
+% }
+% $data[$x++][$d] = $tix->Count;
+% }
+<& /RTx/Statistics/Elements/CollectionAsTable/Row, Format => \@Format, i => $line, record => $record, maxitems => $maxitems &>
+% $line++;
+% }
+% $values {Statistics_Date} = "Totals";
+% $values {Statistics_Created_Count} = $Totals{Statistics_Created_Count};
+% $values {Statistics_Resolved_Count} = $Totals{Statistics_Resolved_Count};
+% $values {Statistics_Deleted_Count} = $Totals{Statistics_Deleted_Count};
+<& /RTx/Statistics/Elements/CollectionAsTable/Row, Format => \@BoldFormat, i => $line, record => $record, maxitems => $maxitems &>
+</table>
+</&>
+
+<hr>
+
+<BR />
+<BR />
+
+<%perl>
+# Create the graph URL
+my $url= 'Elements/Chart?x_labels=';
+for (1..$diff) {
+ $url .= $data[0][$_] . ",";
+}
+chop $url;
+$url .= "&";
+shift @data;
+for (0..$#data) {
+ $url .= "data".(1+$_)."=".(join ",", @{$data[$_]})."&";
+}
+chop $url;
+$url .= "&set_legend=Created,Resolved,Deleted";
+</%perl>
+
+<& /RTx/Statistics/Elements/GraphBox, GraphURL => $url &>
+
+<& /RTx/Statistics/Elements/ControlsAsTable/ControlBox,
+ Title => "Change Queue or Dates",
+ ShowDates => 1, sMonth => \$sMonth, sDay => \$sDay, sYear => \$sYear,
+ eMonth => \$eMonth, eDay => \$eDay, eYear => \$eYear,
+ weekends => $weekends,
+ ShowSingleQueue => 1, Queue => $Queue
+ &>
+
+</form>
+
+<a href="<%$RT::WebPath%>/RTx/Statistics/CallsQueueDay/index.html?<% $QueryString %>"><&|/l&>Bookmarkable link</&></a> |
+<a href="<%$RT::WebPath%>/RTx/Statistics/CallsQueueDay/Results.tsv?<%$QueryString%>"><&|/l&>spreadsheet</&></a>
+<BR>
+<BR>
+
+
+% Statistics::DebugLog("ref of eMonth is " . ref($eMonth) . "\n");
+% Statistics::DebugInit( $m );
+
+<%ARGS>
+$Queue => undef
+$weekends => $Statistics::PerDayWeekends;
+$sMonth=>undef
+$sDay=>undef
+$sYear=>undef
+$eMonth=>undef
+$eDay=>undef
+$eYear=>undef
+$days=>undef
+$currentMonth=>undef
+
+$AllowSorting => undef
+$Order => undef
+$OrderBy => undef
+$ShowNavigation => 1
+$ShowHeader => 1
+$Rows => 50
+$Page => 1
+$BaseURL => undef
+</%ARGS>
+
+<%INIT>
+use RTx::Statistics;
+use Time::Local;
+my $selected;
+my $n = 0;
+my @data = ([]);
+my @dates;
+my @msgs;
+my $diff;
+my $sEpoch=0;
+my $eEpoch=0;
+my %Totals;
+my $QueryString;
+my $maxitems = 4;
+my %record;
+my %values;
+my $record = \%record;
+
+$record{values} = \%values;
+
+
+# If debugging, set things up and display all the args
+Statistics::DebugClear();
+Statistics::DebugLog("CallsQueueDay/index.html ARGS:\n");
+for my $key (keys %ARGS) {
+ Statistics::DebugLog("ARG{ $key }=" . $ARGS{$key} . "\n");
+}
+
+my $Format = qq{ Statistics_Date,
+ '__Statistics_Created_Count__/STYLE:text-align:right;',
+ '__Statistics_Resolved_Count__/STYLE:text-align:right;',
+ '__Statistics_Deleted_Count__/STYLE:text-align:right;' };
+my $BoldFormat = qq{ '<B>__Statistics_Date__</B>',
+ '<B>__Statistics_Created_Count__</B>/STYLE:text-align:right;',
+ '<B>__Statistics_Resolved_Count__</B>/STYLE:text-align:right;',
+ '<B>__Statistics_Deleted_Count__</B>/STYLE:text-align:right;' };
+my (@Format) = $m->comp('/RTx/Statistics/Elements/CollectionAsTable/ParseFormat', Format => $Format);
+my (@BoldFormat) = $m->comp('/RTx/Statistics/Elements/CollectionAsTable/ParseFormat', Format => $BoldFormat);
+Statistics::DebugLog("CallsQueueDay/index.html Format array=" . join(',', @Format) . "\n");
+
+if (!defined $Queue) {
+ my $QueueObj = new RT::Queue($session{'CurrentUser'});
+ $QueueObj->Load($Statistics::PerDayQueue);
+ $Queue = $QueueObj->Id();
+}
+
+if ($sDay > $Statistics::monthsMaxDay{$sMonth}) {
+ $sDay = $Statistics::monthsMaxDay{$sMonth};
+}
+
+if ($eDay > $Statistics::monthsMaxDay{$eMonth}) {
+ $eDay = $Statistics::monthsMaxDay{$eMonth};
+}
+
+if ($sYear){
+ $sEpoch = timelocal(0, 0, 0, $sDay, $sMonth, $sYear-1900);
+}
+if ($eYear){
+Statistics::DebugLog("eMonth = " . $eMonth . "\n");
+ $eEpoch = timelocal(0, 0, 0, $eDay, $eMonth, $eYear-1900);
+} else {
+ # This case happens when the page is first loaded
+ my @local = localtime(time);
+ ($eDay, $eMonth, $eYear) = ($local[3], $local[4], $local[5]);
+ $eYear += 1900;
+ $eEpoch = timelocal(0, 0, 0, $local[3], $local[4], $local[5], $local[6], $local[7], $local[8]);
+Statistics::DebugLog("Setting eEpoch=$eEpoch from current time.\n");
+}
+
+if (($eEpoch < $sEpoch) || ($sEpoch == 0)) {
+ # We have an end, but not a start, or, overlapping.
+
+ # if $currentMonth is set, just set the day to 1
+ if($currentMonth) {
+ # set start vars from end, but with day set to 1
+ (undef, undef, undef, $sDay, $sMonth, $sYear) = localtime($eEpoch);
+ $sDay=1;
+ $sEpoch = timelocal(0, 0, 0, $sDay, $sMonth, $sYear);
+ } else {
+ # If the user has specified how many days back to go, use that,
+ # If not, set start to configured default period before end
+ if(defined $days) {
+ $sEpoch = $eEpoch - ($days * $Statistics::secsPerDay);
+ } else {
+ $sEpoch = $eEpoch - ($Statistics::PerDayPeriod * $Statistics::secsPerDay);
+ }
+ (undef, undef, undef, $sDay, $sMonth, $sYear) = localtime($sEpoch);
+ }
+ $sYear += 1900;
+}
+
+# Compute days to chart.
+# The +1 is because we need to generate one more date. If the user
+# selected a 10 day range, we need to generate 11 days.
+$diff = int(($eEpoch - $sEpoch + $Statistics::secsPerDay - 1) / $Statistics::secsPerDay)+1;
+Statistics::DebugLog("Setting diff=$diff\n");
+
+Statistics::DebugLog("sEpoch=$sEpoch, components=" . join(',', localtime($sEpoch)) . "\n");
+Statistics::DebugLog("eEpoch=$eEpoch, components=" . join(',', localtime($eEpoch)) . "\n");
+
+# Set up the string for the current query for bookmarkable link
+$QueryString = "sDay=$sDay&sMonth=$sMonth&sYear=$sYear&eDay=$eDay&eMonth=$eMonth&eYear=$eYear&weekends=$weekends&Queue=$Queue";
+
+# Set up the end date to be midnight(morning) of the date after the one the user wanted.
+my $endRange = $eEpoch + $Statistics::secsPerDay;
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($Queue);
+$n = 0;
+until ($#dates == $diff) {
+ my $date = new RT::Date($session{CurrentUser});
+ $date->Set(Value=>$endRange - $n, Format => 'unix');
+ # Note: we used to adjust the time to local midnight, but
+ # none of the other date entry fields in RT seem to adjust, so we've stopped.
+ #Statistics::DebugLog("Before adjust to midnight date " . Statistics::FormatDate("%c", $date) . "\n");
+ $n+= $Statistics::secsPerDay;
+ # If we aren't showing weekends and this is one, decrement the number
+ # of days to show and skip to the next date.
+ if(!$weekends and Statistics::RTDateIsWeekend($date)) {$diff--; next;}
+ unshift @dates, $date;
+Statistics::DebugLog("pushing date " . Statistics::FormatDate("%c", $date) . "\n");
+ unshift @{ $data[0] }, Statistics::FormatDate($Statistics::PerDayLabelDateFormat, $date);
+}
+
+# We put an extra day into the lists to cover up till midnight of the next day,
+# But we don't want that to appear in the labels, so pop it off.
+pop( @{ $data[0] } );
+
+</%INIT>
diff --git a/rt/html/RTx/Statistics/DayOfWeek/Elements/Chart b/rt/html/RTx/Statistics/DayOfWeek/Elements/Chart
new file mode 100755
index 000000000..239c09541
--- /dev/null
+++ b/rt/html/RTx/Statistics/DayOfWeek/Elements/Chart
@@ -0,0 +1,26 @@
+% $r->content_type("image/$format");
+% $m->print($graph->plot(\@data)->$format());
+% $m->abort();
+<&|/l, $#data+1&>[_1] Elements</&>:<p>
+% for (0..$#data) {
+<% $data[$_] %><p>
+% }
+<%INIT>
+use GD::Graph::bars;
+
+my @data;
+my $graph = GD::Graph::bars->new($Statistics::GraphWidth,$Statistics::GraphHeight);
+$graph->set(export_format => "png",
+ x_label => 'Day of Week',
+ y_label => 'Ticket actions per Day by type');
+$graph->set_legend(split /,/ , $ARGS{set_legend});
+push @data, [split /,/ , $ARGS{x_labels}];
+push @data, [split /,/ , $ARGS{data1}];
+push @data, [split /,/ , $ARGS{data2}];
+push @data, [split /,/ , $ARGS{data3}];
+
+my $format = $graph->export_format;
+$r->content_type("image/$format");
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/RTx/Statistics/DayOfWeek/index.html b/rt/html/RTx/Statistics/DayOfWeek/index.html
new file mode 100755
index 000000000..2e82b9c24
--- /dev/null
+++ b/rt/html/RTx/Statistics/DayOfWeek/index.html
@@ -0,0 +1,155 @@
+<& /Elements/Header, Title =>loc('Tickets by Day Of Week in Queue:' . $QueueObj->Name()) &>
+<& /RTx/Statistics/Elements/Tabs, Title =>loc('Trends in ticket status by Day Of Week in Queue:' . $QueueObj->Name()) &>
+
+<h3>Description</h3>
+<p>The purpose of this page is to show historical trends for each day of the week.
+It displays details of number of tickets created in your
+selected queue for each day. It also hows how many of those created tickets were Resolved or Deleted</p>
+
+<form method="POST" action="index.html">
+
+
+%my $title = "Ticket counts by day of week in " . $QueueObj->Name();
+<&|/Elements/TitleBox,
+ title => $title,
+ title_href => "/RTx/Statistics/DayOfWeek/index.html?$QueryString" &>
+<TABLE BORDER=0 cellspacing=0 cellpadding=1 WIDTH=100%>
+% if ($ShowHeader) {
+<& /RTx/Statistics/Elements/CollectionAsTable/Header,
+ Format => \@Format,
+ FormatString => $Format,
+ AllowSorting => $AllowSorting,
+ Order => $Order,
+ Query => undef,
+ Rows => $Rows,
+ Page => $Page,
+ OrderBy => $OrderBy ,
+ BaseURL => $BaseURL,
+ maxitems => $maxitems &>
+% }
+% my $line = 1;
+% for my $d (0..$#days) {
+% my $x = 1;
+% $values{Statistics_Date} = $days[$d];
+%# NOTE Show all status values???
+% $values{Statistics_Created_Count} = $counts[$d]{new};
+% $values{Statistics_Resolved_Count} = $counts[$d]{resolved};
+% $values{Statistics_Deleted_Count} = $counts[$d]{deleted};
+<& /RTx/Statistics/Elements/CollectionAsTable/Row, Format => \@Format, i => $line, record => $record, maxitems => $maxitems &>
+% $line++;
+% }
+% $values {Statistics_Date} = "Totals";
+% $values {Statistics_Created_Count} = $Totals{new};
+% $values {Statistics_Resolved_Count} = $Totals{resolved};
+% $values {Statistics_Deleted_Count} = $Totals{deleted};
+<& /RTx/Statistics/Elements/CollectionAsTable/Row, Format => \@BoldFormat, i => $line, record => $record, maxitems => $maxitems &>
+</table>
+</&>
+
+<hr>
+
+<BR />
+<BR />
+
+<%perl>
+my $url = 'Elements/Chart?&x_labels=';
+for (0..$#days) {
+ $url .= $days[$_] . "," ;
+}
+chop $url;
+$url .= "&";
+
+my @things = qw(new resolved deleted);
+for my $th (0..$#things) {
+ $url .= "data".(1+$th)."=".(join ",", map { $counts[$_]{$things[$th]} } (0..6))."&";
+}
+chop $url;
+$url .= '&set_legend=Created,Resolved,Deleted';
+</%perl>
+
+<& /RTx/Statistics/Elements/GraphBox, GraphURL => $url &>
+
+% Statistics::DebugLog("queue name=" . $QueueObj->Id() . "\n");
+
+<& /RTx/Statistics/Elements/ControlsAsTable/ControlBox,
+ Title => "Change Queue",
+ ShowSingleQueue => 1, Queue => $QueueObj->Id()
+ &>
+
+</form>
+
+% Statistics::DebugInit( $m );
+
+<%ARGS>
+$Queue => $Statistics::DayOfWeekQueue
+
+$AllowSorting => undef
+$Order => undef
+$OrderBy => undef
+$ShowNavigation => 1
+$ShowHeader => 1
+$Rows => 50
+$Page => 1
+$BaseURL => undef
+</%ARGS>
+
+<%INIT>
+use GD::Graph;
+use RTx::Statistics;
+my @days = qw(Sun Mon Tue Wed Thu Fri Sat);
+my $n = 0;
+my @data = ([]);
+my @msgs;
+my @counts;
+my %Totals = (
+ resolved => 0,
+ deleted => 0,
+ new => 0
+);
+my $QueryString = "Queue=$Queue";
+my $maxitems = 4;
+my %record;
+my %values;
+my $record = \%record;
+
+$record{values} = \%values;
+
+my $Format = qq{ Statistics_Date,
+ '__Statistics_Created_Count__/STYLE:text-align:right;',
+ '__Statistics_Resolved_Count__/STYLE:text-align:right;',
+ '__Statistics_Deleted_Count__/STYLE:text-align:right;' };
+my $BoldFormat = qq{ '<B>__Statistics_Date__</B>',
+ '<B>__Statistics_Created_Count__</B>/STYLE:text-align:right;',
+ '<B>__Statistics_Resolved_Count__</B>/STYLE:text-align:right;',
+ '<B>__Statistics_Deleted_Count__</B>/STYLE:text-align:right;' };
+my (@Format) = $m->comp('/RTx/Statistics/Elements/CollectionAsTable/ParseFormat', Format => $Format);
+my (@BoldFormat) = $m->comp('/RTx/Statistics/Elements/CollectionAsTable/ParseFormat', Format => $BoldFormat);
+
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($Queue);
+$RT::Logger->warning("Loaded queue $Queue, name=". $QueueObj->Name());
+
+my $tix = new RT::Tickets($session{'CurrentUser'});
+$tix->LimitQueue (VALUE => $Queue);
+$tix->UnLimit;
+if ($tix->Count) {
+ # Initialize the counters to zero, so that all the cells show up
+ foreach my $day (0..@days) {
+ $counts[$day]{resolved} = 0;
+ $counts[$day]{deleted} = 0;
+ $counts[$day]{new} = 0;
+ }
+ while (my $t = $tix->RT::SearchBuilder::Next) { # BLOODY HACK
+ if($t->Status eq "resolved") {
+ $counts[(localtime($t->ResolvedObj->Unix))[6]]{resolved}++;
+ $Totals{resolved}++;
+ }
+ if($t->Status eq "deleted") {
+ $counts[(localtime($t->LastUpdatedObj->Unix))[6]]{deleted}++;
+ $Totals{deleted}++;
+ }
+ $counts[(localtime($t->CreatedObj->Unix))[6]]{new}++;
+ $Totals{new}++;
+ }
+}
+</%INIT>
diff --git a/rt/html/RTx/Statistics/DurationAsString b/rt/html/RTx/Statistics/DurationAsString
new file mode 100755
index 000000000..c0b4d9af4
--- /dev/null
+++ b/rt/html/RTx/Statistics/DurationAsString
@@ -0,0 +1,18 @@
+<%$days|'00'%> days <%$hours|'00'%>:<%$minutes|'00'%>
+<%INIT>
+
+my $MINUTE = 60;
+my $HOUR = $MINUTE*60;
+my $DAY = $HOUR * 24;
+my $WEEK = $DAY * 7;
+my $days = int($Duration / $DAY);
+$Duration = $Duration % $DAY;
+my $hours = int($Duration / $HOUR);
+$hours = sprintf("%02d", $hours);
+$Duration = $Duration % $HOUR;
+my $minutes = int($Duration/$MINUTE);
+$minutes = sprintf("%02d", $minutes);
+</%INIT>
+<%ARGS>
+$Duration => undef
+</%ARGS>
diff --git a/rt/html/RTx/Statistics/Elements/CollectionAsTable/Header b/rt/html/RTx/Statistics/Elements/CollectionAsTable/Header
new file mode 100644
index 000000000..cecb02eee
--- /dev/null
+++ b/rt/html/RTx/Statistics/Elements/CollectionAsTable/Header
@@ -0,0 +1,126 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+@Format => undef
+$FormatString => undef
+$AllowSorting => undef
+$Order=>undef
+$BaseURL => undef
+$Query => undef
+$Rows => undef
+$Page => undef
+$maxitems => undef
+</%ARGS>
+<TR class="collection-as-table">
+<%perl>
+
+my %generic_query_args = ( Query => $Query, Rows => $Rows, Page => $Page, Format => $FormatString );
+
+my $item = 0;
+foreach my $col (@Format) {
+ $item++;
+ if ( $col->{title} eq 'NEWLINE' ) {
+ while ( $item < $maxitems ) {
+ $m->out(qq{<th class="collection-as-table">&nbsp;</th>\n});
+ $item++;
+ }
+
+ $item = 0;
+ $m->out(qq{</TR>\n<TR class="collection-as-table">});
+ }
+ else {
+ $m->out('<TH class="collection-as-table" ');
+ $m->out( 'align="' . $col->{align} . '"' ) if ( $col->{align} );
+ $m->out( 'style="' . $col->{style} . '"' ) if ( $col->{style} );
+ $m->out('>');
+ my $title = $col->{title};
+ $title =~ s/^__(.*)__$/$1/o;
+ $title = (
+ $m->comp(
+ '/RTx/Statistics/Elements/StatColumnMap',
+ Name => $title,
+ Attr => 'title'
+ )
+ || $title
+ );
+ if (
+ $AllowSorting
+ && $col->{'attribute'}
+ && $m->comp(
+ '/RTx/Statistics/Elements/StatColumnMap',
+ Name => $col->{'attribute'},
+ Attr => 'attribute'
+ )
+ )
+ {
+
+ $m->out(
+ '<a href="' . $BaseURL
+ . $m->comp(
+ '/Elements/QueryString',
+ %generic_query_args,
+ OrderBy => (
+ $m->comp(
+ '/RTx/Statistics/Elements/StatColumnMap',
+ Name => $col->{'attribute'},
+ Attr => 'attribute'
+ )
+ || $col->{'attribute'}
+ ),
+ Order => ( $ARGS{'Order'} eq 'ASC' ? 'DESC' : 'ASC' )
+ )
+ . '">'
+ . loc($title) . '</a>'
+ );
+ }
+ else {
+ $m->out( loc($title) );
+ }
+ $m->out('</TH>');
+ }
+}
+</%perl>
+</TR>
diff --git a/rt/html/RTx/Statistics/Elements/CollectionAsTable/ParseFormat b/rt/html/RTx/Statistics/Elements/CollectionAsTable/ParseFormat
new file mode 100644
index 000000000..a482f817e
--- /dev/null
+++ b/rt/html/RTx/Statistics/Elements/CollectionAsTable/ParseFormat
@@ -0,0 +1,109 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+$Format
+</%ARGS>
+
+<%init>
+use Regexp::Common;
+my @Columns;
+
+while ($Format =~ /($RE{delimited}{-delim=>qq{\'"}}|[{}\w.]+)/go) {
+ my $col = $1;
+
+ if ($col =~ /^$RE{quoted}$/o) {
+ substr($col,0,1) = "";
+ substr($col,-1,1) = "";
+ }
+
+ my $colref;
+
+ # kfh at mqsoftware.com added this to be able
+ # to create columns where the actual heading and value
+ # aren't know ahead of time. For instance queue names.
+ # it will work with subcols, but all subcols will have the same KEY
+ if ( $col =~ s!/KEY:([^/]+)!!io ) {
+ $colref->{'keyname'} = $1;
+ }
+ if ( $col =~ s!/STYLE:([^/]+)!!io ) {
+ $colref->{'style'} = $1;
+ }
+ if ( $col =~ s!/CLASS:([^/]+)!!io ) {
+ $colref->{'class'} = $1;
+ }
+ if ( $col =~ s!/TITLE:([^/]+)!!io ) {
+ $colref->{'title'} = $1;
+ }
+ if ( $col =~ s!/ALIGN:([^\/]+)!!io ) {
+ $colref->{'align'} = $1;
+ }
+ if ( $col =~ /__(.*?)__/gio ) {
+ my @subcols;
+ while ( $col =~ s/^(.*?)__(.*?)__//o ) {
+ push ( @subcols, $1 ) if ($1);
+ push ( @subcols, "__$2__" );
+ $colref->{'attribute'} = $2;
+ }
+ push ( @subcols, $col );
+ @{ $colref->{'output'} } = @subcols;
+ }
+ else {
+ @{ $colref->{'output'} } = ( "__" . $col . "__" );
+ $colref->{'attribute'} = $col;
+ }
+
+ if ( !$colref->{'title'} && grep { /^__(.*?)__$/io }
+ @{ $colref->{'output'} } )
+ {
+ $colref->{'title'} = $1;
+ $colref->{'attribute'} = $1;
+ }
+
+
+ push @Columns, $colref;
+}
+ return(@Columns);
+</%init>
diff --git a/rt/html/RTx/Statistics/Elements/CollectionAsTable/Row b/rt/html/RTx/Statistics/Elements/CollectionAsTable/Row
new file mode 100644
index 000000000..bcfabe5c3
--- /dev/null
+++ b/rt/html/RTx/Statistics/Elements/CollectionAsTable/Row
@@ -0,0 +1,112 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+$i => undef
+@Format => undef
+$record => undef
+$maxitems => undef
+$Depth => undef
+$Warning => undef
+</%ARGS>
+
+<%PERL>
+$m->out('<TR class="' . ( $Warning ? 'warnline' : $i % 2 ? 'oddline' : 'evenline' ) . '" >' );
+my $item;
+foreach my $column (@Format) {
+ if ( $column->{title} eq 'NEWLINE' ) {
+ while ( $item < $maxitems ) {
+ $m->out(qq{<td class="collection-as-table">&nbsp;</td>\n});
+ $item++;
+ }
+ $item = 0;
+ $m->out('</TR>');
+ $m->out('<TR class="'
+ . ( $Warning ? 'warnline' : $i % 2 ? 'oddline' : 'evenline' )
+ . '" >' );
+ next;
+ }
+ $item++;
+ $m->out('<td class="collection-as-table" ');
+ $m->out( 'align="' . $column->{align} . '"' ) if ( $column->{align} );
+ $m->out( 'style="' . $column->{style} . '"' ) if ( $column->{style} );
+ $m->out('>');
+ foreach my $subcol ( @{ $column->{output} } ) {
+ if ( $subcol =~ /^__(.*?)__$/o ) {
+ my $col = $1;
+ my $value = $m->comp(
+ '/RTx/Statistics/Elements/StatColumnMap',
+ Name => $col,
+ Attr => 'value'
+ );
+ my @out;
+
+ if ( $value && ref($value) ) {
+
+ # All HTML snippets are returned by the callback function
+ # as scalar references. Data fetched from the objects are
+ # plain scalars, and needs to be escaped properly.
+ @out =
+ map {
+ ref($_) ? $$_ : $m->interp->apply_escapes( $_ => 'h' )
+ } &{$value}( $record, $i, $column->{keyname} );
+ ;
+ }
+ else {
+
+ # Simple value; just escape it.
+ @out = $m->interp->apply_escapes( $value => 'h' );
+ }
+ s/\n/<br>/gs for @out;
+ $m->out( @out );
+ }
+ else {
+ $m->out($subcol);
+ }
+ }
+ $m->out('</td>');
+}
+$m->out('</TR>');
+</%PERL>
diff --git a/rt/html/RTx/Statistics/Elements/ControlsAsTable/ControlBox b/rt/html/RTx/Statistics/Elements/ControlsAsTable/ControlBox
new file mode 100644
index 000000000..ce043e294
--- /dev/null
+++ b/rt/html/RTx/Statistics/Elements/ControlsAsTable/ControlBox
@@ -0,0 +1,103 @@
+<table class="box" bgcolor="#336699" style="border-style:none solid solid solid;border-width:1px;border-color:#2E2E8C;" cellpadding="0" cellspacing="0">
+ <tbody>
+ <tr>
+ <th style="color: rgb(51, 102, 153);" class="titlebox">
+ <span class="titleboxclose">
+ <a href="#" onclick="hideshow('stats_control')">X</a></span>&nbsp;
+ <span class="titleboxtitle" style="color: rgb(255, 255, 255);">
+ <b><% $Title %></b></span>
+ </th>
+ <th style="color: rgb(51, 102, 153);" class="titleboxright">
+ <span class="titleboxright">&nbsp;</span>
+ </th>
+ </tr>
+ <tr id="element-stats_control">
+ <td colspan="3" class="" bgcolor="#dddddd">
+ <table border="0" cellpadding="1" cellspacing="0">
+% if (defined $ShowStatus) {
+ <tr>
+ <td class="collection-as-table" style="text-align:left;">Show Status:</td>
+ <td COLSPAN=3 class="collection-as-table" style="text-align:left;">
+ <& /Elements/SelectStatus, Name=>"status", Default => $Status, DefaultValue => undef &>
+ </td>
+ </tr>
+% }
+% if (defined $ShowSingleQueue) {
+ <tr>
+ <td class="collection-as-table" style="text-align:left;">Show Queue:</td>
+ <td COLSPAN=3 class="collection-as-table" style="text-align:left;">
+ <& /Elements/SelectQueue, Name=>"Queue", Default=>$Queue ,ShowNullOption=>0,
+ CheckQueueRight=>'SeeQueue' &>
+ </td>
+ </tr>
+% }
+% if (defined $ShowDates) {
+ <tr>
+ <& /RTx/Statistics/Elements/DateSelectRow, Label => "Start Date:",
+ refMonth => $sMonth, nameMonth => "sMonth",
+ refDay => $sDay, nameDay => "sDay",
+ refYear => $sYear, nameYear => "sYear" &>
+ </tr>
+ <tr>
+ <& /RTx/Statistics/Elements/DateSelectRow, Label => "End Date:",
+ refMonth => $eMonth, nameMonth => "eMonth",
+ refDay => $eDay, nameDay => "eDay",
+ refYear => $eYear, nameYear => "eYear" &>
+ </tr>
+ <tr>
+ <td class="collection-as-table" style="text-align:left;">Show Weekends:</td>
+ <td class="collection-as-table" style="text-align:left;">
+ <select name=weekends>
+ <option value=0 <% (!$weekends) && 'selected' %> >No</option>
+ <option value=1 <% $weekends && 'selected' %> >Yes</option>
+ </select>
+ </td>
+ </tr>
+% }
+% if (defined $ShowMultiQueues) {
+ <tr>
+% if (defined $ShowDates) {
+%# If we're showing the dates, we put these side by side.
+ <td COLSPAN=2 class="collection-as-table" style="text-align:left;">Select All Queues: <input type=checkbox name="AddAllCheck"></td>
+ <td COLSPAN=3 class="collection-as-table" >
+ <& /RTx/Statistics/Elements/SelectMultiQueue, Name=>"queues", Selected=>$queues_ref,
+ ShowNullOption=>0, CheckQueueRight=>'SeeQueue', Size => 10, NamedValues => 1 &>
+ </td>
+% } else {
+ <td COLSPAN=3 class="collection-as-table" style="text-align:left;">
+ <& /RTx/Statistics/Elements/SelectMultiQueue, Name=>"queues", Selected=>$queues_ref,
+ ShowNullOption=>0, CheckQueueRight=>'SeeQueue', Size => 10, NamedValues => 1 &>
+ </td>
+ </tr>
+ <tr>
+ <td class="collection-as-table" style="text-align:left;">Select All Queues: <input type=checkbox name="AddAllCheck"></td>
+% }
+ </tr>
+% }
+ <& /RTx/Statistics/Elements/ControlsAsTable/UpdatePage &>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<BR>
+<%args>
+$Title => undef
+$ShowMultiQueues => undef
+$queues_ref => undef
+$ShowDates => undef
+$sMonth => undef
+$sDay => undef
+$sYear => undef
+$eMonth => undef
+$eDay => undef
+$eYear => undef
+$weekends => undef
+$ShowSingleQueue => undef
+$Queue => undef
+$ShowStatus => undef
+$Status => undef
+</%args>
+
diff --git a/rt/html/RTx/Statistics/Elements/ControlsAsTable/UpdatePage b/rt/html/RTx/Statistics/Elements/ControlsAsTable/UpdatePage
new file mode 100644
index 000000000..b4ccfd56f
--- /dev/null
+++ b/rt/html/RTx/Statistics/Elements/ControlsAsTable/UpdatePage
@@ -0,0 +1,5 @@
+<tr>
+ <td colspan="4" style="text-align:center;padding-top:3px; background-color:#C8C8C8;">
+ <INPUT TYPE="submit" VALUE="<&|/l&>Update Page</&>">
+ </td>
+</tr>
diff --git a/rt/html/RTx/Statistics/Elements/DateSelectRow b/rt/html/RTx/Statistics/Elements/DateSelectRow
new file mode 100644
index 000000000..325e168c9
--- /dev/null
+++ b/rt/html/RTx/Statistics/Elements/DateSelectRow
@@ -0,0 +1,55 @@
+ <td class="collection-as-table" style="text-align:left;"><% $Label %></td>
+ <td class="collection-as-table" style="text-align:left;">
+ <select name=<% $nameMonth %> >
+% for ($n=0;$n<=$#Statistics::months;$n++){
+% if ($$refMonth eq $n){
+% $selected ="selected";
+% }else {
+% $selected ="";
+% }
+ <option value=<% $n %> <% $selected %> ><% $Statistics::months[$n] %></option>
+%}
+ </select>
+ </td>
+ <td class="collection-as-table" style="text-align:left;">
+ <select name=<% $nameDay %> >
+% for ($n=1;$n<=31;$n++){
+% if ($$refDay == $n ){
+% $selected ="selected";
+% }else {
+% $selected ="";
+% }
+ <option value=<% $n %> <% $selected %> ><% $n %></option>
+% }
+ </select>
+ </td>
+ <td class="collection-as-table" style="text-align:left;">
+ <select name=<% $nameYear %> >
+%
+% for ($n=0;$n <= scalar @Statistics::years-1;$n++){
+% if ($Statistics::years[$n] == $$refYear){
+% $selected ="selected";
+% }else{
+% $selected ="";
+% }
+ <option value=<% $Statistics::years[$n] %> <% $selected %> ><% $Statistics::years[$n] %></option>
+% }
+ </select>
+ </td>
+
+
+<%args>
+$Label => undef
+$refMonth => undef
+$nameMonth => undef
+$refDay => undef
+$nameDay => undef
+$refYear => undef
+$nameYear => undef
+</%args>
+<%init>
+use RTx::Statistics;
+my $n;
+my $selected;
+
+</%init>
diff --git a/rt/html/RTx/Statistics/Elements/DurationAsString b/rt/html/RTx/Statistics/Elements/DurationAsString
new file mode 100755
index 000000000..c0b4d9af4
--- /dev/null
+++ b/rt/html/RTx/Statistics/Elements/DurationAsString
@@ -0,0 +1,18 @@
+<%$days|'00'%> days <%$hours|'00'%>:<%$minutes|'00'%>
+<%INIT>
+
+my $MINUTE = 60;
+my $HOUR = $MINUTE*60;
+my $DAY = $HOUR * 24;
+my $WEEK = $DAY * 7;
+my $days = int($Duration / $DAY);
+$Duration = $Duration % $DAY;
+my $hours = int($Duration / $HOUR);
+$hours = sprintf("%02d", $hours);
+$Duration = $Duration % $HOUR;
+my $minutes = int($Duration/$MINUTE);
+$minutes = sprintf("%02d", $minutes);
+</%INIT>
+<%ARGS>
+$Duration => undef
+</%ARGS>
diff --git a/rt/html/RTx/Statistics/Elements/GraphBox b/rt/html/RTx/Statistics/Elements/GraphBox
new file mode 100644
index 000000000..3dc06973e
--- /dev/null
+++ b/rt/html/RTx/Statistics/Elements/GraphBox
@@ -0,0 +1,27 @@
+<div style="float:left; padding-right:30px;">
+<table class="box" bgcolor="#336699" style="border-style:none solid solid solid;border-width:1px;border-color:#2E2E8C;" cellpadding="0" cellspacing="0">
+ <tbody><tr>
+ <th style="color: rgb(51, 102, 153);" class="titlebox">
+ <span class="titleboxclose">
+ <a href="#" onclick="hideshow('stats_chart')">X</a></span>&nbsp;
+
+ <span class="titleboxtitle">
+ <b><a href="<% $GraphURL %>">Download Chart as Image</a></b>
+ </span>
+ </th>
+ <th style="color: rgb(51, 102, 153);" class="titleboxright">
+ <span class="titleboxright">&nbsp;</span>
+ </th>
+ </tr>
+
+ <tr id="element-stats_chart">
+ <td colspan="3" class="" bgcolor="#dddddd">
+ <img src="<% $GraphURL %>" ALT="Result Graph" >
+ </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<%args>
+$GraphURL => undef
+</%args>
diff --git a/rt/html/RTx/Statistics/Elements/SelectMultiQueue b/rt/html/RTx/Statistics/Elements/SelectMultiQueue
new file mode 100755
index 000000000..637f6dc80
--- /dev/null
+++ b/rt/html/RTx/Statistics/Elements/SelectMultiQueue
@@ -0,0 +1,81 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<SELECT NAME ="<%$Name%>" multiple size="<% $Size %>">
+% if ($ShowNullOption) {
+<OPTION VALUE="">-</OPTION>
+% }
+% while (my $queue=$q->Next) {
+% if ($ShowAllQueues || $queue->CurrentUserHasRight($CheckQueueRight)) {
+% my $targ="," . $queue->Name . ",";
+<OPTION VALUE="<%($NamedValues ? $queue->Name : $queue->Id) %>" <%( ($sel_list =~ m/$targ/) ? 'SELECTED' : '')%>><%$queue->Name%>
+% if (($Verbose) and ($queue->Description) ){
+(<%$queue->Description%>)
+% }
+</OPTION>
+% }
+% }
+</SELECT>
+<%ARGS>
+$CheckQueueRight => 'CreateTicket'
+$ShowNullOption => 1
+$ShowAllQueues => 1
+$Name => undef
+$Verbose => undef
+$NamedValues => 0
+$Selected => undef # ref to array containing selected queue names
+$Lite => 0
+$Size => 5
+</%ARGS>
+
+<%INIT>
+
+# put list of queue names into string, starting and ending with commas
+my $sel_list = "," . join(",", @$Selected) . ",";
+
+my $q=new RT::Queues($session{'CurrentUser'});
+$q->UnLimit;
+
+</%INIT>
diff --git a/rt/html/RTx/Statistics/Elements/StatColumnMap b/rt/html/RTx/Statistics/Elements/StatColumnMap
new file mode 100644
index 000000000..aef9e2f3e
--- /dev/null
+++ b/rt/html/RTx/Statistics/Elements/StatColumnMap
@@ -0,0 +1,173 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+$Name => undef
+$Attr => undef
+</%ARGS>
+
+
+<%ONCE>
+our ( $STAT_COLUMN_MAP );
+
+sub StatColumnMap {
+ my $name = shift;
+ my $attr = shift;
+
+ # First deal with the simple things from the map
+ if ( $STAT_COLUMN_MAP->{$name} ) {
+ return ( $STAT_COLUMN_MAP->{$name}->{$attr} );
+ }
+
+ # now, let's deal with harder things, like Custom Fields
+
+ elsif ( $name =~ /^(?:CF|CustomField)\.\{(.+)\}$/ ) {
+ my $field = $1;
+
+ if ( $attr eq 'attribute' ) {
+ return (undef);
+ }
+ elsif ( $attr eq 'title' ) {
+ return ( $field );
+ }
+ elsif ( $attr eq 'value' ) {
+ # Display custom field contents, separated by newlines.
+ # For Image custom fields we also show a thumbnail here.
+ return sub {
+ my $values = $_[0]->CustomFieldValues($field);
+ return map {
+ (
+ ($_->CustomFieldObj->Type eq 'Image')
+ ? \($m->scomp( '/Elements/ShowCustomFieldImage', Object => $_ ))
+ : $_->Content
+ ),
+ \'<br>',
+ } @{ $values->ItemsArrayRef }
+ };
+ }
+ }
+}
+
+sub LinkCallback {
+ my $method = shift;
+
+ my $mode = $RT::Ticket::LINKTYPEMAP{$method}{Mode};
+ my $type = $RT::Ticket::LINKTYPEMAP{$method}{Type};
+ my $mode_uri = $mode.'URI';
+ my $local_type = 'Local'.$mode;
+
+ return sub {
+ map {
+ \'<A HREF="',
+ $_->$mode_uri->Resolver->HREF,
+ \'">',
+ ( $_->$mode_uri->IsLocal ? $_->$local_type : $_->$mode ),
+ \'</A><BR>',
+ } @{ $_[0]->Links($mode,$type)->ItemsArrayRef }
+ }
+}
+
+$STAT_COLUMN_MAP = {
+ LastUpdated => {
+ attribute => 'LastUpdated',
+ title => 'Last Updated',
+ value => sub { return $_[0]->LastUpdatedObj->AsString }
+ },
+
+ Statistics_Date => {
+ title => 'Date',
+ value => sub { return $_[0]{values}{Statistics_Date} }
+ },
+
+ Statistics_Created_Count => {
+ title => 'Created',
+ value => sub { return $_[0]{values}{Statistics_Created_Count} }
+ },
+
+ Statistics_Resolved_Count => {
+ title => 'Resolved',
+ value => sub { return $_[0]{values}{Statistics_Resolved_Count} }
+ },
+
+ Statistics_Deleted_Count => {
+ title => 'Deleted',
+ value => sub { return $_[0]{values}{Statistics_Deleted_Count} }
+ },
+
+ Statistics_Totals => {
+ title => 'Totals',
+ value => sub { return $_[0]{values}{Statistics_Totals} }
+ },
+
+ Statistics_Status => {
+ title => 'Status',
+ value => sub { return $_[0]{values}{Statistics_Status} }
+ },
+
+ Statistics_Dynamic => {
+ # Depends on having a KEY as second param
+ value => sub {
+ my $record = shift;
+ my $line = shift;
+ my $key = shift;
+ return $$record{values}{$key}
+ }
+ },
+
+ # Everything from LINKTYPEMAP
+ (map {
+ $_ => { value => LinkCallback( $_ ) }
+ } keys %RT::Ticket::LINKTYPEMAP),
+
+ '_CLASS' => {
+ value => sub { return $_[1] % 2 ? 'oddline' : 'evenline' }
+ },
+
+};
+</%ONCE>
+<%init>
+$m->comp( '/Elements/Callback', STAT_COLUMN_MAP => $STAT_COLUMN_MAP, _CallbackName => 'StatColumnMap');
+return StatColumnMap($Name, $Attr);
+</%init>
diff --git a/rt/html/RTx/Statistics/Elements/Tabs b/rt/html/RTx/Statistics/Elements/Tabs
new file mode 100755
index 000000000..4fde113ea
--- /dev/null
+++ b/rt/html/RTx/Statistics/Elements/Tabs
@@ -0,0 +1,72 @@
+%# BEGIN LICENSE BLOCK
+%#
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%#
+%# (Except where explictly superceded by other copyright notices)
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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.
+%#
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%#
+%#
+%# END LICENSE BLOCK
+<& /Elements/Tabs,
+ tabs => $tabs,
+ current_toptab => 'RTx/Statistics/index.html',
+ current_tab => $current_tab,
+ Title => $Title &>
+
+<%INIT>
+ my $tabs = { A => { title => loc('Tickets per Day'),
+ path => 'RTx/Statistics/CallsQueueDay/index.html',
+ },
+ B => { title => loc('Tickets by status'),
+ path => 'RTx/Statistics/OpenStalled/index.html',
+ },
+ C => { title => loc('Multiple Queues'),
+ path => 'RTx/Statistics/CallsMultiQueue/index.html',
+ },
+ D => { title => loc('Ticket Trends by Day'),
+ path => 'RTx/Statistics/DayOfWeek/index.html',
+ },
+ E => { 'title' => loc('Time to Resolve'),
+ path => 'RTx/Statistics/Resolution/index.html',
+ },
+ F => { 'title' => loc('Resolve Time Graph'),
+ path => 'RTx/Statistics/TimeToResolve/index.html',
+ },
+ Z => { 'title' => loc('FAQ'),
+ path => 'RTx/Statistics/FAQ/index.html',
+ },
+ };
+
+ # Now let callbacks add their extra tabs
+ $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+ foreach my $tab (sort keys %{$tabs}) {
+ if ($tabs->{$tab}->{'path'} eq $current_tab) {
+ $tabs->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{$tab}->{"current_subtab"} = $current_subtab;
+ }
+ }
+
+</%INIT>
+
+
+<%ARGS>
+$subtabs => undef
+$current_tab => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/RTx/Statistics/FAQ/index.html b/rt/html/RTx/Statistics/FAQ/index.html
new file mode 100644
index 000000000..e7839eaad
--- /dev/null
+++ b/rt/html/RTx/Statistics/FAQ/index.html
@@ -0,0 +1,23 @@
+<& /Elements/Header, Title => 'FAQ and known issues' &>
+<& /RTx/Statistics/Elements/Tabs, Title => loc("FAQ and Known Issues") &>
+<hr noshade size="1">
+<p>This page will be used to contain known issues and FAQ`s for the Statistics
+package<br />
+This will also be used to clarify limitations of the package as they stand.</p>
+
+<p><strong>What Version of the Statistics package is this?</strong></p>
+<p>0.1.8</p>
+
+<p><strong>What time zone are the charts set to?</strong></p>
+<p>Because of the new programming method of the date functions, the charts are currently built in GMT(UTC). This may once again be
+customisable in a future release.</p>
+
+<p><strong>What is the default date period and queue?</strong></p>
+<p>The default date period is the previous 10 days, except where the chart is over a fixed 7 day period. The default queue is either
+General, or another queue set in your local configuration.</p>
+
+<p><strong>What are the limitations of the date function?</strong></p>
+<p>It has few, but it will not let you chose less than one day. you cannot select an end date before the start date and it is not
+recommended to select a date in the future or an illegal date, such at 30th February. Code has been put in place to trap these, but it may
+not be fool proof.</p>
+<hr size="1" noshade>
diff --git a/rt/html/RTx/Statistics/OpenStalled/Elements/Chart b/rt/html/RTx/Statistics/OpenStalled/Elements/Chart
new file mode 100755
index 000000000..9505881e8
--- /dev/null
+++ b/rt/html/RTx/Statistics/OpenStalled/Elements/Chart
@@ -0,0 +1,27 @@
+<%perl>
+$r->content_type("image/$format");
+print $graph->plot(\@data)->$format();
+$m->abort();
+print $#data+1 . " Elements:<p>";
+for (0..$#data) {
+print $data[$_];
+print "<p>";
+}
+</%perl>
+<%INIT>
+use GD::Graph::bars;
+
+my @data;
+my $graph = GD::Graph::bars->new($Statistics::GraphWidth,$Statistics::GraphHeight);
+$graph->set(export_format => "png",
+ x_label => 'Queue name',
+ y_label => 'Total per queue by status');
+my $format = $graph->export_format;
+$graph->set_legend(split /,/ , $ARGS{set_legend});
+push @data, [split /,/ , $ARGS{x_labels}];
+push @data, [split /,/ , $ARGS{data1}];
+push @data, [split /,/ , $ARGS{data2}];
+push @data, [split /,/ , $ARGS{data3}];
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/RTx/Statistics/OpenStalled/Results.tsv b/rt/html/RTx/Statistics/OpenStalled/Results.tsv
new file mode 100644
index 000000000..2ec1e0c4a
--- /dev/null
+++ b/rt/html/RTx/Statistics/OpenStalled/Results.tsv
@@ -0,0 +1,114 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+@queues => @Statistics::OpenStalledQueueList
+</%ARGS>
+
+<%INIT>
+use RTx::Statistics;
+use Time::Local;
+
+ my $n = 0;
+ my @data;
+ my @msgs;
+ my %totals;
+ my $QueryString;
+ my $now = new RT::Date($session{CurrentUser});
+ my $tix = new RT::Tickets($session{'CurrentUser'});
+
+ my %queues = map {
+ $_ => 1;
+ } (@queues);
+
+ # set content type
+ $r->content_type('application/vnd.ms-excel');
+
+ $QueryString = "queues=" . join("&queues=", @queues);
+
+ my $queue = new RT::Queues($session{CurrentUser});
+ $queue->UnLimit;
+
+ my $QueueObj = new RT::Queue($session{'CurrentUser'});
+ $QueueObj->Load($queue);
+
+ # Put out some data about the generation of this file
+ $m->out("Tickets by Status by Queue for Queues:\t" . join(',', @queues) . "\tGenerated at:\t" . Statistics::FormatDate("%x %X", $now). "\n\n");
+
+ # basically the same as index.html
+
+ # Output header row
+ $m->out("Status");
+ for ( sort keys %queues) {
+ push @data, $_;
+ my $Queueobj = new RT::Queue($session{'CurrentUser'});
+ $Queueobj->Load($_);
+ next if !$Queueobj->CurrentUserHasRight('SeeQueue');
+ $m->out("\t" . $_);
+ }
+ $m->out("\tTotals\n");
+
+ foreach my $s (qw(new open stalled)) {
+ $m->out("$s");
+ my $total=0;
+ foreach my $q (sort keys %queues) {
+ $tix = new RT::Tickets($session{'CurrentUser'});
+ $tix->LimitQueue(VALUE => "$q");
+ $tix->LimitStatus(VALUE => "$s");
+ $totals{$q} += $tix->Count; # Add up columns for each queue
+ $m->out("\t" . $tix->Count);
+ $total += $tix->Count;
+ }
+ $m->out("\t$total\n");
+ $totals{"Totals"} += $total;
+ }
+ $m->out("Totals");
+ foreach my $q (sort keys %queues) {
+ $m->out("\t" . $totals{$q});
+ }
+ $m->out("\t" . $totals{"Totals"} . "\n");
+
+ $m->abort();
+</%INIT>
diff --git a/rt/html/RTx/Statistics/OpenStalled/index.html b/rt/html/RTx/Statistics/OpenStalled/index.html
new file mode 100755
index 000000000..d0cd9f158
--- /dev/null
+++ b/rt/html/RTx/Statistics/OpenStalled/index.html
@@ -0,0 +1,188 @@
+<& /Elements/Header, Title => loc('New, Open and Stalled tickets by Queue') &>
+<& /RTx/Statistics/Elements/Tabs, Title => loc('New, Open and Stalled tickets by Queue') &>
+
+<h3>Description</h3>
+<p>The purpose of this page is to show a snapshot of the current status of tickets by Queue. You can multi select Queues from the dropdown
+list or simply show all available queues. This will indicate how many tickets have not yet been viewed (New), how many have been at least
+viewed once (Open) and how many have had their status changed to stalled.</p>
+
+<form method="POST" action="index.html">
+
+%my $tix = new RT::Tickets($session{'CurrentUser'});
+%if ($queue) {
+% $tix->LimitQueue (VALUE => $queue);
+%}
+
+
+%my $title = "New, Open and Stalled Tickets in " . join(', ', @queues);
+<& /Elements/TitleBoxStart, title => $title, title_href => "/RTx/Statistics/OpenStalled/index.html?$QueryString"&>
+<TABLE BORDER=0 cellspacing=0 cellpadding=1 WIDTH="100%">
+% if ($ShowHeader) {
+<& /RTx/Statistics/Elements/CollectionAsTable/Header,
+ Format => \@RowFormat,
+ FormatString => $RowFormat,
+ AllowSorting => $AllowSorting,
+ Order => $Order,
+ Query => undef,
+ Rows => $Rows,
+ Page => $Page,
+ OrderBy => $OrderBy ,
+ BaseURL => $BaseURL,
+ maxitems => $maxitems &>
+% }
+
+% for ( sort keys %queues_to_show) {
+% push @data, $_;
+% }
+% my @legend;
+% my $total = 0;
+% my $line = 0;
+%# NOTE need to handle all status values (see share/html/Elements/SelectStatus).
+% foreach my $s (qw(new open stalled)) {
+% $line++;
+% push @legend, $s;
+% $total=0;
+% foreach my $q (sort keys %queues_to_show) {
+% $tix = new RT::Tickets($session{'CurrentUser'});
+% $tix->LimitQueue(VALUE => "$q");
+% $tix->LimitStatus(VALUE => "$s");
+% push @data, $tix->Count;
+% $totals{$q} += $tix->Count; # Add up columns for each queue
+% $total += $tix->Count;
+% $values{$q} = $tix->Count;
+% }
+% $totals{"Totals"} += $total;
+% $values{Statistics_Status} = $s;
+% $values{Statistics_Totals} = $total;
+<& /RTx/Statistics/Elements/CollectionAsTable/Row, Format => \@RowFormat, i => $line, record => $record, maxitems => $maxitems &>
+% }
+% $values{Statistics_Status} = "Totals";
+% foreach my $q (sort keys %queues_to_show) {
+% $values{$q} = $totals{$q};
+% }
+% $values{Statistics_Totals} = $totals{"Totals"};
+<& /RTx/Statistics/Elements/CollectionAsTable/Row, Format => \@BoldRowFormat, i => $line+1, record => $record, maxitems => $maxitems &>
+</table>
+<& /Elements/TitleBoxEnd&>
+
+<hr>
+
+<BR />
+<BR />
+
+% use Data::Dumper;
+% Statistics::DebugLog("Dump of data array is " . Dumper(@data) . "\n");
+% my $url = 'Elements/Chart?x_labels=';
+% for (1..(scalar keys %queues_to_show)) {
+% $url .= $m->interp->apply_escapes((shift @data),'u') . ',';
+% }
+% chop $url;
+% $url .= '&data1=' ;
+% for (1..(scalar keys %queues_to_show)) {
+% $url .= $m->interp->apply_escapes((shift @data),'u') . ',';
+% }
+% chop $url;
+% $url .= '&data2=' ;
+% for (1..(scalar keys %queues_to_show)) {
+% $url .= $m->interp->apply_escapes((shift @data),'u') . ',';
+% }
+% chop $url;
+% $url .= '&data3=' ;
+% for (1..(scalar keys %queues_to_show)) {
+% $url .= $m->interp->apply_escapes((shift @data),'u') . ',';
+% }
+% $url .= '&set_legend='.(join ",", @legend);
+
+
+<& /RTx/Statistics/Elements/GraphBox, GraphURL => $url &>
+
+<& /RTx/Statistics/Elements/ControlsAsTable/ControlBox, Title => "Select Queues", ShowMultiQueues => 1, queues_ref => \@queues &>
+
+<a href="<%$RT::WebPath%>/RTx/Statistics/OpenStalled/index.html?<% $QueryString %>"><&|/l&>Bookmarkable link</&></a>
+%# | <a href="<%$RT::WebPath%>/RTx/Statistics/OpenStalled/Results.tsv?<%$QueryString%>"><&|/l&>spreadsheet</&></a>
+<BR>
+<BR>
+
+</FORM>
+
+% Statistics::DebugInit( $m );
+
+<%ARGS>
+@queues => @Statistics::OpenStalledQueueList
+$AllowSorting => undef
+$Order => undef
+$OrderBy => undef
+$ShowNavigation => 1
+$ShowHeader => 1
+$Rows => 50
+$Page => 1
+$BaseURL => undef
+$AddAllCheck => undef
+</%ARGS>
+
+<%INIT>
+ use RTx::Statistics;
+
+ my $n = 0;
+ my @data;
+ my @msgs;
+ my %totals;
+ my $QueryString;
+ my %queues_to_show;
+ my $maxitems;
+ my $RowFormat;
+ my $BoldRowFormat;
+ my %record;
+ my %values;
+ my $record = \%record;
+
+ $record{values} = \%values;
+
+ Statistics::DebugClear();
+
+ # Handle the Add All Checkbox
+ if($AddAllCheck eq "on") {
+ $AddAllCheck = undef;
+ undef (@queues);
+ my $q=new RT::Queues($session{'CurrentUser'});
+ $q->UnLimit;
+ while (my $queue=$q->Next) {
+ next if !$queue->CurrentUserHasRight('SeeQueue');
+ push @queues, $queue->Name;
+ }
+ }
+
+ # If the user has the right to see the queue, put it into the map
+ for my $q (@queues) {
+ my $Queueobj = new RT::Queue($session{'CurrentUser'});
+ $Queueobj->Load($q);
+ next if !$Queueobj->CurrentUserHasRight('SeeQueue');
+ $queues_to_show{$q} = 1;
+ }
+
+ $maxitems = (scalar @queues) + 2;
+
+ # Build the new query string
+ $QueryString = "queues=" . join("&queues=", @queues);
+
+ # Build the format strings
+ $RowFormat = "'__Statistics_Status__'";
+ $BoldRowFormat = "'<B>__Statistics_Status__</B>'";
+ for my $q (@queues) {
+ $RowFormat .= ",'__Statistics_Dynamic__/KEY:$q/TITLE:$q/STYLE:text-align:right;'";
+ $BoldRowFormat .= ",'<B>__Statistics_Dynamic__</B>/KEY:$q/TITLE:$q/STYLE:text-align:right;'";
+ }
+ $RowFormat .= ",'<B>__Statistics_Totals__</B>/STYLE:text-align:right;'";
+ $BoldRowFormat .= ",'<B>__Statistics_Totals__</B>/STYLE:text-align:right;'";
+ # Parse the formats into structures.
+ my (@RowFormat) = $m->comp('/RTx/Statistics/Elements/CollectionAsTable/ParseFormat', Format => $RowFormat);
+ my (@BoldRowFormat) = $m->comp('/RTx/Statistics/Elements/CollectionAsTable/ParseFormat', Format => $BoldRowFormat);
+
+
+ my $queue = new RT::Queues($session{CurrentUser});
+ $queue->UnLimit;
+
+ my $QueueObj = new RT::Queue($session{'CurrentUser'});
+ $QueueObj->Load($queue);
+
+</%INIT>
diff --git a/rt/html/RTx/Statistics/Resolution/Elements/Chart b/rt/html/RTx/Statistics/Resolution/Elements/Chart
new file mode 100755
index 000000000..fa0ac5538
--- /dev/null
+++ b/rt/html/RTx/Statistics/Resolution/Elements/Chart
@@ -0,0 +1,29 @@
+<%perl>
+$r->content_type("image/$format");
+print $graph->plot(\@data)->$format();
+$m->abort();
+print $#data+1 . " Elements:<p>";
+for (0..$#data) {
+print $data[$_];
+print "<p>";
+}
+</%perl>
+<%INIT>
+use GD::Graph::lines;
+
+my @data;
+my $graph = GD::Graph::lines->new($Statistics::GraphWidth,$Statistics::GraphHeight);
+$graph->set(export_format => "png",
+ x_label => 'Days',
+ y_label => 'Average time in Days');
+
+push @data, [split /,/ , $ARGS{x_labels}];
+push @data, [split /,/ , $ARGS{data1}];
+push @data, [split /,/ , $ARGS{data2}];
+push @data, [split /,/ , $ARGS{data3}];
+
+my $format = $graph->export_format;
+#$r->content_type("image/$format");
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/RTx/Statistics/Resolution/index.html b/rt/html/RTx/Statistics/Resolution/index.html
new file mode 100644
index 000000000..d9885b093
--- /dev/null
+++ b/rt/html/RTx/Statistics/Resolution/index.html
@@ -0,0 +1,269 @@
+<& /Elements/Header, Title => 'Time to Resolution' &>
+<& /RTx/Statistics/Elements/Tabs, Title => loc("Time To Resolve tickets by Queue for : " .$QueueObj->Name()) &>
+<h3>Description</h3>
+<p>This page shows details of resolution of tickets in the selected queue. It displays tickets created on each day in your selected date
+range. Of those tickets created on that day, how many have been resolved and the total time it has taken for all tickets created on that
+day to be resolved.</p>
+<p>At the bottom of the chart is shows total time taken to resolve all tickets
+in the selected date range and the average time per ticket to
+resolve.</p>
+
+<form method="POST" action="index.html">
+
+%my $title = "Time to resolve in " . $QueueObj->Name() . " per day from " .
+% Statistics::FormatDate($Statistics::PerDayDateFormat, $dates[0]) . " through " .
+% Statistics::FormatDate($Statistics::PerDayDateFormat, $dates[$#dates-1]);
+<&|/Elements/TitleBox,
+ title => $title,
+ title_href => "/RTx/Statistics/Resolution/index.html?$QueryString" &>
+<TABLE BORDER=0 cellspacing=0 cellpadding=1 WIDTH=100%>
+% if ($ShowHeader) {
+<& /RTx/Statistics/Elements/CollectionAsTable/Header,
+ Format => \@Format,
+ FormatString => $Format,
+ AllowSorting => $AllowSorting,
+ Order => $Order,
+ Query => undef,
+ Rows => $Rows,
+ Page => $Page,
+ OrderBy => $OrderBy ,
+ BaseURL => $BaseURL,
+ maxitems => $maxitems &>
+% }
+% my $line = 1;
+% LINE: for my $d (0..$#dates ) {
+% if ($d == $#dates ){
+% next LINE;
+% }
+% my $x = 1;
+% $values{Statistics_Date} = Statistics::FormatDate($Statistics::PerDayDateFormat, $dates[$d]);
+% my $tix = new RT::Tickets($session{'CurrentUser'});
+% $tix->LimitCreated(VALUE => $dates[$d]->ISO, OPERATOR => ">=");
+% if ($dates[$d+1]) {
+% $tix->LimitCreated(VALUE => $dates[$d+1]->ISO, OPERATOR => "<=");
+% }
+% if ($Queue) {
+% $tix->LimitQueue (VALUE => $Queue);
+% }
+% $values{Statistics_Created_Count} = $tix->Count;
+% $tix->LimitStatus(VALUE => "resolved");
+% $values{Statistics_Resolved_Count} = $tix->Count;
+% if ($tix->Count) {
+% my @tix = @{$tix->ItemsArrayRef};
+% my $total;
+% $total += ($_->ResolvedObj->Unix - $_->CreatedObj->Unix) for @tix;
+% $size+= ($#tix +1);
+% $grandtotal += $total;
+% $values{Duration} = Statistics::DurationAsString($total);
+% $data[$x++][$d] = int ($total );
+% } else {
+% $values{Duration} = "N/A";
+% }
+<& /RTx/Statistics/Elements/CollectionAsTable/Row, Format => \@Format, i => $line, record => $record, maxitems => $maxitems &>
+% $line++;
+%}
+% $size =1 if $size==0;
+% $values{text} = "Average time to resolve = " . Statistics::DurationAsString($grandtotal / $size);
+<& /RTx/Statistics/Elements/CollectionAsTable/Row, Format => \@OneCellFormat, i => $line, record => $record, maxitems => $maxitems &>
+% $line++;
+% $values{text} = "Total time to resolve = " . Statistics::DurationAsString( $grandtotal );
+<& /RTx/Statistics/Elements/CollectionAsTable/Row, Format => \@OneCellFormat, i => $line, record => $record, maxitems => $maxitems &>
+% $line++;
+</table>
+</&>
+
+<hr>
+
+<BR />
+<BR />
+
+<%perl>
+# Create the graph URL
+
+# change the total time to resolve to a floating point number of days
+foreach my $dat(@{$data[1]} ){
+ $dat = ($dat / $Statistics::secsPerDay);
+ $dat = sprintf("%0.4f", $dat);
+}
+
+my $url = 'Elements/Chart?x_labels=';
+for (0..$diff-1) {
+ $url .= $data[0][$_] . ",";
+}
+chop $url;
+shift @data;
+$url .= "&data1=";
+for(0..$diff-1) {
+ $data[0][$_] = 0 if !$data[0][$_];
+ $url .= $data[0][$_] . ",";
+}
+</%perl>
+
+<& /RTx/Statistics/Elements/GraphBox, GraphURL => $url &>
+
+<& /RTx/Statistics/Elements/ControlsAsTable/ControlBox,
+ Title => "Change Queue or Dates",
+ ShowDates => 1, sMonth => \$sMonth, sDay => \$sDay, sYear => \$sYear,
+ eMonth => \$eMonth, eDay => \$eDay, eYear => \$eYear,
+ weekends => $weekends,
+ ShowSingleQueue => 1, Queue => $Queue
+ &>
+
+</form>
+
+<%ARGS>
+$max => $Statistics::TimeToResolveMaxRows
+$Queue => undef
+$weekends =>$Statistics::TimeToResolveWeekends
+$sMonth=>undef
+$sDay=>undef
+$sYear=>undef
+$eMonth=>undef
+$eDay=>undef
+$eYear=>undef
+$days=>undef
+$currentMonth=>undef
+
+$AllowSorting => undef
+$Order => undef
+$OrderBy => undef
+$ShowNavigation => 1
+$ShowHeader => 1
+$Rows => 50
+$Page => 1
+$BaseURL => undef
+</%ARGS>
+
+<%INIT>
+use RTx::Statistics;
+use Time::Local;
+my $n = 0;
+my @data = ([]);
+my @dates;
+my @msgs;
+my $size;
+my $selected;
+my $grandtotal = 0;
+my $diff;
+my $sEpoch=0;
+my $eEpoch=0;
+my $QueryString;
+
+my $maxitems = 4;
+my %record;
+my %values;
+my $record = \%record;
+
+$record{values} = \%values;
+
+
+# If debugging, set things up and display all the args
+Statistics::DebugClear();
+Statistics::DebugLog("CallsQueueDay/index.html ARGS:\n");
+for my $key (keys %ARGS) {
+ Statistics::DebugLog("ARG{ $key }=" . $ARGS{$key} . "\n");
+}
+
+my $Format = qq{ Statistics_Date,
+ '__Statistics_Created_Count__/STYLE:text-align:right;',
+ '__Statistics_Resolved_Count__/STYLE:text-align:right;',
+ '__Statistics_Dynamic__/KEY:Duration/TITLE:Time To Resolve/STYLE:text-align:right;' };
+my $BoldFormat = qq{ '<B>__Statistics_Date__</B>',
+ '<B>__Statistics_Created_Count__</B>/STYLE:text-align:right;',
+ '<B>__Statistics_Resolved_Count__</B>/STYLE:text-align:right;',
+ '<B>__Statistics_Dynamic__</B>/KEY:Duration/TITLE:Time To Resolve/STYLE:text-align:right;' };
+
+# TODO need way to make this cell do colspan
+my $OneCellFormat = qq{ '<B>__Statistics_Dynamic__</B>/KEY:text/STYLE:text-align:left;','','','' };
+
+my (@Format) = $m->comp('/RTx/Statistics/Elements/CollectionAsTable/ParseFormat', Format => $Format);
+my (@BoldFormat) = $m->comp('/RTx/Statistics/Elements/CollectionAsTable/ParseFormat', Format => $BoldFormat);
+my (@OneCellFormat) = $m->comp('/RTx/Statistics/Elements/CollectionAsTable/ParseFormat', Format => $OneCellFormat);
+
+Statistics::DebugLog("CallsQueueDay/index.html Format array=" . join(',', @Format) . "\n");
+
+if ($sDay > $Statistics::monthsMaxDay{$sMonth}) {
+ $sDay = $Statistics::monthsMaxDay{$sMonth};
+}
+
+if ($eDay > $Statistics::monthsMaxDay{$eMonth}) {
+ $eDay = $Statistics::monthsMaxDay{$eMonth};
+}
+
+if ($sYear){
+ $sEpoch = timelocal(0, 0, 0, $sDay, $sMonth, $sYear-1900);
+}
+if ($eYear){
+Statistics::DebugLog("eMonth = " . $eMonth . "\n");
+ $eEpoch = timelocal(0, 0, 0, $eDay, $eMonth, $eYear-1900);
+} else {
+ # This case happens when the page is first loaded
+ my @local = localtime(time);
+ ($eDay, $eMonth, $eYear) = ($local[3], $local[4], $local[5]);
+ $eYear += 1900;
+ $eEpoch = timelocal(0, 0, 0, $local[3], $local[4], $local[5], $local[6], $local[7], $local[8]);
+Statistics::DebugLog("Setting eEpoch=$eEpoch from current time.\n");
+}
+
+if (($eEpoch < $sEpoch) || ($sEpoch == 0)) {
+ # We have an end, but not a start, or, overlapping.
+
+ # if $currentMonth is set, just set the day to 1
+ if($currentMonth) {
+ # set start vars from end, but with day set to 1
+ (undef, undef, undef, $sDay, $sMonth, $sYear) = localtime($eEpoch);
+ $sDay=1;
+ $sEpoch = timelocal(0, 0, 0, $sDay, $sMonth, $sYear);
+ } else {
+ # If the user has specified how many days back to go, use that,
+ # If not, set start to configured default period before end
+ if(defined $days) {
+ $sEpoch = $eEpoch - ($days * $Statistics::secsPerDay);
+ } else {
+ $sEpoch = $eEpoch - ($Statistics::PerDayPeriod * $Statistics::secsPerDay);
+ }
+ (undef, undef, undef, $sDay, $sMonth, $sYear) = localtime($sEpoch);
+ }
+ $sYear += 1900;
+}
+
+# Compute days to chart.
+# The +1 is because we need to generate one more date. If the user
+# selected a 10 day range, we need to generate 11 days.
+$diff = int(($eEpoch - $sEpoch + $Statistics::secsPerDay - 1) / $Statistics::secsPerDay)+1;
+Statistics::DebugLog("Setting diff=$diff\n");
+
+Statistics::DebugLog("sEpoch=$sEpoch, components=" . join(',', localtime($sEpoch)) . "\n");
+Statistics::DebugLog("eEpoch=$eEpoch, components=" . join(',', localtime($eEpoch)) . "\n");
+
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+if (!defined $Queue) {
+ $QueueObj->Load($Statistics::TimeToResolveQueue);
+ $Queue = $QueueObj->Id();
+}
+
+# Set up the string for the current query for bookmarkable link
+$QueryString = "sDay=$sDay&sMonth=$sMonth&sYear=$sYear&eDay=$eDay&eMonth=$eMonth&eYear=$eYear&weekends=$weekends&Queue=$Queue";
+
+# Set up the end date to be midnight(morning) of the date after the one the user wanted.
+my $endRange = $eEpoch + $Statistics::secsPerDay;
+$QueueObj->Load($Queue);
+# NOTE: list loop starts at the end of the date range, unshifting dates onto
+# the arrays, so that they end up in start to finish order.
+$eEpoch += $Statistics::secsPerDay;
+$n = 0;
+until ($#dates == $diff ) {
+ my $date = new RT::Date($session{CurrentUser});
+ $date->Set(Value=>$endRange - $n, Format => 'unix');
+ # Note: we used to adjust the time to local midnight, but
+ # none of the other date entry fields in RT seem to adjust, so we've stopped.
+ #Statistics::DebugLog("Before adjust to midnight date " . Statistics::FormatDate("%c", $date) . "\n");
+ $n+= $Statistics::secsPerDay;
+ # If we aren't showing weekends and this is one, decrement the number
+ # of days to show and skip to the next date.
+ if(!$weekends and Statistics::RTDateIsWeekend($date)) {$diff--; next;}
+ unshift @dates, $date;
+Statistics::DebugLog("pushing date " . Statistics::FormatDate("%c", $date) . "\n");
+ unshift @{ $data[0] }, Statistics::FormatDate($Statistics::PerDayLabelDateFormat, $date);
+}
+</%INIT>
diff --git a/rt/html/RTx/Statistics/TimeToResolve/Elements/Chart b/rt/html/RTx/Statistics/TimeToResolve/Elements/Chart
new file mode 100755
index 000000000..a069a7bfb
--- /dev/null
+++ b/rt/html/RTx/Statistics/TimeToResolve/Elements/Chart
@@ -0,0 +1,23 @@
+<%perl>
+print $graph->plot(\@data)->$format();
+$m->abort();
+</%perl>
+<%INIT>
+use GD::Graph::points;
+
+my @data;
+my $graph = GD::Graph::points->new(400,300);
+$graph->set(export_format => "png",
+ marker_size => $ARGS{marker_size},
+ x_label => 'Average time to resolve (Days)',
+ y_label => 'Number of tickets resolved' );
+#$r->content_type("image/$format");
+my $format = $graph->export_format;
+push @data, [split /,/ , $ARGS{x_labels}];
+for (1..((scalar keys %ARGS)-2)) {
+ push @data, [split /,/ , $ARGS{"data".$_}];
+}
+
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/RTx/Statistics/TimeToResolve/index.html b/rt/html/RTx/Statistics/TimeToResolve/index.html
new file mode 100755
index 000000000..2124b538d
--- /dev/null
+++ b/rt/html/RTx/Statistics/TimeToResolve/index.html
@@ -0,0 +1,75 @@
+<& /Elements/Header, Title => 'Time to Resolve in Queue' &>
+<& /RTx/Statistics/Elements/Tabs, Title => 'Time to Resolve, by ticket in Queue:' . $QueueObj->Name() &>
+
+<h3>Description</h3>
+<p>This page displays the same information as the Time to Resolve chart, but in a scattergraph format and only for the previous 7 calendar
+days. It only displays data for tickets which have been resolved. Each division on the Days axis is one day and the granularity of this chart
+is 30 minutes.</p>
+<form method="POST">
+
+<table>
+ <tr>
+ <td>Show Queue:</td>
+ <td COLSPAN=3><& /Elements/SelectQueue, Name=>"queue", Default=>$queue ,ShowNullOption=>0,
+ CheckQueueRight=>'SeeQueue' &></td>
+ </tr>
+</table>
+<INPUT TYPE="submit" VALUE="Update Page"</INPUT>
+</form>
+
+<BR>
+% my $url = 'Elements/Chart?x_labels=';
+% my $i;
+% $url .= join ",", (map {(int($_/2) == $_/2 && (++$i)%2) ? $_/2 : ""} grep {$counts[$_]} 0..($#counts-1)), "longer";
+% $url .= '&';
+% $url .= "marker_size=1&";
+% $url .= "data1=".(join ",", map { $_ || () } @counts)."&";
+% chop $url;
+<IMG SRC="<% $url %>">
+
+<BR>
+
+%Statistics::DebugInit($m);
+
+<%ARGS>
+$queue => undef
+</%ARGS>
+
+<%INIT>
+use RTx::Statistics;
+
+my @days = qw(Sun Mon Tue Wed Thu Fri Sat);
+my $n = 0;
+my @data = ([]);
+my @msgs;
+my @counts;
+
+Statistics::DebugClear();
+Statistics::DebugLog("TimeToResolve/index.html ARGS:\n");
+for my $key (keys %ARGS) {
+ Statistics::DebugLog("ARG{ $key }=" . $ARGS{$key} . "\n");
+}
+
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+if (!defined $queue) {
+ $QueueObj->Load($Statistics::TimeToResolveGraphQueue);
+ $queue = $QueueObj->Id();
+} else {
+ $QueueObj->Load($queue);
+}
+
+
+my $tix = new RT::Tickets($session{'CurrentUser'});
+$tix->LimitQueue (VALUE => $queue) if $queue;
+$tix->LimitStatus(VALUE => "resolved");
+$tix->UnLimit;
+if ($tix->Count) {
+ while (my $t = $tix->RT::SearchBuilder::Next) { # BLOODY HACK
+ my $when = $t->ResolvedObj->Unix - $t->CreatedObj->Unix;
+ next unless $when > 0; # Doubly bloody hack
+ my $max = (60*60*24*2) / 1800;
+ my $x = int($when / 1800);
+ $counts[$x > $max ? $max : $x]++;
+ }
+}
+</%INIT>
diff --git a/rt/html/RTx/Statistics/UserTest/Elements/Chart b/rt/html/RTx/Statistics/UserTest/Elements/Chart
new file mode 100755
index 000000000..99eb2a2b1
--- /dev/null
+++ b/rt/html/RTx/Statistics/UserTest/Elements/Chart
@@ -0,0 +1,28 @@
+<%perl>
+print $graph->plot(\@data)->$format();
+$m->abort();
+print $#data+1 . " Elements:<p>";
+for (0..$#data) {
+print $data[$_];
+print "<p>";
+}
+</%perl>
+<%INIT>
+use GD::Graph::lines;
+
+my @data;
+my $graph = GD::Graph::lines->new(640,480);
+$graph->set(export_format => "png",
+ x_label => 'Days',
+ y_label => 'Average time in Days');
+
+push @data, [split /,/ , $ARGS{x_labels}];
+push @data, [split /,/ , $ARGS{data1}];
+push @data, [split /,/ , $ARGS{data2}];
+push @data, [split /,/ , $ARGS{data3}];
+
+my $format = $graph->export_format;
+#$r->content_type("image/$format");
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/RTx/Statistics/UserTest/index.html b/rt/html/RTx/Statistics/UserTest/index.html
new file mode 100755
index 000000000..7bc25da70
--- /dev/null
+++ b/rt/html/RTx/Statistics/UserTest/index.html
@@ -0,0 +1,54 @@
+<& /Elements/Header, Title => 'Time to Resolve in Queue' &>
+<& /RTx/Statistics/Elements/Tabs, Title => 'Time to Resolve, by ticket in Queue:' . $QueueObj->Name() &>
+
+
+<form method="POST">
+
+See Queue:<BR>
+<& /Elements/SelectQueue, Name=>"queue", Default => "$queue" &>
+<BR>
+<INPUT TYPE="submit" VALUE="Go!"</INPUT>
+</form>
+
+<BR>
+% my $url = 'Elements/Chart?x_labels=';
+% my $i;
+% $url .= join ",", (map {(int($_/2) == $_/2 && (++$i)%2) ? $_/2 : ""} grep {$counts[$_]} 0..($#counts-1)), "longer";
+% $url .= '&';
+% $url .= "marker_size=1&";
+% $url .= "data1=".(join ",", map { $_ || () } @counts)."&";
+% chop $url;
+<IMG SRC="<% $url %>">
+
+<BR>
+
+<%ARGS>
+$queue => $Statistics::TimeToResolveGraphQueue;
+</%ARGS>
+
+<%INIT>
+use RTx::Statistics;
+
+my @days = qw(Sun Mon Tue Wed Thu Fri Sat);
+my $n = 0;
+my @data = ([]);
+my @msgs;
+my @counts;
+
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($queue);
+
+my $tix = new RT::Tickets($session{'CurrentUser'});
+$tix->LimitQueue (VALUE => $queue) if $queue;
+$tix->LimitStatus(VALUE => "resolved");
+$tix->UnLimit;
+if ($tix->Count) {
+ while (my $t = $tix->RT::SearchBuilder::Next) { # BLOODY HACK
+ my $when = $t->ResolvedObj->Unix - $t->CreatedObj->Unix;
+ next unless $when > 0; # Doubly bloody hack
+ my $max = (60*60*24*2) / 1800;
+ my $x = int($when / 1800);
+ $counts[$x > $max ? $max : $x]++;
+ }
+}
+</%INIT>
diff --git a/rt/html/RTx/Statistics/index.html b/rt/html/RTx/Statistics/index.html
new file mode 100755
index 000000000..41490de18
--- /dev/null
+++ b/rt/html/RTx/Statistics/index.html
@@ -0,0 +1,59 @@
+%# BEGIN LICENSE BLOCK
+%#
+%# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
+%#
+%# (Except where explictly superceded by other copyright notices)
+%#
+%# Copyright this file (c) 2003 Harald Wagener <hwagener@hamburg.fcb.com>
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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.
+%#
+%# Unless otherwise specified, all modifications, corrections or
+%# extensions to this work which alter its source code become the
+%# property of Best Practical Solutions, LLC when submitted for
+%# inclusion in the work.
+%#
+%#
+%# END LICENSE BLOCK
+<& /Elements/Header, Title => loc('RT Statistics') &>
+<& /RTx/Statistics/Elements/Tabs, Title => loc('RT Statistics') &>
+
+<&|/l&><h2>Description</h2>
+<p>These 6 options below enable you to display management data from the RT Database in table and graphical forms, enabling trends, bottlenecks, load problems etc to be identified.
+Each contains a description of how the data is displayed and describes the options available to you.</p></&>
+<ul>
+<li><strong><a href="CallsQueueDay/index.html">
+<&|/l&>Tickets per day per Queue</&></a></strong><br />
+<&|/l&>View the number of tickets created, resolved or deleted in a<br /> specific Queue, over the requested period of days</&>
+</li>
+<li><strong><a href="OpenStalled/index.html">
+<&|/l&>Tickets status by Queue</&></a></strong><br>
+<&|/l&>View numbers of new, open and stalled tickets in a selected Queue</&>
+</li>
+<li><strong><a href="CallsMultiQueue/index.html">
+<&|/l&>Tickets per Day in Multiple Queues</&>
+</a></strong><br>
+<&|/l&>View tickets created, resolved or deleted on in one or more Queues<br /> over a specified time period</&>
+</li>
+<li><strong><a href="DayOfWeek/index.html">
+<&|/l&>Tickets per Day of Week (absolute)</&></a></strong><br>
+<&|/l&>View trends showing when tickets are created, resolved or deleted</&>
+</li>
+<li><strong><a href="Resolution/index.html">
+<&|/l&>Time to Resolve</&></a></strong><br>
+<&|/l&>View how long tickets take to be resolved by Queue</&>
+</li>
+</li>
+<li><strong><a href="TimeToResolve/index.html">
+<&|/l&>Time to Resolve (scatter graph)</&></a></strong><br>
+<&|/l&>View a detailed scatter graph of time to resolve tickets by Queue</&>
+</li>
+</ul>
diff --git a/rt/html/Reports/Activity/ActivityDetail.html b/rt/html/Reports/Activity/ActivityDetail.html
new file mode 100644
index 000000000..ef0d830f7
--- /dev/null
+++ b/rt/html/Reports/Activity/ActivityDetail.html
@@ -0,0 +1,83 @@
+<&|Elements/Wrapper, %ARGS, title => loc("Activity detail"),
+ path => "Reports/Activity/ActivityDetail.html",
+ &>
+
+<& Elements/MiniPlot, data => \%counts &>
+
+<table style="width: 100%">
+<tr class="titlerow">
+<th>Queue</th><th>Activity</th><th>Date</th><th>Time</th><th>Ticket #</th><th>User</th><th>Short description</th>
+</tr>
+% for my $item (@items) {
+<tr>
+<td><% $item->{queue} %></td>
+<td><% $item->{status} %></td>
+<td><% $item->{date} %></td>
+<td><% $item->{time} %></td>
+<td><% $item->{id} %></td>
+<td><% $item->{actor} %></td>
+<td><% $item->{notes} %></td>
+</tr>
+% }
+</table>
+
+</&>
+<%args>
+$query => 'id > 0'
+$start => "2005/01/01"
+$end => "2006/01/01"
+</%args>
+<%init>
+
+
+my $summary_tickets = RT::Tickets->new($session{'CurrentUser'});
+$summary_tickets->FromSQL($query . " AND ( Updated >= '$start' AND Updated <= '$end')");
+my %counts;
+while (my $ticket = $summary_tickets->Next) {
+ my $txns = $ticket->Transactions;
+ $txns->Limit(FIELD => 'Created', OPERATOR => '>=', VALUE => $start);
+ $txns->Limit(FIELD => 'Created', OPERATOR => '<=', VALUE => $end);
+ # I think they really don't just want status changes
+ $txns->Limit(FIELD => 'Type', VALUE => 'Status', ENTRYAGGREGATOR => 'OR');
+ $txns->Limit(FIELD => 'Type', VALUE => 'Create');
+
+ while (my $txn = $txns->Next){
+ my $date = substr($txn->Created, 0, 10);
+ # we don't have data on the status of a new ticket, default to 'new'
+ $counts{$date}{$txn->NewValue || 'new'}++;
+ }
+}
+
+
+my $tickets = RT::Tickets->new($session{'CurrentUser'});
+$tickets->FromSQL($query);
+my @items;
+while (my $ticket = $tickets->Next) {
+ my $txns = $ticket->Transactions;
+ $txns->Limit(FIELD => 'Created', OPERATOR => '>=', VALUE => $start);
+ $txns->Limit(FIELD => 'Created', OPERATOR => '<=', VALUE => $end);
+ # I think they really don't just want status changes
+ $txns->Limit(FIELD => 'Type', VALUE => 'Status', ENTRYAGGREGATOR => 'OR');
+ $txns->Limit(FIELD => 'Type', VALUE => 'Create');
+
+ while (my $txn = $txns->Next) {
+ push @items, { queue => $txn->TicketObj->QueueObj->Name,
+ id => $txn->TicketObj->id,
+ date => (split ' ', $txn->CreatedObj->ISO)[0],
+ time => (split ' ', $txn->CreatedObj->ISO)[1],
+ status => $txn->NewValue || 'new',
+ actor => $txn->CreatorObj->Name,
+ notes => ($txn->Content ne 'This transaction appears to have no content' ? substr($txn->Content, 0, 60) : $txn->BriefDescription)
+ };
+ }
+}
+
+@items = sort {
+ $a->{queue} cmp $b->{'queue'}
+ || $a->{'status'} cmp $b->{'status'}
+ || $a->{'id'} <=> $b->{'id'}
+ || $a->{'actor'} cmp $b->{'actor'}
+ || $a->{'notes'} <=> $b->{'notes'}
+} @items;
+
+</%init>
diff --git a/rt/html/Reports/Activity/ActivitySummary.html b/rt/html/Reports/Activity/ActivitySummary.html
new file mode 100644
index 000000000..7bb756fbc
--- /dev/null
+++ b/rt/html/Reports/Activity/ActivitySummary.html
@@ -0,0 +1,61 @@
+<&|Elements/Wrapper, %ARGS, title => loc("Activity summary"),
+ path => "Reports/Activity/ActivitySummary.html",
+ &>
+
+<& Elements/MiniPlot, data => \%queues &>
+
+<table style="width: 100%">
+<tr class="titlerow">
+<th>Queue</th>
+% for my $status (sort keys %status) {
+<th><% $status %></th>
+% }
+<th>Total</th>
+</tr>
+% for my $queue (sort keys %queues) {
+<th class="label"><% $queue %></th>
+% for my $status (sort keys %status) {
+<td><% $queues{$queue}{$status} || 0 %>
+% }
+<td><% $total{$queue} %></td>
+</tr>
+% }
+<tr class="grandtotal">
+<th class="label" >Grand Total</th>
+% for my $status (sort keys %status) {
+<td><% $status{$status} %></td>
+% }
+<td><% $total %></td>
+</table>
+</&>
+<%args>
+$query => 'id > 0'
+$start => "2005/01/01"
+$end => "2006/01/01"
+</%args>
+<%init>
+
+my $tickets = RT::Tickets->new($session{'CurrentUser'});
+$tickets->FromSQL($query . " AND ( Updated >= '$start' AND Updated <= '$end')");
+
+my %queues;
+my %status;
+my %total;
+my $total;
+while (my $ticket = $tickets->Next) {
+ my $txns = $ticket->Transactions;
+ $txns->Limit(FIELD => 'Created', OPERATOR => '>=', VALUE => $start);
+ $txns->Limit(FIELD => 'Created', OPERATOR => '<=', VALUE => $end);
+ $txns->Limit(FIELD => 'Type', VALUE => 'Status', ENTRYAGGREGATOR => 'OR');
+ $txns->Limit(FIELD => 'Type', VALUE => 'Create');
+
+ while (my $txn = $txns->Next) {
+ $queues{$txn->TicketObj->QueueObj->Name}{$txn->NewValue || 'new'}++;
+ $status{$txn->NewValue || 'new'}++;
+ $total{$txn->TicketObj->QueueObj->Name}++;
+ $total++;
+ }
+}
+
+
+</%init>
diff --git a/rt/html/Reports/Activity/Elements/LimitReport b/rt/html/Reports/Activity/Elements/LimitReport
new file mode 100644
index 000000000..7c4aac73b
--- /dev/null
+++ b/rt/html/Reports/Activity/Elements/LimitReport
@@ -0,0 +1,23 @@
+<form action="index.html" method="POST" enctype="multipart/form-data">
+Query:
+<textarea name="query" rows="5" cols="80"><% $query %></textarea><br />
+
+Report type: <select name="type">
+<option value="ActivityDetail" <% $ARGS{path} =~ /ActivityDetail/ ? 'selected' : '' %>>Activity detail</option>
+<option value="ActivitySummary" <% $ARGS{path} =~ /ActivitySummary/ ? 'selected' : '' %>>Activity summary</option>
+<option value="ResolutionComments" <% $ARGS{path} =~ /ResolutionComments/ ? 'selected' : '' %>>Resolution comments</option>
+<option value="ResolutionStatistics" <% $ARGS{path} =~ /ResolutionStatistics/ ? 'selected' : '' %>>Resolution statistics</option>
+</select><br />
+
+Start date: <input type="text" name="start" value="<% $start %>" /><br />
+End date: <input type="text" name="end" value="<% $end %>" /><br />
+<& /Elements/Submit, Label => loc('Report') &>
+</form>
+<%args>
+$type => undef
+$start => undef
+$end => undef
+$query => undef
+</%args>
+<%init>
+</%init>
diff --git a/rt/html/Reports/Activity/Elements/MiniPlot b/rt/html/Reports/Activity/Elements/MiniPlot
new file mode 100644
index 000000000..f92032818
--- /dev/null
+++ b/rt/html/Reports/Activity/Elements/MiniPlot
@@ -0,0 +1,57 @@
+<table class="miniplot"><tr>
+% for my $major (@major) {
+<td><div class="graph">
+ <ul>
+% my $i = 0;
+% for my $minor (@minor) {
+% my $percent = int( 100 * ($data->{$major}{$minor} || 0) / $max );
+ <li class="c<% ($i % 6) + 1%>" style="width: <% $barwidth %>%;
+ left: <% $baroffset + $each * $i %>%;
+ height: <% $percent %>%;"><div class="data"><% $minor %>: <% $percent %>%</div></li>
+% $i++;
+% }
+ </ul>
+</div></td>
+% }
+</tr><tr>
+% for my $major (@major) {
+<th class="legend"><% $major %></th>
+% }
+</tr>
+</table>
+
+<table class="miniplot"><tr>
+% my $i = 0;
+% for my $minor (@minor) {
+<th><span class="demoblock c<% ($i++ % 6) + 1 %>"></span> <% $minor %></th>
+% }
+</tr>
+</table>
+
+<%args>
+$data
+$major => undef
+$minor => undef
+</%args>
+<%init>
+
+my $max = 1;
+
+my %minor;
+for my $major (keys %{$data}) {
+ for (keys %{$data->{$major}}) {
+ $minor{$_}++;
+ $max = $data->{$major}{$_} if $data->{$major}{$_} > $max;
+ }
+}
+
+my @major = $major ? @{$major} : sort keys %{$data};
+my @minor = $minor ? @{$minor} : sort keys %minor;
+
+return unless @minor and @major;
+
+my $each = int( (100 / @minor) );
+my $barwidth = int( (100 / @minor) * (3/4) );
+my $baroffset = int( (100 / @minor) * (1/8) );
+
+</%init>
diff --git a/rt/html/Reports/Activity/Elements/PrintFooter b/rt/html/Reports/Activity/Elements/PrintFooter
new file mode 100644
index 000000000..fa9f47582
--- /dev/null
+++ b/rt/html/Reports/Activity/Elements/PrintFooter
@@ -0,0 +1,7 @@
+<hr/>
+<div style="text-align: center;">
+<%$RT::ReportFooterMessage || 'Proprietary and Confidential' %>
+</div>
+</body>
+</html>
+%$m->abort();
diff --git a/rt/html/Reports/Activity/Elements/PrintHeader b/rt/html/Reports/Activity/Elements/PrintHeader
new file mode 100644
index 000000000..b7c4b3419
--- /dev/null
+++ b/rt/html/Reports/Activity/Elements/PrintHeader
@@ -0,0 +1,32 @@
+<%args>
+$title => undef
+$path => undef
+$query => undef
+</%args>
+<HTML>
+<HEAD>
+<TITLE><%$title%></TITLE>
+<link rel="shortcut icon" href="<%$RT::WebImagesURL%>/favicon.png" type="image/png" />
+<link media="all" rel="stylesheet" href="<%$RT::WebPath%>/NoAuth/webrt.css" type="text/css" />
+<link media="print" rel="stylesheet" href="<%$RT::WebPath%>/NoAuth/printrt.css" type="text/css" />
+%# XXX TODO THIS SHOULD NOT BE A TABLE
+<body>
+<table width="100%">
+<tr>
+<td align="left">
+<div id="username">User: <%$session{'CurrentUser'}->Name%></div>
+<div id="reportdate">
+%my $d= RT::Date->new($session{'CurrentUser'}); $d->SetToNow;
+<%$d->AsString%></div>
+</td>
+<td align="center">
+<h1><%$title%></h1>
+</td>
+<td align="right">
+<img src="<%$RT::LogoURL%>" alt="RT Logo"/>
+</td>
+</tr>
+</table>
+<hr/>
+<&|/l&>Report criteria:</&> <%$query%>
+<hr />
diff --git a/rt/html/Reports/Activity/Elements/ScreenFooter b/rt/html/Reports/Activity/Elements/ScreenFooter
new file mode 100644
index 000000000..235b7b306
--- /dev/null
+++ b/rt/html/Reports/Activity/Elements/ScreenFooter
@@ -0,0 +1,13 @@
+<& LimitReport, %ARGS &>
+% if ($show_print_link) {
+<div align="right">
+% my %printable_args = %ARGS;
+% delete $printable_args{$_} for (qw/path title mode/);
+% $printable_args{'mode'} = 'print';
+% my $url = $ARGS{'path'} .'?'. join(';', map { $_."=".$printable_args{$_} } keys %printable_args);
+<a href="<%$RT::WebPath|n%>/<%$url|n%>"><&|/l&>Printable version</&></a>
+</div>
+% }
+<%args>
+$show_print_link => 1
+</%args>
diff --git a/rt/html/Reports/Activity/Elements/ScreenHeader b/rt/html/Reports/Activity/Elements/ScreenHeader
new file mode 100644
index 000000000..080efc0dd
--- /dev/null
+++ b/rt/html/Reports/Activity/Elements/ScreenHeader
@@ -0,0 +1,8 @@
+<%args>
+$title => undef
+$path => undef
+</%args>
+<& /Elements/Header, Title => $title &>
+<& Tabs,
+ current_subtab => $path,
+ Title => $title &>
diff --git a/rt/html/Reports/Activity/Elements/Tabs b/rt/html/Reports/Activity/Elements/Tabs
new file mode 100644
index 000000000..a9498209e
--- /dev/null
+++ b/rt/html/Reports/Activity/Elements/Tabs
@@ -0,0 +1,52 @@
+<& /Elements/Tabs,
+ tabs => $tabs,
+ subtabs => $subtabs,
+ current_toptab => 'Tools/Offline.html',
+ current_tab => 'Reports/Activity/index.html'.$args,
+ Title => $Title &>
+
+<%INIT>
+my $subtabs = {};
+
+my $top = $m->caller_args(-1);
+my $args = "?" . $m->comp( '/Elements/QueryString',
+ query => $top->{query},
+ start => $top->{start},
+ end => $top->{end});
+if ($m->caller_args(-1)->{'query'}) {
+ $current_subtab .= $args;
+ $subtabs = {
+ a => { title => 'Activity detail',
+ path => 'Reports/Activity/ActivityDetail.html'.$args,
+ },
+ b => { title => 'Activity summary',
+ path => 'Reports/Activity/ActivitySummary.html'.$args,
+ },
+ c => { title => 'Resolution comments',
+ path => 'Reports/Activity/ResolutionComments.html'.$args,
+ },
+ d => { title => 'Resolution statistics',
+ path => 'Reports/Activity/ResolutionStatistics.html'.$args,
+ },
+ };
+}
+
+my $tabs = {
+ a => { title => loc('Offline'),
+ path => 'Tools/Offline.html',
+ },
+ r => { title => loc('Reports'),
+ path => 'Reports/Activity/index.html'.$args,
+ subtabs => $subtabs,
+ current_subtab => $current_subtab,
+ }
+ };
+
+</%INIT>
+
+
+<%ARGS>
+$current_tab => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Reports/Activity/Elements/Wrapper b/rt/html/Reports/Activity/Elements/Wrapper
new file mode 100644
index 000000000..6f81f5f50
--- /dev/null
+++ b/rt/html/Reports/Activity/Elements/Wrapper
@@ -0,0 +1,16 @@
+<%args>
+$mode => 'screen'
+</%args>
+
+% if ($mode eq 'print') {
+<& PrintHeader, %ARGS &>
+%} else {
+<& ScreenHeader, %ARGS &>
+% }
+<%$m->content |n%>
+% if ($mode eq 'print') {
+<& PrintFooter, %ARGS &>
+%} else {
+<& ScreenFooter, %ARGS &>
+% }
+
diff --git a/rt/html/Reports/Activity/ResolutionComments.html b/rt/html/Reports/Activity/ResolutionComments.html
new file mode 100644
index 000000000..81ca301cc
--- /dev/null
+++ b/rt/html/Reports/Activity/ResolutionComments.html
@@ -0,0 +1,62 @@
+<&|Elements/Wrapper, %ARGS, title => loc("Resolution Comments"),
+ path => "Reports/Activity/ResolutionComments.html",
+ &>
+
+<table style="width: 100%">
+<tr>
+<th>Queue</th><th>Ticket #</th><th>Created</th><th>Resolved</th><th>Time to resolve</th>
+</tr>
+<tr>
+<th colspan="5">Resolution comments</th>
+</tr>
+% for my $item (@items) {
+<tr class="titlerow">
+<td><% $item->{queue} %></td>
+<td><% $item->{id} %></td>
+<td><% $item->{created} %></td>
+<td><% $item->{resolved} %></td>
+<td><% $item->{duration} %></td>
+</tr>
+<tr>
+<td colspan="5"><% $item->{whiteboard} %></td>
+</tr>
+% }
+</table>
+</&>
+
+<%args>
+$query => 'id > 0'
+$start => "2005/01/01"
+$end => "2006/01/01"
+</%args>
+<%init>
+
+use Time::Duration;
+
+my $summary_tickets = RT::Tickets->new( $session{'CurrentUser'} );
+$summary_tickets->FromSQL(
+ $query . " AND (Status = 'resolved') AND ( Updated >= '$start' AND Updated <= '$end')" );
+
+my @items;
+while ( my $ticket = $summary_tickets->Next ) {
+ push @items, {
+ queue => $ticket->QueueObj->Name,
+ id => $ticket->id,
+ created => $ticket->CreatedObj->AsString,
+ resolved => $ticket->ResolvedObj->AsString,
+ duration => Time::Duration::concise(
+ Time::Duration::duration(
+ $ticket->ResolvedObj->Unix - $ticket->CreatedObj->Unix
+ )
+ ),
+ whiteboard => $ticket->FirstCustomFieldValue('Whiteboard')
+ };
+}
+
+@items = sort { $a->{queue} cmp $b->{queue} || $a->{id} <=> $b->{id} } @items;
+
+
+
+
+
+</%init>
diff --git a/rt/html/Reports/Activity/ResolutionStatistics.html b/rt/html/Reports/Activity/ResolutionStatistics.html
new file mode 100644
index 000000000..4ecde2c82
--- /dev/null
+++ b/rt/html/Reports/Activity/ResolutionStatistics.html
@@ -0,0 +1,95 @@
+<&|Elements/Wrapper, %ARGS, title => loc("Resolution statistics"),
+ path => "Reports/Activity/ResolutionStatistics.html",
+ &>
+
+<& Elements/MiniPlot,
+ data => \%plot,
+ major => ['Date range','Last 30 days','Last 60 days','Last 90 days','Ever'],
+ minor => [(sort keys %queues), "Average"]
+ &>
+
+<table style="width: 100%">
+<tr>
+<td></td><th colspan="4">Number of tickets closed / Average resolution time per ticket</th>
+</tr>
+<tr class="titlerow">
+<th>Queue</th>
+<th>Date range</th>
+<th>Last 30 days</th>
+<th>Last 60 days</th>
+<th>Last 90 days</th>
+<th>Ever</th>
+</tr>
+% for my $queue (sort keys %queues) {
+<tr>
+<th><% $queue %></th>
+% for my $period ('Date range','Last 30 days','Last 60 days','Last 90 days','Ever') {
+<td><% scalar @{$closed{$period}{$queue}} %> / <% $average_resolve_times{$period}{$queue} %></td>
+% }
+</tr>
+% }
+<tr class="grandtotal">
+<th>Ticket average</th>
+% for my $period ('Date range','Last 30 days','Last 60 days','Last 90 days','Ever') {
+<td><% $average_resolve_times{$period}{_all_count} %> / <% $average_resolve_times{$period}{_all} %></td>
+% }
+</tr>
+</table>
+
+</&>
+<%args>
+$query => 'id > 0'
+$start => "2005/01/01"
+$end => "2006/01/01"
+</%args>
+<%init>
+
+my $in_30_days = RT::Date->new($session{'CurrentUser'});
+$in_30_days->Set(Format => 'Unix', Value => ( time - (86400*30)));
+my $in_60_days = RT::Date->new($session{'CurrentUser'});
+$in_60_days->Set(Format => 'Unix', Value => ( time - (86400*60)));
+my $in_90_days = RT::Date->new($session{'CurrentUser'});
+$in_90_days->Set(Format => 'Unix', Value => ( time - (86400*90)));
+
+my %queries;
+$queries{'Date range'} = "(Resolved >= '$start' AND Resolved <= '$end')";
+$queries{'Last 30 days'} = "(Resolved >= '".$in_30_days->ISO."')";
+$queries{'Last 60 days'} = "(Resolved >= '".$in_60_days->ISO."')";
+$queries{'Last 90 days'} = "(Resolved >= '".$in_90_days->ISO."')";
+$queries{'Ever'} = "(Status = 'resolved' OR Status = 'rejected')";
+
+
+my %closed;
+my %queues;
+foreach my $period (keys %queries) {
+ my $tix = RT::Tickets->new($session{'CurrentUser'});
+ $tix->FromSQL($query . " AND " .$queries{$period});
+
+ while (my $ticket = $tix->Next) {
+ push @{ $closed{$period}{$ticket->QueueObj->Name}}, $ticket;
+ $queues{$ticket->QueueObj->Name}++;
+ }
+}
+
+my %restimes;
+my %average_resolve_times;
+my %plot;
+use Time::Duration;
+foreach my $period ( keys %closed ) {
+ foreach my $queue ( keys %{$closed{$period}} ) {
+ foreach my $ticket (@{$closed{$period}{$queue}} ) {
+ push @{$restimes{$period}{$queue}}, ( $ticket->ResolvedObj->Unix - $ticket->CreatedObj->Unix);
+ }
+
+ my $total_time = 0;
+ $total_time+= $_ for @{$restimes{$period}{$queue}};
+ $average_resolve_times{$period}{'_all_time'} += $total_time;
+ $average_resolve_times{$period}{'_all_count'} += @{$restimes{$period}{$queue}};
+ $plot{$period}{$queue} = $total_time / @{$restimes{$period}{$queue}};
+ $average_resolve_times{$period}{$queue} = Time::Duration::concise(Time::Duration::duration($plot{$period}{$queue}));
+ }
+ $plot{$period}{Average} = $average_resolve_times{$period}{'_all_time'} / $average_resolve_times{$period}{'_all_count'};
+ $average_resolve_times{$period}{'_all'} = Time::Duration::concise(Time::Duration::duration($plot{$period}{Average}));
+}
+
+</%init>
diff --git a/rt/html/Reports/Activity/index.html b/rt/html/Reports/Activity/index.html
new file mode 100644
index 000000000..1f6ddb0d5
--- /dev/null
+++ b/rt/html/Reports/Activity/index.html
@@ -0,0 +1,29 @@
+<&| Elements/Wrapper, %ARGS, title => loc("Activity reports"), show_print_link => 0 &>
+
+
+</&>
+
+<%args>
+$type => undef
+$start => undef
+$end => undef
+$query => "Status = 'resolved'"
+</%args>
+<%init>
+
+unless ($start) {
+ my $then = RT::Date->new($session{'CurrentUser'});
+ $then->Set(Format => 'Unix', Value => time - (86400*7));
+ $ARGS{start} = substr($then->ISO,0,10);
+}
+
+unless ($end) {
+ my $now = RT::Date->new($session{'CurrentUser'});
+ $now->SetToNow();
+ $ARGS{end} = substr($now->ISO,0,10);
+}
+
+if ($type) {
+ $m->redirect($type . ".html?" . $m->comp('/Elements/QueryString', query => $query, start => $start, end => $end));
+}
+</%init>
diff --git a/rt/html/Search/Build.html b/rt/html/Search/Build.html
new file mode 100644
index 000000000..263958775
--- /dev/null
+++ b/rt/html/Search/Build.html
@@ -0,0 +1,832 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%#
+%# Data flow here:
+%# The page receives a Query from the previous page, and maybe arguments
+%# corresponding to actions. (If it doesn't get a Query argument, it pulls
+%# one out of the session hash. Also, it could be getting just a raw query from
+%# Build/Edit.html (Advanced).)
+%#
+%# After doing some stuff with default arguments and saved searches, the ParseQuery
+%# function (which is similar to, but not the same as, _parser in RT/Tickets_Overlay_SQL)
+%# converts the Query into a RT::Interface::Web::QueryBuilder::Tree. This mason file
+%# then adds stuff to or modifies the tree based on the actions that had been requested
+%# by clicking buttons. It then calls GetQueryAndOptionList on the tree to generate
+%# the SQL query (which is saved as a hidden input) and the option list for the Clauses
+%# box in the top right corner.
+%#
+%# Worthwhile refactoring: the tree manipulation code for the actions could use some cleaning
+%# up. The node-adding code is different in the "add" actions from in ParseQuery, which leads
+%# to things like ParseQuery correctly not quoting numbers in numerical fields, while the "add"
+%# action does quote it (this breaks SQLite).
+%#
+<& /Elements/Header, Title => $title &>
+<& /Ticket/Elements/Tabs,
+ current_tab => "Search/Build.html".$QueryString,
+ Title => $title,
+ Format => $Format,
+ Query => $Query,
+ Order => $Order,
+ OrderBy => $OrderBy,
+ Rows => $RowsPerPage
+&>
+
+<form method="post" action="Build.html" name="BuildQuery">
+<input type="hidden" class="hidden" name="SearchId" value="<%$SearchId%>" />
+<input type="hidden" class="hidden" name="Query" value="<%$Query%>" />
+<input type="hidden" class="hidden" name="Format" value="<%$Format%>" />
+<table width="100%" border="0" cellpadding="5">
+<tr valign="top">
+<td class="boxcontainer" rowspan="2" width="65%">
+<& Elements/PickCriteria, query => $Query, cfqueues => $queues &>
+<& /Elements/Submit, Caption => loc('Add these terms to your search'), Label => loc('Add'), Name => 'AddClause'&>
+</td>
+
+<td>
+<& Elements/EditQuery,
+ %ARGS,
+ actions => \@actions,
+ optionlist => $optionlist,
+ Description => $Description &>
+<& /Elements/Submit, Label => loc('Add and Search'), Name => 'DoSearch'&>
+</td>
+</tr>
+
+<tr valign="top">
+<td>
+<& Elements/EditSearches, CurrentSearch => $search_hash, Dirty => $dirty, SearchId => $SearchId &>
+</td>
+</tr>
+
+<tr>
+<td colspan="2" class="boxcontainer">
+
+<& Elements/DisplayOptions, %ARGS, Format=> $Format,
+AvailableColumns => $AvailableColumns, CurrentFormat => $CurrentFormat, RowsPerPage => $RowsPerPage, OrderBy => $OrderBy, Order => $Order &>
+<& /Elements/Submit, Label => loc('Add and Search'), Name => 'DoSearch'&>
+</td>
+</tr>
+</table>
+</form>
+
+<%INIT>
+use RT::Interface::Web::QueryBuilder;
+use RT::Interface::Web::QueryBuilder::Tree;
+
+my $search_hash = {};
+my $search;
+my $title = loc("Query Builder");
+
+# {{{ Clear out unwanted data
+if ( $NewQuery or $ARGS{'Delete'} ) {
+
+ # Wipe all data-carrying variables clear if we want a new
+ # search, or we're deleting an old one..
+ $Query = '';
+ $Format = '';
+ $Description = '';
+ $SearchId = '';
+ $Order = '';
+ $OrderBy = '';
+ $RowsPerPage = undef;
+
+ # ($search hasn't been set yet; no need to clear)
+
+ # ..then wipe the session out..
+ undef $session{'CurrentSearchHash'};
+
+ # ..and the search results.
+ $session{'tickets'}->CleanSlate() if defined $session{'tickets'};
+}
+
+# }}}
+
+if (ref $OrderBy eq "ARRAY") {
+ $OrderBy = join("|", @$OrderBy);
+}
+if (ref $Order eq "ARRAY") {
+ $Order = join("|", @$Order);
+}
+
+# {{{ Attempt to load what we can from the session, set defaults
+
+# We don't read or write to the session again until the end
+$search_hash = $session{'CurrentSearchHash'};
+
+# Read from user preferences
+my $prefs = $session{'CurrentUser'}->UserObj->Preferences("SearchDisplay") || {};
+
+# These variables are what define a search_hash; this is also
+# where we give sane defaults.
+$Query ||= $search_hash->{'Query'};
+$Format ||= $search_hash->{'Format'} || $prefs->{'Format'};
+$Description ||= $search_hash->{'Description'};
+$SearchId ||= $search_hash->{'SearchId'} || 'new';
+$Order ||= $search_hash->{'Order'} || $prefs->{'Order'} || 'ASC';
+$OrderBy ||= $search_hash->{'OrderBy'} || $prefs->{'OrderBy'} || 'id';
+
+unless ( defined $RowsPerPage ) {
+ if ( defined $search_hash->{'RowsPerPage'} ) {
+ $RowsPerPage = $search_hash->{'RowsPerPage'};
+ }
+ elsif ( defined $prefs->{'RowsPerPage'} ) {
+ $RowsPerPage = $prefs->{'RowsPerPage'};
+ }
+ else {
+ $RowsPerPage = 50;
+ }
+}
+
+ $search ||= $search_hash->{'Object'};
+
+# }}}
+
+my @actions = ();
+
+# Clean unwanted junk from the format
+$Format = $m->comp( '/Elements/ScrubHTML', Content => $Format ) if ($Format);
+
+# {{{ If we're asked to delete the current search, make it go away and reset the search parameters
+if ( $ARGS{'Delete'} ) {
+
+ # We set $SearchId to 'new' above already, so peek into the %ARGS
+ my ($container_object, $search_id) = _parse_saved_search ($ARGS{'SearchId'});
+ if ($container_object && $container_object->id) {
+ # We have the object the entry is an attribute on; delete the
+ # entry..
+ $container_object->Attributes->DeleteEntry(
+ Name => 'SavedSearch',
+ id => $search_id
+ );
+ }
+}
+
+# }}}
+
+# {{{ If the user wants to copy a search, uncouple from the one that this was based on, but don't erase the $Query or $Format
+if ( $ARGS{'CopySearch'} ) {
+ $SearchId = 'new';
+ $search = undef;
+ $Description = loc( "[_1] copy", $Description );
+}
+
+# }}}
+
+# {{{ if we're asked to revert the current search, we just want to load it
+if ( $ARGS{'Revert'} ) {
+ $ARGS{'LoadSavedSearch'} = $SearchId;
+}
+
+# }}}
+
+# {{{ if we're asked to load a search, load it.
+
+if ( my ($container_object, $search_id ) = _parse_saved_search ($ARGS{'LoadSavedSearch'})) {
+ $search = $container_object->Attributes->WithId($search_id);
+
+ # We have a $search and now; import the others
+ $SearchId = $ARGS{'LoadSavedSearch'};
+ $Description = $search->Description;
+ $Format = $search->SubValue('Format');
+ $Query = $search->SubValue('Query');
+ $Order = $search->SubValue('Order');
+ $OrderBy = $search->SubValue('OrderBy');
+ $RowsPerPage = $search->SubValue('RowsPerPage');
+}
+
+# }}}
+
+# {{{ if we're asked to save the current search, save it
+if ( $ARGS{'Save'} ) {
+ if ( $search && $search->id ) {
+ # permission check
+ if ($search->Object->isa('RT::System')) {
+ unless ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'SuperUser')) {
+ Abort("No permission to save system-wide searches");
+ }
+ }
+
+ # This search is based on a previously loaded search -- so
+ # just update the current search object with new values
+ $search->SetSubValues(
+ Format => $Format,
+ Query => $Query,
+ Order => $Order,
+ OrderBy => $OrderBy,
+ RowsPerPage => $RowsPerPage,
+ );
+ $search->SetDescription($Description);
+
+ }
+ elsif ( $SearchId eq 'new' ) {
+ my $saved_search = RT::SavedSearch->new( $session{'CurrentUser'} );
+ my ( $ok, $search_msg ) = $saved_search->Save(
+ Privacy => $ARGS{'Owner'},
+ Name => $Description,
+ SearchParams => {
+ Format => $Format,
+ Query => $Query,
+ Order => $Order,
+ OrderBy => $OrderBy,
+ RowsPerPage => $RowsPerPage } );
+
+ if ($ok) {
+ $search = $session{'CurrentUser'}->UserObj->Attributes->WithId($saved_search->Id);
+ # Build new SearchId
+ $SearchId =
+ ref( $session{'CurrentUser'}->UserObj ) . '-'
+ . $session{'CurrentUser'}->UserObj->Id
+ . '-SavedSearch-'
+ . $search->Id;
+ }
+ else {
+ push @actions, [ loc("Can't find a saved search to work with").': '.loc($search_msg), 0 ];
+ }
+ }
+ else {
+ push @actions, [ loc("Can't save this search"), 0 ];
+ }
+
+}
+
+# }}}
+
+
+# {{{ Parse the query
+use Regexp::Common qw /delimited/;
+
+# States
+use constant VALUE => 1;
+use constant AGGREG => 2;
+use constant OP => 4;
+use constant PAREN => 8;
+use constant KEYWORD => 16;
+
+my $_match = sub {
+
+ # Case insensitive equality
+ my ( $y, $x ) = @_;
+ return 1 if $x =~ /^$y$/i;
+
+ # return 1 if ((lc $x) eq (lc $y)); # Why isnt this equiv?
+ return 0;
+};
+
+my $ParseQuery = sub {
+ my $string = shift;
+ my $tree = shift;
+ my $actions = shift;
+ my $want = KEYWORD | PAREN;
+ my $last = undef;
+
+ my $depth = 1;
+
+ # make a tree root
+ $$tree = RT::Interface::Web::QueryBuilder::Tree->new;
+ my $root = RT::Interface::Web::QueryBuilder::Tree->new( 'AND', $$tree );
+ my $parentnode = $root;
+
+ # on new searches, we're passed undef but still need to construct the
+ # RT::Interface::Web::QueryBuilder::Tree. Quiet warning
+ return unless defined $string;
+
+ # get the FIELDS from Tickets_Overlay
+ my $tickets = new RT::Tickets( $session{'CurrentUser'} );
+ my %FIELDS = %{ $tickets->FIELDS };
+
+ # Lower Case version of FIELDS, for case insensitivity
+ my %lcfields = map { ( lc($_) => $_ ) } ( keys %FIELDS );
+
+ my @tokens = qw[VALUE AGGREG OP PAREN KEYWORD];
+ my $re_aggreg = qr[(?i:AND|OR)];
+ my $re_value = qr[$RE{delimited}{-delim=>qq{\'\"}}|\d+];
+ my $re_keyword = qr[$RE{delimited}{-delim=>qq{\'\"}}|(?:\{|\}|\w|\.)+];
+ my $re_op =
+ qr[=|!=|>=|<=|>|<|(?i:IS NOT)|(?i:IS)|(?i:NOT LIKE)|(?i:LIKE)]
+ ; # long to short
+ my $re_paren = qr'\(|\)';
+
+ # assume that $ea is AND if it is not set
+ my ( $ea, $key, $op, $value ) = ( "AND", "", "", "" );
+
+ # order of matches in the RE is important.. op should come early,
+ # because it has spaces in it. otherwise "NOT LIKE" might be parsed
+ # as a keyword or value.
+
+ while (
+ $string =~ /(
+ $re_aggreg
+ |$re_op
+ |$re_keyword
+ |$re_value
+ |$re_paren
+ )/igx
+ )
+ {
+ my $val = $1;
+ my $current = 0;
+
+ # Highest priority is last
+ $current = OP if $_match->( $re_op, $val );
+ $current = VALUE if $_match->( $re_value, $val );
+ $current = KEYWORD
+ if $_match->( $re_keyword, $val ) && ( $want & KEYWORD );
+ $current = AGGREG if $_match->( $re_aggreg, $val );
+ $current = PAREN if $_match->( $re_paren, $val );
+
+ unless ( $current && $want & $current ) {
+
+ # Error
+ # FIXME: I will only print out the highest $want value
+ my $token = $tokens[ ( ( log $want ) / ( log 2 ) ) ];
+ push @$actions,
+ [
+ loc("Error near ->[_1]<- expecting a [_2] in '[_3]'",
+ $val, $token, $string ),
+ -1
+ ];
+ }
+
+ # State Machine:
+ my $parentdepth = $depth;
+
+ # Parens are highest priority
+ if ( $current & PAREN ) {
+ if ( $val eq "(" ) {
+ $depth++;
+
+ # make a new node that the clauses can be children of
+ $parentnode = RT::Interface::Web::QueryBuilder::Tree->new( $ea, $parentnode );
+ }
+ else {
+ $depth--;
+ $parentnode = $parentnode->getParent();
+ }
+
+ $want = KEYWORD | PAREN | AGGREG;
+ }
+ elsif ( $current & AGGREG ) {
+ $ea = $val;
+ $parentnode->setNodeValue($ea);
+ $want = KEYWORD | PAREN;
+ }
+ elsif ( $current & KEYWORD ) {
+ $key = $val;
+ $want = OP;
+ }
+ elsif ( $current & OP ) {
+ $op = $val;
+ $want = VALUE;
+ }
+ elsif ( $current & VALUE ) {
+ $value = $val;
+
+ # Remove surrounding quotes from $key, $val
+ # (in future, simplify as for($key,$val) { action on $_ })
+ if ( $key =~ /$RE{delimited}{-delim=>qq{\'\"}}/ ) {
+ substr( $key, 0, 1 ) = "";
+ substr( $key, -1, 1 ) = "";
+ }
+ if ( $val =~ /$RE{delimited}{-delim=>qq{\'\"}}/ ) {
+ substr( $val, 0, 1 ) = "";
+ substr( $val, -1, 1 ) = "";
+ }
+
+ # Unescape escaped characters
+ $key =~ s!\\(.)!$1!g;
+ $val =~ s!\\(.)!$1!g;
+
+ my $class;
+
+ my ($key_base, $subkey) = split(/\./,$key,2);
+ $key_base =~ s/\..*$//; # Strip off .EmailAddress, for example
+
+ if ( exists $lcfields{lc $key_base } ) {
+ $key = $lcfields{lc $key_base } . (defined $subkey ? '.'.$subkey : '');
+ $class = $FIELDS{$key_base}->[0];
+ }
+ elsif ( $key =~ /^C(?:ustom)?F(?:ield)?\.{(.*)}$/i ) {
+ $class = $FIELDS{'CF'}->[0];
+ }
+
+ if ( $class ne 'INT' ) {
+ $val = "'$val'";
+ }
+
+ push @$actions, [ loc("Unknown field: [_1]", $key), -1 ] unless $class;
+
+ $want = PAREN | AGGREG;
+ }
+ else {
+ push @$actions, [ loc("I'm lost"), -1 ];
+ }
+
+ if ( $current & VALUE ) {
+ if ( $key =~ /^CF./ ) {
+ $key = "'" . $key . "'";
+ }
+ my $clause = {
+ Key => $key,
+ Op => $op,
+ Value => $val
+ };
+
+ # explicity add a child to it
+ RT::Interface::Web::QueryBuilder::Tree->new( $clause, $parentnode );
+
+ ( $ea, $key, $op, $value ) = ( "", "", "", "" );
+
+ }
+
+ $last = $current;
+ } # while
+
+ push @$actions, [ loc("Incomplete query"), -1 ]
+ unless ( ( $want | PAREN ) || ( $want | KEYWORD ) );
+
+ push @$actions, [ loc("Incomplete Query"), -1 ]
+ unless ( $last && ( $last | PAREN ) || ( $last || VALUE ) );
+
+ # This will never happen, because the parser will complain
+ push @$actions, [ loc("Mismatched parentheses"), -1 ]
+ unless $depth == 1;
+};
+
+my $tree;
+{
+ my @parsing_errors;
+ $ParseQuery->( $Query, \$tree, \@parsing_errors );
+
+ # if parsing went poorly, send them to the edit page
+ # to fix it
+ if ( @parsing_errors ) {
+ return $m->comp(
+ "Edit.html",
+ Query => $Query,
+ actions => \@parsing_errors
+ );
+ }
+}
+
+$Query = "";
+
+my @options = $tree->GetDisplayedNodes;
+
+my @current_values = grep { defined } @options[@clauses];
+
+# {{{ Move things around
+if ( $ARGS{"Up"} ) {
+ if (@current_values) {
+ foreach my $value (@current_values) {
+ my $index = $value->getIndex();
+ if ( $value->getIndex() > 0 ) {
+ my $parent = $value->getParent();
+ $parent->removeChild($index);
+ $parent->insertChild( $index - 1, $value );
+ $value = $parent->getChild( $index - 1 );
+ }
+ else {
+ push( @actions, [ loc("error: can't move up"), -1 ] );
+ }
+ }
+ }
+ else {
+ push( @actions, [ loc("error: nothing to move"), -1 ] );
+ }
+}
+elsif ( $ARGS{"Down"} ) {
+ if (@current_values) {
+ foreach my $value (@current_values) {
+ my $index = $value->getIndex();
+ my $parent = $value->getParent();
+ if ( $value->getIndex() < ( $parent->getChildCount - 1 ) ) {
+ $parent->removeChild($index);
+ $parent->insertChild( $index + 1, $value );
+ $value = $parent->getChild( $index + 1 );
+ }
+ else {
+ push( @actions, [ loc("error: can't move down"), -1 ] );
+ }
+ }
+ }
+ else {
+ push( @actions, [ loc("error: nothing to move"), -1 ] );
+ }
+}
+elsif ( $ARGS{"Left"} ) {
+ if (@current_values) {
+ foreach my $value (@current_values) {
+ my $parent = $value->getParent();
+ my $grandparent = $parent->getParent();
+ if ( !$grandparent->isRoot ) {
+ my $index = $parent->getIndex();
+ $parent->removeChild($value);
+ $grandparent->insertChild( $index, $value );
+ if ( $parent->isLeaf() ) {
+ $grandparent->removeChild($parent);
+ }
+ }
+ else {
+ push( @actions, [ loc("error: can't move left"), -1 ] );
+ }
+ }
+ }
+ else {
+ push( @actions, [ loc("error: nothing to move"), -1 ] );
+ }
+}
+elsif ( $ARGS{"Right"} ) {
+ if (@current_values) {
+ foreach my $value (@current_values) {
+ my $parent = $value->getParent();
+ my $index = $value->getIndex();
+ my $newparent;
+ if ( $index > 0 ) {
+ my $sibling = $parent->getChild( $index - 1 );
+ if ( ref( $sibling->getNodeValue ) ) {
+ $parent->removeChild($value);
+ my $newtree = RT::Interface::Web::QueryBuilder::Tree->new( 'AND', $parent );
+ $newtree->addChild($value);
+ }
+ else {
+ $parent->removeChild($index);
+ $sibling->addChild($value);
+ }
+ }
+ else {
+ $parent->removeChild($value);
+ $newparent = RT::Interface::Web::QueryBuilder::Tree->new( 'AND', $parent );
+ $newparent->addChild($value);
+ }
+ }
+ }
+ else {
+ push( @actions, [ loc("error: nothing to move"), -1 ] );
+ }
+}
+elsif ( $ARGS{"DeleteClause"} ) {
+ if (@current_values) {
+ $_->getParent()->removeChild($_) for @current_values;
+ @current_values = ();
+ }
+ else {
+ push( @actions, [ loc("error: nothing to delete"), -1 ] );
+ }
+}
+elsif ( $ARGS{"Toggle"} ) {
+ my $ea;
+ if (@current_values) {
+ foreach my $value (@current_values) {
+ my $parent = $value->getParent();
+
+ if ( $parent->getNodeValue eq 'AND' ) {
+ $parent->setNodeValue('OR');
+ }
+ else {
+ $parent->setNodeValue('AND');
+ }
+ }
+ }
+ else {
+ push( @actions, [ loc("error: nothing to toggle"), -1 ] );
+ }
+}
+
+# {{{ Try to find if we're adding a clause
+foreach my $arg ( keys %ARGS ) {
+ if (
+ $arg =~ m/^ValueOf(\w+|'CF.{.*?}')$/
+ && ( ref $ARGS{$arg} eq "ARRAY"
+ ? grep { $_ ne "" } @{ $ARGS{$arg} }
+ : $ARGS{$arg} ne "" )
+ )
+ {
+
+ # We're adding a $1 clause
+ my $field = $1;
+ my ( $keyword, $op, $value );
+
+ #figure out if it's a grouping
+ if ( $ARGS{ $field . "Field" } ) {
+ $keyword = $ARGS{ $field . "Field" };
+ }
+ else {
+ $keyword = $field;
+ }
+
+ my ( @ops, @values );
+ if ( ref $ARGS{ 'ValueOf' . $field } eq "ARRAY" ) {
+
+ # we have many keys/values to iterate over, because there is
+ # more than one CF with the same name.
+ @ops = @{ $ARGS{ $field . 'Op' } };
+ @values = @{ $ARGS{ 'ValueOf' . $field } };
+ }
+ else {
+ @ops = ( $ARGS{ $field . 'Op' } );
+ @values = ( $ARGS{ 'ValueOf' . $field } );
+ }
+ $RT::Logger->error("Bad Parameters passed into Query Builder")
+ unless @ops == @values;
+
+ for my $i ( 0 .. @ops - 1 ) {
+ my ( $op, $value ) = ( $ops[$i], $values[$i] );
+ next if $value eq "";
+
+ if ( $value eq 'NULL' && $op =~ /=/ ) {
+ if ( $op eq '=' ) {
+ $op = "IS";
+ }
+ elsif ( $op eq '!=' ) {
+ $op = "IS NOT";
+ }
+
+ # This isn't "right", but...
+ # It has to be this way until #5182 is fixed
+ $value = "'NULL'";
+ }
+ else {
+ $value = "'$value'";
+ }
+
+ my $clause = {
+ Key => $keyword,
+ Op => $op,
+ Value => $value
+ };
+
+ my $newnode = RT::Interface::Web::QueryBuilder::Tree->new($clause);
+ if (@current_values) {
+ foreach my $value (@current_values) {
+ my $newindex = $value->getIndex() + 1;
+ $value->insertSibling( $newindex, $newnode );
+ $value = $newnode;
+ }
+ }
+ else {
+ $tree->getChild(0)->addChild($newnode);
+ @current_values = $newnode;
+ }
+ $newnode->getParent()->setNodeValue( $ARGS{'AndOr'} );
+ }
+ }
+}
+
+# }}}
+
+$tree->PruneChildlessAggregators;
+
+# }}}
+
+# {{{ Rebuild $Query based on the additions / movements
+$Query = "";
+my $optionlist_arrayref;
+
+($Query, $optionlist_arrayref) = $tree->GetQueryAndOptionList(\@current_values);
+
+my $optionlist = join "\n", map { qq(<option value="$_->{INDEX}" $_->{SELECTED}>)
+ . ("&nbsp;" x (5 * $_->{DEPTH}))
+ . $m->interp->apply_escapes($_->{TEXT}, 'h') . qq(</option>) } @$optionlist_arrayref;
+
+
+
+
+# }}}
+
+# }}}
+
+my $queues = $tree->GetReferencedQueues;
+
+# {{{ Deal with format changes
+my ( $AvailableColumns, $CurrentFormat );
+( $Format, $AvailableColumns, $CurrentFormat ) = $m->comp(
+ 'Elements/BuildFormatString',
+ cfqueues => $queues,
+ %ARGS, Format => $Format
+);
+
+# }}}
+
+# {{{ If we're modifying an old query, check if it has changed
+my $dirty = 0;
+$dirty = 1
+ if defined $search
+ and ($search->SubValue('Format') ne $Format
+ or $search->SubValue('Query') ne $Query
+ or $search->SubValue('Order') ne $Order
+ or $search->SubValue('OrderBy') ne $OrderBy
+ or $search->SubValue('RowsPerPage') ne $RowsPerPage );
+
+# }}}
+
+# {{{ Push the updates into the session so we don't loose 'em
+$search_hash->{'SearchId'} = $SearchId;
+$search_hash->{'Format'} = $Format;
+$search_hash->{'Query'} = $Query;
+$search_hash->{'Description'} = $Description;
+$search_hash->{'Object'} = $search;
+$search_hash->{'Order'} = $Order;
+$search_hash->{'OrderBy'} = $OrderBy;
+$search_hash->{'RowsPerPage'} = $RowsPerPage;
+
+$session{'CurrentSearchHash'} = $search_hash;
+
+# }}}
+
+# {{{ Show the results, if we were asked.
+if ( $ARGS{"DoSearch"}) {
+ $m->comp(
+ "Results.html",
+ Query => $Query,
+ Format => $Format,
+ Order => $Order,
+ OrderBy => $OrderBy,
+ Rows => $RowsPerPage
+ );
+ $m->comp('/Elements/Footer');
+ $m->abort();
+}
+
+# }}}
+
+# {{{ Build a querystring for the tabs
+
+my $QueryString;
+if ($NewQuery) {
+ $QueryString = '?NewQuery=1';
+}
+else {
+ $QueryString = '?'
+ . $m->comp(
+ '/Elements/QueryString',
+ Query => $Query,
+ Format => $Format,
+ Order => $Order,
+ OrderBy => $OrderBy,
+ Rows => $RowsPerPage
+ )
+ if ($Query);
+}
+
+# }}}
+
+</%INIT>
+
+<%ARGS>
+$NewQuery => 0
+$SearchId => undef
+$Query => undef
+$Format => undef
+$Description => undef
+$Order => undef
+$OrderBy => undef
+$RowsPerPage => undef
+$HideResults => 0
+@clauses => ()
+</%ARGS>
+
diff --git a/rt/html/Search/Bulk.html b/rt/html/Search/Bulk.html
new file mode 100644
index 000000000..9742df5ae
--- /dev/null
+++ b/rt/html/Search/Bulk.html
@@ -0,0 +1,396 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title &>
+<& /Ticket/Elements/Tabs,
+ current_tab => "Search/Bulk.html",
+ Title => $title,
+ Format => $ARGS{'Format'}, # we don't want the locally modified one
+ Query => $Query,
+ Rows => $Rows,
+ OrderBy => $OrderBy,
+ Order => $Order &>
+
+<& /Elements/ListActions, actions => \@results &>
+<form method="post" action="<%$RT::WebPath%>/Search/Bulk.html" enctype="multipart/form-data">
+% foreach my $var qw(Query Format OrderBy Order Rows Page) {
+<input type="hidden" class="hidden" name="<%$var%>" value="<%$ARGS{$var}%>" />
+%}
+<& /Elements/TicketList, Query => $Query,
+ DisplayFormat => $Format,
+ Format => $ARGS{'Format'},
+ Verbatim => 1,
+ AllowSorting => 1,
+ OrderBy => $OrderBy,
+ Order => $Order,
+ Rows => $Rows,
+ Page => $Page,
+ BaseURL => $RT::WebPath."/Search/Bulk.html?"
+ &>
+
+<hr>
+
+<& /Elements/Submit, Label => loc('Update'), CheckAll => 1, ClearAll => 1 &>
+<br />
+<&|/Widgets/TitleBox, title => $title &>
+<table>
+<tr>
+<td valign="top">
+<table>
+<tr><td class="label"> <&|/l&>Make Owner</&>: </td>
+<td class="value"> <& /Elements/SelectOwner, Name => "Owner" &> (<input type="checkbox" class="checkbox" name="ForceOwnerChange" /> <&|/l&>Force change</&>) </td></tr>
+<tr><td class="label"> <&|/l&>Add Requestor</&>: </td>
+<td class="value"> <input name="AddRequestor" size="20" /> </td></tr>
+<tr><td class="label"> <&|/l&>Remove Requestor</&>: </td>
+<td class="value"> <input name="DeleteRequestor" size="20" /> </td></tr>
+<tr><td class="label"> <&|/l&>Add Cc</&>: </td>
+<td class="value"> <input name="AddCc" size="20" /> </td></tr>
+<tr><td class="label"> <&|/l&>Remove Cc</&>: </td>
+<td class="value"> <input name="DeleteCc" size="20" /> </td></tr>
+<tr><td class="label"> <&|/l&>Add AdminCc</&>: </td>
+<td class="value"> <input name="AddAdminCc" size="20" /> </td></tr>
+<tr><td class="label"> <&|/l&>Remove AdminCc</&>: </td>
+<td class="value"> <input name="DeleteAdminCc" size="20" /> </td></tr>
+</table>
+</td>
+<td valign="top">
+<table>
+<tr><td class="label"> <&|/l&>Make subject</&>: </td>
+<td class="value"> <input name="Subject" size="20" /> </td></tr>
+<tr><td class="label"> <&|/l&>Make priority</&>: </td>
+<td class="value"> <input name="Priority" size="4" /> </td></tr>
+<tr><td class="label"> <&|/l&>Make queue</&>: </td>
+<td class="value"> <& /Elements/SelectQueue, Name => "Queue" &> </td></tr>
+<tr><td class="label"> <&|/l&>Make Status</&>: </td>
+<td class="value"> <& /Elements/SelectStatus, Name => "Status" &> </td></tr>
+<tr><td class="label"> <&|/l&>Make date Starts</&>: </td>
+<td class="value"> <& /Elements/SelectDate, Name => "Starts_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class="label"> <&|/l&>Make date Started</&>: </td>
+<td class="value"> <& /Elements/SelectDate, Name => "Started_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class="label"> <&|/l&>Make date Told</&>: </td>
+<td class="value"> <& /Elements/SelectDate, Name => "Told_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class="label"> <&|/l&>Make date Due</&>: </td>
+<td class="value"> <& /Elements/SelectDate, Name => "Due_Date", ShowTime => 0, Default => '' &> </td></tr>
+<tr><td class="label"> <&|/l&>Make date Resolved</&>: </td>
+<td class="value"> <& /Elements/SelectDate, Name => "Resolved_Date", ShowTime => 0, Default => '' &> </td></tr>
+</table>
+
+</td>
+</tr>
+</table>
+</&>
+<&| /Widgets/TitleBox, title => loc('Add comments or replies to selected tickets') &>
+<table>
+<tr><td align="right"><&|/l&>Update Type</&>:</td>
+<td><select name="UpdateType">
+ <option value="private" ><&|/l&>Comments (not sent to requestors)</&></option>
+<option value="response" ><&|/l&>Reply to requestors</&></option>
+</select>
+</td></tr>
+<tr><td align="right"><&|/l&>Subject</&>:</td><td> <input name="UpdateSubject" size="60" value="" /></td></tr>
+% while (my $CF = $TxnCFs->Next()) {
+<tr>
+<td align="right"><% $CF->Name %>:</td>
+<td><& /Elements/EditCustomField,
+ CustomField => $CF,
+ NamePrefix => "Object-RT::Transaction--CustomField-"
+ &><em><% $CF->FriendlyType %></em></td>
+</td></tr>
+% } # end if while
+ <tr><td align="right"><&|/l&>Attach</&>:</td><td><input name="UpdateAttachment" type="file" /></td></tr>
+ <tr><td class="labeltop"><&|/l&>Message</&>:</td><td>
+ <& /Elements/MessageBox, Name=>"UpdateContent"&>
+ </td></tr>
+ </table>
+
+</&>
+<&|/Widgets/TitleBox, title => loc('Edit Custom Fields'), color => "#336633"&>
+<%perl>
+my $cfs = RT::CustomFields->new($session{'CurrentUser'});
+$cfs->LimitToGlobal();
+$cfs->LimitToQueue($_) for keys %$seen_queues;
+</%perl>
+<table>
+<tr>
+<th><&|/l&>Name</&></th>
+<th><&|/l&>Add values</&></th>
+<th><&|/l&>Delete values</&></th>
+</tr>
+% while (my $cf = $cfs->Next()) {
+<tr>
+<td class="label"><%$cf->Name%><br />
+<em>(<%$cf->FriendlyType%>)</em></td>
+% my $rows = 5;
+% my @add = (NamePrefix => 'Bulk-Add-CustomField-', CustomField => $cf, Rows => $rows, Multiple => ($cf->MaxValues ==1 ? 0 : 1) , Cols => 25);
+% my @del = (NamePrefix => 'Bulk-Delete-CustomField-', CustomField => $cf, Rows => $rows, Multiple => 1, Cols => 25);
+% if ($cf->Type eq 'Select') {
+<td><& /Elements/EditCustomFieldSelect, @add &></td>
+<td><& /Elements/EditCustomFieldSelect, @del &></td>
+% } elsif ($cf->Type eq 'Combobox') {
+<td><& /Elements/EditCustomFieldCombobox, @add &></td>
+<td><& /Elements/EditCustomFieldCombobox, @del &></td>
+% } elsif ($cf->Type eq 'Freeform') {
+<td><& /Elements/EditCustomFieldFreeform, @add &></td>
+<td><& /Elements/EditCustomFieldFreeform, @del &></td>
+% } elsif ($cf->Type eq 'Text') {
+<td><& /Elements/EditCustomFieldText, @add &></td>
+<td>&nbsp;</td>
+% } else {
+% $RT::Logger->crit("Unknown CustomField type: " . $cf->Type);
+% }
+</tr>
+% }
+</table>
+</&>
+
+<&|/Widgets/TitleBox, title => loc('Edit Links'), color => "#336633"&>
+<em><&|/l&>Enter tickets or URIs to link tickets to. Separate multiple entries with spaces.</&></em><br />
+<& /Ticket/Elements/BulkLinks &>
+</&>
+
+<& /Elements/Submit, Label => loc('Update') &>
+
+
+</form>
+
+
+<%INIT>
+my $title = loc("Update multiple tickets");
+
+# Iterate through the ARGS hash and remove anything with a null value.
+map ( $ARGS{$_} =~ /^$/ && ( delete $ARGS{$_} ), keys %ARGS );
+
+my (@results);
+
+$Page ||= 1;
+
+$Format ||= $RT::DefaultSearchResultFormat;
+
+# inject _CHECKBOX to the first field.
+$Format =~ s/'?([^']+)'?,/'___CHECKBOX__$1',/;
+
+my $Tickets = RT::Tickets->new( $session{'CurrentUser'} );
+$Tickets->FromSQL($Query);
+if ( $OrderBy =~ /\|/ ) {
+
+ # Multiple Sorts
+ my @OrderBy = split /\|/, $OrderBy;
+ my @Order = split /\|/, $Order;
+ $Tickets->OrderByCols(
+ map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } }
+ ( 0 .. $#OrderBy ) );
+}
+else {
+ $Tickets->OrderBy( FIELD => $OrderBy, ORDER => $Order );
+}
+
+$Tickets->RowsPerPage($Rows) if ($Rows);
+$Tickets->GotoPage( $Page - 1 ); # SB uses page 0 as the first page
+
+Abort( loc("No search to operate on.") ) unless ($Tickets);
+
+# build up a list of all custom fields for tickets that we're displaying, so
+# we can display sane edit widgets.
+
+my $fields = {};
+my $seen_queues = {};
+while ( my $ticket = $Tickets->Next ) {
+ next if $seen_queues->{ $ticket->Queue }++;
+
+ my $custom_fields = $ticket->QueueObj->TicketCustomFields;
+ while ( my $field = $custom_fields->Next ) {
+ $fields->{ $field->id } = $field;
+ }
+}
+
+my $do_comment_reply = 0;
+
+# Prepare for ticket updates
+if ($ARGS{'UpdateContent'}) {
+ $ARGS{'UpdateContent'} =~ s/\r\n/\n/g;
+ chomp( $ARGS{'UpdateContent'} );
+
+ if ($ARGS{'UpdateContent'} ne ''
+ && $ARGS{'UpdateContent'} ne "-- \n"
+ . $session{'CurrentUser'}->UserObj->Signature ) {
+ $do_comment_reply = 1;
+ }
+}
+
+#Iterate through each ticket we've been handed
+my @linkresults;
+my %queues;
+
+$Tickets->RedoSearch();
+
+# pull out the labels for any custom fields we want to update
+
+my $cf_del_keys;
+@$cf_del_keys = grep { /^Bulk-Delete-CustomField/ } keys %ARGS;
+my $cf_add_keys;
+@$cf_add_keys = grep { /^Bulk-Add-CustomField/ } keys %ARGS;
+
+
+while ( my $Ticket = $Tickets->Next ) {
+ next unless ( $ARGS{ "UpdateTicket" . $Ticket->Id } );
+
+ #Update the links
+ $ARGS{'id'} = $Ticket->id;
+ $queues{ $Ticket->QueueObj->Id }++;
+
+ my @updateresults;
+ if ($do_comment_reply) {
+ ProcessUpdateMessage(
+ TicketObj => $Ticket,
+ ARGSRef => \%ARGS,
+ Actions => \@updateresults
+ );
+ }
+
+ #Update the basics.
+ my @basicresults =
+ ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS );
+ my @dateresults =
+ ProcessTicketDates( TicketObj => $Ticket, ARGSRef => \%ARGS );
+
+ #Update the watchers
+ my @watchresults =
+ ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS );
+
+ foreach my $type qw(MergeInto DependsOn MemberOf RefersTo) {
+ $ARGS{ $Ticket->id . "-" . $type } = $ARGS{"Ticket-$type"};
+ $ARGS{ $type . "-" . $Ticket->id } = $ARGS{"$type-Ticket"};
+ }
+ @linkresults =
+ ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS );
+ foreach my $type qw(MergeInto DependsOn MemberOf RefersTo) {
+ delete $ARGS{ $type . "-" . $Ticket->id };
+ delete $ARGS{ $Ticket->id . "-" . $type };
+ }
+
+ my @cfresults;
+
+ foreach my $list ( $cf_add_keys, $cf_del_keys ) {
+ next unless $list->[0];
+
+
+ my $op;
+ if ( $list->[0] =~ /Add/ ) {
+ $op = 'add';
+
+ }
+ elsif ( $list->[0] =~ /Del/ ) {
+ $op = 'del';
+ }
+ else {
+ $RT::Logger->crit(
+ "Got an op that was neither add nor delete. can never happen"
+ . $list->[0] );
+ last;
+ }
+
+ foreach my $key (@$list) {
+ my ( $cfid, $cf );
+ if ( $key =~ /CustomField-(\d+)-/ ) {
+ $cfid = $1;
+ $cf = RT::CustomField->new( $session{'CurrentUser'} );
+ $cf->Load($cfid);
+ }
+ else {next}
+ my @values =
+ ref( $ARGS{$key} ) eq 'ARRAY'
+ ? @{ $ARGS{$key} }
+ : ( $ARGS{$key} );
+ map { s/(\r\n|\r)/\n/g; } @values; # fix the newlines
+ # now break the multiline values into multivalues
+ @values = map { split( /\n/, $_ ) } @values
+ unless ( $cf->SingleValue );
+
+ my $current_values = $Ticket->CustomFieldValues($cfid);
+ foreach my $value (@values) {
+ if ( $op eq 'del' && $current_values->HasEntry($value) ) {
+ my ( $id, $msg ) = $Ticket->DeleteCustomFieldValue(
+ Field => $cfid,
+ Value => $value
+ );
+ push @cfresults, $msg;
+ }
+
+ elsif ( $op eq 'add' && !$current_values->HasEntry($value) ) {
+ my ( $id, $msg ) = $Ticket->AddCustomFieldValue(
+ Field => $cfid,
+ Value => $value
+ );
+ push @cfresults, $msg;
+ }
+ }
+ }
+ }
+ my @tempresults = (
+ @watchresults, @basicresults, @dateresults,
+ @updateresults, @linkresults, @cfresults
+ );
+
+ @tempresults =
+ map { loc( "Ticket [_1]: [_2]", $Ticket->Id, $_ ) } @tempresults;
+
+ @results = ( @results, @tempresults );
+}
+
+my $TxnCFs = RT::CustomFields->new( $session{CurrentUser} );
+$TxnCFs->LimitToLookupType( RT::Transaction->CustomFieldLookupType );
+$TxnCFs->LimitToGlobalOrObjectId( sort keys %queues );
+
+</%INIT>
+<%args>
+$Format => undef
+$Page => 1
+$Rows => undef
+$Order => 'ASC'
+$OrderBy => 'id'
+$Query => undef
+</%args>
diff --git a/rt/html/Search/Chart b/rt/html/Search/Chart
new file mode 100644
index 000000000..82704fdc7
--- /dev/null
+++ b/rt/html/Search/Chart
@@ -0,0 +1,188 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Query => "id > 0"
+$PrimaryGroupBy => 'Queue'
+$SecondaryGroupBy => undef
+$ChartStyle => 'bars'
+</%args>
+<%init>
+my @keys;
+my @values;
+my $chart_class;
+use GD;
+use GD::Text;
+
+if ($ChartStyle eq 'pie') {
+ require GD::Graph::pie;
+ $chart_class = "GD::Graph::pie";
+} else {
+ require GD::Graph::bars;
+ $chart_class = "GD::Graph::bars";
+}
+
+use RT::Report::Tickets;
+my $tix = RT::Report::Tickets->new( $session{'CurrentUser'} );
+$tix->FromSQL( $Query );
+my $count_name = $tix->Column( FUNCTION => 'COUNT', FIELD => 'id' );
+$tix->GroupBy( FIELD => $PrimaryGroupBy );
+my $value_name = $tix->Column( FIELD => $PrimaryGroupBy );
+
+my $chart = $chart_class->new( 600 => 400 );
+
+my $font = $RT::ChartFont || ['verdana', 'arial', gdMediumBoldFont];
+$chart->set_title_font( $font, 12 ) if $chart->can('set_title_font');
+$chart->set_legend_font( $font, 12 ) if $chart->can('set_legend_font');
+$chart->set_x_label_font( $font, 10 ) if $chart->can('set_x_label_font');
+$chart->set_y_label_font( $font, 10 ) if $chart->can('set_y_label_font');
+$chart->set_label_font( $font, 10 ) if $chart->can('set_label_font');
+$chart->set_x_axis_font( $font, 9 ) if $chart->can('set_x_axis_font');
+$chart->set_y_axis_font( $font, 9 ) if $chart->can('set_y_axis_font');
+$chart->set_values_font( $font, 9 ) if $chart->can('set_values_font');
+$chart->set_value_font( $font, 9 ) if $chart->can('set_value_font');
+
+# Pie charts don't like having no input, so we show a special image
+# that indicates an error message. Because this is used in an <img>
+# context, it can't be a simple error message. Without this check,
+# the chart will just be a non-loading image.
+if ($tix->Count == 0) {
+ my $plot = GD::Image->new(600 => 400);
+ $plot->colorAllocate(255, 255, 255); # background
+ my $black = $plot->colorAllocate(0, 0, 0);
+
+ require GD::Text::Wrap;
+ my $error = GD::Text::Wrap->new($plot,
+ color => $black,
+ text => loc("No tickets found."),
+ );
+ $error->set_font( $font, 12 );
+ $error->draw(0, 0);
+
+ $m->comp( 'SELF:Plot', plot => $plot, %ARGS );
+}
+
+if ($chart_class eq "GD::Graph::bars") {
+ $chart->set(
+ x_label => $tix->Label( $PrimaryGroupBy ),
+ x_labels_vertical => 1,
+ y_label => loc('Tickets'),
+ show_values => 1
+ );
+}
+
+my %class = (
+ Queue => 'RT::Queue',
+ Owner => 'RT::User',
+);
+my $class = $class{ $PrimaryGroupBy };
+
+while ( my $entry = $tix->Next ) {
+ if ( $class ) {
+ my $q = $class->new( $session{'CurrentUser'} );
+ $q->Load( $entry->__Value( $value_name ) );
+ push @keys, $q->Name;
+ }
+ else {
+ push @keys, $entry->__Value($value_name);
+ }
+
+ $keys[-1] ||= loc('(no value)');
+ if ($chart_class eq 'GD::Graph::pie') {
+ $keys[-1] .= " - ". $entry->__Value( $count_name );
+ }
+ push @values, $entry->__Value($count_name);
+}
+
+# XXX: Convert 1970-01-01 date to the 'Not Set'
+# this code should be generalized!!!
+if ( $PrimaryGroupBy =~ /(Daily|Monthly|Annually)$/ ) {
+ my $re;
+ $re = qr{1970-01-01} if $PrimaryGroupBy =~ /Daily$/;
+ $re = qr{1970-01} if $PrimaryGroupBy =~ /Monthly$/;
+ $re = qr{1970} if $PrimaryGroupBy =~ /Annually$/;
+ foreach (@keys) {
+ s/^$re/loc('Not Set')/e;
+ }
+}
+
+unless (@keys && @values) {
+ @keys = ('');
+ @values = (0);
+}
+
+my %data;
+foreach my $key (@keys) { $data{$key} = shift @values; }
+my @sorted_keys = sort @keys;
+my @sorted_values = map { $data{$_}} @sorted_keys;
+
+
+
+my $plot = $chart->plot( [ [@sorted_keys], [@sorted_values] ] ) or die $chart->error;
+$m->comp( 'SELF:Plot', plot => $plot, %ARGS );
+</%init>
+
+<%METHOD Plot>
+<%ARGS>
+$plot => undef
+</%ARGS>
+<%INIT>
+my @types = ('png', 'gif');
+
+for my $type (@types) {
+ $plot->can($type)
+ or next;
+
+ $r->content_type("image/$type");
+ $m->out( $plot->$type );
+ $m->abort();
+}
+
+die "Your GD library appears to support none of the following image types: " . join(', ', @types);
+</%INIT>
+
+</%METHOD>
diff --git a/rt/html/Search/Chart.html b/rt/html/Search/Chart.html
new file mode 100644
index 000000000..a07d89502
--- /dev/null
+++ b/rt/html/Search/Chart.html
@@ -0,0 +1,73 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Query => "id > 0"
+$PrimaryGroupBy => 'Queue'
+$SecondaryGroupBy => ''
+$ChartStyle => 'bars'
+$Description => undef
+</%args>
+<%init>
+$ARGS{SecondaryGroupBy} ||= '';
+
+my $title = loc( "Search results grouped by [_1]", $PrimaryGroupBy );
+
+my $saved_search = $m->comp( '/Widgets/SavedSearch:new',
+ SearchType => 'Chart',
+ SearchFields => [qw(Query PrimaryGroupBy SecondaryGroupBy ChartStyle)] );
+
+my @actions = $m->comp( '/Widgets/SavedSearch:process', args => \%ARGS, self => $saved_search );
+
+</%init>
+<& /Elements/Header, Title => $title &>
+<& /Ticket/Elements/Tabs, Title => $title &>
+<& /Elements/ListActions, actions => \@actions &>
+<& /Search/Elements/Chart, %ARGS &>
+
+
+<& /Widgets/SavedSearch:show, %ARGS, Action => 'Chart.html', self => $saved_search, Title => 'Saved charts' &>
diff --git a/rt/html/Search/Edit.html b/rt/html/Search/Edit.html
new file mode 100755
index 000000000..21df0db97
--- /dev/null
+++ b/rt/html/Search/Edit.html
@@ -0,0 +1,88 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title&>
+<& /Ticket/Elements/Tabs,
+ current_tab => "Search/Edit.html?".$QueryString,
+ Title => $title,
+ Format => $Format,
+ Query => $Query,
+ Rows => $ARGS{'Rows'},
+ OrderBy => $ARGS{'OrderBy'},
+ Order => $ARGS{'Order'} &>
+
+<& Elements/NewListActions, actions => \@actions &>
+
+<form method="post" action="Build.html">
+<input type="hidden" class="hidden" name="SearchId" value="<%$SearchId%>" />
+<textarea name="Query" rows="8" cols="72"><%$Query%></textarea>
+<br />
+<textarea name="Format" rows="8" cols="72"><%$Format%></textarea>
+<br />
+<& /Elements/Submit, Label => loc("Apply"), Reset => 1, Caption => loc("Apply your changes")&>
+</form>
+
+<%INIT>
+my $title = loc("Edit Query");
+$Format = $m->comp('/Elements/ScrubHTML', Content => $Format);
+my $QueryString = $m->comp('/Elements/QueryString',
+ Query => $Query,
+ Format => $Format,
+ Rows => $ARGS{'Rows'},
+ OrderBy => $ARGS{'OrderBy'},
+ Order => $ARGS{'Order'},
+ );
+
+</%INIT>
+
+
+<%ARGS>
+$Query => undef
+$Format => undef
+$SearchId => 'new'
+@actions => undef
+</%ARGS>
diff --git a/rt/html/Search/Elements/BuildFormatString b/rt/html/Search/Elements/BuildFormatString
new file mode 100644
index 000000000..3bd39b5c2
--- /dev/null
+++ b/rt/html/Search/Elements/BuildFormatString
@@ -0,0 +1,244 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Format => undef
+%cfqueues => undef
+$Face => undef
+$Size => undef
+$Link => undef
+$Title => undef
+$AddCol => undef
+$RemoveCol => undef
+$ColUp => undef
+$ColDown => undef
+$SelectDisplayColumns => undef
+$CurrentDisplayColumns => undef
+</%args>
+<%init>
+
+unless ($Format) {
+ $Format = $RT::DefaultSearchResultFormat;
+}
+
+
+# All the things we can display in the format string by default
+my @fields = qw(
+ id
+ Status
+ ExtendedStatus
+ Subject
+ QueueName
+ OwnerName
+ Priority
+ InitialPriority
+ FinalPriority
+ Type
+ TimeWorked
+ TimeLeft
+ TimeEstimated
+ CreatedBy
+ LastUpdatedBy
+ Requestors
+ Cc
+ AdminCc
+ Starts
+ StartsRelative
+ Started
+ StartedRelative
+ Created
+ CreatedRelative
+ LastUpdated
+ LastUpdatedRelative
+ Told
+ ToldRelative
+ Due
+ DueRelative
+ Resolved
+ ResolvedRelative
+ RefersTo
+ ReferredToBy
+ DependsOn
+ DependedOnBy
+ MemberOf
+ Members
+ Parents
+ Children
+ NEWLINE
+);
+
+my $CustomFields = RT::CustomFields->new( $session{'CurrentUser'});
+foreach my $id (keys %cfqueues) {
+ # What does this _do_? What are the keys to cfqueues
+ $id =~ s/^.'*(.*).'*$/$1/;
+ # Gotta load up the $queue object, since queues get stored by name now.
+ my $queue = RT::Queue->new($session{'CurrentUser'});
+ $queue->Load($id);
+ $CustomFields->LimitToQueue($queue->Id);
+}
+$CustomFields->LimitToGlobal;
+
+while ( my $CustomField = $CustomFields->Next ) {
+ push @fields, "CustomField.{" . $CustomField->Name . "}";
+}
+
+my ( @seen);
+
+my @format = split( /,\s*/, $Format );
+foreach my $field (@format) {
+ my %column = ();
+ $field =~ s/'(.*)'/$1/;
+ my ( $prefix, $suffix );
+ if ( $field =~ m/(.*)__(.*)__(.*)/ ) {
+ $prefix = $1;
+ $suffix = $3;
+ $field = $2;
+ }
+ $field = "<blank>" if !$field;
+ $column{Prefix} = $prefix;
+ $column{Suffix} = $suffix;
+ $field =~ s/\s*(.*)\s*/$1/;
+ $column{Column} = $field;
+ push @seen, \%column;
+}
+
+if ( $RemoveCol ) {
+ my $index = $CurrentDisplayColumns;
+ my $column = $seen[$index];
+ if ($index) {
+ delete $seen[$index];
+ my @temp = @seen;
+ @seen = ();
+ foreach my $element (@temp) {
+ next unless $element;
+ push @seen, $element;
+ }
+ }
+}
+elsif ( $AddCol ) {
+ if ( defined $SelectDisplayColumns ) {
+ my $selected = $SelectDisplayColumns;
+ my @columns;
+ if (ref($selected) eq 'ARRAY') {
+ @columns = @$selected;
+ } else {
+ push @columns, $selected;
+ }
+ foreach my $col (@columns) {
+ my %column = ();
+ $column{Column} = $col;
+
+ if ( $Face eq "Bold" ) {
+ $column{Prefix} .= "<b>";
+ $column{Suffix} .= "</b>";
+ }
+ if ( $Face eq "Italic" ) {
+ $column{Prefix} .= "<i>";
+ $column{Suffix} .= "</i>";
+ }
+ if ($Size) {
+ $column{Prefix} .= "<" . $m->interp->apply_escapes( $Size, 'h' ) . ">";
+ $column{Suffix} .= "</" . $m->interp->apply_escapes( $Size, 'h' ) . ">";
+ }
+ if ( $Link eq "Display" ) {
+ $column{Prefix} .=
+ "<a HREF=\"" . $RT::WebPath . "/Ticket/Display.html?id=__id__\">";
+ $column{Suffix} .= "</a>";
+ }
+ elsif ( $Link eq "Take" ) {
+ $column{Prefix} .= "<a HREF=\"" . $RT::WebPath
+ . "/Ticket/Display.html?Action=Take&id=__id__\">";
+ $column{Suffix} .= "</a>";
+ }
+
+ if ($Title) {
+ $column{Suffix} .= "/TITLE:" . $m->interp->apply_escapes( $Title, 'h' );
+ }
+ push @seen, \%column;
+}
+}
+}
+elsif ( $ColUp ) {
+ my $index = $CurrentDisplayColumns;
+ if ( defined $index && ( $index - 1 ) >= 0 ) {
+ my $column = $seen[$index];
+ $seen[$index] = $seen[ $index - 1 ];
+ $seen[ $index - 1 ] = $column;
+ $CurrentDisplayColumns = $index - 1;
+ }
+}
+elsif ( $ColDown ) {
+ my $index = $CurrentDisplayColumns;
+ if ( defined $index && ( $index + 1 ) < scalar @seen ) {
+ my $column = $seen[$index];
+ $seen[$index] = $seen[ $index + 1 ];
+ $seen[ $index + 1 ] = $column;
+ $CurrentDisplayColumns = $index + 1;
+ }
+}
+
+
+my @format_string;
+foreach my $field (@seen) {
+ next unless $field;
+ my $row = "'";
+ $row .= $field->{Prefix} if $field->{Prefix};
+ $row .= "__" . ($field->{Column} =~ m/\(/ ? $field->{Column} # func, don't escape
+ : $m->interp->apply_escapes( $field->{Column}, 'h' )) . "__"
+ unless ( $field->{Column} eq "<blank>" );
+ $row .= $field->{Suffix} if $field->{Suffix};
+ $row .= "'";
+ push( @format_string, $row );
+}
+
+$Format = join(",\n", @format_string);
+
+
+return($Format, \@fields, \@seen);
+
+</%init>
+
diff --git a/rt/html/Search/Elements/Chart b/rt/html/Search/Elements/Chart
new file mode 100644
index 000000000..2eca6afda
--- /dev/null
+++ b/rt/html/Search/Elements/Chart
@@ -0,0 +1,139 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Query => "id > 0"
+$PrimaryGroupBy => 'Queue'
+$SecondaryGroupBy => undef
+$ChartStyle => 'bars'
+</%args>
+<%init>
+use RT::Report::Tickets;
+my $tix = RT::Report::Tickets->new( $session{'CurrentUser'} );
+$tix->FromSQL( $Query );
+my $count_name = $tix->Column( FUNCTION => 'COUNT', FIELD => 'id' );
+$tix->GroupBy( FIELD => $PrimaryGroupBy );
+my $value_name = $tix->Column( FIELD => $PrimaryGroupBy );
+
+my %class = (
+ Queue => 'RT::Queue',
+ Owner => 'RT::User',
+);
+my $class = $class{ $PrimaryGroupBy };
+
+my (@keys, @values);
+while ( my $entry = $tix->Next ) {
+ if ($class) {
+ my $q = $class->new( $session{'CurrentUser'} );
+ $q->Load( $entry->__Value( $value_name ) );
+ push @keys, $q->Name;
+ }
+ else {
+ push @keys, $entry->__Value( $value_name );
+ }
+ $keys[-1] ||= loc('(no value)');
+ push @values, $entry->__Value( $count_name );
+}
+
+# XXX: Convert 1970-01-01 date to the 'Not Set'
+# this code should be generalized!!!
+if ( $PrimaryGroupBy =~ /(Daily|Monthly|Annually)$/ ) {
+ my $re;
+ $re = qr{1970-01-01} if $PrimaryGroupBy =~ /Daily$/;
+ $re = qr{1970-01} if $PrimaryGroupBy =~ /Monthly$/;
+ $re = qr{1970} if $PrimaryGroupBy =~ /Annually$/;
+ foreach (@keys) {
+ s/^$re/loc('Not Set')/e;
+ }
+}
+
+my %data;
+foreach my $key (@keys) { $data{$key} = shift @values; }
+my @sorted_keys = sort @keys;
+my @sorted_values = map { $data{$_}} @sorted_keys;
+
+
+my $query_string = $m->comp('/Elements/QueryString', %ARGS);
+</%init>
+
+<% loc('Query:') %>&nbsp;<% $Query %><br />
+
+<img src="<%$RT::WebPath%>/Search/Chart?<%$query_string|n%>" /><br />
+
+<table class="collection-as-table">
+<tr>
+<th class="collection-as-table"><% $tix->Label($PrimaryGroupBy) %>
+</th>
+<th class="collection-as-table"><&|/l&>Tickets</&>
+</th>
+</tr>
+% my ($i,$total);
+% while (my $key = shift @sorted_keys) {
+% $i++;
+% my $value = shift @sorted_values;
+% $total += $value;
+<tr class="<%$i%2 ? 'evenline' : 'oddline' %>">
+<td class="label collection-as-table">
+<%$key%>
+</td>
+<td class="value collection-as-table">
+<%$value%>
+</td>
+</tr>
+% }
+
+%$i++;
+<tr class="<%$i%2 ? 'evenline' : 'oddline' %>">
+<td class="label collection-as-table">
+<%loc('Total')%>
+</td>
+<td class="value collection-as-table">
+<%$total%>
+</td>
+</tr>
+
+</table>
diff --git a/rt/html/Search/Elements/DisplayOptions b/rt/html/Search/Elements/DisplayOptions
new file mode 100644
index 000000000..cc57f96dc
--- /dev/null
+++ b/rt/html/Search/Elements/DisplayOptions
@@ -0,0 +1,143 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<&| /Widgets/TitleBox, title => loc("Display Columns") &>
+<table width="100%">
+<tr>
+<td>
+<& EditFormat, %ARGS &>
+</td>
+<td valign="top">
+<table valign="top">
+
+% for my $o (0..3) {
+<tr>
+<td class="label">
+% if ($o == 0) {
+<&|/l&>Order by</&>:
+% }
+</td>
+<td class="value">
+<select name="OrderBy">
+% if ($o > 0) {
+<option value=""><&|/l&>~[none~]</&></option>
+% }
+% foreach my $field (sort keys %fields) {
+% next unless $field;
+<option value="<%$field%>"
+% if (defined $OrderBy[$o] and $field eq $OrderBy[$o]) {
+selected
+% }
+><&|/l&><%$field%></&></option>
+% }
+</select>
+<select name="Order">
+<option value="ASC"
+% unless ( ($Order[$o]||'') eq "DESC" ) {
+selected
+% }
+><&|/l&>Asc</&></option>
+<option value="DESC"
+% if ( ($Order[$o]||'') eq "DESC" ) {
+selected
+% }
+><&|/l&>Desc</&></option>
+</select>
+</td>
+</tr>
+% }
+<tr>
+<td class="label">
+<&|/l&>Rows per page</&>:
+</td><td class="value">
+<& /Elements/SelectResultsPerPage,
+ Name => "RowsPerPage",
+ Default => $RowsPerPage &>
+</td>
+</tr>
+</table>
+</td>
+</tr>
+</table>
+</&>
+
+<%INIT>
+my $tickets = new RT::Tickets($session{'CurrentUser'});
+my %fields = %{$tickets->FIELDS};
+map { $fields{$_}->[0] =~ /^(?:ENUM|INT|DATE|STRING)$/ || delete $fields{$_} } keys %fields;
+delete $fields{'EffectiveId'};
+$fields{ $_ . '.EmailAddress' } = 1 foreach( qw(Requestor Cc AdminCc) );
+
+# Add all available CustomFields to the list of sortable columns.
+my @cfs = grep /^CustomField/, @{$ARGS{AvailableColumns}};
+$fields{$_}=1 for @cfs;
+
+# Add PAW sort
+$fields{'Custom.Ownership'} = 1;
+
+my @Order;
+my @OrderBy;
+if ($OrderBy =~ /\|/) {
+ @OrderBy = split /\|/, $OrderBy;
+} else {
+ @OrderBy = ( $OrderBy );
+}
+if ($Order =~ /\|/) {
+ @Order = split /\|/, $Order;
+} else {
+ @Order = ( $Order );
+}
+
+</%INIT>
+
+<%ARGS>
+$Order => undef
+$OrderBy => undef
+$RowsPerPage => undef
+$Format => undef
+$GroupBy => 'id'
+</%ARGS>
diff --git a/rt/html/Search/Elements/EditFormat b/rt/html/Search/Elements/EditFormat
new file mode 100644
index 000000000..fa0ac96e0
--- /dev/null
+++ b/rt/html/Search/Elements/EditFormat
@@ -0,0 +1,116 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table>
+<tr>
+<td>
+<&|/l&>Add Columns</&>:
+</td>
+<td>
+<&|/l&>Format</&>:
+</td>
+<td></td>
+<td>
+<&|/l&>Show Columns</&>:
+</td>
+<tr>
+<td valign="top">
+<select size="6" name="SelectDisplayColumns" multiple>
+% foreach my $field ( @$AvailableColumns) {
+<option value="<%$field%>"><% loc( $field) %></option>
+%# $m->comp( '/Elements/RT__Ticket/ColumnMap', Name => $field, Attr => 'title') ||
+% }
+</select>
+</td>
+<td>
+<&|/l&>Link</&>:
+<select name="Link">
+<option value="None">-</option>
+<option value="Display"><&|/l&>Display</&></option>
+<option value="Take"><&|/l&>Take</&></option>
+</select>
+<br /><&|/l&>Title</&>: <input name="Title" size="10" />
+<br /><&|/l&>Size</&>:
+<select name="Size">
+<option value="">-</option>
+<option value="Small"><&|/l&>Small</&></option>
+<option value="Large"><&|/l&>Large</&></option>
+</select>
+<br /><&|/l&>Style</&>:
+<select name="Face">
+<option value="">-</option>
+<option value="Bold"><&|/l&>Bold</&></option>
+<option value="Italic"><&|/l&>Italic</&></option>
+</select>
+</td>
+<td>
+<input type="submit" class="button" name="AddCol" value=" &rarr; " />
+</td>
+<td valign="top">
+<select size="4" name="CurrentDisplayColumns">
+% my $i=0;
+% foreach my $field (@$CurrentFormat) {
+<option value="<%$i++%>><%$field->{Column}%>">
+<%loc( $field->{Column}) %></option>
+% }
+</select>
+<br />
+<center>
+<input type="submit" class="button" name="ColUp" value=" &uarr; " />
+<input type="submit" class="button" name="ColDown" value=" &darr; " />
+<input type="submit" class="button" name="RemoveCol" value="<%loc('Delete')%>" />
+</center>
+</td>
+<td colspan="3" align="center">
+</td>
+</tr>
+</table>
+
+<%ARGS>
+$CurrentFormat => undef
+$AvailableColumns => undef
+</%ARGS>
diff --git a/rt/html/Search/Elements/EditQuery b/rt/html/Search/Elements/EditQuery
new file mode 100644
index 000000000..5c40c2573
--- /dev/null
+++ b/rt/html/Search/Elements/EditQuery
@@ -0,0 +1,67 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& NewListActions, actions => $actions &>
+<&|/Widgets/TitleBox, title => join(': ', grep defined, loc("Current search"), $Description) &>
+<select size="10" name="clauses" style="width: 100%" multiple>
+% $m->out($optionlist);
+</select>
+<p align="center">
+<input type="submit" class="button" name="Up" value=" &uarr; " />
+<input type="submit" class="button" name="Down" value=" &darr; " />
+<input type="submit" class="button" name="Left" value=" &larr; " />
+<input type="submit" class="button" name="Right" value=" &rarr; " />
+<input type="submit" class="button" name="Toggle" value="<&|/l&>And/Or</&>" />
+<input type="submit" class="button" name="DeleteClause" value="<&|/l&>Delete</&>" />
+%#<input type="submit" class="button" name="EditQuery" value="Advanced" />
+</p>
+</&>
+<%ARGS>
+$Description
+$optionlist
+$actions
+</%ARGS>
diff --git a/rt/html/Search/Elements/EditSearches b/rt/html/Search/Elements/EditSearches
new file mode 100644
index 000000000..3978ea320
--- /dev/null
+++ b/rt/html/Search/Elements/EditSearches
@@ -0,0 +1,103 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<&| /Widgets/TitleBox, title => loc($Title)&>
+%# Hide all the save functionality if the user shouldn't see it.
+% if ($session{'CurrentUser'}->HasRight( Right => 'CreateSavedSearch',
+% Object=> $RT::System )) {
+<&|/l&>Privacy:</&>
+% if ($CurrentSearch->{'Object'} && $CurrentSearch->{'Object'}->id) {
+<& SearchPrivacy, Object => $CurrentSearch->{'Object'}->Object &><br />
+% } else {
+<& SelectSearchObject, Name => 'Owner', Objects => \@Objects &><br />
+% }
+<&|/l&>Description</&>:<br>
+<font size="-1"><input size="25" name="Description" value="<%$CurrentSearch->{'Description'} || ''%>" /></font>
+% if ($SearchId ne 'new') {
+<nobr>
+% if ($Dirty) {
+<input type="submit" class="button" name="Revert" value="<%loc('Revert')%>" />
+% }
+<input type="submit" class="button" name="Delete" value="<%loc('Delete')%>" />
+% if ($AllowCopy) {
+<input type="submit" class="button" name="CopySearch" value="<%loc('Copy')%>" />
+% }
+</nobr>
+
+% }
+<input type="submit" name="Save" value="<%loc('Save')%>" class="button" />
+<hr />
+% }
+<&|/l&>Load saved search:</&><br />
+<& SelectSearchesForObjects, Name => 'LoadSavedSearch', Objects => \@Objects, SearchType => $SearchType &>
+<input value="<%loc('Load')%>" type="submit" class="button" />
+</&>
+
+<%init>
+unless ($session{'CurrentUser'}->HasRight( Right => 'LoadSavedSearch',
+ Object=> $RT::System )) {
+ return;
+}
+
+use RT::SavedSearches;
+my @Objects = RT::SavedSearches->new($session{CurrentUser})->_PrivacyObjects;
+push @Objects, RT::System->new($session{'CurrentUser'})
+ if $session{'CurrentUser'}->HasRight( Object=> $RT::System,
+ Right => 'SuperUser');
+
+</%INIT>
+
+<%ARGS>
+$SearchType => 'Ticket'
+$SearchId => undef
+$CurrentSearch => undef
+$Description => undef
+$HideResults => 0
+$Dirty => 0
+$AllowCopy => 1
+$Title => 'Saved searches'
+</%ARGS>
diff --git a/rt/html/Search/Elements/NewListActions b/rt/html/Search/Elements/NewListActions
new file mode 100644
index 000000000..535ac8cb9
--- /dev/null
+++ b/rt/html/Search/Elements/NewListActions
@@ -0,0 +1,68 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% if ($actions[0] ) {
+<b><%loc('Results')%></b><br />
+% foreach my $action (@actions) {
+% next unless ($action);
+% my @item = @$action;
+% if ($item[1] < 0) {
+<font color="red">
+% }
+&nbsp;<%$item[0]%><br />
+% if ($item[1] < 0) {
+</font>
+% }
+% }
+<br />
+% }
+<%init>
+@actions = grep (/./,@actions);
+</%init>
+<%ARGS>
+@actions => undef
+</%ARGS>
diff --git a/rt/html/Search/Elements/PickBasics b/rt/html/Search/Elements/PickBasics
new file mode 100644
index 000000000..44a378c14
--- /dev/null
+++ b/rt/html/Search/Elements/PickBasics
@@ -0,0 +1,176 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<tr>
+<td class="label">
+<&|/l&>id</&>
+</td><td>
+<& /Elements/SelectEqualityOperator, Name => "idOp" &>
+</td><td>
+<input name="ValueOfid" size="5" />
+</td>
+</tr>
+
+<tr><td>
+<& /Elements/SelectAttachmentField, Name => 'AttachmentField' &>
+</td><td>
+<& /Elements/SelectBoolean, Name => "AttachmentOp",
+ True => loc("matches"),
+ False => loc("does not match"),
+ TrueVal => 'LIKE',
+ FalseVal => 'NOT LIKE'
+&>
+</td><td>
+<input name="ValueOfAttachment" size="20" />
+</td>
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Queue</&>
+</td><td>
+<& /Elements/SelectBoolean, Name => "QueueOp" ,
+ True => loc("is"),
+ False => loc("isn't"),
+ TrueVal=> '=',
+ FalseVal => '!=' &>
+</td><td>
+<& /Elements/SelectQueue,
+ Name => "ValueOfQueue",
+ NamedValues => 1,
+ CheckQueueRight => 'ShowTicket' &>
+</td>
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Status</&>
+</td><td>
+<& /Elements/SelectBoolean, Name => "StatusOp",
+ True => loc("is"),
+ False => loc("isn't"),
+ TrueVal=> '=',
+ FalseVal => '!='
+&>
+</td><td>
+<& /Elements/SelectStatus, Name => "ValueOfStatus", SkipDeleted => 1 &>
+</td>
+</tr>
+<tr><td class="label">
+<select name="ActorField">
+<option value="Owner"><&|/l&>Owner</&></option>
+<option value="Creator"><&|/l&>Creator</&></option>
+<option value="LastUpdatedBy"><&|/l&>LastUpdatedBy</&></option>
+</select>
+</td><td>
+<& /Elements/SelectBoolean, Name => "ActorOp",
+ TrueVal=> '=',
+ FalseVal => '!='
+&>
+</td><td>
+<& /Elements/SelectOwner, Name => "ValueOfActor", ValueAttribute => 'Name' &>
+</td>
+</tr>
+<tr>
+<td class="label">
+<& SelectPersonType, Name => 'WatcherField', Default => 'Requestor' &>
+</td><td>
+<& /Elements/SelectMatch, Name => "WatcherOp" &>
+</td><td>
+<input name="ValueOfWatcher" size="20" />
+</tr>
+<tr>
+<td class="label">
+<& /Elements/SelectDateType, Name=>"DateField" &>
+</td><td>
+<& /Elements/SelectDateRelation, Name=>"DateOp" &>
+</td><td>
+<& /Elements/SelectDate, Name => "ValueOfDate", ShowTime => 0, Default => '' &>
+</td></tr>
+<tr>
+<td class="label">
+<select name="TimeField">
+<option value="TimeWorked"><&|/l&>Time Worked</&></option>
+<option value="TimeEstimated"><&|/l&>Time Estimated</&></option>
+<option value="TimeLeft"><&|/l&>Time Left</&></option>
+</select>
+</td><td>
+<& /Elements/SelectEqualityOperator, Name => "TimeOp" &>
+</td><td>
+<input name="ValueOfTime" size="5" />
+<& /Elements/SelectTimeUnits, Name =>'ValueOfTime' &>
+</td>
+</tr>
+<tr>
+<td class="label">
+<select name="PriorityField">
+<option value="Priority"><&|/l&>Priority</&></option>
+<option value="InitialPriority"><&|/l&>Initial Priority</&></option>
+<option value="FinalPriority"><&|/l&>Final Priority</&></option>
+</select>
+</td><td>
+<& /Elements/SelectEqualityOperator, Name => "PriorityOp" &>
+</td><td>
+<input name="ValueOfPriority" size="5" />
+</td>
+</tr>
+<tr>
+<td class="label">
+<& SelectLinks, Name=>"LinksField" &>
+</td><td>
+<& /Elements/SelectBoolean, Name => "LinksOp",
+ True => loc("is"),
+ False => loc("isn't"),
+ TrueVal=> '=',
+ FalseVal => '!=' &>
+</td><td>
+<input name="ValueOfLinks" value="" size="5" />
+</td></tr>
+<%INIT>
+my @people = ('Actor',
+ 'Watcher',
+ 'WatcherGroup',
+ );
+</%INIT>
diff --git a/rt/html/Search/Elements/PickCFs b/rt/html/Search/Elements/PickCFs
new file mode 100644
index 000000000..734f5f871
--- /dev/null
+++ b/rt/html/Search/Elements/PickCFs
@@ -0,0 +1,80 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% while ( my $CustomField = $CustomFields->Next ) {
+% my $name = "'CF.{" . $CustomField->Name . "}'";
+<tr><td class="label">
+<% $CustomField->Name %>
+</td>
+<td>
+ <& /Elements/SelectCustomFieldOperator, Name => $name . "Op",
+ True => loc("is"),
+ False => loc("isn't"),
+ TrueVal=> '=', FalseVal => '!=' &>
+</td>
+<td>
+<& /Elements/SelectCustomFieldValue, Name => "ValueOf" . $name,
+ CustomField => $CustomField,
+ &>
+</td></tr>
+% }
+<%INIT>
+my $CustomFields = RT::CustomFields->new( $session{'CurrentUser'});
+foreach my $id (keys %cfqueues) {
+ $id =~ s/^.'*(.*).'*$/$1/;
+ # Gotta load up the $queue object, since queues get stored by name now. my $id
+ my $queue = RT::Queue->new($session{'CurrentUser'});
+ $queue->Load($id);
+ $CustomFields->LimitToQueue($queue->Id);
+}
+$CustomFields->LimitToGlobal();
+
+</%INIT>
+
+<%ARGS>
+%cfqueues => undef
+</%ARGS>
diff --git a/rt/html/Search/Elements/PickCriteria b/rt/html/Search/Elements/PickCriteria
new file mode 100644
index 000000000..58b29fb57
--- /dev/null
+++ b/rt/html/Search/Elements/PickCriteria
@@ -0,0 +1,82 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<&| /Widgets/TitleBox, title => loc('Add Criteria')&>
+<table width="100%" cellspacing="0" cellpadding="0" border="0">
+ <tr>
+ <td>
+ <table cellspacing="0" border="0">
+ <tr><td class="label">
+ <&|/l&>Aggregator</&>:
+ </td>
+ <td><& SelectAndOr, Name => "AndOr" &>
+ </td></tr>
+ </table>
+ </td></tr>
+ <tr>
+ <td>
+ <hr>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top">
+ <table cellspacing="0" border="0">
+ <& PickBasics &>
+ <& PickCFs, cfqueues => \%cfqueues &>
+ </table>
+ </td>
+ </tr>
+ <tr><td>&nbsp;</td></tr>
+</table>
+
+</&>
+
+<%ARGS>
+$addquery => 0
+$query => undef
+%cfqueues => undef
+</%ARGS>
diff --git a/rt/html/Search/Elements/SearchPrivacy b/rt/html/Search/Elements/SearchPrivacy
new file mode 100644
index 000000000..745ba62ac
--- /dev/null
+++ b/rt/html/Search/Elements/SearchPrivacy
@@ -0,0 +1,55 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Object => undef
+</%args>
+% if (ref($Object) eq 'RT::User' && $Object->id == $session{'CurrentUser'}->Id) {
+<&|/l&>My saved searches</&>
+% } else {
+<&|/l, $Object->Name&>[_1]'s saved searches</&>
+% }
diff --git a/rt/html/Search/Elements/SearchesForObject b/rt/html/Search/Elements/SearchesForObject
new file mode 100644
index 000000000..45aa4535e
--- /dev/null
+++ b/rt/html/Search/Elements/SearchesForObject
@@ -0,0 +1,65 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Object => undef
+</%args>
+<%init>
+# Returns an array of search objects associated on $Object,
+# in the form of [Description, searchObj]
+my @result;
+while (my $search = $Object->Attributes->Next) {
+ my $desc;
+ if ($search->Name eq 'SavedSearch') {
+ push @result, [$search->Description, $search];
+ }
+ elsif ($search->Name =~ m/^Search - (.*)/) {
+ push @result, [$1, $search];
+ }
+}
+return @result;
+</%init>
diff --git a/rt/html/Search/Elements/SelectAndOr b/rt/html/Search/Elements/SelectAndOr
new file mode 100644
index 000000000..c8122660a
--- /dev/null
+++ b/rt/html/Search/Elements/SelectAndOr
@@ -0,0 +1,53 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<input type="radio" class="radio" name="<%$Name%>" checked value="AND" /><&|/l&>AND</&></input>
+<input type="radio" class="radio" name="<%$Name%>" value="OR" /><&|/l&>OR</&></input>
+
+<%ARGS>
+$Name => "Operator"
+</%ARGS>
diff --git a/rt/html/Search/Elements/SelectChartType b/rt/html/Search/Elements/SelectChartType
new file mode 100644
index 000000000..43a6182bf
--- /dev/null
+++ b/rt/html/Search/Elements/SelectChartType
@@ -0,0 +1,56 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Name => 'ChartType'
+$Default => 'bar'
+</%args>
+<select name="<%$Name%>">
+% foreach my $option qw(bar pie) {
+<option value="<%$option%>" <% $option eq $Default ? 'SELECTED' : '' %>><%loc($option)%></option>
+% }
+</select>
diff --git a/rt/html/Search/Elements/SelectGroup b/rt/html/Search/Elements/SelectGroup
new file mode 100644
index 000000000..3f78d3964
--- /dev/null
+++ b/rt/html/Search/Elements/SelectGroup
@@ -0,0 +1,67 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+% if ($AllowNull) {
+<option value="">-</option>
+% }
+%while (my $group = $groups->Next) {
+<option value="<%$group->id%>" <%$group->id eq $Default && "SELECTED"%>><%$group->Name%></option>
+%}
+</select>
+
+<%INIT>
+my $groups = new RT::Groups($session{'CurrentUser'});
+$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain);
+
+</%INIT>
+<%ARGS>
+$AllowNull => 1
+$Default=> ''
+$Name => 'Group'
+$Domain => 'UserDefined';
+</%ARGS>
diff --git a/rt/html/Search/Elements/SelectGroupBy b/rt/html/Search/Elements/SelectGroupBy
new file mode 100644
index 000000000..0ffb5e453
--- /dev/null
+++ b/rt/html/Search/Elements/SelectGroupBy
@@ -0,0 +1,63 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Name => 'GroupBy'
+$Default => 'Status'
+$Query => ''
+</%args>
+<select name="<% $Name %>">
+% while (@options) {
+% my ($text, $value) = (shift @options, shift @options);
+<option value="<% $value %>" <% $value eq $Default ? 'selected' : '' %>><% loc($text) %></option>
+% }
+</select>
+<%init>
+use RT::Report::Tickets;
+my $report = RT::Report::Tickets->new( $session{'CurrentUser'} );
+my @options = $report->Groupings( Query => $Query );
+</%init>
diff --git a/rt/html/Search/Elements/SelectLinks b/rt/html/Search/Elements/SelectLinks
new file mode 100644
index 000000000..f3586528d
--- /dev/null
+++ b/rt/html/Search/Elements/SelectLinks
@@ -0,0 +1,66 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select name="<%$Name%>">
+% foreach (@fields) {
+<option value="<%$_%>"><&|/l&><%$_%></&></option>
+% }
+</select>
+<%ARGS>
+$Name => 'LinksField'
+</%ARGS>
+
+<%INIT>
+my @fields = ('HasMember',
+ 'MemberOf',
+ 'DependsOn',
+ 'DependedOnBy',
+ 'RefersTo',
+ 'ReferredToBy',
+ 'LinkedTo',
+ );
+</%INIT>
diff --git a/rt/html/Search/Elements/SelectPersonType b/rt/html/Search/Elements/SelectPersonType
new file mode 100644
index 000000000..bc631dbb0
--- /dev/null
+++ b/rt/html/Search/Elements/SelectPersonType
@@ -0,0 +1,84 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<select NAME ="<%$Name%>">
+% if ($AllowNull) {
+<option value="">-</option>
+% }
+% for my $option (@types) {
+% if ($Suffix) {
+<option value="<% $option %><% $Suffix %>" <%$option eq $Default && "SELECTED"%> ><%loc($option)%></option>
+% next;
+% }
+% foreach my $subtype (@subtypes) {
+<option value="<%"$option.$subtype"%>" <%$option eq $Default && $subtype eq 'EmailAddress' && "SELECTED"%> ><% loc($option) %> <% loc($subtype) %></option>
+% }
+% }
+</select>
+
+<%INIT>
+my @types;
+if ($Scope =~ 'queue') {
+ @types = qw(Cc AdminCc);
+}
+elsif ($Suffix eq 'Group') {
+ @types = qw(Requestor Cc AdminCc Watcher);
+}
+else {
+ @types = qw(Requestor Cc AdminCc Watcher Owner);
+}
+
+my @subtypes = qw(EmailAddress Name RealName Nickname Organization Address1 Address2 WorkPhone HomePhone MobilePhone PagerPhone);
+
+</%INIT>
+<%ARGS>
+$AllowNull => 1
+$Suffix => ''
+$Default=>undef
+$Scope => 'ticket'
+$Name => 'WatcherType'
+</%ARGS>
diff --git a/rt/html/Search/Elements/SelectSearchObject b/rt/html/Search/Elements/SelectSearchObject
new file mode 100644
index 000000000..f52a83372
--- /dev/null
+++ b/rt/html/Search/Elements/SelectSearchObject
@@ -0,0 +1,60 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+@Objects => undef
+$Name => undef
+</%args>
+<select name="<%$Name%>">
+% foreach my $object (@Objects) {
+% if (ref($object) eq 'RT::User' && $object->id == $session{'CurrentUser'}->Id) {
+<option value="<%ref($object)%>-<%$object->id%>"><&|/l&>My saved searches</&></option>
+% } else {
+<option value="<%ref($object)%>-<%$object->id%>"><&|/l, $object->Name&>[_1]'s saved searches</&></option>
+% }
+% }
+</select>
diff --git a/rt/html/Search/Elements/SelectSearchesForObjects b/rt/html/Search/Elements/SelectSearchesForObjects
new file mode 100644
index 000000000..dc8368577
--- /dev/null
+++ b/rt/html/Search/Elements/SelectSearchesForObjects
@@ -0,0 +1,69 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+@Objects => undef
+$Name => undef
+$SearchType => 'Ticket',
+</%args>
+<select name="<%$Name%>">
+% foreach my $object (@Objects) {
+% if (ref($object) eq 'RT::User' && $object->id == $session{'CurrentUser'}->Id) {
+<option value=""><&|/l&>My saved searches</&></option>
+% } else {
+<option value=""></option>
+<option value=""><&|/l, $object->Name&>[_1]'s saved searches</&></option>
+% }
+% my @searches = $object->Attributes->Named('SavedSearch');
+% foreach my $search (@searches) {
+% # Skip it if it is not of search type we want.
+% next if ($search->SubValue('SearchType')
+% && $search->SubValue('SearchType') ne $SearchType);
+<option value="<%ref($object)%>-<%$object->id%>-SavedSearch-<%$search->Id%>"> -<%$search->Description||loc('Unnamed search')%></option>
+% }
+% }
+</select>
diff --git a/rt/html/Search/Results.html b/rt/html/Search/Results.html
new file mode 100755
index 000000000..01bdfffde
--- /dev/null
+++ b/rt/html/Search/Results.html
@@ -0,0 +1,177 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title, Refresh => $session{'tickets_refresh_interval'},
+ RSSAutoDiscovery => $RSSFeedURL &>
+<& /Ticket/Elements/Tabs,
+ current_tab => "Search/Results.html".$QueryString,
+ Title => $title,
+ Format => $Format,
+ Query => $Query,
+ Rows => $Rows,
+ OrderBy => $OrderBy,
+ Order => $Order &>
+<& /Elements/TicketList,
+ Query => $Query,
+ AllowSorting => 1,
+ OrderBy => $OrderBy,
+ Order => $Order,
+ Rows => $Rows,
+ Page => $Page,
+ Format => $Format,
+ BaseURL => $RT::WebPath."/Search/Results.html?"
+
+ &>
+% my %hiddens = (Query => $Query, Format => $Format, Rows => $Rows, OrderBy => $OrderBy, Order => $Order, HideResults => $HideResults, Page => $Page );
+<div align="right">
+<form method="get" action="<%$RT::WebPath%>/Search/Results.html">
+%foreach my $key (keys(%hiddens)) {
+<input type="hidden" class="hidden" name="<%$key%>" value="<%defined($hiddens{$key})?$hiddens{$key}:''%>"/>
+%}
+<& /Elements/Refresh, Name => 'TicketsRefreshInterval', Default => $session {'tickets_refresh_interval'} &>
+<input type="submit" class="button" value="<&|/l&>Go!</&>" />
+</form>
+</div>
+<div align="right">
+<a href="<%$RT::WebPath%>/Search/Bulk.html<%$QueryString%>"><&|/l&>Update multiple tickets</&></a><br />
+<a href="<%$RT::WebPath%>/Search/Results.html<%$QueryString%>"><&|/l&>Bookmarkable link</&></a><br />
+<a href="<%$RT::WebPath%>/Search/Results.tsv<%$QueryString%>"><&|/l&>spreadsheet</&></a> |
+<a href="<%$RSSFeedURL%>"><&|/l&>RSS</&></a> |
+<a href="<%$RT::WebPath%>/Tools/Offline.html<%$ShortQueryString%>"><&|/l&>Work offline</&></a><br />
+<form method="get" action="<%$RT::WebPath%>/Search/Chart.html"><&|/l&>chart</&>
+% %hiddens = (Query => $Query, Format => $Format, Rows => $Rows, OrderBy => $OrderBy, Order => $Order);
+%foreach my $key (keys(%hiddens)) {
+<input type="hidden" class="hidden" name="<%$key%>" value="<%defined($hiddens{$key})?$hiddens{$key}:''%>"/>
+%}
+<&|/l, $m->scomp('Elements/SelectGroupBy', Name => 'PrimaryGroupBy', Query => $Query) &>grouped by [_1]</&>
+<&|/l, $m->scomp('Elements/SelectChartType', Name => 'ChartStyle') &>style: [_1]</&>
+<input type="submit" class="button" value="<%loc('Go!')%>" />
+</form>
+<& /Elements/Callback, _CallbackName => 'SearchActions', QueryString => $QueryString&>
+</div>
+<%INIT>
+# Read from user preferences
+my $prefs = $session{'CurrentUser'}->UserObj->Preferences("SearchDisplay") || {};
+
+# These variables are what define a search_hash; this is also
+# where we give sane defaults.
+$Format ||= $prefs->{'Format'};
+$Order ||= $prefs->{'Order'} || 'ASC';
+$OrderBy ||= $prefs->{'OrderBy'} || 'id';
+
+# Some forms pass in "RowsPerPage" rather than "Rows"
+# We call it RowsPerPage everywhere else.
+
+if ( !defined($Rows) ) {
+ if ( $ARGS{'RowsPerPage'} ) {
+ $Rows = $ARGS{'RowsPerPage'};
+ } elsif ( defined $prefs->{'RowsPerPage'} ) {
+ $Rows = $prefs->{'RowsPerPage'};
+ } else {
+ $Rows = 50;
+ }
+}
+
+my ($title, $ticketcount);
+$session{'i'}++;
+$session{'tickets'} = RT::Tickets->new($session{'CurrentUser'}) ;
+$session{'tickets'}->FromSQL($Query) if ($Query);
+
+if ($OrderBy =~ /\|/) {
+ # Multiple Sorts
+ my @OrderBy = split /\|/,$OrderBy;
+ my @Order = split /\|/,$Order;
+ $session{'tickets'}->OrderByCols(
+ map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } } ( 0
+ .. $#OrderBy ) );;
+} else {
+ $session{'tickets'}->OrderBy(FIELD => $OrderBy, ORDER => $Order);
+}
+
+$session{'CurrentSearchHash'} = {
+ Format => $Format,
+ Query => $Query,
+ Page => $Page,
+ Order => $Order,
+ OrderBy => $OrderBy,
+ RowsPerPage => $Rows
+ };
+
+
+if ( $session{'tickets'}->Query()) {
+ $ticketcount = $session{tickets}->CountAll();
+ $title = loc('Found [quant,_1,ticket]', $ticketcount);
+} else {
+ $title = loc("Find tickets");
+}
+
+my $QueryString = "?".$m->comp('/Elements/QueryString',
+ Query => $Query,
+ Format => $Format,
+ Rows => $Rows,
+ OrderBy => $OrderBy,
+ Order => $Order,
+ Page => $Page);
+my $ShortQueryString = "?".$m->comp('/Elements/QueryString', Query => $Query);
+my $RSSFeedURL = "$RT::WebPath/Search/Results.rdf$ShortQueryString";
+
+if ($ARGS{'TicketsRefreshInterval'}) {
+ $session{'tickets_refresh_interval'} = $ARGS{'TicketsRefreshInterval'};
+}
+</%INIT>
+<%CLEANUP>
+$session{'tickets'}->PrepForSerialization();
+</%CLEANUP>
+<%ARGS>
+$Query => undef
+$Format => undef
+$HideResults => 0
+$Rows => undef
+$Page => 1
+$OrderBy => undef
+$Order => undef
+</%ARGS>
diff --git a/rt/html/Search/Results.rdf b/rt/html/Search/Results.rdf
new file mode 100644
index 000000000..fe97a314c
--- /dev/null
+++ b/rt/html/Search/Results.rdf
@@ -0,0 +1,87 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%INIT>
+
+my $Tickets = RT::Tickets->new($session{'CurrentUser'});
+$Tickets->FromSQL($ARGS{'Query'});
+$r->content_type('application/rss+xml');
+
+
+
+ # create an RSS 1.0 file (http://purl.org/rss/1.0/)
+ use XML::RSS;
+ my $rss = new XML::RSS (version => '1.0');
+ $rss->channel(
+ title => "$RT::rtname: Syndicated Search",
+ link => $RT::WebURL,
+ description => "",
+ dc => {
+ },
+ syn => {
+ updatePeriod => "hourly",
+ updateFrequency => "1",
+ updateBase => "1901-01-01T00:00+00:00",
+ },
+ );
+
+
+ while ( my $Ticket = $Tickets->Next()) {
+ my $row;
+ $rss->add_item(
+ title => $Ticket->Subject,
+ link => $RT::WebURL."/Ticket/Display.html?id=".$Ticket->id,
+ description => $Ticket->Transactions->First->Content,
+ dc => {
+ subject => ($Ticket->Subject || loc('No subject')),
+ creator => $Ticket->CreatorObj->RealName . "<".$Ticket->CreatorObj->EmailAddress.">",
+ },
+ );
+ }
+$m->out($rss->as_string);
+$m->abort();
+</%INIT>
diff --git a/rt/html/Search/Results.tsv b/rt/html/Search/Results.tsv
new file mode 100644
index 000000000..bb1907317
--- /dev/null
+++ b/rt/html/Search/Results.tsv
@@ -0,0 +1,134 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+$OrderBy => 'id'
+$Order => 'ASC'
+</%ARGS>
+<%INIT>
+
+my $Tickets = RT::Tickets->new( $session{'CurrentUser'} );
+$Tickets->FromSQL( $ARGS{'Query'} );
+if ( $OrderBy =~ /\|/ ) {
+
+ # Multiple Sorts
+ my @OrderBy = split /\|/, $OrderBy;
+ my @Order = split /\|/, $Order;
+ $Tickets->OrderByCols(
+ map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } }
+ ( 0 .. $#OrderBy ) );
+}
+else {
+ $Tickets->OrderBy( FIELD => $OrderBy, ORDER => $Order );
+}
+
+my @rows;
+my %known_cfs;
+
+my @attrs = qw( id QueueObj->Name Subject Status TimeEstimated TimeWorked TimeLeft Priority FinalPriority OwnerObj->Name
+ Requestors->MemberEmailAddressesAsString Cc->MemberEmailAddressesAsString AdminCc->MemberEmailAddressesAsString
+ DueObj->ISO ToldObj->ISO CreatedObj->ISO ResolvedObj->ISO LastUpdatedObj->ISO);
+
+$r->content_type('application/vnd.ms-excel');
+while ( my $Ticket = $Tickets->Next()) {
+ my $row;
+ foreach my $attr (@attrs) {
+ if ($attr =~ /(.*)->ISO$/ and $Ticket->$1->Unix <= 0) {
+ $row->{$attr} = "";
+ } else {
+ my $method = '$Ticket->'.$attr.'()';
+ $row->{$attr} = eval $method;
+ if ($@) {die "Failed to find $attr - ". $@};
+ }
+ }
+
+ my $cfs = $Ticket->QueueObj->TicketCustomFields();
+ while (my $cf = $cfs->Next) {
+ my @content;
+ my $values = $Ticket->CustomFieldValues($cf->Id);
+ while (my $value = $values->Next) {
+ push @content, $value->Content;
+ }
+ $row->{'CustomField-'.$cf->Id} = join(', ',@content);
+ if ($row->{'CustomField-'.$cf->Id}) {
+ $known_cfs{$cf->Id} = $cf->Name;
+ }
+ }
+ push @rows, $row;
+}
+
+{
+ my @header;
+ foreach my $attr (@attrs) {
+ my $label = $attr;
+ $label =~ s'Obj-.(?:AsString|Name|ISO)''g;
+ $label =~ s'-\>MemberEmailAddressesAsString''g;
+ push @header, $label;
+ }
+ foreach my $id (sort keys %known_cfs) {
+ push @header, "CF-".$known_cfs{$id};
+ }
+ $m->out(join("\t", @header));
+ $m->out("\n");
+}
+
+foreach my $row (@rows) {
+ my @row;
+ foreach my $attr(@attrs) {
+ push @row, $row->{"$attr"};
+ }
+ foreach my $id (sort keys %known_cfs) {
+ my $val = $row->{'CustomField-'.$id};
+ $val =~ s/(\n|\r)//g;
+ push @row, $val;
+ }
+ $m->out(join("\t",@row));
+ $m->out("\n");
+}
+
+$m->abort();
+</%INIT>
diff --git a/rt/html/Search/Simple.html b/rt/html/Search/Simple.html
new file mode 100644
index 000000000..01424a3b1
--- /dev/null
+++ b/rt/html/Search/Simple.html
@@ -0,0 +1,107 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title &>
+<& /Elements/Tabs,
+ current_toptab => "Search/Simple.html",
+ Title => $title
+&>
+
+<& /Elements/Callback, _CallbackName => 'PreForm', %ARGS &>
+
+<div id="SimpleSearchForm">
+<form action="Simple.html" method="get">
+
+<p><&|/l&>Search for tickets. Enter <strong>id</strong> numbers, <strong>queues</strong> by name, Owners by <strong>username</strong> and Requestors by <strong>email address</strong>. RT will look for anything else you enter in ticket bodies and attachments.</&></p>
+
+<p><&|/l&>Searching the full text of every ticket can take a long time, but if you need to do it, you can search for any word in full ticket history for any word by typing <b>fulltext:<i>word</i></b>.</&></p>
+<p><&|/l&>RT will look for anything else you enter in ticket subjects.</&></p>
+
+<br />
+<br />
+<div align="center">
+<input name="q" size="60" /><input type="submit" class="button" value="<&|/l&>Search</&>" />
+</div>
+
+</form>
+
+<& /Elements/Callback, _CallbackName => 'PostForm', %ARGS &>
+
+</div>
+
+<%INIT>
+my $title = loc("Search for tickets");
+use RT::Search::Googleish;
+
+if ($q) {
+ my $tickets = new RT::Tickets( $session{'CurrentUser'} );
+
+ $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'ModifyQuery', query => \$q);
+
+ if ($q =~ /^(\d+)$/) {
+ RT::Interface::Web::Redirect($RT::WebURL."/Ticket/Display.html?id=".$q);
+ }
+
+ my %args = (
+ Argument => $q,
+ TicketsObj => $tickets,
+ );
+
+ $m->comp('/Elements/Callback', %ARGS, _CallbackName => 'SearchArgs', args => \%args);
+
+ my $search = RT::Search::Googleish->new(%args);
+
+ $m->comp( "Results.html", Query => $search->QueryToSQL() );
+ $m->comp( "/Elements/Footer" );
+ $m->abort();
+}
+</%INIT>
+
+<%ARGS>
+$q => undef
+</%ARGS>
+
diff --git a/rt/html/SelfService/Attachment/dhandler b/rt/html/SelfService/Attachment/dhandler
new file mode 100644
index 000000000..e7d59e63c
--- /dev/null
+++ b/rt/html/SelfService/Attachment/dhandler
@@ -0,0 +1,51 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+$m->comp('/Ticket/Attachment/dhandler', %ARGS);
+$m->abort;
+</%init>
diff --git a/rt/html/SelfService/Closed.html b/rt/html/SelfService/Closed.html
new file mode 100644
index 000000000..766b0bc4f
--- /dev/null
+++ b/rt/html/SelfService/Closed.html
@@ -0,0 +1,56 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /SelfService/Elements/Header, Title => loc('Closed tickets') &>
+
+<& /SelfService/Elements/MyRequests, status => ['rejected', 'resolved'],
+ friendly_status => loc('closed'),
+ BaseURL => $RT::WebPath . "/SelfService/Closed.html?",
+ Page => $Page &>
+<%ARGS>
+$Page => 1
+</%ARGS>
diff --git a/rt/html/SelfService/Create.html b/rt/html/SelfService/Create.html
new file mode 100644
index 000000000..f66961db8
--- /dev/null
+++ b/rt/html/SelfService/Create.html
@@ -0,0 +1,117 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& Elements/Header, Title => loc("Create a ticket") &>
+
+<form action="Display.html" method="post" enctype="multipart/form-data">
+<input type="hidden" class="hidden" name="id" value="new" />
+
+<table>
+<tr>
+<td class="label">
+<&|/l&>Queue</&>:
+</td>
+<td class="value">
+ <input type="hidden" class="hidden" name="Queue" value="<%$queue_obj->id%>" />
+ <strong><%$queue_obj->Name%></strong> (<%$queue_obj->Description%>)
+</td>
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Requestors</&>:
+</td>
+<td class="value">
+<input name="Requestors" value="<%$session{CurrentUser}->EmailAddress%>" size="20" />
+</td>
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Cc</&>:
+</td>
+<td class="value">
+ <input name="Cc" size="20" />
+</td>
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Subject</&>:
+</td>
+<td class="value">
+<input name="Subject" size="60" maxsize="200" value="" />
+</td>
+</tr>
+<tr>
+ <td colspan="2">
+ <& /Ticket/Elements/EditCustomFields, QueueObj => $queue_obj &>
+ </td>
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Attach file</&>:
+</td>
+<td class="value">
+<input name="Attach" type="file" />
+</td>
+</tr>
+<tr>
+<td colspan="2">
+<&|/l&>Describe the issue below</&>:<br />
+<& /Elements/MessageBox &>
+</td>
+</tr>
+</table>
+<& /Elements/Submit, Label => loc("Create ticket")&>
+
+
+</form>
+<%args>
+$Queue => undef
+</%args>
+<%init>
+my $queue_obj = RT::Queue->new($session{'CurrentUser'});
+$queue_obj->Load($Queue);
+</%init>
diff --git a/rt/html/SelfService/CreateTicketInQueue.html b/rt/html/SelfService/CreateTicketInQueue.html
new file mode 100755
index 000000000..fd7e42664
--- /dev/null
+++ b/rt/html/SelfService/CreateTicketInQueue.html
@@ -0,0 +1,63 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& Elements/Header, Title => loc("Create a ticket") &>
+
+<h1><&|/l&>Select a queue for your new ticket</&></h1>
+
+<dl>
+% while (my $queue = $queues->Next) {
+% next unless $queue->CurrentUserHasRight('CreateTicket');
+
+<dt><a href="<%$RT::WebPath%>/SelfService/Create.html?Queue=<%$queue->id%>"><%$queue->Name%></a></dt>
+<dd><%$queue->Description%></dd>
+% }
+</dl>
+<%init>
+my $queues = RT::Queues->new($session{'CurrentUser'});
+$queues->UnLimit;
+</%init>
diff --git a/rt/html/SelfService/Display.html b/rt/html/SelfService/Display.html
new file mode 100644
index 000000000..a38d2593b
--- /dev/null
+++ b/rt/html/SelfService/Display.html
@@ -0,0 +1,235 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /SelfService/Elements/Header, Title => loc('#[_1]: [_2]', $Ticket->id, $Ticket->Subject) &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+ <table width="100%" class="ticketsummary" >
+ <tr>
+ <td valign="top" width="50%" class="boxcontainer">
+ <&| /Widgets/TitleBox, title => loc('The Basics'),
+ title_class=> 'inverse',
+ color => "#993333" &>
+ <& /Ticket/Elements/ShowBasics, Ticket => $Ticket &>
+ <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket &>
+ </&>
+</td>
+ <td valign="top" width="50%" class="boxcontainer">
+ <&| /Widgets/TitleBox, title => loc("Dates"),
+ title_class=> 'inverse',
+ color => "#663366" &>
+ <& /Ticket/Elements/ShowDates, Ticket => $Ticket, UpdatedLink => 0 &>
+ </&>
+</td>
+</tr>
+</table>
+
+
+
+%#!!pape: selfservice_find_attachments.patch {{
+<& /Ticket/Elements/ShowHistory,
+ Ticket => $Ticket,
+ URIFile => "Display.html",
+ ShowHeaders => $ARGS{'ShowHeaders'},
+ AttachPath => "Attachment",
+ Attachments => $attachments,
+ UpdatePath => "Update.html"
+&>
+%#!!pape: selfservice_find_attachments.patch }}
+
+
+
+<%INIT>
+
+my ( $field, @results );
+
+# {{{ Load the ticket
+#If we get handed two ids, mason will make them an array. bleck.
+# We want teh first one. Just because there's no other sensible way
+# to deal
+my @id = ( ref $id eq 'ARRAY' ) ? @{$id} : ($id);
+
+my $Ticket = new RT::Ticket( $session{'CurrentUser'} );
+
+# store the uploaded attachment in session
+if ( $ARGS{'Attach'} ) { # attachment?
+ $session{'Attachments'} = {} unless defined $session{'Attachments'};
+
+ my $subject = "$ARGS{'Attach'}";
+
+ # since CGI.pm deutf8izes the magic field, we need to add it back.
+ Encode::_utf8_on($subject);
+
+ # strip leading directories
+ $subject =~ s#^.*[\\/]##;
+
+ my $attachment = MakeMIMEEntity(
+ Subject => $subject,
+ Body => "",
+ AttachmentFieldName => 'Attach'
+ );
+
+ $session{'Attachments'} =
+ { %{ $session{'Attachments'} || {} },
+ $ARGS{'Attach'} => $attachment };
+}
+
+if ( $id[0] eq 'new' ) {
+
+ # {{{ Create a new ticket
+
+ my $Queue = new RT::Queue( $session{'CurrentUser'} );
+ unless ( $Queue->Load( $ARGS{'Queue'} ) ) {
+ $m->comp( 'Error.html', Why => loc('Queue not found') );
+ $m->abort;
+ }
+
+ unless ( $Queue->CurrentUserHasRight('CreateTicket') ) {
+ $m->comp( 'Error.html',
+ Why =>
+ loc('You have no permission to create tickets in that queue.') );
+ $m->abort;
+ }
+
+
+ ( $Ticket, @results ) =
+ CreateTicket( Attachments => $session{'Attachments'}, %ARGS, Status => 'new' );
+
+ unless ( $Ticket->id ) {
+ $m->comp( 'Error.html', Why => join( "\n", @results ));
+ $m->abort();
+ }
+
+ # }}}
+
+ # delete temporary storage entry to make WebUI clean
+ unless ( keys %{ $session{'Attachments'} } and $ARGS{'UpdateAttach'} ) {
+ delete $session{'Attachments'};
+ }
+
+ # }}}
+ }
+ else {
+ unless ( $Ticket->Load( $id[0] ) ) {
+ $m->comp( 'Error.html',
+ Why => loc( "Couldn't load ticket '[_1]'", $id ) );
+ $m->abort();
+ }
+
+ my ( $code, $msg );
+
+ #Update the status
+ if ( ( defined $ARGS{'Status'} )
+ and $ARGS{'Status'}
+ and ( $ARGS{'Status'} ne $Ticket->Status ) )
+ {
+ ( $code, $msg ) = $Ticket->SetStatus( $ARGS{'Status'} );
+ push @results, "$msg";
+ }
+
+ # }}}
+
+ if (
+ $session{'Attachments'}
+ || ( defined $ARGS{'UpdateContent'}
+ && $ARGS{'UpdateContent'} ne ''
+ && $ARGS{'UpdateContent'} ne "-- \n"
+ . $session{'CurrentUser'}->UserObj->Signature )
+ )
+ {
+ $ARGS{UpdateAttachments} = $session{'Attachments'};
+ }
+ ProcessUpdateMessage(
+ ARGSRef => \%ARGS,
+ Actions => \@results,
+ TicketObj => $Ticket
+ );
+ delete $session{'Attachments'};
+
+ # delete temporary storage entry to make WebUI clean
+ unless ( keys %{ $session{'Attachments'} } and $ARGS{'UpdateAttach'} ) {
+ delete $session{'Attachments'};
+ }
+
+ my @cfupdates = ProcessObjectCustomFieldUpdates(Object => $Ticket, ARGSRef => \%ARGS);
+ push (@results, @cfupdates);
+
+ # }}}
+
+ }
+
+ # This code does automatic redirection if any updates happen.
+
+ unless ( $Ticket->CurrentUserHasRight('ShowTicket') ) {
+ $m->comp( 'Error.html',
+ Why => loc("No permission to display that ticket") );
+ $m->abort();
+ }
+
+ if (@results) {
+ # We've done something, so we need to clear the decks to avoid
+ # resubmission on refresh.
+ # But we need to store Actions somewhere too, so we don't lose them.
+ $session{"Actions"} = \@results;
+ RT::Interface::Web::Redirect($RT::WebURL."SelfService/Display.html?id="
+ . $Ticket->id);
+ } else {
+ @results = @{ delete $session{"Actions"} || [] };
+ }
+
+ my $Transactions = $Ticket->Transactions;
+
+ my $attachments =
+ $m->comp( '/Ticket/Elements/FindAttachments', Ticket => $Ticket );
+
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/SelfService/Elements/GotoTicket b/rt/html/SelfService/Elements/GotoTicket
new file mode 100644
index 000000000..5eac306e9
--- /dev/null
+++ b/rt/html/SelfService/Elements/GotoTicket
@@ -0,0 +1,48 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<form action="<%$RT::WebPath%>/SelfService/Display.html"><input type="submit" class="button" value="<&|/l&>Goto ticket</&>" />&nbsp;<input size="4" name="id" /></form>
diff --git a/rt/html/SelfService/Elements/Header b/rt/html/SelfService/Elements/Header
new file mode 100644
index 000000000..f248292e2
--- /dev/null
+++ b/rt/html/SelfService/Elements/Header
@@ -0,0 +1,49 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, %ARGS, Prefs => '/SelfService/Prefs.html' &>
+<& /SelfService/Elements/Tabs, %ARGS &>
diff --git a/rt/html/SelfService/Elements/MyRequests b/rt/html/SelfService/Elements/MyRequests
new file mode 100644
index 000000000..41f6b09b1
--- /dev/null
+++ b/rt/html/SelfService/Elements/MyRequests
@@ -0,0 +1,84 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<&| /Widgets/TitleBox, title => $title &>
+<& /Elements/TicketList, Title => $title,
+ Format => @Format,
+ Query => $Query,
+ Order => $Order,
+ OrderBy => $OrderBy,
+ BaseURL => $BaseURL,
+ Page => $Page &>
+</&>
+
+<%INIT>
+my $id = $session{'CurrentUser'}->id;
+my $Query = "( "
+ . join( ' OR ', map "$_.id = $id", @roles )
+ . ")";
+if ( @status ) {
+ $Query .= " AND ( "
+ . join( ' OR ', map "Status = '$_'", @status )
+ . " )";
+}
+my $Order = "ASC";
+my $OrderBy = "Created";
+my @Format = qq{
+ '<B><A HREF="$RT::WebPath/SelfService/Display.html?id=__id__">__id__</a></B>/TITLE:#',
+ '<B><A HREF="$RT::WebPath/SelfService/Display.html?id=__id__">__Subject__</a></B>/TITLE:Subject',
+ Status,
+ Requestors,
+ OwnerName};
+</%INIT>
+<%ARGS>
+$friendly_status => loc('open')
+$title => loc("My [_1] tickets", $friendly_status)
+@roles => ('Watcher')
+@status => ('open', 'new', 'stalled')
+$BaseURL => undef
+$Page => 1
+</%ARGS>
diff --git a/rt/html/SelfService/Elements/Tabs b/rt/html/SelfService/Elements/Tabs
new file mode 100644
index 000000000..164fa2863
--- /dev/null
+++ b/rt/html/SelfService/Elements/Tabs
@@ -0,0 +1,113 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Callback, tabs => $tabs, %ARGS &>
+<& /Elements/PageLayout,
+ current_toptab => $current_toptab,
+ current_tab => $current_tab,
+ toptabs => $tabs,
+ topactions => $actions,
+ title => $Title
+&>
+<a name="skipnav" id="skipnav" accesskey="8"></a>
+<%INIT>
+my $queues = RT::Queues->new($session{'CurrentUser'});
+$queues->UnLimit;
+
+my $queue_count = 0;
+my $queue_id = 1;
+
+while (my $queue = $queues->Next) {
+ next unless $queue->CurrentUserHasRight('CreateTicket');
+ $queue_id = $queue->id;
+ $queue_count++;
+ last if ($queue_count > 1);
+}
+
+if ($Title) {
+$Title = loc("RT Self Service") . " / " . $Title;
+} else {
+$Title = loc("RT Self Service");
+
+}
+my ($tab);
+my $tabs = { A => { title => loc('Open tickets'),
+ path => 'SelfService/',
+ },
+ B => { title => loc('Closed tickets'),
+ path => 'SelfService/Closed.html',
+ },
+ };
+
+if ($queue_count > 1) {
+ $tabs->{C} = { title => loc('New ticket'),
+ path => 'SelfService/CreateTicketInQueue.html'
+ };
+} else {
+ $tabs->{C} = { title => loc('New ticket'),
+ path => 'SelfService/Create.html?Queue=' . $queue_id
+ };
+}
+
+if ($session{'CurrentUser'}->HasRight( Right => 'ModifySelf',
+ Object => $RT::System )) {
+ $tabs->{Z} = { title => loc('Preferences'),
+ path => 'SelfService/Prefs.html'
+ };
+}
+
+my $actions = {
+ B => { html => $m->scomp('GotoTicket')
+ }
+ };
+</%INIT>
+<%ARGS>
+$Title => undef
+$current_toptab => undef
+$current_tab => undef
+</%ARGS>
+
diff --git a/rt/html/SelfService/Error.html b/rt/html/SelfService/Error.html
new file mode 100644
index 000000000..81a483d39
--- /dev/null
+++ b/rt/html/SelfService/Error.html
@@ -0,0 +1,70 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /SelfService/Elements/Header, Title => loc('Error') &>
+<h2 class="title"><%loc('Error')%></h2>
+<&| /Widgets/TitleBox, title => $Title &>
+<%$Why%>
+<br />
+<font size="-1">
+<%$Details%>
+</font>
+</&>
+</body>
+</html>
+
+
+<%args>
+$Code => undef
+$Details => undef
+$Title => loc("RT Error")
+$Why => loc("the calling component did not specify why")
+</%args>
+
+<%INIT>
+$RT::Logger->error("WebRT: $Why ($Details)");
+</%INIT>
diff --git a/rt/html/SelfService/Prefs.html b/rt/html/SelfService/Prefs.html
new file mode 100644
index 000000000..0cd3756c3
--- /dev/null
+++ b/rt/html/SelfService/Prefs.html
@@ -0,0 +1,92 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /SelfService/Elements/Header, Title => loc('Preferences') &>
+
+<& /Elements/ListActions, actions => \@results &>
+<form method="post">
+
+% unless ($RT::WebExternalAuth and !$RT::WebFallbackToInternalAuth) {
+<&| /Widgets/TitleBox, title => loc('Change password') &>
+<&|/l&>New password</&>: <input type="password" name="NewPass1" size="16" />
+<&|/l&>Confirm</&>: <input type="password" name="NewPass2" size="16" />
+</&>
+<br />
+% }
+<& /Elements/Submit, Label => loc('Save Changes') &>
+ </form>
+
+
+<%INIT>
+my @results;
+
+if ($NewPass1) {
+ if ($NewPass1 ne $NewPass2) {
+ push (@results, "Passwords did not match.");
+ }
+ else {
+ my ($val, $msg)=$session{'CurrentUser'}->UserObj->SetPassword($NewPass1);
+ push (@results, "Password: ".$msg);
+ }
+}
+if ($Signature) {
+ $Signature =~ s/(\r\n|\r)/\n/g;
+ if ($Signature ne $session{'CurrentUser'}->UserObj->Signature) {
+ my ($val, $msg)=$session{'CurrentUser'}->UserObj->SetSignature($Signature);
+ push (@results, "Signature: ".$msg);
+ }
+}
+#A hack to make sure that session gets rewritten.
+
+$session{'i'}++;
+</%INIT>
+
+<%ARGS>
+$Signature => undef
+$NewPass1 => undef
+$NewPass2 => undef
+</%ARGS>
diff --git a/rt/html/SelfService/Update.html b/rt/html/SelfService/Update.html
new file mode 100644
index 000000000..b10716f9a
--- /dev/null
+++ b/rt/html/SelfService/Update.html
@@ -0,0 +1,129 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /SelfService/Elements/Header,
+ Title =>loc('Update ticket #[_1]', $Ticket->id)
+&>
+
+
+<form action="Display.html" method="post" enctype="multipart/form-data">
+<input type="hidden" class="hidden" name="UpdateType" value="response" />
+<input type="hidden" class="hidden" name="id" value="<%$Ticket->Id%>" />
+<table>
+ <tr>
+ <td class="label">
+ <&|/l&>Status</&>
+ </td>
+ <td class="value">
+ <& /Elements/SelectStatus, Name=>"Status", DefaultLabel => loc("[_1] (Unchanged)",loc($DefaultStatus)) &>
+ </td>
+ </tr>
+ <tr>
+ <td class="label">
+ <&|/l&>Subject</&>
+ </td>
+ <td class="value">
+ <input name="UpdateSubject" size="60" value="<% $Ticket->Subject %>" />
+ </td>
+
+ </tr>
+% if (exists $session{'Attachments'}) {
+<tr>
+ <td class="label">
+ <&|/l&>Attached file</&>
+ </td>
+ <td colspan="5" class="value">
+ <&|/l&>Check box to delete</&><br />
+% foreach my $attach_name (keys %{$session{'Attachments'}}) {
+ <input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1" /><%$attach_name%><br />
+% } # end of foreach
+ </td>
+</tr>
+% } # end of if
+<tr>
+ <td class"label">
+ <&|/l&>Attach</&>
+ </td>
+ <td class="value">
+ <input name="Attach" type="file" />
+ <input type="hidden" class="hidden" name="UpdateAttach" value="1" />
+ </td>
+ </tr>
+</table>
+<& /Ticket/Elements/EditCustomFields, TicketObj => $Ticket &>
+<& /Elements/MessageBox,
+ Name => "UpdateContent",
+ QuoteTransaction => $ARGS{QuoteTransaction}
+ &>
+ <br />
+
+
+<& /Elements/Submit &>
+ </form>
+
+
+
+<%INIT>
+
+my $Ticket = LoadTicket($id);
+
+my $title = loc( "Update ticket #[_1]", $Ticket->id );
+
+$DefaultStatus = $Ticket->Status() unless ($DefaultStatus);
+
+
+Abort( loc("No permission to view update ticket") )
+ unless ( $Ticket->CurrentUserHasRight('ReplyToTicket')
+ or $Ticket->CurrentUserHasRight('ModifyTicket') );
+
+</%INIT>
+
+<%ARGS>
+$id => undef
+$Action => undef
+$DefaultStatus => undef
+</%ARGS>
diff --git a/rt/html/SelfService/index.html b/rt/html/SelfService/index.html
new file mode 100644
index 000000000..cd7dfb02f
--- /dev/null
+++ b/rt/html/SelfService/index.html
@@ -0,0 +1,54 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /SelfService/Elements/Header, Title => loc('Open tickets') &>
+
+<& /SelfService/Elements/MyRequests, BaseURL => $RT::WebPath . "/SelfService/?",
+ Page => $Page &>
+<%ARGS>
+$Page => 1
+</%ARGS>
diff --git a/rt/html/Ticket/Attachment/dhandler b/rt/html/Ticket/Attachment/dhandler
new file mode 100644
index 000000000..4872ef2a7
--- /dev/null
+++ b/rt/html/Ticket/Attachment/dhandler
@@ -0,0 +1,94 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%perl>
+ my ($ticket, $trans,$attach, $filename);
+ my $arg = $m->dhandler_arg; # get rest of path
+ if ($arg =~ '^(\d+)/(\d+)') {
+ $trans = $1;
+ $attach = $2;
+ }
+ else {
+ Abort("Corrupted attachment URL.");
+ }
+ my $AttachmentObj = new RT::Attachment($session{'CurrentUser'});
+ $AttachmentObj->Load($attach) || Abort("Attachment '$attach' could not be loaded");
+
+
+ unless ($AttachmentObj->id) {
+ Abort("Bad attachment id. Couldn't find attachment '$attach'\n");
+ }
+ unless ($AttachmentObj->TransactionId() == $trans ) {
+ Abort("Bad transaction number for attachment. $trans should be".$AttachmentObj->TransactionId() ."\n");
+
+ }
+
+ my $content_type = $AttachmentObj->ContentType || 'text/plain';
+
+ unless ($RT::TrustHTMLAttachments) {
+ $content_type = 'text/plain' if ($content_type =~ /^text\/html/i);
+ }
+
+ if (my $enc = $AttachmentObj->OriginalEncoding) {
+ # normalize Encode.pm convention with IANA ones
+ $enc = 'big5' if $enc eq 'big5-eten';
+ $enc = 'utf-8' if $enc eq 'utf8';
+ $content_type .= ";charset=$enc";
+ }
+
+ # unless ($RT::TrustMIMEAttachments) {
+ # $content_type = 'application/octet-stream';
+ # }
+
+ $r->content_type( $content_type );
+ $m->clear_buffer();
+ $m->out($AttachmentObj->OriginalContent);
+ $m->abort;
+</%perl>
+<%attr>
+AutoFlush => 0
+</%attr>
diff --git a/rt/html/Ticket/Create.html b/rt/html/Ticket/Create.html
new file mode 100644
index 000000000..2061b3be3
--- /dev/null
+++ b/rt/html/Ticket/Create.html
@@ -0,0 +1,405 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header,
+ Title => loc("Create a new ticket"),
+ onload => "hide(document.getElementById('Ticket-Create-details'));" &>
+<& /Elements/Tabs,
+ current_toptab => "Ticket/Create.html",
+ Title => loc("Create a new ticket"),
+ actions => $actions &>
+<& /Elements/ListActions, actions => \@results &>
+<form action="<%$RT::WebPath%>/Ticket/Create.html" method="post" enctype="multipart/form-data" name="TicketCreate">
+<input type="hidden" class="hidden" name="id" value="new" />
+<& /Elements/Callback, _CallbackName => 'FormStart',ARGSRef =>\%ARGS &>
+
+<div id="Ticket-Create-basics">
+<a name="basics"></a>
+<&| /Widgets/TitleBox, title => loc("Create a new ticket") &>
+<table border="0" cellpadding="0" cellspacing="0">
+<tr><td class="label"><&|/l&>Queue</&>:</td>
+<td class="value"><& Elements/ShowQueue, QueueObj => $QueueObj &>
+<input type="hidden" class="hidden" name="Queue" value="<% $QueueObj->Name %>" />
+</td>
+<td class="label"><&|/l&>Status</&>:
+</td>
+<td class="value">
+<& /Elements/SelectStatus, Name => "Status", Default => $ARGS{Status}||'new', DefaultValue => 0 &>
+</td>
+<td class="label">
+<&|/l&>Owner</&>:
+</td>
+<td class="value">
+<& /Elements/SelectOwner, Name => "Owner", QueueObj => $QueueObj, Default => $ARGS{Owner}||$RT::Nobody->Id, DefaultValue => 0 &>
+</td>
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Requestors</&>:
+</td>
+<td class="value" colspan="5">
+<input name="Requestors" value="<% ($ARGS{Requestors}) || $session{CurrentUser}->EmailAddress %>" size="40" />
+</td>
+</tr>
+<tr>
+<td class="labeltop">
+<&|/l&>Cc</&>:
+</td>
+<td class="value" colspan="5">
+<input name="Cc" size="40" value="<% $ARGS{Cc} %>" /><br />
+<i><font size="-2">
+<&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of email addresses. These people <strong>will</strong> receive future updates.)</&></font></i>
+</td>
+</tr>
+<tr>
+<td class="labeltop">
+<&|/l&>Admin Cc</&>:
+</td>
+<td class="value" colspan="5">
+<input name="AdminCc" size="40" value="<% $ARGS{AdminCc} %>" /><br />
+<i><font size="-2">
+<&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of administrative email addresses. These people <strong>will</strong> receive future updates.)</&></font></i>
+</td>
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Subject</&>:
+</td>
+<td class="value" colspan="5">
+<input name="Subject" size="60" maxsize="200" value="<%$ARGS{Subject} || ''%>" />
+</td>
+</tr>
+<tr>
+<td colspan="6">
+<& /Ticket/Elements/EditCustomFields, QueueObj => $QueueObj &>
+</td>
+</tr>
+% if ($TxnCFs->Count) {
+% while (my $CF = $TxnCFs->Next()) {
+<tr>
+<td align="right"><% $CF->Name %>:</td>
+<td><& /Elements/EditCustomField, CustomField => $CF, NamePrefix =>
+ "Object-RT::Transaction--CustomField-" &><em><% $CF->FriendlyType %></em></td>
+</td></tr>
+% }
+% }
+<tr>
+% if (exists $session{'Attachments'}) {
+<td class="label">
+<&|/l&>Attached file</&>:
+</td>
+<td colspan="5">
+<&|/l&>Check box to delete</&><br />
+% foreach my $attach_name (keys %{$session{'Attachments'}}) {
+<input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1" /><%$attach_name%><br />
+% } # end of foreach
+</td>
+</tr>
+<tr>
+% } # end of if
+<td>
+<&|/l&>Attach file</&>:
+</td>
+<td class="value" colspan="5">
+<input type="file" name="Attach" />
+<input type="submit" class="button" name="AddMoreAttach" value="<&|/l&>Add More Files</&>" />
+</td>
+</tr>
+<tr>
+<td colspan="6">
+<&|/l&>Describe the issue below</&>:<br />
+% if (exists $ARGS{Content}) {
+<& /Elements/MessageBox, Default => $ARGS{Content}, IncludeSignature => 0 &>
+% } else {
+<& /Elements/MessageBox, QuoteTransaction => $QuoteTransaction &>
+%}
+
+<br />
+</td>
+</tr>
+<tr>
+<td align="right" colspan="2">
+</td>
+</tr>
+</table>
+</&>
+<& /Elements/Submit, Label => loc("Create")&>
+</div>
+
+<div id="Ticket-Create-details">
+<a name="details"></a>
+<table width="100%" border="0">
+<tr>
+<td width="50%" valign="top">
+
+ <&| /Widgets/TitleBox, title => loc('The Basics'),
+ title_class=> 'inverse',
+ color => "#993333" &>
+<table border="0">
+<tr><td align="right"><&|/l&>Priority</&>:</td><td><input size="3" name="InitialPriority" value="<% $ARGS{InitialPriority} ? $ARGS{InitialPriority} : $QueueObj->InitialPriority %>" /></td></tr>
+<tr><td align="right"><&|/l&>Final Priority</&>:</td><td><input size="3" name="FinalPriority" value="<% $ARGS{FinalPriority} ? $ARGS{FinalPriority} : $QueueObj->FinalPriority %>" /></td></tr>
+<tr><td align="right"><&|/l&>Time Estimated</&>:</td>
+<td>
+<input size="3" name="TimeEstimated" value="<%$ARGS{TimeEstimated}%>" />
+<& /Elements/SelectTimeUnits, Name =>'TimeEstimated' &>
+
+</td></tr>
+<tr><td align="right"><&|/l&>Time Worked</&>:</td>
+<td>
+<input size="3" name="TimeWorked" value="<%$ARGS{TimeWorked}%>" />
+<& /Elements/SelectTimeUnits, Name =>'TimeWorked' &>
+
+</td></tr>
+<tr>
+<td align="right"><&|/l&>Time Left</&>:</td>
+<td><input size="3" name="TimeLeft" value="<%$ARGS{TimeLeft}%>" />
+<& /Elements/SelectTimeUnits, Name =>'TimeLeft' &>
+</td></tr>
+</table>
+</&>
+<br />
+<&|/Widgets/TitleBox, title => loc("Dates"),
+ title_class=> 'inverse',
+ color => "#663366" &>
+
+<table>
+<tr><td class="label"><&|/l&>Starts</&>:</td><td><& /Elements/SelectDate, Name => "Starts", Default => $ARGS{Starts} || '' &></td></tr>
+<tr><td class="label"><&|/l&>Due</&>:</td><td><& /Elements/SelectDate, Name => "Due", Default => $ARGS{Due} || '' &></td></tr>
+</table>
+</&>
+<br />
+</td>
+
+<td valign="top">
+<&| /Widgets/TitleBox, title => loc('Links'), title_class=> 'inverse' &>
+
+<em><&|/l&>(Enter ticket ids or URLs, separated with spaces)</&></em>
+<table border="0">
+<tr><td align="right"><&|/l&>Depends on</&></td><td><input size="10" name="new-DependsOn" value="<% $ARGS{'new-DependsOn'} %>" /></td></tr>
+<tr><td align="right"><&|/l&>Depended on by</&></td><td><input size="10" name="DependsOn-new" value="<% $ARGS{'DependsOn-new'} %>" /></td></tr>
+<tr><td align="right"><&|/l&>Parents</&></td><td><input size="10" name="new-MemberOf" value="<% $ARGS{'new-MemberOf'} %>" /></td></tr>
+<tr><td align="right"><&|/l&>Children</&></td><td><input size="10" name="MemberOf-new" value="<% $ARGS{'MemberOf-new'} %>" /></td></tr>
+<tr><td align="right"><&|/l&>Refers to</&></td><td><input size="10" name="new-RefersTo" value="<% $ARGS{'new-RefersTo'} %>" /></td></tr>
+<tr><td align="right"><&|/l&>Referred to by</&></td><td><input size="10" name="RefersTo-new" value="<% $ARGS{'RefersTo-new'} %>" /></td></tr>
+
+
+</table>
+</&>
+<br />
+
+</td>
+</tr>
+</table>
+<& /Elements/Submit, Label => loc("Create") &>
+</div>
+</form>
+
+<%INIT>
+
+my $CloneTicketObj;
+if ( $CloneTicket ) {
+ $CloneTicketObj = RT::Ticket->new( $session{CurrentUser} );
+ $CloneTicketObj->Load($CloneTicket) or Abort(loc("Ticket could not be loaded"));
+
+ my $clone = {
+ Requestors => join( ',', $CloneTicketObj->RequestorAddresses ),
+ Cc => join( ',', $CloneTicketObj->CcAddresses),
+ AdminCc => join( ',', $CloneTicketObj->AdminCcAddresses),
+ InitialPriority => $CloneTicketObj->Priority,
+ };
+
+ $clone->{$_} = $CloneTicketObj->$_()
+ for qw/Owner Subject FinalPriority TimeEstimated TimeWorked
+ Status TimeLeft Starts Started Due Resolved/;
+
+ my $members = $CloneTicketObj->Members;
+ my ( @members, @members_of, @refers, @refers_by, @depends, @depends_by );
+ while ( my $member = $members->Next ) {
+ push @members, $member->LocalBase;
+ }
+ $clone->{'MemberOf-new'} = join ' ', @members;
+
+ my $members_of = $CloneTicketObj->MemberOf;
+ while ( my $member_of = $members_of->Next ) {
+ push @members_of, $member_of->LocalTarget;
+ }
+ $clone->{'new-MemberOf'} = join ' ', @members_of;
+
+ my $refers = $CloneTicketObj->RefersTo;
+ while ( my $refer = $refers->Next ) {
+ push @refers, $refer->LocalTarget;
+ }
+ $clone->{'new-RefersTo'} = join ' ', @refers;
+
+ my $refers_by = $CloneTicketObj->ReferredToBy;
+ while ( my $refer_by = $refers_by->Next ) {
+ push @refers_by, $refer_by->LocalBase;
+ }
+ $clone->{'RefersTo-new'} = join ' ', @refers_by;
+
+ my $depends = $CloneTicketObj->DependsOn;
+ while ( my $depend = $depends->Next ) {
+ push @depends, $depend->LocalTarget;
+ }
+ $clone->{'new-DependsOn'} = join ' ', @depends;
+
+ my $depends_by = $CloneTicketObj->DependedOnBy;
+ while ( my $depend_by = $depends_by->Next ) {
+ push @depends_by, $depend_by->LocalBase;
+ }
+ $clone->{'DependsOn-new'} = join ' ', @depends_by;
+
+
+
+ my $cfs = $CloneTicketObj->QueueObj->TicketCustomFields();
+ while ( my $cf = $cfs->Next ) {
+ my $cf_id = $cf->id;
+ my $cf_values = $CloneTicketObj->CustomFieldValues( $cf->id );
+ my @cf_values;
+ while ( my $cf_value = $cf_values->Next ) {
+ push @cf_values, $cf_value->Content;
+ }
+ $clone->{"Object-RT::Ticket--CustomField-$cf_id-Value"}
+ = join "\n", @cf_values;
+ }
+
+ for ( keys %$clone ) {
+ $ARGS{$_} = $clone->{$_} if not defined $ARGS{$_};
+ }
+
+}
+
+my @results;
+my $QueueObj = new RT::Queue($session{'CurrentUser'});
+$QueueObj->Load($Queue) || Abort(loc("Queue could not be loaded."));
+my $CFs = $QueueObj->TicketCustomFields();
+my $TxnCFs = $QueueObj->TicketTransactionCustomFields();
+
+my $ValidCFs = $m->comp(
+ '/Elements/ValidateCustomFields',
+ CustomFields => $CFs,
+ ARGSRef => \%ARGS
+);
+
+# if no due date has been set explicitly, then use the
+# queue's default if it exists
+if ($QueueObj->DefaultDueIn && !$ARGS{'Due'}) {
+ my $default_due = RT::Date->new($session{'CurrentUser'});
+ $default_due->SetToNow();
+ $default_due->AddDays($QueueObj->DefaultDueIn);
+ $ARGS{'Due'} = $default_due->ISO();
+}
+
+# {{{ deal with deleting uploaded attachments
+foreach my $key (keys %ARGS) {
+ if ($key =~ m/^DeleteAttach-(.+)$/) {
+ delete $session{'Attachments'}{$1};
+ }
+ $session{'Attachments'} = { %{$session{'Attachments'} || {}} };
+}
+
+# {{{ store the uploaded attachment in session
+if ($ARGS{'Attach'}) { # attachment?
+ $session{'Attachments'} = {} unless defined $session{'Attachments'};
+
+ my $subject = "$ARGS{'Attach'}";
+
+ # strip leading directories
+ $subject =~ s#^.*[\\/]##;
+
+ my $attachment = MakeMIMEEntity(
+ Subject => $subject,
+ Body => "",
+ AttachmentFieldName => 'Attach'
+ );
+
+ $session{'Attachments'} = { %{$session{'Attachments'} || {}},
+ $ARGS{'Attach'} => $attachment };
+}
+# }}}
+
+# delete temporary storage entry to make WebUI clean
+unless (keys %{$session{'Attachments'}} and $ARGS{'id'} eq 'new') {
+ delete $session{'Attachments'};
+}
+
+
+# }}}
+
+if ((!exists $ARGS{'AddMoreAttach'}) and ($ARGS{'id'} eq 'new')) { # new ticket?
+ if ($ValidCFs) {
+ $m->comp('Display.html', %ARGS);
+ $RT::Logger->crit("After display call; error is $@");
+ $m->abort();
+ }
+ else {
+ # Invalid CFs
+ while (my $CF = $CFs->Next) {
+ my $msg = $m->notes('InvalidField-' . $CF->Id) or next;
+ push @results, $CF->Name . ': ' . $msg;
+ }
+ }
+}
+
+my $actions = {
+ A => {
+ html => q[<a href="#basics" onclick="return switchVisibility('Ticket-Create-basics','Ticket-Create-details');">] . loc('Show basics') . q[</a>],
+ },
+ B => {
+ html => q[<a href="#details" onclick="return switchVisibility('Ticket-Create-details','Ticket-Create-basics');">] . loc('Show details') . q[</a>],
+ },
+};
+</%INIT>
+
+<%ARGS>
+$DependsOn => undef
+$DependedOnBy => undef
+$MemberOf => undef
+$QuoteTransaction => undef
+$Queue => undef
+$CloneTicket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Display.html b/rt/html/Ticket/Display.html
new file mode 100644
index 000000000..17d00a00c
--- /dev/null
+++ b/rt/html/Ticket/Display.html
@@ -0,0 +1,182 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header,
+ Title => loc("#[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $TicketObj,
+ current_tab => 'Ticket/Display.html?id='.$TicketObj->id,
+ Title => loc("#[_1]: [_2]", $TicketObj->Id, $TicketObj->Subject) &>
+
+<& /Elements/ListActions, actions => \@Actions &>
+<& /Elements/Callback, _CallbackName => 'BeforeShowSummary', Ticket => $TicketObj, %ARGS &>
+<&| /Widgets/TitleBox, title => loc('Ticket metadata') &>
+<& /Ticket/Elements/ShowSummary, Ticket => $TicketObj, Attachments => $attachments &>
+</&>
+
+<br />
+
+<& /Elements/Callback, _CallbackName => 'BeforeShowHistory', Ticket => $TicketObj, %ARGS &>
+
+<& /Ticket/Elements/ShowHistory ,
+ Ticket => $TicketObj,
+ Tickets => $Tickets,
+ Collapsed => $ARGS{'Collapsed'},
+ ShowHeaders => $ARGS{'ShowHeaders'},
+ Attachments => $attachments,
+ AttachmentContent => $attachment_content
+
+ &>
+
+<& /Elements/Callback, _CallbackName => 'AfterShowHistory', Ticket => $TicketObj,
+current_tab => 'Ticket/Display.html?id=' . $TicketObj->id, %ARGS &>
+
+<%ARGS>
+$id => undef
+$Create => undef
+$ShowHeaders => 0
+$Collapsed => undef
+$TicketObj => undef
+</%ARGS>
+
+<%INIT>
+
+$m->comp('/Elements/Callback', _CallbackName => 'Initial', TicketObj => $TicketObj, ARGSRef => \%ARGS);
+
+my ($linkid, $message, $tid, @Actions, $Tickets);
+
+unless ($id || $TicketObj) {
+ Abort('No ticket specified');
+}
+
+if ($ARGS{'id'} eq 'new') {
+ # {{{ Create a new ticket
+
+ my $Queue = new RT::Queue($session{'CurrentUser'});
+ unless ($Queue->Load($ARGS{'Queue'})) {
+ Abort('Queue not found');
+ }
+
+ unless ($Queue->CurrentUserHasRight('CreateTicket')) {
+ Abort('You have no permission to create tickets in that queue.');
+ }
+ ($TicketObj, @Actions) =
+ CreateTicket(Attachments => $session{'Attachments'}, %ARGS);
+ delete $session{'Attachments'};
+ unless ($TicketObj->CurrentUserHasRight('ShowTicket')) {
+ Abort("No permission to view newly created ticket #".$TicketObj->id.".");
+ }
+ # }}}
+} else {
+ if (!$TicketObj) {
+
+ $TicketObj = RT::Ticket->new($session{'CurrentUser'});
+
+ $TicketObj = LoadTicket($ARGS{'id'});
+ unless ($TicketObj->CurrentUserHasRight('ShowTicket')) {
+ Abort("No permission to view ticket");
+ }
+ }
+
+ $m->comp('/Elements/Callback', _CallbackName => 'BeforeProcessArguments',
+ TicketObj => $TicketObj, Tickets => $Tickets,
+ ActionsRef => \@Actions, ARGSRef => \%ARGS);
+
+ if (defined $ARGS{'Action'}) {
+ if ($ARGS{'Action'} =~ /^(Steal|Kill|Take|SetTold)$/) {
+ my $action = $1;
+ my ($res, $msg)=$TicketObj->$action();
+ push(@Actions, $msg);
+ }
+ }
+
+ $ARGS{'UpdateContent'} =~ s/\r\n/\n/g if defined $ARGS{'UpdateContent'};
+ if ( $ARGS{'UpdateTimeWorked'} || (
+ defined $ARGS{'UpdateContent'}
+ && $ARGS{'UpdateContent'} ne ''
+ && $ARGS{'UpdateContent'} ne "-- \n"
+ . $session{'CurrentUser'}->UserObj->Signature ) )
+ {
+ $ARGS{UpdateAttachments} = $session{'Attachments'};
+ ProcessUpdateMessage(
+ ARGSRef => \%ARGS,
+ Actions => \@Actions,
+ TicketObj => $TicketObj,
+ );
+ delete $session{'Attachments'};
+ }
+ #Process status updates
+ my @PeopleActions = ProcessTicketWatchers(ARGSRef => \%ARGS, TicketObj=>$TicketObj);
+ my @BasicActions = ProcessTicketBasics(ARGSRef => \%ARGS, TicketObj=>$TicketObj);
+ my @results = ProcessTicketLinks( TicketObj => $TicketObj, ARGSRef => \%ARGS);
+
+ push (@Actions, @PeopleActions, @BasicActions, @results);
+}
+
+$m->comp('/Elements/Callback', _CallbackName => 'BeforeDisplay',
+ TicketObj => \$TicketObj,
+ Tickets => \$Tickets,
+ Actions => \@Actions,
+ ARGSRef => \%ARGS,
+);
+
+# This code does automatic redirection if any updates happen.
+
+if (@Actions) {
+ # We've done something, so we need to clear the decks to avoid
+ # resubmission on refresh.
+ # But we need to store Actions somewhere too, so we don't lose them.
+ $session{"Actions"} = \@Actions;
+ RT::Interface::Web::Redirect($RT::WebURL."Ticket/Display.html?id=".$TicketObj->id);
+} else {
+ @Actions = @{ delete $session{"Actions"} || [] };
+}
+
+my $attachments = $m->comp('Elements/FindAttachments', Ticket => $TicketObj, Tickets => $Tickets);
+my $attachment_content = $m->comp('Elements/LoadTextAttachments', Ticket => $TicketObj);
+
+</%INIT>
diff --git a/rt/html/Ticket/Elements/AddCustomers b/rt/html/Ticket/Elements/AddCustomers
new file mode 100644
index 000000000..e04c07702
--- /dev/null
+++ b/rt/html/Ticket/Elements/AddCustomers
@@ -0,0 +1,52 @@
+%# Copyright (c) 2004 Ivan Kohler <ivan-rt@420.am>
+%# Copyright (c) 2008 Freeside Internet Services, Inc.
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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.
+<BR>
+<%$msg%><br>
+
+% if (@Customers) {
+
+<br><i>(Check box to link)<i>
+<table>
+% foreach my $customer (@Customers) {
+<tr>
+ <td>
+ <input type="checkbox" name="Ticket-AddCustomer-<% $customer->{'custnum'} %>" VALUE="1" <% scalar(@Customers) == 1 ? 'CHECKED' : '' %>>
+ <A HREF="<%$freeside_url%>/view/cust_main.cgi?<% $customer->{'custnum'} %>"><% &RT::URI::freeside::small_custview($customer->{'custnum'}, &RT::URI::freeside::FreesideGetConfig('countrydefault'), 1) |n %>
+ </td>
+</tr>
+% }
+</table>
+
+% }
+
+<%INIT>
+my ($msg);
+
+my $freeside_url = &RT::URI::freeside::FreesideURL();
+
+my @Customers = ();
+if ( $CustomerString ) {
+ @Customers = &RT::URI::freeside::smart_search( 'search' => $CustomerString );
+}
+
+my @Services = ();
+if ($ServiceString) {
+ @Services = (); #service_search();
+}
+
+</%INIT>
+
+<%ARGS>
+$CustomerString => undef
+$ServiceString => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/AddWatchers b/rt/html/Ticket/Elements/AddWatchers
new file mode 100644
index 000000000..891ff95b5
--- /dev/null
+++ b/rt/html/Ticket/Elements/AddWatchers
@@ -0,0 +1,123 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<br />
+<%$msg%><br />
+
+<&|/l&>Add new watchers</&>:<br />
+
+<table>
+% if ($Users and $Users->Count) {
+<tr><td>
+<&|/l&>Type</&>
+</td><td>
+<&|/l&>Username</&>
+</td></tr>
+% while (my $u = $Users->Next ) {
+<tr><td><&/Elements/SelectWatcherType, Name => "Ticket-AddWatcher-Principal-".$u->PrincipalId &></td><td><%$u->Name%> (<%$u->RealName%>)</td></tr>
+% }
+% }
+
+% if ($Groups and $Groups->Count) {
+<tr><td>
+<&|/l&>Type</&>
+</td><td>
+<&|/l&>Group</&>
+</td></tr>
+% while (my $g = $Groups->Next ) {
+<tr><td><&/Elements/SelectWatcherType, Name => "Ticket-AddWatcher-Principal-".$g->PrincipalId, Scope => 'queue' &></td><td><%$g->Name%> (<%$g->Description%>)</td></tr>
+% }
+% }
+
+<tr><td>
+<&|/l&>Type</&>
+</td><td>
+<&|/l&>Email</&>
+</td></tr>
+<tr><td>
+<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail1" &>
+</td><td>
+<input name="WatcherAddressEmail1" size="15" />
+</td></tr>
+<tr><td>
+<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail2" &>
+</td><td>
+<input name="WatcherAddressEmail2" size="15" />
+</td></tr>
+<tr><td>
+<&/Elements/SelectWatcherType, Name => "WatcherTypeEmail3" &>
+</td><td>
+<input name="WatcherAddressEmail3" size="15" />
+</td></tr>
+</table>
+
+<%INIT>
+my ($msg, $Users, $Groups);
+
+if ($UserString) {
+ $Users = RT::Users->new($session{'CurrentUser'});
+ $Users->Limit(FIELD => $UserField, VALUE => $UserString, OPERATOR => $UserOp);
+ $Users->LimitToPrivileged if $PrivilegedOnly;
+ }
+
+if ($GroupString) {
+ $Groups = RT::Groups->new($session{'CurrentUser'});
+ $Groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined');
+ $Groups->Limit(FIELD => $GroupField, VALUE => $GroupString, OPERATOR => $GroupOp);
+ }
+
+</%INIT>
+
+<%ARGS>
+$UserField => 'Name'
+$UserOp => '='
+$UserString => undef
+$GroupField => 'Name'
+$GroupOp => '='
+$GroupString => undef
+$PrivilegedOnly => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/BulkLinks b/rt/html/Ticket/Elements/BulkLinks
new file mode 100644
index 000000000..e449b18d8
--- /dev/null
+++ b/rt/html/Ticket/Elements/BulkLinks
@@ -0,0 +1,77 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table>
+ <tr>
+ <td class="label"><&|/l&>Merge into</&>:</td>
+ <td class="entry"><input name="Ticket-MergeInto" /> <i><&|/l&>(only one ticket)</&></i></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Depends on</&>:</td>
+ <td class="entry"><input name="Ticket-DependsOn" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Depended on by</&>:</td>
+ <td class="entry"><input name="DependsOn-Ticket" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Parents</&>:</td>
+ <td class="entry"><input name="Ticket-MemberOf" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Children</&>:</td>
+ <td class="entry"> <input name="MemberOf-Ticket" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Refers to</&>:</td>
+ <td class="entry"><input name="Ticket-RefersTo" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Referred to by</&>:</td>
+ <td class="entry"> <input name="RefersTo-Ticket" /></td>
+ </tr>
+</table>
diff --git a/rt/html/Ticket/Elements/EditBasics b/rt/html/Ticket/Elements/EditBasics
new file mode 100644
index 000000000..d68fe6522
--- /dev/null
+++ b/rt/html/Ticket/Elements/EditBasics
@@ -0,0 +1,117 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table>
+ <tr>
+ <td class="label"><&|/l&>Subject</&>:</td>
+ <td class="value"><input name="Subject" value="<%$TicketObj->Subject|h%>" size="50" /></td>
+ </tr>
+
+ <tr>
+ <td class="label"><&|/l&>Status</&>:</td>
+ <td class="value"><%$SelectStatus|n%></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Queue</&>:</td>
+ <td class="value"><%$SelectQueue|n%></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Owner</&>:</td>
+ <td class="value"><& /Elements/SelectOwner,
+ Name => 'Owner',
+ QueueObj => $TicketObj->QueueObj,
+ TicketObj => $TicketObj,
+ Default => $TicketObj->OwnerObj->Id,
+ DefaultValue => 0,
+ &></td>
+ </tr>
+
+ <tr>
+ <td class="label"><&|/l&>Time Estimated</&>:</td>
+ <td class="value"><input name="TimeEstimated" value="<%$TicketObj->TimeEstimated|h%>" size="5" />
+ <& /Elements/SelectTimeUnits, Name =>'TimeEstimated' &>
+</td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Time Worked</&>:</td>
+ <td class="value"><input name="TimeWorked" value="<%$TicketObj->TimeWorked|h%>" size="5" />
+ <& /Elements/SelectTimeUnits, Name =>'TimeWorked' &>
+</td>
+
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Time Left</&>:</td>
+ <td class="value"><input name="TimeLeft" value="<%$TicketObj->TimeLeft|h%>" size="5" />
+ <& /Elements/SelectTimeUnits, Name =>'TimeLeft' &>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="label"><&|/l&>Priority</&>:</td>
+ <td class="value"><input name="Priority" value="<%$TicketObj->Priority|h%>" size="5" /></td>
+ </tr>
+
+ <tr>
+ <td class="label"><&|/l&>Final Priority</&>:</td>
+ <td class="value"><input name="FinalPriority" value="<%$TicketObj->FinalPriority|h%>" size="5" /></td>
+ </tr>
+
+
+
+<& /Elements/Callback, _CallbackName => 'EndOfList', TicketObj => $TicketObj, %ARGS &>
+</table>
+
+<%INIT>
+#It's hard to do this inline, so we'll preload the html of the selectstatus in here.
+my $SelectStatus = $m->scomp("/Elements/SelectStatus", Name => 'Status', DefaultLabel => loc("[_1] (Unchanged)",loc($TicketObj->Status)));
+my $SelectQueue = $m->scomp("/Elements/SelectQueue", Name => 'Queue', Default =>$TicketObj->QueueObj->Id);
+
+</%INIT>
+<%ARGS>
+
+$TicketObj => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/EditCustomField b/rt/html/Ticket/Elements/EditCustomField
new file mode 100644
index 000000000..fff3925aa
--- /dev/null
+++ b/rt/html/Ticket/Elements/EditCustomField
@@ -0,0 +1,57 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+
+# RT 3.2 API compatibility glue
+
+$RT::Logger->debug("Ticket/Elements/EditCustomField is deprecated in RT 3.4 and will be removed in 3.6.");
+
+$ARGS{'NamePrefix'} =~ s/^Ticket-/Object-RT::Ticket-/;
+$ARGS{'NamePrefix'} =~ s/^CustomField-/Object-RT::Ticket--CustomField-/;
+$m->comp('/Elements/EditCustomField', %ARGS, Object=> $ARGS{'TicketObj'});
+</%init>
diff --git a/rt/html/Ticket/Elements/EditCustomFields b/rt/html/Ticket/Elements/EditCustomFields
new file mode 100644
index 000000000..04d7180af
--- /dev/null
+++ b/rt/html/Ticket/Elements/EditCustomFields
@@ -0,0 +1,110 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table>
+% my $i = 0;
+% while ( my $CustomField = $CustomFields->Next ) {
+% next unless $CustomField->CurrentUserHasRight('ModifyCustomField');
+% $i++;
+% if ( $i % 2 ) {
+<tr>
+% }
+<td width="50%">
+<table>
+ <tr id="CF-<%$CustomField->id%>-EditRow">
+ <td class="labeltop">
+ <b><%$CustomField->Name%></b><br />
+ <i><%$CustomField->FriendlyType%></i>
+ </td>
+ <td class="entry"><& /Elements/EditCustomField,
+ Object => $TicketObj,
+ CustomField => $CustomField,
+ NamePrefix => $NamePrefix ,
+ Default => $m->notes('Field-' . $CustomField->Id),
+ &>
+% if (my $msg = $m->notes('InvalidField-' . $CustomField->Id)) {
+ <br />
+ <em style="color: red"><% $msg %></em>
+% }
+ </td>
+ </tr>
+</table>
+</td>
+
+% unless ( $i % 2 ) {
+</tr>
+% }
+
+% }
+
+%# close row if required
+% if ( $i % 2 ) {
+</tr>
+% }
+
+</table>
+<%INIT>
+my $CustomFields;
+my $NamePrefix;
+
+if ($TicketObj) {
+ $CustomFields = $TicketObj->CustomFields();
+ $NamePrefix = "Object-RT::Ticket-".$TicketObj->Id."-CustomField-";
+
+} else {
+ $CustomFields = $QueueObj->TicketCustomFields();
+ $NamePrefix = "Object-RT::Ticket--CustomField-";
+}
+
+ $m->comp('/Elements/Callback', _CallbackName => 'MassageCustomFields',
+ CustomFields => $CustomFields);
+
+</%INIT>
+<%ARGS>
+$TicketObj => undef
+$QueueObj => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/EditCustomers b/rt/html/Ticket/Elements/EditCustomers
new file mode 100644
index 000000000..0ba6e447b
--- /dev/null
+++ b/rt/html/Ticket/Elements/EditCustomers
@@ -0,0 +1,63 @@
+%# Copyright (c) 2004 Ivan Kohler <ivan-rt@420.am>
+%# Copyright (c) 2008 Freeside Internet Services, Inc.
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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.
+<TABLE width=100%>
+ <TR>
+ <TD VALIGN=TOP WIDTH=50%>
+ <h3><&|/l&>Current Customers</&></h3>
+
+<table>
+ <tr>
+ <td><i><&|/l&>(Check box to disassociate)</&></i></td>
+ </tr>
+ <tr>
+ <td class="value">
+% foreach my $link ( @{ $Ticket->Customers->ItemsArrayRef } ) {
+
+ <INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>">
+%# <& ShowLink, URI => $link->TargetURI &><br>
+ <A HREF="<% $link->TargetURI->Resolver->HREF %>"><% $link->TargetURI->Resolver->AsStringLong |n %></A>
+ <BR>
+% }
+ </td>
+ </tr>
+</table>
+
+</TD>
+
+<TD VALIGN=TOP>
+<h3><&|/l&>New Customer Links</&></h3>
+<&|/l&>Find customer</&><BR>
+<input name="CustomerString">
+<input type=submit name="OnlySearchForCustomers" value="<&|/l&>Go!</&>">
+<br><i>cust #, name, company or phone</i>
+<BR>
+%#<BR>
+%#<&|/l&>Find service</&><BR>
+%#<input name="ServiceString">
+%#<input type=submit name="OnlySearchForServices" value="<&|/l&>Go!</&>">
+%#<br><i>username, username@domain, domain, or IP address</i>
+%#<BR>
+
+<& AddCustomers, Ticket => $Ticket,
+ CustomerString => $CustomerString,
+ ServiceString => $ServiceString, &>
+
+</TD>
+</TR>
+</TABLE>
+
+<%ARGS>
+$CustomerString => undef
+$ServiceString => undef
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/EditDates b/rt/html/Ticket/Elements/EditDates
new file mode 100644
index 000000000..f694506d0
--- /dev/null
+++ b/rt/html/Ticket/Elements/EditDates
@@ -0,0 +1,77 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table>
+ <tr>
+ <td class="label"><&|/l&>Starts</&>:</td>
+ <td class="entry"><& /Elements/SelectDate, menu_prefix => 'Starts', current => 0 &>
+ (<% $TicketObj->StartsObj->AsString %>)</td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Started</&>:</td>
+ <td class="entry"><& /Elements/SelectDate, menu_prefix => 'Started', current => 0 &> (<%$TicketObj->StartedObj->AsString %>)</td>
+ </tr>
+
+ <tr>
+ <td class="label">
+ <&|/l&>Last Contact</&>:
+ </td>
+ <td class="entry">
+ <& /Elements/SelectDate, menu_prefix => 'Told', current => 0 &> (<% $TicketObj->ToldObj->AsString %>)
+ </td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Due</&>:</td>
+ <td class="entry">
+ <& /Elements/SelectDate, menu_prefix => 'Due', current => 0 &> (<% $TicketObj->DueObj->AsString %>)
+ </td>
+ </tr>
+</table>
+<%ARGS>
+$TicketObj => undef
+</%ARGS>
+
diff --git a/rt/html/Ticket/Elements/EditPeople b/rt/html/Ticket/Elements/EditPeople
new file mode 100644
index 000000000..fd23ae0d6
--- /dev/null
+++ b/rt/html/Ticket/Elements/EditPeople
@@ -0,0 +1,93 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table width="100%">
+<tr>
+<td valign="top">
+
+<h3><&|/l&>New watchers</&></h3>
+<&|/l&>Find people whose</&><br />
+<& /Elements/SelectUsers &>
+<input type="submit" class="button" name="OnlySearchForPeople" value="<&|/l&>Go!</&>" />
+<br />
+<&|/l&>Find groups whose</&><br />
+<& /Elements/SelectGroups &>
+<input type="submit" class="button" name="OnlySearchForGroup" value="<&|/l&>Go!</&>" />
+
+<& AddWatchers, Ticket => $Ticket, UserString => $UserString,
+ UserOp => $UserOp, UserField => $UserField,
+ GroupString => $GroupString, GroupOp => $GroupOp,
+ GroupField => $GroupField, PrivilegedOnly => $PrivilegedOnly &>
+</td><td valign="top">
+<h3><&|/l&>Owner</&></h3>
+<&|/l&>Owner</&>: <& /Elements/SelectOwner, Name => 'Owner', QueueObj => $Ticket->QueueObj, TicketObj => $Ticket, Default => $Ticket->OwnerObj->Id, DefaultValue => 0&>
+<h3><&|/l&>Current watchers</&></h3>
+<&|/l&>(Check box to delete)</&><br />
+
+<&|/l&>Requestors</&>:
+<& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->Requestors &>
+
+<&|/l&>Cc</&>:
+<& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->Cc &>
+
+<&|/l&>Administrative Cc</&>:
+<& EditWatchers, TicketObj => $Ticket, Watchers => $Ticket->AdminCc &>
+
+</td>
+</tr>
+</table>
+
+<%ARGS>
+$UserField => undef
+$UserOp => undef
+$UserString => undef
+$GroupField => undef
+$GroupOp => undef
+$GroupString => undef
+$PrivilegedOnly => undef
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/EditWatchers b/rt/html/Ticket/Elements/EditWatchers
new file mode 100644
index 000000000..918dddb68
--- /dev/null
+++ b/rt/html/Ticket/Elements/EditWatchers
@@ -0,0 +1,81 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<ul>
+%# Print out a placeholder if there are none.
+%if ($Members->Count == 0 ) {
+<li><i><&|/l&>none</&></i></li>
+% }
+
+
+%while (my $watcher=$Members->Next) {
+<li>
+<input type="checkbox" class="checkbox" name="Ticket-DeleteWatcher-Type-<%$Watchers->Type%>-Principal-<%$watcher->MemberId%>" value="1" unchecked />
+%if ($watcher->MemberObj->IsUser) {
+<a href="<%$RT::WebPath%>/Admin/Users/Modify.html?id=<%$watcher->MemberObj->Object->id%>">
+<%$watcher->MemberObj->Object->Name%></a>
+% if ($TicketObj and grep { $_->Content eq $watcher->MemberObj->Object->EmailAddress } $TicketObj->SquelchMailTo) {
+<b><&|/l&>(Will not be sent email)</&></b>
+% }
+
+%} else {
+<a href="<%$RT::WebPath%>/Admin/Groups/Modify.html?id=<%$watcher->MemberObj->Object->id%>">
+<%$watcher->MemberObj->Object->Name%></a>
+%}
+</li>
+% }
+</ul>
+<%INIT>
+my $Members = $Watchers->MembersObj;
+</%INIT>
+<%ARGS>
+$TicketObj => undef
+$Watchers => undef
+</%ARGS>
+
+
+
diff --git a/rt/html/Ticket/Elements/FindAttachments b/rt/html/Ticket/Elements/FindAttachments
new file mode 100755
index 000000000..a9d698d31
--- /dev/null
+++ b/rt/html/Ticket/Elements/FindAttachments
@@ -0,0 +1,95 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%INIT>
+my %documents;
+
+#A default implementation here loops through all transactions and pulls out all their attachments.
+# We end up doing an end-run around that to get a bit more performance
+
+# We force the cache of ticket transactions to get populated up front. otherwise, the
+# code that looks at attachments will look at each one in turn.
+my $attachments = RT::Attachments->new( $session{'CurrentUser'} );
+
+$attachments->Columns( qw( Id Filename ContentType Headers Subject Parent ContentEncoding ContentType TransactionId Created));
+
+my $transactions = $attachments->NewAlias('Transactions');
+$attachments->Join( ALIAS1 => 'main',
+ FIELD1 => 'TransactionId',
+ ALIAS2 => $transactions,
+ FIELD2 => 'id' );
+
+my $tickets = $attachments->NewAlias('Tickets');
+
+ $attachments->Join( ALIAS1 => $transactions,
+ FIELD1 => 'ObjectId',
+ ALIAS2 => $tickets,
+ FIELD2 => 'id' );
+
+ $attachments->Limit( ALIAS => $transactions,
+ FIELD => 'ObjectType',
+ VALUE => 'RT::Ticket');
+if ($Tickets) {
+ while ($Ticket = $Tickets->Next) {
+ $attachments->Limit( ALIAS => $tickets,
+ FIELD => 'EffectiveId',
+ VALUE => $Ticket->id() );
+ }
+} else {
+ $attachments->Limit( ALIAS => $tickets,
+ FIELD => 'EffectiveId',
+ VALUE => $Ticket->id() );
+}
+
+
+return ($attachments);
+</%INIT>
+<%ARGS>
+$Ticket => undef
+$Tickets => undef
+</%ARGS>
+
diff --git a/rt/html/Ticket/Elements/LoadTextAttachments b/rt/html/Ticket/Elements/LoadTextAttachments
new file mode 100755
index 000000000..fc83d6605
--- /dev/null
+++ b/rt/html/Ticket/Elements/LoadTextAttachments
@@ -0,0 +1,94 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%INIT>
+
+my $attachments = RT::Attachments->new( $session{'CurrentUser'} );
+
+$attachments->Columns( qw(id Content ContentType TransactionId ContentEncoding));
+
+if ( $Ticket->CurrentUserHasRight('ShowTicket') ) {
+ my $transactions = $attachments->NewAlias('Transactions');
+ $attachments->Join( ALIAS1 => 'main',
+ FIELD1 => 'TransactionId',
+ ALIAS2 => $transactions,
+ FIELD2 => 'id' );
+
+ my $tickets = $attachments->NewAlias('Tickets');
+
+
+ $attachments->Join( ALIAS1 => $transactions,
+ FIELD1 => 'ObjectId',
+ ALIAS2 => $tickets,
+ FIELD2 => 'id' );
+
+ $attachments->Limit( ALIAS => $transactions,
+ FIELD => 'ObjectType',
+ VALUE => 'RT::Ticket');
+
+
+ $attachments->Limit( ALIAS => $tickets,
+ FIELD => 'EffectiveId',
+ VALUE => $Ticket->id() );
+ # if the user may not see comments do not return them
+ unless ( $Ticket->CurrentUserHasRight('ShowTicketComments') ) {
+ $attachments->Limit( ALIAS => $transactions, FIELD => 'Type', OPERATOR => '!=', VALUE => "Comment" );
+ }
+
+ $attachments->Limit ( FIELD => 'ContentType', OPERATOR => '=', VALUE => 'text/plain');
+ $attachments->Limit ( FIELD => 'ContentType', OPERATOR => 'STARTSWITH', VALUE => 'message/');
+ $attachments->Limit ( FIELD => 'ContentType', OPERATOR => '=', VALUE => 'text');
+ if ($RT::SuppressInlineTextFiles) {
+ $attachments->Limit ( FIELD => 'Filename', OPERATOR => 'IS', VALUE => 'NULL');
+ }
+}
+return ($attachments);
+</%INIT>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
+
diff --git a/rt/html/Ticket/Elements/PreviewScrips b/rt/html/Ticket/Elements/PreviewScrips
new file mode 100755
index 000000000..423040c8e
--- /dev/null
+++ b/rt/html/Ticket/Elements/PreviewScrips
@@ -0,0 +1,133 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$TicketObj => undef
+
+</%args>
+<%init>
+
+my $arg = 'Ticket-'.$TicketObj->Id.'-SquelchMailTo';
+my @squelchto = ref($ARGS{$arg}) eq 'ARRAY' ? @{$ARGS{$arg}} : ($ARGS{$arg});
+
+foreach my $address (@squelchto) {
+ $TicketObj->SquelchMailTo($address) if ($address);
+}
+
+
+$arg = 'Ticket-'.$TicketObj->Id.'-UnsquelchMailTo';
+my @unsquelchto = ref($ARGS{$arg}) eq 'ARRAY' ? @{$ARGS{$arg}} : ($ARGS{$arg});
+
+foreach my $address (@unsquelchto) {
+ $TicketObj->UnsquelchMailTo($address) if ($address);
+}
+
+
+my $action;
+
+if (( $ARGS{'UpdateType'} eq 'response' ) || ($ARGS{'Action'} eq 'Respond' )) {
+ $action = 'Correspond';
+}
+else {
+ $action = 'Comment';
+}
+
+my $Message = MakeMIMEEntity(
+ Subject => $ARGS{'UpdateSubject'},
+ Body => $ARGS{'UpdateContent'},
+);
+
+my ( $Transaction, $Description, $Object ) = $TicketObj->$action(
+ CcMessageTo => $ARGS{'UpdateCc'},
+ BccMessageTo => $ARGS{'UpdateBcc'},
+ MIMEObj => $Message,
+ TimeTaken => $ARGS{'UpdateTimeWorked'},
+ DryRun => 1
+);
+unless ( $Transaction ) {
+ $RT::Logger->error("Coulfn't fire '$action' action: $Description");
+}
+
+
+my @non_recipients = $TicketObj->SquelchMailTo;
+</%init>
+<h2><&|/l&>This message will be sent to...</&></h2>
+
+% if ( $Object ) {
+<i><&|/l&>(Check boxes to disable notifications to the listed recipients)</&></i><br />
+% foreach my $scrip (@{$Object->Scrips->Prepared}) {
+% next unless $scrip->ActionObj->Action->isa('RT::Action::SendEmail');
+<b><% $scrip->Description %></b><br />
+<&|/l, loc($scrip->ConditionObj->Name), loc($scrip->ActionObj->Name), loc($scrip->TemplateObj->Name)&>[_1] [_2] with template [_3]</&>
+<br />
+%foreach my $type qw(To Cc Bcc) {
+%my @addresses = $scrip->ActionObj->Action->$type();
+<ul>
+%foreach my $addr (@addresses) {
+<li> <b><%loc($type)%></b>: <input type="checkbox" class="checkbox" name="Ticket-<%$TicketObj->id%>-SquelchMailTo" value="<%$addr->address%>" /> <%$addr->address%>
+% }
+</ul>
+% }
+% if ($RT::PreviewScripMessages) {
+<textarea cols="80" rows="5">
+<%$scrip->ActionObj->TemplateObj->MIMEObj->as_string%>
+</textarea>
+% }
+% }
+% }
+<br />
+
+<h2><&|/l&>Messages about this ticket will not be sent to...</&></h2>
+<i><&|/l&>(Check boxes to enable notifications to the listed recipients)</&></i>
+<br />
+<ul>
+% foreach my $recipient (@non_recipients) {
+<li><input type="checkbox" class="checkbox" name="Ticket-<%$TicketObj->id%>-UnsquelchMailTo" value="<%$recipient->Content%>" />
+<% $recipient->Content %>
+% }
+</ul>
+<& /Elements/Submit, Value => 'UpdatePreview', Label => loc('Save changes')&>
diff --git a/rt/html/Ticket/Elements/Reminders b/rt/html/Ticket/Elements/Reminders
new file mode 100644
index 000000000..63d68c7b1
--- /dev/null
+++ b/rt/html/Ticket/Elements/Reminders
@@ -0,0 +1,168 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Ticket => undef
+$id => undef
+$ShowCompleted => 0
+$Edit => 0
+</%args>
+<%init>
+
+$Ticket = LoadTicket($id) if ($id);
+
+my $request_args = $m->request_args();
+
+my $reminder_collection = $Ticket->Reminders->Collection;
+
+if ( $request_args->{'update-reminders'} ) {
+ while ( my $reminder = $reminder_collection->Next ) {
+ if ( $reminder->Status ne 'resolved' && $request_args->{ 'Complete-Reminder-' . $reminder->id } ) {
+ $Ticket->Reminders->Resolve($reminder);
+ }
+ elsif ( $reminder->Status eq 'resolved' && !$request_args->{ 'Complete-Reminder-' . $reminder->id } ) {
+ $Ticket->Reminders->Open($reminder);
+ }
+
+ if ( exists( $request_args->{ 'Reminder-Subject-' . $reminder->id } ) && ( $reminder->Subject ne $request_args->{ 'Reminder-Subject-' . $reminder->id } )) {
+ $reminder->SetSubject( $request_args->{ 'Reminder-Subject-' . $reminder->id } ) ;
+ }
+
+ if ( exists( $request_args->{ 'Reminder-Owner-' . $reminder->id } ) && ( $reminder->Owner != $request_args->{ 'Reminder-Owner-' . $reminder->id } )) {
+ $reminder->SetOwner( $request_args->{ 'Reminder-Owner-' . $reminder->id } , "Force" ) ;
+ }
+
+ if ( exists( $request_args->{ 'Reminder-Due-' . $reminder->id } ) && ( $reminder->DueObj->Date ne $request_args->{ 'Reminder-Due-' . $reminder->id } )) {
+ $reminder->SetDue( $request_args->{ 'Reminder-Due-' . $reminder->id } ) ;
+ }
+ }
+}
+
+if ( $request_args->{'NewReminder-Subject'} ) {
+ my $due_obj = RT::Date->new( $session{'CurrentUser'} );
+ my $date = Time::ParseDate::parsedate(
+ $request_args->{'NewReminder-Due'},
+ UK => $RT::DateDayBeforeMonth,
+ PREFER_PAST => 0,
+ PREFER_FUTURE => 1
+ );
+ $due_obj->Set( Value => $date, Format => 'unix' );
+ my ( $add_id, $msg, $txnid ) = $Ticket->Reminders->Add(
+
+ Subject => $request_args->{'NewReminder-Subject'},
+ Owner => $request_args->{'NewReminder-Owner'},
+ Due => $due_obj->ISO
+ );
+}
+
+# We've made changes, let's reload our search
+
+$reminder_collection = $Ticket->Reminders->Collection;
+</%init>
+<input type="hidden" class="hidden" name="id" value="<% $Ticket->id %>" />
+<input type="hidden" class="hidden" name="update-reminders" value="1" />
+<div>
+% while (my $reminder = $reminder_collection->Next) {
+% if ($reminder->Status eq 'resolved' && !$ShowCompleted) {
+<input type="hidden" class="hidden" name="Complete-Reminder-<% $reminder->id %>" value="1" />
+% } elsif ($Edit) {
+<& SELF:EditEntry, Reminder => $reminder, Ticket => $Ticket &>
+% } else {
+<& SELF:ShowEntry, Reminder => $reminder, Ticket => $Ticket &>
+% }
+% }
+</div>
+<div>
+<h3><&|/l&>New reminder:</&></h3>
+<& SELF:NewReminder, Ticket => $Ticket &>
+<%method NewReminder>
+<%args>
+$Ticket
+</%args>
+<div class="input-row">
+<label class="horizontal" for="NewReminder-Subject" ><&|/l&>Subject</&>:</label>
+<input type="text" size="15" name="NewReminder-Subject" />
+</div>
+<div class="input-row">
+<label class="horizontal" for="NewReminder-Owner" ><&|/l&>Owner</&>:</label>
+<& /Elements/SelectOwner, Name => 'NewReminder-Owner', QueueObj => $Ticket->QueueObj, DefaultValue => 0 &>
+</div>
+<div class="input-row">
+<label class="horizontal" for="NewReminder-Due" ><&|/l&>Due</&> <&|/l&>(yyyy/mm/dd)</&>:</label>
+<& /Elements/SelectDate, Name => "NewReminder-Due", Default => "" &>
+</div>
+</div>
+</%method>
+<%method EditEntry>
+<%args>
+$Reminder
+$Ticket
+</%args>
+<input
+ type="checkbox"
+ name="Complete-Reminder-<%$Reminder->id%>"
+ <% $Reminder->Status eq 'resolved' ? 'CHECKED' : '' %>
+/>
+ <input type="text" size="15" name="Reminder-Subject-<% $Reminder->id %>" value="<%$Reminder->Subject%>" /> &bull;
+ <& /Elements/SelectOwner, Name => 'Reminder-Owner-'.$Reminder->id, Queue => $Ticket->QueueObj, Default => $Reminder->Owner, DefaultValue => 0 &>
+ <& /Elements/SelectDate, Name => 'Reminder-Due-'.$Reminder->id, Default => $Reminder->DueObj->Date &>
+ (<%$Reminder->DueObj->Unix>0 ? $Reminder->DueObj->AgeAsString : '' %>)<br />
+</%method>
+<%method ShowEntry>
+<%args>
+$Reminder
+$Ticket
+</%args>
+<input
+ type="checkbox"
+ name="Complete-Reminder-<%$Reminder->id%>"
+ <% $Reminder->Status eq 'resolved' ? 'CHECKED' : '' %>
+/>
+ <%$Reminder->Subject%> &bull;
+ <%$Reminder->OwnerObj->Name%>
+ <%$Reminder->DueObj->Unix>0 ? "&bull; ". $Reminder->DueObj->AgeAsString : '' |n%><br />
+</%method>
diff --git a/rt/html/Ticket/Elements/ShowAttachments b/rt/html/Ticket/Elements/ShowAttachments
new file mode 100644
index 000000000..6f1de620a
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowAttachments
@@ -0,0 +1,104 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% if (keys %documents) {
+<&| /Widgets/TitleBox, title => loc('Attachments'),
+ title_class=> 'inverse',
+ color => "#336699" &>
+
+% foreach my $key (keys %documents) {
+
+<%$key%><br />
+<ul>
+% foreach my $rev (@{$documents{$key}}) {
+
+<%PERL>
+my $size = $rev->ContentLength;
+
+if ($size) {
+ if ($size > 1024) {
+ $size = int($size/102.4)/10 . "k";
+ }
+ else {
+ $size = $size ."b";
+ }
+
+</%PERL>
+
+<li><font size="-2">
+<a href="<%$RT::WebPath%>/Ticket/Attachment/<%$rev->TransactionId%>/<%$rev->Id%>/<%$rev->Filename | u%>">
+<&|/l, $rev->CreatedAsString, $size, $rev->CreatorObj->Name &>[_1] ([_2]) by [_3]</&>
+</a>
+</font></li>
+% }
+% }
+</ul>
+
+% }
+</&>
+
+<br />
+% }
+
+<%INIT>
+
+# If we haven't been passed in an Attachments object (through the precaching mechanism)
+# then we need to find one
+$Attachments ||= $m->comp('FindAttachments', Ticket => $Ticket);
+
+my %documents;
+while ( my $attach = $Attachments->Next() ) {
+ next unless ($attach->Filename());
+ unshift( @{ $documents{ $attach->Filename } }, $attach );
+}
+
+</%INIT>
+<%ARGS>
+$Ticket => undef
+$Attachments => undef
+</%ARGS>
+
diff --git a/rt/html/Ticket/Elements/ShowBasics b/rt/html/Ticket/Elements/ShowBasics
new file mode 100644
index 000000000..631b90927
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowBasics
@@ -0,0 +1,85 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table>
+ <tr>
+ <td class="label id"><&|/l&>Id</&>:</td>
+ <td class="value id"><%$Ticket->Id %></td>
+ </tr>
+ <tr>
+ <td class="label status"><&|/l&>Status</&>:</td>
+ <td class="value status"><&|/l&><% $Ticket->Status%></&></td>
+ </tr>
+% if ($Ticket->TimeEstimated) {
+ <tr>
+ <td class="label time estimated"><&|/l&>Estimated</&>:</td>
+ <td class="value time estimated"><& ShowTime, minutes => $Ticket->TimeEstimated &></td>
+ </tr>
+% }
+% if ($Ticket->TimeWorked) {
+ <tr>
+ <td class="label time worked"><&|/l&>Worked</&>:</td>
+ <td class="value time worked"><& ShowTime, minutes => $Ticket->TimeWorked &></td>
+ </tr>
+% }
+ <tr>
+ <td class="label time left"><&|/l&>Left</&>:</td>
+ <td class="value time left"><& ShowTime, minutes => $Ticket->TimeLeft &></td>
+ </tr>
+ <tr>
+ <td class="label priority"><&|/l&>Priority</&>:</td>
+ <td class="value priority"><%$Ticket->Priority%>/<%$Ticket->FinalPriority %></td>
+ </tr>
+ <tr>
+ <td class="label queue"><&|/l&>Queue</&>:</td>
+ <td class="value queue"><& ShowQueue, QueueObj => $Ticket->QueueObj &></td>
+ </tr>
+<& /Elements/Callback, _CallbackName => 'EndOfList', TicketObj => $Ticket, %ARGS &>
+</table>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowCustomFields b/rt/html/Ticket/Elements/ShowCustomFields
new file mode 100644
index 000000000..f307d9dd2
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowCustomFields
@@ -0,0 +1,51 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/ShowCustomFields, Object => $Ticket &>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowCustomers b/rt/html/Ticket/Elements/ShowCustomers
new file mode 100644
index 000000000..3acf92dd4
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowCustomers
@@ -0,0 +1,38 @@
+%# Copyright (c) 2004 Ivan Kohler <ivan-rt@420.am>
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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.
+<table>
+% my $cust = 0;
+% foreach my $custResolver ( map { $_->TargetURI->Resolver }
+% @{ $Ticket->Customers->ItemsArrayRef }
+% )
+% {
+% $cust++;
+% my $cust_main = '';
+ <tr>
+ <td class="value">
+ <A HREF="<% $custResolver->HREF %>"><% $custResolver->AsStringLong |n %></A>
+ </td>
+ </tr>
+% }
+% unless ( $cust ) {
+ <tr>
+ <td class="labeltop">
+ <i>(none)<i>
+ </td>
+ </tr>
+
+% }
+</table>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
+
diff --git a/rt/html/Ticket/Elements/ShowDates b/rt/html/Ticket/Elements/ShowDates
new file mode 100644
index 000000000..e00b5ee80
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowDates
@@ -0,0 +1,86 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table>
+ <tr>
+ <td class="label date created"><&|/l&>Created</&>:</td>
+ <td class="value date created"><% $Ticket->CreatedObj->AsString %></td>
+ </tr>
+ <tr>
+ <td class="label date starts"><&|/l&>Starts</&>:</td>
+ <td class="value date starts"><% $Ticket->StartsObj->AsString %></td>
+ </tr>
+ <tr>
+ <td class="label date started"><&|/l&>Started</&>:</td>
+ <td class="value date started"><% $Ticket->StartedObj->AsString %></td>
+ </tr>
+ <tr>
+ <td class="label date told"><a href="<% $RT::WebPath %>/Ticket/Display.html?id=<% $Ticket->id %>&Action=SetTold"><&|/l&>Last Contact</&></a>:</td>
+ <td class="value date told"><% $Ticket->ToldObj->AsString %></td>
+ </tr>
+ <tr>
+ <td class="label date due"><&|/l&>Due</&>:</td>
+ <td class="value date due"><% $Ticket->DueObj->AsString %></td>
+ </tr>
+ <tr>
+ <td class="label date resolved"><&|/l&>Closed</&>:</td>
+ <td class="value date resolved"><% $Ticket->ResolvedObj->AsString %></td>
+ </tr>
+ <tr>
+ <td class="label date updated"><&|/l&>Updated</&>:</td>
+% my $UpdatedString = $Ticket->LastUpdated ? loc("[_1] by [_2]", $Ticket->LastUpdatedAsString, $Ticket->LastUpdatedByObj->Name) : loc("Never");
+% if ($UpdatedLink) {
+ <td class="value date updated"><A HREF="#lasttrans"><% $UpdatedString | h %></a></td>
+% } else {
+ <td class="value date updated"><% $UpdatedString | h %></td>
+% }
+ </tr>
+</table>
+<%ARGS>
+$Ticket => undef
+$UpdatedLink => 1
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowDependencies b/rt/html/Ticket/Elements/ShowDependencies
new file mode 100644
index 000000000..b2f4d298d
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowDependencies
@@ -0,0 +1,65 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<&|/l&>Depends on</&>:<br />
+% while (my $Link = $Ticket->DependsOn->Next) {
+% my $member = $Link->TargetObj;
+<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%>
+[<%$member->Status%>]
+ <br />
+% }
+<&|/l&>Depended on by</&>:<br />
+% while (my $Link = $Ticket->DependedOnBy->Next) {
+% my $member = $Link->TargetObj;
+<a href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$member->Id%>"><%$member->Id%></a>: (<%$member->OwnerObj->Name%>) <%$member->Subject%>
+[<%$member->Status%>]
+ <br />
+% }
+
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowGroupMembers b/rt/html/Ticket/Elements/ShowGroupMembers
new file mode 100644
index 000000000..e39bc690e
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowGroupMembers
@@ -0,0 +1,63 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# Released under the terms of version 2 of the GNU Public License
+
+% my $UserMembers = $Group->UserMembersObj;
+% while (my $member = $UserMembers->Next()) {
+<& ShowUserEntry, User => $member, Ticket => $Ticket &><br />
+% }
+% my $GroupMembers = $Group->MembersObj;
+% $GroupMembers->LimitToGroups();
+% while (my $member = $GroupMembers->Next()) {
+<&|/l&>Group</&>: <%$member->MemberObj->Object->Name%><br />
+% }
+
+<%ARGS>
+$Group => undef
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowHistory b/rt/html/Ticket/Elements/ShowHistory
new file mode 100644
index 000000000..45cd5122f
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowHistory
@@ -0,0 +1,166 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%doc>
+# This is (ab)used in Admin/(Users|Groups)/History.html and should probably
+# be generalized at some point.
+</%doc>
+<%perl>
+if ($ShowDisplayModes or $ShowTitle) {
+ my $title = $ShowTitle
+ ? loc('History')
+ : '&nbsp;';
+
+ my $titleright;
+
+ if ($ShowDisplayModes) {
+ $titleright = q[<span style="color: black">] . loc('Display mode') . ':</span> ';
+
+ if ($ShowHeaders) {
+ $titleright .= qq{<a href="$URIFile?id=} .
+ $Ticket->id.qq{">} .
+ loc("Brief headers") .
+ qq{</a> &mdash; };
+ $titleright .= q[<span class="selected">] . loc("Full headers") . "</span>";
+ }
+ else {
+ $titleright .= q[<span class="selected">] . loc("Brief headers") . "</span> &mdash; ";
+ $titleright .= qq{<a href="$URIFile?ShowHeaders=1;id=} .
+ $Ticket->id.qq{">} .
+ loc("Full headers") .
+ qq{</a>};
+ }
+ }
+</%perl>
+<& /Widgets/TitleBoxStart, title => $title, titleright => $titleright &>
+% }
+
+<div id="ticket-history">
+<%perl>
+my @attachments = @{$Attachments->ItemsArrayRef()};
+my @attachment_content = @{$AttachmentContent->ItemsArrayRef()};
+
+while ( my $Transaction = $Transactions->Next ) {
+ my $skip = 0;
+ $m->comp( '/Elements/Callback',
+ _CallbackName => 'SkipTransaction',
+ Transaction => $Transaction,
+ skip => \$skip,
+ %ARGS );
+ next if $skip;
+ $i++;
+
+ my @trans_attachments = grep { $_->TransactionId == $Transaction->Id } @attachments;
+
+ my $trans_content = {};
+ grep { ($_->TransactionId == $Transaction->Id ) && ($trans_content->{$_->Id} = $_) } @attachment_content;
+
+
+ #Args is first because we're clobbering the "Attachments" parameter
+ $m->comp( 'ShowTransaction',
+ %ARGS,
+
+ AttachPath => $AttachPath,
+ UpdatePath => $UpdatePath,
+ Ticket => $Ticket,
+ Transaction => $Transaction,
+ ShowHeaders => $ShowHeaders,
+ Collapsed => $Collapsed,
+ RowNum => $i,
+ ShowTitleBarCommands => $ShowTitleBarCommands,
+ Attachments => \@trans_attachments,
+ AttachmentContent => $trans_content,
+ LastTransaction => $Transactions->IsLast
+ );
+
+# manually flush the content buffer after each txn, so the user sees
+# some update
+$m->flush_buffer();
+}
+
+</%perl>
+</div>
+% if ($ShowDisplayModes or $ShowTitle) {
+<& /Widgets/TitleBoxEnd &>
+% }
+<%INIT>
+my $Transactions = new RT::Transactions($session{'CurrentUser'});
+if ($Tickets) {
+ while (my $t = $Tickets->Next) {
+ $Transactions->LimitToTicket($t->id);
+ }
+} else {
+ $Transactions = $Ticket->Transactions;
+}
+
+
+my $OldestFirst = $RT::OldestTransactionsFirst? 'ASC': 'DESC';
+$Transactions->OrderByCols( { FIELD => 'Created',
+ ORDER => $OldestFirst },
+ { FIELD => 'id',
+ ORDER => $OldestFirst },
+ );
+
+my $i;
+$Attachments ||= $m->comp('/Ticket/Elements/FindAttachments', Ticket => $Ticket, Tickets => $Tickets || undef);
+$AttachmentContent ||= $m->comp('/Ticket/Elements/LoadTextAttachments', Ticket => $Ticket);
+
+</%INIT>
+<%ARGS>
+$URIFile => $RT::WebPath."/Ticket/Display.html"
+$Ticket => undef
+$Tickets => undef
+$Attachments => undef
+$AttachmentContent => undef
+$ShowHeaders => undef
+$Collapsed => undef
+$ShowTitle => 1
+$ShowDisplayModes => 1
+$ShowTitleBarCommands => 1
+$AttachPath => $RT::WebPath."/Ticket/Attachment"
+$UpdatePath => $RT::WebPath."/Ticket/Update.html"
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowMembers b/rt/html/Ticket/Elements/ShowMembers
new file mode 100644
index 000000000..f87ce8fc9
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowMembers
@@ -0,0 +1,68 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<ul>
+% while (my $link = $members->Next) {
+<li><& /Elements/ShowLink, URI => $link->BaseURI &><br />
+% if ($depth < 8) {
+<& /Ticket/Elements/ShowMembers, Ticket => $link->BaseObj, depth => ($depth+1) &>
+% }
+</li>
+% }
+</ul>
+
+<%INIT>
+
+my $members = $Ticket->Members;
+return unless $members->Count;
+
+</%INIT>
+
+<%ARGS>
+$Ticket => undef
+$depth => 1
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowMessageHeaders b/rt/html/Ticket/Elements/ShowMessageHeaders
new file mode 100644
index 000000000..81c56375d
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowMessageHeaders
@@ -0,0 +1,92 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table>
+% foreach my $header (@headers) {
+% next unless $display_headers{_all}
+% or ($display_headers{ lc $header->{Tag} }
+% and length $header->{Value});
+ <tr>
+ <td align="right" class="message-header-key"><%$header->{'Tag'}%>:</td>
+ <td class="message-header-value"><%$header->{'Value'} | n%></td>
+ </tr>
+% }
+</table>
+<%INIT>
+my $content = $Headers;
+$m->comp('/Elements/Callback', content => \$content, %ARGS);
+
+# apply html escaping on the original content
+# we'll display the value without escaping later (for MakeClicky et al.)
+$content = $m->interp->apply_escapes($content, 'h');
+
+my @lines = split /\n/, $content;
+my $in_header = 0;
+my @headers;
+
+for (@lines) {
+ if (/^(\S+):\s+(.*)$/) {
+ push @headers, { Tag => $1, Value => $2 };
+ }
+ elsif (/^\s+/) {
+ $headers[-1]->{'Value'} .= $_;
+ }
+ else {
+ s/:$//;
+ push @headers, { Tag => $_, Value => '' };
+ }
+}
+
+my %display_headers = map { lc($_) => 1 } @$DisplayHeaders;
+
+$m->comp('/Elements/Callback', _CallbackName => 'Headers', content => \$content, headers => \@headers, display_headers => \%display_headers, %ARGS);
+
+</%INIT>
+<%ARGS>
+$Headers => undef
+$DisplayHeaders => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowMessageStanza b/rt/html/Ticket/Elements/ShowMessageStanza
new file mode 100644
index 000000000..8040096f1
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowMessageStanza
@@ -0,0 +1,84 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% if (ref($Message)) {
+<div class="message-stanza-depth-<% $Depth %>">
+<%perl>
+foreach my $stanza (@$Message) {
+ if ( ref $stanza eq "ARRAY" ) {
+ $m->comp( 'ShowMessageStanza',
+ Depth => $Depth + 1,
+ Transaction => $Transaction,
+ Message => $stanza );
+ }
+ elsif ( ref $stanza eq "HASH" ) {
+ my $content = $stanza->{raw};
+ RT::Interface::Web::EscapeUTF8(\$content);
+ $m->comp('/Elements/Callback', content => \$content, %ARGS);
+ $content =~ s{$}{<br />}mg
+ if defined $content;
+
+</%perl>
+<%$content |n%>
+% }
+% } # end foreach
+</div>
+% } else {
+% my $content = $Message;
+% RT::Interface::Web::EscapeUTF8(\$content);
+% $m->comp('/Elements/Callback', content => \$content, %ARGS);
+% $content =~ s{$}{<br />}mg;
+<%$content |n%>
+% }
+<%INIT>
+use URI::URL;
+</%INIT>
+<%ARGS>
+$Message => undef
+$Depth => 0
+$Transaction => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowPeople b/rt/html/Ticket/Elements/ShowPeople
new file mode 100644
index 000000000..76336ecdc
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowPeople
@@ -0,0 +1,68 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<table>
+ <tr>
+ <td class="label"><&|/l&>Owner</&>:</td>
+ <td class="value"><& ShowUserEntry, User => $Ticket->OwnerObj, Ticket => $Ticket &></td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Requestors</&>:</td>
+ <td class="value"><& ShowGroupMembers, Group => $Ticket->Requestors, Ticket => $Ticket &></td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Cc</&>:</td>
+ <td class="value"><& ShowGroupMembers, Group => $Ticket->Cc, Ticket => $Ticket &></td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>AdminCc</&>:</td>
+ <td class="value"><& ShowGroupMembers, Group => $Ticket->AdminCc, Ticket => $Ticket &></td>
+ </tr>
+</table>
+<%ARGS>
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowQueue b/rt/html/Ticket/Elements/ShowQueue
new file mode 100644
index 000000000..484760244
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowQueue
@@ -0,0 +1,9 @@
+<% $QueueObj->Name %>
+<%ARGS>
+$QueueObj
+</%ARGS>
+<%INIT>
+my $value = $QueueObj->Name;
+$value = '#'. $QueueObj->id
+ unless defined $value && length $value;
+</%INIT>
diff --git a/rt/html/Ticket/Elements/ShowRequestor b/rt/html/Ticket/Elements/ShowRequestor
new file mode 100644
index 000000000..d7fe6b185
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowRequestor
@@ -0,0 +1,89 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%PERL>
+my $rows = 10;
+my $has_right_adminusers = $session{'CurrentUser'}->HasRight(Object => $RT::System, Right => 'AdminUsers');
+my $people = $Ticket->Requestors->UserMembersObj;
+while (my $requestor=$people->Next) {
+next if $requestor->Privileged;
+my $name=$requestor->RealName || $requestor->EmailAddress;
+my $tickets = RT::Tickets->new($session{'CurrentUser'});
+$tickets->FromSQL( "Requestor.id = ". $requestor->id ." AND (Status = 'open' OR Status = 'new')" );
+$tickets->RowsPerPage($rows);
+$tickets->OrderBy(FIELD => 'Priority', ORDER => 'DESC');
+</%PERL>
+
+<&| /Widgets/TitleBox,
+ title_href => $has_right_adminusers ? "$RT::WebPath/Admin/Users/Modify.html?id=".$requestor->id : undef,
+ title=> loc("More about [_1]", $name),
+&>
+
+%# Additional information about this user. Empty by default.
+<& /Elements/Callback, _CallbackName => 'AboutThisUser', requestor => $requestor, %ARGS &>
+
+<&|/l&>Comments about this user</&>:<br />
+<b><% ($requestor->Comments || loc("No comment entered about this user")) %></b><br />
+
+<&|/l, $rows &>This user's [_1] highest priority tickets</&>:<br />
+<ul>
+%while (my $w=$tickets->Next) {
+<li><a href="<%$RT::WebPath%><%$DisplayPath%>?id=<%$w->id%>"><%$w->Id%>: <%$w->Subject%></a> (<%$w->Status%>)
+%}
+</ul>
+
+<&|/l&>Groups this user belongs to</&>:<br />
+
+<& /Elements/ShowMemberships, UserObj => $requestor &>
+
+</&>
+
+%}
+<%ARGS>
+$Ticket=>undef
+$DisplayPath => "/Ticket/Display.html"
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowSummary b/rt/html/Ticket/Elements/ShowSummary
new file mode 100644
index 000000000..e3464c732
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowSummary
@@ -0,0 +1,120 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+ <table width="100%" class="ticket-summary">
+ <tr>
+ <td valign="top" width="50%" class="boxcontainer">
+ <&| /Widgets/TitleBox, title => loc('The Basics'),
+ title_href =>"$RT::WebPath/Ticket/Modify.html?id=".$Ticket->Id,
+ class => 'ticket-info-basics' &>
+ <& /Ticket/Elements/ShowBasics, Ticket => $Ticket &>
+ </&>
+
+% if ($Ticket->QueueObj->TicketCustomFields->First) {
+ <&| /Widgets/TitleBox, title => loc('Custom Fields'),
+ title_href =>"$RT::WebPath/Ticket/Modify.html?id=".$Ticket->Id,
+ class => 'ticket-info-cfs' &>
+ <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket &>
+ </&>
+% }
+ <&| /Widgets/TitleBox, title => loc('People'),
+ title_href =>"$RT::WebPath/Ticket/ModifyPeople.html?id=".$Ticket->Id,
+ class => 'ticket-info-people' &>
+ <& /Ticket/Elements/ShowPeople, Ticket => $Ticket &>
+ </&>
+
+ <&| /Widgets/TitleBox, title => loc('Customers'),
+ title_href =>"$RT::WebPath/Ticket/ModifyCustomers.html?id=".$Ticket->Id,
+ class=> 'ticket-info-customers' &>
+ <& /Ticket/Elements/ShowCustomers, Ticket => $Ticket &>
+ </&>
+
+ <& /Ticket/Elements/ShowAttachments, Ticket => $Ticket, Attachments => $Attachments &>
+ <br />
+ <& /Ticket/Elements/ShowRequestor, Ticket => $Ticket &>
+
+ <& /Elements/Callback, %ARGS, _CallbackName => 'LeftColumn' &>
+ </td>
+ <td valign="top" width="50%" class="boxcontainer">
+ <&|/Widgets/TitleBox, title => loc("Reminders"),
+ title_href =>"$RT::WebPath/Ticket/Reminders.html?id=".$Ticket->Id,
+ class => 'ticket-info-reminders' &>
+ <table>
+ <tr>
+ <td>
+ <form action="<%$RT::WebPath%>/Ticket/Display.html" method="post">
+ <& /Ticket/Elements/Reminders, Ticket => $Ticket, ShowCompleted => 0 &>
+ <div align="right"><input type="submit" class="button" value="Save" /></div>
+ </form>
+ </td>
+ </tr>
+ </table>
+ </&>
+ <&| /Widgets/TitleBox, title => loc("Dates"),
+ title_href =>"$RT::WebPath/Ticket/ModifyDates.html?id=".$Ticket->Id,
+ class => 'ticket-info-dates' &>
+ <& /Ticket/Elements/ShowDates, Ticket => $Ticket &>
+ </&>
+
+ <&| /Widgets/TitleBox, title => loc('Links'),
+ title_href => "$RT::WebPath/Ticket/ModifyLinks.html?id=".$Ticket->Id,
+ class => 'ticket-info-links' &>
+ <& /Elements/ShowLinks, Ticket => $Ticket &>
+ </&>
+ <& /Elements/Callback, %ARGS, _CallbackName => 'RightColumn' &>
+
+ </td>
+ </tr>
+ </table>
+<%ARGS>
+$Ticket => undef
+$Attachments => undef
+</%ARGS>
+
+
+
+
diff --git a/rt/html/Ticket/Elements/ShowTime b/rt/html/Ticket/Elements/ShowTime
new file mode 100644
index 000000000..92e84f681
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowTime
@@ -0,0 +1,55 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+% if ($minutes < 60) {
+<&|/l, $minutes &>[_1] min</&>
+% } else {
+<&|/l, sprintf("%.1f",$minutes / 60) &>[quant,_1,hour]</&> (<&|/l, $minutes &>[_1] min</&>)
+% }
+<%ARGS>
+$minutes
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/ShowTransaction b/rt/html/Ticket/Elements/ShowTransaction
new file mode 100644
index 000000000..f6d73c2f5
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowTransaction
@@ -0,0 +1,194 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<div class="ticket-transaction<% $type_class && " $type_class" %><% $RowNum % 2 ? ' odd' : ' even' %>">
+<table width="100%" cellspacing="0" cellpadding="2" border="0">
+ <tr>
+ <td rowspan="2" valign="top" class="type">
+ <a name="txn-<%$Transaction->Id%>" href="<% $DisplayPath %>#txn-<%$Transaction->Id%>">#</a>
+ <% $LastTransaction ? '<a name="lasttrans">&nbsp;</a>' : '&nbsp;' |n %>
+ </td>
+ <td class="date"><% $transdate|n %></td>
+% my $desc = $Transaction->BriefDescription;
+% $m->comp('/Elements/Callback', _CallbackName => 'ModifyDisplay', text => \$desc, Transaction => $Transaction, %ARGS);
+ <td class="description">
+ <%$Transaction->CreatorObj->Name%> - <%$TicketString%> <%$desc%>
+ </td>
+ <td class="time-taken"><%$TimeTaken%></td>
+ <td class="actions"><%$titlebar_commands|n%></td>
+ </tr>
+
+ <tr>
+ <td colspan="4" class="content">
+% if ($Transaction->CustomFieldValues->Count) {
+ <& /Elements/ShowCustomFields, Object => $Transaction &>
+% }
+% $m->comp('ShowTransactionAttachments', %ARGS, Parent => 0) unless ($Collapsed ||!$ShowBody);
+ </td>
+ </tr>
+</table>
+</div>
+
+<%ARGS>
+$Ticket => undef
+$Transaction => undef
+$ShowHeaders => 0
+$Collapsed => undef
+$ShowTitleBarCommands => 1
+$RowNum => 1
+$DisplayPath => $RT::WebPath."/Ticket/Display.html?id=".$Ticket->id
+$AttachPath => $RT::WebPath."/Ticket/Attachment"
+$UpdatePath => $RT::WebPath."/Ticket/Update.html"
+$EmailRecordPath => $RT::WebPath."/Ticket/ShowEmailRecord.html"
+$Attachments => undef
+$AttachmentContent => undef
+$ShowBody => 1
+$LastTransaction => 0
+</%ARGS>
+
+<%INIT>
+
+my ( $TimeTaken, $TicketString, $type_class );
+
+my $transdate = $Transaction->CreatedAsString();
+$transdate =~ s/\s/&nbsp;/g;
+
+if ( $Transaction->Type =~ /^(Create|Correspond|Comment$)/ ) {
+ if ( $Transaction->IsInbound ) {
+ $type_class = 'message';
+ }
+ else {
+ $type_class = 'message';
+ }
+}
+elsif ( ( $Transaction->Field =~ /^Owner$/ )
+ or ( $Transaction->Type =~ /^(AddWatcher|DelWatcher)$/ ) ) {
+ $type_class = 'people';
+
+}
+elsif ( $Transaction->Type =~ /^(AddLink|DeleteLink)$/ ) {
+ $type_class = 'links';
+}
+elsif ( $Transaction->Type =~ /^(Status|Set|Told)$/ ) {
+ if ( $Transaction->Field =~ /^(Told|Starts|Started|Due)$/ ) {
+ $type_class = 'dates';
+ }
+ else {
+ $type_class = 'basics';
+ }
+}
+else {
+ $type_class = 'other';
+}
+
+if ( $Ticket->Id != $Transaction->Ticket ) {
+ $TicketString = "Ticket " . $Transaction->Ticket . ": ";
+}
+$TicketString ||= '';
+
+if ( $Transaction->TimeTaken != 0 ) {
+ $TimeTaken = $Transaction->TimeTaken . " min";
+} else {
+ $TimeTaken = '';
+}
+
+unless ($Attachments) {
+ my $attachments = $Transaction->Attachments;
+ $attachments->Columns( qw( Id Filename ContentType Headers Subject Parent ContentEncoding ContentType TransactionId) );
+ $Attachments = $attachments->ItemsArrayRef();
+}
+my $titlebar_commands = '&nbsp;';
+
+my @DisplayHeaders=qw ( _all);
+
+if ( $Transaction->Type =~ /EmailRecord$/ ) {
+ @DisplayHeaders = qw(To Cc Bcc);
+
+ $titlebar_commands .=
+ "[<a target=\"_blank\" href=\"$EmailRecordPath?id="
+ . $Transaction->Ticket
+ . "&Transaction="
+ . $Transaction->Id
+ . "&Attachment="
+ . ( $Attachments->[0] && $Attachments->[0]->id )
+ . '">' . loc('Show') . "</a>]&nbsp;";
+ $ShowBody = 0;
+}
+
+
+# If the transaction has anything attached to it at all
+else {
+
+ unless ( $ShowHeaders ) {
+ @DisplayHeaders = qw(To From RT-Send-Cc Cc Bcc Date Subject);
+ }
+
+ if ( $Attachments->[0] && $ShowTitleBarCommands ) {
+ if ( $Transaction->TicketObj->CurrentUserHasRight('ReplyToTicket')
+ or $Transaction->TicketObj->CurrentUserHasRight('ModifyTicket')) {
+ $titlebar_commands .=
+ "[<a href=\"".$UpdatePath."?id="
+ . $Transaction->Ticket
+ . "&QuoteTransaction="
+ . $Transaction->Id
+ . "&Action=Respond\">"
+ . loc('Reply')
+ . "</a>]&nbsp;";
+ }
+ if ( $Transaction->TicketObj->CurrentUserHasRight('CommentOnTicket')
+ or $Transaction->TicketObj->CurrentUserHasRight('ModifyTicket')) {
+ $titlebar_commands .=
+ "[<a href=\"".$UpdatePath."?id="
+ . $Transaction->Ticket
+ . "&QuoteTransaction="
+ . $Transaction->Id
+ . "&Action=Comment\">"
+ . loc('Comment') . "</a>]";
+ }
+ }
+}
+</%INIT>
diff --git a/rt/html/Ticket/Elements/ShowTransactionAttachments b/rt/html/Ticket/Elements/ShowTransactionAttachments
new file mode 100644
index 000000000..85e04e5e5
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowTransactionAttachments
@@ -0,0 +1,215 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%perl>
+# Find all the attachments which have parent $Parent
+# For each of these attachments
+foreach my $message ( grep { $_->Parent == $Parent } @$Attachments ) {
+
+ # {{{ show the headers
+ my $headers = $message->Headers;
+ chomp $headers;
+
+ # localize the common headers (like 'Subject:'), too.
+ $headers =~ s/^([^:]+)(?=:)/loc($1)/em;
+ $m->comp(
+ 'ShowMessageHeaders',
+ Headers => $headers,
+ Transaction => $Transaction,
+ DisplayHeaders => \@DisplayHeaders
+ );
+
+ # }}}
+ # {{{ if there's any size at all, show the download link
+ my $size = $message->ContentLength;
+ if ($size) {
+
+</%perl>
+<div class="downloadattachment">
+<%perl>
+
+ # show a download link
+ if ( $size > 1024 ) {
+ $size = loc( "[_1]k", int( $size / 102.4 ) / 10 );
+ }
+ else {
+ $size = loc( "[_1]b", $size );
+ }
+
+</%PERL>
+<a href="<%$AttachPath%>/<%$Transaction->Id%>/<%$message->Id%>/<%$message->Filename | u%>"><&|/l&>Download</&> <%$message->Filename || loc('(untitled)') %></a>
+<span class="downloadcontenttype">
+[<%$message->ContentType%> <% $size %>]
+</span>
+</div>
+% }
+% # }}}
+<div class="messagebody">
+<%perl>
+# {{{ if it has a content-disposition: attachment, don't show inline
+unless ( ($message->GetHeader('Content-Disposition')||"") =~ /attachment/i ) {
+
+ my $content;
+
+ # If it's text
+ if ( $message->ContentType =~ m{^(text|message)}i
+ && !($RT::SuppressInlineTextFiles && $message->Filename)
+ && $message->ContentLength <= $RT::MaxInlineBody )
+ {
+
+ if (
+
+ # it's a toplevel object
+ !$ParentObj
+
+ # or its parent isn't a multipart alternative
+ || ( $ParentObj->ContentType !~ m{^multipart/alternative$}i )
+
+ # or it's of our prefered alterative type
+ || (
+ (
+ $RT::PreferRichText
+ && ( $message->ContentType =~ m{^text/(?:html|enriched)$} )
+ )
+ || ( !$RT::PreferRichText
+ && ( $message->ContentType !~ m{^text/(?:html|enriched)$} )
+ )
+ )
+ )
+ {
+
+ if ( $AttachmentContent->{ $message->id } ) {
+ $content = $AttachmentContent->{ $message->id }->Content;
+ }
+ else {
+ $content = $message->Content;
+ }
+
+ # if it's a text/html clean the body and show it
+ if ( $message->ContentType =~ m{^text/(?:html|enriched)$}i ) {
+ $content =
+ $m->comp( '/Elements/ScrubHTML', Content => $content );
+ $m->out($content);
+ }
+
+ # if it's a text/plain show the body
+ elsif ( $message->ContentType =~ m{^(text|message|text)}i ) {
+
+ #don't want to use this even if it is installed, its
+ #segfaulting on weird characters and silently truncating the
+ #ticket history output
+ #see:
+ # r44838@pinglin: jesse | 2006-11-14 15:53:18 -0500
+ # * Move Text::Quoted back to being a run-time require. So that it's possible to turn off the feature if it causes your perl to segfault. (Text::Tabs is...not robust in the face of perl bugs)
+ #eval { require Text::Quoted; $content = Text::Quoted::extract($content); };
+ #if ($@) { 1; }
+
+ $m->comp(
+ 'ShowMessageStanza',
+ Depth => 0,
+ Message => $content,
+ Transaction => $Transaction
+ );
+ }
+ }
+
+ }
+
+ # if it's an image, show it as an image
+ elsif ( $RT::ShowTransactionImages and $message->ContentType =~ /^image\//i ) {
+ $m->out('<img src="'
+ . $AttachPath . '/'
+ . $Transaction->Id . '/'
+ . $message->Id
+ . '/" />' );
+ }
+ elsif ( $message->ContentLength > 0 ) {
+ $m->out(
+ loc( 'Message body not shown because it is too large or is not plain text.' )
+ );
+ }
+}
+
+# }}}
+
+$m->comp(
+ 'ShowTransactionAttachments', %ARGS,
+ Parent => $message->id,
+ ParentObj => $message
+);
+
+</%PERL>
+</div>
+% }
+<%ARGS>
+$Ticket => undef
+$Transaction => undef
+$ShowHeaders => 0
+$Collapsed => undef
+$ShowTitleBarCommands => 1
+$RowNum => 1
+$AttachPath => $RT::WebPath."/Ticket/Attachment"
+$UpdatePath => $RT::WebPath."/Ticket/Update.html"
+$EmailRecordPath => $RT::WebPath."/Ticket/ShowEmailRecord.html"
+$Attachments => undef
+$AttachmentContent => undef
+$ShowBody => 1
+$Parent => 0
+$ParentObj => 0
+</%ARGS>
+<%INIT>
+my @DisplayHeaders=qw( _all);
+
+if ( $Transaction->Type =~ /EmailRecord$/ ) {
+ @DisplayHeaders = qw(To Cc Bcc);
+}
+
+# If the transaction has anything attached to it at all
+elsif (!$ShowHeaders) {
+ @DisplayHeaders = qw(To From RT-Send-Cc Cc Bcc Date Subject);
+}
+</%INIT>
diff --git a/rt/html/Ticket/Elements/ShowUserEntry b/rt/html/Ticket/Elements/ShowUserEntry
new file mode 100644
index 000000000..8481c143b
--- /dev/null
+++ b/rt/html/Ticket/Elements/ShowUserEntry
@@ -0,0 +1,61 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# Released under the terms of version 2 of the GNU Public License
+
+<%$User->Name%>
+% if ($User->EmailAddress && $User->EmailAddress ne $User->Name) {
+&lt;<%$User->EmailAddress%>&gt;
+% }
+% if ($Ticket and grep { $_->Content eq $User->EmailAddress } $Ticket->SquelchMailTo) {
+<b><&|/l&>(Will not be sent email)</&></b>
+% }
+
+<%ARGS>
+$User => undef
+$Ticket => undef
+</%ARGS>
diff --git a/rt/html/Ticket/Elements/Tabs b/rt/html/Ticket/Elements/Tabs
new file mode 100644
index 000000000..3dee8dff6
--- /dev/null
+++ b/rt/html/Ticket/Elements/Tabs
@@ -0,0 +1,250 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Callback, Ticket => $Ticket, actions=> $actions, tabs => $tabs, %ARGS &>
+<& /Elements/Tabs,
+ tabs => $tabs,
+ actions => $actions,
+ current_tab => $current_tab,
+ current_toptab => $current_toptab,
+ Title => $Title &>
+<%INIT>
+
+my $tabs = {};
+my $current_toptab = "Search/Build.html",
+my $searchtabs = {};
+my $actions;
+
+if ( $Ticket) {
+
+my $id = $Ticket->id();
+
+if ( defined $session{'tickets'} ) {
+
+ # we have to update session data if we get new ItemMap
+ my $updatesession = 1 unless($session{'tickets'}->{'item_map'});
+
+ my $item_map = $session{'tickets'}->ItemMap;
+
+ if ($updatesession) {
+ $session{'i'}++;
+ $session{'tickets'}->PrepForSerialization();
+ }
+
+ # Don't display prev links if we're on the first ticket
+ if ($item_map->{$Ticket->Id}->{prev}) {
+ $searchtabs->{'_a'} = {
+ class => "nav",
+ path => "Ticket/Display.html?id=" . $item_map->{first},
+ title => '<< ' . loc('First') };
+ $searchtabs->{"_b"} = { class => "nav",
+ path => "Ticket/Display.html?id=" . $item_map->{$Ticket->Id}->{prev},
+ title => '< ' . loc('Prev') };
+ }
+
+
+ # Don't display next links if we're on the last ticket
+ if ($item_map->{$Ticket->Id}->{next}) {
+ $searchtabs->{'d'} = { class => "nav",
+ path => "Ticket/Display.html?id=" . $item_map->{$Ticket->Id}->{next},
+ title => loc('Next') . ' >' };
+ $searchtabs->{'e'} = {
+ class => "nav",
+ path => "Ticket/Display.html?id=" . $item_map->{last},
+ title => loc('Last') . ' >>' };
+ }
+}
+
+
+
+$tabs->{"this"} = { class => "currentnav",
+ path => "Ticket/Display.html?id=" . $Ticket->id,
+ title => "#" . $id,
+ current_subtab => $current_subtab };
+
+my $ticket_page_tabs = {
+ _A => { title => loc('Display'),
+ path => "Ticket/Display.html?id=" . $id, },
+
+ _Ab => { title => loc('History'),
+ path => "Ticket/History.html?id=" . $id, },
+ _B => { title => loc('Basics'),
+ path => "Ticket/Modify.html?id=" . $id, },
+
+ _C => { title => loc('Dates'),
+ path => "Ticket/ModifyDates.html?id=" . $id, },
+ _D =>
+ { title => loc('People'), path => "Ticket/ModifyPeople.html?id=" . $id, },
+ _E => { title => loc('Links'),
+ path => "Ticket/ModifyLinks.html?id=" . $id, },
+ _Eb=> { title => loc('Customers'),
+ path => "Ticket/ModifyCustomers.html?id=" . $id, },
+ _F => { title => loc('Reminders'),
+ path => "Ticket/Reminders.html?id=" . $id,
+ separator => 1, },
+ _X => { title => loc('Jumbo'),
+ path => "Ticket/ModifyAll.html?id=" . $id,
+ },
+
+};
+
+foreach my $tab ( sort keys %{$ticket_page_tabs} ) {
+ if ( $ticket_page_tabs->{$tab}->{'path'} eq $current_tab ) {
+ $ticket_page_tabs->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{'this'}->{"current_subtab"} =
+ $ticket_page_tabs->{$tab}->{"path"};
+ }
+}
+$tabs->{'this'}->{"subtabs"} = $ticket_page_tabs;
+$current_tab = "Ticket/Display.html?id=" . $id;
+
+my %can = (
+ ModifyTicket => $Ticket->CurrentUserHasRight('ModifyTicket'),
+);
+
+if ( $can{'ModifyTicket'} or $Ticket->CurrentUserHasRight('ReplyToTicket') ) {
+ $actions->{'F'} = {
+ title => loc('Reply'),
+ path => "Ticket/Update.html?Action=Respond&id=" . $id,
+ };
+}
+
+if ( $can{'ModifyTicket'} ) {
+ if ( $Ticket->Status ne 'resolved' ) {
+ $actions->{'G'} = {
+ path => "Ticket/Update.html?Action=Comment&DefaultStatus=resolved&id=" . $id,
+ title => loc('Resolve') };
+ }
+ if ( $Ticket->Status ne 'open' ) {
+ $actions->{'A'} = { path => "Ticket/Display.html?Status=open&id=" . $id,
+ title => loc('Open it') };
+ }
+}
+
+if ( $Ticket->CurrentUserHasRight('OwnTicket') ) {
+ if ( $Ticket->OwnerObj->Id == $RT::Nobody->id
+ and ( $can{'ModifyTicket'} or $Ticket->CurrentUserHasRight('TakeTicket') ) )
+ {
+ $actions->{'B'} = {
+ path => "Ticket/Display.html?Action=Take&id=" . $id,
+ title => loc('Take'),
+ };
+ }
+ elsif ( $Ticket->OwnerObj->id != $session{CurrentUser}->id
+ and ( $can{'ModifyTicket'} or $Ticket->CurrentUserHasRight('StealTicket') ) )
+ {
+ $actions->{'C'} = {
+ path => "Ticket/Display.html?Action=Steal&id=" . $id,
+ title => loc('Steal'),
+ };
+ }
+}
+
+if ( $can{'ModifyTicket'} or $Ticket->CurrentUserHasRight('CommentOnTicket') ) {
+ $actions->{'E'} = {
+ title => loc('Comment'),
+ path => "Ticket/Update.html?Action=Comment&id=" . $id,
+ };
+}
+}
+
+if ( (defined $actions->{A} || defined $actions->{B} || defined $actions->{C})
+ && (defined $actions->{E} || defined $actions->{F} || defined $actions->{G}) ) {
+
+ if (defined $actions->{C}) { $actions->{C}->{separator} = 1 }
+ elsif (defined $actions->{B}) { $actions->{B}->{separator} = 1 }
+ elsif (defined $actions->{A}) { $actions->{A}->{separator} = 1 }
+}
+
+my $args;
+$args= "?" . $m->comp(
+ '/Elements/QueryString',
+ Query => $ARGS{'Query'} || $session{'CurrentSearchHash'}->{'Query'},
+ Format => $ARGS{'Format'} || $session{'CurrentSearchHash'}->{'Format'},
+ OrderBy => $ARGS{'OrderBy'} || $session{'CurrentSearchHash'}->{'OrderBy'},
+ Order => $ARGS{'Order'} || $session{'CurrentSearchHash'}->{'Order'},
+ Page => $ARGS{'Page'} || $session{'CurrentSearchHash'}->{'Page'},
+ Rows => $ARGS{'Rows'},
+ ) if ($ARGS{'Query'} or $session{'CurrentSearchHash'}->{'Query'});
+$args ||= '';
+
+$tabs->{"f"} = { path => "Search/Build.html?NewQuery=1",
+ title => loc('New Search')};
+$tabs->{"g"} = { path => "Search/Build.html$args",
+ title => loc('Edit Search')};
+$tabs->{"h"} = { path => "Search/Edit.html$args",
+ title => loc('Advanced'),
+ separator => 1 };
+if ($args) {
+ $tabs->{"i"} = { path => "Search/Results.html$args",
+ title => loc('Show Results'),
+ };
+ if ($current_tab =~ "Search/Results.html") {
+ $current_tab = "Search/Results.html$args";
+ }
+ $tabs->{"j"} = { path => "Search/Bulk.html$args",
+ title => loc('Bulk Update'),
+ };
+ if ($current_tab =~ "Search/Bulk.html") {
+ $current_tab = "Search/Bulk.html$args";
+ }
+ foreach my $searchtab (keys %{$searchtabs}) {
+ ($searchtab =~ /^_/) ? $tabs->{"s".$searchtab} = $searchtabs->{$searchtab} : $tabs->{"z_".$searchtab} = $searchtabs->{$searchtab};
+ }
+}
+
+
+</%INIT>
+
+
+<%ARGS>
+$Ticket => undef
+$subtabs => undef
+$current_tab => ''
+$current_subtab => ''
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Ticket/History.html b/rt/html/Ticket/History.html
new file mode 100644
index 000000000..bf533b304
--- /dev/null
+++ b/rt/html/Ticket/History.html
@@ -0,0 +1,89 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc("Ticket History # [_1] [_2]", $Ticket->Id, $Ticket->Subject) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $Ticket, current_tab => 'Ticket/History.html?id='.$Ticket->id,
+ Title => loc("Ticket History # [_1] [_2]", $Ticket->Id, $Ticket->Subject) &>
+
+<br />
+
+<& /Ticket/Elements/ShowHistory ,
+ Ticket => $Ticket,
+ ShowHeaders => $ARGS{'ShowHeaders'},
+ URIFile => 'History.html',
+ Attachments => $attachments,
+ AttachmentContent => $attachment_content
+ &>
+
+<& /Elements/Callback, _CallbackName => 'AfterShowHistory', Ticket => $Ticket,
+current_tab => 'Ticket/History.html?id=' . $Ticket->id, %ARGS &>
+
+<%ARGS>
+$id => undef
+</%ARGS>
+
+<%INIT>
+
+
+
+my $Ticket = LoadTicket ($id);
+
+unless ($Ticket->CurrentUserHasRight('ShowTicket')) {
+ Abort("No permission to view ticket");
+}
+
+my $attachments = $m->comp('Elements/FindAttachments', Ticket => $Ticket);
+my $attachment_content = $m->comp('Elements/LoadTextAttachments', Ticket =>
+$Ticket);
+
+
+</%INIT>
+
+
+
+
diff --git a/rt/html/Ticket/Modify.html b/rt/html/Ticket/Modify.html
new file mode 100644
index 000000000..488e0ad46
--- /dev/null
+++ b/rt/html/Ticket/Modify.html
@@ -0,0 +1,91 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc('Modify ticket #[_1]', $TicketObj->Id) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $TicketObj, current_subtab => "Ticket/Modify.html?id=".$TicketObj->Id,
+ Title => loc('Modify ticket #[_1]', $TicketObj->Id) &>
+
+<& /Elements/ListActions, actions => \@results &>
+<form method="post" action="Modify.html" enctype="multipart/form-data">
+<& /Elements/Callback, _CallbackName => 'FormStart',ARGSRef =>\%ARGS &>
+<input type="hidden" class="hidden" name="id" value="<%$TicketObj->Id%>" />
+<&| /Widgets/TitleBox, title => loc('Modify ticket #[_1]',$TicketObj->Id) &>
+<& Elements/EditBasics, TicketObj => $TicketObj &>
+<& Elements/EditCustomFields, TicketObj => $TicketObj &>
+</&>
+
+<& /Elements/Submit, Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), color => "#993333" &>
+</form>
+<%INIT>
+
+my $TicketObj = LoadTicket($id);
+my $CustomFields = $TicketObj->QueueObj->TicketCustomFields();
+
+# Now let callbacks have a chance at editing %ARGS
+$m->comp('/Elements/Callback', TicketObj => $TicketObj, CustomFields => $CustomFields, ARGSRef => \%ARGS);
+
+my @results = ProcessTicketBasics(TicketObj => $TicketObj, ARGSRef => \%ARGS);
+my @cf_results = ProcessObjectCustomFieldUpdates(Object => $TicketObj, ARGSRef => \%ARGS);
+push (@results, @cf_results);
+
+# undef so that TransactionBatch scrips run and update the ticket
+$TicketObj = undef;
+$TicketObj = LoadTicket($id);
+
+# TODO: display the results, even if we can't display the ticket
+
+unless ($TicketObj->CurrentUserHasRight('ShowTicket')) {
+ Abort("No permission to view ticket");
+}
+
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Ticket/ModifyAll.html b/rt/html/Ticket/ModifyAll.html
new file mode 100644
index 000000000..7f7ae30bd
--- /dev/null
+++ b/rt/html/Ticket/ModifyAll.html
@@ -0,0 +1,221 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc("Ticket #[_1] Jumbo update: [_2]", $Ticket->Id, $Ticket->Subject) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $Ticket,
+ current_tab => "Ticket/ModifyAll.html?id=".$Ticket->Id,
+ Title => loc("Ticket #[_1] Jumbo update: [_2]", $Ticket->Id, $Ticket->Subject) &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" action="ModifyAll.html" enctype="multipart/form-data">
+<& /Elements/Callback, _CallbackName => 'FormStart',ARGSRef =>\%ARGS &>
+<input type="hidden" class="hidden" name="id" value="<%$Ticket->Id%>" />
+
+<&| /Widgets/TitleBox, title => loc('Modify ticket # [_1]', $Ticket->Id) &>
+<& Elements/EditBasics, TicketObj => $Ticket &>
+<& Elements/EditCustomFields, TicketObj => $Ticket &>
+</&>
+
+<br />
+
+<&| /Widgets/TitleBox, title => loc('Dates') &>
+<& Elements/EditDates, TicketObj => $Ticket &>
+</&>
+
+<br />
+
+
+<&| /Widgets/TitleBox, title => loc('People') &>
+<& Elements/EditPeople, Ticket => $Ticket, UserField => $UserField, UserString => $UserString, UserOp => $UserOp &>
+</&>
+
+<br />
+
+<&| /Widgets/TitleBox, title => loc('Links') &>
+<& /Elements/EditLinks, Object => $Ticket, Merge => 1 &>
+</&>
+
+<br />
+
+<&| /Widgets/TitleBox, title => loc('Update ticket') &>
+<table>
+ <tr>
+ <td class="label"><&|/l&>Update Type</&>:</td>
+ <td class="entry">
+ <select name="UpdateType">
+% if ($CanComment) {
+ <option value="private" ><&|/l&>Comments (Not sent to requestors)</&></option>
+% }
+% if ($CanRespond) {
+ <option value="response"><&|/l&>Reply to requestors</&></option>
+% }
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Subject</&>:</td>
+ <td class="entry"><input name="UpdateSubject" size="60" value="<%$Ticket->Subject%>" /></td>
+ </tr>
+% if (my $TxnCFs = $Ticket->TransactionCustomFields) {
+% while (my $CF = $TxnCFs->Next()) {
+<tr>
+<td class="label"><% $CF->Name %>:</td>
+<td class="entry"><& /Elements/EditCustomField,
+ CustomField => $CF,
+ NamePrefix => "Object-RT::Transaction--CustomField-"
+ &><em><% $CF->FriendlyType %></em></td>
+</td></tr>
+% } # end if while
+% } # end of if
+ <tr>
+ <td class="label"><&|/l&>Attach</&>:</td>
+ <td class="entry"><input name="UpdateAttachment" type="file" /></td>
+ </tr>
+ <tr>
+ <td class="labeltop"><&|/l&>Content</&>:</td>
+ <td class="entry"><& /Elements/MessageBox, Name=>"UpdateContent", QuoteTransaction=>$ARGS{QuoteTransaction} &></td>
+ </tr>
+</table>
+</&>
+
+
+<& /Elements/Submit,
+ Label => loc('Save Changes'),
+ Caption => loc("If you've updated anything above, be sure to"), color => "#333399" &>
+</form>
+
+<%INIT>
+
+
+
+my $Ticket = LoadTicket($id);
+
+my $CanRespond = 0;
+my $CanComment = 0;
+
+
+$CanRespond = 1 if ( $Ticket->CurrentUserHasRight('ReplyToTicket') or
+ $Ticket->CurrentUserHasRight('ModifyTicket') );
+
+$CanComment = 1 if ( $Ticket->CurrentUserHasRight('CommentOnTicket') or
+ $Ticket->CurrentUserHasRight('ModifyTicket') );
+
+
+$m->comp('/Elements/Callback', TicketObj => $Ticket, ARGSRef => \%ARGS);
+my (@wresults, @results, @dresults, @lresults, @cf_results);
+
+unless ($OnlySearchForPeople) {
+ # There might be two owners.
+ if ( ref ($ARGS{'Owner'} )) {
+ my @owners =@{$ARGS{'Owner'}};
+ delete $ARGS{'Owner'};
+ foreach my $owner(@owners){
+ $ARGS{'Owner'} = $owner unless ($Ticket->OwnerObj->id == $owner);
+ }
+
+ }
+
+ @wresults = ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS);
+ @cf_results = ProcessObjectCustomFieldUpdates( Object => $Ticket, ARGSRef => \%ARGS);
+ @dresults = ProcessTicketDates( TicketObj => $Ticket, ARGSRef => \%ARGS);
+ @lresults = ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS);
+
+ if ($ARGS{'UpdateAttachment'}) {
+ my $subject = "$ARGS{'UpdateAttachment'}";
+ # since CGI.pm deutf8izes the magic field, we need to add it back.
+ Encode::_utf8_on($subject);
+ # strip leading directories
+ $subject =~ s#^.*[\\/]##;
+
+ my $attachment = MakeMIMEEntity(
+ Subject => $subject,
+ Body => "",
+ AttachmentFieldName => 'UpdateAttachment'
+ );
+ delete $ARGS{'UpdateAttachment'};
+ $ARGS{'UpdateAttachments'}->{ $subject } = $attachment;
+ }
+
+ $ARGS{'UpdateContent'} =~ s/\r+\n/\n/g if $ARGS{'UpdateContent'};
+
+ if ($ARGS{'UpdateAttachments'} || ( $ARGS{'UpdateContent'} && $ARGS{'UpdateContent'} ne "-- \n" .
+ $session{'CurrentUser'}->UserObj->Signature)) {
+ ProcessUpdateMessage(TicketObj => $Ticket, ARGSRef=>\%ARGS, Actions=>\@results);
+ }
+ @results = ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS);
+}
+push @results, @wresults;
+push @results, @dresults;
+push @results, @lresults;
+push @results, @cf_results;
+
+# undef so that TransactionBatch scrips run and update the ticket
+$Ticket = undef;
+$Ticket = LoadTicket($id);
+
+# If they've gone and moved the ticket to somewhere they can't see, etc...
+# TODO: display the results, even if we can't display the ticket.
+
+unless ($Ticket->CurrentUserHasRight('ShowTicket')) {
+ Abort("No permission to view ticket");
+}
+
+
+</%INIT>
+
+
+
+<%ARGS>
+$OnlySearchForPeople => undef
+$UserField => undef
+$UserOp => undef
+$UserString => undef
+$id => undef
+</%ARGS>
+
diff --git a/rt/html/Ticket/ModifyCustomers.html b/rt/html/Ticket/ModifyCustomers.html
new file mode 100644
index 000000000..72d103b23
--- /dev/null
+++ b/rt/html/Ticket/ModifyCustomers.html
@@ -0,0 +1,49 @@
+%# Copyright (c) 2004 Ivan Kohler <ivan-rt@420.am>
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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.
+<& /Elements/Header, Title => loc("Customers for ticket #[_1]", $Ticket->Id) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $Ticket,
+ current_tab => "Ticket/ModifyCustomers.html?id=".$Ticket->Id,
+ Title => loc("Customers for ticket #[_1]", $Ticket->Id) &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<form action="ModifyCustomers.html" method="post">
+<input type="hidden" name="id" value="<%$Ticket->id%>">
+
+<& /Elements/TitleBoxStart, title => loc('Edit Customer Links'), color => "#7f007b"&>
+<& Elements/EditCustomers, Ticket => $Ticket, CustomerString => $CustomerString, ServiceString => $ServiceString &>
+<& /Elements/TitleBoxEnd &>
+<& /Elements/Submit, color => "#7f007b", Label => loc('Save Changes') &>
+</form>
+
+
+<%INIT>
+
+my @results = ();
+my $Ticket = LoadTicket($id);
+
+# if we're trying to search for customers/services and nothing else
+unless ( $OnlySearchForCustomers || $OnlySearchForServices) {
+ @results = ProcessTicketCustomers( TicketObj => $Ticket, ARGSRef => \%ARGS);
+}
+
+</%INIT>
+
+
+<%ARGS>
+$OnlySearchForCustomers => undef
+$OnlySearchForServices => undef
+$CustomerString => undef
+$ServiceString => undef
+$id => undef
+</%ARGS>
diff --git a/rt/html/Ticket/ModifyDates.html b/rt/html/Ticket/ModifyDates.html
new file mode 100644
index 000000000..d12619002
--- /dev/null
+++ b/rt/html/Ticket/ModifyDates.html
@@ -0,0 +1,77 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc('Modify dates for #[_1]', $TicketObj->Id) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $TicketObj,
+ current_tab => "Ticket/ModifyDates.html?id=".$TicketObj->Id,
+ Title => loc('Modify dates for #[_1]', $TicketObj->Id) &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" action="ModifyDates.html">
+<& /Elements/Callback, _CallbackName => 'FormStart',ARGSRef =>\%ARGS &>
+<input type="hidden" class="hidden" name="id" value="<%$TicketObj->Id%>" />
+<&| /Widgets/TitleBox,title => loc('Modify dates for ticket # [_1]', $TicketObj->Id) &>
+<& Elements/EditDates, TicketObj => $TicketObj &>
+</&>
+<& /Elements/Submit, Label => loc('Save Changes') &>
+</form>
+
+
+<%INIT>
+
+my $TicketObj = LoadTicket($id);
+$m->comp('/Elements/Callback', TicketObj => $TicketObj, ARGSRef => \%ARGS);
+my @results = ProcessTicketDates( TicketObj => $TicketObj, ARGSRef => \%ARGS);
+
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Ticket/ModifyLinks.html b/rt/html/Ticket/ModifyLinks.html
new file mode 100644
index 000000000..93c80db18
--- /dev/null
+++ b/rt/html/Ticket/ModifyLinks.html
@@ -0,0 +1,82 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc("Link ticket #[_1]", $Ticket->Id) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $Ticket,
+ current_tab => "Ticket/ModifyLinks.html?id=".$Ticket->Id,
+ Title => loc("Link ticket #[_1]", $Ticket->Id) &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<form action="ModifyLinks.html" method="post">
+<input type="hidden" class="hidden" name="id" value="<%$Ticket->id%>" />
+<& /Elements/Callback, _CallbackName => 'FormStart',ARGSRef =>\%ARGS &>
+<&| /Widgets/TitleBox, title => loc('Edit Links') &>
+
+<& /Elements/EditLinks, Object => $Ticket, Merge => 1 &>
+</&>
+<& /Elements/Submit, Label => loc('Save Changes') &>
+</form>
+
+
+
+
+<%INIT>
+
+my $Ticket = LoadTicket($id);
+
+my @results;
+$m->comp('/Elements/Callback', TicketObj => $Ticket, ARGSRef => \%ARGS, Results => \@results );
+push @results, ProcessTicketLinks( TicketObj => $Ticket, ARGSRef => \%ARGS );
+
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Ticket/ModifyPeople.html b/rt/html/Ticket/ModifyPeople.html
new file mode 100644
index 000000000..aa3811269
--- /dev/null
+++ b/rt/html/Ticket/ModifyPeople.html
@@ -0,0 +1,94 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc('Modify people related to ticket #[_1]', $Ticket->id) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $Ticket,
+ current_tab => "Ticket/ModifyPeople.html?id=".$Ticket->Id,
+ Title => loc('Modify people related to ticket #[_1]', $Ticket->id) &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" action="ModifyPeople.html">
+<input type="hidden" class="hidden" name="id" value="<%$Ticket->Id%>" />
+<& /Elements/Callback, _CallbackName => 'FormStart',ARGSRef =>\%ARGS &>
+<&| /Widgets/TitleBox, title => loc('Modify people related to ticket #[_1]', $Ticket->Id), width => "100%", color=> "#333399" &>
+<& Elements/EditPeople, Ticket => $Ticket, UserField => $UserField, UserString => $UserString, UserOp => $UserOp, GroupString => $GroupString, GroupOp => $GroupOp, GroupField => $GroupField &>
+</&>
+<& /Elements/Submit, Label => loc('Save Changes'), Caption => loc("If you've updated anything above, be sure to"), color => "#333399" &>
+</form>
+
+<%INIT>
+
+my (@results, @wresults);
+
+my $Ticket = LoadTicket($id);
+$m->comp('/Elements/Callback', TicketObj => $Ticket, ARGSRef => \%ARGS);
+
+# if we're trying to search for watchers and nothing else
+unless ($OnlySearchForPeople or $OnlySearchForGroup) {
+ @results = ProcessTicketBasics( TicketObj => $Ticket, ARGSRef => \%ARGS);
+ @wresults = ProcessTicketWatchers( TicketObj => $Ticket, ARGSRef => \%ARGS);
+}
+
+push @results, @wresults;
+</%INIT>
+
+
+
+<%ARGS>
+$OnlySearchForPeople => undef
+$OnlySearchForGroup => undef
+$UserField => undef
+$UserOp => undef
+$UserString => undef
+$GroupField => undef
+$GroupOp => undef
+$GroupString => undef
+$id => undef
+</%ARGS>
+
diff --git a/rt/html/Ticket/Reminders.html b/rt/html/Ticket/Reminders.html
new file mode 100755
index 000000000..2a3ba4c08
--- /dev/null
+++ b/rt/html/Ticket/Reminders.html
@@ -0,0 +1,71 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc("Reminder ticket #[_1]", $Ticket->Id) &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $Ticket,
+ current_tab => "Ticket/Reminders.html?id=".$Ticket->Id,
+ Title => loc("Reminders for ticket #[_1]", $Ticket->Id) &>
+<form action="<%$RT::WebPath%>/Ticket/Reminders.html" method="post">
+<&|/Widgets/TitleBox, title => loc("Reminders"),
+ title_class=> 'inverse',
+ color => "#666699" &>
+
+<& /Ticket/Elements/Reminders, Ticket => $Ticket, ShowCompleted => 1, Edit => 1 &>
+</&>
+<& /Elements/Submit, Label => 'Save'&>
+</form>
+
+
+<%INIT>
+
+my $Ticket = LoadTicket($id);
+
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/html/Ticket/ShowEmailRecord.html b/rt/html/Ticket/ShowEmailRecord.html
new file mode 100644
index 000000000..f77406c77
--- /dev/null
+++ b/rt/html/Ticket/ShowEmailRecord.html
@@ -0,0 +1,73 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Attachment => undef
+$Transaction => undef
+</%ARGS>
+<%init>
+ my $AttachmentObj = new RT::Attachment($session{'CurrentUser'});
+ $AttachmentObj->Load($Attachment) || Abort(loc("Attachment '[_1]' could not be loaded", $Attachment));
+
+
+ unless ($AttachmentObj->id) {
+ Abort(loc("Attachment '[_1]' could not be loaded", $Attachment));
+ }
+ unless ($AttachmentObj->TransactionId() == $Transaction ) {
+ Abort(loc("Attachment '[_1]' could not be loaded", $Attachment));
+ }
+
+</%init>
+<& /Elements/Header, ShowBar => 0 &>
+<pre style="padding: 2em;">
+<%$AttachmentObj->Headers%>
+
+<%$AttachmentObj->Content%>
+</pre>
+</body>
+</html>
+%$m->abort;
diff --git a/rt/html/Ticket/Update.html b/rt/html/Ticket/Update.html
new file mode 100644
index 000000000..3824873b5
--- /dev/null
+++ b/rt/html/Ticket/Update.html
@@ -0,0 +1,228 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title &>
+<& /Ticket/Elements/Tabs,
+ Ticket => $TicketObj,
+ Title=> $title &>
+
+<form action="Update.html" name="TicketUpdate"
+ method="post" enctype="multipart/form-data">
+<& /Elements/Callback, _CallbackName => 'FormStart',ARGSRef =>\%ARGS &>
+<input type="hidden" class="hidden" name="QuoteTransaction" value="<% $ARGS{QuoteTransaction} %>" />
+<input type="hidden" class="hidden" name="DefaultStatus" value="<% $DefaultStatus %>" />
+<input type="hidden" class="hidden" name="Action" value="<% $ARGS{Action} %>" />
+<table width="100%" border="0">
+
+<tr><td align="right"><&|/l&>Status</&>:</td>
+<td>
+<& /Elements/SelectStatus, Name=>"Status", DefaultLabel => loc("[_1] (Unchanged)", loc($TicketObj->Status)), Default => $ARGS{'Status'} || ($TicketObj->Status eq $DefaultStatus ? undef : $DefaultStatus)&>
+<&|/l&>Owner</&>:
+<& /Elements/SelectOwner, Name=>"Owner", DefaultLabel => loc("[_1] (Unchanged)", $TicketObj->OwnerObj->Name()), QueueObj => $TicketObj->QueueObj, TicketObj => $TicketObj, Default => $ARGS{'Owner'} &>
+<&|/l&>Worked</&>: <input size="4" name="UpdateTimeWorked" value="<% $ARGS{UpdateTimeWorked} %>" />
+<& /Elements/SelectTimeUnits, Name => 'UpdateTimeWorked'&>
+</td></tr>
+% my $skip;
+<& /Elements/Callback, _CallbackName => 'BeforeUpdateType', skip => \$skip, %ARGS &>
+% if (!$skip) {
+<input type="hidden" class="hidden" name="id" value="<%$TicketObj->Id%>" /><br />
+% }
+<tr><td align="right"><&|/l&>Update Type</&>:</td>
+<td><select name="UpdateType">
+% if ($CanComment) {
+ <option value="private" <%$ARGS{'UpdateType'} eq "private" ? "SELECTED" : !$ARGS{'UpdateType'}&&$CommentDefault%>><&|/l&>Comments (Not sent to requestors)</&></option>
+% }
+% if ($CanRespond) {
+ <option value="response" <%$ARGS{'UpdateType'} eq "response" ? "SELECTED" : !$ARGS{'UpdateType'}&&$ResponseDefault%>><&|/l&>Reply to requestors</&></option>
+% }
+</select>
+</td></tr>
+<tr><td align="right"><&|/l&>Subject</&>:</td><td> <input name="UpdateSubject" size="60" value="<% $ARGS{UpdateSubject} || $TicketObj->Subject()%>" /></td></tr>
+<tr><td align="right"><&|/l&>Cc</&>:</td><td> <input name="UpdateCc" size="60"
+value="<%$ARGS{UpdateCc}||""%>" /><br />
+<i><font size="-2">
+<&|/l&>(Sends a carbon-copy of this update to a comma-delimited list of email addresses. Does <strong>not</strong> change who will receive future updates.)</&></font></i>
+</td></tr>
+<tr><td align="right"><&|/l&>Bcc</&>:</td><td> <input name="UpdateBcc" size="60" value="<%$ARGS{UpdateBcc}||""%>" /><br />
+<i><font size="-2">
+<&|/l&>(Sends a blind carbon-copy of this update to a comma-delimited list of email addresses. Does <strong>not</strong> change who will receive future updates.)</&></font></i>
+</td></tr>
+% if (exists $session{'Attachments'}) {
+<td>
+<&|/l&>Attached file</&>:
+</td>
+<td colspan="5">
+<&|/l&>Check box to delete</&><br />
+% foreach my $attach_name (keys %{$session{'Attachments'}}) {
+<input type="checkbox" class="checkbox" name="DeleteAttach-<%$attach_name%>" value="1" /><%$attach_name%><br />
+% } # end of foreach
+</td>
+</tr>
+<tr>
+% } # end of if
+
+% if (my $TxnCFs = $TicketObj->TransactionCustomFields) {
+% while (my $CF = $TxnCFs->Next()) {
+<tr>
+<td align="right"><% $CF->Name %>:</td>
+<td><& /Elements/EditCustomField, CustomField => $CF, NamePrefix =>
+ "Object-RT::Transaction--CustomField-" &><em><% $CF->FriendlyType %></em></td>
+</tr>
+% } # end if while
+% } # end of if
+
+<tr><td align="right"><&|/l&>Attach</&>:</td><td><input name="Attach" type="file" /><input type="submit" class="button" name="AddMoreAttach" value="<&|/l&>Add More Files</&>" /><input type="hidden" class="hidden" name="UpdateAttach" value="1" />
+</td></tr>
+<tr><td align="right" valign="top"><&|/l&>Message</&>:</td><td>
+<& /Elements/Callback, _CallbackName => 'BeforeMessageBox', %ARGS &>
+% if (exists $ARGS{UpdateContent}) {
+% # preserve QuoteTransaction so we can use it to set up sane references/in/reply to
+% my $temp = $ARGS{'QuoteTransaction'};
+% delete $ARGS{'QuoteTransaction'};
+<& /Elements/MessageBox, Name=>"UpdateContent", Default=>$ARGS{UpdateContent}, IncludeSignature => 0, %ARGS&>
+% $ARGS{'QuoteTransaction'} = $temp;
+% } else {
+<& /Elements/MessageBox, Name=>"UpdateContent", %ARGS &>
+% }
+</td></tr>
+</table>
+
+
+
+
+<& /Elements/Submit, Label => loc('Update Ticket'), Name => 'SubmitTicket' &>
+% if ($TicketObj->CurrentUserHasRight('ShowOutgoingEmail')) {
+<& /Ticket/Elements/PreviewScrips, TicketObj => $TicketObj, %ARGS &>
+% }
+</form>
+<%INIT>
+my $CanRespond = 0;
+my $CanComment = 0;
+my $title;
+
+my $TicketObj = LoadTicket($id);
+
+unless($DefaultStatus){
+ $DefaultStatus=($ARGS{'Status'} ||$TicketObj->Status());
+}
+
+if ($DefaultStatus =~ '^new$'){
+ $DefaultStatus='open';
+}
+
+if ($DefaultStatus eq 'resolved') {
+ $title = loc("Resolve ticket #[_1] ([_2])", $TicketObj->id, $TicketObj->Subject);
+} else {
+ $title = loc("Update ticket #[_1] ([_2])", $TicketObj->id, $TicketObj->Subject);
+}
+
+# Things needed in the template - we'll do the processing here, just
+# for the convenience:
+
+my ($CommentDefault, $ResponseDefault);
+if ($Action ne 'Respond') {
+ $CommentDefault = "SELECTED";
+} else {
+ $ResponseDefault = "SELECTED";
+}
+
+
+$CanRespond = 1 if ( $TicketObj->CurrentUserHasRight('ReplyToTicket') or
+ $TicketObj->CurrentUserHasRight('ModifyTicket') );
+
+$CanComment = 1 if ( $TicketObj->CurrentUserHasRight('CommentOnTicket') or
+ $TicketObj->CurrentUserHasRight('ModifyTicket') );
+
+
+# {{{ deal with deleting uploaded attachments
+foreach my $key (keys %ARGS) {
+ if ($key =~ m/^DeleteAttach-(.+)$/) {
+ delete $session{'Attachments'}{$1};
+ }
+ $session{'Attachments'} = { %{$session{'Attachments'} || {}} };
+}
+# }}}
+
+# {{{ store the uploaded attachment in session
+if ($ARGS{'Attach'}) { # attachment?
+ $session{'Attachments'} = {} unless defined $session{'Attachments'};
+
+ my $subject = "$ARGS{'Attach'}";
+ # since CGI.pm deutf8izes the magic field, we need to add it back.
+ Encode::_utf8_on($subject);
+ # strip leading directories
+ $subject =~ s#^.*[\\/]##;
+
+ my $attachment = MakeMIMEEntity(
+ Filename => $subject,
+ Body => "",
+ AttachmentFieldName => 'Attach'
+ );
+
+ $session{'Attachments'} = { %{$session{'Attachments'} || {}},
+ $ARGS{'Attach'} => $attachment };
+}
+# }}}
+
+# delete temporary storage entry to make WebUI clean
+unless (keys %{$session{'Attachments'}} and $ARGS{'UpdateAttach'}) {
+ delete $session{'Attachments'};
+}
+# }}}
+
+if ( exists $ARGS{SubmitTicket} ) {
+ $m->comp('Display.html', TicketObj => $TicketObj, %ARGS);
+ return;
+}
+
+</%INIT>
+
+<%ARGS>
+$id => undef
+$Action => undef
+$DefaultStatus => undef
+</%ARGS>
diff --git a/rt/html/Tools/Elements/Tabs b/rt/html/Tools/Elements/Tabs
new file mode 100644
index 000000000..cd6d16916
--- /dev/null
+++ b/rt/html/Tools/Elements/Tabs
@@ -0,0 +1,84 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Tabs,
+ tabs => $tabs,
+ current_toptab => 'Tools/index.html',
+ current_tab => $current_tab,
+ Title => $Title &>
+
+<%INIT>
+my $tabs = {
+ a => {
+ title => loc('Offline'),
+ path => 'Tools/Offline.html',
+ },
+ b => {
+ title => loc('Reports'),
+ path => 'Tools/Reports/index.html',
+ },
+ c => {
+ title => loc('My Day'),
+ path => 'Tools/MyDay.html',
+ },
+};
+
+$m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+foreach my $tab ( sort keys %{$tabs} ) {
+ if ( $tabs->{$tab}->{'path'} eq $current_tab ) {
+ $tabs->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{$tab}->{"current_subtab"} = $current_subtab;
+ }
+}
+</%INIT>
+<%ARGS>
+$subtabs => undef
+$current_tab => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Tools/MyDay.html b/rt/html/Tools/MyDay.html
new file mode 100644
index 000000000..dbda0f9aa
--- /dev/null
+++ b/rt/html/Tools/MyDay.html
@@ -0,0 +1,117 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title &>
+<& /Tools/Elements/Tabs, current_tab => "Tools/MyDay.html", Title => $title &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<&|/l, $session{'CurrentUser'}->Name&>(displaying new and open tickets for [_1])</&>
+<form method="post" action="MyDay.html">
+<table width="100%" cellpadding="0" cellspacing="0">
+% while ( my $Ticket = $Tickets->Next()) {
+% my $class;
+% $i++;
+% if ($i % 2 ) {
+% $class = 'class="oddline"';
+% }
+<tr <%$class|n%>><td colspan="2"><h2><a
+href="<%$RT::WebPath%>/Ticket/Display.html?id=<%$Ticket->Id%>"><%$Ticket->Id%>:
+<%$Ticket->Subject%></a></h2></td></tr>
+<tr <%$class|n%>><td><span class="label"><&|/l&>Worked</&>:</span><input size="3" name="UpdateTimeWorked-<%$Ticket->Id%>" /> <&|/l&>minutes</&>
+</td>
+<td rowspan="2"><span class="label"><&|/l&>Comments</&>:<br /></span><textarea name="UpdateContent-<%$Ticket->Id%>" rows="5"
+cols="60"></textarea></td></tr>
+<tr <%$class|n%>>
+<td><span class="label"><&|/l&>Status</&>:</span> <& /Elements/SelectStatus, Name=> 'UpdateStatus-'.$Ticket->Id,
+ DefaultLabel => loc("[_1] (Unchanged)",loc($Ticket->Status())) &></td>
+ </tr>
+
+% }
+</table>
+<& /Elements/Submit, Label => "Record all updates" , Reset => 'Clear'&>
+</form>
+</html>
+<%INIT>
+my $title = loc("What I did today");
+
+my $i = 0;
+my @results;
+foreach my $arg ( keys %ARGS ) {
+ next unless ( $arg =~ /^UpdateStatus-(\d*)$/ );
+ my $id = $1;
+ my $ticket = LoadTicket($id);
+ next unless ( $ticket->id );
+ if ( my $content = $ARGS{'UpdateContent-'.$id} ) {
+ my ( $val, $msg ) = $ticket->Comment(
+ Content => $content,
+ TimeTaken => $ARGS{ 'UpdateTimeWorked-' . $id }
+ );
+ push @results, loc( "Ticket [_1]: [_2]", $id, $msg );
+ } elsif ( my $worked = $ARGS{ 'UpdateTimeWorked-' . $id } ) {
+ my ( $val, $msg ) = $ticket->SetTimeWorked( $worked + $ticket->TimeWorked );
+ push @results, loc( "Ticket [_1]: [_2]", $id, $msg );
+ }
+
+ if ( my $status = $ARGS{ 'UpdateStatus-' . $id } ) {
+ if ( $status ne $ticket->Status ) {
+ my ( $val, $msg ) = $ticket->SetStatus($status);
+ push @results, loc( "Ticket [_1]: [_2]", $id, $msg );
+
+ }
+ }
+
+}
+
+my $Tickets = RT::Tickets->new($session{'CurrentUser'});
+$Tickets->LimitOwner(VALUE => $session{'CurrentUser'}->Id);
+$Tickets->LimitStatus( VALUE => 'open' );
+$Tickets->LimitStatus ( VALUE => 'new');
+$Tickets->OrderBy ( FIELD => 'Priority', ORDER => 'DESC');
+
+
+</%INIT>
diff --git a/rt/html/Tools/Offline.html b/rt/html/Tools/Offline.html
new file mode 100644
index 000000000..385e6add8
--- /dev/null
+++ b/rt/html/Tools/Offline.html
@@ -0,0 +1,166 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc("Offline upload") &>
+<& Elements/Tabs,
+ current_tab => "Tools/Offline.html",
+ Title => loc("Offline edits") &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<& /Elements/Callback, Requestor => \$requestoraddress,
+ Queue => \$qname, %ARGS &>
+
+<form action="Offline.html" name="TicketUpdate"
+ method="post" enctype="multipart/form-data">
+<table>
+<tr>
+<td class="label">
+<&|/l&>Default Queue</&>:
+</td>
+<td>
+<& /Elements/SelectQueue, Name => "qname", NamedValues => 1 &>
+<em><&|/l&>If no queue is specified, create tickets in this queue.</&></em>
+</td>
+</tr>
+<tr>
+<td class="label">
+<&|/l&>Default Requestor</&>:
+</td>
+<td>
+<input name="requestoraddress" value="<%$requestoraddress%>" />
+<em><&|/l&>If no Requestor is specified, create tickets with this requestor.</&></em>
+</td>
+</tr>
+<tr><td class="labeltop">
+<&|/l&>Template</&>:
+</td>
+<td colspan="2">
+<textarea name="string" cols="80" rows="30"><%$string%></textarea>
+</td>
+</tr>
+<tr><td class="label">
+<&|/l&>Get template from file</&>:
+</td>
+<td>
+<input name="Template" type="file" value="foo" />
+<input type="submit" class="button" name="Parse" value="<&|/l&>Go!</&>" />
+</td>
+</tr>
+</table>
+<& /Elements/Submit, Name => 'UpdateTickets', Label => loc('Upload'), Caption => loc("Upload your changes"), color => "#993333" &>
+
+</form>
+<%args>
+$requestoraddress => ''
+$qname => undef
+$string => undef
+</%args>
+<%INIT>
+
+my @results;
+use RT::Action::CreateTickets;
+my $action = RT::Action::CreateTickets->new(CurrentUser => $session{'CurrentUser'});
+;
+if ($ARGS{'Parse'} && $ARGS{'Template'}) {
+ $string = "";
+ my $cgi_object = $m->cgi_object;
+ my $fh = $cgi_object->upload('Template');
+ my $filename = "$fh";
+
+ my ($buffer, $template);
+ while ( my $bytesread = read( $fh, $buffer, 4096 ) ) {
+ $template .= $buffer;
+ }
+ $template =~ s/\r\n/\n/gs;
+ $action->Parse(Content => $template, Queue => $qname, Requestor => $requestoraddress);
+ foreach ( @{ $action->{'create_tickets'} } ) {
+ my $id = $_;
+ $id =~ s/^create\-//;
+ $string .= "===Create-Ticket: $id\n";
+ $string .= $action->{'templates'}->{$_} . "\n";
+ }
+ foreach ( @{ $action->{'update_tickets'} } ) {
+ my $id = $_;
+ $id =~ s/^update\-//;
+ $string .= "===Update-Ticket: $id\n";
+ $string .= $action->{'templates'}->{$_} . "\n";
+ }
+
+
+} elsif ($ARGS{'UpdateTickets'}) {
+ $action->Parse(Content => $ARGS{string}, Queue => $qname, Requestor=> $requestoraddress);
+ push @results, $action->CreateByTemplate();
+ push @results, $action->UpdateByTemplate();
+} else {
+ if ($ARGS{'Query'}) {
+ my $Tickets = RT::Tickets->new($session{'CurrentUser'});
+ $Tickets->FromSQL($ARGS{'Query'});
+
+ while (my $t = $Tickets->Next) {
+ $string .= "===Update-Ticket: " . $t->Id . "\n";
+ $string .= $action->GetUpdateTemplate($t);
+ $string .= "" . "\n";
+ }
+
+ $string .= "" . "\n";
+ $string .= "===# DO NOT EDIT BELOW THIS LINE#===\n";
+ $string .= "" . "\n";
+
+ while (my $t = $Tickets->Next) {
+ $string .= "===# DO NOT EDIT #===\n";
+ $string .= "===Base-Ticket: " . $t->Id . "\n";
+ $string .= $action->GetBaseTemplate($t);
+ $string .= "===# DO NOT EDIT #===\n";
+ $string .= "" . "\n";
+ }
+ } else {
+ $string .= "===Create-Ticket: ticket1\n";
+ $string .= $action->GetCreateTemplate();
+ }
+}
+</%INIT>
diff --git a/rt/html/Tools/Reports/CreatedByDates.html b/rt/html/Tools/Reports/CreatedByDates.html
new file mode 100644
index 000000000..b6d6f940a
--- /dev/null
+++ b/rt/html/Tools/Reports/CreatedByDates.html
@@ -0,0 +1,94 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Queue => undef
+$CreatedBefore => undef
+$CreatedAfter => undef
+</%args>
+<%init>
+my $title = loc("Created tickets in period, grouped by status");
+my $q = RT::Queue->new($session{'CurrentUser'});
+my $before = RT::Date->new($session{'CurrentUser'});
+my $after = RT::Date->new($session{'CurrentUser'});
+my $query = 'Status != "deleted" ';
+
+
+if ($CreatedAfter) {
+ $after->Set(Format => 'unknown', Value => $CreatedAfter);
+ $CreatedAfter = $after->AsString;
+}
+if ($CreatedBefore) {
+ $before->Set(Format => 'unknown', Value => $CreatedBefore);
+ $CreatedBefore = $before->AsString;
+}
+
+
+$q->LoadByCols(Name => $Queue);
+</%init>
+<& /Elements/Header, Title => $title &>
+<& /Tools/Reports/Elements/Tabs, current_tab => 'Tools/Reports/CreatedByDates.html', Title => $title &>
+<form method="post" action="CreatedByDates.html">
+% if ($Queue|| $CreatedBefore ||$CreatedAfter) {
+% # if we have a queue, do the search
+% if ($Queue) { $query .= " AND Queue = '$Queue'"}
+% if ($CreatedBefore) { $query .= " AND Created < '".$before->ISO."'"; }
+% if ($CreatedAfter) { $query .= " AND Created > '".$after->ISO."'"}
+% my $groupby = 'Status';
+<& /Search/Elements/Chart, Query => $query, PrimaryGroupBy => $groupby &>
+% }
+
+<hr>
+
+<br /><&|/l&>Queue</&>: <& /Elements/SelectQueue, Name => 'Queue', NamedValues => 1, Default => $q->id &>
+<br /><&|/l&>Tickets created after</&>:
+<input size="20" name="CreatedAfter" value="<%$CreatedAfter%>" />
+<br /><&|/l&>Tickets created before</&>:
+<input size="20" name="CreatedBefore" value="<%$CreatedBefore%>" />
+
+<& /Elements/Submit&>
+</form>
diff --git a/rt/html/Tools/Reports/Elements/Tabs b/rt/html/Tools/Reports/Elements/Tabs
new file mode 100644
index 000000000..18829f085
--- /dev/null
+++ b/rt/html/Tools/Reports/Elements/Tabs
@@ -0,0 +1,89 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Tools/Elements/Tabs,
+ subtabs => $tabs,
+ current_tab => 'Tools/Reports/index.html',
+ current_subtab => $current_tab,
+ Title => $Title &>
+
+<%INIT>
+my $tabs = {
+ a => {
+ title => loc('Resolved by owner'),
+ path => 'Tools/Reports/ResolvedByOwner.html',
+ },
+ b => {
+ title => loc('Resolved in date range'),
+ path => 'Tools/Reports/ResolvedByDates.html',
+ },
+ c => {
+ title => loc('Created in a date range'),
+ path => 'Tools/Reports/CreatedByDates.html',
+ },
+};
+
+
+
+
+$m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+foreach my $tab ( sort keys %{$tabs} ) {
+ if ( $tabs->{$tab}->{'path'} eq $current_tab ) {
+ $tabs->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{$tab}->{"current_subtab"} = $current_subtab;
+ }
+}
+</%INIT>
+
+
+<%ARGS>
+$subtabs => undef
+$current_tab => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/Tools/Reports/ResolvedByDates.html b/rt/html/Tools/Reports/ResolvedByDates.html
new file mode 100644
index 000000000..265a1caa4
--- /dev/null
+++ b/rt/html/Tools/Reports/ResolvedByDates.html
@@ -0,0 +1,95 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Queue => undef
+$ResolvedBefore => undef
+$ResolvedAfter => undef
+</%args>
+<%init>
+my $title = loc("Resolved tickets in period, grouped by owner");
+my $q = RT::Queue->new($session{'CurrentUser'});
+my $before = RT::Date->new($session{'CurrentUser'});
+my $after = RT::Date->new($session{'CurrentUser'});
+my $query = '';
+
+
+if ($ResolvedAfter) {
+ $after->Set(Format => 'unknown', Value => $ResolvedAfter);
+ $ResolvedAfter = $after->AsString;
+}
+if ($ResolvedBefore) {
+ $before->Set(Format => 'unknown', Value => $ResolvedBefore);
+ $ResolvedBefore = $before->AsString;
+}
+
+
+$q->LoadByCols(Name => $Queue);
+</%init>
+<& /Elements/Header, Title => $title &>
+<& /Tools/Reports/Elements/Tabs, current_tab => 'Tools/Reports/ResolvedByDates.html', Title => $title &>
+<form method="post" action="ResolvedByDates.html">
+% if ($Queue|| $ResolvedBefore ||$ResolvedAfter) {
+% # if we have a queue, do the search
+% $query = "Status = 'resolved'";
+% if ($Queue) { $query .= " AND Queue = '$Queue'"}
+% if ($ResolvedBefore) { $query .= " AND Resolved < '".$before->ISO."'"; }
+% if ($ResolvedAfter) { $query .= " AND Resolved > '".$after->ISO."'"}
+% my $groupby = 'Owner';
+<& /Search/Elements/Chart, Query => $query, PrimaryGroupBy => $groupby &>
+% }
+
+<hr>
+
+<br /><&|/l&>Queue</&>: <& /Elements/SelectQueue, Name => 'Queue', NamedValues => 1, Default => $q->id &>
+<br /><&|/l&>Tickets resolved after</&>:
+<input size="20" name="ResolvedAfter" value="<%$ResolvedAfter%>" />
+<br /><&|/l&>Tickets resolved before</&>:
+<input size="20" name="ResolvedBefore" value="<%$ResolvedBefore%>" />
+
+<& /Elements/Submit&>
+</form>
diff --git a/rt/html/Tools/Reports/ResolvedByOwner.html b/rt/html/Tools/Reports/ResolvedByOwner.html
new file mode 100644
index 000000000..142af6475
--- /dev/null
+++ b/rt/html/Tools/Reports/ResolvedByOwner.html
@@ -0,0 +1,70 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%args>
+$Queue => undef
+</%args>
+<%init>
+my $title = loc("Resolved tickets, grouped by owner");
+my $q = RT::Queue->new($session{'CurrentUser'});
+$q->LoadByCols(Name => $Queue);
+</%init>
+<& /Elements/Header, Title => $title &>
+<& /Tools/Reports/Elements/Tabs, current_tab => '/Tools/Reports/ResolvedByOwner.html', Title => $title &>
+<form method="post" action="ResolvedByOwner.html">
+% if ($Queue) {
+% # if we have a queue, do the search
+% my $query = "Status = 'resolved' AND Queue = '$Queue'";
+% my $groupby = 'Owner';
+<& /Search/Elements/Chart, Query => $query, PrimaryGroupBy => $groupby &>
+% }
+
+<hr>
+
+<&|/l&>Queue</&>: <& /Elements/SelectQueue, Name => 'Queue', NamedValues => 1, Default => $q->id &>
+<& /Elements/Submit&>
+</form>
diff --git a/rt/html/Tools/Reports/index.html b/rt/html/Tools/Reports/index.html
new file mode 100644
index 000000000..149dc7619
--- /dev/null
+++ b/rt/html/Tools/Reports/index.html
@@ -0,0 +1,50 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc('Reports') &>
+<& /Tools/Reports/Elements/Tabs, Title => loc('Reports') &>
+<& /Elements/Callback &>
diff --git a/rt/html/Tools/index.html b/rt/html/Tools/index.html
new file mode 100644
index 000000000..8d2efdbed
--- /dev/null
+++ b/rt/html/Tools/index.html
@@ -0,0 +1,52 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc("Tools") &>
+<& Elements/Tabs,
+ current_tab => "Tools/index.html",
+ Title => loc("Tools") &>
+
diff --git a/rt/html/User/Delegation.html b/rt/html/User/Delegation.html
new file mode 100644
index 000000000..2587f8cde
--- /dev/null
+++ b/rt/html/User/Delegation.html
@@ -0,0 +1,107 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => loc("Delegate rights") &>
+<& /User/Elements/Tabs,
+ current_tab => 'User/Delegation.html',
+ Title => loc("Delegate rights") &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post">
+<& Elements/DelegateRights, personalgroups => $personalgroups, objects => $objects, ObjectType => 'RT::System' &>
+<& Elements/DelegateRights, personalgroups => $personalgroups, objects => $objects, ObjectType => 'RT::Queue' &>
+<& Elements/DelegateRights, personalgroups => $personalgroups, objects => $objects, ObjectType => 'RT::Group' &>
+
+<& /Elements/Submit, Label => loc('Modify Rights') &>
+</form>
+<%INIT>
+
+my (@results, $arg);
+foreach $arg (keys %ARGS) {
+ next unless ($arg =~ /^Delegate-Existing-ACE-(\d+)-to-(\d+)-as-(\d+)$/);
+ my $parent = $1;
+ my $principal = $2;
+ my $delegation = $3;
+ unless ($ARGS{"Delegate-ACE-$1-to-$2"}) {
+ my $ace_to_del = RT::ACE->new($session{'CurrentUser'});
+ $ace_to_del->Load($delegation);
+ my ($delval, $delmsg) = $ace_to_del->Delete();
+ push (@results, $delmsg);
+ }
+}
+
+foreach $arg (keys %ARGS) {
+ next unless ($arg =~ /^Delegate-ACE-(\d+)-to-(\d+)$/);
+ my $parent = $1;
+ my $principal = $2;
+ # if we already delegate it, we just don't care
+ next if (grep /^Delegate-Existing-ACE-$parent-to-$principal-/, keys %ARGS);
+ my $ace = RT::ACE->new($session{'CurrentUser'});
+ $ace->Load($1);
+ unless ($ace->Id) {
+ push (@results, loc('Right not found'));
+ next;
+ }
+ my ($delid, $delmsg) = $ace->Delegate(PrincipalId => $principal);
+ push (@results, $delmsg);
+}
+
+my $personalgroups = RT::Groups->new($session{'CurrentUser'});
+$personalgroups->LimitToPersonalGroupsFor($session{'CurrentUser'}->PrincipalId);
+
+my $objects;
+my $acl = RT::ACL->new ($session{'CurrentUser'});
+$acl->ExcludeDelegatedRights();
+$acl->LimitToPrincipal(Id => $session{'CurrentUser'}->PrincipalId,
+ IncludeGroupMembership => 1
+ );
+
+while(my $right = $acl->Next) {
+ push @{$objects->{$right->ObjectType}{$right->ObjectId}},$right;
+}
+</%INIT>
diff --git a/rt/html/User/Elements/DelegateRights b/rt/html/User/Elements/DelegateRights
new file mode 100644
index 000000000..3d42ed54e
--- /dev/null
+++ b/rt/html/User/Elements/DelegateRights
@@ -0,0 +1,109 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<h2><%$sectionheading%></h2>
+<%perl>
+
+foreach my $object (keys %{$objects->{$ObjectType}}) {
+unless ($ObjectType eq 'RT::System') {
+my $object_obj = @{$objects->{$ObjectType}{$object}}[0]->Object;
+
+</%perl>
+<h3><% $object_obj->Name %></h3>
+% }
+<table width="100%" border="0" cellspacing="0" cellpadding="3">
+<tr>
+ <th width="15%"><&|/l&>Personal groups:</&></th>
+% while (my $pg = $personalgroups->Next) {
+<th><%$pg->Name%></th>
+% }
+</tr>
+<%perl>
+my $i;
+foreach my $right (@{$objects->{$ObjectType}{$object}}) {
+my $delegations = RT::ACL->new($session{'CurrentUser'});
+$delegations->DelegatedBy( Id => $session{'CurrentUser'}->PrincipalId);
+$delegations->DelegatedFrom ( Id => $right->Id);
+
+my $del_hash = {};
+while ( my $delegation = $delegations->Next) {
+ $del_hash->{$delegation->PrincipalId} = $delegation;
+}
+</%perl>
+% $i++;
+%
+<tr class="<%($i%2) && 'oddline'%>">
+<td>
+<% loc($right->RightName) %><br />
+<div align="right"><font size="-2" color="#999999"><&|/l, $right->PrincipalObj->Object->SelfDescription &>as granted to [_1]</&></font></div>
+ </td>
+% while (my $pg = $personalgroups->Next) {
+<td align="center">
+ <input name="Delegate-ACE-<% $right->Id %>-to-<% $pg->PrincipalId%>" type="checkbox" value="1" <%$ del_hash->{$pg->PrincipalId} && 'CHECKED' %> />
+% if ( $del_hash->{$pg->PrincipalId}) {
+<input type="hidden" class="hidden" name="Delegate-Existing-ACE-<% $right->Id %>-to-<% $pg->PrincipalId%>-as-<%$del_hash->{$pg->PrincipalId}->Id%>" />
+% }
+</td>
+% }
+<td>&nbsp;</td>
+</tr>
+%}
+</table>
+% }
+<%init>
+
+my $sectionheading = loc("[_1] rights", loc($ObjectType =~ /^RT::(.*)$/));
+# 'System' # loc
+# 'Group' # loc
+# 'Queue' # loc
+
+</%init>
+<%args>
+$ObjectType => undef
+$objects => undef
+$personalgroups => undef
+</%args>
diff --git a/rt/html/User/Elements/GroupTabs b/rt/html/User/Elements/GroupTabs
new file mode 100644
index 000000000..b0eba0f8e
--- /dev/null
+++ b/rt/html/User/Elements/GroupTabs
@@ -0,0 +1,84 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /User/Elements/Tabs,
+ subtabs => $tabs,
+ current_tab => 'User/Groups/',
+ current_subtab => $current_subtab,
+ Title => $Title &>
+
+<%INIT>
+my $tabs;
+if ( $GroupObj and $GroupObj->id ) {
+ $tabs->{"this"} = {
+ title => $GroupObj->Name,
+ path => "User/Groups/Modify.html?id=" . $GroupObj->id,
+ subtabs => {
+ Basics => { title => loc('Basics'),
+ path => "User/Groups/Modify.html?id=" . $GroupObj->id
+ },
+
+ Members => { title => loc('Members'),
+ path => "User/Groups/Members.html?id=" . $GroupObj->id
+ },
+
+ } };
+ $tabs->{'this'}->{'current_subtab'} = $current_subtab;
+ $current_subtab = "User/Groups/Modify.html?id=" . $GroupObj->id,
+}
+$tabs->{"A"} = { title => loc('Select group'),
+ path => "User/Groups/index.html" };
+$tabs->{"B"} = { title => loc('New group'),
+ path => "User/Groups/Modify.html?Create=1",
+ separator => 1 };
+
+</%INIT>
+<%ARGS>
+$GroupObj => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/User/Elements/Tabs b/rt/html/User/Elements/Tabs
new file mode 100644
index 000000000..0aca8b5c3
--- /dev/null
+++ b/rt/html/User/Elements/Tabs
@@ -0,0 +1,89 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Tabs,
+ tabs => $tabs,
+ current_toptab => 'User/Prefs.html',
+ current_tab => $current_tab,
+ Title => $Title &>
+
+<%INIT>
+ my $tabs = { a => { title => loc('About me'),
+ path => 'User/Prefs.html',
+ },
+ g => { title => loc('Personal Groups'),
+ path => 'User/Groups/',
+ },
+ h => { title => loc('Delegation'),
+ path => 'User/Delegation.html',
+ },
+ f => { title => loc('Search options'),
+ path => 'Prefs/SearchOptions.html',
+ },
+ r => { title => loc('RT at a glance'),
+ path => 'Prefs/MyRT.html',
+ },
+ };
+
+ # Now let callbacks add their extra tabs
+ $m->comp('/Elements/Callback', tabs => $tabs, %ARGS);
+
+ foreach my $tab (sort keys %{$tabs}) {
+ if ($tabs->{$tab}->{'path'} eq $current_tab) {
+ $tabs->{$tab}->{"subtabs"} = $subtabs;
+ $tabs->{$tab}->{"current_subtab"} = $current_subtab;
+ }
+ }
+</%INIT>
+
+
+<%ARGS>
+$subtabs => undef
+$current_tab => undef
+$current_subtab => undef
+$Title => undef
+</%ARGS>
diff --git a/rt/html/User/Groups/Members.html b/rt/html/User/Groups/Members.html
new file mode 100644
index 000000000..0634260ca
--- /dev/null
+++ b/rt/html/User/Groups/Members.html
@@ -0,0 +1,160 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title &>
+<& /User/Elements/GroupTabs,
+ GroupObj => $Group,
+ current_subtab => "User/Groups/Members.html?id=".$Group->id,
+ Title => $title &>
+<& /Elements/ListActions, actions => \@results &>
+
+
+
+<form action="<%$RT::WebPath%>/User/Groups/Members.html" method="post">
+<input type="hidden" class="hidden" name="id" value="<%$Group->Id%>" />
+<table width="100%">
+<tr>
+<td>
+<&|/l&>Add members</&>
+</td>
+<td>
+<&|/l&>Current members</&>
+</td>
+</tr>
+
+<tr>
+<td valign="top">
+<& /Admin/Elements/SelectNewGroupMembers, Name => "AddMembers", Group => $Group &>
+</td>
+<td valign="top">
+
+% if ($Group->MembersObj->Count == 0 ) {
+<em><&|/l&>(No members)</&></em>
+% } else {
+<em><&|/l&>(Check box to delete)</&></em>
+<br />
+<br />
+<&|/l&>Users</&>
+% my $UserMembers = $Group->MembersObj;
+% $UserMembers->LimitToUsers();
+<ul>
+% while (my $member = $UserMembers->Next()) {
+<li><input type="checkbox" class="checkbox" name="DeleteMember-<%$member->MemberId%>" value="1" />
+<%$member->MemberObj->Object->Name%> (<%$member->MemberObj->Object->RealName%>)
+% }
+</ul>
+<&|/l&>Groups</&>
+<ul>
+% my $GroupMembers = $Group->MembersObj;
+% $GroupMembers->LimitToGroups();
+% while (my $member = $GroupMembers->Next()) {
+<li><input type="checkbox" class="checkbox" name="DeleteMember-<%$member->MemberId%>" value="1" />
+<%$member->MemberObj->Object->Name%>
+% }
+</ul>
+% }
+</td>
+</tr>
+</table>
+<& /Elements/Submit, Label => loc('Modify Members') &>
+</form>
+
+
+<%INIT>
+
+my $Group = new RT::Group($session{'CurrentUser'});
+$Group->Load($id) ;
+
+unless ($Group->id) {
+ Abort(loc('Could not load group'));
+}
+
+my (@results);
+
+foreach my $key (keys %ARGS) {
+
+if ($key =~ /^DeleteMember-(\d+)$/) {
+ my $mem_id = $1;
+ my ($val,$msg) = $Group->DeleteMember($mem_id);
+ push (@results, $msg);
+}
+}
+
+# Make sure AddMembers is always an array
+my @AddMembersUsers = (ref $AddMembersUsers eq 'ARRAY') ? @{$AddMembersUsers} : ($AddMembersUsers);
+my @AddMembersGroups = (ref $AddMembersGroups eq 'ARRAY') ? @{$AddMembersGroups} : ($AddMembersGroups);
+
+foreach my $member (@AddMembersUsers, @AddMembersGroups) {
+ next unless ($member);
+
+ my $principal;
+
+ if ($member =~ /^Group-(\d+)$/) {
+ $principal = RT::Group->new($session{'CurrentUser'});
+ $principal->Load($1);
+ } elsif ($member =~ /^User-(\d+)$/) {
+ $principal = RT::User->new($session{'CurrentUser'});
+ $principal->Load($1);
+ } else {
+ next;
+ }
+
+
+ my ($val, $msg) = $Group->AddMember($principal->PrincipalId);
+ push (@results, $msg);
+}
+
+
+my $title = loc('Editing membership for personal group [_1]', $Group->Name);
+
+</%INIT>
+
+<%ARGS>
+$AddMembersUsers => undef
+$AddMembersGroups => undef
+$id => undef
+</%ARGS>
diff --git a/rt/html/User/Groups/Modify.html b/rt/html/User/Groups/Modify.html
new file mode 100644
index 000000000..da42f2c2a
--- /dev/null
+++ b/rt/html/User/Groups/Modify.html
@@ -0,0 +1,157 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title &>
+
+<& /User/Elements/GroupTabs,
+ GroupObj => $Group,
+ current_subtab => $current_tab,
+ Title => $title &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+
+<form action="<%$RT::WebPath%>/User/Groups/Modify.html" method="post">
+
+%unless ($Group->Id) {
+<input type="hidden" class="hidden" name="id" value="new" />
+% } else {
+<input type="hidden" class="hidden" name="id" value="<%$Group->Id%>" />
+% }
+<table>
+<tr><td align="right">
+<&|/l&>Name</&>:
+</td>
+<td><input name="Name" value="<%$Group->Name%>" /></td>
+</tr><tr>
+<td align="right">
+<&|/l&>Description</&>:</td><td colspan="3"><input name="Description" value="<%$Group->Description%>" size="60" /></td>
+</tr><tr>
+<td colspan="2">
+<input type="hidden" class="hidden" name="SetEnabled" value="1" />
+<input type="checkbox" class="checkbox" name="Enabled" value="1" <%$EnabledChecked%> /> <&|/l&>Enabled (Unchecking this box disables this group)</&><br />
+</tr>
+</table>
+<& /Elements/Submit, Label => loc('Save Changes'), Reset => 1 &>
+</form>
+<%INIT>
+
+my $current_tab;
+my ($title, @results, $Disabled, $EnabledChecked);
+
+my $Group = RT::Group->new($session{'CurrentUser'});
+
+if ($Create) {
+ $current_tab = 'User/Groups/Modify.html?Create=1';
+ $title = loc("Create a new personal group");
+}
+else {
+ if ( $id eq 'new' ) {
+
+ my ( $id, $msg ) = $Group->CreatePersonalGroup(
+ Name => "$Name",
+ PrincipalId => $session{'CurrentUser'}->PrincipalId
+ );
+ unless ($id) {
+ Abort( loc("Could not create group") );
+ }
+ $id = $Group->Id;
+ }
+ else {
+ $Group->Load($id) || Abort( loc('Could not load group') );
+ }
+
+ if ($id) {
+ $title = loc( "Modify the group [_1]", $Group->Name );
+
+ }
+
+ # If the create failed
+ else {
+ $title = loc("Create a new personal group");
+ $Create = 1;
+ }
+
+ $current_tab = 'User/Groups/Modify.html?id=' . $Group->Id;
+}
+
+if ($id) {
+
+ my @fields = qw(Description Name );
+ my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields,
+ Object => $Group,
+ ARGSRef => \%ARGS );
+ push (@results,@fieldresults);
+}
+
+#we're asking about enabled on the web page but really care about disabled.
+if ($Enabled == 1) {
+ $Disabled = 0;
+}
+else {
+ $Disabled = 1;
+}
+if ( ($SetEnabled) and ( $Disabled != $Group->Disabled) ) {
+ my ($code, $msg) = $Group->SetDisabled($Disabled);
+ push @results, loc('Enabled status [_1]', loc_fuzzy($msg));
+}
+
+unless ($Group->Disabled()) {
+ $EnabledChecked ="CHECKED";
+}
+
+</%INIT>
+
+
+<%ARGS>
+$Create => undef
+$Name => undef
+$Description => undef
+$SetEnabled => undef
+$Enabled => undef
+$id => undef
+</%ARGS>
diff --git a/rt/html/User/Groups/index.html b/rt/html/User/Groups/index.html
new file mode 100644
index 000000000..76ffac3af
--- /dev/null
+++ b/rt/html/User/Groups/index.html
@@ -0,0 +1,67 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title => $title &>
+<& /User/Elements/GroupTabs,
+ current_subtab => 'User/Groups/index.html',
+ Title => $title &>
+
+<&|/l&>Personal groups</&>:<br />
+<ul>
+%while ( my $Group = $Groups->Next) {
+<li><a href="Modify.html?id=<%$Group->id%>"><%$Group->Name || loc('(empty)')%></a><br />
+%}
+</ul>
+
+<%INIT>
+my $Groups = RT::Groups->new($session{'CurrentUser'});
+$Groups->LimitToPersonalGroupsFor($session{'CurrentUser'}->PrincipalId());
+my $title = loc('Personal groups');
+
+</%INIT>
+<%ARGS>
+</%ARGS>
diff --git a/rt/html/User/Prefs.html b/rt/html/User/Prefs.html
new file mode 100644
index 000000000..8c6d5f18e
--- /dev/null
+++ b/rt/html/User/Prefs.html
@@ -0,0 +1,289 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Header, Title=>loc("Preferences") &>
+<& /User/Elements/Tabs,
+ current_tab => 'User/Prefs.html',
+ Title=>loc("Preferences") &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<form action="<%$RT::WebPath%>/User/Prefs.html" method="post">
+<input type="hidden" class="hidden" name="id" value="<%$UserObj->Id%>" />
+
+<table width="100%" border="0">
+<tr>
+
+<td valign="top" class="boxcontainer">
+<&| /Widgets/TitleBox, title => loc('Identity'), id => "user-prefs-identity" &>
+
+<input type="hidden" class="hidden" name="Name" value="<%$UserObj->Name%>" />
+<table cellspacing="0" cellpadding="0">
+ <tr>
+ <td class="label"><&|/l&>Email</&>: </td>
+ <td class="value"><input name="EmailAddress" value="<%$UserObj->EmailAddress%>" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Real Name</&>:</td>
+ <td class="value"><input name="RealName" value="<%$UserObj->RealName%>" /></td> </tr>
+ <tr>
+ <td class="label"><&|/l&>Nickname</&>:</td>
+ <td class="value"><input name="NickName" value="<%$UserObj->NickName%>" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Language</&>:</td>
+ <td class="value"><& /Elements/SelectLang, Name => 'Lang', Default => $UserObj->Lang &></td>
+ </tr>
+</table>
+</&>
+<&| /Widgets/TitleBox, title => loc('Phone numbers'), id => "user-prefs-phone" &>
+<table cellspacing="0" cellpadding="0">
+ <tr>
+ <td class="label"><&|/l&>Residence</&>:</td>
+ <td class="value"><input name="HomePhone" value="<%$UserObj->HomePhone%>" size="13" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Work</&>:</td>
+ <td class="value"><input name="WorkPhone" value="<%$UserObj->WorkPhone%>" size="13" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Mobile</&>:</td>
+ <td class="value"><input name="MobilePhone" value="<%$UserObj->MobilePhone%>" size="13" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Pager</&>:</td>
+ <td class="value"><input name="PagerPhone" value="<%$UserObj->PagerPhone%>" size="13" /></td>
+ </tr>
+</table>
+</&>
+<& /Elements/Callback, _CallbackName => 'FormLeftColumn', UserObj => $UserObj, %ARGS &>
+</td>
+<td valign="top" class="boxcontainer">
+% unless ($RT::WebExternalAuth and !$RT::WebFallbackToInternalAuth) {
+<&| /Widgets/TitleBox, title => loc('Password'), id => "user-prefs-password" &>
+<table>
+<tr>
+<td class="label">
+<&|/l&>New Password</&>:
+</td>
+<td class="value">
+<input type="password" name="Pass1" />
+</td>
+</tr>
+<tr><td class="label">
+<&|/l&>Retype Password</&>:
+</td>
+<td class="value">
+<input type="password" name="Pass2" />
+</td>
+</tr>
+</table>
+</&>
+% }
+
+<&| /Widgets/TitleBox, title => loc('Location'), id => "user-prefs-location" &>
+<table cellspacing="0" cellpadding="0">
+ <tr>
+ <td class="label"><&|/l&>Organization</&>:</td>
+ <td class="value"><input name="Organization" value="<%$UserObj->Organization%>" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Address1</&>:</td>
+ <td class="value"><input name="Address1" value="<%$UserObj->Address1%>" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Address2</&>:</td>
+ <td class="value"><input name="Address2" value="<%$UserObj->Address2%>" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>City</&>:</td>
+ <td><input name="City" value="<%$UserObj->City%>" size="14" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>State</&>:</td>
+ <td class="value"><input name="State" value="<%$UserObj->State%>" size="3" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Zip</&>:</td>
+ <td class="value"><input name="Zip" value="<%$UserObj->Zip%>" size="9" /></td>
+ </tr>
+ <tr>
+ <td class="label"><&|/l&>Country</&>:</td>
+ <td class="value"><input name="Country" value="<%$UserObj->Country%>" /></td>
+ </tr>
+</table>
+</&>
+<& /Elements/Callback, _CallbackName => 'FormRightColumn', UserObj => $UserObj, %ARGS &>
+</td>
+</tr>
+<tr>
+
+
+
+<td colspan="2" valign="top" class="boxcontainer">
+%if ($UserObj->Privileged) {
+<br />
+<&| /Widgets/TitleBox, title => loc('Signature') &>
+<textarea cols="80" rows="5" name="Signature" class="signature" wrap="hard">
+<%$UserObj->Signature%></textarea>
+</&>
+% }
+
+</td>
+
+</tr>
+</table>
+
+<& /Elements/Callback, _CallbackName => 'FormEnd', UserObj => $UserObj, %ARGS &>
+
+<& /Elements/Submit, Label => loc('Save Preferences') &>
+</form>
+
+
+<%INIT>
+
+my $UserObj = new RT::User($session{'CurrentUser'});
+my ($title, $PrivilegedChecked, $EnabledChecked, $Disabled, $result, @results);
+
+my ($val, $msg);
+
+
+ $UserObj->Load($id) || $UserObj->Load($Name) || Abort("Couldn't load user '$Name'");
+ $val = $UserObj->Id();
+
+
+
+
+
+
+# If we have a user to modify, lets try.
+if ($UserObj->Id) {
+
+ my @fields = qw(Name Comments Signature EmailAddress FreeformContactInfo
+ Organization RealName NickName Lang EmailEncoding WebEncoding
+ ExternalContactInfoId ContactInfoSystem Gecos ExternalAuthId
+ AuthSystem HomePhone WorkPhone MobilePhone PagerPhone Address1
+ Address2 City State Zip Country Lang
+ );
+
+ $m->comp('/Elements/Callback', _CallbackName => 'UpdateLogic',
+ fields => \@fields,
+ results => \@results,
+ UserObj => $UserObj,
+ ARGSRef => \%ARGS);
+
+ my @fieldresults = UpdateRecordObject ( AttributesRef => \@fields,
+ Object => $UserObj,
+ ARGSRef => \%ARGS );
+ if ($Lang) {
+ $session{'CurrentUser'}->LanguageHandle($Lang);
+ $session{'CurrentUser'} = $session{'CurrentUser'}; # force writeback
+ }
+
+ push (@results,@fieldresults);
+
+
+# {{{ Deal with special fields: Privileged, Enabled and Password
+if ( ($SetPrivileged) and ( $Privileged != $UserObj->Privileged) ) {
+my ($code, $msg) = $UserObj->SetPrivileged($Privileged);
+ push @results, loc('Privileged status: [_1]', loc_fuzzy($msg));
+}
+
+
+
+#TODO: make this report errors properly
+if ((defined $Pass1) and ($Pass1 ne '') and ($Pass1 eq $Pass2) and (!$UserObj->IsPassword($Pass1))) {
+ my ($code, $msg);
+ ($code, $msg) = $UserObj->SetPassword($Pass1);
+ push @results, loc('Password: [_1]', loc_fuzzy($msg));
+} elsif ( $Pass1 && ($Pass1 ne $Pass2)) {
+ push @results, loc("Passwords do not match. Your password has not been changed");
+}
+
+# }}}
+}
+
+
+</%INIT>
+
+
+<%ARGS>
+$id => $session{'CurrentUser'}->Id
+$Name => undef
+$Comments => undef
+$Signature => undef
+$EmailAddress => undef
+$FreeformContactInfo => undef
+$Organization => undef
+$RealName => undef
+$NickName => undef
+$Privileged => undef
+$SetPrivileged => undef
+$Enabled => undef
+$SetEnabled => undef
+$Lang => undef
+$EmailEncoding => undef
+$WebEncoding => undef
+$ExternalContactInfoId => undef
+$ContactInfoSystem => undef
+$Gecos => undef
+$ExternalAuthId => undef
+$AuthSystem => undef
+$HomePhone => undef
+$WorkPhone => undef
+$MobilePhone => undef
+$PagerPhone => undef
+$Address1 => undef
+$Address2 => undef
+$City => undef
+$State => undef
+$Zip => undef
+$Country => undef
+$Pass1 => undef
+$Pass2=> undef
+$Create=> undef
+</%ARGS>
diff --git a/rt/html/Widgets/ComboBox b/rt/html/Widgets/ComboBox
new file mode 100644
index 000000000..8fb5682d9
--- /dev/null
+++ b/rt/html/Widgets/ComboBox
@@ -0,0 +1,69 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<nobr>
+<script type="text/javascript" src="<%$RT::WebPath%>/NoAuth/js/combobox.js"></script>
+
+<span id="<% $Name %>_Container" class="combobox">
+<input name="<% $Name %>" id="<% $Name %>" class="combo-text" value="<% $Default %>" type="text" <% $Size ? "size='$Size'" : '' |n %> autocomplete="off" />
+<br style="display: none" /><span id="<% $Name %>_Button" class="combo-button"></span></span><select name="List-<% $Name %>" id="<% $Name %>_List" class="combo-list" onchange="ComboBox_SimpleAttach(this, this.form['<% $Name %>']); " rows="<% $Rows %>">
+<option style="display: none" value="">-</option>
+% foreach my $value (@Values) {
+ <option value="<%$value%>"><% $value%></option>
+% }
+</select>
+<script language="javascript"><!--
+ComboBox_InitWith('<% $Name %>');
+//--></script>
+</nobr>
+<%ARGS>
+$Name
+$Size => undef
+$Rows => 5
+$Default => ''
+@Values => ()
+</%ARGS>
diff --git a/rt/html/Widgets/SavedSearch b/rt/html/Widgets/SavedSearch
new file mode 100644
index 000000000..b873c2bcb
--- /dev/null
+++ b/rt/html/Widgets/SavedSearch
@@ -0,0 +1,158 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%method new>
+<%init>
+return \%ARGS;
+</%init>
+</%method>
+
+<%method process>
+
+<%init>
+my @actions;
+my @Objects = RT::SavedSearches->new( $session{CurrentUser} )->_PrivacyObjects;
+push @Objects, RT::System->new($session{'CurrentUser'})
+ if $session{'CurrentUser'}->HasRight( Object=> $RT::System,
+ Right => 'SuperUser');
+$self->{SearchId} ||= 'new';
+my $SearchParams = { map { $_ => $args->{$_} } @{$self->{SearchFields}} };
+
+if ( my ( $container_object, $search_id ) = _parse_saved_search( $args->{'LoadSavedSearch'} ) ) {
+ my $search = $container_object->Attributes->WithId($search_id);
+ # We have a $search and now; import the others
+ $self->{SearchId} = $args->{'LoadSavedSearch'};
+ $self->{CurrentSearch}{Object} = $search;
+ $args->{$_} = $search->SubValue($_) for @{ $self->{SearchFields} };
+}
+
+# look for the current one in the available saved searches
+if ($self->{SearchId} eq 'new') {
+ for my $obj (@Objects) {
+ for ( $m->comp( "/Search/Elements/SearchesForObject", Object => $obj ) ) {
+ my ( $desc, $search ) = @$_;
+ use Data::Dumper;
+ # FFS
+ local $Data::Dumper::Sortkeys = 1;
+ if ( Dumper( $search->Content ) eq
+ Dumper( { %$SearchParams, SearchType => $self->{SearchType} } ) ) {
+ $self->{CurrentSearch}{Object} = $search;
+ $self->{SearchId} = $search->Id;
+ }
+ }
+ }
+}
+
+if ( $args->{Save} ) {
+ if ( my $search = $self->{CurrentSearch}{Object} ) {
+ # rename
+ $search->SetDescription( $args->{Description} );
+ push @actions, loc($self->{SearchType}).loc( ' [_1] renamed to [_2].', $self->{CurrentSearch}{Description}, $args->{Description} );
+ }
+ else {
+ # new saved search
+ my $saved_search = RT::SavedSearch->new( $session{'CurrentUser'} );
+ my ( $ok, $search_msg ) = $saved_search->Save(
+ Privacy => $args->{'Owner'},
+ Name => $args->{'Description'},
+ Type => $self->{'SearchType'},
+ SearchParams => $SearchParams
+ );
+ if ($ok) {
+ $self->{CurrentSearch}{Object} = $saved_search->{Attribute};
+ push @actions, loc($self->{SearchType}).loc( ' [_1] saved.', $args->{Description} );
+ } else {
+ push @actions,
+ [ loc("Can't save [_1]", loc($self->{SearchType})) . ': ' . loc($search_msg), 0 ];
+ }
+ }
+}
+
+if ( $args->{Delete} && $self->{CurrentSearch}{Object} ) {
+ my ($ok, $msg) = $self->{CurrentSearch}{Object}->Delete;
+ push @actions, $ok ? loc($self->{SearchType}).loc( ' [_1] deleted.', $self->{CurrentSearch}{Object}->Description ) : $msg;
+ delete $self->{CurrentSearch}{Object};
+ delete $self->{SearchId};
+
+}
+
+$self->{CurrentSearch}{Description} = $self->{CurrentSearch}{Object}->Description
+ if $self->{CurrentSearch}{Object};
+
+return @actions;
+</%init>
+<%ARGS>
+$self
+$args
+</%ARGS>
+
+</%method>
+
+<%method show>
+<form method="post" action="<% $Action %>" name="SaveSearch">
+<& /Search/Elements/EditSearches, Name => 'Owner', SearchType => $self->{SearchType}, AllowCopy => 0,
+ CurrentSearch => $self->{CurrentSearch}, SearchId => $self->{SearchId}, Title => $Title &><br />
+<%PERL>
+foreach my $field ( @{$self->{SearchFields}} ) {
+ if ( ref($ARGS{$field}) && ref($ARGS{$field}) ne 'ARRAY' ) {
+ $RT::Logger->error("Couldn't store '$field'. it's reference to ". ref($ARGS{$field}) );
+ next;
+ }
+ foreach my $value ( grep defined, ref($ARGS{$field})? @{ $ARGS{$field} } : $ARGS{$field} ) {
+</%PERL>
+<input type="hidden" class="hidden" name="<% $field %>" value="<% $value %>" />
+% }
+% }
+</form>
+<%ARGS>
+$self => undef
+$Action => ''
+$Title => 'Saved searches'
+</%ARGS>
+<%init>
+</%init>
+</%method>
diff --git a/rt/html/Widgets/SelectionBox b/rt/html/Widgets/SelectionBox
new file mode 100644
index 000000000..38ae7a04a
--- /dev/null
+++ b/rt/html/Widgets/SelectionBox
@@ -0,0 +1,243 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# The SelectionBox Widget
+%#
+%# SYNOPSIS
+%#
+%# include javascript:
+%# <& /Widgets/SelectionBox:header &>
+%#
+%# <%init>:
+%# my $sel = $m->comp ('/Widgets/SelectionBox:new',
+%# Action => me.html',
+%# Name => 'my-selection',
+%# Available => \@items,
+%# # you can do things with @{$sel->{Current}} in the
+%# # OnSubmit callback
+%# OnSubmit => sub { my $sel = shift; },
+%# Selected => \@selected);
+%#
+%# $m->comp ('/Widgets/SelectionBox:process', %ARGS, self => $sel)
+%#
+%# where @items is an arrayref, each element is [value, label],
+%# and @selected is an arrayref of selected values from @items.
+%#
+%# and in html:
+%# <& /Widgets/SelectionBox:sow, self => $sel &>
+%#
+%# if the SelectionBox is created with AutoSave option, OnSubmit will be called
+%# on every button clicked in non-js mode.
+<%method header>
+% unless ($nojs) {
+<script type="text/javascript" src="<%$RT::WebPath%>/NoAuth/js/class.js"></script>
+<script type="text/javascript" src="<%$RT::WebPath%>/NoAuth/js/list.js"></script>
+% }
+<%ARGS>
+$nojs => 0
+</%ARGS>
+</%method>
+
+<%method new>
+<%init>
+$ARGS{_item_map} = {map {$_->[0] => $_->[1]} @{$ARGS{Available}}};
+return \%ARGS;
+</%init>
+</%method>
+
+<%method process>
+<%init>
+unless ($ARGS{$self->{Name}.'-Submit'}) {
+ # init
+ $self->{Current} = $self->{Selected};
+ $self->{Selected} = [];
+ return;
+}
+
+$self->{Selected} = $ARGS{$self->{Name}.'-Selected'};
+if ($self->{Selected} && !ref($self->{Selected})) {
+ $self->{Selected} = [$self->{Selected}];
+}
+
+if ($ARGS{fromjs}) {
+ $self->{Current} = $self->{Selected};
+}
+else {
+ my $current = $self->{Current} = $ARGS{$self->{Name}.'-Current'};
+ ++$self->{Modified};
+ if ($current && !ref ($current)) {
+ $current = [$current];
+ }
+
+ if ($ARGS{add}) {
+ my $choosed = $ARGS{$self->{Name}.'-Available'};
+ for my $add (ref($choosed) ? @$choosed : $choosed) {
+ next if grep { $_ eq $add } @$current;
+ push @$current, $add;
+ }
+ }
+
+ if ($ARGS{remove}) {
+ my $choosed = $ARGS{$self->{Name}.'-Selected'};
+ for my $del (ref($choosed) ? @$choosed : $choosed) {
+ @$current = map { $_ eq $del ? () : $_ } @$current;
+ }
+ }
+
+ if ($ARGS{moveup} or $ARGS{movedown}) {
+ my $offset = $ARGS{moveup} ? 1 : 0;
+ my $choosed = $ARGS{$self->{Name}.'-Selected'};
+ $choosed = [$choosed] unless ref ($choosed);
+ my $canmove = 0; # not in the cornor
+ for my $i ($ARGS{moveup} ? 0..$#{$current} : reverse 0..$#{$current}) {
+ if (grep {$_ eq $current->[$i]} @$choosed) {
+ if ($canmove) {
+ splice (@$current, $i-$offset, 2,
+ @{$current}[$i+1-$offset,$i-$offset]);
+ }
+ }
+ else {
+ ++$canmove;
+ }
+ }
+ }
+
+ if ($ARGS{clear}) {
+ $current = [];
+ }
+
+ $self->{Current} = $current;
+}
+
+@{$self->{Current}} = grep { exists $self->{_item_map}{$_} } @{$self->{Current}};
+
+if ($self->{AutoSave} or $ARGS{$self->{Name}.'-Save'}) {
+ $self->{OnSubmit}->($self);
+ delete $self->{Modified};
+}
+
+</%init>
+<%ARGS>
+$self => undef
+</%ARGS>
+
+</%method>
+
+<%method current>
+% for (@{$self->{Current}}) {
+<input type="hidden" class="hidden" name="<% $self->{Name} %>-Current" value="<%$_%>" />
+% }
+<%INIT>
+</%INIT>
+<%ARGS>
+$self => undef
+</%ARGS>
+
+</%method>
+
+<%method show>
+<form method="post" action="<%$self->{Action}%>" name="SelectionBox-<% $name %>" id="SelectionBox-<% $name %>"
+% unless ($nojs) {
+onsubmit="list_<% $name %>.selectAll();"
+% }
+>
+<input type="hidden" class="hidden" name="<% $self->{Name} %>-Submit" value="1" />
+<& SelectionBox:current, self => $self &>
+<input type="hidden" class="hidden" name="fromjs" value="0" />
+<&|/l&>Available</&>:
+<br />
+<select name="<%$name%>-Available" id="<%$name%>-Available" size="<%$size%>" multiple="multiple">
+% for (@{$self->{Available}}) {
+<option value="<% $_->[0] %>"><% $_->[1] %></option>
+% }
+</select>
+<input name="add" type="submit" class="button" value=" &rarr; " />
+<select name="<%$name%>-Selected" id="<%$name%>-Selected" size="<%$size%>" multiple="multiple">
+% for (@{$self->{Current}}) {
+<option value="<% $_ %>"
+% if (exists $selected{$_}) {
+selected="selected"
+% }
+><% $self->{_item_map}{$_} %></option>
+% }
+</select>
+% unless ($ARGS{'NoArrows'}) {
+ <input name="moveup" type="submit" class="button" value=" &uarr; " />
+ <input name="movedown" type="submit" class="button" value=" &darr; " />
+% }
+ <input name="remove" type="submit" class="button" value="<&|/l&>Delete</&>" />
+% if ($ARGS{'Clear'}) {
+ <input name="clear" type="submit" class="button" value="<&|/l&>Clear</&>" />
+% }
+
+% my $caption = "";
+% unless ($self->{'AutoSave'}) {
+% if ($self->{Modified}) {
+% $caption = loc('Selections modified. Please save your changes');
+% }
+<& /Elements/Submit, Caption => loc($caption), Label => loc('Save'), Name => $name.'-Save' &>
+% }
+</form>
+
+% unless ($nojs) {
+<script type="text/javascript">
+//<![CDATA[
+var list_<%$name%> = new list(document.getElementById("SelectionBox-<% $name %>"), 0, "list_<%$name%>");
+//]]>
+</script>
+% }
+<%ARGS>
+$self => undef
+$size => 10
+$nojs => 0
+</%ARGS>
+<%INIT>
+my $name = $self->{Name};
+my %selected = map {$_ => 1} @{$self->{Selected}};
+</%INIT>
+
+</%method>
diff --git a/rt/html/Widgets/TitleBox b/rt/html/Widgets/TitleBox
new file mode 100644
index 000000000..00d9e4c63
--- /dev/null
+++ b/rt/html/Widgets/TitleBox
@@ -0,0 +1,54 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<div class="<% $class %>">
+ <& TitleBoxStart, %ARGS &><% $m->content | n %><& TitleBoxEnd &>
+</div>
+<%ARGS>
+$class => ''
+</%ARGS>
+
diff --git a/rt/html/Widgets/TitleBoxEnd b/rt/html/Widgets/TitleBoxEnd
new file mode 100755
index 000000000..b12b58f4d
--- /dev/null
+++ b/rt/html/Widgets/TitleBoxEnd
@@ -0,0 +1,59 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+ <hr class="clear" />
+ </div>
+</div>
+
+% #Manually flush the content buffer after each titlebox is displayed
+% $m->flush_buffer();
+
+<%ARGS>
+$title => undef
+$content => undef
+</%ARGS>
+
diff --git a/rt/html/Widgets/TitleBoxStart b/rt/html/Widgets/TitleBoxStart
new file mode 100755
index 000000000..1d8548d00
--- /dev/null
+++ b/rt/html/Widgets/TitleBoxStart
@@ -0,0 +1,86 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<div class="titlebox <% $class %>" id="<% $id %>">
+ <div class="titlebox-title<% $title_class && " $title_class" %>">
+% if ($hideable) {
+ <span class="widget"><a href="#" onclick="return rollup('<%$tid%>');" onfocus="this.blur(); return false;" title="Toggle visibility">X</a></span>
+% }
+ <span class="left"><% $title_href && qq[<a href="$title_href">] | n %><% $title |n %><% $title_href && "</a>" |n%></span>
+ <span class="right"><% $titleright_href && qq[<a href="$titleright_href">] | n %><% $titleright |n %><% $titleright_href && "</a>" |n%></span>
+ </div>
+ <div class="titlebox-content <% $bodyclass %>" id="<%$tid%>">
+
+<%ARGS>
+$width => undef
+$class => ''
+$bodyclass => ''
+$title_href => undef
+$title => ''
+$title_class => ''
+$titleright_href => undef
+$titleright => undef
+$id => ''
+$hideable => 1
+</%ARGS>
+
+<%init>
+#
+# This should be pretty bulletproof
+#
+my $page = $m->request_comp->path;
+
+my $tid = "TitleBox--$page--" .
+ join '--', ($class, $bodyclass, $title, $id);
+
+$tid =~ s{/}{_}g;
+
+my $i = 0;
+$i++ while $m->notes("$tid-$i");
+$m->notes("$tid-$i" => 1);
+$tid = "$tid-$i";
+</%init>
diff --git a/rt/html/autohandler b/rt/html/autohandler
new file mode 100644
index 000000000..909b922c8
--- /dev/null
+++ b/rt/html/autohandler
@@ -0,0 +1,331 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%INIT>
+
+# Roll back any dangling transactions from a previous failed connection
+$RT::Handle->ForceRollback() if $RT::Handle->TransactionDepth;
+
+
+if ($RT::StatementLog) {
+ $RT::Handle->ClearSQLStatementLog;
+ $RT::Handle->LogSQLStatements(1);
+}
+
+local *session
+ unless $m->is_subrequest; # avoid reentrancy, as suggested by masonbook
+
+# Disable AutoFlush using an attribute
+if ( $m->request_comp->attr_exists('AutoFlush') ) {
+ $m->autoflush( $m->request_comp->attr('AutoFlush') );
+}
+
+%ARGS = map {
+
+ # if they've passed multiple values, they'll be an array. if they've
+ # passed just one, a scalar whatever they are, mark them as utf8
+ my $type = ref($_);
+ ( !$type )
+ ? Encode::is_utf8($_)
+ ? $_
+ : Encode::decode( utf8 => $_, Encode::FB_PERLQQ )
+ : ( $type eq 'ARRAY' )
+ ? [
+ map {
+ ( ref($_) or Encode::is_utf8($_) )
+ ? $_
+ : Encode::decode( utf8 => $_, Encode::FB_PERLQQ )
+ } @$_
+ ]
+ : ( $type eq 'HASH' )
+ ? {
+ map {
+ ( ref($_) or Encode::is_utf8($_) )
+ ? $_
+ : Encode::decode( utf8 => $_, Encode::FB_PERLQQ )
+ } %$_
+ }
+ : $_
+} %ARGS;
+
+# Latter in the code we use
+# $m->comp( { base_comp => $m->request_comp }, $m->fetch_next, %ARGS );
+# instead of $m->call_next to avoid problems with UTF8 keys in arguments.
+# The call_next method pass through original arguments and if you have
+# an argument with unicode key then in a next component you'll get two
+# records in the args hash: one with key without UTF8 flag and another
+# with the flag, which may result into errors. "{ base_comp => $m->request_comp }"
+# is copied from mason's source to get the same results as we get from
+# call_next method, this feature is not documented, so we just leave it
+# here to avoid possible side effects.
+
+# This code canonicalizes time inputs in hours into minutes
+foreach my $field ( keys %ARGS ) {
+ next unless $field =~ /^(.*)-TimeUnits$/i && $ARGS{$1};
+ my $local = $1;
+ $ARGS{$local} =~ s{\b (?: (\d+) \s+ )? (\d+)/(\d+) \b}
+ {($1 || 0) + $3 ? $2 / $3 : 0}xe;
+ if ( $ARGS{$field} && $ARGS{$field} =~ /hours/i ) {
+ $ARGS{$local} *= 60;
+ }
+ delete $ARGS{$field};
+}
+
+$m->{'rt_base_time'} = [ Time::HiRes::gettimeofday() ];
+
+$m->comp( '/Elements/SetupSessionCookie', %ARGS );
+
+unless ( $session{'CurrentUser'} && $session{'CurrentUser'}->Id ) {
+ $session{'CurrentUser'} = RT::CurrentUser->new();
+}
+
+# Set the proper encoding for the current language handle
+$r->content_type("text/html; charset=utf-8");
+
+# If it's a noauth file, don't ask for auth.
+if ( $m->base_comp->path =~ $RT::WebNoAuthRegex ) {
+ $m->comp( { base_comp => $m->request_comp }, $m->fetch_next, %ARGS);
+ $m->abort;
+}
+
+# If RT is configured for external auth, let's go through and get REMOTE_USER
+elsif ($RT::WebExternalAuth) {
+
+ # do we actually have a REMOTE_USER equivlent?
+ if ( RT::Interface::Web::WebCanonicalizeInfo() ) {
+
+ my $orig_user = $user;
+
+ $user = RT::Interface::Web::WebCanonicalizeInfo();
+ $session{'CurrentUser'} = RT::CurrentUser->new();
+ my $load_method = $RT::WebExternalGecos ? 'LoadByGecos' : 'Load';
+
+ if ( $^O eq 'MSWin32' and $RT::WebExternalGecos ) {
+ my $NodeName = Win32::NodeName();
+ $user =~ s/^\Q$NodeName\E\\//i;
+ }
+
+ $session{'CurrentUser'}->$load_method($user);
+
+ if ( $RT::WebExternalAuto and !$session{'CurrentUser'}->Id() ) {
+
+ # Create users on-the-fly
+
+ my $UserObj = RT::User->new( RT::CurrentUser->new('RT_System') );
+
+ my ( $val, $msg ) = $UserObj->Create(
+ %{ ref($RT::AutoCreate) ? $RT::AutoCreate : {} },
+ Name => $user,
+ Gecos => $user,
+ );
+
+ if ($val) {
+
+ # now get user specific information, to better create our user.
+ my $new_user_info
+ = RT::Interface::Web::WebExternalAutoInfo($user);
+
+ # set the attributes that have been defined.
+ # FIXME: this is a horrible kludge. I'm sure there's something cleaner
+ foreach my $attribute (
+ 'Name', 'Comments',
+ 'Signature', 'EmailAddress',
+ 'PagerEmailAddress', 'FreeformContactInfo',
+ 'Organization', 'Disabled',
+ 'Privileged', 'RealName',
+ 'NickName', 'Lang',
+ 'EmailEncoding', 'WebEncoding',
+ 'ExternalContactInfoId', 'ContactInfoSystem',
+ 'ExternalAuthId', 'Gecos',
+ 'HomePhone', 'WorkPhone',
+ 'MobilePhone', 'PagerPhone',
+ 'Address1', 'Address2',
+ 'City', 'State',
+ 'Zip', 'Country'
+ )
+ {
+ $m->comp( '/Elements/Callback', %ARGS,
+ _CallbackName => 'NewUser' );
+
+ my $method = "Set$attribute";
+ $UserObj->$method( $new_user_info->{$attribute} )
+ if ( defined $new_user_info->{$attribute} );
+ }
+ $session{'CurrentUser'}->Load($user);
+ }
+ else {
+
+ # we failed to successfully create the user. abort abort abort.
+ delete $session{'CurrentUser'};
+ $m->abort() unless $RT::WebFallbackToInternalAuth;
+ $m->comp( '/Elements/Login', %ARGS,
+ Error => loc( 'Cannot create user: [_1]', $msg ) );
+ }
+ }
+
+ unless ( $session{'CurrentUser'}->Id() ) {
+ delete $session{'CurrentUser'};
+ $user = $orig_user;
+
+ if ($RT::WebExternalOnly) {
+ $m->comp( '/Elements/Login', %ARGS,
+ Error => loc('You are not an authorized user') );
+ $m->abort();
+ }
+ }
+ }
+ elsif ($RT::WebFallbackToInternalAuth) {
+ unless ( defined( $session{'CurrentUser'} ) ) {
+ $m->comp( '/Elements/Login', %ARGS,
+ Error => loc('You are not an authorized user') );
+ $m->abort();
+ }
+ }
+ else {
+
+ # WebExternalAuth is set, but we don't have a REMOTE_USER. abort
+ delete $session{'CurrentUser'} if defined $session{'CurrentUser'};
+ }
+}
+
+delete $session{'CurrentUser'}
+ unless $session{'CurrentUser'}
+ and $session{'CurrentUser'}->Id;
+
+# Process per-page authentication callbacks
+$m->comp( '/Elements/Callback', %ARGS, _CallbackName => 'Auth' );
+
+# If the user is logging in, let's authenticate
+if ( !$session{'CurrentUser'} && defined $user && defined $pass ) {
+ $session{'CurrentUser'} = RT::CurrentUser->new();
+ $session{'CurrentUser'}->Load($user);
+
+ unless ( $session{'CurrentUser'}->id
+ && $session{'CurrentUser'}->IsPassword($pass) )
+ {
+ delete $session{'CurrentUser'};
+ $RT::Logger->error("FAILED LOGIN for $user from $ENV{'REMOTE_ADDR'}");
+ $m->comp( '/Elements/Login', %ARGS,
+ Error => loc('Your username or password is incorrect') );
+ $m->comp( '/Elements/Callback', %ARGS, _CallbackName => 'FailedLogin' );
+ $m->abort;
+ }
+ else {
+ $RT::Logger->info(
+ "Successful login for $user from $ENV{'REMOTE_ADDR'}");
+ $m->comp( '/Elements/Callback', %ARGS, _CallbackName => 'SuccessfulLogin' );
+ }
+}
+
+# If we've got credentials, let's serve the file up.
+if ( ( defined $session{'CurrentUser'} )
+ and ( $session{'CurrentUser'}->Id ) )
+{
+
+ # Process per-page global callbacks
+ $m->comp( '/Elements/Callback', %ARGS );
+
+ # If the user isn't privileged, they can only see SelfService
+ if ( not $session{'CurrentUser'}->Privileged ) {
+
+ # if the user is trying to access a ticket, redirect them
+ if ( $m->request_comp->path =~ '^(/+)Ticket/Display.html'
+ and $ARGS{'id'} )
+ {
+ RT::Interface::Web::Redirect($RT::WebURL."SelfService/Display.html?id=".$ARGS{'id'});
+ }
+
+ # otherwise, drop the user at the SelfService default page
+ elsif ( $m->base_comp->path !~ '^(/+)SelfService/' ) {
+ RT::Interface::Web::Redirect($RT::WebURL."SelfService/");
+ }
+ else {
+ $m->comp( { base_comp => $m->request_comp }, $m->fetch_next, %ARGS);
+ }
+ }
+ else {
+ $m->comp( { base_comp => $m->request_comp }, $m->fetch_next, %ARGS);
+ }
+}
+
+# If we have no credentials
+else {
+ $m->comp( '/Elements/Login', %ARGS );
+ $m->abort();
+}
+
+if ($RT::StatementLog) {
+ my @log = $RT::Handle->SQLStatementLog;
+ $RT::Handle->ClearSQLStatementLog;
+ for my $stmt (@log) {
+ my ( $time, $sql, $bind, $duration ) = @{$stmt};
+ my @bind;
+ if ( ref $bind ) {
+ @bind = @{$bind};
+ }
+ else {
+
+ # Older DBIx-SB
+ $duration = $bind;
+ }
+ $RT::Logger->log(
+ level => $RT::StatementLog,
+ message => "SQL(" . sprintf( "%.2f", $duration ) . "s): $sql;"
+ . (
+ @bind ? " [ bound values: @{[map{qq|'$_'|} @bind]} ]" : ""
+ )
+ );
+ }
+}
+
+</%INIT>
+<& /Elements/Footer, %ARGS &>
+<%ARGS>
+$user => undef
+$pass => undef
+$menu => undef
+</%ARGS>
diff --git a/rt/html/index.html b/rt/html/index.html
new file mode 100644
index 000000000..af95a655c
--- /dev/null
+++ b/rt/html/index.html
@@ -0,0 +1,117 @@
+<& /Elements/Header, Title=>loc("RT at a glance"), Refresh => $session{'home_refresh_interval'} &>
+<!--
+% $m->out('--'.'>');
+% if (0) {
+%# -->
+<html><head>
+<meta http-equiv="refresh" content="30; url=http://bestpractical.com/rt/rt-broken-install.html">
+<title>Almost there!</title></head>
+<body>
+
+<img src="http://www.bestpractical.com/images/unconfigured-rtlogo.jpg" />
+<br /><br />
+<h1>You're almost there!</h1>
+You haven't yet configured your webserver to run RT.
+
+You appear to have installed RT's web interface correctly, but haven't yet configured your web
+server to "run" the RT server which powers the web interface.
+
+The next step is to edit your webserver's configuration file to instruct it to use
+RT's <strong>mod_perl</strong>, <strong>FastCGI</strong> or <strong>SpeedyCGI</strong> handler.
+
+If you need commercial support, please contact us at sales@bestpractical.com.
+
+
+<!--
+% }
+
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Elements/Tabs,
+ current_toptab => '',
+ Title=>loc("RT at a glance"),
+ actions => $actions,
+ &>
+<& /Elements/ListActions, actions => \@results &>
+<& /Elements/MyRT &>
+<%init>
+
+my @results;
+
+if ($ARGS{'QuickCreate'} ) {
+ my $ticket = RT::Ticket->new($session{'CurrentUser'});
+ my ($tid, $trans, $tmsg) = $ticket->Create(Queue => $ARGS{'Queue'},
+ Owner => $ARGS{'Owner'},
+ Requestor => $session{'CurrentUser'}->UserObj->EmailAddress,
+ Subject => $ARGS{'Subject'});
+
+
+ push (@results, $tmsg);
+}
+
+
+if ( $ARGS{'q'} ) {
+ RT::Interface::Web::Redirect($RT::WebURL."Search/Simple.html?q=".$m->interp->apply_escapes($ARGS{q}));
+}
+
+if ($ARGS{'HomeRefreshInterval'}) {
+ $session{'home_refresh_interval'} = $ARGS{'HomeRefreshInterval'};
+}
+
+my $actions;
+if ($session{'CurrentUser'}->HasRight(Right => 'ModifySelf', Object => $RT::System)) {
+ $actions = {
+ A => { title => loc('Edit'),
+ path => 'Prefs/MyRT.html',
+ },
+ };
+}
+
+</%init>
+
+%# --></body></html>
diff --git a/rt/html/l b/rt/html/l
new file mode 100644
index 000000000..32302aaa0
--- /dev/null
+++ b/rt/html/l
@@ -0,0 +1,52 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+%# <jesse@bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work 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 program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/copyleft/gpl.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%init>
+ my $hand = ($session{'CurrentUser'} ||= RT::CurrentUser->new)->LanguageHandle;
+ $m->print($hand->maketext($m->content,@_));
+ return(1);
+</%init>