Skip to content

Commit 260cbb1

Browse files
committed
- Added PersonalDevices Obsidian block and removed legacy WebForms version
1 parent 4e534e0 commit 260cbb1

File tree

15 files changed

+1231
-344
lines changed

15 files changed

+1231
-344
lines changed

Rock.Blocks/Crm/PersonalDevices.cs

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
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+
18+
using System.Collections.Generic;
19+
using System.ComponentModel;
20+
using System.Data.Entity;
21+
using System.Linq;
22+
23+
using Rock;
24+
using Rock.Attribute;
25+
using Rock.Data;
26+
using Rock.Model;
27+
using Rock.ViewModels.Blocks;
28+
using Rock.ViewModels.Blocks.Crm.PersonalDevices;
29+
using Rock.Web.Cache;
30+
using Rock.Web.UI;
31+
32+
namespace Rock.Blocks.Crm
33+
{
34+
[DisplayName( "Personal Devices" )]
35+
[Category( "CRM" )]
36+
[Description( "Shows a list of all personal devices." )]
37+
38+
[LinkedPage(
39+
"Interactions Page",
40+
Key = NavigationUrlKey.InteractionsPage,
41+
Description = "The interactions associated with a specific personal device.",
42+
Order = 0 )]
43+
44+
[BooleanField(
45+
"Show Device Last Seen DateTime",
46+
Description = "Checking this option will display the time when the device was last seen.",
47+
DefaultBooleanValue = false,
48+
Order = 1,
49+
Key = AttributeKey.ShowDeviceLastSeenDateTime )]
50+
51+
[ContextAware( typeof( Person ) )]
52+
// was [Rock.SystemGuid.BlockTypeGuid( "9A504904-8AF6-4351-AE31-CBC4DB2F55BA" )]
53+
[Rock.SystemGuid.BlockTypeGuid( "2D90562E-7332-46DB-9100-0C4106151CA1" )]
54+
public class PersonalDevices : RockBlockType
55+
{
56+
#region Keys
57+
58+
private static class AttributeKey
59+
{
60+
public const string ShowDeviceLastSeenDateTime = "ShowDeviceLastSeenDateTime";
61+
}
62+
63+
private static class PageParameterKey
64+
{
65+
public const string PersonId = "PersonId";
66+
public const string PersonGuid = "PersonGuid";
67+
}
68+
69+
private static class NavigationUrlKey
70+
{
71+
public const string InteractionsPage = "InteractionsPage";
72+
}
73+
74+
#endregion Keys
75+
76+
#region Methods
77+
78+
/// <inheritdoc/>
79+
public override object GetObsidianBlockInitialization()
80+
{
81+
var box = new CustomBlockBox<PersonalDevicesBag, PersonalDevicesOptionsBag>();
82+
83+
var person = GetPerson();
84+
85+
var personalDevices = GetPersonalDevices( person?.Id );
86+
87+
box.Bag = new PersonalDevicesBag
88+
{
89+
PersonalDevices = personalDevices,
90+
PersonName = person?.FullName ?? string.Empty
91+
};
92+
93+
box.Options.ShowDeviceLastSeenDateTime = GetAttributeValue( AttributeKey.ShowDeviceLastSeenDateTime ).AsBoolean();
94+
box.Options.DeviceTypeOptions = DefinedTypeCache.Get( Rock.SystemGuid.DefinedType.PERSONAL_DEVICE_TYPE.AsGuid() ).DefinedValues.ToListItemBagList();
95+
96+
return box;
97+
}
98+
99+
/// <summary>
100+
/// Gets the current person either from the context or the page parameter.
101+
/// </summary>
102+
/// <returns>The resolved person or null.</returns>
103+
private Person GetPerson()
104+
{
105+
var person = this.RequestContext.GetContextEntity<Person>();
106+
if ( person != null )
107+
{
108+
return person;
109+
}
110+
111+
var personIdKey = PageParameter( PageParameterKey.PersonId );
112+
if ( personIdKey.IsNotNullOrWhiteSpace() )
113+
{
114+
return new PersonService( RockContext ).Get( personIdKey, !PageCache.Layout.Site.DisablePredictableIds );
115+
}
116+
117+
var personGuidKey = PageParameter( PageParameterKey.PersonGuid );
118+
if ( personGuidKey.IsNotNullOrWhiteSpace() )
119+
{
120+
var personGuid = personGuidKey.AsGuidOrNull();
121+
if ( personGuid.HasValue )
122+
{
123+
return new PersonService( RockContext ).Get( personGuid.Value );
124+
}
125+
}
126+
127+
return null;
128+
}
129+
130+
/// <summary>
131+
/// Gets the personal devices for the specified person identifier.
132+
/// </summary>
133+
/// <param name="personId">The person identifier.</param>
134+
/// <returns>A list of personal device list item bags.</returns>
135+
private List<PersonalDeviceListItemBag> GetPersonalDevices( int? personId )
136+
{
137+
if ( !personId.HasValue )
138+
{
139+
return new List<PersonalDeviceListItemBag>();
140+
}
141+
142+
var personalDeviceService = new PersonalDeviceService( RockContext );
143+
144+
var personalDevices = personalDeviceService
145+
.Queryable()
146+
.AsNoTracking()
147+
.Include( pd => pd.PersonalDeviceType )
148+
.Include( pd => pd.Platform )
149+
.Where( pd => pd.PersonAlias != null && pd.PersonAlias.PersonId == personId.Value )
150+
.ToList();
151+
152+
var items = personalDevices.Select( pd => new PersonalDeviceListItemBag
153+
{
154+
Name = pd.Name,
155+
IsActive = pd.IsActive,
156+
Guid = pd.Guid,
157+
DeviceType = pd.PersonalDeviceType != null
158+
? pd.PersonalDeviceType.ToListItemBag()
159+
: null,
160+
IconCssClass = pd.PersonalDeviceTypeValueId.HasValue
161+
? DefinedValueCache.Get( pd.PersonalDeviceTypeValueId.Value )?.GetAttributeValue( "IconCssClass" )
162+
: null,
163+
Platform = pd.Platform != null
164+
? pd.Platform.ToListItemBag()
165+
: null,
166+
DeviceVersion = pd.DeviceVersion,
167+
MacAddress = pd.MACAddress,
168+
NotificationsEnabled = pd.NotificationsEnabled,
169+
LocationPermissionStatus = pd.LocationPermissionStatus,
170+
IsPreciseLocationEnabled = pd.IsPreciseLocationEnabled,
171+
IsBeaconMonitoringEnabled = pd.IsBeaconMonitoringEnabled,
172+
CreatedDateTime = pd.CreatedDateTime,
173+
LastSeenDateTime = pd.LastSeenDateTime,
174+
} ).ToList();
175+
176+
return items;
177+
}
178+
179+
#endregion Methods
180+
181+
#region Block Actions
182+
183+
/// <summary>
184+
/// Deletes the specified personal device.
185+
/// </summary>
186+
/// <param name="key">The personal device key (IdKey) identifying the device to delete.</param>
187+
[BlockAction]
188+
public BlockActionResult DeletePersonalDevice( string key )
189+
{
190+
var personalDeviceService = new PersonalDeviceService( RockContext );
191+
var personalDevice = personalDeviceService.Get( key, !PageCache.Layout.Site.DisablePredictableIds );
192+
193+
if ( personalDevice == null )
194+
{
195+
return ActionBadRequest( "Personal Device not found." );
196+
}
197+
198+
if ( !BlockCache.IsAuthorized( Rock.Security.Authorization.EDIT, RequestContext.CurrentPerson ) )
199+
{
200+
return ActionBadRequest( "Not authorized to delete this personal device." );
201+
}
202+
203+
if ( !personalDeviceService.CanDelete( personalDevice, out var errorMessage ) )
204+
{
205+
return ActionBadRequest( errorMessage );
206+
}
207+
208+
personalDeviceService.Delete( personalDevice );
209+
RockContext.SaveChanges();
210+
211+
return ActionOk();
212+
}
213+
214+
/// <summary>
215+
/// Gets the interactions page URL for the specified personal device.
216+
/// </summary>
217+
/// <param name="key">The identifier of the personal device.</param>
218+
/// <returns>The URL to navigate to for viewing interactions.</returns>
219+
[BlockAction]
220+
public BlockActionResult GetInteractionsUrl( string key )
221+
{
222+
var personalDeviceService = new PersonalDeviceService( RockContext );
223+
var personalDevice = personalDeviceService.Get( key, !PageCache.Layout.Site.DisablePredictableIds );
224+
225+
if ( personalDevice == null )
226+
{
227+
return ActionBadRequest( "Personal Device not found." );
228+
}
229+
230+
if ( !BlockCache.IsAuthorized( Rock.Security.Authorization.VIEW, RequestContext.CurrentPerson ) )
231+
{
232+
return ActionBadRequest( "Not authorized to view interactions for this personal device." );
233+
}
234+
235+
var queryParams = new Dictionary<string, string>
236+
{
237+
["PersonalDeviceId"] = personalDevice.IdKey
238+
};
239+
240+
var url = this.GetLinkedPageUrl( NavigationUrlKey.InteractionsPage, queryParams );
241+
242+
if ( string.IsNullOrWhiteSpace( url ) )
243+
{
244+
return ActionBadRequest( "Interactions page is not configured." );
245+
}
246+
247+
return ActionOk( url );
248+
}
249+
250+
#endregion Block Actions
251+
}
252+
}

0 commit comments

Comments
 (0)