v9: Implement telemetry levels (#12267)
* Add initial classes * Add TelemetryProviders * Add new NodeCountService.cs and NodeTelemetryProvider * Add data contract attribute to UsageInformation Otherwise it wont serialize correctly * Implement more providers * Fix builders and propertyEditorTelemetry * Add MediaTelemetryProvider * Add MediaTelemetryProvider * Fix doubling of media telemetry * Move contentCount from NodeCountTelemetryProvider and move to ContentTelemetryProvider * Revert ContentTelemetryProvider changes * Add detailed information to TelemetryService * Add integration tests * Add more tests and todos for tests * Fix stylecop warnings * Use yield return instead of instantiating local list * Implement Macro test * Inject interface instead of implementation in TelemetryService * Fix TelemetryServiceTests.cs * Implement media tests * Implement propertyTypeTests * Implement constants instead of hardcoded strings * Add SystemInformationTelemetryProvider * Use SystemInformationTableDataProvider in UserDataService * Implement more properties * Add UsageInformation * Replace UserDataService with SystemInformationTelemetryProvider * Undo changes to UserDataService and obsolete it * Remove ISystemInformationTableDataProvider * Register SystemInformationTelemetryProvider as telemetry provider * Use constants for telemetry names * Make UserDataServiceTests test SystemInformationTelemetryProvider instead * Update UserDataServiceTests to cover new data * Add unit tests * Add integration test testing expected data is returned * Implement Analytics dashboard * Improve assertion message * Add text and styling to analyticspage * Rename consent to analytic * implement save button for consent level * Implement save button * Fix system information test * Add TelemetryResource * Move telemetry providers to infrastructure * Add database provider to system information * Set startvalue for slider * Fix unit tests * Implement MetricsConsentService using KeyValueService * Return void hen setting the telemetry level * fix startposition when not reloading * Add a couple tests * Update src/Umbraco.Core/Services/MetricsConsentService.cs * Rename ConsentLevel.cs * Use direct Enum instead of parsing * rename consent resource * add lazy database * refactor slider * Implement ng-if and propers pips * Make classes internal * Fix slider not loading when navigating to tab * Add telemetry level check to TelemetryService.cs * Add Consent for analytics text * Fix build errors for unit tests * Fix TelemetryServiceTests * revert package-lock.json * Fix integration test * Update slider * Update TelemetryService.cs * Apply suggestions from code review Co-authored-by: Mole <nikolajlauridsen@protonmail.ch> Co-authored-by: Nikolaj Geisle <niko737@edu.ucl.dk> Co-authored-by: nikolajlauridsen <nikolajlauridsen@protonmail.ch>
This commit is contained in:
@@ -19,7 +19,7 @@ namespace Umbraco.Cms.Core.Configuration.Models
|
||||
internal const bool StaticHideTopLevelNodeFromPath = true;
|
||||
internal const bool StaticUseHttps = false;
|
||||
internal const int StaticVersionCheckPeriod = 7;
|
||||
internal const string StaticUmbracoPath = "~/umbraco";
|
||||
internal const string StaticUmbracoPath = Constants.System.DefaultUmbracoPath;
|
||||
internal const string StaticIconsPath = "~/umbraco/assets/icons";
|
||||
internal const string StaticUmbracoCssPath = "~/css";
|
||||
internal const string StaticUmbracoScriptsPath = "~/scripts";
|
||||
|
||||
@@ -59,7 +59,9 @@
|
||||
public const string RecycleBinMediaPathPrefix = "-1,-21,";
|
||||
|
||||
public const int DefaultLabelDataTypeId = -92;
|
||||
public const string UmbracoConnectionName = "umbracoDbDSN";
|
||||
public const string UmbracoConnectionName = "umbracoDbDSN";
|
||||
|
||||
public const string DefaultUmbracoPath = "~/umbraco";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
32
src/Umbraco.Core/Constants-Telemetry.cs
Normal file
32
src/Umbraco.Core/Constants-Telemetry.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
namespace Umbraco.Cms.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
public static class Telemetry
|
||||
{
|
||||
|
||||
public static string RootCount = "RootCount";
|
||||
public static string DomainCount = "DomainCount";
|
||||
public static string ExamineIndexCount = "ExamineIndexCount";
|
||||
public static string LanguageCount = "LanguageCount";
|
||||
public static string MacroCount = "MacroCount";
|
||||
public static string MediaCount = "MediaCount";
|
||||
public static string MemberCount = "MemberCount";
|
||||
public static string TemplateCount = "TemplateCount";
|
||||
public static string ContentCount = "ContentCount";
|
||||
public static string DocumentTypeCount = "DocumentTypeCount";
|
||||
public static string Properties = "Properties";
|
||||
public static string UserCount = "UserCount";
|
||||
public static string UserGroupCount = "UserGroupCount";
|
||||
public static string ServerOs = "ServerOs";
|
||||
public static string ServerFramework = "ServerFramework";
|
||||
public static string OsLanguage = "OsLanguage";
|
||||
public static string WebServer = "WebServer";
|
||||
public static string ModelsBuilderMode = "ModelBuilderMode";
|
||||
public static string CustomUmbracoPath = "CustomUmbracoPath";
|
||||
public static string AspEnvironment = "AspEnvironment";
|
||||
public static string IsDebug = "IsDebug";
|
||||
public static string DatabaseProvider = "DatabaseProvider";
|
||||
}
|
||||
}
|
||||
}
|
||||
15
src/Umbraco.Core/Dashboards/AnalyticsDashboard.cs
Normal file
15
src/Umbraco.Core/Dashboards/AnalyticsDashboard.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Cms.Core.Dashboards
|
||||
{
|
||||
public class AnalyticsDashboard : IDashboard
|
||||
{
|
||||
public string Alias => "settingsAnalytics";
|
||||
|
||||
public string[] Sections => new [] { "settings" };
|
||||
|
||||
public string View => "views/dashboard/settings/analytics.html";
|
||||
|
||||
public IAccessRule[] AccessRules => Array.Empty<IAccessRule>();
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ using Umbraco.Cms.Core.Install;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Logging;
|
||||
using Umbraco.Cms.Core.Mail;
|
||||
using Umbraco.Cms.Core.Manifest;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.Notifications;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
@@ -39,7 +39,6 @@ using Umbraco.Cms.Core.Sync;
|
||||
using Umbraco.Cms.Core.Telemetry;
|
||||
using Umbraco.Cms.Core.Templates;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Web.Common.DependencyInjection;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Core.DependencyInjection
|
||||
@@ -182,7 +181,7 @@ namespace Umbraco.Cms.Core.DependencyInjection
|
||||
Services.AddSingleton<UriUtility>();
|
||||
|
||||
Services.AddUnique<IDashboardService, DashboardService>();
|
||||
Services.AddUnique<IUserDataService, UserDataService>();
|
||||
Services.AddSingleton<IMetricsConsentService, MetricsConsentService>();
|
||||
|
||||
// will be injected in controllers when needed to invoke rest endpoints on Our
|
||||
Services.AddUnique<IInstallationService, InstallationService>();
|
||||
|
||||
12
src/Umbraco.Core/Models/TelemetryLevel.cs
Normal file
12
src/Umbraco.Core/Models/TelemetryLevel.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Cms.Core.Models
|
||||
{
|
||||
[DataContract]
|
||||
public enum TelemetryLevel
|
||||
{
|
||||
Minimal,
|
||||
Basic,
|
||||
Detailed,
|
||||
}
|
||||
}
|
||||
11
src/Umbraco.Core/Models/TelemetryResource.cs
Normal file
11
src/Umbraco.Core/Models/TelemetryResource.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Cms.Core.Models
|
||||
{
|
||||
[DataContract]
|
||||
public class TelemetryResource
|
||||
{
|
||||
[DataMember]
|
||||
public TelemetryLevel TelemetryLevel { get; set; }
|
||||
}
|
||||
}
|
||||
20
src/Umbraco.Core/Models/UsageInformation.cs
Normal file
20
src/Umbraco.Core/Models/UsageInformation.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Cms.Core.Models
|
||||
{
|
||||
[DataContract]
|
||||
public class UsageInformation
|
||||
{
|
||||
[DataMember(Name = "name")]
|
||||
public string Name { get; }
|
||||
|
||||
[DataMember(Name = "data")]
|
||||
public object Data { get; }
|
||||
|
||||
public UsageInformation(string name, object data)
|
||||
{
|
||||
Name = name;
|
||||
Data = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
7
src/Umbraco.Core/Services/IExamineIndexCountService.cs
Normal file
7
src/Umbraco.Core/Services/IExamineIndexCountService.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Umbraco.Cms.Core.Services
|
||||
{
|
||||
public interface IExamineIndexCountService
|
||||
{
|
||||
public int GetCount();
|
||||
}
|
||||
}
|
||||
11
src/Umbraco.Core/Services/IMetricsConsentService.cs
Normal file
11
src/Umbraco.Core/Services/IMetricsConsentService.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Umbraco.Cms.Core.Models;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services
|
||||
{
|
||||
public interface IMetricsConsentService
|
||||
{
|
||||
TelemetryLevel GetConsentLevel();
|
||||
|
||||
void SetConsentLevel(TelemetryLevel telemetryLevel);
|
||||
}
|
||||
}
|
||||
10
src/Umbraco.Core/Services/INodeCountService.cs
Normal file
10
src/Umbraco.Core/Services/INodeCountService.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services
|
||||
{
|
||||
public interface INodeCountService
|
||||
{
|
||||
int GetNodeCount(Guid nodeType);
|
||||
int GetMediaCount();
|
||||
}
|
||||
}
|
||||
10
src/Umbraco.Core/Services/IUsageInformationService.cs
Normal file
10
src/Umbraco.Core/Services/IUsageInformationService.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services
|
||||
{
|
||||
public interface IUsageInformationService
|
||||
{
|
||||
IEnumerable<UsageInformation> GetDetailed();
|
||||
}
|
||||
}
|
||||
34
src/Umbraco.Core/Services/MetricsConsentService.cs
Normal file
34
src/Umbraco.Core/Services/MetricsConsentService.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services
|
||||
{
|
||||
public class MetricsConsentService : IMetricsConsentService
|
||||
{
|
||||
internal const string Key = "UmbracoAnalyticsLevel";
|
||||
|
||||
private readonly IKeyValueService _keyValueService;
|
||||
|
||||
public MetricsConsentService(IKeyValueService keyValueService)
|
||||
{
|
||||
_keyValueService = keyValueService;
|
||||
}
|
||||
|
||||
public TelemetryLevel GetConsentLevel()
|
||||
{
|
||||
var analyticsLevelString = _keyValueService.GetValue(Key);
|
||||
|
||||
if (analyticsLevelString is null || Enum.TryParse(analyticsLevelString, out TelemetryLevel analyticsLevel) is false)
|
||||
{
|
||||
return TelemetryLevel.Basic;
|
||||
}
|
||||
|
||||
return analyticsLevel;
|
||||
}
|
||||
|
||||
public void SetConsentLevel(TelemetryLevel telemetryLevel)
|
||||
{
|
||||
_keyValueService.SetValue(Key, telemetryLevel.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -9,11 +10,13 @@ using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services
|
||||
{
|
||||
[Obsolete("Use the IUserDataService interface instead")]
|
||||
public class UserDataService : IUserDataService
|
||||
{
|
||||
private readonly IUmbracoVersion _version;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
|
||||
|
||||
public UserDataService(IUmbracoVersion version, ILocalizationService localizationService)
|
||||
{
|
||||
_version = version;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
|
||||
namespace Umbraco.Cms.Core.Telemetry.Models
|
||||
{
|
||||
@@ -30,5 +31,8 @@ namespace Umbraco.Cms.Core.Telemetry.Models
|
||||
/// </remarks>
|
||||
[DataMember(Name = "packages")]
|
||||
public IEnumerable<PackageTelemetry> Packages { get; set; }
|
||||
|
||||
[DataMember(Name = "detailed")]
|
||||
public IEnumerable<UsageInformation> Detailed { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Cms.Core.Configuration;
|
||||
using Umbraco.Cms.Core.Manifest;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Telemetry.Models;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
@@ -13,6 +15,8 @@ namespace Umbraco.Cms.Core.Telemetry
|
||||
private readonly IManifestParser _manifestParser;
|
||||
private readonly IUmbracoVersion _umbracoVersion;
|
||||
private readonly ISiteIdentifierService _siteIdentifierService;
|
||||
private readonly IUsageInformationService _usageInformationService;
|
||||
private readonly IMetricsConsentService _metricsConsentService;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TelemetryService"/> class.
|
||||
@@ -20,11 +24,15 @@ namespace Umbraco.Cms.Core.Telemetry
|
||||
public TelemetryService(
|
||||
IManifestParser manifestParser,
|
||||
IUmbracoVersion umbracoVersion,
|
||||
ISiteIdentifierService siteIdentifierService)
|
||||
ISiteIdentifierService siteIdentifierService,
|
||||
IUsageInformationService usageInformationService,
|
||||
IMetricsConsentService metricsConsentService)
|
||||
{
|
||||
_manifestParser = manifestParser;
|
||||
_umbracoVersion = umbracoVersion;
|
||||
_siteIdentifierService = siteIdentifierService;
|
||||
_usageInformationService = usageInformationService;
|
||||
_metricsConsentService = metricsConsentService;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -39,14 +47,30 @@ namespace Umbraco.Cms.Core.Telemetry
|
||||
telemetryReportData = new TelemetryReportData
|
||||
{
|
||||
Id = telemetryId,
|
||||
Version = _umbracoVersion.SemanticVersion.ToSemanticStringWithoutBuild(),
|
||||
Version = GetVersion(),
|
||||
Packages = GetPackageTelemetry(),
|
||||
Detailed = _usageInformationService.GetDetailed(),
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
private string GetVersion()
|
||||
{
|
||||
if (_metricsConsentService.GetConsentLevel() == TelemetryLevel.Minimal)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _umbracoVersion.SemanticVersion.ToSemanticStringWithoutBuild();
|
||||
}
|
||||
|
||||
private IEnumerable<PackageTelemetry> GetPackageTelemetry()
|
||||
{
|
||||
if (_metricsConsentService.GetConsentLevel() == TelemetryLevel.Minimal)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<PackageTelemetry> packages = new();
|
||||
IEnumerable<PackageManifest> manifests = _manifestParser.GetManifests();
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ using Umbraco.Cms.Infrastructure.Persistence.Mappers;
|
||||
using Umbraco.Cms.Infrastructure.Runtime;
|
||||
using Umbraco.Cms.Infrastructure.Search;
|
||||
using Umbraco.Cms.Infrastructure.Serialization;
|
||||
using Umbraco.Cms.Infrastructure.Services.Implement;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.DependencyInjection
|
||||
@@ -196,6 +197,7 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
|
||||
|
||||
builder.Services.AddSingleton<PackageDataInstallation>();
|
||||
|
||||
builder.Services.AddTransient<INodeCountService, NodeCountService>();
|
||||
builder.AddInstaller();
|
||||
|
||||
// Services required to run background jobs (with out the handler)
|
||||
|
||||
@@ -20,6 +20,7 @@ using Umbraco.Cms.Core.Services.Implement;
|
||||
using Umbraco.Cms.Infrastructure.Packaging;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement;
|
||||
using Umbraco.Cms.Infrastructure.Services.Implement;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Providers;
|
||||
using Umbraco.Cms.Infrastructure.Templates;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
@@ -93,6 +94,9 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection
|
||||
builder.Services.AddSingleton<PackageDataInstallation>();
|
||||
builder.Services.AddUnique<IPackageInstallation, PackageInstallation>();
|
||||
builder.Services.AddUnique<IHtmlMacroParameterParser, HtmlMacroParameterParser>();
|
||||
builder.Services.AddTransient<IExamineIndexCountService, ExamineIndexCountService>();
|
||||
builder.Services.AddUnique<IUserDataService, SystemInformationTelemetryProvider>();
|
||||
builder.Services.AddTransient<IUsageInformationService, UsageInformationService>();
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Providers;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.DependencyInjection
|
||||
{
|
||||
public static class UmbracoBuilder_TelemetryProviders
|
||||
{
|
||||
public static IUmbracoBuilder AddTelemetryProviders(this IUmbracoBuilder builder)
|
||||
{
|
||||
builder.Services.AddTransient<IDetailedTelemetryProvider, ContentTelemetryProvider>();
|
||||
builder.Services.AddTransient<IDetailedTelemetryProvider, DomainTelemetryProvider>();
|
||||
builder.Services.AddTransient<IDetailedTelemetryProvider, ExamineTelemetryProvider>();
|
||||
builder.Services.AddTransient<IDetailedTelemetryProvider, LanguagesTelemetryProvider>();
|
||||
builder.Services.AddTransient<IDetailedTelemetryProvider, MacroTelemetryProvider>();
|
||||
builder.Services.AddTransient<IDetailedTelemetryProvider, MediaTelemetryProvider>();
|
||||
builder.Services.AddTransient<IDetailedTelemetryProvider, NodeCountTelemetryProvider>();
|
||||
builder.Services.AddTransient<IDetailedTelemetryProvider, PropertyEditorTelemetryProvider>();
|
||||
builder.Services.AddTransient<IDetailedTelemetryProvider, UserTelemetryProvider>();
|
||||
builder.Services.AddTransient<IDetailedTelemetryProvider, SystemInformationTelemetryProvider>();
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Linq;
|
||||
using Examine;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Services.Implement
|
||||
{
|
||||
public class ExamineIndexCountService : IExamineIndexCountService
|
||||
{
|
||||
private readonly IExamineManager _examineManager;
|
||||
|
||||
public ExamineIndexCountService(IExamineManager examineManager)
|
||||
{
|
||||
_examineManager = examineManager;
|
||||
}
|
||||
|
||||
public int GetCount()
|
||||
{
|
||||
return _examineManager.Indexes.Count();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Services.Implement
|
||||
{
|
||||
public class NodeCountService : INodeCountService
|
||||
{
|
||||
private readonly IScopeProvider _scopeProvider;
|
||||
|
||||
public NodeCountService(IScopeProvider scopeProvider) => _scopeProvider = scopeProvider;
|
||||
|
||||
public int GetNodeCount(Guid nodeType)
|
||||
{
|
||||
int count = 0;
|
||||
using (IScope scope = _scopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
var query = scope.Database.SqlContext.Sql()
|
||||
.SelectCount()
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.NodeObjectType == nodeType && x.Trashed == false);
|
||||
|
||||
count = scope.Database.ExecuteScalar<int>(query);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public int GetMediaCount()
|
||||
{
|
||||
using (IScope scope = _scopeProvider.CreateScope(autoComplete: true))
|
||||
{
|
||||
var query = scope.Database.SqlContext.Sql()
|
||||
.SelectCount()
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<ContentDto>()
|
||||
.On<NodeDto, ContentDto>(left => left.NodeId, right => right.NodeId)
|
||||
.InnerJoin<ContentTypeDto>()
|
||||
.On<ContentDto, ContentTypeDto>(left => left.ContentTypeId, right => right.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == Constants.ObjectTypes.Media)
|
||||
.Where<NodeDto>(x => !x.Trashed)
|
||||
.Where<ContentTypeDto>(x => x.Alias != Constants.Conventions.MediaTypes.Folder);
|
||||
|
||||
return scope.Database.ExecuteScalar<int>(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Telemetry.Interfaces
|
||||
{
|
||||
internal interface IDetailedTelemetryProvider
|
||||
{
|
||||
IEnumerable<UsageInformation> GetInformation();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Telemetry.Providers
|
||||
{
|
||||
public class ContentTelemetryProvider : IDetailedTelemetryProvider
|
||||
{
|
||||
private readonly IContentService _contentService;
|
||||
|
||||
public ContentTelemetryProvider(IContentService contentService) => _contentService = contentService;
|
||||
|
||||
public IEnumerable<UsageInformation> GetInformation()
|
||||
{
|
||||
var rootNodes = _contentService.GetRootContent();
|
||||
int nodes = rootNodes.Count();
|
||||
yield return new UsageInformation(Constants.Telemetry.RootCount, nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Telemetry.Providers
|
||||
{
|
||||
public class DomainTelemetryProvider : IDetailedTelemetryProvider
|
||||
{
|
||||
private readonly IDomainService _domainService;
|
||||
|
||||
public DomainTelemetryProvider(IDomainService domainService) => _domainService = domainService;
|
||||
|
||||
public IEnumerable<UsageInformation> GetInformation()
|
||||
{
|
||||
var domains = _domainService.GetAll(true).Count();
|
||||
yield return new UsageInformation(Constants.Telemetry.DomainCount, domains);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Telemetry.Providers
|
||||
{
|
||||
public class ExamineTelemetryProvider : IDetailedTelemetryProvider
|
||||
{
|
||||
private readonly IExamineIndexCountService _examineIndexCountService;
|
||||
|
||||
public ExamineTelemetryProvider(IExamineIndexCountService examineIndexCountService) => _examineIndexCountService = examineIndexCountService;
|
||||
|
||||
public IEnumerable<UsageInformation> GetInformation()
|
||||
{
|
||||
var indexes = _examineIndexCountService.GetCount();
|
||||
yield return new UsageInformation(Constants.Telemetry.ExamineIndexCount, indexes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Telemetry.Providers
|
||||
{
|
||||
public class LanguagesTelemetryProvider : IDetailedTelemetryProvider
|
||||
{
|
||||
private readonly ILocalizationService _localizationService;
|
||||
|
||||
public LanguagesTelemetryProvider(ILocalizationService localizationService)
|
||||
{
|
||||
_localizationService = localizationService;
|
||||
}
|
||||
|
||||
public IEnumerable<UsageInformation> GetInformation()
|
||||
{
|
||||
int languages = _localizationService.GetAllLanguages().Count();
|
||||
yield return new UsageInformation(Constants.Telemetry.LanguageCount, languages);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Telemetry.Providers
|
||||
{
|
||||
public class MacroTelemetryProvider : IDetailedTelemetryProvider
|
||||
{
|
||||
private readonly IMacroService _macroService;
|
||||
|
||||
public MacroTelemetryProvider(IMacroService macroService)
|
||||
{
|
||||
_macroService = macroService;
|
||||
}
|
||||
|
||||
public IEnumerable<UsageInformation> GetInformation()
|
||||
{
|
||||
var macros = _macroService.GetAll().Count();
|
||||
yield return new UsageInformation(Constants.Telemetry.MacroCount, macros);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Telemetry.Providers
|
||||
{
|
||||
public class MediaTelemetryProvider : IDetailedTelemetryProvider
|
||||
{
|
||||
private readonly INodeCountService _nodeCountService;
|
||||
|
||||
public MediaTelemetryProvider(INodeCountService nodeCountService) => _nodeCountService = nodeCountService;
|
||||
|
||||
public IEnumerable<UsageInformation> GetInformation()
|
||||
{
|
||||
yield return new UsageInformation(Constants.Telemetry.MediaCount, _nodeCountService.GetMediaCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Telemetry.Providers
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class NodeCountTelemetryProvider : IDetailedTelemetryProvider
|
||||
{
|
||||
private readonly INodeCountService _nodeCountService;
|
||||
|
||||
public NodeCountTelemetryProvider(INodeCountService nodeCountService) => _nodeCountService = nodeCountService;
|
||||
|
||||
public IEnumerable<UsageInformation> GetInformation()
|
||||
{
|
||||
yield return new UsageInformation(Constants.Telemetry.MemberCount, _nodeCountService.GetNodeCount(Constants.ObjectTypes.Member));
|
||||
yield return new UsageInformation(Constants.Telemetry.TemplateCount, _nodeCountService.GetNodeCount(Constants.ObjectTypes.Template));
|
||||
yield return new UsageInformation(Constants.Telemetry.ContentCount, _nodeCountService.GetNodeCount(Constants.ObjectTypes.Document));
|
||||
yield return new UsageInformation(Constants.Telemetry.DocumentTypeCount, _nodeCountService.GetNodeCount(Constants.ObjectTypes.DocumentType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Telemetry.Providers
|
||||
{
|
||||
public class PropertyEditorTelemetryProvider : IDetailedTelemetryProvider
|
||||
{
|
||||
private readonly IContentTypeService _contentTypeService;
|
||||
|
||||
public PropertyEditorTelemetryProvider(IContentTypeService contentTypeService) => _contentTypeService = contentTypeService;
|
||||
|
||||
public IEnumerable<UsageInformation> GetInformation()
|
||||
{
|
||||
var contentTypes = _contentTypeService.GetAll();
|
||||
var propertyTypes = new HashSet<string>();
|
||||
foreach (IContentType contentType in contentTypes)
|
||||
{
|
||||
propertyTypes.UnionWith(contentType.PropertyTypes.Select(x => x.PropertyEditorAlias));
|
||||
}
|
||||
|
||||
yield return new UsageInformation(Constants.Telemetry.Properties, propertyTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Persistence;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Telemetry.Providers
|
||||
{
|
||||
internal class SystemInformationTelemetryProvider : IDetailedTelemetryProvider, IUserDataService
|
||||
{
|
||||
private readonly IUmbracoVersion _version;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
private readonly IHostEnvironment _hostEnvironment;
|
||||
private readonly Lazy<IUmbracoDatabase> _database;
|
||||
private readonly GlobalSettings _globalSettings;
|
||||
private readonly HostingSettings _hostingSettings;
|
||||
private readonly ModelsBuilderSettings _modelsBuilderSettings;
|
||||
|
||||
public SystemInformationTelemetryProvider(
|
||||
IUmbracoVersion version,
|
||||
ILocalizationService localizationService,
|
||||
IOptions<ModelsBuilderSettings> modelsBuilderSettings,
|
||||
IOptions<HostingSettings> hostingSettings,
|
||||
IOptions<GlobalSettings> globalSettings,
|
||||
IHostEnvironment hostEnvironment,
|
||||
Lazy<IUmbracoDatabase> database)
|
||||
{
|
||||
_version = version;
|
||||
_localizationService = localizationService;
|
||||
_hostEnvironment = hostEnvironment;
|
||||
_database = database;
|
||||
_globalSettings = globalSettings.Value;
|
||||
_hostingSettings = hostingSettings.Value;
|
||||
_modelsBuilderSettings = modelsBuilderSettings.Value;
|
||||
}
|
||||
|
||||
private string CurrentWebServer => IsRunningInProcessIIS() ? "IIS" : "Kestrel";
|
||||
|
||||
private string ServerFramework => RuntimeInformation.FrameworkDescription;
|
||||
|
||||
private string ModelsBuilderMode => _modelsBuilderSettings.ModelsMode.ToString();
|
||||
|
||||
private string CurrentCulture => Thread.CurrentThread.CurrentCulture.ToString();
|
||||
|
||||
private bool IsDebug => _hostingSettings.Debug;
|
||||
|
||||
private bool UmbracoPathCustomized => _globalSettings.UmbracoPath != Constants.System.DefaultUmbracoPath;
|
||||
|
||||
private string AspEnvironment => _hostEnvironment.EnvironmentName;
|
||||
|
||||
private string ServerOs => RuntimeInformation.OSDescription;
|
||||
|
||||
private string DatabaseProvider => _database.Value.DatabaseType.GetProviderName();
|
||||
|
||||
public IEnumerable<UsageInformation> GetInformation() =>
|
||||
new UsageInformation[]
|
||||
{
|
||||
new(Constants.Telemetry.ServerOs, ServerOs),
|
||||
new(Constants.Telemetry.ServerFramework, ServerFramework),
|
||||
new(Constants.Telemetry.OsLanguage, CurrentCulture),
|
||||
new(Constants.Telemetry.WebServer, CurrentWebServer),
|
||||
new(Constants.Telemetry.ModelsBuilderMode, ModelsBuilderMode),
|
||||
new(Constants.Telemetry.CustomUmbracoPath, UmbracoPathCustomized),
|
||||
new(Constants.Telemetry.AspEnvironment, AspEnvironment),
|
||||
new(Constants.Telemetry.IsDebug, IsDebug),
|
||||
new(Constants.Telemetry.DatabaseProvider, DatabaseProvider),
|
||||
};
|
||||
|
||||
public IEnumerable<UserData> GetUserData() =>
|
||||
new UserData[]
|
||||
{
|
||||
new("Server OS", ServerOs),
|
||||
new("Server Framework", ServerFramework),
|
||||
new("Default Language", _localizationService.GetDefaultLanguageIsoCode()),
|
||||
new("Umbraco Version", _version.SemanticVersion.ToSemanticStringWithoutBuild()),
|
||||
new("Current Culture", CurrentCulture),
|
||||
new("Current UI Culture", Thread.CurrentThread.CurrentUICulture.ToString()),
|
||||
new("Current Webserver", CurrentWebServer),
|
||||
new("Models Builder Mode", ModelsBuilderMode),
|
||||
new("Debug Mode", IsDebug.ToString()),
|
||||
new("Database Provider", DatabaseProvider),
|
||||
};
|
||||
|
||||
private bool IsRunningInProcessIIS()
|
||||
{
|
||||
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string processName = Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().ProcessName);
|
||||
return (processName.Contains("w3wp") || processName.Contains("iisexpress"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Infrastructure.Telemetry.Providers
|
||||
{
|
||||
public class UserTelemetryProvider : IDetailedTelemetryProvider
|
||||
{
|
||||
private readonly IUserService _userService;
|
||||
|
||||
public UserTelemetryProvider(IUserService userService)
|
||||
{
|
||||
_userService = userService;
|
||||
}
|
||||
|
||||
public IEnumerable<UsageInformation> GetInformation()
|
||||
{
|
||||
_userService.GetAll(1, 1, out long total);
|
||||
int userGroups = _userService.GetAllUserGroups().Count();
|
||||
|
||||
yield return new UsageInformation(Constants.Telemetry.UserCount, total);
|
||||
yield return new UsageInformation(Constants.Telemetry.UserGroupCount, userGroups);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Infrastructure.Telemetry.Interfaces;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services
|
||||
{
|
||||
internal class UsageInformationService : IUsageInformationService
|
||||
{
|
||||
private readonly IMetricsConsentService _metricsConsentService;
|
||||
private readonly IEnumerable<IDetailedTelemetryProvider> _providers;
|
||||
|
||||
public UsageInformationService(
|
||||
IMetricsConsentService metricsConsentService,
|
||||
IEnumerable<IDetailedTelemetryProvider> providers)
|
||||
{
|
||||
_metricsConsentService = metricsConsentService;
|
||||
_providers = providers;
|
||||
}
|
||||
|
||||
public IEnumerable<UsageInformation> GetDetailed()
|
||||
{
|
||||
if (_metricsConsentService.GetConsentLevel() != TelemetryLevel.Detailed)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var detailedUsageInformation = new List<UsageInformation>();
|
||||
foreach (IDetailedTelemetryProvider provider in _providers)
|
||||
{
|
||||
detailedUsageInformation.AddRange(provider.GetInformation());
|
||||
}
|
||||
|
||||
return detailedUsageInformation;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
{
|
||||
public class AnalyticsController : UmbracoAuthorizedJsonController
|
||||
{
|
||||
private readonly IMetricsConsentService _metricsConsentService;
|
||||
public AnalyticsController(IMetricsConsentService metricsConsentService)
|
||||
{
|
||||
_metricsConsentService = metricsConsentService;
|
||||
}
|
||||
|
||||
public TelemetryLevel GetConsentLevel()
|
||||
{
|
||||
return _metricsConsentService.GetConsentLevel();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult SetConsentLevel([FromBody]TelemetryResource telemetryResource)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
_metricsConsentService.SetConsentLevel(telemetryResource.TelemetryLevel);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
public IEnumerable<TelemetryLevel> GetAllLevels() => new[] { TelemetryLevel.Minimal, TelemetryLevel.Basic, TelemetryLevel.Detailed };
|
||||
}
|
||||
}
|
||||
@@ -385,7 +385,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
{
|
||||
"trackedReferencesApiBaseUrl", _linkGenerator.GetUmbracoApiServiceBaseUrl<TrackedReferencesController>(
|
||||
controller => controller.GetPagedReferences(0, 1, 1, false))
|
||||
}
|
||||
},
|
||||
{
|
||||
"analyticsApiBaseUrl", _linkGenerator.GetUmbracoApiServiceBaseUrl<AnalyticsController>(
|
||||
controller => controller.GetConsentLevel())
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -160,6 +160,7 @@ namespace Umbraco.Extensions
|
||||
));
|
||||
|
||||
builder.AddCoreInitialServices();
|
||||
builder.AddTelemetryProviders();
|
||||
|
||||
// aspnet app lifetime mgmt
|
||||
builder.Services.AddUnique<IUmbracoApplicationLifetime, AspNetCoreUmbracoApplicationLifetime>();
|
||||
|
||||
@@ -13,7 +13,7 @@ For extra details about options and events take a look here: https://refreshless
|
||||
<pre>
|
||||
<div ng-controller="My.Controller as vm">
|
||||
|
||||
<umb-range-slider
|
||||
<umb-range-slider
|
||||
ng-model="vm.value"
|
||||
on-end="vm.slideEnd(values)">
|
||||
</umb-range-slider>
|
||||
@@ -229,11 +229,13 @@ For extra details about options and events take a look here: https://refreshless
|
||||
var origins = slider.noUiSlider.getOrigins();
|
||||
|
||||
// Move tooltips into the origin element. The default stylesheet handles this.
|
||||
if(tooltips && tooltips.length !== 0){
|
||||
tooltips.forEach(function (tooltip, index) {
|
||||
if (tooltip) {
|
||||
origins[index].appendChild(tooltip);
|
||||
}
|
||||
if (tooltip) {
|
||||
origins[index].appendChild(tooltip);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
slider.noUiSlider.on('update', function (values, handle, unencoded, tap, positions) {
|
||||
|
||||
@@ -283,7 +285,7 @@ For extra details about options and events take a look here: https://refreshless
|
||||
offset = (textIsRtl && !isVertical ? 100 : 0) + (offset / handlesInPool) - lastOffset;
|
||||
|
||||
// Filter to unique values
|
||||
var tooltipValues = poolValues[poolIndex].filter((v, i, a) => a.indexOf(v) === i);
|
||||
var tooltipValues = poolValues[poolIndex].filter((v, i, a) => a.indexOf(v) === i);
|
||||
|
||||
// Center this tooltip over the affected handles
|
||||
tooltips[handleNumber].innerHTML = tooltipValues.join(separator);
|
||||
|
||||
@@ -20,7 +20,8 @@ Umbraco.Sys.ServerVariables = {
|
||||
"updateCheckApiBaseUrl": "/umbraco/Api/UpdateCheck/",
|
||||
"relationApiBaseUrl": "/umbraco/UmbracoApi/Relation/",
|
||||
"rteApiBaseUrl": "/umbraco/UmbracoApi/RichTextPreValue/",
|
||||
"iconApiBaseUrl": "/umbraco/UmbracoApi/Icon/"
|
||||
"iconApiBaseUrl": "/umbraco/UmbracoApi/Icon/",
|
||||
"analyticsApiBaseUrl": "/umbraco/UmbracoApi/Consent/"
|
||||
},
|
||||
umbracoSettings: {
|
||||
"umbracoPath": "/umbraco",
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name umbraco.resources.consentResource
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* Used by the health check dashboard to get checks and send requests to fix checks.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function analyticResource($http, umbRequestHelper) {
|
||||
|
||||
function getConsentLevel () {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"analyticsApiBaseUrl",
|
||||
"GetConsentLevel")),
|
||||
'Server call failed for getting current consent level');
|
||||
}
|
||||
|
||||
function getAllConsentLevels () {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"analyticsApiBaseUrl",
|
||||
"GetAllLevels")),
|
||||
'Server call failed for getting current consent level');
|
||||
}
|
||||
|
||||
function saveConsentLevel (value) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"analyticsApiBaseUrl",
|
||||
"SetConsentLevel"),
|
||||
{ telemetryLevel : value }
|
||||
),
|
||||
'Server call failed for getting current consent level');
|
||||
}
|
||||
|
||||
var resource = {
|
||||
getConsentLevel: getConsentLevel,
|
||||
getAllConsentLevels : getAllConsentLevels,
|
||||
saveConsentLevel : saveConsentLevel
|
||||
};
|
||||
|
||||
return resource;
|
||||
|
||||
}
|
||||
|
||||
|
||||
angular.module('umbraco.resources').factory('analyticResource', analyticResource);
|
||||
|
||||
|
||||
})();
|
||||
@@ -200,6 +200,10 @@ angular.module('umbraco.services')
|
||||
* localizationService.localizeMany(["speechBubbles_templateErrorHeader", "speechBubbles_templateErrorText"]).then(function(data){
|
||||
* var header = data[0];
|
||||
* var message = data[1];
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* notificationService.error(header, message);
|
||||
* });
|
||||
* </pre>
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function AnalyticsController($q, analyticResource, localizationService, notificationsService) {
|
||||
|
||||
let sliderRef = null;
|
||||
|
||||
var vm = this;
|
||||
vm.getConsentLevel = getConsentLevel;
|
||||
vm.getAllConsentLevels = getAllConsentLevels;
|
||||
vm.saveConsentLevel = saveConsentLevel;
|
||||
vm.sliderChange = sliderChange;
|
||||
vm.setup = setup;
|
||||
vm.loading = true;
|
||||
vm.consentLevel = '';
|
||||
vm.consentLevels = [];
|
||||
vm.val = 1;
|
||||
vm.sliderOptions =
|
||||
{
|
||||
"start": 1,
|
||||
"step": 1,
|
||||
"tooltips": [false],
|
||||
"range": {
|
||||
"min": 1,
|
||||
"max": 3
|
||||
},
|
||||
pips: {
|
||||
mode: 'values',
|
||||
density: 50,
|
||||
values: [1, 2, 3],
|
||||
format: {
|
||||
to: function (value) {
|
||||
return vm.consentLevels[value - 1];
|
||||
},
|
||||
from: function (value) {
|
||||
return Number(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
$q.all(
|
||||
[getConsentLevel(),
|
||||
getAllConsentLevels()
|
||||
]).then( () => {
|
||||
vm.startPos = calculateStartPositionForSlider();
|
||||
vm.sliderVal = vm.consentLevels[vm.startPos - 1];
|
||||
vm.sliderOptions.start = vm.startPos;
|
||||
vm.val = vm.startPos;
|
||||
vm.sliderOptions.pips.format = {
|
||||
to: function (value) {
|
||||
return vm.consentLevels[value - 1];
|
||||
},
|
||||
from: function (value) {
|
||||
return Number(value);
|
||||
}
|
||||
}
|
||||
vm.loading = false;
|
||||
if (sliderRef) {
|
||||
sliderRef.noUiSlider.set(vm.startPos);
|
||||
}
|
||||
|
||||
});
|
||||
function setup(slider) {
|
||||
sliderRef = slider;
|
||||
}
|
||||
|
||||
function getConsentLevel() {
|
||||
return analyticResource.getConsentLevel().then(function (response) {
|
||||
vm.consentLevel = response;
|
||||
})
|
||||
}
|
||||
function getAllConsentLevels(){
|
||||
return analyticResource.getAllConsentLevels().then(function (response) {
|
||||
vm.consentLevels = response;
|
||||
})
|
||||
}
|
||||
function saveConsentLevel(){
|
||||
analyticResource.saveConsentLevel(vm.sliderVal);
|
||||
localizationService.localize("analytics_analyticsLevelSavedSuccess").then(function(value) {
|
||||
notificationsService.success(value);
|
||||
});
|
||||
}
|
||||
|
||||
function sliderChange(values) {
|
||||
const result = Number(values[0]);
|
||||
vm.sliderVal = vm.consentLevels[result - 1];
|
||||
}
|
||||
|
||||
function calculateStartPositionForSlider(){
|
||||
let startPosition = vm.consentLevels.indexOf(vm.consentLevel) + 1;
|
||||
if(startPosition === 0){
|
||||
return 2;// Default start value
|
||||
}
|
||||
return startPosition;
|
||||
}
|
||||
}
|
||||
angular.module("umbraco").controller("Umbraco.Dashboard.AnalyticsController", AnalyticsController);
|
||||
})();
|
||||
@@ -0,0 +1,59 @@
|
||||
<div ng-controller="Umbraco.Dashboard.AnalyticsController as vm">
|
||||
<umb-box>
|
||||
<umb-box-content>
|
||||
<h3 class="bold">
|
||||
<localize key="analytics_consentForAnalytics">Consent for analytics</localize>
|
||||
</h3>
|
||||
<div class="umb-healthcheck-help-text">
|
||||
<p>In order to improve Umbraco and add new functionality based on as relevant information as possible,
|
||||
<br>we would like to collect system- and usage information from your installation.
|
||||
<br>We will NOT collect any personal data like content, code or users, and all data will be fully anonymous.
|
||||
<br>
|
||||
<br>We will on a regular basis share some of the overall learnings from these metrics.
|
||||
Hopefully, you'll help us collect some valuable data.</p>
|
||||
<div ng-if="!vm.loading" style="padding-left: 12px;padding-top: 50px; padding-bottom: 50px; width: 25%">
|
||||
<umb-range-slider
|
||||
ng-model="vm.val"
|
||||
on-setup="vm.setup(slider)"
|
||||
options="vm.sliderOptions"
|
||||
on-update="vm.sliderChange(values)">
|
||||
</umb-range-slider>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<div ng-if="vm.sliderVal === 'Minimal'">
|
||||
<b>{{vm.sliderVal}}</b>
|
||||
<br>We'll only send an anonymous site ID to let us know that the site exists.
|
||||
</div>
|
||||
<div ng-if="vm.sliderVal === 'Basic'">
|
||||
<b>{{vm.sliderVal}}</b>
|
||||
<br>We'll send site ID, umbraco version and packages installed
|
||||
</div>
|
||||
<div ng-if="vm.sliderVal === 'Detailed'">
|
||||
<b>{{vm.sliderVal}}</b>
|
||||
|
||||
<br> We'll send:
|
||||
<br>- Site ID, umbraco version and packages installed
|
||||
<br>- System information like Server OS and Webserver
|
||||
<br>- Statistics, like number of content nodes and number of media items
|
||||
<br>- Configuration settings, like modelsbuilder mode and used languages
|
||||
<br>
|
||||
<br>We might change/extend what we send on the detailed level in the future, but if so, it will be listed in
|
||||
this view.
|
||||
By choosing "detailed" I accept these future changes
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
<div class="umb-panel-group__details-status-actions">
|
||||
<umb-button type="button"
|
||||
button-style="success"
|
||||
label="Save"
|
||||
action="vm.saveConsentLevel()"
|
||||
ng-model="vm.sliderVal" ng-if="vm.consentLevel">
|
||||
</umb-button>
|
||||
</div>
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2508,6 +2508,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
|
||||
<key alias="settingsPublishedStatus">Published Status</key>
|
||||
<key alias="settingsModelsBuilder">Models Builder</key>
|
||||
<key alias="settingsHealthCheck">Health Check</key>
|
||||
<key alias="settingsAnalytics">Analytics</key>
|
||||
<key alias="settingsProfiler">Profiling</key>
|
||||
<key alias="memberIntro">Getting Started</key>
|
||||
<key alias="formsInstall">Install Umbraco Forms</key>
|
||||
@@ -2863,4 +2864,8 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
|
||||
<key alias="searchResult">item returned</key>
|
||||
<key alias="searchResults">items returned</key>
|
||||
</area>
|
||||
<area alias="analytics">
|
||||
<key alias="consentForAnalytics">Consent for analytics</key>
|
||||
<key alias="analyticsLevelSavedSuccess">Analytics level saved!</key>
|
||||
</area>
|
||||
</language>
|
||||
|
||||
Reference in New Issue
Block a user