%# BEGIN BPS TAGGED BLOCK {{{ %# %# COPYRIGHT: %# %# This software is Copyright (c) 1996-2024 Best Practical Solutions, LLC %# %# %# (Except where explicitly superseded by other copyright notices) %# %# %# LICENSE: %# %# This work is made available to you under the terms of Version 2 of %# the GNU General Public License. A copy of that license should have %# been provided with this software, but in any event can be snarfed %# from www.gnu.org. %# %# This work is distributed in the hope that it will be useful, but %# WITHOUT ANY WARRANTY; without even the implied warranty of %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU %# General Public License for more details. %# %# You should have received a copy of the GNU General Public License %# along with this program; if not, write to the Free Software %# 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 &>
% use List::MoreUtils 'uniq'; % foreach my $var ( uniq @{$search{'PassArguments'}}, qw(Query Format OrderBy Order Rows Page Token) ) { % } <& /Elements/CollectionList, %search, Collection => $assets, AllowSorting => 1, DisplayFormat => $DisplayFormat, InlineEdit => 0, &> % if (not $assets->Count) { <&|/l&>No assets matching search criteria found. % }
<& /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" &>
<&| /Elements/LabeledValue, Label => loc('Catalog') &> <& /Asset/Elements/SelectCatalog, Name => 'UpdateCatalog', UpdateSession => 0, ShowNullOption => 1 &>
<&| /Elements/LabeledValue, Label => loc('Name') &>
<&| /Elements/LabeledValue, Label => loc('Description') &>
<&| /Elements/LabeledValue, Label => loc('Status') &> <& /Asset/Elements/SelectStatus, Name => 'UpdateStatus', DefaultValue => 1 &>
% my $basic_cfs = $cfs->Clone; % $basic_cfs->LimitToGrouping( 'RT::Asset' => 'Basics'); % if ( $basic_cfs->Count ) { <& /Elements/BulkCustomFields, CustomFields => $basic_cfs, &> % } <&| /Widgets/TitleBox, title => loc("People"), class => "asset-people asset-bulk-people", title_class => "inverse" &> % for my $rname ( $asset->Roles( ACLOnly => 0, Single => 1 ), map { $_->GroupType } @{ $single_roles->ItemsArrayRef } ) { % my $input = "SetRoleMember-$rname";
<&| /Elements/LabeledValue, Label => RT::Asset->LabelForRole($rname) &>
% } % for my $rname ( $asset->Roles( ACLOnly => 0, Single => 0 ), map { $_->GroupType } @{ $multi_roles->ItemsArrayRef } ) { % my $input = "AddRoleMember-$rname";
<&| /Elements/LabeledValue, Label => loc("Add [_1]", RT::Asset->LabelForRole($rname)) &>
% $input = "RemoveRoleMember-$rname";
<&| /Elements/LabeledValue, Label => loc("Remove [_1]", RT::Asset->LabelForRole($rname)) &>
% } % my $people_cfs = $cfs->Clone; % $people_cfs->LimitToGrouping( 'RT::Asset' => 'People'); % if ( $people_cfs->Count ) { <& /Elements/BulkCustomFields, CustomFields => $people_cfs, &> % } % my $date_cfs = $cfs->Clone; % $date_cfs->LimitToGrouping( 'RT::Asset' => 'Dates'); % if ( $date_cfs->Count ) { <&| /Widgets/TitleBox, title => loc("Dates"), class => "asset-dates asset-bulk-dates", title_class => "inverse" &> <& /Elements/BulkCustomFields, CustomFields => $date_cfs, &> % } % for my $group ( RT::CustomField->CustomGroupings( 'RT::Asset' ), '' ) { % my $group_cfs = $cfs->Clone; % $group_cfs->LimitToGrouping( 'RT::Asset' => $group); % if ( $group_cfs->Count ) { <&| /Widgets/TitleBox, class=>'asset-bulk-grouping asset-info-cfs asset-bulk-cfs', title => loc('Edit [_1]', ($group? loc($group) : loc('Custom Fields')) ), title_class => "inverse" &> <& /Elements/BulkCustomFields, CustomFields => $group_cfs, &> % } % } <&|/Widgets/TitleBox, title => loc('Edit Links'), class => "asset-links asset-bulk-links", title_class => "inverse" &> <& /Elements/BulkLinks, Collection => $assets, %ARGS &> % my $link_cfs = $cfs->Clone; % $link_cfs->LimitToGrouping( 'RT::Asset' => 'Links'); % if ( $cfs->Count ) { <& /Elements/BulkCustomFields, CustomFields => $link_cfs, &> % }
<& /Elements/Submit, Label => loc('Update'), Name => 'Update' &>
<%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; if ( $ARGS{Query} ) { $assets->FromSQL($ARGS{Query}); } else { %search = ProcessAssetsSearchArguments( Assets => $assets, Catalog => $catalog_obj, ARGSRef => \%ARGS, ); } $search{Format} ||= RT->Config->Get('AssetDefaultSearchResultFormat'); my $DisplayFormat = "'__CheckBox.{UpdateAsset}__',". ($ARGS{Format} || $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; my $cfs; my $single_roles = RT::CustomRoles->new( $session{CurrentUser} ); my $multi_roles = RT::CustomRoles->new( $session{CurrentUser} ); if ( $ARGS{Query} ) { $cfs = RT::CustomFields->new( $session{'CurrentUser'} ); $cfs->LimitToLookupType( RT::Asset->CustomFieldLookupType ); my $tree = RT::Interface::Web::QueryBuilder::Tree->new; $tree->ParseSQL( Class => 'RT::Assets', Query => $ARGS{Query}, CurrentUser => $session{CurrentUser}, ); my $catalogs = $tree->GetReferencedCatalogs; my @ids; for my $name ( keys %$catalogs ) { my $catalog = RT::Catalog->new( $session{CurrentUser} ); $catalog->Load($name); if ( $catalog->Id ) { push @ids, $catalog->Id; $cfs->SetContextObject($catalog) if keys %$catalogs == 1; } else { RT->Logger->warning("Couldn't load catalog $name"); } } $cfs->LimitToGlobalOrObjectId(@ids); if ( @ids ) { $single_roles->LimitToObjectId($_) for @ids; $multi_roles->LimitToObjectId($_) for @ids; } } else { $cfs = $catalog_obj->AssetCustomFields; $single_roles->LimitToObjectId( $catalog_obj->Id ); $multi_roles->LimitToObjectId( $catalog_obj->Id ); } if ( $single_roles->_isLimited ) { $single_roles->LimitToLookupType( RT::Asset->CustomFieldLookupType ); $single_roles->LimitToSingleValue; } if ( $multi_roles->_isLimited ) { $multi_roles->LimitToLookupType( RT::Asset->CustomFieldLookupType ); $multi_roles->LimitToMultipleValue; } if ( $ARGS{'CreateLinkedTicket'} ){ my $url = RT->Config->Get('WebURL') . "Asset/CreateLinkedTicket.html"; $url .= '?'. $m->comp( '/Elements/QueryString', 'Assets' => \@UpdateAsset ); RT::Interface::Web::Redirect($url); } elsif ( $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, ProcessAssetRoleMembers( $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 ); my $prefix = loc('Asset') . ' ' . $asset->Id . ': '; push @results, map { /^$prefix/ ? $_ : loc( "Asset [_1]: [_2]", $asset->id, $_ ) } @tmp_res; } MaybeRedirectForResults( Actions => \@results, Arguments => { map { $_ => $ARGS{$_} } grep { defined $ARGS{$_} } @{$search{'PassArguments'}}, qw(Query Format OrderBy Order Rows Page Token) }, ); } <%ARGS> @UpdateAsset => ()