[Rt-commit] rt branch, master, updated. rt-4.4.4-877-g1a84098d4

? sunnavy sunnavy at bestpractical.com
Fri Feb 14 04:09:55 EST 2020


The branch, master has been updated
       via  1a84098d477406c39dbaf1b618177f131d9c854b (commit)
       via  9d3392297ab8e907952f2d65a2443e6aa63c3f8e (commit)
       via  c412bce5f345a61cb12056be0ce2795ddcd4f431 (commit)
       via  95867dc1b5312311593c2f75859ad93c9222b6af (commit)
       via  dd396c5661d12511f5516cc4b426ef118ad67aab (commit)
       via  dda1009c15f410d982d29759bf2b8098422c8740 (commit)
       via  d5f3e02e64fe7133ddec26177865359576ed9a64 (commit)
       via  da817215e019220fa2474efc1bd41104b2cf9bdb (commit)
       via  e0357e292f336e1baf2d01bdf6d9da5a53eff485 (commit)
       via  37b3620a31da790024513bd59d1c889db75c657f (commit)
       via  2bae18b7f5955b948c1c46cd14038a62de38ca59 (commit)
       via  7638ed5205c472f1be0b294cfa7071ed8fd60e52 (commit)
       via  92bb6103d2de64e6f71a29473bec43323e669959 (commit)
       via  dfccc8865eb387e541d2691377ddf66229309ae1 (commit)
       via  7094c8a62f4bbe0c5434fe53550ac3b6bc8a37cf (commit)
       via  d93e0996175b8ed4e7eb13e63c411dad54dc0764 (commit)
       via  90b5decd502be2fb41657fb0b432318538fa2889 (commit)
       via  334fb191105d7771805a423adb5fc68987df23f3 (commit)
       via  b9828c28eae8110d191eeea6f8b5f61085a2cd7c (commit)
       via  81e18339bcf71087d3f85986f1aabb01e85a3620 (commit)
       via  f2a2479d1d287dd35313715ca0fb569d7566b1b0 (commit)
       via  2534e227710b3b18278112a4f29ae68b01dc5dc2 (commit)
       via  14300260e7abbf4bee49ef2adc17482cb5135881 (commit)
       via  3c3050702dd428c1f3bdf11f9a5e74b2f1513286 (commit)
       via  76662342be665dc767b79972173f12ea8d79e4b0 (commit)
       via  0da6058b5e388a02b1b8e065ea58dbf277e9c45c (commit)
       via  235ebd57a0fdd58ad43b16f30dda10a14ec7bfb3 (commit)
       via  f3e3df5ad8869fad8a98a8c8db2706ffa4a5c6da (commit)
       via  c25ba37248586efb5f58b93758132932a1e94ecb (commit)
       via  a24731a499ce54730f8574a9aeb5233e99b0cd30 (commit)
       via  4aad9e6d58b79fabfc1aad2fb8e682bd74f4fc48 (commit)
       via  e92d7ef03939077fd21f886b54ecdb8184f56ff3 (commit)
       via  3e1545b291befb9c56c88122b57227619a0b3c7b (commit)
       via  27b236e512fbc485bfc629a331f2b4ef37485673 (commit)
       via  a520bbabcc5a8c436478b68c7b31e14637c8488d (commit)
       via  a12613d974e01a507f2b19a7fbf682b350d056f3 (commit)
       via  0cc1bbf23536cb18613e28490865a1813fa17e43 (commit)
       via  1599c75f833aa1028a7ffbac60bd0db1f1fa42bd (commit)
       via  7d5502ffe1a4ee0be0d7854dbfef966c36150f36 (commit)
       via  cea23cb97465440a1f5e33c40f676f8a32a4ab2a (commit)
       via  10113b8ce89c867b4ca032dfd473a53dfce85650 (commit)
       via  6b2a2f0472122706403a907f44b0d3a4fb747ea3 (commit)
       via  8575f4ddd63795ab10cb26a148a6d8f36c7ecd55 (commit)
       via  7aa3edf8a97547071f3c4d99b83b70c2775fd0d0 (commit)
       via  e1afd2e7b88da4321aeb635bd8129aa69bd3c0f3 (commit)
       via  cc190fec889acb7b48075ae1ac8ccd5dd4a6894c (commit)
       via  43b908eeb0e65a601a5af11c5faa63edee5fd9b0 (commit)
       via  dabcae2c4ec72a42ec68c2649450cf60a018e5b3 (commit)
       via  dad0a00b591f4fb4f0ede64367f0aedf7cf73fe2 (commit)
       via  0280dedf509159d3295d9cb2849e633fc6654e61 (commit)
       via  143e79009f6593207c5c6016a83524d792259cb7 (commit)
       via  9bb218b5588ed357c4ff4b309b344d2d43c1a77a (commit)
       via  e0582855356ea216fd53e94559eb2812679c7bfa (commit)
       via  0cf5fbe84ce70dfca8065eacd1a1e6c78d3d43e8 (commit)
       via  4d9d4227f8caa2498f5fb26a10e66948aa3f6e85 (commit)
       via  6874d09f52b325436fc32f2f6b429788dd5e1f9a (commit)
       via  24818eb8396242e8573bba566a51daa8eb064a1b (commit)
       via  6ccfdc4fd3937c21d3b001f96feec65830f474cd (commit)
       via  eb7b0ef29481eba15634ffde9a749cd92e509de9 (commit)
       via  ba0c3309ec023f8411703887b69a0ca4beabb84a (commit)
       via  7e04d335c195d4a96244caf85b1adfce2d5ba637 (commit)
       via  d49581e1dcfc83ca8d7a7a338b536c0390549fd6 (commit)
       via  36d27303e5eca3c2e72b9e2d6b0c1e9fffd51a25 (commit)
       via  91fae5fbb958897da845cd10d486837d2b59b68b (commit)
       via  83227fc27401a12a39caeb83c7a920dc1400e5a8 (commit)
       via  d4f3ce719cd8deb4aa6121fc152221e957c121d5 (commit)
       via  ae26a8c8d8bea5f82859231b61dae729c42c6059 (commit)
       via  4c55894d59ab5312534d572af1b1db2e76e2dc87 (commit)
       via  c87df1c38356cabe2f2bf7e2e99b72d76a63e01a (commit)
       via  79d249f90defa08d5975f1e831824ce747ec2172 (commit)
       via  35bfdaa9b631c40a0812e61fa0fbf8612cdfdc0f (commit)
       via  77348044ce560978efbd7f8c4642dbd569edb82b (commit)
       via  6805c82f4dad7ebbed47c426128dd35f387c5a11 (commit)
       via  23d0cf6f6dcba541eec32cff45c57e0a7b3c4a30 (commit)
       via  201ff40cfccdc488b00b67f68243779bf9b4c088 (commit)
       via  c2035aa8572ee2a5cf80ebea7aa3509ef6e06d2d (commit)
       via  035dd991a95e6f466dde8497d488e76998a4b69e (commit)
       via  98e1d002543c3ba100a31a48013b3c3043cfd27d (commit)
       via  fe90199feac05ae8b34f6de84eb5a2277ebb48d4 (commit)
       via  e453fd2dbcb3b6367cfc79728337803cd91e2451 (commit)
       via  566b8fa1664a87552ce60b51c58acb53d0e19c28 (commit)
      from  25a5e734d8b96e8c845ec754483b15cbcc80ba73 (commit)

Summary of changes:
 docs/UPGRADING-4.4                                 |  26 +++++
 .../database.pod}                                  |  87 +++++++++++++-
 etc/RT_Config.pm.in                                |  54 ++++++---
 lib/RT/Authen/ExternalAuth.pm                      | 125 ++++++++++++++++++++-
 lib/RT/Authen/ExternalAuth/DBI.pm                  |  45 +++++++-
 lib/RT/Authen/ExternalAuth/LDAP.pm                 |  49 +++++++-
 lib/RT/Config.pm                                   |   6 +
 lib/RT/CustomField.pm                              |  33 +++---
 lib/RT/CustomFieldValues/External.pm               |  13 ++-
 lib/RT/Interface/Email.pm                          |   4 +-
 lib/RT/Queue.pm                                    |  25 +++--
 lib/RT/Record.pm                                   |   6 -
 lib/RT/SavedSearch.pm                              |  32 ++++++
 lib/RT/SearchBuilder.pm                            |  23 +++-
 lib/RT/Test.pm                                     |   1 +
 lib/RT/Ticket.pm                                   |  14 ++-
 lib/RT/Tickets.pm                                  |   4 +-
 lib/RT/Transaction.pm                              |  11 +-
 lib/RT/User.pm                                     |  62 ++++++++--
 sbin/rt-server.in                                  |  11 ++
 share/html/Admin/Groups/Members.html               |  29 +++--
 share/html/Admin/Groups/index.html                 |   9 ++
 share/html/Admin/Users/index.html                  |   9 ++
 share/html/Elements/EditCustomFields               |   3 +-
 share/html/Elements/SelectStatus                   |   2 +-
 share/html/Prefs/Elements/EditAboutMe              |   2 +-
 share/html/Search/Elements/EditSearches            |  13 ++-
 share/html/SelfService/Create.html                 |   2 +
 share/html/Ticket/Elements/AddAttachments          |   2 +-
 share/html/Ticket/Elements/ShowUpdateStatus        |  13 ++-
 share/html/Ticket/Forward.html                     |   3 +
 share/html/Ticket/Update.html                      | 102 ++++++++++++-----
 share/po/de.po                                     |  10 +-
 share/static/css/elevator-light/ticket.css         |  14 ++-
 share/static/js/autocomplete.js                    |  14 ++-
 t/api/customfield.t                                |  30 +++++
 t/api/rtname.t                                     |  14 ++-
 t/api/savedsearch.t                                |  14 ++-
 t/api/user.t                                       |  25 ++++-
 t/externalauth/ldap.t                              |  66 ++++++++++-
 t/externalauth/sqlite.t                            |  48 +++++++-
 t/shredder/02queue.t                               |  66 +++++++++--
 t/ticket/add-watchers.t                            |  30 ++++-
 t/ticket/search_by_cf_date.t                       |  61 ++++++++++
 t/web/admin_groups.t                               |  41 +++++++
 t/web/admin_user.t                                 |  17 +++
 t/web/cf_datetime.t                                |   1 -
 t/web/self_service.t                               |   2 +-
 t/web/ticket_seen.t                                |   9 +-
 49 files changed, 1117 insertions(+), 165 deletions(-)
 rename docs/{backups.pod => system_administration/database.pod} (70%)
 create mode 100644 t/ticket/search_by_cf_date.t

- Log -----------------------------------------------------------------
commit 1a84098d477406c39dbaf1b618177f131d9c854b
Merge: 25a5e734d 9d3392297
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Feb 14 08:31:20 2020 +0800

    Merge branch '4.4-trunk'

diff --cc docs/system_administration/database.pod
index 9f86711b0,43fbf753f..2e3f64fb2
--- a/docs/system_administration/database.pod
+++ b/docs/system_administration/database.pod
@@@ -225,3 -222,82 +227,82 @@@ Simply saving a tarball should be suffi
  
  Be sure to include all the directories and files you enumerated above!
  
+ =head1 Migrating to a Different Database
+ 
+ RT supports many different databases, including MySQL, MariaDB, PostgreSQL,
+ and Oracle. Each of these databases is different and if you want to switch
+ from one type to another, you can't just take a backup in one and try to
+ restore it to another. One exception is MySQL and MariaDB, which are currently
+ compatible and don't require the extra steps discussed here.
+ 
+ RT provides tools that allow you to export your RT database
+ to the filesystem and then import it back into another database through
+ RT. The tools are L<rt-serializer> and L<rt-importer> and the general
+ process for migrating from one database to another is described below.
+ 
+ Plan to do a full test of this process and thoroughly check the data
+ in a test version of the new database before performing a final conversion
+ on your production system.
+ 
+ The serializer and importer tools can also be used to move only part of
+ your RT database, like an individual queue. The process is similar to the
+ steps described here, but the options will be different.
+ 
+ You do not need to perform these steps when upgrading RT on the same database.
+ See the L<README> for upgrade instructions.
+ 
+ =over
+ 
+ =item Export from Current Database
+ 
+ First run the L<rt-serializer> tool to export your database to the filesystem.
+ Note that this will require space similar to the size of your database, so
+ plan accordingly. If your database is very large, it can take some time.
+ The documentation contains additional information on available flags.
+ It's also a good idea to run the L<rt-validator> tool to detect and resolve
+ any errors in your database before starting:
+ 
 -    /opt/rt4/sbin/rt-validator --check (and maybe --resolve)
 -    /opt/rt4/sbin/rt-serializer --clone --directory /path/to/serialized/data
++    /opt/rt5/sbin/rt-validator --check (and maybe --resolve)
++    /opt/rt5/sbin/rt-serializer --clone --directory /path/to/serialized/data
+ 
+ =item Setup New Database
+ 
+ After the database serializes cleanly, you can then begin to set up your
+ new database. As you are working from some existing data, you do
+ not need the initial RT data inserted into the databases, but you will need
+ the tables created. When you use the L<rt-importer> tool, the data will fill
+ the corresponding tables.
+ 
+ RT's L<rt-setup-database> tool can set the database up for you.
+ If you are running the import in the same RT installation, you will need to
+ update your database options in C<RT_SiteConfig.pm> to point to the new database
+ before running this step.
+ 
 -    /opt/rt4/sbin/rt-setup-database --action create,schema,acl
++    /opt/rt5/sbin/rt-setup-database --action create,schema,acl
+ 
+ =item Import Data
+ 
+ Once you have your new database set up, you can then use L<rt-importer>
+ to insert the serialized data:
+ 
 -    /opt/rt4/sbin/rt-importer /path/to/serialized/data
++    /opt/rt5/sbin/rt-importer /path/to/serialized/data
+ 
+ As with the serializer step, this will take time proportionate to the size of
+ your database.
+ 
+ =item Reset Sequences
+ 
+ Some databases, like Postgres, use sequences for RT table values like ids. For
+ these database types, you need to reset the sequences from 1, set in the newly
+ created database, to the next available id for each table. The C<reset-sequences>
+ script will reset these for you:
+ 
 -    /opt/rt4/etc/upgrade/reset-sequences
++    /opt/rt5/etc/upgrade/reset-sequences
+ 
+ =item Test
+ 
+ Test your new system and confirm all of the expected data is available. Your RT
+ system should look exactly the same as before, but the backend is on an entirely
+ new database.
+ 
+ =back
diff --cc etc/RT_Config.pm.in
index 3719b35ab,f59de9ca2..258c193a1
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@@ -1229,27 -1211,18 +1229,17 @@@ minutes.  Note that this only effects e
  
  =cut
  
 -Set($WebFlushDbCacheEveryRequest, 1);
 +Set($DefaultTimeUnitsToHours, 0);
  
- =item C<$SignatureAboveQuote>
- 
- By default RT places the signature at the bottom of the quoted text in
- the message box for ticket replies.  Set this to 1 to place the signature
- above the quoted text.
- 
- =cut
- 
- Set($SignatureAboveQuote, 0);
- 
 -=item C<%ChartFont>
 +=item C<$TimeInICal>
  
 -The L<GD> module (which RT uses for graphs) ships with a built-in font
 -that doesn't have full Unicode support. You can use a given TrueType
 -font for a specific language by setting %ChartFont to (language =E<gt>
 -the absolute path of a font) pairs. Your GD library must have support
 -for TrueType fonts to use this option. If there is no entry for a
 -language in the hash then font with 'others' key is used.
 +By default, events in the iCal feed on the ticket search page
 +contain only dates, making them all day calendar events. Set
 +C<$TimeInICal> if you have start or due dates on tickets that
 +have significant time values and you want those times to be
 +included in the events in the iCal feed.
  
 -RT comes with two TrueType fonts covering most available languages.
 +This option can also be set as an individual user preference.
  
  =cut
  
@@@ -2424,36 -2372,57 +2414,53 @@@ edit capabilities
  
  =back
  
 +You may also provide the special key C<_default> inside a record type to
 +specify a default behavior for all panels.
  
 -=head1 Application logic
 -
 -=over 4
 -
 -=item C<$ParseNewMessageForTicketCcs>
 -
 -If C<$ParseNewMessageForTicketCcs> is set to 1, RT will attempt to
 -divine Ticket 'Cc' watchers from the To and Cc lines of incoming
 -messages that create new tickets. This option does not apply to replies
 -or comments on existing tickets. Be forewarned that if you have I<any>
 -addresses which forward mail to RT automatically and you enable this
 -option without modifying C<$RTAddressRegexp> below, you will get
 -yourself into a heap of trouble.
 +This sample configuration will provide a default inline edit behavior of
 +click, but also specifies different behaviors for several other panels.
 +Note that the non-standard panel names "Grouping Name" and "Another
 +Grouping" are created by the L</%CustomFieldGroupings> setting.
  
 -See also the L<RT::Action::AutoAddWatchers> extension which adds
 -watchers from ticket replies on existing tickets.
 +    Set(%InlineEditPanelBehavior,
 +        'RT::Ticket' => {
 +            '_default'          => 'click',
  
 -=cut
 +            'Grouping Name'     => 'link',
 +            'Another Grouping'  => 'click',
 +            'Dates'             => 'always',
 +            'Links'             => 'hide',
 +            'People'            => 'link',
 +        },
 +    );
  
 -Set($ParseNewMessageForTicketCcs, undef);
 +=back
  
 -=item C<$UseTransactionBatch>
 +=head2 Ticket display
  
 -Set C<$UseTransactionBatch> to 1 to execute transactions in batches,
 -such that a resolve and comment (for example) would happen
 -simultaneously, instead of as two transactions, unaware of each
 -others' existence.
 +=over 4
  
 -=cut
++=item C<$DisplayTotalTimeWorked>
+ 
 -Set($UseTransactionBatch, 1);
++Set to 1 to display Total Time Worked in the Basics section.
+ 
 -=item C<$StrictLinkACL>
++Total Time Worked is a dynamic value containing a sum of Time Worked for
++the parent and all child tickets.  This value is generated when displaying
++the ticket and automatically updates when a child ticket is added or removed.
++Total Time Worked follows only parent/child link relationships.  Tickets
++linked with depends-on or refers-to links are not included.
+ 
 -When this feature is enabled a user needs I<ModifyTicket> rights on
 -both tickets to link them together; otherwise, I<ModifyTicket> rights
 -on either of them is sufficient.
++Total Time Worked is also available as a column for reports generated with
++the Query Builder.
+ 
+ =cut
+ 
 -Set($StrictLinkACL, 1);
++Set($DisplayTotalTimeWorked, 0);
+ 
 -=item C<$RedistributeAutoGeneratedMessages>
 +=item C<$ShowMoreAboutPrivilegedUsers>
  
 -Should RT redistribute correspondence that it identifies as machine
 -generated?  A 1 will do so; setting this to 0 will cause no
 -such messages to be redistributed.  You can also use 'privileged' (the
 -default), which will redistribute only to privileged users. This helps
 -to protect against malformed bounces and loops caused by auto-created
 -requestors with bogus addresses.
 +This determines if the 'More about requestor' box on
 +Ticket/Display.html is shown for Privileged Users.
  
  =cut
  
@@@ -3022,557 -2929,30 +3029,576 @@@ something like
  
  =cut
  
 -Set($TimeInICal, 0);
 +# loc('Related tickets')
 +Set($AssetSearchFormat, q[
 +    '<a href="__WebHomePath__/Asset/Display.html?id=__id__">__Name__</a>/TITLE:Name',
 +    Description,
 +    '__Status__ (__Catalog__)/TITLE:Status',
 +    Owner,
 +    HeldBy,
 +    Contacts,
 +    '__ActiveTickets__ __InactiveTickets__/TITLE:Related tickets',
 +]);
  
 -=item C<$PreferDateTimeFormatNatural>
 +=item C<$AssetSummaryFormat>
  
 -By default, RT parses an unknown date first with L<Time::ParseDate>, and if
 -this fails with L<DateTime::Format::Natural>.
 -C<$PreferDateTimeFormatNatural> changes this behavior to first parse with
 -L<DateTime::Format::Natural>, and if this fails with L<Time::ParseDate>.
 -This gives you the possibility to use the more advanced features of
 -L<DateTime::Format::Natural>.
 -For example with L<Time::ParseDate> it isn't possible to get the
 -'first day of the last month', where L<DateTime::Format::Natural> supports
 -this with 'last month'.
 +The information that is displayed on ticket display pages about assets
 +related to the ticket.  This is displayed in a table beneath the asset
 +name.
 +
 +=cut
 +
 +Set($AssetSummaryFormat, q[
 +    '<a href="__WebHomePath__/Asset/Display.html?id=__id__">__Name__</a>/TITLE:Name',
 +    Description,
 +    '__Status__ (__Catalog__)/TITLE:Status',
 +    Owner,
 +    HeldBy,
 +    Contacts,
 +    '__ActiveTickets__ __InactiveTickets__/TITLE:Related tickets',
 +]);
 +
 +=item C<$AssetSummaryRelatedTicketsFormat>
 +
 +The information that is displayed on ticket display pages about tickets
 +related to assets related to the ticket.  This is displayed as a list of
 +tickets underneath the asset properties.
 +
 +=cut
 +
 +Set($AssetSummaryRelatedTicketsFormat, q[
 +    '<a href="__WebPath__/Ticket/Display.html?id=__id__">__id__</a>',
 +    '(__OwnerName__)',
 +    '<a href="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a>',
 +    QueueName,
 +    Status,
 +]);
 +
 +=item C<$AssetBasicCustomFieldsOnCreate>
 +
 +Specify a list of Asset custom fields to show in "Basics" widget on create.
 +
 +e.g.
 +
 +Set( $AssetBasicCustomFieldsOnCreate, [ 'foo', 'bar' ] );
 +
 +=cut
 +
 +# Set($AssetBasicCustomFieldsOnCreate, undef );
 +
 +=back
 +
 +=head2 Message box properties
 +
 +=over 4
 +
 +=item C<$MessageBoxWidth>, C<$MessageBoxHeight>
 +
 +For message boxes, set the entry box width, height and what type of
 +wrapping to use.  These options can be overridden by users in their
 +preferences.
 +
 +When the width is set to undef, no column count is specified and the
 +message box will take up 100% of the available width.  Combining this
 +with HARD messagebox wrapping (below) is not recommended, as it will
 +lead to inconsistent width in transactions between browsers.
 +
 +These settings only apply to the non-RichText message box.  See below
 +for Rich Text settings.
 +
 +=cut
 +
 +Set($MessageBoxWidth, undef);
 +Set($MessageBoxHeight, 15);
 +
 +=item C<$MessageBoxRichText>
 +
 +Should "rich text" editing be enabled? This option lets your users
 +send HTML email messages from the web interface.
 +
 +=cut
 +
 +Set($MessageBoxRichText, 1);
 +
 +=item C<$MessageBoxRichTextHeight>
 +
 +Height of rich text JavaScript enabled editing boxes (in pixels)
 +
 +=cut
 +
 +Set($MessageBoxRichTextHeight, 300);
 +
 +=item C<$MessageBoxIncludeSignature>
 +
 +Should your users' signatures (from their Preferences page) be
 +included in Comments and Replies.
 +
 +=cut
 +
 +Set($MessageBoxIncludeSignature, 1);
 +
 +=item C<$MessageBoxIncludeSignatureOnComment>
 +
 +Should your users' signatures (from their Preferences page) be
 +included in Comments. Setting this to 0 overrides
 +C<$MessageBoxIncludeSignature>.
 +
 +=cut
 +
 +Set($MessageBoxIncludeSignatureOnComment, 1);
 +
++=item C<$SignatureAboveQuote>
++
++By default RT places the signature at the bottom of the quoted text in
++the message box for ticket replies.  Set this to 1 to place the signature
++above the quoted text.
++
++=cut
++
++Set($SignatureAboveQuote, 0);
++
 +=back
 +
 +=head2 Attach Files
 +
 +=over 4
 +
 +=item C<$PreferDropzone>
 +
 +By default, RT uses Dropzone to attach files if possible. If
 +C<$PreferDropzone> is set to 0, RT will always use plain file inputs.
 +
 +=cut
 +
 +Set($PreferDropzone, 1);
 +
 +=back
 +
 +=head2 Transaction search
 +
 +=over 4
 +
 +=item C<%TransactionDefaultSearchResultFormat>
 +
 +C<%TransactionDefaultSearchResultFormat> is the default format for RT
 +transaction search results for various object types. Keys are object types
 +like C<RT::Ticket>, values are the format string.
 +
 +=cut
 +
 +Set(%TransactionDefaultSearchResultFormat,
 +    'RT::Ticket' => qq{
 +        '<B><A HREF="__WebPath__/Transaction/Display.html?id=__id__">__id__</a></B>/TITLE:ID',
 +        '<B><A HREF="__WebPath__/Ticket/Display.html?id=__ObjectId__">__ObjectId__</a></B>/TITLE:Ticket',
 +        '__Description__',
 +        '<small>__OldValue__</small>',
 +        '<small>__NewValue__</small>',
 +        '<small>__Content__</small>',
 +        '<small>__CreatedRelative__</small>',
 +   },
 +);
 +
 +=item C<%TransactionDefaultSearchResultOrderBy>
 +
 +What Transactions column should we order by for RT Transaction search
 +results for various object types.  Keys are object types like C<RT::Ticket>,
 +values are the column names.
 +
 +Defaults to I<id>.
 +
 +=cut
 +
 +Set( %TransactionDefaultSearchResultOrderBy, 'RT::Ticket' => 'id' );
 +
 +=item C<%TransactionDefaultSearchResultOrder>
 +
 +When ordering RT Transaction search results by
 +C<%TransactionDefaultSearchResultOrderBy>, should the sort be ascending
 +(ASC) or descending (DESC).  Keys are object types like C<RT::Ticket>,
 +values are either "ASC" or "DESC".
 +
 +Defaults to I<ASC>.
 +
 +=cut
 +
 +Set( %TransactionDefaultSearchResultOrder, 'RT::Ticket' => 'ASC' );
 +
 +=item C<%TransactionShowSearchResultCount>
 +
 +Display search result count on transaction lists.  Keys are object types
 +like C<RT::Ticket>, values are either 1 or 0.
 +
 +Defaults to 1 (show them).
 +
 +=cut
 +
 +Set( %TransactionShowSearchResultCount, 'RT::Ticket' => 1 );
 +
 +=back
 +
 +=head2 Transaction display
 +
 +=over 4
 +
 +=item C<$OldestTransactionsFirst>
 +
 +By default, RT shows newest transactions at the bottom of the ticket
 +history page, if you want see them at the top set this to 0.  This
 +option can be overridden by users in their preferences.
 +
 +=cut
 +
 +Set($OldestTransactionsFirst, 1);
 +
 +=item C<$ShowHistory>
 +
 +This option controls how history is shown on the ticket display page.  It
 +accepts one of three possible modes and is overrideable on a per-user
 +preference level.  If you regularly deal with long tickets and don't care much
 +about the history, you may wish to change this option to C<click>.
 +
 +=over
 +
 +=item C<delay> (the default)
 +
 +When set to C<delay>, history is loaded via javascript after the rest of the
 +page has been loaded.  This speeds up apparent page load times and generally
 +provides a smoother experience.  You may notice slight delays before the ticket
 +history appears on very long tickets.
 +
 +=item C<click>
 +
 +When set to C<click>, history is loaded on demand when a placeholder link is
 +clicked.  This speeds up ticket display page loads and history is never loaded
 +if not requested.
 +
 +=item C<always>
 +
 +When set to C<always>, history is loaded before showing the page.  This ensures
 +history is always available immediately, but at the expense of longer page load
 +times.  This behaviour was the default in RT 4.0.
 +
 +=item C<scroll>
 +
 +When set to C<scroll>, history is loaded via javascript after the rest of the
 +page has been loaded, as you scroll down the page. Ten transactions are loaded
 +initially, and then more are loaded ten at a time. This can dramatically speed
 +up initial page load times on very long tickets.
 +
 +=back
 +
 +=cut
 +
 +Set($ShowHistory, 'delay');
 +
 +=item C<$ShowBccHeader>
 +
 +By default, RT hides from the web UI information about blind copies
 +user sent on reply or comment.
 +
 +=cut
 +
 +Set($ShowBccHeader, 0);
 +
 +=item C<$TrustHTMLAttachments>
 +
 +If C<TrustHTMLAttachments> is not defined, we will display them as
 +text. This prevents malicious HTML and JavaScript from being sent in a
 +request (although there is probably more to it than that)
 +
 +=cut
 +
 +Set($TrustHTMLAttachments, undef);
 +
 +=item C<$AlwaysDownloadAttachments>
 +
 +Always download attachments, regardless of content type. If set, this
 +overrides C<TrustHTMLAttachments>.
 +
 +=cut
 +
 +Set($AlwaysDownloadAttachments, undef);
 +
 +=item C<$AttachmentListCount>
 +
- The number of attachments to display by default on ticket display and ticket
- reply pages. Attachments beyond this count will be displayed only after the
- user clicks a "Show all" link. The default value, C<undef>, means always show
++Sets the number of attachments to display on ticket display and ticket
++update pages (default is 5). Attachments beyond this number are displayed
++only after the user clicks the "Show all" link. Set to C<undef> to always show
 +all attachments. A value of C<0> means show no attachments by default.
 +
 +=cut
 +
- Set($AttachmentListCount, undef);
++Set($AttachmentListCount, 5);
 +
 +=item C<$PreferRichText>
 +
 +By default, RT shows rich text (HTML) messages if possible.  If
 +C<$PreferRichText> is set to 0, RT will show plain text messages in
 +preference to any rich text alternatives.
 +
 +As a security precaution, RT limits the HTML that is displayed to a
 +known-good subset -- as allowing arbitrary HTML to be displayed exposes
 +multiple vectors for XSS and phishing attacks.  If
 +L</$TrustHTMLAttachments> is enabled, the original HTML is available for
 +viewing via the "Download" link.
 +
 +=cut
 +
 +Set($PreferRichText, 1);
 +
 +=item C<$MaxInlineBody>
 +
 +C<$MaxInlineBody> is the maximum textual attachment size that we want to
 +see inline when viewing a transaction.  RT will inline any text if the
 +value is undefined or 0.  This option can be overridden by users in
 +their preferences.  The default is 25k.
 +
 +=cut
 +
 +Set($MaxInlineBody, 25 * 1024);
 +
 +=item C<$ShowTransactionImages>
 +
 +By default, RT shows images attached to incoming (and outgoing) ticket
 +updates inline. Set this variable to 0 if you'd like to disable that
 +behavior.
 +
 +=cut
 +
 +Set($ShowTransactionImages, 1);
 +
 +=item C<$ShowRemoteImages>
 +
 +By default, RT doesn't show remote images attached to incoming (and outgoing)
 +ticket updates inline.  Set this variable to 1 if you'd like to enable remote
 +image display.  Showing remote images may allow spammers and other senders to
 +track when messages are viewed and see referer information.
 +
 +Note that this setting is independent of L</$ShowTransactionImages> above.
 +
 +=cut
 +
 +Set($ShowRemoteImages, 0);
 +
 +=item C<$PlainTextMono>
 +
 +Normally plaintext attachments are displayed as HTML with line breaks
 +preserved.  This causes space- and tab-based formatting not to be
 +displayed correctly.  Set C<$PlainTextMono> to 1 to use a monospaced
 +font and preserve formatting.
 +
 +=cut
 +
 +Set($PlainTextMono, 0);
 +
 +=item C<$SuppressInlineTextFiles>
 +
 +If C<$SuppressInlineTextFiles> is set to 1, then uploaded text files
 +(text-type attachments with file names) are prevented from being
 +displayed in-line when viewing a ticket's history.
 +
 +=cut
 +
 +Set($SuppressInlineTextFiles, undef);
 +
 +
 +=item C<@Active_MakeClicky>
 +
 +MakeClicky detects various formats of data in headers and email
 +messages, and extends them with supporting links.  By default, RT
 +provides two formats:
 +
 +* 'httpurl': detects http:// and https:// URLs and adds '[Open URL]'
 +  link after the URL.
 +
 +* 'httpurl_overwrite': also detects URLs as 'httpurl' format, but
 +  replaces the URL with a link.  Enabled by default.
 +
 +See F<share/html/Elements/MakeClicky> for documentation on how to add
 +your own styles of link detection.
 +
 +=cut
 +
 +Set(@Active_MakeClicky, qw(httpurl_overwrite));
 +
 +=item C<$QuoteFolding>
 +
 +Quote folding is the hiding of old replies in transaction history.
 +It defaults to on.  Set this to 0 to disable it.
 +
 +=cut
 +
 +Set($QuoteFolding, 1);
 +
++=item C<$QuoteWrapWidth>
++
++C<$QuoteWrapWidth> controls the number of columns to use when wrapping
++quoted text within transactions.
++
++=cut
++
++Set($QuoteWrapWidth, 70);
++
 +=back
 +
 +
 +=head2 Administrative interface
 +
 +=over 4
 +
 +=item C<$ShowRTPortal>
 +
 +RT can show administrators a feed of recent RT releases and other
 +related announcements and information from Best Practical on the top
 +level Admin page.  This feature helps you stay up to date on
 +RT security announcements and version updates.
 +
 +RT provides this feature using an "iframe" on C</Admin/index.html>
 +which asks the administrator's browser to show an inline page from
 +Best Practical's website.
 +
 +If you'd rather not make this feature available to your
 +administrators, set C<$ShowRTPortal> to 0.
 +
 +=cut
 +
 +Set($ShowRTPortal, 1);
 +
 +=item C<%AdminSearchResultFormat>
 +
 +In the admin interface, format strings similar to tickets result
 +formats are used. Use C<%AdminSearchResultFormat> to define the format
 +strings used in the admin interface on a per-RT-class basis.
 +
 +=cut
 +
 +Set(%AdminSearchResultFormat,
 +    Queues =>
 +        q{'<a href="__WebPath__/Admin/Queues/Modify.html?id=__id__">__id__</a>/TITLE:#'}
 +        .q{,'<a href="__WebPath__/Admin/Queues/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
 +        .q{,__Description__,__Address__,__Priority__,__DefaultDueIn__,__Lifecycle__,__SubjectTag__,__Disabled__,__SortOrder__},
 +
 +    Groups =>
 +        q{'<a href="__WebPath__/Admin/Groups/Modify.html?id=__id__">__id__</a>/TITLE:#'}
 +        .q{,'<a href="__WebPath__/Admin/Groups/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
 +        .q{,'__Description__',__Disabled__},
 +
 +    Users =>
 +        q{'<a href="__WebPath__/Admin/Users/Modify.html?id=__id__">__id__</a>/TITLE:#'}
 +        .q{,'<a href="__WebPath__/Admin/Users/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
 +        .q{,__RealName__, __EmailAddress__,__Disabled__},
 +
 +    CustomFields =>
 +        q{'<a href="__WebPath__/Admin/CustomFields/Modify.html?id=__id__">__id__</a>/TITLE:#'}
 +        .q{,'<a href="__WebPath__/Admin/CustomFields/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
 +        .q{,__AddedTo__, __EntryHint__, __FriendlyPattern__,__Disabled__},
 +
 +    CustomRoles =>
 +        q{'<a href="__WebPath__/Admin/CustomRoles/Modify.html?id=__id__">__id__</a>/TITLE:#'}
 +        .q{,'<a href="__WebPath__/Admin/CustomRoles/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
 +        .q{,__Description__,__MaxValues__,__Disabled__},
 +
 +    Scrips =>
 +        q{'<a href="__WebPath__/Admin/Scrips/Modify.html?id=__id____From__">__id__</a>/TITLE:#'}
 +        .q{,'<a href="__WebPath__/Admin/Scrips/Modify.html?id=__id____From__">__Description__</a>/TITLE:Description'}
 +        .q{,__Condition__, __Action__, __Template__, __Disabled__},
 +
 +    Templates =>
 +        q{'<a href="__WebPath__/__WebRequestPathDir__/Template.html?Queue=__QueueId__&Template=__id__">__id__</a>/TITLE:#'}
 +        .q{,'<a href="__WebPath__/__WebRequestPathDir__/Template.html?Queue=__QueueId__&Template=__id__">__Name__</a>/TITLE:Name'}
 +        .q{,'__Description__','__UsedBy__','__IsEmpty__'},
 +    Classes =>
 +        q{ '<a href="__WebPath__/Admin/Articles/Classes/Modify.html?id=__id__">__id__</a>/TITLE:#'}
 +        .q{,'<a href="__WebPath__/Admin/Articles/Classes/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
 +        .q{,__Description__,__Disabled__},
 +
 +    Catalogs =>
 +        q{'<a href="__WebPath__/Admin/Assets/Catalogs/Modify.html?id=__id__">__id__</a>/TITLE:#'}
 +        .q{,'<a href="__WebPath__/Admin/Assets/Catalogs/Modify.html?id=__id__">__Name__</a>/TITLE:Name'}
 +        .q{,__Description__,__Lifecycle__,__Disabled__},
 +);
 +
 +=item C<%AdminSearchResultRows>
 +
 +Use C<%AdminSearchResultRows> to define the search result rows in the admin
 +interface on a per-RT-class basis.
 +
 +=cut
 +
 +Set(%AdminSearchResultRows,
 +    Queues       => 50,
 +    Groups       => 50,
 +    Users        => 50,
 +    CustomFields => 50,
 +    CustomRoles  => 50,
 +    Scrips       => 50,
 +    Templates    => 50,
 +    Classes      => 50,
 +    Catalogs     => 50,
 +    Assets       => 50,
 +);
 +
 +=back
 +
 +
 +
 +
 +=head1 Features
 +
 +=head2 Syncing Users and Groups with LDAP or AD
 +
 +In addition to the authentication services described above, RT also
 +has a utility you can schedule to periodicially sync from your
 +directory service additional user attributes, new users,
 +disabled users, and group membership. Options for the
 +LDAPImport tool are listed here. Additional information is
 +available in the L<RT::LDAPImport> documentation.
 +
 +=over 4
 +
 +=item C<$LDAPHost>
 +
 +Your LDAP server hostname.
 +
 +=item C<$LDAPUser>
 +
 +The LDAP user to log in with.
 +
 +=item C<$LDAPOptions>
 +
 +LDAP options that are supported by the L<Net::LDAP> new method.
 +
 +Example:
 +
 +    Set($LDAPOptions, [ port => 636 ]);
 +
 +=item C<$LDAPPassword>
 +
 +Password for LDAPUser.
 +
 +=item C<$LDAPFilter>
 +
 +The filter to use when querying LDAP for the set of users to sync.
 +
 +=item C<$LDAPMapping>
 +
 +Mapping to apply between LDAP attributes retrieved and RT user
 +record attributes. See the L<RT::LDAPImport> documentation
 +for details.
  
 -Be aware that L<Time::ParseDate> and L<DateTime::Format::Natural> have
 -different definitions for the relative date and time syntax.
 -L<Time::ParseDate> returns for 'last month' this DayOfMonth from the last month.
 -L<DateTime::Format::Natural> returns for 'last month' the first day of the last
 -month. So changing this config option maybe changes the results of your saved
 -searches.
 +=item C<$LDAPGroupBase>
  
 -=cut
 +The base for the LDAP group search.
  
 -Set($PreferDateTimeFormatNatural, 0);
 +=item C<$LDAPGroupFilter>
 +
 +The filter to use when querying LDAP for groups to sync.
 +
 +=item C<$LDAPGroupMapping>
 +
 +Mapping to apply between LDAP group member attributes retrieved and
 +RT groups. See the L<RT::LDAPImport> documentation
 +for details.
  
  =back
  
diff --cc lib/RT/Config.pm
index 9a71a48b8,431a12ca2..9362e2a66
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@@ -1396,400 -1221,7 +1396,406 @@@ our %META
      ServiceAgreements => {
          Type => 'HASH',
      },
 +    AllowUserAutocompleteForUnprivileged => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    AlwaysDownloadAttachments => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    AmbiguousDayInFuture => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    AmbiguousDayInPast => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ApprovalRejectionNotes => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ArticleOnTicketCreate => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    AutoCreateNonExternalUsers => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    AutocompleteOwnersForSearch => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    CanonicalizeRedirectURLs => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    CanonicalizeURLsInFeeds => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ChartsTimezonesInDB => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    CheckMoreMSMailHeaders => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    DateDayBeforeMonth => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
++    DisplayTotalTimeWorked => {
++        Widget => '/Widgets/Form/Boolean',
++    },
 +    DontSearchFileAttachments => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    DropLongAttachments => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    EditCustomFieldsSingleColumn => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    EnableReminders => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ExternalStorageDirectLink => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ForceApprovalsView => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ForwardFromUser => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    Framebusting => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    HideArticleSearchOnReplyCreate => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    HideResolveActionsWithDependencies => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    HideTimeFieldsFromUnprivilegedUsers => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    LoopsToRTOwner => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    MessageBoxIncludeSignature => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    MessageBoxIncludeSignatureOnComment => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    OnlySearchActiveTicketsInSimpleSearch => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ParseNewMessageForTicketCcs => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    PreferDateTimeFormatNatural => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    PreviewScripMessages => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    RecordOutgoingEmail => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    RestrictLoginReferrer => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    RestrictReferrer => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    SearchResultsAutoRedirect => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ShowBccHeader => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ShowMoreAboutPrivilegedUsers => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ShowRTPortal => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ShowRemoteImages => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ShowTransactionImages => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    StoreLoops => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    StrictLinkACL => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    SuppressInlineTextFiles => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    TruncateLongAttachments => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    TrustHTMLAttachments => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    UseFriendlyFromLine => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    UseFriendlyToLine => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    UseOriginatorHeader => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    UseSQLForACLChecks => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    UseTransactionBatch => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ValidateUserEmailAddresses => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    WebFallbackToRTLogin => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    WebFlushDbCacheEveryRequest => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    WebHttpOnlyCookies => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    WebRemoteUserAuth => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    WebRemoteUserAutocreate => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    WebRemoteUserContinuous => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    WebRemoteUserGecos => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    WebSecureCookies => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    WikiImplicitLinks => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    HideOneTimeSuggestions => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    LinkArticlesOnInclude => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    SelfServiceCorrespondenceOnly => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    SelfServiceDownloadUserData => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    SelfServiceShowGroupTickets => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    ShowSearchResultCount => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +    AllowGroupAutocompleteForUnprivileged => {
 +        Widget => '/Widgets/Form/Boolean',
 +    },
 +
 +    AttachmentListCount => {
 +        Widget => '/Widgets/Form/Integer',
 +    },
 +    AutoLogoff => {
 +        Widget => '/Widgets/Form/Integer',
 +    },
 +    BcryptCost => {
 +        Widget => '/Widgets/Form/Integer',
 +    },
 +    DefaultSummaryRows => {
 +        Widget => '/Widgets/Form/Integer',
 +    },
 +    DropdownMenuLimit => {
 +        Widget => '/Widgets/Form/Integer',
 +    },
 +    ExternalStorageCutoffSize => {
 +        Widget => '/Widgets/Form/Integer',
 +    },
 +    LogoutRefresh => {
 +        Widget => '/Widgets/Form/Integer',
 +    },
 +    MaxAttachmentSize => {
 +        Widget => '/Widgets/Form/Integer',
 +    },
 +    MaxFulltextAttachmentSize => {
 +        Widget => '/Widgets/Form/Integer',
 +    },
 +    MinimumPasswordLength => {
 +        Widget => '/Widgets/Form/Integer',
 +    },
 +    MoreAboutRequestorGroupsLimit => {
 +        Widget => '/Widgets/Form/Integer',
 +    },
 +    TicketsItemMapSize => {
 +        Widget => '/Widgets/Form/Integer',
 +    },
 +
 +    CanonicalizeEmailAddressMatch => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    CanonicalizeEmailAddressReplace => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    CommentAddress => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    CorrespondAddress => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    DashboardAddress => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    DashboardSubject => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    DefaultErrorMailPrecedence => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    DefaultMailPrecedence => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    DefaultSearchResultOrderBy => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    EmailSubjectTagRegex => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    EmailOutputEncoding => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    FriendlyFromLineFormat => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    FriendlyToLineFormat => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    LDAPHost => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    LDAPUser => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    LDAPPassword => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    LDAPGroupBase => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    LogDir => {
 +        Immutable => 1,
 +        Widget => '/Widgets/Form/String',
 +    },
 +    LogToFileNamed => {
 +        Immutable => 1,
 +        Widget => '/Widgets/Form/String',
 +    },
 +    LogoAltText => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    LogoLinkURL => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    LogoURL => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    OwnerEmail => {
 +        Widget => '/Widgets/Form/String',
 +    },
++    QuoteWrapWidth => {
++        Widget => '/Widgets/Form/Integer',
++    },
 +    RedistributeAutoGeneratedMessages => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    SelfServiceRequestUpdateQueue => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    SendmailArguments => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    SendmailBounceArguments => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    SendmailPath => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    SetOutgoingMailFrom => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    Timezone => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +    VERPPrefix => {
 +        Widget => '/Widgets/Form/String',
 +        WidgetArguments => { Hints  => 'rt-', },
 +    },
 +    VERPDomain => {
 +        Widget => '/Widgets/Form/String',
 +        WidgetArguments => {
 +            Callback => sub {  return { Hints => RT->Config->Get( 'Organization') } },
 +        },
 +    },
 +    WebImagesURL => {
 +        Widget => '/Widgets/Form/String',
 +    },
 +
 +    LogToSyslog => {
 +        Immutable => 1,
 +        Widget => '/Widgets/Form/Select',
 +        WidgetArguments => { Values => [qw(debug info notice warning error critical alert emergency)] },
 +    },
 +    LogToSTDERR => {
 +        Immutable => 1,
 +        Widget => '/Widgets/Form/Select',
 +        WidgetArguments => { Values => [qw(debug info notice warning error critical alert emergency)] },
 +    },
 +    LogToFile => {
 +        Immutable => 1,
 +        Widget => '/Widgets/Form/Select',
 +        WidgetArguments => { Values => [qw(debug info notice warning error critical alert emergency)] },
 +    },
 +    LogStackTraces => {
 +        Immutable => 1,
 +        Widget => '/Widgets/Form/Select',
 +        WidgetArguments => { Values => [qw(debug info notice warning error critical alert emergency)] },
 +    },
 +    StatementLog => {
 +        Widget => '/Widgets/Form/Select',
 +        WidgetArguments => { Values => ['', qw(debug info notice warning error critical alert emergency)] },
 +    },
 +
 +    DefaultCatalog => {
 +        Widget          => '/Widgets/Form/Select',
 +        WidgetArguments => {
 +            Description => 'Default catalog',    #loc
 +            Callback    => sub {
 +                my $ret = { Values => [], ValuesLabel => {} };
 +                my $c = RT::Catalogs->new( $HTML::Mason::Commands::session{'CurrentUser'} );
 +                $c->UnLimit;
 +                while ( my $catalog = $c->Next ) {
 +                    next unless $catalog->CurrentUserHasRight("CreateAsset");
 +                    push @{ $ret->{Values} }, $catalog->Id;
 +                    $ret->{ValuesLabel}{ $catalog->Id } = $catalog->Name;
 +                }
 +                return $ret;
 +            },
 +        }
 +    },
 +    DefaultSearchResultOrder => {
 +        Widget => '/Widgets/Form/Select',
 +        WidgetArguments => { Values => [qw(ASC DESC)] },
 +    },
 +    LogToSyslogConf => {
 +        Immutable     => 1,
 +    },
  );
  my %OPTIONS = ();
  my @LOADED_CONFIGS = ();
diff --cc share/html/Prefs/Elements/EditAboutMe
index 058030803,b3e869c14..da7780a67
--- a/share/html/Prefs/Elements/EditAboutMe
+++ b/share/html/Prefs/Elements/EditAboutMe
@@@ -45,107 -45,64 +45,107 @@@
  %# those contributions and any derivatives thereof.
  %#
  %# END BPS TAGGED BLOCK }}}
- <form name="EditAboutMe" action="" method="post">
+ <form name="EditAboutMe" action="" method="post" enctype="multipart/form-data">
  <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>
 -  <tr>
 -    <td class="label"><&|/l&>Timezone</&>:</td>
 -    <td class="value"><& /Elements/SelectTimezone, Name => 'Timezone', Default => $UserObj->Timezone &></td>
 -  </tr>
 -<& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Identity', InTable => 1 &>
 -</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>
 -<& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Phones', InTable => 1 &>
 -</table>
 -</&>
 -%if ($UserObj->Privileged) {
 -<&| /Widgets/TitleBox, title => loc('Signature'), id => "user-prefs-signature" &>
 -<textarea cols="80" rows="5" name="Signature" class="signature" wrap="hard">
 -<%$UserObj->Signature || ''%></textarea>
 -</&>
 -% }
 +<div class="form-row">
 +%### Left column ###
 +  <div class="col-md-6">
 +
 +    <&| /Widgets/TitleBox, title => loc('Identity'), id => "user-prefs-identity" &>
 +      <input type="hidden" class="hidden" name="Name" value="<%$UserObj->Name%>" />
 +      <div class="form-row">
 +        <div class="label col-md-3">
 +          <&|/l&>Email</&>:
 +        </div>
 +        <div class="col-md-9 value">
 +          <input class="form-control" type="text" name="EmailAddress" value="<%$UserObj->EmailAddress%>" />
 +        </div>
 +      </div>
 +
 +      <div class="form-row">
 +        <div class="label col-md-3">
 +          <&|/l&>Real Name</&>:
 +        </div>
 +        <div class="col-md-9 value">
 +          <input class="form-control" type="text" name="RealName" value="<%$UserObj->RealName%>" />
 +        </div>
 +      </div>
 +
 +      <div class="form-row">
 +        <div class="label col-md-3">
 +          <&|/l&>Nickname</&>:
 +        </div>
 +        <div class="col-md-9 value">
 +          <input class="form-control" type="text" name="NickName" value="<%$UserObj->NickName || ''%>" />
 +        </div>
 +      </div>
 +
 +      <div class="form-row">
 +        <div class="label col-md-3">
 +          <&|/l&>Language</&>:
 +        </div>
 +        <div class="col-md-9 value">
 +          <& /Elements/SelectLang, Name => 'Lang', Default => $UserObj->Lang &>
 +        </div>
 +      </div>
 +      <div class="form-row">
 +        <div class="label col-md-3">
 +          <&|/l&>Timezone</&>:
 +        </div>
 +        <div class="col-md-9 value">
 +          <& /Elements/SelectTimezone, Name => 'Timezone', Default => $UserObj->Timezone &>
 +        </div>
 +      </div>
 +
 +      <div class="form-row">
 +        <& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Identity' &>
 +      </div>
 +    </&>
 +
 +    <&| /Widgets/TitleBox, title => loc('Phone numbers'), id => "user-prefs-phone" &>
 +      <div class="form-row">
 +        <div class="label col-md-3">
 +          <&|/l&>Residence</&>:
 +        </div>
 +        <div class="col-md-9 value">
 +          <input class="form-control" type="tel" name="HomePhone" value="<%$UserObj->HomePhone || ''%>" size="13" />
 +        </div>
 +      </div>
 +
 +      <div class="form-row">
 +        <div class="label col-md-3">
 +          <&|/l&>Work</&>:
 +        </div>
 +        <div class="col-md-9 value">
 +          <input class="form-control" type="tel" name="WorkPhone" value="<%$UserObj->WorkPhone || ''%>" size="13" />
 +        </div>
 +      </div>
 +
 +      <div class="form-row">
 +        <div class="label col-md-3">
 +          <&|/l&>Mobile</&>:
 +        </div>
 +        <div class="col-md-9 value">
 +          <input class="form-control" type="tel" name="MobilePhone" value="<%$UserObj->MobilePhone || ''%>" size="13" />
 +        </div>
 +      </div>
 +
 +      <div class="form-row">
 +        <div class="label col-md-3">
 +          <&|/l&>Pager</&>:
 +        </div>
 +        <div class="col-md-9 value">
 +          <input class="form-control" type="tel" name="PagerPhone" value="<%$UserObj->PagerPhone || ''%>" size="13" />
 +        </div>
 +      </div>
 +
 +      <div class="form-row">
 +        <div class="label col-md-12">
 +          <& /Elements/EditCustomFields, Object => $UserObj, Grouping => 'Phones' &>
 +        </div>
 +      </div>
 +    </&>
  
  % $m->callback( %ARGS, UserObj => $UserObj, CallbackName => 'FormLeftColumn' );
  
diff --cc share/html/Search/Elements/EditSearches
index 211f66041,6e7220eb1..3750212e1
--- a/share/html/Search/Elements/EditSearches
+++ b/share/html/Search/Elements/EditSearches
@@@ -47,46 -47,37 +47,46 @@@
  %# END BPS TAGGED BLOCK }}}
  <div class="edit-saved-searches">
  <&| /Widgets/TitleBox, title => loc($Title)&>
 -
  %# Hide all the save functionality if the user shouldn't see it.
  % if ( $can_modify ) {
 -<span class="label"><&|/l&>Privacy</&>:</span>
 -<& SelectSearchObject, Name => 'SavedSearchOwner', Objects => \@CreateObjects, Object => ( $Object && $Object->id ) ? $Object->Object : '' &>
 -<br />
 -<span class="label"><&|/l&>Description</&>:</span>
 -<input size="25" name="SavedSearchDescription" value="<% $Description || '' %>" />
  
 +<div class="form-row">
 +  <div class="col-md-4 label"><&|/l&>Privacy</&>:</div>
 +  <div class="col-md-8">
- <& SelectSearchObject, Name => 'SavedSearchOwner', Objects => \@Objects, Object => ( $Object && $Object->id ) ? $Object->Object : '' &>
++<& SelectSearchObject, Name => 'SavedSearchOwner', Objects => \@CreateObjects, Object => ( $Object && $Object->id ) ? $Object->Object : '' &>
 +  </div>
 +</div>
 +  <div class="form-row">
 +    <div class="col-md-4 label"><&|/l&>Description</&>:</div>
 +    <div class="col-md-8 input-group">
 +      <input type="text" size="25" name="SavedSearchDescription" value="<% $Description || '' %>" class="form-control" />
  % if ($Id ne 'new') {
 -<nobr>
  % if ( $Dirty ) {
 -<input type="submit" class="button" name="SavedSearchRevert" value="<%loc('Revert')%>" />
 +<input type="submit" class="button btn btn-primary" name="SavedSearchRevert" value="<%loc('Revert')%>" />
  % }
 -<input type="submit" class="button" name="SavedSearchDelete" value="<%loc('Delete')%>" />
 +<input type="submit" class="button btn btn-primary" name="SavedSearchDelete" value="<%loc('Delete')%>" />
  % if ( $AllowCopy ) {
 -<input type="submit" class="button" name="SavedSearchCopy"   value="<%loc('Save as New')%>" />
 +<input type="submit" class="button btn btn-primary" name="SavedSearchCopy"   value="<%loc('Save as New')%>" />
  % }
 -</nobr>
  % }
 +
  % if ( $Object && $Object->Id && $Object->CurrentUserHasRight('update') ) {
 -<input type="submit" class="button" id="SavedSearchSave" name="SavedSearchSave"   value="<%loc('Update')%>" />
 +<input type="submit" class="button btn btn-primary" id="SavedSearchSave" name="SavedSearchSave"   value="<%loc('Update')%>" />
  % } elsif ( !$Object ) {
 -<input type="submit" class="button" id="SavedSearchSave" name="SavedSearchSave"   value="<%loc('Save')%>" />
 +<input type="submit" class="button btn btn-primary" id="SavedSearchSave" name="SavedSearchSave"   value="<%loc('Save')%>" />
  %}
  % }
 -<br />
 -<hr />
 -<span class="label"><&|/l&>Load saved search</&>:</span>
 +    </div>
 +  </div>
 +
 +  <hr />
 +  <div class="form-row">
 +    <div class="col-md-4 label"><&|/l&>Load saved search</&>:</div>
 +    <div class="col-md-8 input-group">
- <& SelectSearchesForObjects, Name => 'SavedSearchLoad', Objects => \@Objects, SearchType => $Type &>
+ <& SelectSearchesForObjects, Name => 'SavedSearchLoad', Objects => \@LoadObjects, SearchType => $Type &>
 -<input type="submit" value="<% loc('Load') %>" id="SavedSearchLoadSubmit" name="SavedSearchLoadSubmit" class="button" />
 +<input type="submit" class="button btn btn-primary" value="<% loc('Load') %>" id="SavedSearchLoadSubmit" name="SavedSearchLoadSubmit" />
 +    </div>
 +  </div>
  
  </&>
  </div>
diff --cc share/html/Ticket/Elements/AddAttachments
index 9857786ae,125399ce3..e51c13048
--- a/share/html/Ticket/Elements/AddAttachments
+++ b/share/html/Ticket/Elements/AddAttachments
@@@ -52,14 -52,15 +52,14 @@@
      <div>
          <label for="DeleteAttach-<%$attach_name%>"><% $attach_name %></label>
  %       $m->callback( ARGSRef => \%ARGS, CallbackName => 'BeforeDeleteLink', AttachmentName => $attach_name );
-         (<a href="#" class="delete-attach" data-name="<%$attach_name%>" /><&|/l&>Delete</&></a>)
+         (<a href="#" class="delete-attach" data-name="<%$attach_name%>"><&|/l&>Delete</&></a>)
      </div>
  % } # end of foreach
 -</td>
 -</tr>
 +</div>
 +</div>
  % } # end of if
  
 -<tr><td class="label"><&|/l&>Attach</&>:</td>
 -    <td>
 +<div class="form-group">
          <div class="dropzone" id="attach-dropzone">
          </div>
  <script type="text/javascript">
diff --cc share/html/Ticket/Forward.html
index 5061cf9a0,7e81b0c37..c08bc4b5e
--- a/share/html/Ticket/Forward.html
+++ b/share/html/Ticket/Forward.html
@@@ -105,11 -91,12 +105,12 @@@
  % } else {
  <& /Elements/MessageBox, SuppressAttachmentWarning => 1 &>
  %}
 -</td>
 -</tr>
 +    </div>
 +  </div>
 +</div>
  
+ % $m->callback(CallbackName => 'AfterMessageBox', ARGSRef => \%ARGS, TicketObj => $TicketObj);
 -
 -</table>
 +</&>
  
  <& /Ticket/Elements/ShowAttachments, Ticket => $TicketObj, Attachments => $attachments, Count => RT->Config->Get('AttachmentListCount') &>
  
diff --cc share/html/Ticket/Update.html
index cad90aabc,0439b74ac..645394ab4
--- a/share/html/Ticket/Update.html
+++ b/share/html/Ticket/Update.html
@@@ -232,35 -217,40 +232,40 @@@ jQuery( function() 
         jQuery('#recipients div.titlebox-content').addClass('refreshing');
         jQuery('#previewscrips div.titlebox-content').addClass('refreshing');
  
-        var payload = jQuery('form[name=TicketUpdate]').serializeArray();
- 
-        jQuery('#recipients div.titlebox-content div.card-body').load( '<% RT->Config->Get('WebPath')%>/Helpers/ShowSimplifiedRecipients',
-            payload,
-            function() {
-                jQuery('#recipients div.titlebox-content').removeClass('refreshing');
-                var txn_send_field = jQuery("#recipients input[name=TxnSendMailTo]");
-                txn_send_field.change( syncCheckboxes );
-                txn_send_field.click( function () { setCheckbox(this) } );
-                jQuery("#recipients input[name=TxnSendMailToAll]").click( function() { setCheckbox(this, 'TxnSendMailTo'); } );
-                if (txn_send_field.length > 0) {
-                    setCheckbox(txn_send_field[0]);
+        // Wait a little bit in case user leaves related inputs(which
+        // could fire updateScrips) by checking/unchecking recipient
+        // checkboxes, this is to get checkboxes' latest status
+        setTimeout( function() {
+            var payload = jQuery('form[name=TicketUpdate]').serializeArray();
+ 
 -           jQuery('#recipients div.titlebox-content').load( '<% RT->Config->Get('WebPath')%>/Helpers/ShowSimplifiedRecipients',
++           jQuery('#recipients div.titlebox-content div.card-body').load( '<% RT->Config->Get('WebPath')%>/Helpers/ShowSimplifiedRecipients',
+                payload,
+                function() {
+                    jQuery('#recipients div.titlebox-content').removeClass('refreshing');
+                    var txn_send_field = jQuery("#recipients input[name=TxnSendMailTo]");
+                    txn_send_field.change( syncCheckboxes );
+                    txn_send_field.click( function () { setCheckbox(this) } );
+                    jQuery("#recipients input[name=TxnSendMailToAll]").click( function() { setCheckbox(this, 'TxnSendMailTo'); } );
+                    if (txn_send_field.length > 0) {
+                        setCheckbox(txn_send_field[0]);
+                    }
                 }
-            }
-        );
- 
-        jQuery('#previewscrips div.titlebox-content div.card-body').load( '<% RT->Config->Get('WebPath')%>/Helpers/PreviewScrips',
-            payload,
-            function() {
-                jQuery('#previewscrips div.titlebox-content').removeClass('refreshing');
-                var txn_send_field = jQuery("#previewscrips input[name=TxnSendMailTo]");
-                txn_send_field.change( syncCheckboxes );
-                txn_send_field.click( function () { setCheckbox(this) } );
-                jQuery("#previewscrips input[name=TxnSendMailToAll]").click( function() { setCheckbox(this, 'TxnSendMailTo'); } );
-                if (txn_send_field.length > 0) {
-                    setCheckbox(txn_send_field[0]);
+            );
+ 
 -           jQuery('#previewscrips div.titlebox-content').load( '<% RT->Config->Get('WebPath')%>/Helpers/PreviewScrips',
++           jQuery('#previewscrips div.titlebox-content div.card-body').load( '<% RT->Config->Get('WebPath')%>/Helpers/PreviewScrips',
+                payload,
+                function() {
+                    jQuery('#previewscrips div.titlebox-content').removeClass('refreshing');
+                    var txn_send_field = jQuery("#previewscrips input[name=TxnSendMailTo]");
+                    txn_send_field.change( syncCheckboxes );
+                    txn_send_field.click( function () { setCheckbox(this) } );
+                    jQuery("#previewscrips input[name=TxnSendMailToAll]").click( function() { setCheckbox(this, 'TxnSendMailTo'); } );
+                    if (txn_send_field.length > 0) {
+                        setCheckbox(txn_send_field[0]);
+                    }
                 }
-            }
-        );
+            );
+        }, 100);
     };
     updateScrips();
  
diff --cc share/static/css/elevator-light/ticket.css
index fd3fa8839,000000000..fbc1456d5
mode 100644,000000..100644
--- a/share/static/css/elevator-light/ticket.css
+++ b/share/static/css/elevator-light/ticket.css
@@@ -1,142 -1,0 +1,154 @@@
 +/* More about requestor ticket lists */
 +
 +.more-about-requestor-tickets {
 +    background: none;
 +    border: none;
 +    font-family: arial,helvetica,sans-serif !important;
 +    padding: 0 !important;
 +}
 +
 +.more-about-requestor-tickets .ui-tabs-nav {
 +    background: none;
 +    border: none;
 +    font-size: 80%;
 +    padding: 0;
 +    margin: 0;
 +}
 +
 +.more-about-requestor-tickets .ui-tabs-nav li {
 +    border: none !important;
 +    background: none !important;
 +    padding-right: 1em;
 +}
 +
 +.more-about-requestor-tickets .ui-tabs-nav a {
 +    padding: 0 !important;
 +    margin: 0 !important;
 +    color: black !important;
 +}
 +
 +.more-about-requestor-tickets .ui-tabs-nav a:hover,
 +.more-about-requestor-tickets .ui-tabs-nav .ui-tabs-active a {
 +    text-decoration: underline;
 +}
 +
 +.more-about-requestor-tickets .ui-tabs-panel {
 +    border: none;
 +    padding: 0;
 +    margin: 0;
 +    color: black !important;
 +}
 +
 +.more-about-requestor-tickets .ui-tabs-panel a {
 +    color: black !important;
 +}
 +
 +.ticket-info-reminders .save {
 +    text-align: right;
 +}
 +
 +.plain-text-white-space {
 + white-space: pre-wrap;
 + font-family: monospace;
 +}
 +
 +.plain-text-white-space br {
 +    display: none;
 +}
 +
 +.dependency-status {
 +    font-style: italic;
 +}
 +.dependency-status .summary {
 +    font-weight: bold;
 +    font-style: normal;
 +}
 +
 +.unread-messages .titlebox-content :link {
-     text-decoration: underline;
++    text-decoration: none;
++}
++
++.small-button {
++    padding: 0.2em 0.5em !important;
++}
++
++.new-messages-buttons {
++    display: inline-block;
++}
++
++.new-messages-on-ticket {
++    font-style: italic;
 +}
 +
 +.ticket-inactive {
 +  text-decoration: line-through;
 +  color: #666
 +}
 +
 +div.requestor-ticket-links {
 +    text-align: left;
 +    font-size: 0.8em;
 +    padding-top: 0.25em;
 +}
 +
 +.ticket-info-requestor .more-about-requestor-extra,
 +.ticket-info-requestor .comments-about-user,
 +.ticket-info-requestor .more-about-requestor-tickets,
 +.ticket-info-requestor .more-about-user-groups
 +{
 +    margin: 0.5em 0 1em 0;
 +}
 +
 +.ticket-info-requestor .comments-about-user .label,
 +.ticket-info-requestor .more-about-user-groups .label,
 +.ticket-info-requestor .more-about-requestor-tickets .label
 +{
 +    display: block;
 +    font-weight: bold;
 +    text-align: left;
 +}
 +
 +.ticket-info-requestor .more-about-user-groups .value ul,
 +.ticket-info-requestor .more-about-requestor-tickets ul
 +{
 +    margin-top: 0;
 +    margin-bottom: 0;
 +}
 +
 +.unset-fields-hidden .unset-field {
 +    display: none !important;
 +}
 +
 +.ticket-info-attachments .revision {
 +    font-size: 85%;
 +}
 +
 +.transaction .downloadattachment a,
 +.transaction .message-header-value,
 +.ticket-info-attachments .filename {
 +    word-break: break-word;
 +}
 +
 +ul.select-queue {
 +    list-style-type: none;
 +    margin-left: 0;
 +    padding-left: 1.5em;
 +}
 +ul.select-queue li + li {
 +    margin-top: .5em;
 +}
 +ul.select-queue li a:visited {
 +    color: #000;
 +}
 +
 +.ticket-merge-text {
 +    font-style: italic;
 +}
 +
 +.ticket-merge-position {
 +    padding-left: 2em;
 +}
 +
 +#create-linked-ticket {
 +    padding-top: 15px;
 +}

-----------------------------------------------------------------------


More information about the rt-commit mailing list