diff options
author | Dianne Skoll <dianne@bestpractical.com> | 2020-12-29 19:38:44 +0300 |
---|---|---|
committer | Dianne Skoll <dianne@bestpractical.com> | 2020-12-29 19:38:44 +0300 |
commit | b0c2b271a3ecca228e5021db05e2e65ba535c984 (patch) | |
tree | 8fa269fa86600f6b802e8dbd20ee495105ebb18b | |
parent | f27628549c754235e4615a1c3772496790d8d7c1 (diff) |
Remove modal class selection for creating articles.5.0/remove-modal-selector-for-article-class
Instead, the article Class is chosen similarly to how Queue is chosen
for Tickets or Catalog is chosen for Assets: There is a pulldown
selection element in the create/edit page. Updating this refreshes
the page so the appropriate custom fields are presented for editing.
-rw-r--r-- | lib/RT/Interface/Web/MenuBuilder.pm | 2 | ||||
-rw-r--r-- | share/html/Articles/Article/Edit.html | 205 | ||||
-rw-r--r-- | share/html/Articles/Article/Elements/EditBasics | 4 | ||||
-rw-r--r-- | share/html/Articles/Article/Elements/EditCustomFields | 3 | ||||
-rw-r--r-- | share/html/Articles/Article/PreCreate.html | 83 | ||||
-rw-r--r-- | share/html/Articles/Elements/CreateArticleButton | 4 | ||||
-rw-r--r-- | share/html/Articles/Elements/SelectClass | 4 |
7 files changed, 126 insertions, 179 deletions
diff --git a/lib/RT/Interface/Web/MenuBuilder.pm b/lib/RT/Interface/Web/MenuBuilder.pm index c93e0d92c0..179ce821b8 100644 --- a/lib/RT/Interface/Web/MenuBuilder.pm +++ b/lib/RT/Interface/Web/MenuBuilder.pm @@ -233,7 +233,7 @@ sub BuildMainNav { my $articles = $top->child( articles => title => loc('Articles'), path => "/Articles/index.html"); $articles->child( articles => title => loc('Overview'), path => "/Articles/index.html" ); $articles->child( topics => title => loc('Topics'), path => "/Articles/Topics.html" ); - $articles->child( create => title => loc('Create'), path => "/Articles/Article/PreCreate.html" ); + $articles->child( create => title => loc('Create'), path => "/Articles/Article/Edit.html" ); $articles->child( search => title => loc('Search'), path => "/Articles/Article/Search.html" ); } diff --git a/share/html/Articles/Article/Edit.html b/share/html/Articles/Article/Edit.html index d22f554341..d2fdea6398 100644 --- a/share/html/Articles/Article/Edit.html +++ b/share/html/Articles/Article/Edit.html @@ -52,11 +52,14 @@ <form method="post" action="Edit.html" name="EditArticle" id="EditArticle" enctype="multipart/form-data"> <input type="hidden" name="next" value="<%$ARGS{next}||''%>" /> <input type="hidden" name="id" value="<%$id%>" /> +<input type="hidden" name="ClassChanged" value="0" /> <&| /Widgets/TitleBox, title => $title, class => 'article-basics', &> <& Elements/EditBasics, ArticleObj => $ArticleObj, - EditClass =>$EditClass, + EditClass => 1, + DefaultClass => $DefaultClass, ClassObj => $ClassObj, + OnClassChange => "jQuery(this).closest('form').find('input[name=ClassChanged]').val(1);jQuery(this).closest('form').submit();", %ARGS , id => $id &> @@ -66,6 +69,7 @@ <& Elements/EditCustomFields, ArticleObj => $ArticleObj, CFContent => \%CFContent, ClassObj => $ClassObj, + ClassChanged => $ARGS{ClassChanged}, %ARGS, id => $id, ForCreation => ($id eq 'new'), @@ -90,7 +94,7 @@ <div class="form-row"> <div class="col-12"> - <& /Elements/Submit, Label => ($id eq 'new' ? loc('Create') : loc('Save Changes')), color => "#993333" &> + <& /Elements/Submit, Label => ($id eq 'new' ? loc('Create') : loc('Save Changes')) &> </div> </div> </form> @@ -108,15 +112,30 @@ my $title; my $Entries = {}; my $ArticleObj = RT::Article->new( $session{'CurrentUser'} ); my $ClassObj = RT::Class->new( $session{'CurrentUser'} ); +my $DefaultClass; + +$Class ||= $ARGS{Class}; if ($Class) { $ClassObj->Load($Class); Abort(loc("'[_1]' isn't a valid class", $Class)) unless $ClassObj->Id; + $DefaultClass = $ClassObj->Id; +} + +# If we don't have a class, default to the first class that user can +# see and in which user can create articles +if (!$DefaultClass) { + my $Classes = RT::Classes->new($session{'CurrentUser'}); + $Classes->LimitToEnabled(); + while (my $class = $Classes->Next) { + next unless ($class->Name); + $DefaultClass = $class->Id; + last; + } } my %create_args; my %CFContent; -my $EditClass = 1; if ( $ARGS{SetEnabled} ) { $ARGS{Disabled} = $ARGS{Enabled} ? 0 : 1; @@ -140,8 +159,6 @@ if ( !$id ) { $CFContent{ $ARGS{$arg} } .= $trans->Content; } } - - $EditClass = 0; $id = 'new'; } elsif ( $id eq 'new' ) { @@ -157,24 +174,28 @@ elsif ( $id eq 'new' ) { } my %cfs; - if ($sortorder_ok) { - %cfs = ProcessObjectCustomFieldUpdatesForCreate( - ARGSRef => \%ARGS, - ContextObject => $ClassObj, - ); - - my $msg; - ( $id, $msg ) = $ArticleObj->Create( - Summary => $ARGS{'Summary'}, - Name => $ARGS{'Name'}, - SortOrder => $ARGS{'SortOrder'}, - Class => $ARGS{'Class'}, - Topics => $ARGS{'Topics'}, - Disabled => $ARGS{'Disabled'}, - %create_args, - %cfs - ); - push( @results, $msg ); + if (!$ARGS{ClassChanged}) { + if ($sortorder_ok) { + %cfs = ProcessObjectCustomFieldUpdatesForCreate( + ARGSRef => \%ARGS, + ContextObject => $ClassObj, + ); + + my $msg; + ( $id, $msg ) = $ArticleObj->Create( + Summary => $ARGS{'Summary'}, + Name => $ARGS{'Name'}, + SortOrder => $ARGS{'SortOrder'}, + Class => $ARGS{'Class'}, + Topics => $ARGS{'Topics'}, + Disabled => $ARGS{'Disabled'}, + %create_args, + %cfs + ); + push( @results, $msg ); + } else { + $id = 0; + } } else { $id = 0; } @@ -182,7 +203,7 @@ elsif ( $id eq 'new' ) { if ($id) { $ArticleObj->Load($id); - $title = loc( 'Modify article #[_1]', $ArticleObj->Id ); + $title = loc( 'Modify article #[_1]', $id ); delete $ARGS{id}; if ( $ARGS{next} ) { @@ -191,103 +212,105 @@ elsif ( $id eq 'new' ) { else { MaybeRedirectForResults( Actions => \@results, - Arguments => { id => $ArticleObj->id }, + Arguments => { id => $id }, ); } } else { $ArticleObj = RT::Article->new( $session{'CurrentUser'} ); $id = 'new'; - $EditClass = 0; $title = loc('Create a new article'); } } else { - $ArticleObj->Load($id); - unless ( $ArticleObj->id ) { - $m->comp( "/Elements/Error", - Why => loc("Unable to load article") ); - } - my @attribs = qw(Name Summary Class Disabled SortOrder); - if ($sortorder_ok) { - @results = UpdateRecordObject( - AttributesRef => \@attribs, - Object => $ArticleObj, - ARGSRef => \%ARGS - ); - } + # If it was a real submit, make changes. + # If it was just a reload to change the Class, don't make changes. + $ArticleObj->Load($id); + if (!$ARGS{ClassChanged}) { + unless ( $ArticleObj->id ) { + $m->comp( "/Elements/Error", + Why => loc("Unable to load article") ); + } + if ($sortorder_ok) { + @results = UpdateRecordObject( + AttributesRef => \@attribs, + Object => $ArticleObj, + ARGSRef => \%ARGS + ); + } - my @cf_results = ProcessObjectCustomFieldUpdates( - Object => $ArticleObj, - ARGSRef => \%ARGS - ); - @results = ( @results, @cf_results ); - - # Delete links that are gone gone gone. - foreach my $arg ( keys %ARGS ) { - if ( $arg =~ /DeleteLink-(.*?)-(RefersTo|MemberOf|RefersTo)-(.*)$/ ) { - my $base = $1; - my $type = $2; - my $target = $3; - - my ( $val, $msg ) = $ArticleObj->DeleteLink( - Base => $base, - Type => $type, - Target => $target + my @cf_results = ProcessObjectCustomFieldUpdates( + Object => $ArticleObj, + ARGSRef => \%ARGS ); + @results = ( @results, @cf_results ); + $DefaultClass = $ArticleObj->ClassObj->Id; + + # Delete links that are gone gone gone. + foreach my $arg ( keys %ARGS ) { + if ( $arg =~ /DeleteLink-(.*?)-(RefersTo|MemberOf|RefersTo)-(.*)$/ ) { + my $base = $1; + my $type = $2; + my $target = $3; + + my ( $val, $msg ) = $ArticleObj->DeleteLink( + Base => $base, + Type => $type, + Target => $target + ); - push @results, $msg; + push @results, $msg; + } } - } + my @linktypes = qw(DependsOn MemberOf RefersTo ); - my @linktypes = qw(DependsOn MemberOf RefersTo ); + foreach my $linktype (@linktypes) { - foreach my $linktype (@linktypes) { + for my $luri ( split( / /, ( $ARGS{ $ArticleObj->Id . "-$linktype" } || '' )) ) { + $luri =~ s/\s*$//; # Strip trailing whitespace + my ( $val, $msg ) = + $ArticleObj->AddLink( Target => $luri, Type => $linktype ); + push @results, $msg; + delete $ARGS{ $ArticleObj->Id . "-$linktype" } if $val; + } - for my $luri ( split( / /, ( $ARGS{ $ArticleObj->Id . "-$linktype" } || '' )) ) { - $luri =~ s/\s*$//; # Strip trailing whitespace - my ( $val, $msg ) = - $ArticleObj->AddLink( Target => $luri, Type => $linktype ); - push @results, $msg; - delete $ARGS{ $ArticleObj->Id . "-$linktype" } if $val; - } + for my $luri ( split( / /, ( $ARGS{ "$linktype-" . $ArticleObj->Id } || '' )) ) { + my ( $val, $msg ) = + $ArticleObj->AddLink( Base => $luri, Type => $linktype ); + push @results, $msg; + delete $ARGS{ "$linktype-" . $ArticleObj->Id } if $val; + } - for my $luri ( split( / /, ( $ARGS{ "$linktype-" . $ArticleObj->Id } || '' )) ) { - my ( $val, $msg ) = - $ArticleObj->AddLink( Base => $luri, Type => $linktype ); - push @results, $msg; - delete $ARGS{ "$linktype-" . $ArticleObj->Id } if $val; } - } - - my %topics; - if ( $ARGS{'EditTopics'} ) { - $topics{$_}++ for @{ $ARGS{'Topics'} }; - my $objTopics = - RT::ObjectTopics->new( $session{'CurrentUser'} ); - $objTopics->LimitToObject($ArticleObj); - while ( my $t = $objTopics->Next ) { - $topics{ $t->Topic }--; - } - for my $id ( keys %topics ) { - if ( $topics{$id} > 0 ) { - my ( $val, $msg ) = $ArticleObj->AddTopic( Topic => $id ); - push @results, $msg; + my %topics; + if ( $ARGS{'EditTopics'} ) { + $topics{$_}++ for @{ $ARGS{'Topics'} }; + my $objTopics = + RT::ObjectTopics->new( $session{'CurrentUser'} ); + $objTopics->LimitToObject($ArticleObj); + while ( my $t = $objTopics->Next ) { + $topics{ $t->Topic }--; } - elsif ( $topics{$id} < 0 ) { - my ( $val, $msg ) = $ArticleObj->DeleteTopic( Topic => $id ); - push @results, $msg; + for my $topic_id ( keys %topics ) { + if ( $topics{$topic_id} > 0 ) { + my ( $val, $msg ) = $ArticleObj->AddTopic( Topic => $topic_id ); + push @results, $msg; + } + elsif ( $topics{$topic_id} < 0 ) { + my ( $val, $msg ) = $ArticleObj->DeleteTopic( Topic => $topic_id ); + push @results, $msg; + } } } } - $title = loc( 'Modify article #[_1]', $ArticleObj->Id ); + $title = loc( 'Modify article #[_1]', $id ); } # if they're working on an existing article diff --git a/share/html/Articles/Article/Elements/EditBasics b/share/html/Articles/Article/Elements/EditBasics index b6dcd70dbf..747ddd0bf7 100644 --- a/share/html/Articles/Article/Elements/EditBasics +++ b/share/html/Articles/Article/Elements/EditBasics @@ -75,7 +75,7 @@ </div> <div class="value col-9"> % if ($EditClass) { -<& /Articles/Elements/SelectClass, Name => 'Class', Default =>$ArticleObj->ClassObj->Id&> +<& /Articles/Elements/SelectClass, Name => 'Class', Default => $DefaultClass || $ArticleObj->ClassObj->Id, ShowAllClasses => 0, ShowNullOption => 0, OnChange => $OnClassChange &> % } else { <span class="current-value form-control"><%$ClassObj->Name%></span> <input type="hidden" name="Class" value="<%$ClassObj->Id%>" /> @@ -124,6 +124,8 @@ </%INIT> <%ARGS> $EditClass => 1 +$DefaultClass => undef $ClassObj => undef $ArticleObj => undef +$OnClassChange => undef </%ARGS> diff --git a/share/html/Articles/Article/Elements/EditCustomFields b/share/html/Articles/Article/Elements/EditCustomFields index 5582623a84..4e3e0cdb3e 100644 --- a/share/html/Articles/Article/Elements/EditCustomFields +++ b/share/html/Articles/Article/Elements/EditCustomFields @@ -67,7 +67,7 @@ <%INIT> my $CustomFields; -if ($ArticleObj->id && $ArticleObj->ClassObj->id) { +if ($ArticleObj->id && $ArticleObj->ClassObj->id && !$ClassChanged) { $CustomFields = $ArticleObj->CustomFields(); } else { @@ -77,6 +77,7 @@ else { <%ARGS> $ArticleObj => undef $ClassObj => undef +$ClassChanged => undef $CFContent => undef $id => undef </%ARGS> diff --git a/share/html/Articles/Article/PreCreate.html b/share/html/Articles/Article/PreCreate.html deleted file mode 100644 index 01747e03a1..0000000000 --- a/share/html/Articles/Article/PreCreate.html +++ /dev/null @@ -1,83 +0,0 @@ -%# BEGIN BPS TAGGED BLOCK {{{ -%# -%# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2020 Best Practical Solutions, LLC -%# <sales@bestpractical.com> -%# -%# (Except where explicitly superseded by other copyright notices) -%# -%# -%# LICENSE: -%# -%# This work is made available to you under the terms of Version 2 of -%# the GNU General Public License. A copy of that license should have -%# been provided with this software, but in any event can be snarfed -%# from www.gnu.org. -%# -%# This work is distributed in the hope that it will be useful, but -%# WITHOUT ANY WARRANTY; without even the implied warranty of -%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -%# General Public License for more details. -%# -%# You should have received a copy of the GNU General Public License -%# along with this program; if not, write to the Free Software -%# 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 an article in class...') &> -<& /Elements/Tabs &> - -% if (not $classes_configured) { -<& /Articles/Elements/NeedsSetup &> -% } elsif (not @classes) { -<i><&|/l&>You don't have permission to create Articles in any Class</&></i> -% } else { -<ul> -% for my $Class (@classes) { -% my $qs = $m->comp("/Elements/QueryString", %ARGS, Class=> $Class->Id); -<li><a href="Edit.html?<% $qs|n %>"><&|/l, $Class->Name &>in class [_1]</&></a></li> -% } -</ul> -% } -<%init> -my $Classes = RT::Classes->new($session{'CurrentUser'}); -$Classes->LimitToEnabled(); - -# This is a COUNT(), which doesn't apply ACLs; as such, we don't display -# the warning if there are classes, but the user can't see them. -my $classes_configured = $Classes->Count; - -# ->Next applies SeeClass, but we also want to check CreateArticle -my @classes; -while (my $class = $Classes->Next) { - push @classes, $class if $class->CurrentUserHasRight("CreateArticle"); -} - -# If there is only one, redirect to it -MaybeRedirectForResults( - Path => "/Articles/Article/Edit.html", - Force => 1, - Arguments => { Class => $classes[0]->id }, -) if @classes == 1; -</%init> diff --git a/share/html/Articles/Elements/CreateArticleButton b/share/html/Articles/Elements/CreateArticleButton index 683b856a1f..dac38b027d 100644 --- a/share/html/Articles/Elements/CreateArticleButton +++ b/share/html/Articles/Elements/CreateArticleButton @@ -45,8 +45,8 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<form action="<% RT->Config->Get('WebPath') %>/Articles/Article/PreCreate.html"> +<form action="<% RT->Config->Get('WebPath') %>/Articles/Article/Edit.html"> <div class="create-article-button"> - <input type="submit" class="btn btn-primary article-create-modal" value="<&|/l&>Create new article</&>" /> + <input type="submit" class="btn btn-primary" value="<&|/l&>Create new article</&>" /> </div> </form> diff --git a/share/html/Articles/Elements/SelectClass b/share/html/Articles/Elements/SelectClass index da932141b8..997fe61b23 100644 --- a/share/html/Articles/Elements/SelectClass +++ b/share/html/Articles/Elements/SelectClass @@ -52,6 +52,9 @@ % if ($Multiple) { MULTIPLE % } +% if ($OnChange) { +onchange="<%$OnChange%>" +% } % if ($Size) { SIZE=<%$Size%> % } @@ -80,6 +83,7 @@ $Name => undef $Verbose => undef $Default => undef $Lite => 0 +$OnChange => undef </%ARGS> <%INIT> |