diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbprogresscircle.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbprogresscircle.directive.js new file mode 100644 index 0000000000..ad79cb2e3b --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbprogresscircle.directive.js @@ -0,0 +1,88 @@ +/** +@ngdoc directive +@name umbraco.directives.directive:umbProgressCircle +@restrict E +@scope + +@description +Use this directive to render a circular progressbar. + +
++ +@param {string} size (+ +++ + +
attribute): This parameter defines the width and the height of the circle in pixels.
+@param {string} percentage (attribute): Takes a number between 0 and 100 and applies it to the circle's highlight length.
+@param {string} color (attribute): the color of the highlight (primary, secondary, success, warning, danger). Success by default.
+**/
+
+(function (){
+ 'use strict';
+
+ function ProgressCircleDirective($http, $timeout) {
+
+ function link(scope, element, $filter) {
+
+ function onInit() {
+
+ // making sure we get the right numbers
+ var percent = scope.percentage;
+
+ if (percent > 100) {
+ percent = 100;
+ }
+ else if (percent < 0) {
+ percent = 0;
+ }
+
+ // calculating the circle's highlight
+ var circle = element.find(".umb-progress-circle__highlight");
+ var r = circle.attr('r');
+ var strokeDashArray = (r*Math.PI)*2;
+
+ // Full circle length
+ scope.strokeDashArray = strokeDashArray;
+
+ var strokeDashOffsetDifference = (percent/100)*strokeDashArray;
+ var strokeDashOffset = strokeDashArray - strokeDashOffsetDifference;
+
+ // Distance for the highlight dash's offset
+ scope.strokeDashOffset = strokeDashOffset;
+
+ // set font size
+ scope.percentageSize = (scope.size * 0.3) + "px";
+
+ }
+
+ onInit();
+ }
+
+
+ var directive = {
+ restrict: 'E',
+ replace: true,
+ templateUrl: 'views/components/umb-progress-circle.html',
+ scope: {
+ size: "@?",
+ percentage: "@",
+ color: "@"
+ },
+ link: link
+
+ };
+
+ return directive;
+ }
+
+ angular.module('umbraco.directives').directive('umbProgressCircle', ProgressCircleDirective);
+
+})();
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tour.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tour.service.js
index aad11af94a..9dea7d74a8 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/tour.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/tour.service.js
@@ -4,6 +4,7 @@
function tourService(eventsService, localStorageService) {
var localStorageKey = "umbTours";
+ var currentTour = null;
var tours = [
{
@@ -23,12 +24,19 @@
content: "These are the Sections and allows you to navigate the different areas of Umbraco.",
backdropOpacity: 0.6
},
+
{
element: "#tree",
elementPreventClick: true,
title: "The Tree",
content: "This is the Tree and will contain all the content of your website."
},
+ {
+ element: "[data-element='editor-content']",
+ elementPreventClick: true,
+ title: "Dashboards",
+ content: "A dashboard is the main view you are presented with when entering a section within the backoffice, and can be used to show valuable information to the users of the system."
+ },
{
element: "[data-element='global-search-field']",
title: "Search",
@@ -66,6 +74,11 @@
title: "Help",
content: "In the help drawer you will find articles and videos related to the section you are using.
This is also where you will find the next tour on how to get started with Umbraco.
", backdropOpacity: 0.6 + }, + { + element: "[data-element='drawer'] [data-element='help-tours']", + title: "Tours", + content: "To continue your journey on getting started with Umbraco, you can find more tours right here." } ] }, @@ -117,9 +130,10 @@ event: "click" }, { - element: "[data-element='group-name']", + element: "[data-element='group-name-field']", title: "Enter a name", - content: "EnterContent in the tab name."
+ content: "Enter Content in the tab name.",
+ view: "tabName"
},
{
element: "[data-element='property-add']",
@@ -192,6 +206,13 @@
content: "The Content section contains the content of the website. Content is displayed as nodes in the content tree.
In this tour we will learn how to create our Home page for our website.
", type: "intro" }, + { + element: "#applications [data-element='section-content']", + title: "Navigate to the content sections", + content: "In the Content section we will find the content of our website.", + event: "click", + backdropOpacity: 0.6 + }, { element: "[data-element='tree-root']", title: "Open context menu", @@ -279,6 +300,13 @@ content: "Our three main components to a page is done: Document type, Template, and Content - it is now time to see the result.
In this tour we will learn how to see our published website.
", type: "intro" }, + { + element: "#applications [data-element='section-content']", + title: "Navigate to the content sections", + content: "In the Content section we will find the content of our website.", + event: "click", + backdropOpacity: 0.6 + }, { element: "#tree [data-element='tree-item-Home']", title: "Open the Home page", @@ -387,15 +415,23 @@ function startTour(tour) { eventsService.emit("appState.tour.start", tour); + currentTour = tour; } function endTour() { + currentTour = null; eventsService.emit("appState.tour.end"); + currentTour = null; } function completeTour(tour) { saveInLocalStorage(tour); eventsService.emit("appState.tour.complete", tour); + currentTour = null; + } + + function getCurrentTour() { + return currentTour; } function getAllTours() { @@ -475,6 +511,7 @@ startTour: startTour, endTour: endTour, completeTour: completeTour, + getCurrentTour: getCurrentTour, getAllTours: getAllTours, getGroupedTours: getGroupedTours, getTourByAlias: getTourByAlias, diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less index 8d7c32a026..6232522611 100644 --- a/src/Umbraco.Web.UI.Client/src/less/belle.less +++ b/src/Umbraco.Web.UI.Client/src/less/belle.less @@ -129,6 +129,8 @@ @import "components/umb-checkmark.less"; @import "components/umb-list.less"; @import "components/umb-box.less"; +@import "components/umb-number-badge.less"; +@import "components/umb-progress-circle.less"; @import "components/buttons/umb-button.less"; @import "components/buttons/umb-button-group.less"; @@ -170,4 +172,4 @@ @import "typeahead.less"; @import "hacks.less"; -@import "healthcheck.less"; +@import "healthcheck.less"; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less b/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less index 46c75486ef..0fae291e72 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/application/umb-drawer.less @@ -149,7 +149,8 @@ border-bottom: 1px solid @gray-9; } -.umb-help-list-item > a { +.umb-help-list-item > a, +.umb-help-list-item__content { display: flex; align-items: center; padding: 10px 20px; @@ -186,4 +187,8 @@ font-size: 14px; color: @gray-6; margin-left: auto; +} + +.umb-help-list-item:hover .umb-help-list-item__group-title { + text-decoration: underline; } \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button.less b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button.less index c161d8d62d..ab8b6b0671 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button.less @@ -99,6 +99,11 @@ } /* Sizes */ +.umb-button--xxs { + padding: 2px 10px; + font-size: 13px; +} + .umb-button--xs { padding: 5px 16px; font-size: 14px; diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-number-badge.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-number-badge.less new file mode 100644 index 0000000000..d35abff550 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-number-badge.less @@ -0,0 +1,40 @@ +.umb-number-badge { + border: 1px solid @gray-6; + width: 25px; + height: 25px; + border-radius: 50%; + box-sizing: border-box; + display: flex; + justify-content: center; + align-items: center; + color: @black; + font-size: 15px; +} + +.umb-number-badge--xs { + width: 20px; + height: 20px; + font-size: 13px; +} + +.umb-number-badge--s { + width: 25px; + height: 25px; +} + +.umb-number-badge--m { + width: 30px; + height: 30px; +} + +.umb-number-badge--l { + width: 40px; + height: 40px; + font-size: 18px; +} + +.umb-number-badge--xl { + width: 50px; + height: 50px; + font-size: 20px; +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-progress-circle.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-progress-circle.less new file mode 100644 index 0000000000..348d7bb5db --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-progress-circle.less @@ -0,0 +1,49 @@ +.umb-progress-circle { + position: relative; +} + +.umb-progress-circle__view-box { + position: absolute; + -webkit-transform: rotate(-90deg); + -moz-transform: rotate(-90deg); + -o-transform: rotate(-90deg); + -ms-transform: rotate(-90deg); + transform: rotate(-90deg); +} + +// circle highlight on progressbar +.umb-progress-circle__highlight { + stroke: @green; +} + +.umb-progress-circle__highlight--primary { + stroke: @turquoise; +} + +.umb-progress-circle__highlight--secondary { + stroke: @purple; +} + +.umb-progress-circle__highlight--success { + stroke: @green; +} + +.umb-progress-circle__highlight--warning { + stroke: @yellow; +} + +.umb-progress-circle__highlight--danger { + stroke: @red; +} + +// circle progressbar bg +.umb-progress-circle__bg { + stroke: @gray-8; +} + +// the text in the center +.umb-progress-circle__percentage { + font-size: 16px; + font-weight: bold; + text-align: center; +} diff --git a/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.controller.js index ec5ea13639..b4773cdaad 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function HelpDrawerController($scope, $routeParams, $timeout, dashboardResource, localizationService, userService, eventsService, helpService, appState) { + function HelpDrawerController($scope, $routeParams, $timeout, dashboardResource, localizationService, userService, eventsService, helpService, appState, tourService, $filter) { var vm = this; var evts = []; @@ -12,11 +12,22 @@ vm.tree = $routeParams.tree; vm.sectionName = ""; vm.customDashboard = null; + vm.tours = []; vm.closeDrawer = closeDrawer; + vm.startTour = startTour; + vm.getTourGroupCompletedPercentage = getTourGroupCompletedPercentage; + vm.showTourButton = showTourButton; + + function startTour(tour) { + tourService.startTour(tour); + closeDrawer(); + } function oninit() { + vm.tours = tourService.getGroupedTours(); + // load custom help dashboard dashboardResource.getDashboard("user-help").then(function (dashboard) { vm.customDashboard = dashboard; @@ -41,6 +52,15 @@ }); + getTourGroupCompletedPercentage(); + + // check if a tour is running - if it is open the matching group + var currentTour = tourService.getCurrentTour(); + + if (currentTour) { + openTourGroup(currentTour.alias); + } + } function closeDrawer() { @@ -101,7 +121,45 @@ }); } - oninit(); + function showTourButton(index, tourGroup) { + if(index !== 0) { + var prevTour = tourGroup[index - 1]; + if(prevTour.completed) { + return true; + } + } else { + return true; + } + } + + function openTourGroup(tourAlias) { + angular.forEach(vm.tours, function (group) { + angular.forEach(group, function (tour) { + if (tour.alias === tourAlias) { + group.open = true; + } + }); + }); + } + + function getTourGroupCompletedPercentage() { + // Finding out, how many tours are completed for the progress circle + angular.forEach(vm.tours, function(group){ + var completedTours = 0; + angular.forEach(group, function(tour){ + if(tour.completed) { + completedTours++; + } + }); + group.completedPercentage = Math.round((completedTours/group.length)*100); + }); + } + + evts.push(eventsService.on("appState.tour.complete", function (event, tour) { + vm.tours = tourService.getGroupedTours(); + openTourGroup(tour.alias); + getTourGroupCompletedPercentage(); + })); $scope.$on('$destroy', function () { for (var e in evts) { @@ -109,6 +167,8 @@ } }); + oninit(); + } angular.module("umbraco").controller("Umbraco.Drawers.Help", HelpDrawerController); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.html b/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.html index 35deec56ca..cefbe3d89e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/drawers/help/help.html @@ -4,11 +4,49 @@ title="{{ vm.title }}" description="{{ vm.subtitle }}"> - +