Skip to content

Commit 2ba64e2

Browse files
committed
- Add automated and manual workflow handling to BenevolenceRequestDetail
1 parent fd94c4e commit 2ba64e2

File tree

7 files changed

+223
-27
lines changed

7 files changed

+223
-27
lines changed

Rock.Blocks/Finance/BenevolenceRequestDetail.cs

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,7 @@ public class BenevolenceRequestDetail : RockEntityDetailBlockType<BenevolenceReq
125125

126126
#region Properties
127127

128-
#region Properties - Services
129-
128+
// Services
130129
private PersonAliasService PersonAliasService => new PersonAliasService( RockContext );
131130
private LocationService LocationService => new LocationService( RockContext );
132131
private CampusService CampusService => new CampusService( RockContext );
@@ -135,8 +134,6 @@ public class BenevolenceRequestDetail : RockEntityDetailBlockType<BenevolenceReq
135134
private BinaryFileService BinaryFileService => new BinaryFileService( RockContext );
136135
private BenevolenceRequestDocumentService BenevolenceRequestDocumentService => new BenevolenceRequestDocumentService( RockContext );
137136

138-
#endregion Properties - Services
139-
140137
#endregion Properties
141138

142139
#region Keys
@@ -158,8 +155,6 @@ private static class AttributeKey
158155
public const string EthnicityOption = "EthnicityOption";
159156
}
160157

161-
#region List Source
162-
163158
/// <summary>
164159
/// Provides a source of predefined list values used for configuration or validation purposes.
165160
/// </summary>
@@ -170,8 +165,6 @@ private static class ListSource
170165
public const string HIDE_OPTIONAL_REQUIRED = "Hide,Optional,Required";
171166
}
172167

173-
#endregion
174-
175168
/// <summary>
176169
/// Provides a collection of constant keys used for identifying page parameters.
177170
/// </summary>
@@ -493,10 +486,6 @@ protected override bool TryGetEntityForEditAction( string idKey, out Benevolence
493486
return true;
494487
}
495488

496-
#region Helper Methods
497-
498-
#region Helper Methods - Entity Update
499-
500489
/// <summary>
501490
/// Updates the properties of the requester in the specified <see cref="BenevolenceRequest"/> entity based on
502491
/// the provided <see cref="ValidPropertiesBox{T}"/> and a list of active country codes.
@@ -710,10 +699,6 @@ private void UpdateDetailProperties( BenevolenceRequest entity, ValidPropertiesB
710699
box.IfValidProperty( nameof( box.Bag.ProvidedNextSteps ), () => entity.ProvidedNextSteps = box.Bag.ProvidedNextSteps );
711700
}
712701

713-
#endregion Helper Methods - Entity Update
714-
715-
#region Helper Methods - Bag Construction
716-
717702
/// <summary>
718703
/// Gets the entity bag that is common between both view and edit modes.
719704
/// </summary>
@@ -732,6 +717,23 @@ private BenevolenceRequestBag GetCommonEntityBag( BenevolenceRequest entity )
732717
var caseWorkerPersonBag = BuildPersonBag( entity, entity.CaseWorkerPersonAliasId ?? 0, "", isRequester: false );
733718
var campus = BuildCampusBag( entity.CampusId ?? 0 );
734719

720+
// Add workflow info for frontend
721+
var workflows = GetAuthorizedManualWorkflows( entity )
722+
.Select( w => new BenevolenceRequestWorkflowBag
723+
{
724+
TypeId = w.WorkflowTypeId,
725+
TypeGuid = w.WorkflowType.Guid,
726+
TypeName = w.WorkflowType.Name,
727+
TriggerType = w.TriggerType,
728+
LaunchUrl = this.GetLinkedPageUrl( AttributeKey.WorkflowEntryPage, new Dictionary<string, string>
729+
{
730+
{ "WorkflowTypeId", w.WorkflowTypeId.ToString() },
731+
{ "BenevolenceRequestId", entity.IdKey }
732+
}),
733+
iconCssClass = w.WorkflowType.IconCssClass,
734+
})
735+
.ToList();
736+
735737
return new BenevolenceRequestBag
736738
{
737739
IdKey = entity.IdKey,
@@ -763,7 +765,8 @@ private BenevolenceRequestBag GetCommonEntityBag( BenevolenceRequest entity )
763765
FileName = document.BinaryFile.FileName,
764766
IsMarkedForDeletion = false
765767
} )
766-
.ToList()
768+
.ToList(),
769+
Workflows = workflows
767770
};
768771
}
769772

@@ -1269,10 +1272,6 @@ private LocationBag GetLocationBag( Location location )
12691272
};
12701273
}
12711274

1272-
#endregion Helper Methods - Bag Construction
1273-
1274-
#region Helper Methods - Person Creation
1275-
12761275
/// <summary>
12771276
/// Finds an existing person based on the provided information or creates a new person record if no match is
12781277
/// found.
@@ -1504,9 +1503,35 @@ private bool ValidatePhoneNumbers( List<PhoneNumberBag> phoneNumberBags, out str
15041503
return true;
15051504
}
15061505

1507-
#endregion Helper Methods - Person Creation
1506+
/// <summary>
1507+
/// Gets the authorized manual workflows for the given benevolence request.
1508+
/// </summary>
1509+
/// <param name="benevolenceRequest">The benevolence request.</param>
1510+
/// <returns>A list of authorized manual workflows.</returns>
1511+
private List<BenevolenceWorkflow> GetAuthorizedManualWorkflows( BenevolenceRequest benevolenceRequest )
1512+
{
1513+
if ( benevolenceRequest?.BenevolenceType == null )
1514+
{
1515+
return new List<BenevolenceWorkflow>();
1516+
}
1517+
1518+
var benevolenceWorkflows = benevolenceRequest.BenevolenceType.BenevolenceWorkflows;
1519+
var manualWorkflows = benevolenceWorkflows
1520+
.Where( w => w.TriggerType == BenevolenceWorkflowTriggerType.Manual && w.WorkflowType != null )
1521+
.OrderBy( w => w.WorkflowType.Name )
1522+
.Distinct();
15081523

1509-
#endregion Helper Methods
1524+
var authorizedWorkflows = new List<BenevolenceWorkflow>();
1525+
foreach ( var manualWorkflow in manualWorkflows )
1526+
{
1527+
if ( ( manualWorkflow.WorkflowType.IsActive ?? true ) && manualWorkflow.WorkflowType.IsAuthorized( Authorization.VIEW, RequestContext.CurrentPerson ) )
1528+
{
1529+
authorizedWorkflows.Add( manualWorkflow );
1530+
}
1531+
}
1532+
1533+
return authorizedWorkflows;
1534+
}
15101535

15111536
#endregion Methods
15121537

Rock.JavaScript.Obsidian.Blocks/src/Finance/BenevolenceRequestDetail/viewPanel.partial.obs

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,29 @@
4242
</div>
4343
</div>
4444

45-
<div v-if="hasRequestLavaTemplateDetails"
46-
class="row">
45+
<div v-if="hasAuthorizedManualWorkflows" class="row">
4746
<div class="col-md-12">
48-
{{ benevolenceRequestTypeLavaDetails }}
47+
<NotificationBox v-if="launchWorkflowError" alertType="danger" class="mt-2">
48+
<strong><i class="ti ti-exclamation-circle"></i> Error Launching Workflow</strong>
49+
<span>{{ launchWorkflowError }}</span>
50+
</NotificationBox>
51+
<dl>
52+
<dt>Available Workflows</dt>
53+
<dd>
54+
<RockButton v-for="workflow in authorizedManualWorkflows"
55+
class="m-1"
56+
:key="workflow.typeId"
57+
:btnType="BtnType.Default"
58+
:btnSize="BtnSize.ExtraSmall"
59+
@click="onWorkflowButtonClick(workflow.typeName, workflow.launchUrl)">
60+
<i :class="workflow.iconCssClass"></i> {{ workflow.typeName }}
61+
</RockButton>
62+
</dd>
63+
</dl>
4964
</div>
5065
</div>
66+
67+
<ValueDetailList :modelValue="contactInfoBottomValues" />
5168
</ContentStack>
5269
</ContentSection>
5370

@@ -129,6 +146,7 @@
129146
import HighlightLabel from "@Obsidian/Controls/highlightLabel.obs";
130147
import RockButton from "@Obsidian/Controls/rockButton.obs";
131148
import ValueDetailList from "@Obsidian/Controls/valueDetailList.obs";
149+
import NotificationBox from "@Obsidian/Controls/notificationBox.obs";
132150
import { BenevolenceRequestBag } from "@Obsidian/ViewModels/Blocks/Finance/BenevolenceRequestDetail/benevolenceRequestBag";
133151
import { PersonBag } from "@Obsidian/ViewModels/Blocks/Finance/BenevolenceRequestDetail/personBag";
134152
import { BenevolenceResultBag } from "@Obsidian/ViewModels/Blocks/Finance/BenevolenceRequestDetail/benevolenceResultBag";
@@ -140,6 +158,8 @@
140158
import { BtnSize } from "@Obsidian/Enums/Controls/btnSize";
141159
import { isNotNullish } from "@Obsidian/Utility/util";
142160
import { emptyGuid } from "@Obsidian/Utility/guid";
161+
import { confirm } from "@Obsidian/Utility/dialogs";
162+
import { BenevolenceRequestWorkflowBag } from "@Obsidian/ViewModels/Blocks/Finance/BenevolenceRequestDetail/benevolenceRequestWorkflowBag";
143163

144164
const props = defineProps({
145165
modelValue: {
@@ -163,6 +183,8 @@
163183
(e: "update:requestResults", value: BenevolenceResultBag[]): void,
164184
}>();
165185

186+
const launchWorkflowError = ref("");
187+
166188
// #region Value Builders
167189

168190
/** The values to display full-width at the top of the block. */
@@ -260,6 +282,21 @@
260282
return valueBuilder.build();
261283
});
262284

285+
286+
const contactInfoBottomValues = computed((): ValueDetailListItem[] => {
287+
const valueBuilder = new ValueDetailListItemBuilder();
288+
289+
if (!props.modelValue) {
290+
return valueBuilder.build();
291+
}
292+
293+
if (hasRequestLavaTemplateDetails.value) {
294+
valueBuilder.addHtmlValue("", benevolenceRequestTypeLavaDetails);
295+
}
296+
297+
return valueBuilder.build();
298+
});
299+
263300
/** The values to display full-width at the top of the block. */
264301
const requestDetailsTopValues = computed((): ValueDetailListItem[] => {
265302
const valueBuilder = new ValueDetailListItemBuilder();
@@ -453,6 +490,15 @@
453490

454491
const requestType = props.options.benevolenceRequestTypes?.find(requestType => requestType.id === entity.benevolenceTypeId);
455492

493+
const hasAuthorizedManualWorkflows = computed((): boolean => {
494+
return props.modelValue?.workflows != null
495+
&& props.modelValue?.workflows !== undefined
496+
&& props.modelValue?.workflows.length > 0;
497+
});
498+
const authorizedManualWorkflows = computed((): BenevolenceRequestWorkflowBag[] => {
499+
return props.modelValue?.workflows ?? [];
500+
});
501+
456502
const benevolenceRequestTypeLavaDetails = requestType?.lavaDetails ?? "";
457503
const hasRequestLavaTemplateDetails = computed((): boolean => {
458504
return benevolenceRequestTypeLavaDetails !== null
@@ -587,5 +633,18 @@
587633
emit("update:requestResults", newValue);
588634
}
589635

636+
/**
637+
* Opens a workflow launch URL in a new tab.
638+
* @param url The workflow launch URL.
639+
*/
640+
async function onWorkflowButtonClick(workflowName: string | null | undefined, url: string | null | undefined): Promise<void> {
641+
if (!workflowName || !url) {
642+
return;
643+
}
644+
645+
await confirm(`A '${workflowName}' workflow has been started.`);
646+
window.open(url, "_blank");
647+
}
648+
590649
// #endregion
591650
</script>

Rock.JavaScript.Obsidian/Framework/ViewModels/Blocks/Finance/BenevolenceRequestDetail/benevolenceRequestBag.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
//
2323

2424
import { BenevolenceDocumentBag } from "@Obsidian/ViewModels/Blocks/Finance/BenevolenceRequestDetail/benevolenceDocumentBag";
25+
import { BenevolenceRequestWorkflowBag } from "@Obsidian/ViewModels/Blocks/Finance/BenevolenceRequestDetail/benevolenceRequestWorkflowBag";
2526
import { BenevolenceResultBag } from "@Obsidian/ViewModels/Blocks/Finance/BenevolenceRequestDetail/benevolenceResultBag";
2627
import { CampusBag } from "@Obsidian/ViewModels/Blocks/Finance/BenevolenceRequestDetail/campusBag";
2728
import { PersonBag } from "@Obsidian/ViewModels/Blocks/Finance/BenevolenceRequestDetail/personBag";
@@ -73,4 +74,7 @@ export type BenevolenceRequestBag = {
7374

7475
/** Gets or sets the summary of the request result. */
7576
resultSummary?: string | null;
77+
78+
/** Gets or sets the collection of workflow options available for this request. */
79+
workflows?: BenevolenceRequestWorkflowBag[] | null;
7680
};
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by the Rock.CodeGeneration project
4+
// Changes to this file will be lost when the code is regenerated.
5+
// </auto-generated>
6+
//------------------------------------------------------------------------------
7+
// <copyright>
8+
// Copyright by the Spark Development Network
9+
//
10+
// Licensed under the Rock Community License (the "License");
11+
// you may not use this file except in compliance with the License.
12+
// You may obtain a copy of the License at
13+
//
14+
// http://www.rockrms.com/license
15+
//
16+
// Unless required by applicable law or agreed to in writing, software
17+
// distributed under the License is distributed on an "AS IS" BASIS,
18+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19+
// See the License for the specific language governing permissions and
20+
// limitations under the License.
21+
// </copyright>
22+
//
23+
24+
import { BenevolenceWorkflowTriggerType } from "@Obsidian/Enums/Finance/benevolenceWorkflowTriggerType";
25+
import { Guid } from "@Obsidian/Types";
26+
27+
/** Represents a workflow option for a benevolence request. */
28+
export type BenevolenceRequestWorkflowBag = {
29+
/** Gets or sets the CSS class for the workflow icon. */
30+
iconCssClass?: string | null;
31+
32+
/** Gets or sets the URL to launch the workflow. */
33+
launchUrl?: string | null;
34+
35+
/** Gets or sets the trigger type for the workflow. */
36+
triggerType: BenevolenceWorkflowTriggerType;
37+
38+
/** Gets or sets the workflow type unique identifier. */
39+
typeGuid: Guid;
40+
41+
/** Gets or sets the workflow type identifier. */
42+
typeId: number;
43+
44+
/** Gets or sets the workflow type name. */
45+
typeName?: string | null;
46+
};

Rock.ViewModels/Blocks/Finance/BenevolenceRequestDetail/BenevolenceRequestBag.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,5 +102,10 @@ public class BenevolenceRequestBag : EntityBagBase
102102
/// represented as a list of <see cref="ListItemBag"/> objects.
103103
/// </summary>
104104
public List<BenevolenceDocumentBag> RequestDocuments { get; set; }
105+
106+
/// <summary>
107+
/// Gets or sets the collection of workflow options available for this request.
108+
/// </summary>
109+
public List<BenevolenceRequestWorkflowBag> Workflows { get; set; }
105110
}
106111
}

Rock.ViewModels/Blocks/Finance/BenevolenceRequestDetail/BenevolenceRequestDetailOptionsBag.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public class BenevolenceRequestDetailOptionsBag
109109
/// <summary>
110110
/// Gets or sets the unique identifier for the binary file type associated with benevolence documents.
111111
/// </summary>
112-
public System.Guid BenevolenceDocumentBinaryFileTypeGuid { get; set; }
112+
public Guid BenevolenceDocumentBinaryFileTypeGuid { get; set; }
113113

114114
/// <summary>
115115
/// Gets or sets a value indicating whether country codes are enabled.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// <copyright>
2+
// Copyright by the Spark Development Network
3+
//
4+
// Licensed under the Rock Community License (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.rockrms.com/license
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
// </copyright>
16+
17+
using System;
18+
using Rock.Model;
19+
20+
namespace Rock.ViewModels.Blocks.Finance.BenevolenceRequestDetail
21+
{
22+
/// <summary>
23+
/// Represents a workflow option for a benevolence request.
24+
/// </summary>
25+
public class BenevolenceRequestWorkflowBag
26+
{
27+
/// <summary>
28+
/// Gets or sets the workflow type identifier.
29+
/// </summary>
30+
public int TypeId { get; set; }
31+
32+
/// <summary>
33+
/// Gets or sets the workflow type unique identifier.
34+
/// </summary>
35+
public Guid TypeGuid { get; set; }
36+
37+
/// <summary>
38+
/// Gets or sets the workflow type name.
39+
/// </summary>
40+
public string TypeName { get; set; }
41+
42+
/// <summary>
43+
/// Gets or sets the trigger type for the workflow.
44+
/// </summary>
45+
public BenevolenceWorkflowTriggerType TriggerType { get; set; }
46+
47+
/// <summary>
48+
/// Gets or sets the URL to launch the workflow.
49+
/// </summary>
50+
public string LaunchUrl { get; set; }
51+
52+
/// <summary>
53+
/// Gets or sets the CSS class for the workflow icon.
54+
/// </summary>
55+
public string iconCssClass { get; set; }
56+
}
57+
}

0 commit comments

Comments
 (0)