[Rt-commit] rt branch, 4.4/core-assets, updated. rt-4.2.11-45-gbc64c0a

Todd Wade todd at bestpractical.com
Thu Aug 13 12:19:15 EDT 2015


The branch, 4.4/core-assets has been updated
       via  bc64c0a30e9de997542549e43129e66b169aa939 (commit)
       via  9a64b0d968df969f53ae8e1884899c18515b66a7 (commit)
      from  0f24385d6628e0a6df6533ab2bd9269bf9975c52 (commit)

Summary of changes:
 lib/RT/Interface/Web.pm                            |   1 +
 share/html/Admin/Assets/Catalogs/Create.html       |  87 ++++++++
 share/html/Admin/Assets/Catalogs/CustomFields.html |  61 ++++++
 .../html/Admin/Assets/Catalogs/Elements/EditBasics |  82 ++++++++
 share/html/Admin/Assets/Catalogs/GroupRights.html  |  64 ++++++
 share/html/Admin/Assets/Catalogs/Modify.html       |  88 ++++++++
 share/html/Admin/Assets/Catalogs/Roles.html        |  82 ++++++++
 share/html/Admin/Assets/Catalogs/UserRights.html   |  64 ++++++
 share/html/Admin/Assets/Catalogs/index.html        | 118 +++++++++++
 share/html/Admin/Assets/index.html                 |  50 +++++
 .../Admin/Global/CustomFields/Catalog-Assets.html  |  54 +++++
 share/html/Asset/Create.html                       | 185 +++++++++++++++++
 share/html/Asset/CreateInCatalog.html              |  51 +++++
 share/html/Asset/CreateLinkedTicket.html           |  58 ++++++
 share/html/Asset/Display.html                      |  75 +++++++
 share/html/Asset/Elements/AssetSearchBasics        |  87 ++++++++
 share/html/Asset/Elements/AssetSearchCFs           |  72 +++++++
 share/html/Asset/Elements/AssetSearchPeople        |  83 ++++++++
 share/html/Asset/Elements/CreateInCatalog          |  53 +++++
 share/html/Asset/Elements/CreateLinkedTicket       |  78 +++++++
 share/html/Asset/Elements/EditBasics               |  85 ++++++++
 share/html/Asset/Elements/EditDates                |  72 +++++++
 share/html/Asset/Elements/EditPeople               |  64 ++++++
 share/html/Asset/Elements/SelectCatalog            |  69 +++++++
 share/html/Asset/Elements/SelectStatus             |  66 ++++++
 share/html/Asset/Elements/ShowBasics               |  70 +++++++
 share/html/Asset/Elements/ShowCatalog              |  69 +++++++
 share/html/Asset/Elements/ShowDates                |  72 +++++++
 share/html/Asset/Elements/ShowLinks                |  48 +++++
 share/html/Asset/Elements/ShowPeople               |  76 +++++++
 share/html/Asset/Elements/ShowRoleMembers          |  90 ++++++++
 share/html/Asset/Elements/ShowSummary              |  83 ++++++++
 share/html/Asset/Elements/TSVExport                | 126 ++++++++++++
 share/html/Asset/Helpers/CreateInCatalog           |  49 +++++
 share/html/Asset/Helpers/CreateLinkedTicket        |  56 +++++
 share/html/Asset/History.html                      |  64 ++++++
 share/html/Asset/Modify.html                       | 133 ++++++++++++
 share/html/Asset/ModifyCFs.html                    | 105 ++++++++++
 share/html/Asset/ModifyDates.html                  |  97 +++++++++
 share/html/Asset/ModifyLinks.html                  |  98 +++++++++
 share/html/Asset/ModifyPeople.html                 | 111 ++++++++++
 share/html/Asset/Search/Bulk.html                  | 197 ++++++++++++++++++
 share/html/Asset/Search/Results.tsv                |  73 +++++++
 share/html/Asset/Search/index.html                 | 108 ++++++++++
 share/html/Asset/index.html                        |  66 ++++++
 share/html/Elements/Assets/AddPeople               |  67 ++++++
 share/html/Elements/Assets/EditPeople              |  59 ++++++
 share/html/Elements/Assets/EditRoleMembers         |  79 +++++++
 share/html/Elements/Assets/Search                  |  53 +++++
 share/html/Elements/Assets/SelectRoleType          |  60 ++++++
 share/html/Elements/FindAsset                      |  53 +++++
 share/html/Elements/MyAssets                       |  48 +++++
 share/html/Elements/RT__Asset/ColumnMap            | 121 +++++++++++
 share/html/Elements/RT__Catalog/ColumnMap          |  79 +++++++
 .../html/SelfService/Asset/CreateLinkedTicket.html |  57 +++++
 share/html/SelfService/Asset/Display.html          |  57 +++++
 .../SelfService/Asset/Helpers/CreateLinkedTicket   |  55 +++++
 share/html/SelfService/Asset/History.html          |  60 ++++++
 share/html/SelfService/Asset/index.html            |  49 +++++
 share/html/Ticket/Elements/ShowAssets              | 204 ++++++++++++++++++
 share/html/Ticket/Elements/ShowAssetsOnCreate      | 121 +++++++++++
 share/html/User/Elements/AssetList                 |  78 +++++++
 share/html/User/Elements/Portlets/UserAssets       |  52 +++++
 share/static/css/base/assets.css                   | 229 +++++++++++++++++++++
 share/static/js/assets.js                          |  44 ++++
 65 files changed, 5265 insertions(+)
 create mode 100644 share/html/Admin/Assets/Catalogs/Create.html
 create mode 100644 share/html/Admin/Assets/Catalogs/CustomFields.html
 create mode 100644 share/html/Admin/Assets/Catalogs/Elements/EditBasics
 create mode 100644 share/html/Admin/Assets/Catalogs/GroupRights.html
 create mode 100644 share/html/Admin/Assets/Catalogs/Modify.html
 create mode 100644 share/html/Admin/Assets/Catalogs/Roles.html
 create mode 100644 share/html/Admin/Assets/Catalogs/UserRights.html
 create mode 100644 share/html/Admin/Assets/Catalogs/index.html
 create mode 100644 share/html/Admin/Assets/index.html
 create mode 100644 share/html/Admin/Global/CustomFields/Catalog-Assets.html
 create mode 100644 share/html/Asset/Create.html
 create mode 100644 share/html/Asset/CreateInCatalog.html
 create mode 100644 share/html/Asset/CreateLinkedTicket.html
 create mode 100644 share/html/Asset/Display.html
 create mode 100644 share/html/Asset/Elements/AssetSearchBasics
 create mode 100644 share/html/Asset/Elements/AssetSearchCFs
 create mode 100644 share/html/Asset/Elements/AssetSearchPeople
 create mode 100644 share/html/Asset/Elements/CreateInCatalog
 create mode 100644 share/html/Asset/Elements/CreateLinkedTicket
 create mode 100644 share/html/Asset/Elements/EditBasics
 create mode 100644 share/html/Asset/Elements/EditDates
 create mode 100644 share/html/Asset/Elements/EditPeople
 create mode 100644 share/html/Asset/Elements/SelectCatalog
 create mode 100644 share/html/Asset/Elements/SelectStatus
 create mode 100644 share/html/Asset/Elements/ShowBasics
 create mode 100644 share/html/Asset/Elements/ShowCatalog
 create mode 100644 share/html/Asset/Elements/ShowDates
 create mode 100644 share/html/Asset/Elements/ShowLinks
 create mode 100644 share/html/Asset/Elements/ShowPeople
 create mode 100644 share/html/Asset/Elements/ShowRoleMembers
 create mode 100644 share/html/Asset/Elements/ShowSummary
 create mode 100644 share/html/Asset/Elements/TSVExport
 create mode 100644 share/html/Asset/Helpers/CreateInCatalog
 create mode 100644 share/html/Asset/Helpers/CreateLinkedTicket
 create mode 100644 share/html/Asset/History.html
 create mode 100644 share/html/Asset/Modify.html
 create mode 100755 share/html/Asset/ModifyCFs.html
 create mode 100755 share/html/Asset/ModifyDates.html
 create mode 100755 share/html/Asset/ModifyLinks.html
 create mode 100755 share/html/Asset/ModifyPeople.html
 create mode 100644 share/html/Asset/Search/Bulk.html
 create mode 100644 share/html/Asset/Search/Results.tsv
 create mode 100644 share/html/Asset/Search/index.html
 create mode 100644 share/html/Asset/index.html
 create mode 100644 share/html/Elements/Assets/AddPeople
 create mode 100644 share/html/Elements/Assets/EditPeople
 create mode 100644 share/html/Elements/Assets/EditRoleMembers
 create mode 100644 share/html/Elements/Assets/Search
 create mode 100644 share/html/Elements/Assets/SelectRoleType
 create mode 100644 share/html/Elements/FindAsset
 create mode 100644 share/html/Elements/MyAssets
 create mode 100644 share/html/Elements/RT__Asset/ColumnMap
 create mode 100644 share/html/Elements/RT__Catalog/ColumnMap
 create mode 100644 share/html/SelfService/Asset/CreateLinkedTicket.html
 create mode 100644 share/html/SelfService/Asset/Display.html
 create mode 100644 share/html/SelfService/Asset/Helpers/CreateLinkedTicket
 create mode 100644 share/html/SelfService/Asset/History.html
 create mode 100644 share/html/SelfService/Asset/index.html
 create mode 100644 share/html/Ticket/Elements/ShowAssets
 create mode 100644 share/html/Ticket/Elements/ShowAssetsOnCreate
 create mode 100644 share/html/User/Elements/AssetList
 create mode 100644 share/html/User/Elements/Portlets/UserAssets
 create mode 100644 share/static/css/base/assets.css
 create mode 100644 share/static/js/assets.js

- Log -----------------------------------------------------------------
commit 9a64b0d968df969f53ae8e1884899c18515b66a7
Author: Todd Wade <todd at bestpractical.com>
Date:   Wed Aug 12 11:13:48 2015 -0400

    copy rt-extension-assets/html/* in to share/html

diff --git a/share/html/Admin/Assets/Catalogs/Create.html b/share/html/Admin/Assets/Catalogs/Create.html
new file mode 100644
index 0000000..1179595
--- /dev/null
+++ b/share/html/Admin/Assets/Catalogs/Create.html
@@ -0,0 +1,87 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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("Create catalog") &>
+<& /Elements/Tabs &>
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" enctype="multipart/form-data" id="CreateCatalog" action="Create.html">
+  <input type="hidden" name="id" value="new">
+
+  <&| /Widgets/TitleBox, title => loc("Basics"), class => "catalog-basics" &>
+    <& Elements/EditBasics, %ARGS, CatalogObj => $catalog &>
+  </&>
+
+  <& /Elements/Submit, Label => loc('Create catalog'), Name => "Update" &>
+</form>
+<%args>
+$id => ""
+</%args>
+<%init>
+my @results;
+my $catalog = RT::Catalog->new( $session{CurrentUser} );
+
+if ($id eq "new") {
+    my %create;
+    for ($catalog->WritableAttributes) {
+        $create{$_} = $ARGS{$_} if exists $ARGS{$_};
+    }
+
+    $m->callback( %ARGS, CatalogObj => $catalog, Create => \%create, CallbackName => 'MassageCreate' );
+
+    my ($ok, $msg, $nonfatal) = $catalog->Create( %create );
+    push @results, $msg, @{$nonfatal || []};
+
+    if ($ok) {
+        MaybeRedirectForResults(
+            Actions     => \@results,
+            Path        => "/Admin/Assets/Catalogs/Modify.html",
+            Arguments   => { id => $catalog->id },
+        );
+    }
+}
+</%init>
diff --git a/share/html/Admin/Assets/Catalogs/CustomFields.html b/share/html/Admin/Assets/Catalogs/CustomFields.html
new file mode 100644
index 0000000..a345c7d
--- /dev/null
+++ b/share/html/Admin/Assets/Catalogs/CustomFields.html
@@ -0,0 +1,61 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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("Catalog [_1]: Edit Custom Fields", $Catalog->Name) &>
+<& /Elements/Tabs &>
+<& /Admin/Elements/EditCustomFields,
+    %ARGS,
+    Object      => $Catalog,
+    ObjectType  => 'RT::Catalog',
+    SubType     => 'RT::Asset',
+    &>
+<%init>
+my $Catalog = LoadCatalog($id);
+</%init>
+<%args>
+$id => undef
+</%args>
diff --git a/share/html/Admin/Assets/Catalogs/Elements/EditBasics b/share/html/Admin/Assets/Catalogs/Elements/EditBasics
new file mode 100644
index 0000000..e084fb6
--- /dev/null
+++ b/share/html/Admin/Assets/Catalogs/Elements/EditBasics
@@ -0,0 +1,82 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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"><label for="Name"><&|/l&>Name</&></label></td>
+    <td><input name="Name" value="<% $current{Name} %>" size="40"></td>
+  </tr>
+  <tr>
+    <td class="label"><label for="Description"><&|/l&>Description</&></label></td>
+    <td><input name="Description" value="<% $current{Description} %>" size="40"></td>
+  </tr>
+  <tr class="lifecycle">
+    <td class="label"><label for="Lifecycle"><&|/l&>Lifecycle</&></label></td>
+    <td>
+      <& /Widgets/Form/Select:InputOnly,
+          Name         => 'Lifecycle',
+          Values       => [ sort { loc($a) cmp loc($b) } RT::Lifecycle->List( $CatalogObj->LifecycleType ) ],
+          CurrentValue => $current{Lifecycle},
+          Default      => 0,
+      &>
+    </td>
+  </tr>
+  <tr>
+    <td class="label"><label for="Disabled"><&|/l&>Disabled?</&></label></td>
+    <td>
+      <input name="Disabled" type="checkbox" value="1" <% $current{Disabled} ? "checked" : "" %>>
+      <input name="SetDisabled" type="hidden" value="1">
+    </td>
+  </tr>
+</table>
+<%args>
+$CatalogObj
+</%args>
+<%init>
+my %current = map { $_ => ($ARGS{$_} || $CatalogObj->$_ || '') }
+                  $CatalogObj->WritableAttributes;
+</%init>
diff --git a/share/html/Admin/Assets/Catalogs/GroupRights.html b/share/html/Admin/Assets/Catalogs/GroupRights.html
new file mode 100644
index 0000000..333d476
--- /dev/null
+++ b/share/html/Admin/Assets/Catalogs/GroupRights.html
@@ -0,0 +1,64 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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("Catalog [_1]: Modify group rights", $Catalog->Name) &>
+<& /Elements/Tabs &>
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" action="GroupRights.html" id="ModifyGroupRights" name="ModifyGroupRights">
+  <input type="hidden" class="hidden" name="id" value="<% $Catalog->id %>" />
+  <& /Admin/Elements/EditRights, Context => $Catalog, Principals => \@principals &>
+  <& /Elements/Submit, Label => loc('Save Changes') &>
+</form>
+<%init>
+my $Catalog    = LoadCatalog($id);
+my @results    = ProcessACLs(\%ARGS);
+my @principals = GetPrincipalsMap($Catalog, qw(System Roles Groups));
+</%init>
+<%args>
+$id => undef
+</%args>
diff --git a/share/html/Admin/Assets/Catalogs/Modify.html b/share/html/Admin/Assets/Catalogs/Modify.html
new file mode 100644
index 0000000..cf9a7aa
--- /dev/null
+++ b/share/html/Admin/Assets/Catalogs/Modify.html
@@ -0,0 +1,88 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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("Catalog [_1]: Modify basics", $catalog->Name) &>
+<& /Elements/Tabs &>
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" enctype="multipart/form-data" id="ModifyCatalog" action="Modify.html">
+  <input type="hidden" name="id" value="<% $catalog->id %>">
+
+  <&| /Widgets/TitleBox, title => loc("Basics"), class => "catalog-basics" &>
+    <& Elements/EditBasics, %ARGS, CatalogObj => $catalog &>
+  </&>
+
+  <& /Elements/Submit, Label => loc('Save'), Name => "Update" &>
+</form>
+<%args>
+$id     => undef
+$Update => 0
+</%args>
+<%init>
+my @results;
+my $catalog = LoadCatalog($id);
+
+if ($Update) {
+    my @attributes = $catalog->WritableAttributes;
+
+    # Disabled isn't submitted if unchecked, so use our hidden field to know if
+    # it was included in the form.
+    $ARGS{Disabled} = $ARGS{Disabled} ? 1 : 0
+        if $ARGS{SetDisabled};
+
+    push @results, UpdateRecordObject(
+        Object          => $catalog,
+        AttributesRef   => \@attributes,
+        ARGSRef         => \%ARGS,
+    );
+
+    MaybeRedirectForResults(
+        Actions     => \@results,
+        Arguments   => { id => $catalog->id },
+    );
+}
+</%init>
diff --git a/share/html/Admin/Assets/Catalogs/Roles.html b/share/html/Admin/Assets/Catalogs/Roles.html
new file mode 100644
index 0000000..33bfd4f
--- /dev/null
+++ b/share/html/Admin/Assets/Catalogs/Roles.html
@@ -0,0 +1,82 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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("Catalog [_1]: Modify roles", $catalog->Name) &>
+<& /Elements/Tabs &>
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" enctype="multipart/form-data" id="ModifyCatalogRoles" action="Roles.html">
+  <input type="hidden" name="id" value="<% $catalog->id %>">
+
+  <&| /Widgets/TitleBox, title => loc("Roles"), class => "catalog-roles" &>
+    <table width="60%" class="edit">
+      <tr>
+        <td><& /Elements/Assets/EditPeople, %ARGS, Object => $catalog &></td>
+        <td><& /Elements/Assets/AddPeople, Object => $catalog &></td>
+      </tr>
+    </table>
+  </&>
+
+  <& /Elements/Submit, Label => loc('Save'), Name => "Update" &>
+</form>
+<%args>
+$id     => undef
+$Update => 0
+</%args>
+<%init>
+my $catalog = LoadCatalog($id);
+my @results;
+
+if ($Update) {
+    push @results, ProcessRoleMembers( $catalog => %ARGS );
+
+    MaybeRedirectForResults(
+        Actions     => \@results,
+        Arguments   => { id => $catalog->id },
+    );
+}
+</%init>
diff --git a/share/html/Admin/Assets/Catalogs/UserRights.html b/share/html/Admin/Assets/Catalogs/UserRights.html
new file mode 100644
index 0000000..d676678
--- /dev/null
+++ b/share/html/Admin/Assets/Catalogs/UserRights.html
@@ -0,0 +1,64 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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("Catalog [_1]: Modify user rights", $Catalog->Name) &>
+<& /Elements/Tabs &>
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" action="UserRights.html" id="ModifyUserRights" name="ModifyUserRights">
+  <input type="hidden" class="hidden" name="id" value="<% $Catalog->id %>" />
+  <& /Admin/Elements/EditRights, Context => $Catalog, Principals => \@principals &>
+  <& /Elements/Submit, Label => loc('Save Changes') &>
+</form>
+<%init>
+my $Catalog    = LoadCatalog($id);
+my @results    = ProcessACLs(\%ARGS);
+my @principals = GetPrincipalsMap($Catalog, qw(Users));
+</%init>
+<%args>
+$id => undef
+</%args>
diff --git a/share/html/Admin/Assets/Catalogs/index.html b/share/html/Admin/Assets/Catalogs/index.html
new file mode 100644
index 0000000..572888c
--- /dev/null
+++ b/share/html/Admin/Assets/Catalogs/index.html
@@ -0,0 +1,118 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 Catalogs") &>
+<& /Elements/Tabs &>
+
+<h1><% $caption %></h1>
+<p><&|/l&>Select a catalog</&>:</p>
+% unless ( $catalogs->Count ) {
+<em><&|/l&>No catalogs matching search criteria found.</&></em>
+% } else {
+<& /Elements/CollectionList,
+    OrderBy => 'Name',
+    Order => 'ASC',
+    %ARGS,
+    Format => $Format,
+    Collection => $catalogs,
+    AllowSorting => 1,
+    PassArguments => [qw(
+        Rows Page Order OrderBy FindDisabled String Op Field
+    )],
+&>
+% }
+<form method="post" action="<% RT->Config->Get('WebPath') %>/Admin/Assets/Catalogs/index.html">
+% foreach my $field( qw(Rows Page Order OrderBy) ) {
+%     next unless defined $ARGS{ $field } && length $ARGS{ $field };
+<input type="hidden" name="<% $field %>" value="<% $ARGS{ $field } %>" />
+% }
+
+<select name="Field">
+% foreach my $col (qw(id Name Description Lifecycle)) {
+<option <% $Field eq $col ? 'selected="selected"' : '' |n %> value="<% $col %>"><% loc($col) %></option>
+% }
+</select>
+<& /Elements/SelectMatch, Name => 'Op', Default => $Op &>
+<input size="20" name="String" value="<% $String %>" />
+<br />
+
+<input type="checkbox" class="checkbox" id="FindDisabled" name="FindDisabled" value="1" <% $FindDisabled ? 'checked="checked"': '' |n%> />
+<label for="FindDisabled"><&|/l&>Include disabled catalogs in listing.</&></label>
+<div align="right"><input type="submit" class="button" value="<&|/l&>Search</&>" /></div> 
+</form>
+
+<%INIT>
+my $catalogs = RT::Catalogs->new($session{'CurrentUser'});
+$catalogs->FindAllRows if $FindDisabled;
+
+my ($caption);
+if ( defined $String && length $String ) {
+    $caption = $FindDisabled
+        ? loc("All catalogs matching search criteria")
+        : loc("Enabled catalogs matching search criteria");
+    $catalogs->Limit(
+        FIELD    => $Field,
+        OPERATOR => $Op,
+        VALUE    => $String,
+    );
+    RT::Interface::Web::Redirect(RT->Config->Get('WebURL')."Admin/Assets/Catalogs/Modify.html?id=".$catalogs->First->id)
+          if $catalogs->Count == 1;
+} else {
+    $catalogs->UnLimit;
+    $caption = $FindDisabled
+        ? loc("All Catalogs")
+        : loc("Enabled Catalogs");
+}
+
+my $Format = RT->Config->Get('AdminSearchResultFormat')->{'Catalogs'};
+</%INIT>
+<%ARGS>
+$FindDisabled => 0
+$Field        => 'Name'
+$Op           => '='
+$String       => ''
+</%ARGS>
diff --git a/share/html/Admin/Assets/index.html b/share/html/Admin/Assets/index.html
new file mode 100644
index 0000000..a4ac4bd
--- /dev/null
+++ b/share/html/Admin/Assets/index.html
@@ -0,0 +1,50 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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('Asset Administration') &>
+<& /Elements/Tabs &>
+<& /Elements/ListMenu, menu => Menu()->child('admin')->child('assets') &>
diff --git a/share/html/Admin/Global/CustomFields/Catalog-Assets.html b/share/html/Admin/Global/CustomFields/Catalog-Assets.html
new file mode 100644
index 0000000..f85874b
--- /dev/null
+++ b/share/html/Admin/Global/CustomFields/Catalog-Assets.html
@@ -0,0 +1,54 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 &>
+<& /Elements/Tabs &>
+<& /Admin/Elements/EditCustomFields, %ARGS, title => $title, ObjectType => "RT::Catalog", Object=> $object, SubType => "RT::Asset" &>
+<%init>
+my $title = loc('Edit Custom Fields for Assets in all Catalogs');
+my $object = RT::Catalog->new($session{'CurrentUser'});
+</%init>
diff --git a/share/html/Asset/Create.html b/share/html/Asset/Create.html
new file mode 100644
index 0000000..233c81d
--- /dev/null
+++ b/share/html/Asset/Create.html
@@ -0,0 +1,185 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 asset in catalog [_1]", $catalog->Name),
+    RT->Config->Get('AssetBasicCustomFieldsOnCreate')
+      ? (
+        onload => "function () { hide('Asset-Create-details') }"
+      )
+      : (),
+ &>
+<& /Elements/Tabs &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<span class="catalog <% CSSClass($catalog->Name) %>">
+<form method="post" enctype="multipart/form-data" id="CreateAsset" action="Create.html">
+  <input type="hidden" name="id" value="new">
+  <input type="hidden" name="Catalog" value="<% $catalog->id %>">
+
+<a name="basics"></a>
+<div id="Asset-Create-basics" class="asset-metadata">
+    <table>
+        <tbody>
+        <tr>
+            <td>
+  <&| /Widgets/TitleBox, title => loc("Basics"), class => "asset-basics", title_class => "inverse" &>
+    <& Elements/EditBasics, %ARGS, AssetObj => $asset, CatalogObj => $catalog &>
+  </&>
+
+  <&| /Widgets/TitleBox, title => loc("People"), class => "asset-people", title_class => "inverse" &>
+    <& Elements/EditPeople, %ARGS, AssetObj => $asset &>
+  </&>
+  </td><td>
+  <&| /Widgets/TitleBox, title => loc("Links"), class => "asset-links", title_class => "inverse" &>
+    <& /Elements/AddLinks,
+        Object          => $asset,
+        CustomFields    => $catalog->AssetCustomFields &>
+  </&>
+  </td>
+
+  </tr>
+  </tbody>
+  </table>
+</div>
+
+<div id="Asset-Create-details">
+<a name="details"></a>
+
+  <& /Elements/EditCustomFieldCustomGroupings,
+        Object => $asset,
+        TitleBoxARGS => { title_class => "inverse" },
+        KeepValue => 1,
+        CustomFieldGenerator => sub { $catalog->AssetCustomFields } &>
+</div>
+
+  <& /Elements/Submit, Label => loc('Create asset') &>
+</form>
+</span>
+
+<%args>
+$id => ""
+$Catalog => undef
+</%args>
+<%init>
+my $asset   = RT::Asset->new( $session{CurrentUser} );
+my $catalog = RT::Catalog->new( $session{CurrentUser} );
+$catalog->Load($Catalog);
+
+Abort(loc("Unable to find catalog '[_1]'", $Catalog))
+    unless $catalog->id;
+
+Abort(loc("You don't have permission to create assets in catalog [_1].",
+          $catalog->Name || $catalog->id))
+    unless $catalog->CurrentUserHasRight("CreateAsset");
+
+# Update the current default with the latest selection
+$session{'DefaultCatalog'} = $catalog->Id;
+
+my @results;
+
+if ($id eq "new") {
+    my $skip_create = 0;
+
+    my ($cf_ok, @cf_errors) = $m->comp(
+        '/Elements/ValidateCustomFields',
+        Object          => $asset,
+        CustomFields    => $catalog->AssetCustomFields,
+        ARGSRef         => \%ARGS
+    );
+
+    $m->callback(
+        CallbackName    => 'BeforeCreate',
+        AssetObj        => $asset,
+        CatalogObj      => $catalog,
+        results         => \@results,
+        cf_ok           => \$cf_ok,
+        skip_create     => \$skip_create,
+        ARGSRef         => \%ARGS
+    );
+
+    if ($cf_ok and not $skip_create) {
+        # Handle CFs and links
+        my %create = (
+            ProcessObjectCustomFieldUpdatesForCreate(
+                ARGSRef       => \%ARGS,
+                ContextObject => $catalog,
+            ),
+            ProcessLinksForCreate( ARGSRef => \%ARGS ),
+            map {
+                $_ => $ARGS{$_}
+            } $asset->Roles,
+        );
+
+        # Handle basic fields
+        for ($asset->WritableAttributes) {
+            $create{$_} = $ARGS{$_} if exists $ARGS{$_};
+        }
+
+        $m->callback( %ARGS, AssetObj => $asset, CatalogObj => $catalog, Create => \%create, CallbackName => 'MassageCreate' );
+
+        my ($ok, $msg, $nonfatal) = $asset->Create( %create );
+        push @results, $msg, @{$nonfatal || []};
+
+        if ($ok) {
+            MaybeRedirectForResults(
+                Actions     => \@results,
+                Path        => "/Asset/Display.html",
+                Arguments   => { id => $asset->id },
+            );
+        }
+    } else {
+        push @results, @cf_errors;
+    }
+}
+
+if ( RT->Config->Get('AssetBasicCustomFieldsOnCreate') ) {
+    PageMenu->child( basics => raw_html =>  q[<a href="#basics" onclick="return switchVisibility('Asset-Create-basics','Asset-Create-details');">] . loc('Basics') . q[</a>]);
+    PageMenu->child( details => raw_html =>  q[<a href="#details" onclick="return switchVisibility('Asset-Create-details','Asset-Create-basics');">] . loc('Details') . q[</a>]);
+}
+
+</%init>
diff --git a/share/html/Asset/CreateInCatalog.html b/share/html/Asset/CreateInCatalog.html
new file mode 100644
index 0000000..985ad37
--- /dev/null
+++ b/share/html/Asset/CreateInCatalog.html
@@ -0,0 +1,51 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 new asset") &>
+<& /Elements/Tabs &>
+<& /Asset/Elements/CreateInCatalog &>
diff --git a/share/html/Asset/CreateLinkedTicket.html b/share/html/Asset/CreateLinkedTicket.html
new file mode 100644
index 0000000..104b205
--- /dev/null
+++ b/share/html/Asset/CreateLinkedTicket.html
@@ -0,0 +1,58 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+$Asset => undef
+$Requestors => ''
+</%args>
+<%init>
+my $asset = LoadAsset($Asset);
+</%init>
+<& /Elements/Header,
+    Title => loc("Create linked ticket for asset #[_1]: [_2]", $asset->id, $asset->Name) &>
+<& /Elements/Tabs &>
+<& /Asset/Elements/CreateLinkedTicket, AssetObj => $asset, Requestors => $Requestors &>
diff --git a/share/html/Asset/Display.html b/share/html/Asset/Display.html
new file mode 100644
index 0000000..f155136
--- /dev/null
+++ b/share/html/Asset/Display.html
@@ -0,0 +1,75 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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("Asset #[_1]: [_2]", $asset->id, $asset->Name) &>
+<& /Elements/Tabs &>
+
+% $m->callback(CallbackName => 'BeforeActionList', ARGSRef => \%ARGS, Asset => $asset);
+
+<& /Elements/ListActions &>
+
+<span class="catalog <% CSSClass($asset->CatalogObj->Name) %>">
+<& Elements/ShowSummary, AssetObj => $asset &>
+
+% $m->callback(CallbackName => 'AfterShowSummary', ARGSRef => \%ARGS, Asset => $asset);
+
+<& /Elements/ShowHistory,
+    Object => $asset,
+    ShowDisplayModes => 0,
+    DisplayPath => 'History.html',
+    &>
+
+% $m->callback(CallbackName => 'AfterShowHistory', ARGSRef => \%ARGS, Asset => $asset);
+</span>
+
+<%args>
+$id => undef
+</%args>
+<%init>
+my $asset = LoadAsset($id);
+$m->callback(CallbackName => 'BeforeDisplay', ARGSRef => \%ARGS, Asset => $asset);
+</%init>
diff --git a/share/html/Asset/Elements/AssetSearchBasics b/share/html/Asset/Elements/AssetSearchBasics
new file mode 100644
index 0000000..ec1742b
--- /dev/null
+++ b/share/html/Asset/Elements/AssetSearchBasics
@@ -0,0 +1,87 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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('Basics'), class=>'asset-search-grouping asset-search-basics' &>
+<table>
+<tr class="asset-catalog"><td class="label"><label for="Catalog"><&|/l&>Catalog</&></label></td>
+    <td class="value" colspan="3">
+<& /Asset/Elements/SelectCatalog, Name => 'Catalog', CheckRight => "ShowCatalog",
+       Default => $ARGS{'Catalog'}, OnChange => "jQuery('#AssetSearch').submit()" &>
+</td></tr>
+<tr class="asset-status"><td class="label"><label for="Status"><&|/l&>Status</&></label></td>
+    <td class="value" colspan="3">
+<& /Asset/Elements/SelectStatus, Name => 'Status', CatalogObj => $CatalogObj, DefaultValue => 1,
+       Default => ($ARGS{'Status'} || '') &>
+</td></tr>
+<tr class="asset-name"><td class="label"><label for="Name"><&|/l&>Name</&></label></td>
+    <td class="value"><input type="text" id="Name" name="Name" value="<% $ARGS{Name} || ''%>" /></td>
+    <td class="label not"><label for="!Name"><&|/l&>not</&></td>
+    <td class="value"><input type="text" id="!Name" name="!Name" value="<% $ARGS{"!Name"} || ''%>" /></td></tr>
+<tr class="asset-description"><td class="label"><label for="Description"><&|/l&>Description</&></label></td>
+    <td class="value"><input type="text" id="Description" name="Description" value="<% $ARGS{Description} || ''%>" /></td>
+    <td class="label not"><label for="!Description"><&|/l&>not</&></td>
+    <td class="value"><input type="text" id="!Description" name="!Description" value="<% $ARGS{"!Description"} || ''%>" /></td></tr>
+% my $CFs = RT::CustomFields->new( $session{CurrentUser} );
+% $CFs->LimitToCatalog( $CatalogObj->Id );
+% $CFs->LimitToObjectId(0); # LimitToGlobal but no LookupType restriction
+% $CFs->LimitToGrouping( "RT::Asset" => "Basics" );
+% while (my $cf = $CFs->Next) {
+% my $name = "CF.{" . $cf->Name . "}";
+% my $value  = ref($ARGS{$name}) ? $ARGS{$name}[0] : $ARGS{$name} || '';
+% my $negval = ref($ARGS{"!$name"}) ? $ARGS{"!$name"}[0] : $ARGS{"!$name"} || '';
+<tr>
+  <td class="label"><label for="<% $name %>"><% $cf->Name %></label></td>
+  <td class="value"><& /Elements/SelectCustomFieldValue, CustomField => $cf, Name => $name, Default => $value &></td>
+  <td class="label not"><label for="!<% $name %>"><&|/l&>not</&></label></td>
+  <td class="value"><& /Elements/SelectCustomFieldValue, CustomField => $cf, Name => "!$name", Default => $negval &></td>
+</tr>
+% }
+</table>
+</&>
+<%args>
+$CatalogObj => undef
+</%args>
diff --git a/share/html/Asset/Elements/AssetSearchCFs b/share/html/Asset/Elements/AssetSearchCFs
new file mode 100644
index 0000000..fe1d17e
--- /dev/null
+++ b/share/html/Asset/Elements/AssetSearchCFs
@@ -0,0 +1,72 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 => $Grouping ? loc($Grouping) : loc('Custom Fields'), hide_empty => 1, class=>'asset-search-grouping asset-search-cfs'  &>
+% my $CFs = RT::CustomFields->new( $session{CurrentUser} );
+% $CFs->LimitToCatalog( $CatalogObj->Id );
+% $CFs->LimitToObjectId(0); # LimitToGlobal but no LookupType restriction
+% $CFs->LimitToGrouping( "RT::Asset" => $Grouping );
+% if ( $CFs->Count > 0 ){
+<table>
+%   while (my $cf = $CFs->Next) {
+%     my $name = "CF.{" . $cf->Name . "}";
+%     my $value  = ref($ARGS{$name}) ? $ARGS{$name}[0] : $ARGS{$name} || '';
+%     my $negval = ref($ARGS{"!$name"}) ? $ARGS{"!$name"}[0] : $ARGS{"!$name"} || '';
+<tr>
+  <td class="label"><label for="<% $name %>"><% $cf->Name %></label></td>
+  <td class="value"><& /Elements/SelectCustomFieldValue, CustomField => $cf, Name => $name, Default => $value &></td>
+  <td class="label not"><label for="!<% $name %>"><&|/l&>not</&></label></td>
+  <td class="value"><& /Elements/SelectCustomFieldValue, CustomField => $cf, Name => "!$name", Default => $negval &></td>
+</tr>
+%   }
+</table>
+% }
+</&>
+<%args>
+$Grouping
+$CatalogObj => undef
+</%args>
diff --git a/share/html/Asset/Elements/AssetSearchPeople b/share/html/Asset/Elements/AssetSearchPeople
new file mode 100644
index 0000000..ef4d480
--- /dev/null
+++ b/share/html/Asset/Elements/AssetSearchPeople
@@ -0,0 +1,83 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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, class => "asset-search-people", title => loc('People') &>
+<table>
+% for my $role (RT::Asset->Roles) {
+<tr class="asset-role-<% CSSClass($role) %>">
+  <td class="label"><label for="Role.<% $role %>"><% loc($role) %></td>
+  <td class="value">
+      <input type="text" id="Role.<% $role %>" name="Role.<% $role %>"
+             data-autocomplete="Users" value="<% $ARGS{"Role.$role"} || '' %>" />
+  </td>
+  <td class="label not"><label for="!Role.<% $role %>"><&|/l&>not</&></td>
+  <td class="value">
+      <input type="text" id="!Role.<% $role %>" name="!Role.<% $role %>"
+             data-autocomplete="Users" value="<% $ARGS{"!Role.$role"} || '' %>" />
+  </td>
+</tr>
+% }
+% my $CFs = RT::CustomFields->new( $session{CurrentUser} );
+% $CFs->LimitToCatalog( $CatalogObj->Id );
+% $CFs->LimitToObjectId(0); # LimitToGlobal but no LookupType restriction
+% $CFs->LimitToGrouping( "RT::Asset" => "People" );
+% while (my $cf = $CFs->Next) {
+% my $name = "CF.{" . $cf->Name . "}";
+% my $value  = ref($ARGS{$name}) ? $ARGS{$name}[0] : $ARGS{$name} || '';
+% my $negval = ref($ARGS{"!$name"}) ? $ARGS{"!$name"}[0] : $ARGS{"!$name"} || '';
+<tr>
+  <td class="label"><label for="<% $name %>"><% $cf->Name %></label></td>
+  <td class="value"><& /Elements/SelectCustomFieldValue, CustomField => $cf, Name => $name, Default => $value &></td>
+  <td class="label not"><label for="!<% $name %>"><&|/l&>not</&></label></td>
+  <td class="value"><& /Elements/SelectCustomFieldValue, CustomField => $cf, Name => "!$name", Default => $negval &></td>
+</tr>
+% }
+</table>
+</&>
+<%args>
+$CatalogObj => undef
+</%args>
diff --git a/share/html/Asset/Elements/CreateInCatalog b/share/html/Asset/Elements/CreateInCatalog
new file mode 100644
index 0000000..055dd9e
--- /dev/null
+++ b/share/html/Asset/Elements/CreateInCatalog
@@ -0,0 +1,53 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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->Config->Get("WebPath") %>/Asset/Create.html" id="AssetCreateInCatalog">
+  <&|/l_unsafe,
+    $m->scomp("/Asset/Elements/SelectCatalog"),
+    &>Create a new asset in the catalog [_1].</&>
+  <& /Elements/Submit, Label => loc("Go"), Caption => loc("This will take you to a partially prefilled asset creation form.") &>
+</form>
diff --git a/share/html/Asset/Elements/CreateLinkedTicket b/share/html/Asset/Elements/CreateLinkedTicket
new file mode 100644
index 0000000..63a8eaa
--- /dev/null
+++ b/share/html/Asset/Elements/CreateLinkedTicket
@@ -0,0 +1,78 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+$AssetObj
+$Requestors => ''
+</%args>
+<%init>
+my @description = map { $m->interp->apply_escapes($_, 'h') }
+    $AssetObj->id, $AssetObj->Name;
+</%init>
+<form action="<% RT->Config->Get("WebPath") %><% $session{CurrentUser}->Privileged ? "/Ticket" : "/SelfService" %>/Create.html" id="AssetCreateLinkedTicket">
+  <input name="new-RefersTo" value="asset:<% $AssetObj->id %>" type="hidden">
+  <input name="Subject" value="<% $AssetObj->Name %>" type="hidden">
+  <&|/l_unsafe,
+    $m->scomp("/Elements/SelectNewTicketQueue"),
+    @description &>Create a new ticket in the [_1] queue about asset #[_2]: [_3].</&>
+% if ($Requestors) {
+    <input type="hidden" name="Requestors" value="<% $Requestors%>" />
+% } else {
+%     my $first = 1;
+%     for my $role ($AssetObj->Roles) {
+%         my $addr = $AssetObj->RoleGroup($role)->MemberEmailAddressesAsString;
+%         next unless defined $addr and length $addr;
+  <br>
+  <label>
+    <input type="radio" name="Requestors" value="<% $addr %>" <% $first ? 'checked="checked"' : '' |n%>/>
+    <&|/l, loc($role), $addr &>Use asset [_1] as ticket Requestor: [_2]</&>
+  </label>
+%         $first = 0;
+%     }
+% }
+  <& /Elements/Submit, Label => loc("Go"), Caption => loc("This will take you to a partially prefilled ticket creation form.") &>
+</form>
diff --git a/share/html/Asset/Elements/EditBasics b/share/html/Asset/Elements/EditBasics
new file mode 100644
index 0000000..fbfde33
--- /dev/null
+++ b/share/html/Asset/Elements/EditBasics
@@ -0,0 +1,85 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+% if ($AssetObj->id) {
+  <tr class="asset-catalog">
+    <td class="label"><label for="Catalog"><&|/l&>Catalog</&>:</label></td>
+    <td><& /Asset/Elements/SelectCatalog, Default => $current{Catalog} &></td>
+  </tr>
+% }
+  <tr class="asset-name">
+    <td class="label"><label for="Name"><&|/l&>Name</&>:</label></td>
+    <td><input name="Name" value="<% $current{Name} %>" size="40"></td>
+  </tr>
+  <tr class="asset-description">
+    <td class="label"><label for="Description"><&|/l&>Description</&>:</label></td>
+    <td><input name="Description" value="<% $current{Description} %>" size="40"></td>
+  </tr>
+  <tr class="asset-status">
+    <td class="label"><label for="Status"><&|/l&>Status</&>:</label></td>
+    <td><& /Asset/Elements/SelectStatus, Name => 'Status', AssetObj => $AssetObj, CatalogObj => $CatalogObj &></td>
+  </tr>
+% if ( $AssetObj->id ) {
+  <& /Elements/EditCustomFields, Object => $AssetObj, Grouping => 'Basics', InTable => 1 &>
+% } elsif ( my @cf_names = grep { defined } @{RT->Config->Get('AssetBasicCustomFieldsOnCreate') || []} ) {
+%   my $cfs = $CatalogObj->AssetCustomFields;
+%   for my $name ( @cf_names ) {
+%       $cfs->Limit( FIELD => 'Name', VALUE => $name, CASESENSITIVE => 0 );
+%   }
+  <& /Elements/EditCustomFields, Object => $AssetObj, CustomFields => $cfs, InTable => 1, KeepValue => 1 &>
+% }
+% $m->callback(%ARGS, CallbackName => "AfterFields");
+</table>
+<%args>
+$AssetObj
+$CatalogObj => undef
+</%args>
+<%init>
+my %current = map { $_ => ($ARGS{$_} || $AssetObj->$_ || '') }
+                  $AssetObj->WritableAttributes;
+</%init>
diff --git a/share/html/Asset/Elements/EditDates b/share/html/Asset/Elements/EditDates
new file mode 100644
index 0000000..1e64a26
--- /dev/null
+++ b/share/html/Asset/Elements/EditDates
@@ -0,0 +1,72 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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&>Created</&>:</td>
+    <td>
+      <&|/l_unsafe,
+          $m->interp->apply_escapes($AssetObj->CreatedAsString, 'h'),
+          $m->scomp('/Elements/ShowUser', User => $AssetObj->CreatorObj)
+        &>[_1] by [_2]</&>
+    </td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>Last Updated</&>:</td>
+    <td>
+      <&|/l_unsafe,
+          $m->interp->apply_escapes($AssetObj->LastUpdatedAsString, 'h'),
+          $m->scomp('/Elements/ShowUser', User => $AssetObj->LastUpdatedByObj)
+        &>[_1] by [_2]</&>
+    </td>
+  </tr>
+  <& /Elements/EditCustomFields, Object => $AssetObj, Grouping => 'Dates', InTable => 1 &>
+% $m->callback(%ARGS, CallbackName => "AfterFields");
+</table>
+<%args>
+$AssetObj
+</%args>
diff --git a/share/html/Asset/Elements/EditPeople b/share/html/Asset/Elements/EditPeople
new file mode 100644
index 0000000..6f333df
--- /dev/null
+++ b/share/html/Asset/Elements/EditPeople
@@ -0,0 +1,64 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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" cellpadding="0" cellspacing="0">
+% for my $role ( $AssetObj->Roles ) {
+<tr class="asset-people-<% CSSClass($role) %>">
+<td class="label">
+<% loc($role) %>:
+</td>
+<td class="value" colspan="5">
+<& /Elements/EmailInput, Name => $role, Size => undef, Default => $ARGS{$role}, Autocomplete => 1 &>
+</td>
+</tr>
+% }
+
+</table>
+
+<%args>
+$AssetObj
+</%args>
diff --git a/share/html/Asset/Elements/SelectCatalog b/share/html/Asset/Elements/SelectCatalog
new file mode 100644
index 0000000..48e9df0
--- /dev/null
+++ b/share/html/Asset/Elements/SelectCatalog
@@ -0,0 +1,69 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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/SelectObject,
+    Name           => "Catalog",
+    ShowAll        => $ShowAll,
+    ShowNullOption => 0,
+    CheckRight     => "CreateAsset",
+    %ARGS,
+    ObjectType     => "Catalog",
+    CacheNeedsUpdate => RT::Catalog->CacheNeedsUpdate,
+    Default        => $Default,
+    &>
+<%args>
+$ShowAll => 0
+$Default => undef
+$UpdateSession => 1
+</%args>
+<%init>
+my $catalog_obj = LoadDefaultCatalog($Default || '');
+if ( $UpdateSession && $catalog_obj->Id ){
+    $session{'DefaultCatalog'} = $catalog_obj->Id;
+    $Default = $catalog_obj->Id;
+}
+</%init>
diff --git a/share/html/Asset/Elements/SelectStatus b/share/html/Asset/Elements/SelectStatus
new file mode 100644
index 0000000..f16c804
--- /dev/null
+++ b/share/html/Asset/Elements/SelectStatus
@@ -0,0 +1,66 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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/SelectStatus, %ARGS &>
+<%init>
+if ($AssetObj and $AssetObj->Id) {
+    $ARGS{DefaultValue} = 0;
+    $ARGS{Default} = $DECODED_ARGS->{Status} || $ARGS{Default};
+    $ARGS{Object} = $AssetObj;
+} else {
+    my $lifecycle = ($CatalogObj || "RT::Catalog")->LifecycleObj;
+    if ( not $ARGS{DefaultValue} ){
+        $ARGS{DefaultValue} = 0;
+        $ARGS{Default} ||= $DECODED_ARGS->{Status} || $lifecycle->DefaultOnCreate;
+    }
+    $ARGS{Statuses} = [ $AssetObj ? $lifecycle->Transitions("") : $lifecycle->Valid ];
+}
+</%init>
+<%args>
+$AssetObj   => undef
+$CatalogObj => undef
+</%args>
diff --git a/share/html/Asset/Elements/ShowBasics b/share/html/Asset/Elements/ShowBasics
new file mode 100644
index 0000000..da350a1
--- /dev/null
+++ b/share/html/Asset/Elements/ShowBasics
@@ -0,0 +1,70 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 class="asset-catalog">
+    <td class="label"><&|/l&>Catalog</&>:</td>
+    <td><& ShowCatalog, Asset => $AssetObj &></td>
+  </tr>
+  <tr class="asset-name">
+    <td class="label"><&|/l&>Name</&>:</td>
+    <td><% $AssetObj->Name || '' %></td>
+  </tr>
+  <tr class="asset-description">
+    <td class="label"><&|/l&>Description</&>:</td>
+    <td><% $AssetObj->Description || '' %></td>
+  </tr>
+  <tr class="asset-status">
+    <td class="label"><&|/l&>Status</&>:</td>
+    <td class="value"><% loc($AssetObj->Status) %></td>
+  </tr>
+  <& /Elements/ShowCustomFields, Object => $AssetObj, Grouping => 'Basics', Table => 0 &>
+% $m->callback(%ARGS, CallbackName => "AfterFields");
+</table>
+<%args>
+$AssetObj
+</%args>
diff --git a/share/html/Asset/Elements/ShowCatalog b/share/html/Asset/Elements/ShowCatalog
new file mode 100644
index 0000000..d7c1095
--- /dev/null
+++ b/share/html/Asset/Elements/ShowCatalog
@@ -0,0 +1,69 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 %>
+<%ARGS>
+$Asset   => undef
+$Catalog => undef
+</%ARGS>
+<%INIT>
+$Catalog ||= $Asset->CatalogObj if $Asset;
+return unless $Catalog;
+
+my $value = $Catalog->Name;
+
+if ( $Asset and $Asset->CurrentUserHasRight('ShowCatalog') ) {
+    # Grab the name anyway if the current user can see the catalog based on his
+    # role for this asset.  Simply checking ShowCatalog on the catalog itself
+    # won't work since the role membership is on the asset.  We need to
+    # implement context objects (like CFs do) for catalogs.
+    $value = $Catalog->__Value('Name');
+}
+
+$value = '#'. $Catalog->id
+    unless defined $value and length $value;
+</%INIT>
diff --git a/share/html/Asset/Elements/ShowDates b/share/html/Asset/Elements/ShowDates
new file mode 100644
index 0000000..582423e
--- /dev/null
+++ b/share/html/Asset/Elements/ShowDates
@@ -0,0 +1,72 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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&>Created</&>:</td>
+    <td>
+      <&|/l_unsafe,
+          $m->interp->apply_escapes($AssetObj->CreatedAsString, 'h'),
+          $m->scomp('/Elements/ShowUser', User => $AssetObj->CreatorObj)
+        &>[_1] by [_2]</&>
+    </td>
+  </tr>
+  <tr>
+    <td class="label"><&|/l&>Last Updated</&>:</td>
+    <td>
+      <&|/l_unsafe,
+          $m->interp->apply_escapes($AssetObj->LastUpdatedAsString, 'h'),
+          $m->scomp('/Elements/ShowUser', User => $AssetObj->LastUpdatedByObj)
+        &>[_1] by [_2]</&>
+    </td>
+  </tr>
+  <& /Elements/ShowCustomFields, Object => $AssetObj, Grouping => 'Dates', Table => 0 &>
+% $m->callback(%ARGS, CallbackName => "AfterFields");
+</table>
+<%args>
+$AssetObj
+</%args>
diff --git a/share/html/Asset/Elements/ShowLinks b/share/html/Asset/Elements/ShowLinks
new file mode 100644
index 0000000..3b9a6f0
--- /dev/null
+++ b/share/html/Asset/Elements/ShowLinks
@@ -0,0 +1,48 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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/ShowLinks, Object => delete $ARGS{AssetObj}, %ARGS &>
diff --git a/share/html/Asset/Elements/ShowPeople b/share/html/Asset/Elements/ShowPeople
new file mode 100644
index 0000000..af4f466
--- /dev/null
+++ b/share/html/Asset/Elements/ShowPeople
@@ -0,0 +1,76 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+$AssetObj
+</%args>
+<%init>
+my $CatalogObj = $AssetObj->CatalogObj;
+</%init>
+<table>
+% for my $role ($AssetObj->Roles) {
+<tr><td class="label"><% loc($role) %>:
+% if ($AssetObj->Role($role)->{Single}) {
+%      my $users = $AssetObj->RoleGroup($role)->UserMembersObj(Recursively => 0);
+%      $users->FindAllRows;
+%      my $user = $users->Next;
+<& /Elements/ShowUser, User => $user, Link => 1 &></td></tr>
+%      next if $user->id == RT->Nobody->id;
+<tr><td>
+<& ShowRoleMembers, Group => $AssetObj->RoleGroup($role), Title => 0 &>
+</div></td></tr>
+% } else {
+</td></tr><tr><td class="user-accordion">
+    <& ShowRoleMembers, Group => $AssetObj->RoleGroup($role) &>
+    <& ShowRoleMembers, Group => $CatalogObj->RoleGroup($role), Skip => $AssetObj->RoleGroup($role), Note => loc("(via this asset's catalog)") &>
+  </td></tr>
+% }
+% }
+<& /Elements/ShowCustomFields, Object => $AssetObj, Grouping => 'People', Table => 0 &>
+
+</table>
+% $m->callback( %ARGS, CallbackName => 'AfterPeople' );
diff --git a/share/html/Asset/Elements/ShowRoleMembers b/share/html/Asset/Elements/ShowRoleMembers
new file mode 100644
index 0000000..a716ca9
--- /dev/null
+++ b/share/html/Asset/Elements/ShowRoleMembers
@@ -0,0 +1,90 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 $users = $Group->UserMembersObj( Recursively => 0 );
+% while ( my $user = $users->Next ) {
+%     next if $Skip and $Skip->HasMember( $user->PrincipalId );
+% if (not $Title) {
+% } elsif ($Single) {
+<h3><& /Elements/ShowUser, User => $user, Link => 1 &></h3>
+%      next if $user->id == RT->Nobody->id;
+% } else {
+<h3><a href="#"><& /Elements/ShowUser, User => $user, Link => 0 &>
+%     if ($Note) {
+ <span class="note"><% $Note %></span>
+%     }
+</a>
+% if ( $session{'CurrentUser'}->Privileged ){
+<a class="user-summary" href="<%RT->Config->Get('WebPath')%>/User/Summary.html?id=<% $user->Id %>"><&|/l&>User Summary</&></a>
+% }
+</h3>
+% }
+  <div class="details">
+<& /User/Elements/UserInfo,
+       User => $user,
+       FormatConfig => 'UserAssetExtraInfo',
+       ClassPrefix => 'asset-user' &>
+% $m->callback(CallbackName => 'AfterRecord', User => $user, Group => $Group );
+  </div>
+% }
+% my $groups = $Group->GroupMembersObj( Recursively => 0 );
+% $groups->LimitToUserDefinedGroups;
+% while (my $g = $groups->Next) {
+%     next if $Skip and $Skip->HasMember( $g->PrincipalId );
+<h3><a href="#"><&|/l, $g->Name &>Group: [_1]</&></a>
+%     if ($Note) {
+ <span class="note"><% $Note %></span>
+%     }
+</h3>
+% }
+<%ARGS>
+$Group => undef
+$Note  => ''
+$Skip  => undef
+$Single => 0
+$Title => 1
+</%ARGS>
diff --git a/share/html/Asset/Elements/ShowSummary b/share/html/Asset/Elements/ShowSummary
new file mode 100644
index 0000000..ebfe7f3
--- /dev/null
+++ b/share/html/Asset/Elements/ShowSummary
@@ -0,0 +1,83 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+$AssetObj
+</%args>
+<%init>
+my @sections = (
+    "Basics",   #loc
+    "People",   #loc
+    "Dates",    #loc
+    "Links",    #loc
+);
+
+my $can_edit = $session{CurrentUser}->Privileged
+    && $AssetObj->CurrentUserHasRight("ModifyAsset");
+
+my %link;
+for my $section (@sections) {
+    my $page = $section eq 'Basics' ? "Modify.html" : "Modify$section.html";
+    $link{$section} =
+        RT->Config->Get("WebPath")
+        . "/Asset/$page?id="
+        . $AssetObj->id;
+}
+</%init>
+<div class="asset-metadata">
+% for my $section (@sections) {
+<&| /Widgets/TitleBox, title => loc($section), title_href => $can_edit ? $link{$section} : "", title_class => "inverse", class => "asset-\L$section" &>
+    <& "Show$section", AssetObj => $AssetObj &>
+</&>
+% }
+
+<& /Elements/ShowCustomFieldCustomGroupings,
+     Object => $AssetObj,
+     title_href => $can_edit ? RT->Config->Get("WebPath") . "/Asset/ModifyCFs.html" : "",
+     TitleBoxARGS => { title_class => "inverse" },
+ &>
+</div>
diff --git a/share/html/Asset/Elements/TSVExport b/share/html/Asset/Elements/TSVExport
new file mode 100644
index 0000000..0d34357
--- /dev/null
+++ b/share/html/Asset/Elements/TSVExport
@@ -0,0 +1,126 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+$Collection
+$Format
+$PreserveNewLines => 0
+</%ARGS>
+<%ONCE>
+my $no_html = HTML::Scrubber->new( deny => '*' );
+</%ONCE>
+<%INIT>
+require HTML::Entities;
+
+$r->content_type('application/vnd.ms-excel');
+
+my $DisplayFormat = $m->comp('/Elements/ScrubHTML', Content => $Format);
+
+my @Format = $m->comp('/Elements/CollectionAsTable/ParseFormat', Format => $DisplayFormat);
+
+my @columns;
+
+my $should_loc = { map { $_ => 1 } qw(Status) };
+
+my $col_entry = sub {
+    my $col = shift;
+    # in tsv output, "#" is often a comment character but we use it for "id"
+    delete $col->{title}
+        if $col->{title} and $col->{title} =~ /^\s*#\s*$/;
+    return {
+        header => Encode::encode_utf8(loc($col->{title} || $col->{attribute})),
+        map    => $m->comp(
+            "/Elements/ColumnMap",
+            Class => "RT__Asset",
+            Name  => $col->{attribute},
+            Attr  => 'value'
+        ),
+        should_loc => $should_loc->{$col->{attribute}},
+    }
+};
+
+if ($PreserveNewLines) {
+    my $col = [];
+    push @columns, $col;
+    for (@Format) {
+        if ($_->{title} eq 'NEWLINE') {
+            $col = [];
+            push @columns, $col;
+        }
+        else {
+            push @$col, $col_entry->($_);
+        }
+    }
+}
+else {
+    push @columns, [map { $_->{attribute}
+                          ? $col_entry->($_)
+                          : () } @Format];
+}
+
+for (@columns) {
+    $m->out(join("\t", map { $_->{header} } @$_)."\n");
+}
+
+my $ii = 0;
+while (my $row = $Collection->Next) {
+    for my $col (@columns) {
+        $m->out(join("\t", map {
+            my $val = ProcessColumnMapValue($_->{map}, Arguments => [$row, $ii++], Escape => 0);
+            $val = loc($val) if $_->{should_loc};
+            # remove tabs from all field values, they screw up the tsv
+            $val = '' unless defined $val;
+            $val =~ s/(?:\n|\r)//g; $val =~ s{\t}{    }g;
+            $val = $no_html->scrub($val);
+            $val = HTML::Entities::decode_entities($val);
+            Encode::encode_utf8($val);
+        } @$col)."\n");
+    }
+}
+$m->abort();
+
+</%INIT>
diff --git a/share/html/Asset/Helpers/CreateInCatalog b/share/html/Asset/Helpers/CreateInCatalog
new file mode 100644
index 0000000..034ed91
--- /dev/null
+++ b/share/html/Asset/Helpers/CreateInCatalog
@@ -0,0 +1,49 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<& /Asset/Elements/CreateInCatalog &>
+% $m->abort;
diff --git a/share/html/Asset/Helpers/CreateLinkedTicket b/share/html/Asset/Helpers/CreateLinkedTicket
new file mode 100644
index 0000000..95228f5
--- /dev/null
+++ b/share/html/Asset/Helpers/CreateLinkedTicket
@@ -0,0 +1,56 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+$Asset
+$Requestors => ''
+</%args>
+<%init>
+my $asset = LoadAsset($Asset);
+</%init>
+<& /Asset/Elements/CreateLinkedTicket, AssetObj => $asset, Requestors => $Requestors &>
+% $m->abort;
diff --git a/share/html/Asset/History.html b/share/html/Asset/History.html
new file mode 100644
index 0000000..925eeb4
--- /dev/null
+++ b/share/html/Asset/History.html
@@ -0,0 +1,64 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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("History of Asset #[_1]: [_2]", $asset->id, $asset->Name) &>
+<& /Elements/Tabs &>
+
+<span class="catalog <% CSSClass($asset->CatalogObj->Name) %>">
+<& /Elements/ShowHistory,
+    Object => $asset,
+    ShowDisplayModes => 0,
+    DisplayPath => 'History.html',
+    &>
+</span>
+
+<%args>
+$id => undef
+</%args>
+<%init>
+my $asset = LoadAsset($id);
+</%init>
diff --git a/share/html/Asset/Modify.html b/share/html/Asset/Modify.html
new file mode 100644
index 0000000..f760268
--- /dev/null
+++ b/share/html/Asset/Modify.html
@@ -0,0 +1,133 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 asset #[_1]: [_2]", $asset->id, $asset->Name) &>
+<& /Elements/Tabs &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<span class="catalog <% CSSClass($asset->CatalogObj->Name) %>">
+<form method="post" enctype="multipart/form-data" id="ModifyAsset" action="Modify.html">
+  <input type="hidden" name="id" value="<% $asset->id %>">
+  <input type="hidden" name="DisplayAfter" value="<% $DisplayAfter ? 1 : 0 %>">
+
+  <&| /Widgets/TitleBox, title => loc("Basics"), class => "asset-basics", title_class => "inverse" &>
+    <& Elements/EditBasics, %ARGS, AssetObj => $asset &>
+  </&>
+
+  <&| /Widgets/TitleBox, title => loc("Custom Fields"), class => "asset-info-cfs", title_class => "inverse" &>
+    <& /Elements/EditCustomFields, Object => $asset, Grouping => '' &>
+  </&>
+
+  <& /Elements/Submit, Label => loc('Save asset'), Name => "Update" &>
+</form>
+</span>
+
+<%args>
+$id             => undef
+$Update         => 0
+$DisplayAfter   => 0
+</%args>
+<%init>
+my $asset = LoadAsset($id);
+my @results;
+
+$m->callback( Asset => $asset, ARGSRef => \%ARGS, Update => \$Update, results => \@results );
+
+if ($Update) {
+    my $skip_update = 0;
+    my @attributes  = $asset->WritableAttributes;
+
+    # Don't update status unless we have a value; otherwise RT complains
+    @attributes = grep { $_ ne "Status" } @attributes
+        unless $ARGS{Status};
+
+    my ($cf_ok, @cf_errors) = $m->comp(
+        '/Elements/ValidateCustomFields',
+        Object          => $asset,
+        CustomFields    => $asset->CustomFields,
+        ARGSRef         => \%ARGS
+    );
+
+    $m->callback(
+        CallbackName        => 'BeforeUpdate',
+        AssetObj            => $asset,
+        UpdatableAttributes => \@attributes,
+        results             => \@results,
+        cf_ok               => \$cf_ok,
+        skip_update         => \$skip_update,
+        ARGSRef             => \%ARGS,
+    );
+
+    if ($cf_ok and not $skip_update) {
+        push @results, ProcessObjectCustomFieldUpdates( Object => $asset, ARGSRef => \%ARGS );
+        push @results, UpdateRecordObject(
+            Object          => $asset,
+            AttributesRef   => \@attributes,
+            ARGSRef         => \%ARGS
+        );
+
+        $m->callback(
+            CallbackName        => 'AfterUpdate',
+            AssetObj            => $asset,
+            UpdatableAttributes => \@attributes,
+            results             => \@results,
+            ARGSRef             => \%ARGS,
+        );
+
+        MaybeRedirectForResults(
+            Actions     => \@results,
+            Arguments   => { id => $asset->id },
+            $DisplayAfter
+                ? (Path => "/Asset/Display.html")
+                : (),
+        );
+    } else {
+        push @results, @cf_errors;
+    }
+}
+</%init>
diff --git a/share/html/Asset/ModifyCFs.html b/share/html/Asset/ModifyCFs.html
new file mode 100755
index 0000000..41728ca
--- /dev/null
+++ b/share/html/Asset/ModifyCFs.html
@@ -0,0 +1,105 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 [_3] for asset #[_1]: [_2]", $asset->id, $asset->Name, $Grouping || loc("Custom Fields") ) &>
+<& /Elements/Tabs &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<span class="catalog <% CSSClass($asset->CatalogObj->Name) %>">
+<form method="post" enctype="multipart/form-data" id="ModifyAssetCFs" action="ModifyCFs.html">
+  <input type="hidden" name="id" value="<% $asset->id %>">
+  <input type="hidden" name="Grouping" value="<% $Grouping %>">
+
+  <&| /Widgets/TitleBox, title => $Grouping ? loc($Grouping) : loc("Custom Fields"), class => "asset-info-cfs ".($Grouping ? CSSClass("asset-info-cfs-\L$Grouping") : ""), title_class => "inverse" &>
+    <& /Elements/EditCustomFields, Object => $asset, Grouping => $Grouping &>
+  </&>
+
+  <& /Elements/Submit, Label => loc('Save asset'), Name => "Update" &>
+</form>
+</span>
+
+<%args>
+$id         => undef
+$Update     => 0
+$Grouping   => ''
+</%args>
+<%init>
+my $asset = LoadAsset($id);
+my @results;
+
+my $CFs = $asset->CustomFields;
+$CFs->LimitToGrouping($asset => $Grouping);
+
+Abort(loc("No custom fields found for grouping '[_1]'", $Grouping))
+    if $Grouping and not $CFs->Count;
+
+$m->callback( Asset => $asset, ARGSRef => \%ARGS, Update => \$Update, results => \@results );
+
+if ($Update) {
+    my ($cf_ok, @cf_errors) = $m->comp(
+        '/Elements/ValidateCustomFields',
+        Object          => $asset,
+        CustomFields    => $CFs,
+        ARGSRef         => \%ARGS
+    );
+
+    if ($cf_ok) {
+        push @results, ProcessObjectCustomFieldUpdates( Object => $asset, ARGSRef => \%ARGS );
+
+        MaybeRedirectForResults(
+            Actions     => \@results,
+            Arguments   => {
+                id          => $asset->id,
+                Grouping    => $Grouping,
+            },
+        );
+    } else {
+        push @results, @cf_errors;
+    }
+}
+</%init>
diff --git a/share/html/Asset/ModifyDates.html b/share/html/Asset/ModifyDates.html
new file mode 100755
index 0000000..8ca0f3e
--- /dev/null
+++ b/share/html/Asset/ModifyDates.html
@@ -0,0 +1,97 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 asset #[_1]: [_2]", $asset->id, $asset->Name) &>
+<& /Elements/Tabs &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<span class="catalog <% CSSClass($asset->CatalogObj->Name) %>">
+<form method="post" enctype="multipart/form-data" id="ModifyAssetDates" action="ModifyDates.html">
+  <input type="hidden" name="id" value="<% $asset->id %>">
+
+  <&| /Widgets/TitleBox, title => loc("Dates"), class => "asset-dates", title_class => "inverse" &>
+    <& Elements/EditDates, %ARGS, AssetObj => $asset &>
+  </&>
+
+  <& /Elements/Submit, Label => loc('Save asset'), Name => "Update" &>
+</form>
+</span>
+
+<%init>
+my $asset = LoadAsset($id);
+my @results;
+
+$m->callback( Asset => $asset, ARGSRef => \%ARGS, Update => \$Update, results => \@results );
+
+if ($Update) {
+    my $CFs = $asset->CustomFields;
+    $CFs->LimitToGrouping($asset => "Dates");
+
+    my ($cf_ok, @cf_errors) = $m->comp(
+        '/Elements/ValidateCustomFields',
+        Object          => $asset,
+        CustomFields    => $CFs,
+        ARGSRef         => \%ARGS
+    );
+
+    if ($cf_ok) {
+        push @results, ProcessObjectCustomFieldUpdates( Object => $asset, ARGSRef => \%ARGS );
+
+        MaybeRedirectForResults(
+            Actions     => \@results,
+            Arguments   => { id => $asset->id },
+        );
+    } else {
+        push @results, @cf_errors;
+    }
+}
+</%init>
+<%args>
+$id     => undef
+$Update => 0
+</%args>
diff --git a/share/html/Asset/ModifyLinks.html b/share/html/Asset/ModifyLinks.html
new file mode 100755
index 0000000..ad95b8f
--- /dev/null
+++ b/share/html/Asset/ModifyLinks.html
@@ -0,0 +1,98 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 links for asset #[_1]: [_2]", $asset->id, $asset->Name) &>
+<& /Elements/Tabs &>
+
+<& /Elements/ListActions, actions => \@results &>
+
+<span class="catalog <% CSSClass($asset->CatalogObj->Name) %>">
+<form method="post" enctype="multipart/form-data" id="ModifyAssetLinks" action="ModifyLinks.html">
+  <input type="hidden" name="id" value="<% $asset->id %>">
+
+  <&| /Widgets/TitleBox, title => loc("Links"), class => "asset-links", title_class => "inverse" &>
+    <& /Elements/EditLinks, %ARGS, Object => $asset, Merge => 0 &>
+  </&>
+
+  <& /Elements/Submit, Label => loc('Save asset'), Name => "Update" &>
+</form>
+</span>
+
+<%init>
+my $asset = LoadAsset($id);
+my @results;
+
+$m->callback( Asset => $asset, ARGSRef => \%ARGS, Update => \$Update, results => \@results );
+
+if ($Update) {
+    my $CFs = $asset->CustomFields;
+    $CFs->LimitToGrouping($asset => "Links");
+
+    my ($cf_ok, @cf_errors) = $m->comp(
+        '/Elements/ValidateCustomFields',
+        Object          => $asset,
+        CustomFields    => $CFs,
+        ARGSRef         => \%ARGS
+    );
+
+    if ($cf_ok) {
+        push @results, ProcessRecordLinks( RecordObj => $asset, ARGSRef => \%ARGS );
+        push @results, ProcessObjectCustomFieldUpdates( Object => $asset, ARGSRef => \%ARGS );
+
+        MaybeRedirectForResults(
+            Actions     => \@results,
+            Arguments   => { id => $asset->id },
+        );
+    } else {
+        push @results, @cf_errors;
+    }
+}
+</%init>
+<%args>
+$id     => undef
+$Update => 0
+</%args>
diff --git a/share/html/Asset/ModifyPeople.html b/share/html/Asset/ModifyPeople.html
new file mode 100755
index 0000000..330f530
--- /dev/null
+++ b/share/html/Asset/ModifyPeople.html
@@ -0,0 +1,111 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 asset #[_1]: [_2]", $asset->id, $asset->Name) &>
+<& /Elements/Tabs &>
+
+% $m->callback(CallbackName => 'BeforeActionList', ARGSRef => \%ARGS, Asset => $asset, Actions => \@results);
+
+<& /Elements/ListActions, actions => \@results &>
+
+<span class="catalog <% CSSClass($asset->CatalogObj->Name) %>">
+<form method="post" enctype="multipart/form-data" id="ModifyAssetPeople" action="ModifyPeople.html">
+  <input type="hidden" name="id" value="<% $asset->id %>">
+
+  <&| /Widgets/TitleBox, title => loc("People"), class => "asset-people", title_class => "inverse" &>
+    <table width="100%" class="edit">
+      <tr>
+        <td width="30%"><& /Elements/Assets/EditPeople, %ARGS, Object => $asset &></td>
+        <td width="30%"><& /Elements/Assets/AddPeople, Object => $asset &></td>
+        <td>
+          <& /Elements/EditCustomFields, Object => $asset, Grouping => 'People', AsTable => 1 &>
+        </td>
+      </tr>
+    </table>
+  </&>
+
+  <& /Elements/Submit, Label => loc('Save'), Name => "Update" &>
+</form>
+</span>
+
+<%init>
+my $asset = LoadAsset($id);
+my @results;
+
+$m->callback( Asset => $asset, ARGSRef => \%ARGS, Update => \$Update, results => \@results );
+
+if ($Update) {
+    my $CFs = $asset->CustomFields;
+    $CFs->LimitToGrouping($asset => "People");
+
+    my ($cf_ok, @cf_errors) = $m->comp(
+        '/Elements/ValidateCustomFields',
+        Object          => $asset,
+        CustomFields    => $CFs,
+        ARGSRef         => \%ARGS
+    );
+
+    if ($cf_ok) {
+        push @results, ProcessRoleMembers( $asset => %ARGS );
+        push @results, ProcessObjectCustomFieldUpdates( Object => $asset, ARGSRef => \%ARGS );
+
+        MaybeRedirectForResults(
+            Actions     => \@results,
+            Arguments   => { id => $asset->id },
+        );
+    } else {
+        push @results, @cf_errors;
+    }
+}
+
+$m->callback(CallbackName => 'BeforeDisplay', ARGSRef => \%ARGS, Asset => $asset);
+</%init>
+<%args>
+$id     => undef
+$Update => 0
+</%args>
+
diff --git a/share/html/Asset/Search/Bulk.html b/share/html/Asset/Search/Bulk.html
new file mode 100644
index 0000000..74fe7db
--- /dev/null
+++ b/share/html/Asset/Search/Bulk.html
@@ -0,0 +1,197 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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("Assets") &>
+<& /Elements/Tabs &>
+
+% $m->callback(CallbackName => 'BeforeActionList', ARGSRef => \%ARGS, Assets => $assets, Actions => \@results);
+
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" action="<% RT->Config->Get('WebPath') %>/Asset/Search/Bulk.html" enctype="multipart/form-data" name="BulkUpdate" id="BulkUpdate">
+% foreach my $var ( @{$search{'PassArguments'}} )  {
+<input type="hidden" class="hidden" name="<% $var %>" value="<% $ARGS{$var} || '' %>" />
+% }
+<& /Elements/CollectionList,
+    %search,
+    Collection      => $assets,
+    AllowSorting    => 1,
+    DisplayFormat   => $DisplayFormat,
+    &>
+% if (not $assets->Count) {
+<em><&|/l&>No assets matching search criteria found.</&></em>
+% }
+
+<& /Elements/Submit,
+    Name => 'Update',
+    Label => loc('Update'),
+    CheckboxNameRegex => '/^UpdateAsset(All)?$/',
+    CheckAll => 1, ClearAll => 1,
+&>
+
+<&| /Widgets/TitleBox, title => loc("Basics"), class => "asset-basics asset-bulk-basics", title_class => "inverse" &>
+<table>
+  <tr class="asset-catalog">
+    <td class="label"><label for="UpdateCatalog"><&|/l&>Catalog</&></label></td>
+    <td><& /Asset/Elements/SelectCatalog, Name => 'UpdateCatalog', Default => $catalog_obj->id, UpdateSession => 0, &></td>
+  </tr>
+  <tr class="asset-name">
+    <td class="label"><label for="UpdateName"><&|/l&>Name</&></label></td>
+    <td><input name="UpdateName" value="<% $ARGS{'Name'}||'' %>" size="40"></td>
+  </tr>
+  <tr class="asset-description">
+    <td class="label"><label for="UpdateDescription"><&|/l&>Description</&></label></td>
+    <td><input name="UpdateDescription" value="<% $ARGS{'Description'}||'' %>" size="40"></td>
+  </tr>
+  <tr class="asset-status">
+    <td class="label"><label for="UpdateStatus"><&|/l&>Status</&></label></td>
+    <td><& /Asset/Elements/SelectStatus, Name => 'UpdateStatus', DefaultValue => 1, CatalogObj => $catalog_obj &></td>
+  </tr>
+</table>
+</&>
+
+<&| /Widgets/TitleBox, title => loc("People"), class => "asset-people asset-bulk-people", title_class => "inverse" &>
+<table>
+% for my $rname ( $asset->Roles( ACLOnly => 0 ) ) {
+% my $role = $asset->Role( $rname );
+% if ( $role->{'Single'} ) {
+% my $input = "SetRoleMember-$rname";
+<tr class="full-width">
+<td class="label"><label for="<% $input %>"><% loc($rname) %></label></td>
+<td><input type="text" value="<% $ARGS{ $input } || '' %>" name="<% $input %>" id="<% $input %>" data-autocomplete="Users" data-autocomplete-return="Name" /></td>
+</tr>
+% } else {
+<tr>
+% my $input = "AddRoleMember-$rname";
+<td class="label"><label for="<% $input %>"><% loc("Add [_1]", loc($rname)) %></label></td>
+<td><input type="text" value="<% $ARGS{ $input } || '' %>" name="<% $input %>" id="<% $input %>" data-autocomplete="Users" data-autocomplete-return="Name" /></td>
+</tr>
+
+<tr>
+% $input = "RemoveRoleMember-$rname";
+<td class="label"><label for="<% $input %>"><% loc("Remove [_1]", loc($rname)) %></label></td>
+<td>
+  <input type="text" value="<% $ARGS{ $input } || '' %>" name="<% $input %>" id="<% $input %>" data-autocomplete="Users" data-autocomplete-return="Name" />
+  <label>
+    <input type="checkbox" name="RemoveAllRoleMembers-<% $rname %>" value="1"/>
+    <em><&|/l&>(Check to delete all values)</&></em>
+  </label>
+</td>
+</tr>
+% }
+% }
+</table>
+</&>
+
+% for my $group ( RT::CustomField->CustomGroupings( 'RT::Asset' ), '' ) {
+%   my $cfs = $catalog_obj->AssetCustomFields;
+%   $cfs->LimitToGrouping( 'RT::Asset' => $group);
+%   if ( $cfs->Count ) {
+<&| /Widgets/TitleBox, class=>'asset-bulk-grouping asset-bulk-cfs', title => loc('Edit [_1]', ($group? loc($group) : loc('Custom Fields')) ) &>
+<& /Elements/BulkCustomFields, CustomFields => $cfs, &>
+</&>
+%   }
+% }
+
+<&|/Widgets/TitleBox, title => loc('Edit Links'), color => "#336633"&>
+<& /Elements/BulkLinks, Collection => $assets, %ARGS &>
+</&>
+
+<& /Elements/Submit, Label => loc('Update'), Name => 'Update' &>
+</form>
+
+<%INIT>
+my @results;
+$m->callback(ARGSRef => \%ARGS, Results => \@results, CallbackName => 'Initial');
+
+my $catalog_obj = LoadDefaultCatalog($ARGS{'Catalog'} || '');
+$ARGS{'Catalog'} = $catalog_obj->Id;
+
+my $assets = RT::Assets->new($session{CurrentUser});
+my %search = ProcessAssetsSearchArguments(
+    Assets => $assets, Catalog => $catalog_obj, ARGSRef => \%ARGS,
+);
+
+my $DisplayFormat = "'__CheckBox.{UpdateAsset}__',". $search{'Format'};
+$DisplayFormat =~ s/\s*,\s*('?__NEWLINE__'?)/,$1,''/gi;
+
+my $asset = RT::Asset->new( $session{'CurrentUser'} );
+
+delete $ARGS{$_} foreach grep { $ARGS{$_} =~ /^$/ } keys %ARGS;
+
+$DECODED_ARGS->{'UpdateAssetAll'} = 1 unless @UpdateAsset;
+
+if ( $ARGS{Update} ) {
+    my @attributes  = $asset->WritableAttributes;
+    @attributes = grep exists $ARGS{ 'Update'. $_ }, @attributes;
+    my %basics = map { $_ => $ARGS{ 'Update'. $_ } } @attributes;
+
+    foreach my $aid ( @UpdateAsset ) {
+        my $asset = LoadAsset($aid);
+
+        my @tmp_res;
+        push @tmp_res, UpdateRecordObject(
+            Object          => $asset,
+            AttributesRef   => \@attributes,
+            ARGSRef         => \%basics,
+        );
+        push @tmp_res, ProcessRoleMembers( $asset => %ARGS );
+        push @tmp_res, ProcessObjectCustomFieldUpdates( Object => $asset, ARGSRef => \%ARGS );
+        push @tmp_res, ProcessRecordLinks( RecordObj => $asset, RecordId => 'Asset', ARGSRef => \%ARGS );
+        push @tmp_res, ProcessRecordBulkCustomFields( RecordObj => $asset, ARGSRef => \%ARGS );
+        push @results, map { loc( "Asset #[_1]: [_2]", $asset->id, $_ ) } @tmp_res;
+    }
+
+    MaybeRedirectForResults(
+        Actions     => \@results,
+        Arguments   => { map { $_ => $ARGS{$_} } grep { defined $ARGS{$_} } @{$search{'PassArguments'}} },
+    );
+}
+</%INIT>
+<%ARGS>
+ at UpdateAsset => ()
+</%ARGS>
diff --git a/share/html/Asset/Search/Results.tsv b/share/html/Asset/Search/Results.tsv
new file mode 100644
index 0000000..41248b6
--- /dev/null
+++ b/share/html/Asset/Search/Results.tsv
@@ -0,0 +1,73 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 $catalog_obj = LoadDefaultCatalog($ARGS{'Catalog'} || '');
+$ARGS{'Catalog'} = $catalog_obj->Id;
+
+my $assets = RT::Assets->new($session{CurrentUser});
+ProcessAssetsSearchArguments(
+    Assets => $assets, Catalog => $catalog_obj, ARGSRef => \%ARGS,
+);
+
+my $Format = q|id, Name, Description, Status, Catalog, |;
+
+$Format .= "$_, " for RT::Asset->Roles;
+
+my $CFs = RT::CustomFields->new( $session{CurrentUser} );
+$CFs->LimitToCatalog( $catalog_obj->Id );
+$CFs->LimitToObjectId( 0 ); # LimitToGlobal but no LookupType restriction
+$Format .= "'__CF.{$_}__/TITLE:$_', " for map {$_ = $_->Name; s/['\\]/\\$1/g; $_} @{$CFs->ItemsArrayRef};
+
+$m->callback(CallbackName => "ModifyFormat", Format => \$Format );
+
+my $comp = "/Asset/Elements/TSVExport";
+$comp = "/Elements/TSVExport" if $m->comp_exists("/Elements/TSVExport");
+
+$m->comp($comp, Collection => $assets, Format => $Format );
+
+</%init>
diff --git a/share/html/Asset/Search/index.html b/share/html/Asset/Search/index.html
new file mode 100644
index 0000000..a0eb3fd
--- /dev/null
+++ b/share/html/Asset/Search/index.html
@@ -0,0 +1,108 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 $catalog_obj = LoadDefaultCatalog($ARGS{'Catalog'} || '');
+$ARGS{'Catalog'} = $catalog_obj->Id;
+
+my $assets = RT::Assets->new($session{CurrentUser});
+my %search = ProcessAssetsSearchArguments(
+    Assets => $assets, Catalog => $catalog_obj, ARGSRef => \%ARGS,
+);
+
+my $title = ( $ARGS{'SearchAssets'} or $ARGS{q} ) ?
+      loc("Found [quant,_1,asset,assets]",$assets->Count)
+    : loc("Assets");
+
+</%init>
+<& /Elements/Header, Title => $title &>
+<& /Elements/Tabs &>
+
+% if ( $ARGS{'SearchAssets'} or $ARGS{q} ){
+<& /Elements/CollectionList,
+    %search,
+    Collection      => $assets,
+    AllowSorting    => 1,
+    &>
+%   if (not $assets->Count) {
+<em><&|/l&>No assets matching search criteria found.</&></em>
+%   }
+% }
+<span class="catalog <% CSSClass( $catalog_obj->Name ) %>">
+<form action="<% RT->Config->Get('WebPath') %>/Asset/Search/index.html" id="AssetSearch">
+<&| /Widgets/TitleBox, title => loc("Search Assets") &>
+<& /Asset/Elements/AssetSearchBasics, %ARGS, CatalogObj => $catalog_obj &>
+<& /Asset/Elements/AssetSearchPeople, %ARGS, CatalogObj => $catalog_obj &>
+<& /Elements/Submit, Label => loc('Search'), Name => 'SearchAssets' &>
+
+% foreach my $group ( 'Dates', 'Links', RT::CustomField->CustomGroupings( "RT::Asset" ), '' ) {
+    <& /Asset/Elements/AssetSearchCFs, %ARGS, Grouping => $group,
+       CatalogObj => $catalog_obj &>
+% }
+<& /Elements/Submit, Label => loc('Search'), Name => 'SearchAssets' &>
+</&>
+
+<script>
+jQuery(function() {
+    var all_inputs = jQuery("#AssetSearch input, #AssetSearch select");
+    all_inputs.each(function() {
+        var elem = jQuery(this);
+        var update_elems = all_inputs.filter(function () {
+            return jQuery(this).attr("name") == elem.attr("name");
+        }).not(elem);
+        if (update_elems.length == 0)
+            return;
+        var trigger_func = function() { update_elems.val(elem.val()) };
+        if (elem.attr("type") == "text")
+            elem.keyup( trigger_func );
+        else
+            elem.change( trigger_func );
+    });
+});
+</script>
+</form>
+</span>
diff --git a/share/html/Asset/index.html b/share/html/Asset/index.html
new file mode 100644
index 0000000..ebb2299
--- /dev/null
+++ b/share/html/Asset/index.html
@@ -0,0 +1,66 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 $assets = RT::Assets->new($session{CurrentUser});
+$assets->UnLimit;
+</%init>
+<& /Elements/Header, Title => loc("Assets") &>
+<& /Elements/Tabs &>
+
+<& /Elements/CollectionList,
+    Collection      => $assets,
+    OrderBy         => 'Name',
+    Order           => 'ASC',
+    Format          => q[
+        '<b><a href="__WebPath__/Asset/Display.html?id=__id__">__id__</a></b>/TITLE:#',
+        '<b><a href="__WebPath__/Asset/Display.html?id=__id__">__Name__</a></b>/TITLE:Name',
+        Description,
+        Status,
+    ],
+    AllowSorting    => 0,
+    &>
diff --git a/share/html/Elements/Assets/AddPeople b/share/html/Elements/Assets/AddPeople
new file mode 100644
index 0000000..e73ec5e
--- /dev/null
+++ b/share/html/Elements/Assets/AddPeople
@@ -0,0 +1,67 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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
+</%args>
+<div class="add-user">
+<h3><&|/l&>Add a person</&></h3>
+<& SelectRoleType, Object => $Object, Name => "AddUserRoleMember-Role" &>
+<input type="text" name="AddUserRoleMember"
+       data-autocomplete="Users"
+       data-autocomplete-return="Name"
+       placeholder="<% loc("Find a user...") %>">
+</div>
+
+<div class="add-group">
+<h3><&|/l&>Add a group</&></h3>
+<& SelectRoleType, Object => $Object, Name => "AddGroupRoleMember-Role" &>
+<input type="text" name="AddGroupRoleMember"
+       data-autocomplete="Groups"
+       data-autocomplete-return="Name"
+       placeholder="<% loc("Find a group...") %>">
+</div>
diff --git a/share/html/Elements/Assets/EditPeople b/share/html/Elements/Assets/EditPeople
new file mode 100644
index 0000000..6f9ccdd
--- /dev/null
+++ b/share/html/Elements/Assets/EditPeople
@@ -0,0 +1,59 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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
+</%args>
+<%init>
+</%init>
+% for my $role ($Object->Roles( ACLOnly => 0 )) {
+<div class="role-<% CSSClass($role) %> role">
+  <h3><% loc($role) %></h3>
+  <& EditRoleMembers, Group => $Object->RoleGroup($role) &>
+</div>
+% }
+<em><&|/l&>(Check box to delete)</&></em>
diff --git a/share/html/Elements/Assets/EditRoleMembers b/share/html/Elements/Assets/EditRoleMembers
new file mode 100644
index 0000000..30b6962
--- /dev/null
+++ b/share/html/Elements/Assets/EditRoleMembers
@@ -0,0 +1,79 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+$Group       => undef
+$Recursively => 0
+</%args>
+<%init>
+my $field_name = "RemoveRoleMember-" . $Group->Name;
+</%init>
+<ul class="role-members">
+% my $Users = $Group->UserMembersObj( Recursively => $Recursively );
+% if ($Group->SingleMemberRoleGroup) {
+<input type="text" value="<% $Users->First->Name %>" name="SetRoleMember-<% $Group->Name %>" id="SetRoleMember-<% $Group->Name %>" data-autocomplete="Users" data-autocomplete-return="Name" /><br />
+% } else {
+% while ( my $user = $Users->Next ) {
+<li>
+  <label>
+    <input type="checkbox" name="<% $field_name %>" value="<% $user->PrincipalId %>">
+    <& /Elements/ShowUser, User => $user &>
+  </label>
+</li>
+% }
+% my $Groups = $Group->GroupMembersObj( Recursively => $Recursively );
+% $Groups->LimitToUserDefinedGroups;
+% while (my $group = $Groups->Next) {
+<li>
+  <label>
+    <input type="checkbox" name="<% $field_name %>" value="<% $group->PrincipalId %>">
+    <&|/l&>Group</&>: <% $group->Name %>
+  </label>
+</li>
+% }
+% }
+</ul>
diff --git a/share/html/Elements/Assets/Search b/share/html/Elements/Assets/Search
new file mode 100644
index 0000000..9750ef766
--- /dev/null
+++ b/share/html/Elements/Assets/Search
@@ -0,0 +1,53 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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->Config->Get('WebPath') %>/Asset/Search/">
+  <input size="12" name="q" accesskey="0" class="field" value="<% $value %>" placeholder="<&|/l&>Search Assets</&>..." />
+</form>
+<%init>
+my $value = defined $DECODED_ARGS->{q} ? $DECODED_ARGS->{q} : '';
+</%init>
diff --git a/share/html/Elements/Assets/SelectRoleType b/share/html/Elements/Assets/SelectRoleType
new file mode 100644
index 0000000..a38e305
--- /dev/null
+++ b/share/html/Elements/Assets/SelectRoleType
@@ -0,0 +1,60 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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
+$Name
+$AllowNull  => 0
+</%args>
+<select name="<% $Name %>">
+% if ($AllowNull) {
+  <option value=""></option>
+% }
+% for my $role ($Object->Roles( ACLOnly => 0, Single => 0 )) {
+  <option value="<% $role %>"><% loc($role) %></option>
+% }
+</select>
diff --git a/share/html/Elements/FindAsset b/share/html/Elements/FindAsset
new file mode 100644
index 0000000..d7e8b1f
--- /dev/null
+++ b/share/html/Elements/FindAsset
@@ -0,0 +1,53 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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('Find an asset') &>
+<form action="<% RT->Config->Get('WebPath') %>/Asset/Search/">
+  <input type="text" name="q" />
+  <input type="submit" value="<&|/l&>Search</&>" class="button" />
+</form>
+</&>
diff --git a/share/html/Elements/MyAssets b/share/html/Elements/MyAssets
new file mode 100644
index 0000000..615ffcf
--- /dev/null
+++ b/share/html/Elements/MyAssets
@@ -0,0 +1,48 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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/AssetList, User => $session{'CurrentUser'}->UserObj, Roles => [qw(HeldBy)], Title => loc('My Assets') &>
diff --git a/share/html/Elements/RT__Asset/ColumnMap b/share/html/Elements/RT__Asset/ColumnMap
new file mode 100644
index 0000000..ffc8b0e
--- /dev/null
+++ b/share/html/Elements/RT__Asset/ColumnMap
@@ -0,0 +1,121 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+my $linkUsers;
+$linkUsers = sub {
+    my ($what, $more) = @_;
+    if ($what->isa("RT::Group")) {
+        # Link the users (non-recursively)
+        my @ret = map {$linkUsers->($_->[1], $more), ", "}
+            sort {$a->[0] cmp $b->[0]}
+            map {+[($_->EmailAddress||''), $_]}
+            @{ $what->UserMembersObj( Recursively => 0 )->ItemsArrayRef };
+
+        # But don't link the groups
+        push @ret, map {+("Group: $_", ",")}
+            sort map {$_->Name} @{ $what->GroupMembersObj( Recursively => 0)->ItemsArrayRef };
+
+        pop @ret; # Remove ending ", "
+        return @ret;
+    } else {
+        my @ret = \($m->scomp("/Elements/ShowUser", User => $what));
+        push @ret, $more->($what) if $more;
+        return @ret;
+    }
+};
+my $COLUMN_MAP = {
+    Name => {
+        attribute => 'Name',
+        title     => 'Name',
+        value     => sub { $_[0]->Name },
+    },
+    Description => {
+        attribute => 'Description',
+        title     => 'Description',
+        value     => sub { $_[0]->Description },
+    },
+    Catalog => {
+        attribute => 'Catalog',
+        title     => 'Catalog', # loc
+        value     => sub { $_[0]->CatalogObj->Name },
+    },
+    Status => {
+        title     => 'Status',
+        attribute => 'Status',
+        value     => sub { loc($_[0]->Status) }
+    },
+    ActiveTickets => {
+        title     => 'Active tickets', # loc
+        value     => sub {
+            my $Asset = shift;
+            my $Query = "RefersTo = 'asset:" . $Asset->id . "'";
+            $Query .= " AND (" . join(" OR ", map { "Status = '$_'" } RT::Queue->ActiveStatusArray) . ")";
+            my $SearchURL = RT->Config->Get('WebPath') . '/Search/Results.html?' . $m->comp('/Elements/QueryString', Query => $Query);
+            return \'[ <a href="',$SearchURL,\'">Active</a> ]';
+        }
+    },
+    InactiveTickets => {
+        title     => 'Inactive tickets', # loc
+        value     => sub {
+            my $Asset = shift;
+            my $Query = "RefersTo = 'asset:" . $Asset->id . "'";
+            $Query .= " AND (" . join(" OR ", map { "Status = '$_'" } RT::Queue->InactiveStatusArray) . ")";
+            my $SearchURL = RT->Config->Get('WebPath') . '/Search/Results.html?' . $m->comp('/Elements/QueryString', Query => $Query);
+            return \'[ <a href="',$SearchURL,\'">Inactive</a> ]';
+        }
+    },
+};
+</%ONCE>
+<%init>
+$m->callback( COLUMN_MAP => $COLUMN_MAP, CallbackName => 'Once', CallbackOnce => 1 );
+return GetColumnMapEntry( Map => $COLUMN_MAP, Name => $Name, Attribute => $Attr );
+</%init>
diff --git a/share/html/Elements/RT__Catalog/ColumnMap b/share/html/Elements/RT__Catalog/ColumnMap
new file mode 100644
index 0000000..8aa1bd6
--- /dev/null
+++ b/share/html/Elements/RT__Catalog/ColumnMap
@@ -0,0 +1,79 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+my $COLUMN_MAP = {
+    Name => {
+        attribute => 'Name',
+        title     => 'Name',
+        value     => sub { $_[0]->Name },
+    },
+    Description => {
+        attribute => 'Description',
+        title     => 'Description',
+        value     => sub { $_[0]->Description },
+    },
+    Disabled => {
+        title     => \' ',
+        attribute => 'Disabled',
+        value     => sub { return $_[0]->Disabled? $_[0]->loc('Disabled'): $_[0]->loc('Enabled') },
+    },
+    Lifecycle => {
+        title => 'Lifecycle',
+        attribute => 'Lifecycle',
+        value => sub { return $_[0]->Lifecycle },
+    },
+};
+</%ONCE>
+<%init>
+$m->callback( COLUMN_MAP => $COLUMN_MAP, CallbackName => 'Once', CallbackOnce => 1 );
+return GetColumnMapEntry( Map => $COLUMN_MAP, Name => $Name, Attribute => $Attr );
+</%init>
diff --git a/share/html/SelfService/Asset/CreateLinkedTicket.html b/share/html/SelfService/Asset/CreateLinkedTicket.html
new file mode 100644
index 0000000..ed4b8fd
--- /dev/null
+++ b/share/html/SelfService/Asset/CreateLinkedTicket.html
@@ -0,0 +1,57 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+$id => undef
+</%args>
+<%init>
+my $asset = LoadAsset($id);
+</%init>
+<& /Elements/Header,
+    Title => loc("Create linked ticket for asset #[_1]: [_2]", $asset->id, $asset->Name) &>
+<& /Elements/Tabs &>
+<& /Asset/Elements/CreateLinkedTicket, AssetObj => $asset &>
diff --git a/share/html/SelfService/Asset/Display.html b/share/html/SelfService/Asset/Display.html
new file mode 100644
index 0000000..d105ced
--- /dev/null
+++ b/share/html/SelfService/Asset/Display.html
@@ -0,0 +1,57 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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("Asset #[_1]: [_2]", $asset->id, $asset->Name) &>
+
+<& /Asset/Elements/ShowSummary, AssetObj => $asset &>
+
+<%args>
+$id => undef
+</%args>
+<%init>
+my $asset = LoadAsset($id);
+</%init>
diff --git a/share/html/SelfService/Asset/Helpers/CreateLinkedTicket b/share/html/SelfService/Asset/Helpers/CreateLinkedTicket
new file mode 100644
index 0000000..6cc25f5
--- /dev/null
+++ b/share/html/SelfService/Asset/Helpers/CreateLinkedTicket
@@ -0,0 +1,55 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+$Asset
+</%args>
+<%init>
+my $asset = LoadAsset($Asset);
+</%init>
+<& /Asset/Elements/CreateLinkedTicket, AssetObj => $asset &>
+% $m->abort;
diff --git a/share/html/SelfService/Asset/History.html b/share/html/SelfService/Asset/History.html
new file mode 100644
index 0000000..02f82e7
--- /dev/null
+++ b/share/html/SelfService/Asset/History.html
@@ -0,0 +1,60 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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("History of Asset #[_1]: [_2]", $asset->id, $asset->Name) &>
+
+<& /Elements/ShowHistory,
+    Object => $asset,
+    ShowDisplayModes => 0,
+    &>
+
+<%args>
+$id => undef
+</%args>
+<%init>
+my $asset = LoadAsset($id);
+</%init>
diff --git a/share/html/SelfService/Asset/index.html b/share/html/SelfService/Asset/index.html
new file mode 100644
index 0000000..79016a8
--- /dev/null
+++ b/share/html/SelfService/Asset/index.html
@@ -0,0 +1,49 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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("My Assets") &>
+<& /User/Elements/AssetList, User => $session{'CurrentUser'}->UserObj, Roles => [''], Title => loc('My Assets') &>
diff --git a/share/html/Ticket/Elements/ShowAssets b/share/html/Ticket/Elements/ShowAssets
new file mode 100644
index 0000000..7df9bb0
--- /dev/null
+++ b/share/html/Ticket/Elements/ShowAssets
@@ -0,0 +1,204 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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
+$ShowRelatedTickets => 10
+</%args>
+<%init>
+my $target_assets = $Ticket->Links("Base")->Clone;
+$target_assets->Limit(
+    FIELD    => "Target",
+    OPERATOR => "STARTSWITH",
+    VALUE    => RT::URI::asset->LocalURIPrefix,
+);
+my $base_assets = $Ticket->Links("Target")->Clone;
+$base_assets->Limit(
+    FIELD    => "Base",
+    OPERATOR => "STARTSWITH",
+    VALUE    => RT::URI::asset->LocalURIPrefix,
+);
+
+my @linked_assets;
+push @linked_assets, grep { defined } map { $_->TargetURI->IsLocal }
+    @{ $target_assets->ItemsArrayRef };
+push @linked_assets, grep { defined } map { $_->BaseURI->IsLocal }
+    @{ $base_assets->ItemsArrayRef };
+
+my $asset_queue;
+if (RT->Config->Get('AssetQueues')) {
+    $asset_queue = 1 if grep {$_ eq $Ticket->QueueObj->Name} @{RT->Config->Get('AssetQueues')}
+} else {
+    $asset_queue = 1;
+}
+return unless @linked_assets or ($Ticket->CurrentUserHasRight("ModifyTicket")
+                                     and $asset_queue);
+
+my $assets = RT::Assets->new( $session{CurrentUser} );
+$assets->OrderBy( FIELD => "Name", ORDER => "ASC" );
+if ( @linked_assets ) {
+    $assets->Limit(
+        FIELD       => "id",
+        OPERATOR    => "IN",
+        VALUE       => \@linked_assets,
+    );
+}
+
+my $Format = RT->Config->Get("AssetSummaryFormat") || q[
+    '<a href="__WebHomePath__/Asset/Display.html?id=__id__">__Name__</a>/TITLE:Name',
+    Description,
+    Status,
+    Catalog,
+];
+
+$m->callback(
+    CallbackName    => 'ModifyCollection',
+    Ticket          => $Ticket,
+    Assets          => $assets,
+    Format          => \$Format,
+);
+
+
+</%init>
+<&| /Widgets/TitleBox,
+    title => loc('Assets'),
+    class => 'ticket-assets',
+    title_class => "inverse",
+    &>
+
+<form action="<% RT->Config->Get("WebPath") %>/Ticket/Display.html" method="POST" enctype="multipart/form-data">
+  <input type="hidden" name="id" value="<% $Ticket->id %>">
+
+% $m->callback( CallbackName => "Start", Ticket => $Ticket, Assets => $assets );
+
+<div id="assets-accordion" class="rt-accordion">
+% my $display_path = $session{'CurrentUser'}->Privileged ? 'Asset' : 'SelfService/Asset';
+% while (my $asset = $assets->Next) {
+  <h3><a href="<% RT->Config->Get('WebPath') %>/<% $display_path %>/Display.html?id=<% $asset->id %>"><&|/l, $asset->id, $asset->Name &>#[_1]: [_2]</&></a>
+<%perl>
+if ($Ticket->CurrentUserHasRight("ModifyTicket")) {
+    my $targets = $asset->Links("Target")->Clone;
+    $targets->Limit(
+        FIELD   => "LocalBase",
+        VALUE   => $Ticket->id,
+    );
+    my $bases = $asset->Links("Base")->Clone;
+    $bases->Limit(
+        FIELD   => "LocalTarget",
+        VALUE   => $Ticket->id,
+    );
+
+    my %params;
+    $params{join("-", "DeleteLink", "", $_->Type, $_->Target)} = 1
+        for @{ $targets->ItemsArrayRef };
+    $params{join("-", "DeleteLink", $_->Base, $_->Type, "")} = 1
+        for @{ $bases->ItemsArrayRef };
+
+    my $delete_url = RT->Config->Get("WebPath")
+        . "/Ticket/Display.html?"
+        . $m->comp("/Elements/QueryString", id => $Ticket->id, %params);
+</%perl>
+<a href="<% $delete_url %>" class="unlink-asset ui-icon ui-icon-circle-close" title="Unlink asset">X</a>
+% }
+  </h3>
+  <div class="details">
+    <& /Elements/ShowRecord,
+        Object      => $asset,
+        Format      => $Format,
+        TrustFormat => 1,
+        &>
+% $m->callback( CallbackName => "BeforeTickets", Ticket => $Ticket, Asset => $asset );
+<%perl>
+if ($ShowRelatedTickets) {
+    my %search = (
+        Query   => "id != '@{[$Ticket->id]}' AND LinkedTo = 'asset:@{[$asset->id]}'",
+        OrderBy => "LastUpdated",
+        Order   => "DESC",
+    );
+    my $url = RT->Config->Get("WebPath")
+            . "/Search/Results.html?"
+            . $m->comp("/Elements/QueryString", %search);
+</%perl>
+    <div class="related-tickets">
+      <span class="label">
+        <a href="<% $url %>">
+          <&|/l, $ShowRelatedTickets &>[_1] most recently updated related tickets</&>
+        </a>
+      </span>
+      <& /Elements/CollectionList,
+          %search,
+          Class             => "RT::Tickets",
+          Format            => RT->Config->Get("AssetSummaryRelatedTicketsFormat"),
+          Rows              => $ShowRelatedTickets,
+          ShowHeader        => 0,
+          AllowSorting      => 0,
+          ShowNavigation    => 0,
+      &>
+    </div>
+% }
+
+% $m->callback( CallbackName => "PerAsset", Ticket => $Ticket, Asset => $asset );
+
+  </div>
+% }
+</div>
+
+% if ($Ticket->CurrentUserHasRight("ModifyTicket")) {
+  <div class="add-asset">
+    <label>
+      <&|/l&>Add an asset to this ticket</&>
+    <input size="5" name="<% $Ticket->id %>-RefersTo" placeholder="<&|/l&>Asset #</&>" type="text">
+    </label>
+    <input type="submit" value="+">
+  </div>
+% }
+
+% $m->callback( CallbackName => "End", Ticket => $Ticket, Assets => $assets );
+
+</form>
+
+</&>
diff --git a/share/html/Ticket/Elements/ShowAssetsOnCreate b/share/html/Ticket/Elements/ShowAssetsOnCreate
new file mode 100644
index 0000000..a6f3bb4
--- /dev/null
+++ b/share/html/Ticket/Elements/ShowAssetsOnCreate
@@ -0,0 +1,121 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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>
+$QueueObj
+$ARGSRef
+</%args>
+<%init>
+my @linked_assets;
+foreach my $key ( map {+("new-$_", "$_-new")} keys %RT::Link::DIRMAP ) {
+    next unless $ARGSRef->{$key};
+    for my $linktext (grep $_, split ' ', $ARGSRef->{$key}) {
+        my $uri = RT::URI->new( $session{'CurrentUser'} );
+        next unless $uri->FromURI( $linktext );
+        next unless $uri->IsLocal and $uri->Object and $uri->Object->id and $uri->Object->isa("RT::Asset");
+        push @linked_assets, $uri->Object->id;
+    }
+}
+
+my $asset_queue;
+if (RT->Config->Get('AssetQueues')) {
+    $asset_queue = 1 if grep {$_ eq $QueueObj->Name} @{RT->Config->Get('AssetQueues')}
+} else {
+    $asset_queue = 1;
+}
+
+return unless @linked_assets or $asset_queue;
+
+my $assets = RT::Assets->new( $session{CurrentUser} );
+$assets->OrderBy( FIELD => "Name", ORDER => "ASC" );
+if ( @linked_assets ) {
+    $assets->Limit(
+        FIELD       => "id",
+        OPERATOR    => "IN",
+        VALUE       => \@linked_assets,
+    );
+}
+
+my $Format = RT->Config->Get("AssetSummaryFormat") || q[
+    '<a href="__WebHomePath__/Asset/Display.html?id=__id__">__Name__</a>/TITLE:Name',
+    Description,
+    Status,
+    Catalog,
+];
+
+$m->callback(
+    CallbackName    => 'ModifyCollection',
+    Queue           => $QueueObj,
+    Assets          => $assets,
+    Format          => \$Format,
+);
+
+
+</%init>
+<&| /Widgets/TitleBox,
+    title => loc('Assets'),
+    class => 'ticket-assets',
+    title_class => "inverse",
+    &>
+
+% $m->callback( CallbackName => "Start", Queue => $QueueObj, Assets => $assets );
+
+<div id="assets-accordion" class="rt-accordion">
+% while (my $asset = $assets->Next) {
+  <h3><a href="<% RT->Config->Get('WebPath') %>/Asset/Display.html?id=<% $asset->id %>"><&|/l, $asset->id, $asset->Name &>#[_1]: [_2]</&></a></h3>
+  <div class="details">
+    <& /Elements/ShowRecord,
+        Object      => $asset,
+        Format      => $Format,
+        TrustFormat => 1,
+        &>
+% $m->callback( CallbackName => "PerAsset", Queue => $QueueObj, Asset => $asset );
+  </div>
+% }
+</div>
+% $m->callback( CallbackName => "End", Queue => $QueueObj, Assets => $assets );
+</&>
diff --git a/share/html/User/Elements/AssetList b/share/html/User/Elements/AssetList
new file mode 100644
index 0000000..ef5a6a9
--- /dev/null
+++ b/share/html/User/Elements/AssetList
@@ -0,0 +1,78 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license 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 $assets = RT::Assets->new($session{CurrentUser});
+$m->callback( CallbackName => 'ModifyAssetSearch', %ARGS, Assets => $assets, Roles => \@Roles );
+for my $role (@Roles) {
+    $assets->RoleLimit(
+        TYPE        => $role,
+        VALUE       => $User->PrincipalId,
+        SUBCLAUSE   => "Role$role",
+    );
+}
+my $Format = q[
+    '<b><a href="__WebHomePath__/Asset/Display.html?id=__id__">__id__</a></b>/TITLE:#',
+    '<b><a href="__WebHomePath__/Asset/Display.html?id=__id__">__Name__</a></b>/TITLE:Name',
+    Description,
+];
+$m->callback( CallbackName => 'ModifyFormat', %ARGS, Format => \$Format );
+</%init>
+<&| /Widgets/TitleBox, title => $Title, class => "user asset-list" &>
+    <& /Elements/CollectionList,
+        Collection      => $assets,
+        OrderBy         => 'id',
+        Order           => 'ASC',
+        Format          => $Format,
+        AllowSorting    => 0,
+        &>
+</&>
+<%args>
+$User
+$Title
+ at Roles
+</%args>
diff --git a/share/html/User/Elements/Portlets/UserAssets b/share/html/User/Elements/Portlets/UserAssets
new file mode 100644
index 0000000..8bec6b1
--- /dev/null
+++ b/share/html/User/Elements/Portlets/UserAssets
@@ -0,0 +1,52 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+%# Roles => [''] triggers the magical RoleLimit behavior that matches any role
+<& /User/Elements/AssetList, User => $User, Roles => [''], Title => loc('Assigned Assets') &>
+<%ARGS>
+$User
+</%ARGS>

commit bc64c0a30e9de997542549e43129e66b169aa939
Author: Todd Wade <todd at bestpractical.com>
Date:   Wed Aug 12 11:56:17 2015 -0400

    css/js in the right place

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 413c165..a8ea1b3 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -127,6 +127,7 @@ sub JSFiles {
       forms.js
       event-registration.js
       late.js
+      assets.js
       /static/RichText/ckeditor.js
       }, RT->Config->Get('JSFiles');
 }
diff --git a/share/static/css/base/assets.css b/share/static/css/base/assets.css
new file mode 100644
index 0000000..3526fa7
--- /dev/null
+++ b/share/static/css/base/assets.css
@@ -0,0 +1,229 @@
+#assets-accordion h3 {
+    position: relative;
+}
+
+#assets-accordion h3 a.unlink-asset {
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: inherit;
+    padding: 0;
+}
+
+.ticket-assets .add-asset {
+    padding: 2em 0 0 0;
+    text-align: right;
+}
+
+body#comp-Asset-Search .collection-as-table td {
+    white-space: nowrap;
+}
+
+/* Colors */
+
+.asset-basics   .titlebox .titlebox-title .left,
+.asset-info-cfs .titlebox .titlebox-title .left { background-color: #b32    }
+.asset-people   .titlebox .titlebox-title .left { background-color: #48c    }
+.asset-dates    .titlebox .titlebox-title .left { background-color: #633063 }
+.asset-links    .titlebox .titlebox-title .left { background-color: #316531 }
+.ticket-assets  .titlebox .titlebox-title .left { background-color: #316531 }
+
+/* People display */
+
+#comp-Asset-Display .asset-people table {
+    width: 100%;
+}
+
+#comp-Asset-Display .asset-people td.label {
+    text-align: left;
+}
+
+#comp-Asset-Display .asset-people h3 {
+    margin: 0;
+    padding: 0;
+    line-height: 1.3;
+    font-size: 100%;
+}
+
+#comp-Asset-Display .asset-people .details {
+    padding: 0;
+}
+
+/* People editing */
+
+.asset-people .edit ul.role-members {
+    margin-top: 0;
+    padding-left: 0;
+    list-style: none;
+}
+
+.asset-people .edit td {
+    vertical-align: top;
+}
+
+.asset-people .edit .note {
+    font-size: 0.9em;
+}
+
+.asset-people .edit h3 {
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+.asset-people .edit .role h3 {
+    margin-bottom: 0.5em;
+}
+
+.asset-people .edit .role,
+.asset-people .edit .add-group,
+.asset-people .edit .add-user {
+    margin-bottom: 1em;
+}
+
+/* Asset summary */
+
+.ticket-assets form {
+    display: inherit;
+}
+
+.ticket-assets .related-tickets {
+    margin-top: 1em;
+}
+
+.ticket-assets .related-tickets .label a {
+    font-weight: bold;
+    color: black;
+}
+
+.asset-metadata>div {
+    vertical-align: top;
+    min-width: 30%;
+    max-width: 30%;
+    padding-right: 1.5em;
+    display: inline-block;
+}
+
+.asset-metadata {
+    padding-top: 2em; /* nav overflows this :( */;
+}
+
+ at media (max-width: 800px) {
+    .asset-metadata>div {
+        min-width: 45%;
+        width: 45%;
+    }
+}
+
+/* on a little screen, let's just use a single column */
+ at media (max-width: 600px) {
+    .asset-metadata {
+        padding-top: 6em;
+        /* nav overflows this: < */;
+    }
+
+    .asset-metadata>div {
+        min-width: 100%;
+        width: 100%;
+    }
+
+    #Asset-Create-basics>table,
+    #Asset-Create-basics>table>tbody>tr,
+    #Asset-Create-basics>table>tbody>tr>td {
+        display: block;
+    }
+}
+
+/* On a reasonable-width screen, make better use of whitespace */
+ at media (min-width: 601px) {
+    .asset-info-cfs .edit-custom-fields {
+        width: 100%;
+    }
+
+    .asset-info-cfs .edit-custom-fields tr td,
+    #ModifyAsset .asset-basics tr td {
+        display: inline-block;
+    }
+
+    .asset-info-cfs .edit-custom-fields tr,
+    #ModifyAsset .asset-basics tr {
+        display: inline-block;
+        width: 49%;
+    }
+
+    .asset-info-cfs .edit-custom-fields tr td.cflabel,
+    #ModifyAsset .asset-basics tr td.label,
+    #ModifyAsset .asset-basics tr td.cflabel {
+        width: 8em;
+    }
+
+    /* Asset creation */
+    #Asset-Create-basics>table {
+        width: 100%;
+        align: left;
+    }
+
+    #Asset-Create-basics>table>tbody>tr>td {
+        padding-right: 2em;
+    }
+
+    #Asset-Create-basics>table>tbody>tr {
+        vertical-align: top;
+    }
+}
+
+/* basic cleanups for the search UI's elements */
+.asset-search-grouping input.datepicker {
+    width: 7em;
+}
+
+.asset-search-grouping td * {
+    max-width: 11em;
+}
+
+.asset-search-grouping td.label.not {
+    min-width: 3em;
+    width: auto;
+    padding-left: 1em;
+}
+
+/* On a wide screen, use two columns for search/bulk criteria */
+ at media (min-width:1150px) {
+    .asset-bulk-grouping.asset-bulk-cfs,
+    .asset-search-grouping.asset-search-cfs {
+        display: inline-block;
+        width: 45%;
+        padding-right: 1em;
+        vertical-align: top;
+    }
+
+    .titlebox.asset-bulk-grouping.asset-bulk-cfs,
+    .titlebox.asset-search-grouping.asset-search-cfs {
+        display: block;
+        width: auto;
+        padding: inherit;
+    }
+
+    .asset-bulk-people tr.full-width,
+    .asset-search-people tr.ful-width,
+    .asset-bulk-basics tr.full-width,
+    .asset-search-basics tr.full-width {
+        width: 100%;
+    }
+
+    .asset-bulk-people tr,
+    .asset-search-people tr,
+    .asset-bulk-basics tr,
+    .asset-search-basics tr {
+        width: 49%;
+        display: inline-block;
+        white-space: nowrap;
+    }
+
+    .asset-bulk-people tr>td,
+    .asset-search-people tr>td,
+    .asset-bulk-basics tr>td,
+    .asset-search-basics tr>td {
+        display: inline-block;
+        width: 10em;
+    }
+}
diff --git a/share/static/js/assets.js b/share/static/js/assets.js
new file mode 100644
index 0000000..853ba86
--- /dev/null
+++ b/share/static/js/assets.js
@@ -0,0 +1,44 @@
+jQuery(function() {
+    var showModal = function(html) {
+        jQuery("<div class='modal'></div>")
+            .append(html).appendTo("body")
+            .bind('modal:close', function(ev,modal) { modal.elm.remove(); })
+            .modal();
+    };
+
+    var assets = jQuery("#assets-accordion");
+    assets.accordion({
+        // Open the accordion if there's only one fold, otherwise start with
+        // all assets collapsed.
+        active:         assets.find("h3").length == 1 ? 0 : false,
+        collapsible:    true,
+        heightStyle:    'content',
+        header: "h3"
+    }).find("h3 a.unlink-asset").click(function(ev){
+        ev.stopPropagation();
+        return true;
+    });
+    jQuery(".ticket-assets form").submit(function(){
+        var input = jQuery("[name*=RefersTo]", this);
+        if (input.val())
+            input.val(input.val().match(/\S+/g)
+                                 .map(function(x){return "asset:"+x})
+                                 .join(" "));
+    });
+    jQuery("#page-actions-create-linked-ticket").click(function(ev){
+        ev.preventDefault();
+        var url = this.href.replace(/\/Asset\/CreateLinkedTicket\.html\?/g,
+                                    '/Asset/Helpers/CreateLinkedTicket?');
+        jQuery.get(
+            url,
+            showModal
+        );
+    });
+    jQuery("#assets-create").click(function(ev){
+        ev.preventDefault();
+        jQuery.get(
+            RT.Config.WebHomePath + "/Asset/Helpers/CreateInCatalog",
+            showModal
+        );
+    });
+});

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


More information about the rt-commit mailing list