Merge pull request #11230 from umbraco/v9/feature/debug-dashboard
v9: Created new system information section in help panel
This commit is contained in:
@@ -180,6 +180,7 @@ namespace Umbraco.Cms.Core.DependencyInjection
|
||||
Services.AddUnique<UriUtility>();
|
||||
|
||||
Services.AddUnique<IDashboardService, DashboardService>();
|
||||
Services.AddUnique<IUserDataService, UserDataService>();
|
||||
|
||||
// will be injected in controllers when needed to invoke rest endpoints on Our
|
||||
Services.AddUnique<IInstallationService, InstallationService>();
|
||||
|
||||
19
src/Umbraco.Core/Models/UserData.cs
Normal file
19
src/Umbraco.Core/Models/UserData.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Cms.Core.Models
|
||||
{
|
||||
[DataContract]
|
||||
public class UserData
|
||||
{
|
||||
[DataMember(Name = "name")]
|
||||
public string Name { get; }
|
||||
[DataMember(Name = "data")]
|
||||
public string Data { get; }
|
||||
|
||||
public UserData(string name, string data)
|
||||
{
|
||||
Name = name;
|
||||
Data = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/Umbraco.Core/Services/IUserDataService.cs
Normal file
10
src/Umbraco.Core/Services/IUserDataService.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services
|
||||
{
|
||||
public interface IUserDataService
|
||||
{
|
||||
IEnumerable<UserData> GetUserData();
|
||||
}
|
||||
}
|
||||
48
src/Umbraco.Core/Services/UserDataService.cs
Normal file
48
src/Umbraco.Core/Services/UserDataService.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using Umbraco.Cms.Core.Configuration;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services
|
||||
{
|
||||
public class UserDataService : IUserDataService
|
||||
{
|
||||
private readonly IUmbracoVersion _version;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
|
||||
public UserDataService(IUmbracoVersion version, ILocalizationService localizationService)
|
||||
{
|
||||
_version = version;
|
||||
_localizationService = localizationService;
|
||||
}
|
||||
|
||||
public IEnumerable<UserData> GetUserData() =>
|
||||
new List<UserData>
|
||||
{
|
||||
new("Server OS", RuntimeInformation.OSDescription),
|
||||
new("Server Framework", RuntimeInformation.FrameworkDescription),
|
||||
new("Default Language", _localizationService.GetDefaultLanguageIsoCode()),
|
||||
new("Umbraco Version", _version.SemanticVersion.ToSemanticStringWithoutBuild()),
|
||||
new("Current Culture", Thread.CurrentThread.CurrentCulture.ToString()),
|
||||
new("Current UI Culture", Thread.CurrentThread.CurrentUICulture.ToString()),
|
||||
new("Current Webserver", GetCurrentWebServer())
|
||||
};
|
||||
|
||||
private string GetCurrentWebServer() => IsRunningInProcessIIS() ? "IIS" : "Kestrel";
|
||||
|
||||
public 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,47 @@
|
||||
/// <reference types="Cypress" />
|
||||
|
||||
function openSystemInformation(){
|
||||
//We have to wait for page to load, if the site is slow
|
||||
cy.get('[data-element="global-help"]').should('be.visible').click();
|
||||
cy.get('.umb-help-list-item').last().should('be.visible').click();
|
||||
cy.get('.umb-drawer-content').scrollTo('bottom', {ensureScrollable : false});
|
||||
}
|
||||
|
||||
context('System Information', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
//arrange
|
||||
cy.umbracoLogin(Cypress.env('username'), Cypress.env('password'));
|
||||
cy.umbracoSetCurrentUserLanguage('en-US');
|
||||
});
|
||||
afterEach(() => {
|
||||
cy.umbracoSetCurrentUserLanguage('en-US');
|
||||
});
|
||||
|
||||
it('Check System Info Displays', () => {
|
||||
openSystemInformation();
|
||||
cy.get('.table').find('tr').should('have.length', 10);
|
||||
cy.contains('Current Culture').parent().should('contain', 'en-US');
|
||||
cy.contains('Current UI Culture').parent().should('contain', 'en-US');
|
||||
});
|
||||
|
||||
it('Checks language displays correctly after switching', () => {
|
||||
|
||||
//Navigate to edit user and change language
|
||||
cy.umbracoGlobalUser().click();
|
||||
cy.get('[alias="editUser"]').click();
|
||||
cy.get('[name="culture"]').select('string:da-DK', { force: true});
|
||||
cy.umbracoButtonByLabelKey('buttons_save').click({force: true});
|
||||
//Refresh site to display new language
|
||||
cy.reload();
|
||||
cy.get('.umb-tour-step', { timeout: 60000 }).should('be.visible'); // We now due to the api calls this will be shown, but slow computers can take a while
|
||||
cy.get('.umb-tour-step__close').click();
|
||||
openSystemInformation();
|
||||
//Assert
|
||||
cy.contains('Current Culture').parent().should('contain', 'da-DK');
|
||||
cy.contains('Current UI Culture').parent().should('contain', 'da-DK');
|
||||
cy.get('.umb-button__content').last().click();
|
||||
//Clean
|
||||
cy.umbracoSetCurrentUserLanguage('en-US');
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -100,4 +100,4 @@ function runBackOfficeIntroTour(percentageComplete, buttonText, timeout) {
|
||||
cy.get('.umb-tour-step__footer .umb-button').should('be.visible').click();
|
||||
|
||||
cy.umbracoGlobalHelp().should("be.visible");
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
"del": "^6.0.0",
|
||||
"ncp": "^2.0.0",
|
||||
"prompt": "^1.0.0",
|
||||
"umbraco-cypress-testhelpers": "^1.0.0-beta-57"
|
||||
"umbraco-cypress-testhelpers": "^1.0.0-beta-58"
|
||||
},
|
||||
"dependencies": {
|
||||
"typescript": "^3.9.2"
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Configuration;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Semver;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Services
|
||||
{
|
||||
[TestFixture]
|
||||
public class UserDataServiceTests
|
||||
{
|
||||
private IUmbracoVersion _umbracoVersion;
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void CreateMocks() => CreateUmbracoVersion(9, 0, 0);
|
||||
|
||||
[Test]
|
||||
[TestCase("en-US")]
|
||||
[TestCase("de-DE")]
|
||||
[TestCase("en-NZ")]
|
||||
[TestCase("sv-SE")]
|
||||
public void GetCorrectDefaultLanguageTest(string culture)
|
||||
{
|
||||
var userDataService = CreateUserDataService(culture);
|
||||
var defaultLanguage = userDataService.GetUserData().FirstOrDefault(x => x.Name == "Default Language");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsNotNull(defaultLanguage);
|
||||
Assert.AreEqual(culture, defaultLanguage.Data);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("en-US")]
|
||||
[TestCase("de-DE")]
|
||||
[TestCase("en-NZ")]
|
||||
[TestCase("sv-SE")]
|
||||
public void GetCorrectCultureTest(string culture)
|
||||
{
|
||||
Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
|
||||
var userDataService = CreateUserDataService(culture);
|
||||
var currentCulture = userDataService.GetUserData().FirstOrDefault(x => x.Name == "Current Culture");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsNotNull(currentCulture);
|
||||
Assert.AreEqual(culture, currentCulture.Data);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("en-US")]
|
||||
[TestCase("de-DE")]
|
||||
[TestCase("en-NZ")]
|
||||
[TestCase("sv-SE")]
|
||||
public void GetCorrectUICultureTest(string culture)
|
||||
{
|
||||
Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
|
||||
var userDataService = CreateUserDataService(culture);
|
||||
var currentCulture = userDataService.GetUserData().FirstOrDefault(x => x.Name == "Current UI Culture");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsNotNull(currentCulture);
|
||||
Assert.AreEqual(culture, currentCulture.Data);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
[TestCase("en-US")]
|
||||
[TestCase("de-DE")]
|
||||
[TestCase("en-NZ")]
|
||||
[TestCase("sv-SE")]
|
||||
public void RunTimeInformationNotNullTest(string culture)
|
||||
{
|
||||
var userDataService = CreateUserDataService(culture);
|
||||
IEnumerable<UserData> userData = userDataService.GetUserData().ToList();
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.IsNotNull(userData.Select(x => x.Name == "Server OS"));
|
||||
Assert.IsNotNull(userData.Select(x => x.Name == "Server Framework"));
|
||||
Assert.IsNotNull(userData.Select(x => x.Name == "Current Webserver"));
|
||||
});
|
||||
}
|
||||
|
||||
private UserDataService CreateUserDataService(string culture)
|
||||
{
|
||||
var localizationService = CreateILocalizationService(culture);
|
||||
return new UserDataService(_umbracoVersion, localizationService);
|
||||
}
|
||||
|
||||
private ILocalizationService CreateILocalizationService(string culture)
|
||||
{
|
||||
var localizationService = new Mock<ILocalizationService>();
|
||||
localizationService.Setup(x => x.GetDefaultLanguageIsoCode()).Returns(culture);
|
||||
return localizationService.Object;
|
||||
}
|
||||
|
||||
private void CreateUmbracoVersion(int major, int minor, int patch)
|
||||
{
|
||||
var umbracoVersion = new Mock<IUmbracoVersion>();
|
||||
var semVersion = new SemVersion(major, minor, patch);
|
||||
umbracoVersion.Setup(x => x.SemanticVersion).Returns(semVersion);
|
||||
_umbracoVersion = umbracoVersion.Object;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Cms.Core;
|
||||
@@ -22,11 +22,10 @@ using Umbraco.Cms.Core.Models.Membership;
|
||||
using Umbraco.Cms.Core.Security;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Cms.Web.BackOffice.Extensions;
|
||||
using Umbraco.Cms.Web.BackOffice.Filters;
|
||||
using Umbraco.Cms.Web.Common.ActionsResults;
|
||||
using Umbraco.Cms.Web.Common.Attributes;
|
||||
using Umbraco.Cms.Web.Common.Authorization;
|
||||
using Umbraco.Cms.Web.Common.DependencyInjection;
|
||||
using Umbraco.Cms.Web.Common.Security;
|
||||
using Umbraco.Extensions;
|
||||
using Constants = Umbraco.Cms.Core.Constants;
|
||||
@@ -47,12 +46,13 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
private readonly IUserService _userService;
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
private readonly IBackOfficeUserManager _backOfficeUserManager;
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
private readonly ILocalizedTextService _localizedTextService;
|
||||
private readonly AppCaches _appCaches;
|
||||
private readonly IShortStringHelper _shortStringHelper;
|
||||
private readonly IPasswordChanger<BackOfficeIdentityUser> _passwordChanger;
|
||||
private readonly IUserDataService _userDataService;
|
||||
|
||||
[ActivatorUtilitiesConstructor]
|
||||
public CurrentUserController(
|
||||
MediaFileManager mediaFileManager,
|
||||
IOptions<ContentSettings> contentSettings,
|
||||
@@ -62,11 +62,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
IUserService userService,
|
||||
IUmbracoMapper umbracoMapper,
|
||||
IBackOfficeUserManager backOfficeUserManager,
|
||||
ILoggerFactory loggerFactory,
|
||||
ILocalizedTextService localizedTextService,
|
||||
AppCaches appCaches,
|
||||
IShortStringHelper shortStringHelper,
|
||||
IPasswordChanger<BackOfficeIdentityUser> passwordChanger)
|
||||
IPasswordChanger<BackOfficeIdentityUser> passwordChanger,
|
||||
IUserDataService userDataService)
|
||||
{
|
||||
_mediaFileManager = mediaFileManager;
|
||||
_contentSettings = contentSettings.Value;
|
||||
@@ -76,11 +76,42 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
_userService = userService;
|
||||
_umbracoMapper = umbracoMapper;
|
||||
_backOfficeUserManager = backOfficeUserManager;
|
||||
_loggerFactory = loggerFactory;
|
||||
_localizedTextService = localizedTextService;
|
||||
_appCaches = appCaches;
|
||||
_shortStringHelper = shortStringHelper;
|
||||
_passwordChanger = passwordChanger;
|
||||
_userDataService = userDataService;
|
||||
}
|
||||
|
||||
[Obsolete("This constructor is obsolete and will be removed in v11, use constructor with all values")]
|
||||
public CurrentUserController(
|
||||
MediaFileManager mediaFileManager,
|
||||
IOptions<ContentSettings> contentSettings,
|
||||
IHostingEnvironment hostingEnvironment,
|
||||
IImageUrlGenerator imageUrlGenerator,
|
||||
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
|
||||
IUserService userService,
|
||||
IUmbracoMapper umbracoMapper,
|
||||
IBackOfficeUserManager backOfficeUserManager,
|
||||
ILocalizedTextService localizedTextService,
|
||||
AppCaches appCaches,
|
||||
IShortStringHelper shortStringHelper,
|
||||
IPasswordChanger<BackOfficeIdentityUser> passwordChanger) : this(
|
||||
mediaFileManager,
|
||||
contentSettings,
|
||||
hostingEnvironment,
|
||||
imageUrlGenerator,
|
||||
backofficeSecurityAccessor,
|
||||
userService,
|
||||
umbracoMapper,
|
||||
backOfficeUserManager,
|
||||
localizedTextService,
|
||||
appCaches,
|
||||
shortStringHelper,
|
||||
passwordChanger,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IUserDataService>())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -167,6 +198,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
return userTours;
|
||||
}
|
||||
|
||||
public IEnumerable<UserData> GetUserData() => _userDataService.GetUserData();
|
||||
|
||||
/// <summary>
|
||||
/// When a user is invited and they click on the invitation link, they will be partially logged in
|
||||
/// where they can set their username/password
|
||||
|
||||
@@ -51,7 +51,6 @@ function currentUserResource($q, $http, umbRequestHelper, umbDataFormatter) {
|
||||
[{ permissionToCheck: permission }, { nodeId: id }])),
|
||||
'Failed to check permission for item ' + id);
|
||||
},
|
||||
|
||||
getCurrentUserLinkedLogins: function () {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
@@ -61,6 +60,14 @@ function currentUserResource($q, $http, umbRequestHelper, umbDataFormatter) {
|
||||
"GetCurrentUserLinkedLogins")),
|
||||
'Server call failed for getting current users linked logins');
|
||||
},
|
||||
getUserData: function () {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"currentUserApiBaseUrl",
|
||||
"GetUserData")),
|
||||
'Server call failed for getting current user data');
|
||||
},
|
||||
|
||||
saveTourStatus: function (tourStatus) {
|
||||
|
||||
|
||||
@@ -1,23 +1,84 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function platformService() {
|
||||
function platformService() {
|
||||
const userAgentRules = [
|
||||
['Aol', /AOLShield\/([0-9\._]+)/],
|
||||
['Edge', /Edge\/([0-9\._]+)/],
|
||||
['Edge-ios', /EdgiOS\/([0-9\._]+)/],
|
||||
['Yandexbrowser', /YaBrowser\/([0-9\._]+)/],
|
||||
['Kakaotalk', /KAKAOTALK\s([0-9\.]+)/],
|
||||
['Samsung', /SamsungBrowser\/([0-9\.]+)/],
|
||||
['Silk', /\bSilk\/([0-9._-]+)\b/],
|
||||
['MiUI', /MiuiBrowser\/([0-9\.]+)$/],
|
||||
['Beaker', /BeakerBrowser\/([0-9\.]+)/],
|
||||
['Edge-chromium', /EdgA?\/([0-9\.]+)/],
|
||||
['chromium-webview', /(?!Chrom.*OPR)wv\).*Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/],
|
||||
['Chrome', /(?!Chrom.*OPR)Chrom(?:e|ium)\/([0-9\.]+)(:?\s|$)/],
|
||||
['PhantomJS', /PhantomJS\/([0-9\.]+)(:?\s|$)/],
|
||||
['Crios', /CriOS\/([0-9\.]+)(:?\s|$)/],
|
||||
['Firefox', /Firefox\/([0-9\.]+)(?:\s|$)/],
|
||||
['FxiOS', /FxiOS\/([0-9\.]+)/],
|
||||
['Opera-mini', /Opera Mini.*Version\/([0-9\.]+)/],
|
||||
['Opera', /Opera\/([0-9\.]+)(?:\s|$)/],
|
||||
['Opera', /OPR\/([0-9\.]+)(:?\s|$)/],
|
||||
['IE', /Trident\/7\.0.*rv\:([0-9\.]+).*\).*Gecko$/],
|
||||
['IE', /MSIE\s([0-9\.]+);.*Trident\/[4-7].0/],
|
||||
['IE', /MSIE\s(7\.0)/],
|
||||
['BB10', /BB10;\sTouch.*Version\/([0-9\.]+)/],
|
||||
['Android', /Android\s([0-9\.]+)/],
|
||||
['iOS', /Version\/([0-9\._]+).*Mobile.*Safari.*/],
|
||||
['Safari', /Version\/([0-9\._]+).*Safari/],
|
||||
['Facebook', /FB[AS]V\/([0-9\.]+)/],
|
||||
['Instagram', /Instagram\s([0-9\.]+)/],
|
||||
['iOS-webview', /AppleWebKit\/([0-9\.]+).*Mobile/],
|
||||
['iOS-webview', /AppleWebKit\/([0-9\.]+).*Gecko\)$/],
|
||||
['Curl', /^curl\/([0-9\.]+)$/]
|
||||
];
|
||||
|
||||
function isMac() {
|
||||
return navigator.platform.toUpperCase().indexOf('MAC')>=0;
|
||||
}
|
||||
function isMac() {
|
||||
return navigator.platform.toUpperCase().indexOf('MAC') >= 0;
|
||||
}
|
||||
|
||||
////////////
|
||||
|
||||
var service = {
|
||||
isMac: isMac
|
||||
function getBrowserInfo(){
|
||||
let data = matchUserAgent(navigator.userAgent);
|
||||
console.log(data);
|
||||
if(data){
|
||||
const test = data[1];
|
||||
return {
|
||||
name : data[0],
|
||||
version : test[1]
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return service;
|
||||
function matchUserAgent(ua) {
|
||||
return (ua !== '' && userAgentRules.reduce (
|
||||
(matched, [browser, regex]) => {
|
||||
if (matched) {
|
||||
return matched;
|
||||
}
|
||||
const uaMatch = regex.exec(ua);
|
||||
return !!uaMatch && [browser, uaMatch];
|
||||
},
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
////////////
|
||||
|
||||
angular.module('umbraco.services').factory('platformService', platformService);
|
||||
var service = {
|
||||
isMac: isMac,
|
||||
getBrowserInfo : getBrowserInfo
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
}
|
||||
|
||||
angular.module('umbraco.services').factory('platformService', platformService);
|
||||
|
||||
|
||||
})();
|
||||
|
||||
@@ -101,9 +101,9 @@
|
||||
}
|
||||
|
||||
/* Make sure typography looks good */
|
||||
.umb-help-article h1,
|
||||
.umb-help-article h2,
|
||||
.umb-help-article h3,
|
||||
.umb-help-article h1,
|
||||
.umb-help-article h2,
|
||||
.umb-help-article h3,
|
||||
.umb-help-article h4 {
|
||||
line-height: 1.3em;
|
||||
font-weight: bold;
|
||||
@@ -138,7 +138,7 @@
|
||||
}
|
||||
|
||||
.umb-help-section__title {
|
||||
margin:0 0 10px;
|
||||
margin:0 0 10px;
|
||||
}
|
||||
|
||||
/* Help list */
|
||||
@@ -147,10 +147,10 @@
|
||||
list-style: none;
|
||||
margin-left: 0;
|
||||
margin-bottom: 0;
|
||||
background: @white;
|
||||
background: @white;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 1px 0 rgba(0,0,0,0.16);
|
||||
|
||||
|
||||
[data-element*="help-tours"] & {
|
||||
margin-bottom:5px;
|
||||
}
|
||||
@@ -166,9 +166,20 @@
|
||||
border: 0 none;
|
||||
}
|
||||
|
||||
|
||||
.umb-help-list-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.umb-help-list-item__title-wrapper {
|
||||
display:flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.umb-help-list-item {
|
||||
flex: 1 0 auto;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-help-list-item__group-title i {
|
||||
margin-right:2px;
|
||||
@@ -185,7 +196,7 @@
|
||||
.umb-help-list-item:hover,
|
||||
.umb-help-list-item:focus,
|
||||
.umb-help-list-item:active,
|
||||
.umb-help-list-item > a:hover,
|
||||
.umb-help-list-item > a:hover,
|
||||
.umb-help-list-item > a:focus,
|
||||
.umb-help-list-item > a:active {
|
||||
text-decoration: none;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function HelpDrawerController($scope, $routeParams, $timeout, dashboardResource, localizationService, userService, eventsService, helpService, appState, tourService, $filter, editorState) {
|
||||
function HelpDrawerController($scope, $routeParams, $timeout, dashboardResource, localizationService, userService, eventsService, helpService, appState, tourService, $filter, editorState, notificationsService, currentUserResource, platformService) {
|
||||
|
||||
var vm = this;
|
||||
var evts = [];
|
||||
|
||||
vm.title = "";
|
||||
vm.subtitle = "Umbraco version" + " " + Umbraco.Sys.ServerVariables.application.version;
|
||||
vm.section = $routeParams.section;
|
||||
@@ -13,16 +12,19 @@
|
||||
vm.sectionName = "";
|
||||
vm.customDashboard = null;
|
||||
vm.tours = [];
|
||||
vm.systemInfoDisplay = false;
|
||||
|
||||
vm.closeDrawer = closeDrawer;
|
||||
vm.startTour = startTour;
|
||||
vm.getTourGroupCompletedPercentage = getTourGroupCompletedPercentage;
|
||||
vm.showTourButton = showTourButton;
|
||||
vm.copyInformation = copyInformation;
|
||||
|
||||
vm.showDocTypeTour = false;
|
||||
vm.docTypeTours = [];
|
||||
vm.systemInfo = [];
|
||||
vm.nodeName = '';
|
||||
|
||||
|
||||
function startTour(tour) {
|
||||
tourService.startTour(tour);
|
||||
closeDrawer();
|
||||
@@ -34,7 +36,14 @@
|
||||
localizationService.localize("general_help").then(function(data){
|
||||
vm.title = data;
|
||||
});
|
||||
|
||||
currentUserResource.getUserData().then(function(systemInfo){
|
||||
vm.systemInfo = systemInfo;
|
||||
let browserInfo = platformService.getBrowserInfo();
|
||||
if(browserInfo != null){
|
||||
vm.systemInfo.push({name :"Browser", data: browserInfo.name + " " + browserInfo.version});
|
||||
}
|
||||
vm.systemInfo.push({name :"Browser OS", data: getPlatform()});
|
||||
});
|
||||
tourService.getGroupedTours().then(function(groupedTours) {
|
||||
vm.tours = groupedTours;
|
||||
getTourGroupCompletedPercentage();
|
||||
@@ -52,11 +61,11 @@
|
||||
setSectionName();
|
||||
|
||||
userService.getCurrentUser().then(function (user) {
|
||||
|
||||
|
||||
vm.userType = user.userType;
|
||||
vm.userLang = user.locale;
|
||||
|
||||
vm.hasAccessToSettings = _.contains(user.allowedSections, 'settings');
|
||||
vm.hasAccessToSettings = _.contains(user.allowedSections, 'settings');
|
||||
|
||||
evts.push(eventsService.on("appState.treeState.changed", function (e, args) {
|
||||
handleSectionChange();
|
||||
@@ -72,7 +81,7 @@
|
||||
});
|
||||
|
||||
setDocTypeTour(editorState.getCurrent());
|
||||
|
||||
|
||||
// check if a tour is running - if it is open the matching group
|
||||
var currentTour = tourService.getCurrentTour();
|
||||
|
||||
@@ -89,7 +98,7 @@
|
||||
function handleSectionChange() {
|
||||
$timeout(function () {
|
||||
if (vm.section !== $routeParams.section || vm.tree !== $routeParams.tree) {
|
||||
|
||||
|
||||
vm.section = $routeParams.section;
|
||||
vm.tree = $routeParams.tree;
|
||||
|
||||
@@ -107,7 +116,7 @@
|
||||
vm.topics = topics;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
var rq = {};
|
||||
rq.section = vm.section;
|
||||
@@ -134,7 +143,7 @@
|
||||
helpService.findVideos(rq).then(function (videos) {
|
||||
vm.videos = videos;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setSectionName() {
|
||||
@@ -190,7 +199,7 @@
|
||||
tourService.getToursForDoctype(node.contentTypeAlias).then(function (data) {
|
||||
if (data && data.length > 0) {
|
||||
vm.docTypeTours = data;
|
||||
var currentVariant = _.find(node.variants, (x) => x.active);
|
||||
var currentVariant = _.find(node.variants, (x) => x.active);
|
||||
vm.nodeName = currentVariant.name;
|
||||
vm.showDocTypeTour = true;
|
||||
}
|
||||
@@ -198,7 +207,23 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function copyInformation(){
|
||||
let copyText = "<html>\n<body>\n<!--StartFragment-->\n\nCategory | Data\n-- | --\n";
|
||||
vm.systemInfo.forEach(function (info){
|
||||
copyText += info.name + " | " + info.data + "\n";
|
||||
});
|
||||
copyText += "\n<!--EndFragment-->\n</body>\n</html>"
|
||||
navigator.clipboard.writeText(copyText);
|
||||
if(copyText != null){
|
||||
notificationsService.success("Copied!", "Your system information is now in your clipboard");
|
||||
}
|
||||
else{
|
||||
notificationsService.error("Error", "Could not copy system information");
|
||||
}
|
||||
}
|
||||
function getPlatform() {
|
||||
return window.navigator.platform;
|
||||
}
|
||||
evts.push(eventsService.on("appState.tour.complete", function (event, tour) {
|
||||
tourService.getGroupedTours().then(function(groupedTours) {
|
||||
vm.tours = groupedTours;
|
||||
@@ -206,7 +231,7 @@
|
||||
getTourGroupCompletedPercentage();
|
||||
});
|
||||
}));
|
||||
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
for (var e in evts) {
|
||||
eventsService.unsubscribe(evts[e]);
|
||||
|
||||
@@ -149,6 +149,47 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- System info -->
|
||||
<div class="umb-help-section">
|
||||
|
||||
<h5 class="umb-help-section__title">System Information</h5>
|
||||
<div class="umb-help-list">
|
||||
<div class="umb-help-list-item__title-wrapper">
|
||||
<button
|
||||
type="button"
|
||||
class="umb-help-list-item umb-help-list-item__content"
|
||||
ng-click="vm.systemInfoDisplay = !vm.systemInfoDisplay"
|
||||
aria-expanded="{{vm.systemInfoDisplay === true}}">
|
||||
<umb-icon class="mr1" icon="{{vm.systemInfoDisplay ? 'icon-navigation-down' : 'icon-navigation-right'}}"></umb-icon>
|
||||
<span class="flex-column items-start flex">
|
||||
<span class="umb-help-list-item__group-title bold">System Information</span>
|
||||
<span class="umb-help-list-item__description mt0">View your system information</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
ng-click="vm.copyInformation()"
|
||||
class="btn-reset"
|
||||
type="button"
|
||||
size="30">
|
||||
<span class="">
|
||||
<umb-icon icon="icon-documents" class="umb-help-list-item__icon"></umb-icon>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div ng-if="vm.systemInfoDisplay === true">
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>Category</th>
|
||||
<th>Data</th>
|
||||
</tr>
|
||||
<tr ng-repeat="info in vm.systemInfo">
|
||||
<td>{{info.name}}</td>
|
||||
<td>{{info.data}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</umb-drawer-content>
|
||||
|
||||
<umb-drawer-footer>
|
||||
|
||||
Reference in New Issue
Block a user