Skip to content

Commit

Permalink
Merge branch 'hotfix-1.15.3' into hotfix-1.16.1
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonhendee committed Oct 5, 2023
2 parents f644ced + f8972f0 commit 337a7e9
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 42 deletions.
5 changes: 3 additions & 2 deletions RockWeb/Blocks/Engagement/SignUp/SignUpDetail.ascx
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@
<Rock:RockBoundField DataField="FriendlyDateTime" HeaderText="Date/Time" />
<Rock:RockBoundField DataField="FriendlyLocation" HeaderText="Location" />
<Rock:RockBoundField DataField="ProgressBar" HeaderText="Sign-Ups" ItemStyle-CssClass="progress-sign-ups-cell align-middle" HtmlEncode="false" />
<Rock:LinkButtonField ID="lbOpportunityDetail" Text="<i class='fa fa-users'></i>" CssClass="btn btn-default btn-sm btn-square" OnClick="lbOpportunityDetail_Click" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center" />
<Rock:LinkButtonField ID="lbOpportunityDetail" Text="<i class='fa fa-users'></i>" ToolTip="Attendee List" CssClass="btn btn-default btn-sm btn-square" OnClick="lbOpportunityDetail_Click" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center" />
<Rock:EditField ID="efOpportunities" OnClick="gOpportunities_Edit" />
<Rock:DeleteField ID="dfOpportunities" OnClick="gOpportunities_Delete" />
</Columns>
Expand Down Expand Up @@ -377,7 +377,8 @@
var opportunityConfirmMessage = 'Are you sure you want to delete this Opportunity?';
if ($row.hasClass('js-has-participants')) {
var participantCount = parseInt($row.find('.js-slots-filled').html());
var $progressBar = $row.find('.js-progress-sign-ups');
var participantCount = parseInt($progressBar.attr('data-slots-filled'));
participantLabel = participantCount > 1
? 'participants'
: 'participant';
Expand Down
58 changes: 42 additions & 16 deletions RockWeb/Blocks/Engagement/SignUp/SignUpDetail.ascx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ private static class ViewStateKey
public const string GroupTypeId = "GroupTypeId";
public const string GroupRequirementsState = "GroupRequirementsState";
public const string IsAuthorizedToEdit = "IsAuthorizedToEdit";
public const string IsAuthorizedToSchedule = "IsAuthorizedToSchedule";
public const string IsProjectTypeInPerson = "IsProjectTypeInPerson";
public const string OpportunitiesState = "OpportunitiesState";
public const string ProjectName = "ProjectName";
Expand All @@ -106,6 +107,8 @@ private static class DataKeyName
#region Fields

private bool _canEdit;
private bool _canSchedule;

private bool _isProjectTypeInPerson;

#endregion
Expand Down Expand Up @@ -294,7 +297,9 @@ protected override void LoadViewState( object savedState )
base.LoadViewState( savedState );

_canEdit = ( bool ) ViewState[ViewStateKey.IsAuthorizedToEdit];
gOpportunities.Actions.ShowAdd = _canEdit;

_canSchedule = ( bool ) ViewState[ViewStateKey.IsAuthorizedToSchedule];
gOpportunities.Actions.ShowAdd = _canSchedule;

_isProjectTypeInPerson = ( bool ) ViewState[ViewStateKey.IsProjectTypeInPerson];

Expand Down Expand Up @@ -428,6 +433,7 @@ protected void Block_BlockUpdated( object sender, EventArgs e )
protected override object SaveViewState()
{
ViewState[ViewStateKey.IsAuthorizedToEdit] = _canEdit;
ViewState[ViewStateKey.IsAuthorizedToSchedule] = _canSchedule;
ViewState[ViewStateKey.IsProjectTypeInPerson] = _isProjectTypeInPerson;

var jsonSetting = new JsonSerializerSettings
Expand Down Expand Up @@ -515,7 +521,7 @@ protected void btnSave_Click( object sender, EventArgs e )
else
{
group = groupService.Queryable()
.Include( g => g.ParentGroup ) // Parent group is needed to properly check for edit authorization.
.Include( g => g.ParentGroup ) // ParentGroup may be needed for a proper authorization check.
.Include( g => g.GroupRequirements )
.FirstOrDefault( g => g.Id == this.GroupId );

Expand Down Expand Up @@ -1013,7 +1019,7 @@ protected void gOpportunities_DataBinding( object sender, EventArgs e )
}
}

if ( !_canEdit )
if ( !_canSchedule )
{
var editField = gOpportunities.ColumnsOfType<EditField>().FirstOrDefault( c => c.ID == "efOpportunities" );
if ( editField != null )
Expand Down Expand Up @@ -1071,7 +1077,7 @@ protected void btnDelete_Click( object sender, EventArgs e )
{
var groupService = new GroupService( rockContext );
var group = groupService.Queryable()
.Include( g => g.ParentGroup ) // Parent group is needed to properly check for edit authorization.
.Include( g => g.ParentGroup ) // ParentGroup may be needed for a proper authorization check.
.FirstOrDefault( g => g.Id == this.GroupId );

if ( group == null )
Expand Down Expand Up @@ -1764,20 +1770,34 @@ private void ResetNotificationBoxes()
}

/// <summary>
/// Determines whether [is authorized to edit] [the specified group].
/// Determines whether the current person is authorized to edit the current project (group).
/// </summary>
/// <param name="group">The group.</param>
/// <returns>
/// <c>true</c> if [is authorized to edit] [the specified group]; otherwise, <c>false</c>.
/// Whether the current person is authorized to edit the current project (group).
/// </returns>
private bool IsAuthorizedToEdit( Group group )
{
_canEdit = IsUserAuthorized( Authorization.EDIT )
&& group?.IsSystem == false
&& group?.IsAuthorized( Authorization.EDIT, this.CurrentPerson ) == true;
_canEdit = group != null
&& !group.IsSystem
&& group.IsAuthorized( Authorization.EDIT, this.CurrentPerson );

return _canEdit;
}

/// <summary>
/// Determines whether the current person is authorized to schedule (add/edit/delete) project opportunities.
/// </summary>
/// <param name="group">The group.</param>
/// <returns>Whether the current person is authorized to schedule (add/edit/delete) project opportunities.</returns>
private bool IsAuthorizedToSchedule( Group group )
{
_canSchedule = group != null
&& ( group.IsAuthorized( Authorization.EDIT, this.CurrentPerson ) || group.IsAuthorized( Authorization.SCHEDULE, this.CurrentPerson ) );

return _canSchedule;
}

/// <summary>
/// Shows the group not found message.
/// </summary>
Expand Down Expand Up @@ -2109,9 +2129,14 @@ private void ShowViewDetails( Group group, bool isReadOnly, RockContext rockCont

BindOpportunitiesGrid( group );

pnlActions.Visible = !isReadOnly;
var canAdministrate = group.IsAuthorized( Authorization.ADMINISTRATE, CurrentPerson );

pnlActions.Visible = !isReadOnly || canAdministrate;

btnEdit.Visible = !isReadOnly;
btnDelete.Visible = !isReadOnly;

btnSecurity.Visible = group.IsAuthorized( Authorization.ADMINISTRATE, CurrentPerson );
btnSecurity.Visible = canAdministrate;
btnSecurity.EntityId = group.Id;
}

Expand Down Expand Up @@ -2718,7 +2743,7 @@ string GetIndicator( int percentage, bool isMax = false )
<div class=""indicator"" style=""left: {percentage}%;""></div>";
}

return $@"<div class=""progress progress-sign-ups text-{progressState} m-0 flex-fill js-progress-sign-ups"" role=""progressbar"" title=""{ProgressBarTooltip.EncodeHtml()}"" aria-label=""Sign-Ups Progress"">
return $@"<div class=""progress progress-sign-ups text-{progressState} m-0 flex-fill js-progress-sign-ups"" role=""progressbar"" title=""{ProgressBarTooltip.EncodeHtml()}"" aria-label=""Sign-Ups Progress"" data-slots-filled=""{filled}"">
<div class=""progress-bar progress-bar-sign-ups bg-{progressState}"" style=""width: {filledPercentage}%""></div>{GetIndicator( minPercentage )}{GetIndicator( desiredPercentage )}{GetIndicator( maxPercentage, true )}
</div>";
}
Expand Down Expand Up @@ -2759,6 +2784,7 @@ private void BindOpportunitiesGrid( Group group = null, bool shouldForceRefresh
.Queryable()
.AsNoTracking()
.Include( g => g.Campus )
.Include( g => g.ParentGroup ) // ParentGroup may be needed for a proper authorization check.
.FirstOrDefault( g => g.Id == this.GroupId );

if ( shouldForceRefresh || this.OpportunitiesState?.Any() != true )
Expand Down Expand Up @@ -2824,13 +2850,13 @@ private void BindOpportunitiesGrid( Group group = null, bool shouldForceRefresh
}
}
var particpantCount = participantCounts.FirstOrDefault( c =>
var participantCount = participantCounts.FirstOrDefault( c =>
c.GroupId == gls.Group.Id
&& c.LocationId == gls.Location.Id
&& c.ScheduleId == gls.Schedule.Id
)?.Count ?? 0;
totalParticipantCount += particpantCount;
totalParticipantCount += participantCount;
return new Opportunity
{
Expand All @@ -2846,7 +2872,7 @@ private void BindOpportunitiesGrid( Group group = null, bool shouldForceRefresh
SlotsMin = gls.Config?.MinimumCapacity,
SlotsDesired = gls.Config?.DesiredCapacity,
SlotsMax = gls.Config?.MaximumCapacity,
SlotsFilled = particpantCount,
SlotsFilled = participantCount,
ReminderAdditionalDetails = gls.Config?.ReminderAdditionalDetails,
ConfirmationAdditionalDetails = gls.Config?.ConfirmationAdditionalDetails
};
Expand Down Expand Up @@ -2880,7 +2906,7 @@ private void BindOpportunitiesGrid( Group group = null, bool shouldForceRefresh
}

gOpportunities.RowItemText = timeframe == OpportunityTimeframe.Upcoming ? "Upcoming Opportunity" : "Past Opportunity";
gOpportunities.Actions.ShowAdd = IsAuthorizedToEdit( group );
gOpportunities.Actions.ShowAdd = IsAuthorizedToSchedule( group );

var nameColumn = gOpportunities.ColumnsOfType<RockBoundField>().FirstOrDefault( c => c.DataField == "Name" );
if ( nameColumn != null )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private static class DataKeyName
private int _scheduleId;

private bool _canView;
private bool _canEdit;
private bool _canManageMembers;

private GroupTypeCache _groupTypeCache;

Expand Down Expand Up @@ -221,9 +221,9 @@ protected override void OnInit( EventArgs e )
if ( group != null )
{
_canView = group.IsAuthorized( Authorization.VIEW, this.CurrentPerson );
_canEdit = IsUserAuthorized( Authorization.EDIT )
|| group.IsAuthorized( Authorization.EDIT, this.CurrentPerson )
|| group.IsAuthorized( Authorization.MANAGE_MEMBERS, this.CurrentPerson );
_canManageMembers = group.IsAuthorized( Authorization.EDIT, this.CurrentPerson )
|| group.IsAuthorized( Authorization.MANAGE_MEMBERS, this.CurrentPerson )
|| group.IsAuthorized( Authorization.SCHEDULE, this.CurrentPerson );

InitializeGrid( group );
}
Expand Down Expand Up @@ -687,7 +687,7 @@ private Group GetSharedGroup( RockContext rockContext )
.Include( g => g.Campus )
.Include( g => g.GroupSyncs )
.Include( g => g.GroupType )
.Include( g => g.ParentGroup )
.Include( g => g.ParentGroup ) // ParentGroup may be needed for a proper authorization check.
.FirstOrDefault( g => g.Id == _groupId );

RockPage.SaveSharedItem( key, group );
Expand Down Expand Up @@ -731,8 +731,8 @@ private void InitializeGrid( Group group )
// we'll have custom JavaScript (see SignUpOpportunityAttendeeList.ascx ) do this instead.
gAttendees.ShowConfirmDeleteDialog = false;

gAttendees.Actions.ShowAdd = _canEdit;
gAttendees.IsDeleteEnabled = _canEdit;
gAttendees.Actions.ShowAdd = _canManageMembers;
gAttendees.IsDeleteEnabled = _canManageMembers;

AddGridRowButtons();

Expand Down
21 changes: 18 additions & 3 deletions RockWeb/Blocks/Engagement/SignUp/SignUpOverview.ascx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<ContentTemplate>
<Rock:ModalAlert ID="mdSignUpOverview" runat="server" />

<Rock:NotificationBox ID="nbNotAuthorizedToDelete" runat="server" NotificationBoxType="Warning" Visible="false" Text="You are not authorized to delete this Sign-Up Opportunity." />

<asp:Panel ID="pnlDetails" runat="server">
<asp:HiddenField ID="hfAction" runat="server" />
<div class="panel panel-block">
Expand Down Expand Up @@ -33,7 +35,7 @@
<Rock:RockBoundField DataField="FriendlySchedule" HeaderText="Schedule" SortExpression="NextOrLastStartDateTime" ExcelExportBehavior="AlwaysInclude" />
<Rock:RockBoundField DataField="LeaderCount" HeaderText="Leader Count" SortExpression="LeaderCount" ExcelExportBehavior="AlwaysInclude" />
<Rock:RockLiteralField ID="lParticipantCountBadgeHtml" HeaderText="Participant Count" SortExpression="ParticipantCount" ExcelExportBehavior="NeverInclude" />
<Rock:LinkButtonField ID="lbOpportunityDetail" Text="<i class='fa fa-users'></i>" CssClass="btn btn-default btn-sm btn-square" OnClick="lbOpportunityDetail_Click" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center" />
<Rock:LinkButtonField ID="lbOpportunityDetail" Text="<i class='fa fa-users'></i>" ToolTip="Attendee List" CssClass="btn btn-default btn-sm btn-square" OnClick="lbOpportunityDetail_Click" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center" />
<Rock:DeleteField ID="dfOpportunities" OnClick="dfOpportunities_Click" />

<%-- Fields that are only shown when exporting --%>
Expand All @@ -51,8 +53,21 @@
Sys.Application.add_load(function () {
var $thisBlock = $('#<%= upnlSignUpOverview.ClientID %>');
// delete prompt
$thisBlock.find('table.js-grid-opportunities a.grid-delete-button').on('click', function (e) {
// Get all delete buttons.
var $deleteButtons = $thisBlock.find('table.js-grid-opportunities a.grid-delete-button');
// Disable any buttons whose rows indicate deleting is not allowed.
$deleteButtons.each(function () {
var $btn = $(this);
var $row = $btn.closest('tr');
if ($row.hasClass('js-cannot-delete')) {
$btn.addClass('disabled');
}
});
// Custom delete prompt.
$deleteButtons.on('click', function (e) {
var $btn = $(this);
var $row = $btn.closest('tr');
Expand Down

0 comments on commit 337a7e9

Please sign in to comment.