Merge branch 'v8/dev' into v8/feature/search-media-files

This commit is contained in:
Jeavon
2019-11-12 10:12:03 +00:00
164 changed files with 2715 additions and 1104 deletions
+3 -1
View File
@@ -39,6 +39,8 @@ To build Umbraco, fire up PowerShell and move to Umbraco's repository root (the
build/build.ps1
If you only see a build.bat-file, you're probably on the wrong branch. If you switch to the correct branch (dev-v8) the file will appear and you can build it.
You might run into [Powershell quirks](#powershell-quirks).
### Build Infrastructure
@@ -209,4 +211,4 @@ The best solution is to unblock the Zip file before un-zipping: right-click the
### Git Quirks
Git might have issues dealing with long file paths during build. You may want/need to enable `core.longpaths` support (see [this page](https://github.com/msysgit/msysgit/wiki/Git-cannot-create-a-file-or-directory-with-a-long-path) for details).
Git might have issues dealing with long file paths during build. You may want/need to enable `core.longpaths` support (see [this page](https://github.com/msysgit/msysgit/wiki/Git-cannot-create-a-file-or-directory-with-a-long-path) for details).
+7 -6
View File
@@ -2,15 +2,15 @@
👍🎉 First off, thanks for taking the time to contribute! 🎉👍
The following is a set of guidelines for contributing to Umbraco CMS.
The following is a set of guidelines, for contributing to Umbraco CMS.
These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request.
These are mostly guidelines, not rules. Use your best judgement, and feel free to propose changes to this document in a pull request.
Remember, we're a friendly bunch and are happy with whatever contribution you might provide. Below are guidelines for success that we've gathered over the years. If you choose to ignore them then we still love you 💖.
**Code of conduct**
This project and everyone participating in it is governed by the [our Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [Sebastiaan Janssen - sj@umbraco.dk](mailto:sj@umbraco.dk).
This project and everyone participating in it, is governed by the [our Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [Sebastiaan Janssen - sj@umbraco.dk](mailto:sj@umbraco.dk).
**Table of contents**
@@ -59,7 +59,8 @@ Great question! The short version goes like this:
* **Clone** - when GitHub has created your fork, you can clone it in your favorite Git tool
![Clone the fork](img/clonefork.png)
* **Switch to the correct branch** - switch to the v8-dev branch
* **Build** - build your fork of Umbraco locally as described in [building Umbraco from source code](BUILD.md)
* **Change** - make your changes, experiment, have fun, explore and learn, and don't be afraid. We welcome all contributions and will [happily give feedback](#questions)
* **Commit** - done? Yay! 🎉 **Important:** create a new branch now and name it after the issue you're fixing, we usually follow the format: `temp-12345`. This means it's a temporary branch for the particular issue you're working on, in this case `12345`. When you have a branch, commit your changes. Don't commit to `v8/dev`, create a new branch first.
@@ -169,9 +170,9 @@ If you make the corrections we ask for in the same branch and push them to your
### Keeping your Umbraco fork in sync with the main repository
We recommend you sync with our repository before you submit your pull request. That way, you can fix any potential merge conflicts and make our lives a little bit easier.
We recommend you to sync with our repository before you submit your pull request. That way, you can fix any potential merge conflicts and make our lives a little bit easier.
Also, if you submitted a pull request three weeks ago and want to work on something new, you'll want to get the latest code to build against of course.
Also, if you have submitted a pull request three weeks ago and want to work on something new, you'll want to get the latest code to build against of course.
To sync your fork with this original one, you'll have to add the upstream url. You only have to do this once:
+5 -5
View File
@@ -7,15 +7,15 @@ A brief description of the issue goes here.
<!--
If you haven't yet done so, please read the "contributing guidelines"
thoroughly. Then, proceed by filling out the rest of the details in the issue
template below. The more details you can give us, the easier it will be for us
Please fill out the rest of the details in the issue template below.
The more details you can give us, the easier it will be for us
to determine the cause of a problem.
See: https://github.com/umbraco/Umbraco-CMS/blob/v8/dev/.github/CONTRIBUTING.md
-->
## Umbraco version
I am seeing this issue on Umbraco version: <!-- please note the version here -->
Reproduction
+2 -2
View File
@@ -21,7 +21,7 @@ Please also see our [Code of Conduct](CODE_OF_CONDUCT.md).
[Umbraco Cloud](https://umbraco.com/cloud) is the easiest and fastest way to use Umbraco yet, with full support for all your custom .NET code and integrations. You're up and running in less than a minute, and your life will be made easier with automated upgrades and a built-in deployment engine. We offer a free 14-day trial, no credit card needed.
If you want to DIY, you can [download Umbraco]((https://our.umbraco.com/download)) either as a ZIP file or via NuGet. It's the same version of Umbraco CMS that powers Umbraco Cloud, but you'll need to find a place to host it yourself, and handling deployments and upgrades will be all up to you.
If you want to DIY, then you can [download Umbraco]((https://our.umbraco.com/download)) either as a ZIP file or via NuGet. It's the same version of Umbraco CMS that powers Umbraco Cloud, but you'll need to find a place to host it yourself, and handling deployments and upgrades will be all up to you.
## Documentation
@@ -29,7 +29,7 @@ The documentation for Umbraco CMS can be found [on Our Umbraco](https://our.umbr
## Join the Umbraco community
Our friendly community is available 24/7 at the community hub we call ["Our Umbraco"](https://our.umbraco.com/). Our Umbraco features forums for questions and answers, documentation, downloadable plugins for Umbraco, and a rich collection of community resources.
Our friendly community is available 24/7 at the community hub, we call ["Our Umbraco"](https://our.umbraco.com/). Our Umbraco features forums for questions and answers, documentation, downloadable plugins for Umbraco, and a rich collection of community resources.
Besides "Our", we all support each other also via Twitter: [Umbraco HQ](https://twitter.com/umbraco), [Release Updates](https://twitter.com/umbracoproject), [#umbraco](https://twitter.com/hashtag/umbraco)
+2 -7
View File
@@ -11,17 +11,12 @@ Y88 88Y 888 888 888 888 d88P 888 888 888 Y88b. Y88..88P
Don't forget to build!
We've done our best to transform your configuration files but in case something is not quite right: remember we
backed up your files in App_Data\NuGetBackup so you can find the original files before they were transformed.
We've overwritten all the files in the Umbraco folder, these have been backed up in
App_Data\NuGetBackup. We didn't overwrite the UI.xml file nor did we remove any files or folders that you or
a package might have added. Only the existing files were overwritten. If you customized anything then make
sure to do a compare and merge with the NuGetBackup folder.
We've done our best to transform your configuration files but in case something is not quite right: we recommmend you look in source control for the previous version so you can find the original files before they were transformed.
This NuGet package includes build targets that extend the creation of a deploy package, which is generated by
Publishing from Visual Studio. The targets will only work once Publishing is configured, so if you don't use
Publish this won't affect you.
The following items will now be automatically included when creating a deploy package or publishing to the file
system: umbraco, config\splashes and global.asax.
+2 -2
View File
@@ -18,5 +18,5 @@ using System.Resources;
[assembly: AssemblyVersion("8.0.0")]
// these are FYI and changed automatically
[assembly: AssemblyFileVersion("8.3.0")]
[assembly: AssemblyInformationalVersion("8.3.0")]
[assembly: AssemblyFileVersion("8.4.0")]
[assembly: AssemblyInformationalVersion("8.4.0")]
+1
View File
@@ -11,5 +11,6 @@
public const string TemplateFrontEndCacheKey = "template";
public const string MacroContentCacheKey = "macroContent_"; // used in MacroRenderers
public const string MacroFromAliasCacheKey = "macroFromAlias_";
}
}
+12 -6
View File
@@ -221,7 +221,8 @@ namespace Umbraco.Core
FailedPasswordAttempts,
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Integer, true, FailedPasswordAttempts)
{
Name = FailedPasswordAttemptsLabel
Name = FailedPasswordAttemptsLabel,
DataTypeId = Constants.DataTypes.LabelInt
}
},
{
@@ -242,35 +243,40 @@ namespace Umbraco.Core
LastLockoutDate,
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastLockoutDate)
{
Name = LastLockoutDateLabel
Name = LastLockoutDateLabel,
DataTypeId = Constants.DataTypes.LabelDateTime
}
},
{
LastLoginDate,
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastLoginDate)
{
Name = LastLoginDateLabel
Name = LastLoginDateLabel,
DataTypeId = Constants.DataTypes.LabelDateTime
}
},
{
LastPasswordChangeDate,
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastPasswordChangeDate)
{
Name = LastPasswordChangeDateLabel
Name = LastPasswordChangeDateLabel,
DataTypeId = Constants.DataTypes.LabelDateTime
}
},
{
PasswordAnswer,
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Nvarchar, true, PasswordAnswer)
{
Name = PasswordAnswerLabel
Name = PasswordAnswerLabel,
DataTypeId = Constants.DataTypes.LabelString
}
},
{
PasswordQuestion,
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Nvarchar, true, PasswordQuestion)
{
Name = PasswordQuestionLabel
Name = PasswordQuestionLabel,
DataTypeId = Constants.DataTypes.LabelString
}
}
};
+1 -5
View File
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Core.Models
@@ -9,7 +8,7 @@ namespace Umbraco.Core.Models
/// </summary>
/// <typeparam name="T"></typeparam>
[DataContract(Name = "pagedCollection", Namespace = "")]
public class PagedResult<T>
public abstract class PagedResult
{
public PagedResult(long totalItems, long pageNumber, long pageSize)
{
@@ -39,9 +38,6 @@ namespace Umbraco.Core.Models
[DataMember(Name = "totalItems")]
public long TotalItems { get; private set; }
[DataMember(Name = "items")]
public IEnumerable<T> Items { get; set; }
/// <summary>
/// Calculates the skip size based on the paged parameters specified
/// </summary>
+20
View File
@@ -0,0 +1,20 @@
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Umbraco.Core.Models
{
/// <summary>
/// Represents a paged result for a model collection
/// </summary>
/// <typeparam name="T"></typeparam>
[DataContract(Name = "pagedCollection", Namespace = "")]
public class PagedResult<T> : PagedResult
{
public PagedResult(long totalItems, long pageNumber, long pageSize)
: base(totalItems, pageNumber, pageSize)
{ }
[DataMember(Name = "items")]
public IEnumerable<T> Items { get; set; }
}
}
@@ -225,8 +225,17 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
if (builtinProperties.ContainsKey(propertyType.Alias))
{
//this reset's its current data type reference which will be re-assigned based on the property editor assigned on the next line
propertyType.DataTypeId = 0;
propertyType.DataTypeKey = default;
var propDefinition = builtinProperties[propertyType.Alias];
if (propDefinition != null)
{
propertyType.DataTypeId = propDefinition.DataTypeId;
propertyType.DataTypeKey = propDefinition.DataTypeKey;
}
else
{
propertyType.DataTypeId = 0;
propertyType.DataTypeKey = default;
}
}
}
}
@@ -3083,7 +3083,7 @@ namespace Umbraco.Core.Services.Implement
var version = GetVersion(versionId);
//Good ole null checks
if (content == null || version == null)
if (content == null || version == null || content.Trashed)
{
return new OperationResult(OperationResultType.FailedCannot, evtMsgs);
}
@@ -405,6 +405,21 @@ namespace Umbraco.Core.Services.Implement
/// <returns></returns>
public ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate masterTemplate = null, int userId = Constants.Security.SuperUserId)
{
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException("Name cannot be empty or contain only white-space characters", nameof(name));
}
if (name.Length > 255)
{
throw new ArgumentOutOfRangeException(nameof(name), "Name cannot be more than 255 characters in length.");
}
// file might already be on disk, if so grab the content to avoid overwriting
var template = new Template(name, alias)
{
@@ -539,6 +554,17 @@ namespace Umbraco.Core.Services.Implement
/// <param name="userId"></param>
public void SaveTemplate(ITemplate template, int userId = Constants.Security.SuperUserId)
{
if (template == null)
{
throw new ArgumentNullException(nameof(template));
}
if (string.IsNullOrWhiteSpace(template.Name) || template.Name.Length > 255)
{
throw new InvalidOperationException("Name cannot be null, empty, contain only white-space characters or be more than 255 characters in length.");
}
using (var scope = ScopeProvider.CreateScope())
{
if (scope.Events.DispatchCancelable(SavingTemplate, this, new SaveEventArgs<ITemplate>(template)))
@@ -816,8 +816,8 @@ namespace Umbraco.Core.Services.Implement
{
//trimming username and email to make sure we have no trailing space
member.Username = member.Username.Trim();
member.Email = member.Email.Trim();
member.Email = member.Email.Trim();
using (var scope = ScopeProvider.CreateScope())
{
var saveEventArgs = new SaveEventArgs<IMember>(member);
+9 -2
View File
@@ -10,6 +10,7 @@
<RootNamespace>Umbraco.Core</RootNamespace>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<TargetFrameworkProfile />
<AdditionalFileItemNames>$(AdditionalFileItemNames);Content</AdditionalFileItemNames>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -60,6 +61,11 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="SecurityCodeScan">
<Version>3.3.0</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Serilog.Sinks.Async">
<Version>1.3.0</Version>
</PackageReference>
@@ -267,6 +273,7 @@
<Compile Include="Models\Entities\IMediaEntitySlim.cs" />
<Compile Include="Models\Entities\IMemberEntitySlim.cs" />
<Compile Include="Models\Entities\MediaEntitySlim.cs" />
<Compile Include="Models\PagedResult.cs" />
<Compile Include="Models\Entities\MemberEntitySlim.cs" />
<Compile Include="Models\PublishedContent\ILivePublishedModelFactory.cs" />
<Compile Include="Models\PublishedContent\IPublishedContentType.cs" />
@@ -841,7 +848,7 @@
<Compile Include="Models\Packaging\InstallationSummary.cs" />
<Compile Include="Models\Packaging\PackageAction.cs" />
<Compile Include="Models\Packaging\PreInstallWarnings.cs" />
<Compile Include="Models\PagedResult.cs" />
<Compile Include="Models\PagedResultOfT.cs" />
<Compile Include="Models\PartialView.cs" />
<Compile Include="Models\PartialViewType.cs" />
<Compile Include="Models\Property.cs" />
@@ -1565,4 +1572,4 @@
<Folder Include="Auditing\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>
+2 -2
View File
@@ -15,7 +15,7 @@ namespace Umbraco.Examine
/// <summary>
/// Performs the data lookups required to rebuild a content index
/// </summary>
public class ContentIndexPopulator : IndexPopulator<UmbracoContentIndex>
public class ContentIndexPopulator : IndexPopulator<IUmbracoContentIndex>
{
private readonly IContentService _contentService;
private readonly IValueSetBuilder<IContent> _contentValueSetBuilder;
@@ -36,7 +36,7 @@ namespace Umbraco.Examine
/// <param name="contentValueSetBuilder"></param>
public ContentIndexPopulator(IContentService contentService, ISqlContext sqlContext, IContentValueSetBuilder contentValueSetBuilder)
: this(false, null, contentService, sqlContext, contentValueSetBuilder)
{
{
}
/// <summary>
@@ -0,0 +1,9 @@
using Examine;
namespace Umbraco.Examine
{
public interface IUmbracoContentIndex : IIndex
{
}
}
@@ -0,0 +1,9 @@
using Examine;
namespace Umbraco.Examine
{
public interface IUmbracoMemberIndex : IIndex
{
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ using Umbraco.Core.Services;
namespace Umbraco.Examine
{
public class MemberIndexPopulator : IndexPopulator<UmbracoMemberIndex>
public class MemberIndexPopulator : IndexPopulator<IUmbracoMemberIndex>
{
private readonly IMemberService _memberService;
private readonly IValueSetBuilder<IMember> _valueSetBuilder;
+9 -1
View File
@@ -10,6 +10,7 @@
<RootNamespace>Umbraco.Examine</RootNamespace>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
<TargetFrameworkProfile />
<AdditionalFileItemNames>$(AdditionalFileItemNames);Content</AdditionalFileItemNames>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -56,6 +57,11 @@
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="NPoco" Version="3.9.4" />
<PackageReference Include="SecurityCodeScan">
<Version>3.3.0</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Compile Include="BaseValueSetBuilder.cs" />
@@ -64,10 +70,12 @@
<Compile Include="ExamineExtensions.cs" />
<Compile Include="IContentValueSetBuilder.cs" />
<Compile Include="IContentValueSetValidator.cs" />
<Compile Include="IUmbracoContentIndex.cs" />
<Compile Include="IUmbracoIndexConfig.cs" />
<Compile Include="IIndexCreator.cs" />
<Compile Include="IIndexDiagnostics.cs" />
<Compile Include="IIndexPopulator.cs" />
<Compile Include="IUmbracoMemberIndex.cs" />
<Compile Include="UmbracoIndexConfig.cs" />
<Compile Include="IndexPopulator.cs" />
<Compile Include="IndexRebuilder.cs" />
@@ -104,4 +112,4 @@
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>
+3 -3
View File
@@ -17,13 +17,13 @@ namespace Umbraco.Examine
/// <summary>
/// An indexer for Umbraco content and media
/// </summary>
public class UmbracoContentIndex : UmbracoExamineIndex
public class UmbracoContentIndex : UmbracoExamineIndex, IUmbracoContentIndex
{
public const string VariesByCultureFieldName = SpecialFieldPrefix + "VariesByCulture";
protected ILocalizationService LanguageService { get; }
#region Constructors
/// <summary>
/// Create an index at runtime
/// </summary>
@@ -141,6 +141,6 @@ namespace Umbraco.Examine
base.PerformDeleteFromIndex(idsAsList, onComplete);
}
}
}
+2 -2
View File
@@ -11,7 +11,7 @@ namespace Umbraco.Examine
/// <summary>
/// Custom indexer for members
/// </summary>
public class UmbracoMemberIndex : UmbracoExamineIndex
public class UmbracoMemberIndex : UmbracoExamineIndex, IUmbracoMemberIndex
{
/// <summary>
/// Constructor to allow for creating an indexer at runtime
@@ -32,6 +32,6 @@ namespace Umbraco.Examine
base(name, luceneDirectory, fieldDefinitions, analyzer, profilingLogger, validator)
{
}
}
}
@@ -20,14 +20,14 @@ function watchTask(cb) {
//Setup a watcher for all groups of JS files
_.forEach(config.sources.js, function (group) {
if(group.watch !== false) {
watch(group.files, { ignoreInitial: true, interval: watchInterval }, function JS_Group_Compile() { return processJs(group.files, group.out) });
watch(group.files, { ignoreInitial: true, interval: watchInterval }, function JS_Group_Compile() { return processJs(group.files, group.out);});
}
});
//Setup a watcher for all groups of LESS files
_.forEach(config.sources.less, function (group) {
if(group.watch !== false) {
watch(group.watch, { ignoreInitial: true, interval: watchInterval }, function Less_Group_Compile() { processLess(group.files, group.out) });
watch(group.watch, { ignoreInitial: true, interval: watchInterval }, function Less_Group_Compile() { return processLess(group.files, group.out); });
}
});
@@ -38,7 +38,7 @@ function watchTask(cb) {
viewWatcher = watch(group.files, { ignoreInitial: true, interval: watchInterval });
viewWatcher.on('change', function(path, stats) {
console.log("copying " + group.files + " to " + config.root + config.targets.views + group.folder);
src(group.files).pipe( dest(config.root + config.targets.views + group.folder) )
src(group.files).pipe( dest(config.root + config.targets.views + group.folder) );
});
}
});
@@ -16,7 +16,7 @@ module.exports = function(files, out) {
cssnano({zindex: false})
];
console.log("LESS: ", files, " -> ", config.root + config.targets.js + out)
console.log("LESS: ", files, " -> ", config.root + config.targets.css + out)
var task = gulp.src(files)
.pipe(less())
@@ -271,8 +271,7 @@
function createButtons(content) {
// for trashed and element type items, the save button is the primary action - otherwise it's a secondary action
$scope.page.saveButtonStyle = content.trashed || content.isElement ? "primary" : "info";
$scope.page.saveButtonStyle = content.trashed || content.isElement || content.isBlueprint ? "primary" : "info";
// only create the save/publish/preview buttons if the
// content app is "Conent"
if ($scope.app && $scope.app.alias !== "umbContent" && $scope.app.alias !== "umbInfo" && $scope.app.alias !== "umbListView") {
@@ -195,23 +195,57 @@ Use this directive to construct a header inside the main editor window.
@param {string=} icon Show and edit the content icon. Opens an overlay to change the icon.
@param {boolean=} hideIcon Set to <code>true</code> to hide icon.
@param {string=} alias show and edit the content alias.
@param {boolean=} aliasLocked Set to <code>true</code> to lock the alias.
@param {boolean=} hideAlias Set to <code>true</code> to hide alias.
@param {string=} description Add a description to the content.
@param {boolean=} hideDescription Set to <code>true</code> to hide description.
@param {boolean=} setpagetitle If true the page title will be set to reflect the type of data the header is working with
@param {string=} editorfor The localization to use to aid accessibility on the edit and create screen
**/
(function () {
'use strict';
function EditorHeaderDirective(editorService) {
function EditorHeaderDirective(editorService, localizationService, editorState) {
function link(scope, $injector) {
function link(scope) {
scope.vm = {};
scope.vm.dropdownOpen = false;
scope.vm.currentVariant = "";
scope.loading = true;
scope.accessibility = {};
scope.accessibility.a11yMessage = "";
scope.accessibility.a11yName = "";
scope.accessibility.a11yMessageVisible = false;
scope.accessibility.a11yNameVisible = false;
// need to call localizationService service outside of routine to set a11y due to promise requirements
if (editorState.current) {
//to do make work for user create/edit
// to do make it work for user group create/ edit
// to make it work for language edit/create
scope.isNew = editorState.current.id === 0 ||
editorState.current.id === "0" ||
editorState.current.id === -1 ||
editorState.current.id === 0 ||
editorState.current.id === "-1";
var localizeVars = [
scope.isNew ? "placeholders_a11yCreateItem" : "placeholders_a11yEdit",
"placeholders_a11yName",
scope.isNew ? "general_new" : "general_edit"
];
if (scope.editorfor) {
localizeVars.push(scope.editorfor);
}
localizationService.localizeMany(localizeVars).then(function(data) {
setAccessibilityForEditor(data);
scope.loading = false;
});
} else {
scope.loading = false;
}
scope.goBack = function () {
if (scope.onBack) {
scope.onBack();
@@ -247,6 +281,57 @@ Use this directive to construct a header inside the main editor window.
editorService.iconPicker(iconPicker);
};
function setAccessibilityForEditor(data) {
if (editorState.current) {
if (scope.nameLocked) {
scope.accessibility.a11yName = scope.name;
SetPageTitle(scope.name);
} else {
scope.accessibility.a11yMessage = data[0];
scope.accessibility.a11yName = data[1];
var title = data[2] + ":";
if (!scope.isNew) {
scope.accessibility.a11yMessage += " " + scope.name;
title += " " + scope.name;
} else {
var name = "";
if (editorState.current.contentTypeName) {
name = editorState.current.contentTypeName;
} else if (scope.editorfor) {
name = data[3];
}
if (name !== "") {
scope.accessibility.a11yMessage += " " + name;
scope.accessibility.a11yName = name + " " + scope.accessibility.a11yName;
title += " " + name;
}
}
if (title !== data[2] + ":") {
SetPageTitle(title);
}
}
scope.accessibility.a11yMessageVisible = !isEmptyOrSpaces(scope.accessibility.a11yMessage);
scope.accessibility.a11yNameVisible = !isEmptyOrSpaces(scope.accessibility.a11yName);
}
}
function isEmptyOrSpaces(str) {
return str === null || str===undefined || str.trim ==='';
}
function SetPageTitle(title) {
var setTitle = false;
if (scope.setpagetitle !== undefined) {
setTitle = scope.setpagetitle;
}
if (setTitle) {
scope.$emit("$changeTitle", title);
}
}
}
var directive = {
@@ -262,7 +347,6 @@ Use this directive to construct a header inside the main editor window.
icon: "=",
hideIcon: "@",
alias: "=",
aliasLocked: "<",
hideAlias: "=",
description: "=",
hideDescription: "@",
@@ -271,7 +355,9 @@ Use this directive to construct a header inside the main editor window.
onSelectNavigationItem: "&?",
key: "=",
onBack: "&?",
showBackButton: "<?"
showBackButton: "<?",
editorfor: "=",
setpagetitle:"="
},
link: link
};
@@ -31,6 +31,7 @@
@param {boolean} disabled Set the checkbox to be disabled.
@param {boolean} required Set the checkbox to be required.
@param {callback} onChange Callback when the value of the checkbox change by interaction.
@param {string} cssClass Set a css class modifier
**/
@@ -78,7 +79,8 @@
serverValidationField: "@",
disabled: "<",
required: "<",
onChange: "&?"
onChange: "&?",
cssClass: "@?"
}
};
@@ -16,6 +16,9 @@ angular.module("umbraco.directives")
replace: true,
templateUrl: 'views/components/property/umb-property.html',
link: function (scope) {
scope.propertyEditorAPI = {};
userService.getCurrentUser().then(function (u) {
var isAdmin = u.userGroups.indexOf('admin') !== -1;
scope.propertyAlias = (Umbraco.Sys.ServerVariables.isDebuggingEnabled === true || isAdmin) ? scope.property.alias : null;
@@ -32,6 +35,19 @@ angular.module("umbraco.directives")
self.setPropertyError = function (errorMsg) {
$scope.property.propertyErrorMessage = errorMsg;
};
var unsubscribe = $scope.$on("ExposePropertyEditorAPI", function(event, api) {
//avoid eventual parent properties to capture this.
event.stopPropagation();
$scope.propertyEditorAPI = api;
});
$scope.$on("$destroy", function () {
unsubscribe();
});
}
};
});
@@ -18,6 +18,7 @@
config: "<",
validation: "<",
culture: "<?",
inputId: "@?",
onValueChanged: "&"
}
});
@@ -43,13 +44,13 @@
vm.hidePrompt = hidePrompt;
vm.onKeyUpOnTag = onKeyUpOnTag;
vm.htmlId = "t" + String.CreateGuid();
vm.isLoading = true;
vm.tagToAdd = "";
vm.promptIsVisible = "-1";
vm.viewModel = [];
function onInit() {
vm.inputId = vm.inputId || "t" + String.CreateGuid();
assetsService.loadJs("lib/typeahead.js/typeahead.bundle.min.js").then(function () {
@@ -106,7 +107,7 @@
minLength: 1
};
typeahead = $element.find('.tags-' + vm.htmlId).typeahead(opts, sources)
typeahead = $element.find('.tags-' + vm.inputId).typeahead(opts, sources)
.bind("typeahead:selected", function (obj, datum, name) {
angularHelper.safeApply($rootScope, function () {
addTagInternal(datum["text"]);
@@ -153,7 +154,7 @@
tagsHound.clearRemoteCache();
tagsHound = null;
}
$element.find('.tags-' + vm.htmlId).typeahead('destroy');
$element.find('.tags-' + vm.inputId).typeahead('destroy');
}
function configureViewModel(isInitLoad) {
@@ -228,7 +229,7 @@
function addTagOnEnter(e) {
var code = e.keyCode || e.which;
if (code == 13) { //Enter keycode
if ($element.find('.tags-' + vm.htmlId).parent().find(".tt-menu .tt-cursor").length === 0) {
if ($element.find('.tags-' + vm.inputId).parent().find(".tt-menu .tt-cursor").length === 0) {
//this is required, otherwise the html form will attempt to submit.
e.preventDefault();
addTag();
@@ -56,6 +56,7 @@ function confirmDirective() {
onCancel: '=',
caption: '@',
confirmButtonStyle: '@',
confirmDisabled: '<?',
confirmLabelKey: '@'
},
link: function (scope, element, attr, ctrl) {
@@ -1,7 +1,7 @@
(function () {
'use strict';
function GridSelector($location, overlayService) {
function GridSelector($location, overlayService, editorService) {
function link(scope, el, attr, ctrl) {
@@ -56,8 +56,16 @@
};
scope.openTemplate = function (selectedItem) {
var url = "/settings/templates/edit/" + selectedItem.id;
$location.url(url);
const editor = {
id: selectedItem.id,
submit: function () {
editorService.close();
},
close: function () {
editorService.close();
}
};
editorService.templateEditor(editor);
}
scope.setAsDefaultItem = function (selectedItem) {
@@ -299,7 +299,7 @@
*/
onFilesChanged: "&",
onInit: "&",
required: "@"
required: "="
},
transclude: true,
controllerAs: 'vm',
@@ -389,7 +389,7 @@ function dataTypeResource($q, $http, umbDataFormatter, umbRequestHelper) {
(umbRequestHelper.getApiUrl(
"dataTypeApiBaseUrl",
"PostRenameContainer",
{ id: id, name: name })),
{ id: id, name: encodeURIComponent(name) })),
"Failed to rename the folder with id " + id);
}
};
@@ -250,9 +250,10 @@ angular.module('umbraco.services')
*
* @param {Array} pathArray string array of paths to the files to load
* @param {Scope} scope optional scope to pass into the loader
* @param {string} defaultAssetType optional default asset type used to load assets with no extension
* @returns {Promise} Promise object which resolves when all the files has loaded
*/
load: function (pathArray, scope) {
load: function (pathArray, scope, defaultAssetType) {
var promise;
if (!angular.isArray(pathArray)) {
@@ -294,14 +295,29 @@ angular.module('umbraco.services')
promise = $q.all(promises);
// Split into css and js asset arrays, and use LazyLoad on each array
var cssAssets = _.filter(assets,
function (asset) {
return asset.path.match(/(\.css$|\.css\?)/ig);
});
var jsAssets = _.filter(assets,
function (asset) {
return asset.path.match(/(\.js$|\.js\?)/ig);
});
var cssAssets = [];
var jsAssets = [];
for (var i = 0; i < assets.length; i++) {
var asset = assets[i];
if (asset.path.match(/(\.css$|\.css\?)/ig)) {
cssAssets.push(asset);
} else if (asset.path.match(/(\.js$|\.js\?)/ig)) {
jsAssets.push(asset);
} else {
// Handle unknown assets
switch (defaultAssetType) {
case "css":
cssAssets.push(asset);
break;
case "js":
jsAssets.push(asset);
break;
default:
throw "Found unknown asset without a valid defaultAssetType specified";
}
}
}
function assetLoaded(asset) {
asset.state = "loaded";
@@ -1,203 +1,264 @@
/**
* @ngdoc service
* @name umbraco.services.clipboardService
*
* @requires notificationsService
* @requires eventsService
*
* @description
* Service to handle clipboard in general across the application. Responsible for handling the data both storing and retrive.
* The service has a set way for defining a data-set by a entryType and alias, which later will be used to retrive the posible entries for a paste scenario.
*
*/
function clipboardService(notificationsService, eventsService, localStorageService) {
var STORAGE_KEY = "umbClipboardService";
var retriveStorage = function() {
if (localStorageService.isSupported === false) {
return null;
}
var dataJSON;
var dataString = localStorageService.get(STORAGE_KEY);
if (dataString != null) {
dataJSON = JSON.parse(dataString);
}
if(dataJSON == null) {
dataJSON = new Object();
}
if(dataJSON.entries === undefined) {
dataJSON.entries = [];
}
return dataJSON;
}
var saveStorage = function(storage) {
var storageString = JSON.stringify(storage);
try {
var storageJSON = JSON.parse(storageString);
localStorageService.set(STORAGE_KEY, storageString);
eventsService.emit("clipboardService.storageUpdate");
return true;
} catch(e) {
return false;
}
return false;
}
var service = {};
/**
* @ngdoc method
* @name umbraco.services.clipboardService#copy
* @methodOf umbraco.services.clipboardService
*
* @param {string} type A string defining the type of data to storing, example: 'elementType', 'contentNode'
* @param {string} alias A string defining the alias of the data to store, example: 'product'
* @param {object} data A object containing the properties to be saved.
*
* @description
* Saves a single JS-object with a type and alias to the clipboard.
*/
service.copy = function(type, alias, data) {
var storage = retriveStorage();
var shallowCloneData = Object.assign({}, data);// Notice only a shallow copy, since we dont need to deep copy. (that will happen when storing the data)
delete shallowCloneData.key;
delete shallowCloneData.$$hashKey;
var key = data.key || data.$$hashKey || console.error("missing unique key for this content");
// remove previous copies of this entry:
storage.entries = storage.entries.filter(
(entry) => {
return entry.unique !== key;
}
);
var entry = {unique:key, type:type, alias:alias, data:shallowCloneData};
storage.entries.push(entry);
if (saveStorage(storage) === true) {
notificationsService.success("Clipboard", "Copied to clipboard.");
} else {
notificationsService.success("Clipboard", "Couldnt copy this data to clipboard.");
}
};
/**
* @ngdoc method
* @name umbraco.services.supportsCopy#supported
* @methodOf umbraco.services.clipboardService
*
* @description
* Determins wether the current browser is able to performe its actions.
*/
service.isSupported = function() {
return localStorageService.isSupported;
};
/**
* @ngdoc method
* @name umbraco.services.supportsCopy#hasEntriesOfType
* @methodOf umbraco.services.clipboardService
*
* @param {string} type A string defining the type of data test for.
* @param {string} aliases A array of strings providing the alias of the data you want to test for.
*
* @description
* Determines whether the current clipboard has entries that match a given type and one of the aliases.
*/
service.hasEntriesOfType = function(type, aliases) {
if(service.retriveEntriesOfType(type, aliases).length > 0) {
return true;
}
return false;
};
/**
* @ngdoc method
* @name umbraco.services.supportsCopy#retriveEntriesOfType
* @methodOf umbraco.services.clipboardService
*
* @param {string} type A string defining the type of data to recive.
* @param {string} aliases A array of strings providing the alias of the data you want to recive.
*
* @description
* Returns an array of entries matching the given type and one of the provided aliases.
*/
service.retriveEntriesOfType = function(type, aliases) {
var storage = retriveStorage();
// Find entries that are fulfilling the criteria for this nodeType and nodeTypesAliases.
var filteretEntries = storage.entries.filter(
(entry) => {
return (entry.type === type && aliases.filter(alias => alias === entry.alias).length > 0);
}
);
return filteretEntries;
};
/**
* @ngdoc method
* @name umbraco.services.supportsCopy#retriveEntriesOfType
* @methodOf umbraco.services.clipboardService
*
* @param {string} type A string defining the type of data to recive.
* @param {string} aliases A array of strings providing the alias of the data you want to recive.
*
* @description
* Returns an array of data of entries matching the given type and one of the provided aliases.
*/
service.retriveDataOfType = function(type, aliases) {
return service.retriveEntriesOfType(type, aliases).map((x) => x.data);
};
/**
* @ngdoc method
* @name umbraco.services.supportsCopy#retriveEntriesOfType
* @methodOf umbraco.services.clipboardService
*
* @param {string} type A string defining the type of data to remove.
* @param {string} aliases A array of strings providing the alias of the data you want to remove.
*
* @description
* Removes entries matching the given type and one of the provided aliases.
*/
service.clearEntriesOfType = function(type, aliases) {
var storage = retriveStorage();
// Find entries that are NOT fulfilling the criteria for this nodeType and nodeTypesAliases.
var filteretEntries = storage.entries.filter(
(entry) => {
return !(entry.type === type && aliases.filter(alias => alias === entry.alias).length > 0);
}
);
storage.entries = filteretEntries;
saveStorage(storage);
};
return service;
}
/**
* @ngdoc service
* @name umbraco.services.clipboardService
*
* @requires notificationsService
* @requires eventsService
*
* @description
* Service to handle clipboard in general across the application. Responsible for handling the data both storing and retrive.
* The service has a set way for defining a data-set by a entryType and alias, which later will be used to retrive the posible entries for a paste scenario.
*
*/
function clipboardService(notificationsService, eventsService, localStorageService, iconHelper) {
var STORAGE_KEY = "umbClipboardService";
var retriveStorage = function() {
if (localStorageService.isSupported === false) {
return null;
}
var dataJSON;
var dataString = localStorageService.get(STORAGE_KEY);
if (dataString != null) {
dataJSON = JSON.parse(dataString);
}
if(dataJSON == null) {
dataJSON = new Object();
}
if(dataJSON.entries === undefined) {
dataJSON.entries = [];
}
return dataJSON;
}
var saveStorage = function(storage) {
var storageString = JSON.stringify(storage);
try {
var storageJSON = JSON.parse(storageString);
localStorageService.set(STORAGE_KEY, storageString);
eventsService.emit("clipboardService.storageUpdate");
return true;
} catch(e) {
return false;
}
return false;
}
var prepareEntryForStorage = function(entryData) {
var shallowCloneData = Object.assign({}, entryData);// Notice only a shallow copy, since we dont need to deep copy. (that will happen when storing the data)
delete shallowCloneData.key;
delete shallowCloneData.$$hashKey;
return shallowCloneData;
}
var isEntryCompatible = function(entry, type, allowedAliases) {
return entry.type === type
&&
(
(entry.alias && allowedAliases.filter(allowedAlias => allowedAlias === entry.alias).length > 0)
||
(entry.aliases && entry.aliases.filter(entryAlias => allowedAliases.filter(allowedAlias => allowedAlias === entryAlias).length > 0).length === entry.aliases.length)
);
}
var service = {};
/**
* @ngdoc method
* @name umbraco.services.clipboardService#copy
* @methodOf umbraco.services.clipboardService
*
* @param {string} type A string defining the type of data to storing, example: 'elementType', 'contentNode'
* @param {string} alias A string defining the alias of the data to store, example: 'product'
* @param {object} entry A object containing the properties to be saved, this could be the object of a ElementType, ContentNode, ...
* @param {string} displayLabel (optional) A string swetting the label to display when showing paste entries.
*
* @description
* Saves a single JS-object with a type and alias to the clipboard.
*/
service.copy = function(type, alias, data, displayLabel) {
var storage = retriveStorage();
var uniqueKey = data.key || data.$$hashKey || console.error("missing unique key for this content");
// remove previous copies of this entry:
storage.entries = storage.entries.filter(
(entry) => {
return entry.unique !== uniqueKey;
}
);
var entry = {unique:uniqueKey, type:type, alias:alias, data:prepareEntryForStorage(data), label:displayLabel || data.name, icon:iconHelper.convertFromLegacyIcon(data.icon)};
storage.entries.push(entry);
if (saveStorage(storage) === true) {
notificationsService.success("Clipboard", "Copied to clipboard.");
} else {
notificationsService.error("Clipboard", "Couldnt copy this data to clipboard.");
}
};
/**
* @ngdoc method
* @name umbraco.services.clipboardService#copyArray
* @methodOf umbraco.services.clipboardService
*
* @param {string} type A string defining the type of data to storing, example: 'elementTypeArray', 'contentNodeArray'
* @param {string} aliases An array of strings defining the alias of the data to store, example: ['banana', 'apple']
* @param {object} datas An array of objects containing the properties to be saved, example: [ElementType, ElementType, ...]
* @param {string} displayLabel A string setting the label to display when showing paste entries.
* @param {string} displayIcon A string setting the icon to display when showing paste entries.
* @param {string} uniqueKey A string prodiving an identifier for this entry, existing entries with this key will be removed to ensure that you only have the latest copy of this data.
*
* @description
* Saves a single JS-object with a type and alias to the clipboard.
*/
service.copyArray = function(type, aliases, datas, displayLabel, displayIcon, uniqueKey) {
var storage = retriveStorage();
// Clean up each entry
var copiedDatas = datas.map(data => prepareEntryForStorage(data));
// remove previous copies of this entry:
storage.entries = storage.entries.filter(
(entry) => {
return entry.unique !== uniqueKey;
}
);
var entry = {unique:uniqueKey, type:type, aliases:aliases, data:copiedDatas, label:displayLabel, icon:displayIcon};
storage.entries.push(entry);
if (saveStorage(storage) === true) {
notificationsService.success("Clipboard", "Copied to clipboard.");
} else {
notificationsService.error("Clipboard", "Couldnt copy this data to clipboard.");
}
};
/**
* @ngdoc method
* @name umbraco.services.supportsCopy#supported
* @methodOf umbraco.services.clipboardService
*
* @description
* Determins wether the current browser is able to performe its actions.
*/
service.isSupported = function() {
return localStorageService.isSupported;
};
/**
* @ngdoc method
* @name umbraco.services.supportsCopy#hasEntriesOfType
* @methodOf umbraco.services.clipboardService
*
* @param {string} type A string defining the type of data test for.
* @param {string} aliases A array of strings providing the alias of the data you want to test for.
*
* @description
* Determines whether the current clipboard has entries that match a given type and one of the aliases.
*/
service.hasEntriesOfType = function(type, aliases) {
if(service.retriveEntriesOfType(type, aliases).length > 0) {
return true;
}
return false;
};
/**
* @ngdoc method
* @name umbraco.services.supportsCopy#retriveEntriesOfType
* @methodOf umbraco.services.clipboardService
*
* @param {string} type A string defining the type of data to recive.
* @param {string} aliases A array of strings providing the alias of the data you want to recive.
*
* @description
* Returns an array of entries matching the given type and one of the provided aliases.
*/
service.retriveEntriesOfType = function(type, allowedAliases) {
var storage = retriveStorage();
// Find entries that are fulfilling the criteria for this nodeType and nodeTypesAliases.
var filteretEntries = storage.entries.filter(
(entry) => {
return isEntryCompatible(entry, type, allowedAliases);
}
);
return filteretEntries;
};
/**
* @ngdoc method
* @name umbraco.services.supportsCopy#retriveEntriesOfType
* @methodOf umbraco.services.clipboardService
*
* @param {string} type A string defining the type of data to recive.
* @param {string} aliases A array of strings providing the alias of the data you want to recive.
*
* @description
* Returns an array of data of entries matching the given type and one of the provided aliases.
*/
service.retriveDataOfType = function(type, aliases) {
return service.retriveEntriesOfType(type, aliases).map((x) => x.data);
};
/**
* @ngdoc method
* @name umbraco.services.supportsCopy#retriveEntriesOfType
* @methodOf umbraco.services.clipboardService
*
* @param {string} type A string defining the type of data to remove.
* @param {string} aliases A array of strings providing the alias of the data you want to remove.
*
* @description
* Removes entries matching the given type and one of the provided aliases.
*/
service.clearEntriesOfType = function(type, allowedAliases) {
var storage = retriveStorage();
// Find entries that are NOT fulfilling the criteria for this nodeType and nodeTypesAliases.
var filteretEntries = storage.entries.filter(
(entry) => {
return !isEntryCompatible(entry, type, allowedAliases);
}
);
storage.entries = filteretEntries;
saveStorage(storage);
};
return service;
}
angular.module("umbraco.services").factory("clipboardService", clipboardService);
@@ -606,10 +606,12 @@ When building a custom infinite editor view you can use the same components as a
* @methodOf umbraco.services.editorService
*
* @description
* Opens the document type editor in infinite editing, the submit callback returns the saved document type
* Opens the document type editor in infinite editing, the submit callback returns the alias of the saved document type.
* @param {Object} editor rendering options
* @param {Callback} editor.submit Submits the editor
* @param {Callback} editor.close Closes the editor
* @param {Callback} editor.id Indicates the ID of the document type to be edited. Alternatively the ID may be set to `-1` in combination with `create` being set to `true` to open the document type editor for creating a new document type.
* @param {Callback} editor.create Set to `true` to open the document type editor for creating a new document type.
* @param {Callback} editor.submit Submits the editor.
* @param {Callback} editor.close Closes the editor.
* @returns {Object} editor object
*/
function documentTypeEditor(editor) {
@@ -465,6 +465,8 @@ function navigationService($routeParams, $location, $q, $injector, eventsService
throw "section cannot be null";
}
appState.setMenuState("currentNode", node);
if (action.metaData && action.metaData["actionRoute"] && angular.isString(action.metaData["actionRoute"])) {
//first check if the menu item simply navigates to a route
var parts = action.metaData["actionRoute"].split("?");
@@ -65,10 +65,39 @@
open(overlay);
}
function confirm(overlay) {
if (!overlay.closeButtonLabelKey) overlay.closeButtonLabelKey = "general_cancel";
if (!overlay.view) overlay.view = "views/common/overlays/confirm/confirm.html";
if (!overlay.close) overlay.close = function () { close(); };
switch (overlay.confirmType) {
case "delete":
if (!overlay.confirmMessageStyle) overlay.confirmMessageStyle = "danger";
if (!overlay.submitButtonStyle) overlay.submitButtonStyle = "danger";
if (!overlay.submitButtonLabelKey) overlay.submitButtonLabelKey = "contentTypeEditor_yesDelete";
break;
default:
if (!overlay.submitButtonLabelKey) overlay.submitButtonLabelKey = "general_confirm";
}
open(overlay);
}
function confirmDelete(overlay) {
confirm(overlay);
}
var service = {
open: open,
close: close,
ysod: ysod
ysod: ysod,
confirm: confirm,
confirmDelete: confirmDelete
};
return service;
@@ -0,0 +1,29 @@
(function() {
'use strict';
function propertyEditorService() {
/**
* @ngdoc function
* @name umbraco.services.propertyEditorService#expose
* @methodOf umbraco.services.propertyEditorService
* @function
*
* @param {object} scope An object containing API for the PropertyEditor
*/
function exposeAPI(scope, api) {
if (!scope) {
throw "scope cannot be null";
}
if (!api) {
throw "api cannot be null";
}
scope.$emit("ExposePropertyEditorAPI", api);
}
return {
exposeAPI: exposeAPI
};
}
angular.module('umbraco.services').factory('propertyEditorService', propertyEditorService);
})();
@@ -735,7 +735,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
//get all macro divs and load their content
$(editor.dom.select(".umb-macro-holder.mceNonEditable")).each(function () {
self.loadMacroContent($(this), null);
self.loadMacroContent($(this), null, editor);
});
});
@@ -850,14 +850,15 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
}
var $macroDiv = $(editor.dom.select("div.umb-macro-holder." + uniqueId));
editor.setDirty(true);
//async load the macro content
this.loadMacroContent($macroDiv, macroObject);
this.loadMacroContent($macroDiv, macroObject, editor);
},
/** loads in the macro content async from the server */
loadMacroContent: function ($macroDiv, macroData) {
loadMacroContent: function ($macroDiv, macroData, editor) {
//if we don't have the macroData, then we'll need to parse it from the macro div
if (!macroData) {
@@ -893,7 +894,11 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
$macroDiv.removeClass("loading");
htmlResult = htmlResult.trim();
if (htmlResult !== "") {
var wasDirty = editor.isDirty();
$ins.html(htmlResult);
if (!wasDirty) {
editor.undoManager.clear();
}
}
});
});
@@ -77,6 +77,7 @@
@import "listview.less";
@import "gridview.less";
@import "footer.less";
@import "filter-toggle.less";
@import "forms/umb-validation-label.less";
@@ -129,6 +130,7 @@
@import "components/umb-media-grid.less";
@import "components/umb-folder-grid.less";
@import "components/umb-content-grid.less";
@import "components/umb-contextmenu.less";
@import "components/umb-layout-selector.less";
@import "components/tooltip/umb-tooltip.less";
@import "components/tooltip/umb-tooltip-list.less";
@@ -137,6 +139,7 @@
@import "components/umb-grid.less";
@import "components/umb-empty-state.less";
@import "components/umb-property-editor.less";
@import "components/umb-property-actions.less";
@import "components/umb-color-swatches.less";
@import "components/check-circle.less";
@import "components/umb-file-icon.less";
@@ -187,6 +190,8 @@
@import "components/users/umb-user-preview.less";
@import "components/users/umb-user-picker-list.less";
@import "components/contextdialogs/umb-dialog-datatype-delete.less";
// Utilities
@import "utilities/layout/_display.less";
@@ -217,6 +222,7 @@
@import "dashboards/umbraco-forms.less";
@import "dashboards/examine-management.less";
@import "dashboards/healthcheck.less";
@import "dashboards/nucache.less";
@import "typeahead.less";
@import "hacks.less";
@@ -280,7 +280,7 @@ ul.sections {
margin:0;
padding:0;
margin-left: -80px;
overflow: scroll;
overflow: auto;
overflow-x: hidden;
height: calc(100% - 91px);
@@ -316,35 +316,40 @@ ul.sections li a {
&:hover {
span, i {
opacity: 1;
color:#fff;
}
}
}
ul.sections li a i {
font-size: 30px;
opacity: 0.8;
}
ul.sections li a span {
display:block;
display: block;
font-size: 10px;
line-height: 1.4em;
opacity: 0.4;
opacity: 0.8;
}
ul.sections li.current {
background-color: #2E2246;
}
ul.sections li.current a i {
color: #ffffff;
}
ul.sections li.current, ul.sections li:hover {
border-left: 4px #f5c1bc solid;
}
.fix-left-menu:hover ul.sections li a span,
.fix-left-menu:hover ul.sections li a i,
ul.sections li.current a i {
color: #f5c1bc;
}
ul.sections li.current {
border-left: 4px #f5c1bc solid;
}
ul.sections li:hover a i,
ul.sections li:hover a span {
opacity: 1;
}
.fix-left-menu:hover .help {
opacity: 1;
}
@@ -0,0 +1,33 @@
.umb-dialog-datatype-delete {
.umb-dialog-datatype-delete__table-head-column-name {
width: 140px;
}
.umb-table-body__icon {
margin-right: 5px;
vertical-align: top;
display: inline-block;
}
.table tbody td {
vertical-align: top;
}
.table tbody td > span {
margin: 5px 0;
vertical-align: middle;
}
.table tbody p {
line-height: 12px;
margin: 5px 0;
vertical-align: middle;
}
.table tbody .icon {
vertical-align: top;
margin-right: 5px;
display: inline-block;
}
}
@@ -39,3 +39,8 @@
padding-top: 20px;
padding-bottom: 20px;
}
.emptySection .umb-notifications{
left:0;
}
@@ -117,7 +117,7 @@
.umb-overlay.umb-overlay-center .umb-overlay-drawer {
border: none;
background: transparent;
padding: 0 30px 20px;
padding: 0 20px 20px;
}
/* ---------- OVERLAY TARGET ---------- */
@@ -0,0 +1,75 @@
.umb-contextmenu {
margin: 0;
list-style: none;
user-select: none;
overflow: hidden;
border-radius: 3px;
border: 1px solid @dropdownBorder;
.box-shadow(0 5px 20px rgba(0,0,0,.3));
border-bottom: 1px solid rgba(0,0,0,.2);
.sep {
display: block;
border-top: 1px solid @gray-9;
&:first-child {
border-top: none;
}
}
}
.umb-contextmenu-item {
.icon {
font-size: 18px;
vertical-align: middle;
}
.menu-label {
display: inline-block;
vertical-align: middle;
margin-left: 5px;
}
button {
position: relative;
display: block;
font-weight: normal;
line-height: @baseLineHeight;
white-space: nowrap;
background-color: @ui-option;
border: 0;
padding: 7px 12px;
color: @ui-option-type;
width: 100%;
font-size: 14px;
text-align: left;
&:hover {
text-decoration: none;
color: @ui-option-type-hover;
background-color: @ui-option-hover;
}
}
&.-opens-dialog {
.menu-label:after {
// adds an ellipsis (...) after the menu label for actions that open a dialog
content: '\2026';
}
}
button:disabled {
cursor: not-allowed;
color: @ui-option-disabled-type;
&:hover {
color: @ui-option-disabled-type-hover;
background-color: @ui-option;
}
}
}
@@ -12,6 +12,14 @@
line-height: 22px;
cursor: pointer !important;
&.-small-text{
font-size: 13px;
}
&.-bold{
font-weight: 700;
}
&__text {
margin: 0 0 0 26px;
position: relative;
@@ -1,5 +1,3 @@
/* PACKAGE DETAILS */
.umb-logviewer {
display: flex;
flex-flow: row wrap;
@@ -41,7 +39,7 @@
flex: 1 1 auto;
width: 100%;
margin-bottom: 30px;
margin-right: 0;
margin-right: 0;
}
.umb-logviewer__sidebar {
@@ -49,3 +47,99 @@
width: 100%;
}
}
.umb-logviewer-search {
.filter-name {
margin-left: 5px;
margin-right: 3px;
max-width: 150px;
}
.dropdown-item {
padding: 8px 20px 8px 16px;
}
.filter {
position: relative;
a.btn-link {
padding-left: 0px;
}
}
.search-box {
width: 100%;
.flex-auto {
position: relative;
.search-input {
width: 100%;
padding-right: 160px;
}
.icon-rate {
position: absolute;
top: 0;
line-height: 32px;
right: 140px;
color: #fdb45c;
cursor: pointer;
}
.icon-wrong {
position: absolute;
top: 0;
line-height: 32px;
right: 120px;
color: #bbbabf;
cursor: pointer;
}
.umb-variant-switcher__toggle {
top: 1px;
right: 0;
position: absolute;
.icon-navigation-down {
margin-top: 0;
}
}
.saved-searches {
width: 100%;
max-height: 250px;
overflow-y: scroll;
margin-top: -10px;
}
}
}
.log-items {
.table {
table-layout: fixed;
thead th:first-child, thead th:nth-child(3) {
width: 20%;
}
thead th:nth-child(2) {
width: 15%;
}
tr td:nth-child(3) {
word-break: break-word;
}
}
.exception {
border-left: 4px solid #D42054;
padding: 0 10px 10px 10px;
box-shadow: rgba(0,0,0,0.07) 2px 2px 10px;
.exception-message {
white-space: pre-wrap;
}
}
}
}
@@ -1,5 +1,4 @@
.umb-nested-content {
text-align: center;
position: relative;
}
@@ -170,6 +169,7 @@
.umb-nested-content__add-content {
display: flex;
width: 100%;
align-items: center;
justify-content: center;
border: 1px dashed @ui-action-discreet-border;
@@ -107,5 +107,5 @@
.umb-panel-group__details-status-action-description {
margin-top: 5px;
font-size: 12px;
padding-left: 165px;
padding-left:165px;
}
@@ -0,0 +1,96 @@
.umb-property-actions {
display: inline;
}
.umb-property-actions__toggle,
.umb-property-actions__menu-open-toggle {
position: relative;
display: flex;
flex: 0 0 auto;
padding: 6px 6px;
text-align: center;
cursor: pointer;
border-radius: 3px;
background-color: @ui-action-hover;
i {
height: 3px !important;
width: 3px !important;
border-radius: 3px;
background: @ui-action-type;
display: inline-block;
margin: 0 2px 0 0;
&:last-child {
margin: 0;
}
}
&:hover {
i {
background: @ui-action-type-hover;
}
}
}
.umb-property-actions__menu-open-toggle {
position: absolute;
z-index:1;
outline: none;// this is not acceccible by keyboard, since we use the .umb-property-actions__toggle for that.
top: -15px;
border-radius: 3px 3px 0 0;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border: 1px solid @dropdownBorder;
border-bottom: 1px solid @gray-9;
.box-shadow(0 5px 20px rgba(0,0,0,.3));
background-color: white;
}
.umb-property .umb-property-actions {
float: left;
}
.umb-property .umb-property-actions__toggle {
margin-top: 2px;
opacity: 0;
transition: opacity 120ms;
}
.umb-property:hover .umb-property-actions__toggle,
.umb-property .umb-property-actions__toggle:focus {
opacity: 1;
}
// Revert-style-hack that ensures that we only show property-actions on properties that are directly begin hovered.
.umb-property:hover .umb-property:not(:hover) .umb-property-actions__toggle {
opacity: 0;
}
.umb-property-actions__menu {
position: absolute;
z-index: 1000;
display: block;
float: left;
min-width: 160px;
list-style: none;
.umb-contextmenu {
border-top-left-radius: 0;
margin-top:1px;
}
.umb-contextmenu-item > button {
z-index:2;// need to stay on top of menu-toggle-open shadow.
}
}
@@ -161,6 +161,7 @@ input.umb-table__input {
line-height: 20px;
color: @ui-option-type;
vertical-align: bottom;
text-decoration: none;
}
.umb-table-body__checkicon,
@@ -63,6 +63,10 @@ a.umb-user-details-details__back-link {
.umb-user-details-details__sidebar {
flex: 0 0 @sidebarwidth;
.umb-button{
margin-left:0px;
}
}
@media (max-width: 768px) {
@@ -101,6 +105,7 @@ a.umb-user-details-details__back-link {
.umb-user-details-details__information-item {
margin-bottom: 10px;
font-size: 13px;
margin-top:10px;
}
.umb-user-details-details__information-item-label {
@@ -12,4 +12,9 @@
border-bottom-left-radius: 0;
}
}
.umb-panel-group__details-status-action{
background-color:transparent;
padding-left:0;
}
}
@@ -8,7 +8,6 @@
.umb-healthcheck-help-text {
line-height: 1.6em;
max-width: 750px;
}
.umb-healthcheck-action-bar {
@@ -0,0 +1,13 @@
#nuCache {
.no-background {
background-color: transparent;
}
.top-border {
border-top: 2px solid #f3f3f5;
}
.no-left-padding {
padding-left: 0;
}
}
@@ -0,0 +1,20 @@
.filter-toggle{
margin: 0;
padding: 0 8px 0 0;
position: relative;
}
.filter-toggle__level{
display: inline-block;
font-weight: 700;
margin: 0 5px;
max-width: 150px;
}
.filter-toggle__icon{
position: absolute;
top: 0;
bottom: 0;
right: 0;
margin: auto 0;
}
+56 -9
View File
@@ -116,24 +116,42 @@ h5.-black {
margin: 20px;
}
.umb-control-group {
border-bottom: 1px solid @gray-11;
padding-bottom: 20px;
position: relative;
&::after {
content: '';
display:block;
margin-top: 20px;
width: 100%;
height: 1px;
background-color: @gray-11;
}
}
.umb-control-group.-no-border {
border: none;
&::after {
margin-top: 0px;
height: 0;
background-color: transparent;
}
}
.umb-property:last-of-type .umb-control-group {
border: none;
margin-bottom: 0 !important;
padding-bottom: 0;
&::after {
margin-top: 0px;
height: 0;
background-color: transparent;
}
margin-bottom: 0 !important;
}
/* BLOCK MODE */
.block-form .umb-control-group {
border-bottom: none;
padding-bottom: 0;
margin-top: 0px;
&::after {
margin-top: 0px;
height: 0;
background-color: transparent;
}
}
.block-form .umb-control-group label .help-block,
@@ -163,7 +181,36 @@ h5.-black {
}
.umb-control-group .umb-el-wrap {
padding: 0
padding: 0;
}
.form-horizontal .umb-control-group .control-header {
float: left;
width: 160px;
padding-top: 5px;
text-align: left;
.control-label {
float: left;
width: auto;
padding-top: 0;
text-align: left;
}
.control-description {
display: block;
clear: both;
max-width:480px;// avoiding description becoming too wide when its placed on top of property.
margin-bottom: 10px;
}
}
@media (max-width: 767px) {
.form-horizontal .umb-control-group .control-header {
float: none;
width: 100%;
}
}
/* LABELS*/
@@ -99,7 +99,7 @@
top: 0px;
left: 0px;
right: 0px;
bottom: 52px;
bottom: 49px;
}
.umb-dialog-body .umb-pane{margin-top: 15px;}
@@ -111,7 +111,7 @@
left: 0px;
right: 0px;
bottom: 0px;
padding: 20px;
padding: 8px;
margin: 0;
.btn.umb-outline {
@@ -415,8 +415,6 @@
text-decoration: none;
display: flex;
flex-direction: row;
opacity: 0;
visibility: hidden;
}
.umb-sortable-thumbnails.ui-sortable:not(.ui-sortable-disabled) {
@@ -425,9 +423,8 @@
}
}
.umb-sortable-thumbnails li:hover .umb-sortable-thumbnails__actions {
.umb-sortable-thumbnails li:hover .umb-sortable-thumbnails__action {
opacity: 1;
visibility: visible;
}
.umb-sortable-thumbnails .umb-sortable-thumbnails__action {
@@ -443,6 +440,12 @@
margin-left: 5px;
text-decoration: none;
.box-shadow(0 1px 2px rgba(0,0,0,0.25));
opacity: 0;
transition: opacity .1s ease-in-out;
.tabbing-active &:focus {
opacity: 1;
}
}
.umb-sortable-thumbnails .umb-sortable-thumbnails__action.-red {
@@ -67,4 +67,18 @@
.ml6 { margin-left: @spacing-extra-extra-large; }
.ml7 { margin-left: @spacing-extra-extra-extra-large; }
.mr0 { margin-right: @spacing-none; }
.mr1 { margin-right: @spacing-extra-small; }
.mr2 { margin-right: @spacing-small; }
.mr3 { margin-right: @spacing-medium; }
.mr4 { margin-right: @spacing-large; }
.mr5 { margin-right: @spacing-extra-large; }
.mr6 { margin-right: @spacing-extra-extra-large; }
.mr7 { margin-right: @spacing-extra-extra-extra-large; }
.p0 { padding: @spacing-none; }
.pt0 { padding-top: @spacing-none; }
.pb0 { padding-bottom: @spacing-none; }
.pl0 { padding-left: @spacing-none; }
.pr0 { padding-right: @spacing-none; }
@@ -132,6 +132,7 @@
@ui-option-type: @blueExtraDark;
@ui-option-type-hover: @blueMid;
@ui-option: white;
@ui-option-hover: @sand-7;
@ui-option-disabled-type: @gray-6;
@@ -60,7 +60,7 @@
</ul>
</div>
<div ng-if="vm.availableGroups.length > 0">
<div class="umb-control-group -no-border" ng-if="vm.availableGroups.length > 0">
<ul class="umb-checkbox-list" ng-repeat="group in vm.availableGroups | filter:searchTerm">
<li ng-show="vm.availableGroups.length > 1">
<i class="icon-folder umb-checkbox-list__item-icon"></i>
@@ -5,8 +5,8 @@
var vm = this;
vm.field;
vm.defaultValue;
vm.field = null;
vm.defaultValue = null;
vm.recursive = false;
vm.showDefaultValue = false;
@@ -16,10 +16,14 @@
function onInit() {
var labelKeys = [
"template_insertPageField"
];
// set default title
if(!$scope.model.title) {
localizationService.localize("template_insertPageField").then(function(value){
$scope.model.title = value;
localizationService.localizeMany(labelKeys).then(function (data) {
$scope.model.title = data[0];
});
}
@@ -37,42 +41,40 @@
function generateOutputSample() {
var fallback;
var fallback = null;
if(vm.recursive !== false && vm.defaultValue !== undefined){
if (vm.recursive !== false && vm.defaultValue !== null) {
fallback = "Fallback.To(Fallback.Ancestors, Fallback.DefaultValue)";
}else if(vm.recursive !== false){
} else if (vm.recursive !== false) {
fallback = "Fallback.ToAncestors";
}else if(vm.defaultValue !== undefined){
} else if (vm.defaultValue !== null) {
fallback = "Fallback.ToDefaultValue";
}
var pageField = (vm.field !== undefined ? '@Model.Value("' + vm.field + '"' : "")
+ (fallback !== undefined? ', fallback: ' + fallback : "")
+ (vm.defaultValue !== undefined ? ', defaultValue: new HtmlString("' + vm.defaultValue + '")' : "")
var pageField = (vm.field !== null ? '@Model.Value("' + vm.field + '"' : "")
+ (fallback !== null? ', fallback: ' + fallback : "")
+ (vm.defaultValue !== null ? ', defaultValue: new HtmlString("' + vm.defaultValue + '")' : "")
+ (vm.field ? ')' : "");
$scope.model.umbracoField = pageField;
return pageField;
}
function submit(model) {
if($scope.model.submit) {
if ($scope.model.submit) {
$scope.model.submit(model);
}
}
function close() {
if($scope.model.close) {
if ($scope.model.close) {
$scope.model.close();
}
}
onInit();
}
angular.module("umbraco").controller("Umbraco.Editors.InsertFieldController", InsertFieldController);
@@ -33,10 +33,9 @@
<!-- Default value -->
<div>
<div style="margin-bottom: 20px;">
<i class="icon icon-add blue" ng-hide="vm.showDefaultValue"></i>
<a href="" ng-click="vm.showDefaultValue=true" ng-hide="vm.showDefaultValue"><localize key="templateEditor_addDefaultValue">Add default value</localize></a>
</div>
<button type="button" class="umb-node-preview-add mb3" ng-click="vm.showDefaultValue=true" ng-hide="vm.showDefaultValue">
<localize key="templateEditor_addDefaultValue">Add default value</localize>
</button>
<div class="control-group umb-control-group -no-border" ng-hide="!vm.showDefaultValue">
<div class="umb-el-wrap">
@@ -52,13 +51,17 @@
<div class="control-group umb-control-group">
<div class="umb-el-wrap">
<div class="controls">
<label class="control-label" >
<label class="control-label">
<localize key="templateEditor_recursive">Recursive</localize>
</label>
<label for="recursive">
<input id="recursive" type="checkbox" name="recursive" ng-model="vm.recursive">
<localize key="templateEditor_recursiveDescr">Yes, make it recursive</localize>
</label>
<div class="flex">
<umb-checkbox name="recursive"
disabled="!vm.field"
model="vm.recursive"
text="Yes, make it recursive"
label-key="templateEditor_recursiveDescr">
</umb-checkbox>
</div>
</div>
</div>
</div>
@@ -15,42 +15,40 @@
<div on-drag-leave="vm.dragLeave()" on-drag-end="vm.dragLeave()" on-drag-enter="vm.dragEnter()">
<div class="umb-control-group umb-mediapicker-upload">
<div class="umb-control-group">
<umb-load-indicator
ng-if="vm.loading">
</umb-load-indicator>
<div class="umb-mediapicker-upload">
<div class="form-search">
<i class="icon-search" aria-hidden="true"></i>
<input class="umb-search-field search-query -full-width-input"
ng-model="vm.searchOptions.filter"
localize="placeholder"
placeholder="@placeholders_search"
ng-change="vm.changeSearch()"
type="text"
umb-auto-focus
no-dirty-check
/>
<div class="form-search">
<i class="icon-search" aria-hidden="true"></i>
<input class="umb-search-field search-query -full-width-input"
ng-model="vm.searchOptions.filter"
localize="placeholder"
placeholder="@placeholders_search"
ng-change="vm.changeSearch()"
type="text"
umb-auto-focus
no-dirty-check
/>
<div class="form-search__toggle">
<umb-checkbox
model="showChilds"
on-change="vm.toggle()"
text="Include subfolders in search"
label-key="general_includeFromsubFolders">
</umb-checkbox>
<div class="form-search__toggle">
<umb-checkbox
model="showChilds"
on-change="vm.toggle()"
text="Include subfolders in search"
label-key="general_includeFromsubFolders">
</umb-checkbox>
</div>
</div>
</div>
<div class="upload-button">
<umb-button
type="button"
label-key="general_upload"
action="vm.upload()"
disabled="lockedFolder"
button-style="action">
</umb-button>
<div class="upload-button">
<umb-button
type="button"
label-key="general_upload"
action="vm.upload()"
disabled="lockedFolder"
button-style="action">
</umb-button>
</div>
</div>
</div>
@@ -120,6 +118,11 @@
current-folder-id="{{currentFolder.id}}">
</umb-media-grid>
<umb-load-indicator
ng-if="vm.loading">
</umb-load-indicator>
<div class="flex justify-center">
<umb-pagination
ng-if="vm.searchOptions.totalPages > 0 && !vm.loading"
@@ -136,7 +139,7 @@
</div>
<umb-overlay ng-if="vm.mediaPickerDetailsOverlay.show" model="vm.mediaPickerDetailsOverlay" position="right">
<div class="umb-control-group" ng-if="!target.id">
<h5>
<localize key="@general_url"></localize>
@@ -31,6 +31,7 @@
vm.datePickerChange = datePickerChange;
vm.submit = submit;
vm.close = close;
vm.copyQuery = copyQuery;
function onInit() {
@@ -120,6 +121,11 @@
query.filters.push({});
}
function copyQuery() {
var copyText = $scope.model.result.queryExpression;
navigator.clipboard.writeText(copyText);
}
function trashFilter(query, filter) {
for (var i = 0; i < query.filters.length; i++) {
if (query.filters[i] == filter) {
@@ -15,164 +15,160 @@
<umb-box>
<umb-box-content>
<div class="umb-control-group umb-querybuilder">
<div class="umb-control-group umb-querybuilder">
<div class="row">
<div class="query-items">
<div class="row">
<div class="query-items">
<span><localize key="template_iWant">I want</localize></span>
<span><localize key="template_iWant">I want</localize></span>
<div class="btn-group">
<div class="btn-group">
<umb-button
type="button"
button-style="outline"
action="vm.contentTypeSelectOpen = !vm.contentTypeSelectOpen"
label="{{vm.query.contentType.name}}"
show-caret="true">
</umb-button>
<umb-button type="button"
button-style="outline"
action="vm.contentTypeSelectOpen = !vm.contentTypeSelectOpen"
label="{{vm.query.contentType.name}}"
show-caret="true">
</umb-button>
<umb-dropdown ng-if="vm.contentTypeSelectOpen" on-close="vm.contentTypeSelectOpen = false">
<umb-dropdown-item ng-repeat="contentType in vm.contentTypes">
<a href ng-click="vm.setContentType(contentType); vm.contentTypeSelectOpen = false;">
{{contentType.name}}
</a>
</umb-dropdown-item>
</umb-dropdown>
<umb-dropdown ng-if="vm.contentTypeSelectOpen" on-close="vm.contentTypeSelectOpen = false">
<umb-dropdown-item ng-repeat="contentType in vm.contentTypes">
<a href ng-click="vm.setContentType(contentType); vm.contentTypeSelectOpen = false;">
{{contentType.name}}
</a>
</umb-dropdown-item>
</umb-dropdown>
</div>
</div>
<span><localize key="template_from">from</localize></span>
<span><localize key="template_from">from</localize></span>
<umb-button
type="button"
button-style="outline"
action="vm.chooseSource(vm.query)"
label="{{vm.query.source.name}}">
</umb-button>
<umb-button type="button"
button-style="outline"
action="vm.chooseSource(vm.query)"
label="{{vm.query.source.name}}">
</umb-button>
</div>
</div>
<div class="query-items" ng-repeat="filter in vm.query.filters ">
<div class="query-items" ng-repeat="filter in vm.query.filters ">
<span ng-if="$first">
<localize key="template_where">where</localize>
</span>
<span ng-if="!$first">
<localize key="template_and">and</localize>
</span>
<span ng-if="$first">
<localize key="template_where">where</localize>
</span>
<span ng-if="!$first">
<localize key="template_and">and</localize>
</span>
<div class="btn-group">
<div class="btn-group">
<umb-button
type="button"
button-style="outline"
action="vm.propertyFilterOpen[$index] = !vm.propertyFilterOpen[$index]"
label="{{filter.property.name}}"
show-caret="true">
</umb-button>
<umb-button type="button"
button-style="outline"
action="vm.propertyFilterOpen[$index] = !vm.propertyFilterOpen[$index]"
label="{{filter.property.name}}"
show-caret="true">
</umb-button>
<umb-dropdown ng-if="vm.propertyFilterOpen[$index]" on-close="console.log(1);vm.propertyFilterOpen[$index] = false">
<umb-dropdown-item ng-repeat="property in vm.properties">
<a href ng-click="vm.setFilterProperty(filter, property); vm.propertyFilterOpen[$parent.$parent.$index] = false;">
{{property.name}}
</a>
</umb-dropdown-item>
</umb-dropdown>
<umb-dropdown ng-if="vm.propertyFilterOpen[$index]" on-close="console.log(1);vm.propertyFilterOpen[$index] = false">
<umb-dropdown-item ng-repeat="property in vm.properties">
<a href ng-click="vm.setFilterProperty(filter, property); vm.propertyFilterOpen[$parent.$parent.$index] = false;">
{{property.name}}
</a>
</umb-dropdown-item>
</umb-dropdown>
</div>
</div>
<div class="btn-group" ng-if="filter.property">
<div class="btn-group" ng-if="filter.property">
<umb-button
type="button"
button-style="outline"
action="vm.termFilterOpen[$index] = !vm.termFilterOpen[$index]"
label="{{filter.term.name}}"
show-caret="true">
</umb-button>
<umb-button type="button"
button-style="outline"
action="vm.termFilterOpen[$index] = !vm.termFilterOpen[$index]"
label="{{filter.term.name}}"
show-caret="true">
</umb-button>
<umb-dropdown ng-if="vm.termFilterOpen[$index]" on-close="vm.termFilterOpen[$index] = false">
<umb-dropdown-item ng-repeat="term in vm.getPropertyOperators(filter.property)">
<a href ng-click="vm.setFilterTerm(filter, term); vm.termFilterOpen[$parent.$parent.$index] = false;">
{{term.name}}
</a>
</umb-dropdown-item>
</umb-dropdown>
<umb-dropdown ng-if="vm.termFilterOpen[$index]" on-close="vm.termFilterOpen[$index] = false">
<umb-dropdown-item ng-repeat="term in vm.getPropertyOperators(filter.property)">
<a href ng-click="vm.setFilterTerm(filter, term); vm.termFilterOpen[$parent.$parent.$index] = false;">
{{term.name}}
</a>
</umb-dropdown-item>
</umb-dropdown>
</div>
</div>
<span ng-switch="filter.term.appliesTo[0]">
<span ng-switch="filter.term.appliesTo[0]">
<!-- Filter term types (string, int, date) -->
<input type="text" ng-switch-when="string" style="width:90px; margin-bottom: 0;" ng-model="filter.constraintValue" ng-change="vm.changeConstraintValue()" />
<input type="number" ng-switch-when="int" style="width:90px; margin-bottom: 0;" ng-model="filter.constraintValue" ng-change="vm.changeConstraintValue()" />
<!-- Filter term types (string, int, date) -->
<input type="text" ng-switch-when="string" style="width:90px; margin-bottom: 0;" ng-model="filter.constraintValue" ng-change="vm.changeConstraintValue()" />
<input type="number" ng-switch-when="int" style="width:90px; margin-bottom: 0;" ng-model="filter.constraintValue" ng-change="vm.changeConstraintValue()" />
<span ng-switch-when="datetime">
<umb-date-time-picker
options="vm.datePickerConfig"
on-change="vm.datePickerChange(dateStr, filter)">
</umb-date-time-picker>
</span>
<span ng-switch-when="datetime">
<umb-date-time-picker options="vm.datePickerConfig"
on-change="vm.datePickerChange(dateStr, filter)">
</umb-date-time-picker>
</span>
</span>
</span>
<a href ng-click="vm.addFilter(vm.query)">
<i class="icon-add"></i>
</a>
<a href ng-click="vm.addFilter(vm.query)">
<i class="icon-add"></i>
</a>
<a href ng-click="vm.trashFilter(vm.query, filter)">
<i class="icon-trash"></i>
</a>
<a href ng-click="vm.trashFilter(vm.query, filter)">
<i class="icon-trash"></i>
</a>
</div>
</div>
<div class="query-items">
<div class="query-items">
<span><localize key="template_orderBy">order by</localize></span>
<span><localize key="template_orderBy">order by</localize></span>
<div class="btn-group">
<div class="btn-group">
<umb-button
type="button"
button-style="outline"
action="vm.sortPropertyOpen = !vm.sortPropertyOpen"
label="{{vm.query.sort.property.name}}"
show-caret="true">
</umb-button>
<umb-button type="button"
button-style="outline"
action="vm.sortPropertyOpen = !vm.sortPropertyOpen"
label="{{vm.query.sort.property.name}}"
show-caret="true">
</umb-button>
<umb-dropdown ng-if="vm.sortPropertyOpen" on-close="vm.sortPropertyOpen = false">
<umb-dropdown-item ng-repeat="property in vm.properties">
<a href ng-click="vm.setSortProperty(vm.query, property); vm.sortPropertyOpen = false;">
{{property.name}}
</a>
</umb-dropdown-item>
</umb-dropdown>
<umb-dropdown ng-if="vm.sortPropertyOpen" on-close="vm.sortPropertyOpen = false">
<umb-dropdown-item ng-repeat="property in vm.properties">
<a href ng-click="vm.setSortProperty(vm.query, property); vm.sortPropertyOpen = false;">
{{property.name}}
</a>
</umb-dropdown-item>
</umb-dropdown>
</div>
</div>
<umb-button
ng-show="vm.query.sort.property.name"
type="button"
button-style="outline"
action="vm.changeSortOrder(vm.query)"
label="{{vm.query.sort.translation.currentLabel}}">
</umb-button>
<umb-button ng-show="vm.query.sort.property.name"
type="button"
button-style="outline"
action="vm.changeSortOrder(vm.query)"
label="{{vm.query.sort.translation.currentLabel}}">
</umb-button>
</div>
</div>
</div>
</div>
<h5>{{model.result.resultCount}} <localize key="template_itemsReturned">items, returned in</localize> {{model.result.executionTime}} ms</h5>
<ul class="nav unstyled">
<li ng-repeat="item in model.result.sampleResults">
<i class="icon icon-document turquoise-d1"></i> {{item.name}}
</li>
</ul>
<ul class="nav unstyled">
<li ng-repeat="item in model.result.sampleResults">
<i class="icon icon-document turquoise-d1"></i> {{item.name}}
</li>
</ul>
<pre>{{model.result.queryExpression}}</pre>
<pre>{{model.result.queryExpression}}</pre>
<a href ng-click="vm.copyQuery()">
<i class="icon-document"></i> <localize key="template_copyToClipboard">copy to clipboard</localize>
</a>
</div>
</div>
</umb-box-content>
</umb-box>
@@ -1,7 +1,7 @@
(function () {
"use strict";
function RollbackController($scope, contentResource, localizationService, assetsService) {
function RollbackController($scope, contentResource, localizationService, assetsService, dateHelper, userService) {
var vm = this;
@@ -90,11 +90,15 @@
const culture = $scope.model.node.variants.length > 1 ? vm.currentVersion.language.culture : null;
return contentResource.getRollbackVersions(nodeId, culture)
.then(function(data){
vm.previousVersions = data.map(version => {
version.displayValue = version.versionDate + " - " + version.versionAuthorName;
return version;
});
.then(function (data) {
// get current backoffice user and format dates
userService.getCurrentUser().then(function (currentUser) {
vm.previousVersions = data.map(version => {
var timestampFormatted = dateHelper.getLocalDate(version.versionDate, currentUser.locale, 'LLL');
version.displayValue = timestampFormatted + ' - ' + version.versionAuthorName;
return version;
});
});
});
}
@@ -1,26 +1,42 @@
(function () {
"use strict";
function TemplateSectionsController($scope, formHelper) {
function TemplateSectionsController($scope, formHelper, localizationService) {
var vm = this;
vm.labels = {};
vm.select = select;
vm.submit = submit;
vm.close = close;
$scope.model.mandatoryRenderSection = false;
if(!$scope.model.title) {
$scope.model.title = "Sections";
}
function onInit() {
if($scope.model.hasMaster) {
if ($scope.model.hasMaster) {
$scope.model.insertType = 'addSection';
} else {
$scope.model.insertType = 'renderBody';
}
var labelKeys = [
"template_insertSections",
"template_sectionMandatory"
];
localizationService.localizeMany(labelKeys).then(function (data) {
vm.labels.title = data[0];
vm.labels.sectionMandatory = data[1];
setTitle(vm.labels.title);
});
}
function setTitle(value) {
if (!$scope.model.title) {
$scope.model.title = value;
}
}
function select(type) {
@@ -34,13 +50,12 @@
}
function close() {
if($scope.model.close) {
if ($scope.model.close) {
$scope.model.close();
}
}
onInit();
}
angular.module("umbraco").controller("Umbraco.Editors.TemplateSectionsController", TemplateSectionsController);
@@ -44,10 +44,10 @@
</div>
<div>
<label>
<input type="checkbox" ng-model="model.mandatoryRenderSection" /> <localize key="template_sectionMandatory" />
</label>
<div class="flex">
<umb-checkbox model="model.mandatoryRenderSection" text="{{vm.labels.sectionMandatory}}" />
</div>
<div class="umb-insert-code-box__description">
<localize key="template_sectionMandatoryDesc" />
</div>
@@ -10,12 +10,8 @@
<button type="button" class="umb-language-picker__toggle" ng-click="toggleLanguageSelector()" aria-haspopup="true" aria-expanded="{{page.languageSelectorIsOpen}}">
<span>
<span class="sr-only">
<<<<<<< HEAD
<localize key="visuallyHiddenTexts_currentLanguage">Current language</localize>
<span>: </span>
=======
<localize key="visuallyHiddenTexts_currentLanguage">Current language</localize>:
>>>>>>> v8/dev
</span>
<span>{{selectedLanguage.name}}</span>
</span>
@@ -30,12 +26,8 @@
ng-repeat="language in languages"
>
<span class="sr-only">
<<<<<<< HEAD
<localize key="visuallyHiddenTexts_switchLanguage">Switch language to</localize>
<span>: </span>
=======
<localize key="visuallyHiddenTexts_switchLanguage">Switch language to</localize>:
>>>>>>> v8/dev
</span>
<span>{{language.name}}</span>
</button>
@@ -46,6 +46,7 @@
title="{{historyLabel}}">
<umb-button
ng-hide="node.trashed"
type="button"
button-style="outline"
action="openRollback()"
@@ -168,9 +169,9 @@
ng-change="updateTemplate(node.template)">
<option value="">{{chooseLabel}}...</option>
</select>
<a href="" ng-show="allowChangeTemplate && node.template !== null" class="umb-node-preview__action" style="margin-left:15px;" ng-click="openTemplate()">
<button ng-show="allowChangeTemplate && node.template !== null" class="umb-node-preview__action" style="margin-left:15px;" ng-click="openTemplate()">
<localize key="general_open">Open</localize>
</a>
</button>
</div>
</umb-control-group>
@@ -1,6 +1,6 @@
<div data-element="editor-header" class="umb-editor-header" ng-class="{'-split-view-active': splitViewOpen === true}">
<div class="flex items-center" style="height: 100%;">
<umb-loader ng-show="loading"></umb-loader>
<div class="flex items-center" style="height: 100%;" ng-hide="loading">
<div ng-if="showBackButton === true && splitViewOpen !== true" style="margin-right: 15px;">
<button type="button" class="umb-editor-header__back" ng-click="goBack()" prevent-default>
@@ -22,11 +22,18 @@
</ng-form>
<div id="nameField" class="umb-editor-header__name-and-description" style="flex: 1 1 auto;">
<div>
<p tabindex="0" class="sr-only" ng-show="accessibility.a11yMessageVisible">
{{accessibility.a11yMessage}}
</p>
</div>
<div class="umb-editor-header__name-wrapper" ng-show="!nameLocked || !hideAlias">
<label for="headerName" class="sr-only" ng-show="accessibility.a11yNameVisible">{{accessibility.a11yName}}</label>
<ng-form name="headerNameForm">
<input data-element="editor-name-field"
no-password-manager
type="text"
id="headerName"
class="umb-editor-header__name-input"
localize="placeholder"
placeholder="@placeholders_entername"
@@ -38,7 +45,10 @@
focus-on-filled="true"
val-server-field="Name"
required
autocomplete="off" />
aria-required="true"
aria-invalid="{{contentForm.headerNameForm.headerName.$invalid ? true : false}}"
autocomplete="off"
maxlength="255"/>
</ng-form>
<umb-generate-alias data-element="editor-alias"
@@ -62,7 +72,7 @@
localize="placeholder"
placeholder="@placeholders_enterDescription"
ng-if="!hideDescription && !descriptionLocked"
ng-model="$parent.description" />
ng-model="$parent.description"/>
<div class="umb-panel-header-locked-description" ng-if="descriptionLocked">{{ description }}</div>
@@ -1,4 +1,4 @@
<label class="checkbox umb-form-check umb-form-check--checkbox" ng-class="{ 'umb-form-check--disabled': vm.disabled }">
<label class="checkbox umb-form-check umb-form-check--checkbox {{vm.cssClass}}" ng-class="{ 'umb-form-check--disabled': vm.disabled }">
<input type="checkbox"
id="{{vm.inputId}}"
name="{{vm.name}}"
@@ -0,0 +1,15 @@
<div class="umb-property-actions" ng-if="vm.actions.length > 0">
<button type="button" class="btn-reset umb-outline umb-property-actions__toggle" ng-click="vm.toggle()" localize="title" title="propertyActions_tooltipForPropertyActionsMenu"><i></i><i></i><i></i></button>
<div class="umb-property-actions__menu" role="menu" ng-if="vm.isOpen" on-outside-click="vm.close()" on-close="vm.close()" deep-blur="vm.close()">
<button class="umb-property-actions__menu-open-toggle" ng-click="vm.close()" tabindex="-1"><i></i><i></i><i></i></button>
<ul class="umb-contextmenu">
<li ng-repeat="action in vm.actions" role="menuitem" class="umb-contextmenu-item" ng-class="{'-opens-dialog': action.opensDialog}">
<button type="button" class="btn-reset umb-outline" ng-click="vm.executeAction(action)" ng-disabled="action.isDisabled === true">
<i class="icon icon-{{action.icon}}" aria-hidden="true"></i>
<span class="menu-label"><localize key="{{::action.labelKey}}" tokens="action.labelTokens"></localize></span>
</button>
</li>
</ul>
</div>
</div>
@@ -0,0 +1,61 @@
(function () {
'use strict';
/**
* A component to render the property action toggle
*/
function umbPropertyActionsController(keyboardService) {
var vm = this;
vm.isOpen = false;
function initDropDown() {
keyboardService.bind("esc", vm.close);
}
function destroyDropDown() {
keyboardService.unbind("esc");
}
vm.toggle = function() {
if (vm.isOpen === true) {
vm.close();
} else {
vm.open();
}
}
vm.open = function() {
vm.isOpen = true;
initDropDown();
}
vm.close = function() {
vm.isOpen = false;
destroyDropDown();
}
vm.executeAction = function(action) {
action.method();
vm.close();
}
vm.$onDestroy = function () {
if (vm.isOpen === true) {
destroyDropDown();
}
}
}
var umbPropertyActionsComponent = {
templateUrl: 'views/components/property/property-actions/umb-property-actions.html',
bindings: {
actions: "<"
},
controllerAs: 'vm',
controller: umbPropertyActionsController
};
angular.module('umbraco.directives').component('umbPropertyActions', umbPropertyActionsComponent);
})();
@@ -6,19 +6,25 @@
<div class="umb-el-wrap">
<label class="control-label" ng-hide="property.hideLabel" for="{{property.alias}}" ng-attr-title="{{propertyAlias}}">
<div class="control-header">
<small ng-if="showInherit" class="db" style="padding-top: 0; margin-bottom: 5px;">
<localize key="contentTypeEditor_inheritedFrom"></localize> {{inheritsFrom}}
</small>
{{property.label}}
<label class="control-label" ng-hide="property.hideLabel" for="{{property.alias}}" ng-attr-title="{{propertyAlias}}">
<span ng-if="property.validation.mandatory">
<strong class="umb-control-required">*</strong>
</span>
<small ng-bind-html="property.description | preserveNewLineInHtml"></small>
</label>
{{property.label}}
<span ng-if="property.validation.mandatory">
<strong class="umb-control-required">*</strong>
</span>
</label>
<umb-property-actions actions="propertyEditorAPI.propertyActions"></umb-property-actions>
<small class="control-description" ng-bind-html="property.description | preserveNewLineInHtml"></small>
</div>
<div class="controls" ng-transclude>
</div>
@@ -21,8 +21,8 @@
</span>
<input type="text"
id="{{vm.htmlId}}"
class="typeahead tags-{{vm.htmlId}}"
id="{{vm.inputId}}"
class="typeahead tags-{{vm.inputId}}"
ng-model="vm.tagToAdd"
ng-keydown="vm.addTagOnEnter($event)"
ng-blur="vm.addTag()"
@@ -14,6 +14,7 @@
action="confirm()"
button-style="{{confirmButtonStyle || 'primary'}}"
state="confirmButtonState"
disabled="confirmDisabled === true"
label-key="{{confirmLabelKey || 'general_ok'}}">
</umb-button>
</div>
@@ -6,24 +6,21 @@
</div>
<div ng-switch="vm.changing">
<div ng-switch-when="false">
<a href="" ng-click="vm.doChange()" class="btn btn-small">
<button type="button" ng-click="vm.doChange()" class="btn umb-button__button btn-action">
<localize key="general_changePassword">Change password</localize>
</a>
</button>
</div>
<div ng-switch-when="true">
<ng-form name="changePasswordForm">
<umb-control-group alias="resetPassword" label="@user_resetPassword" ng-show="vm.config.enableReset">
<input type="checkbox" ng-model="vm.passwordValues.reset"
name="resetPassword"
val-server-field="resetPassword"
no-dirty-check
ng-change="vm.showReset = !vm.showReset" />
<umb-checkbox model="vm.passwordValues.reset" server-validation-field="resetPassword"
on-change="vm.showReset = !vm.showReset" />
<span ng-messages="changePasswordForm.resetPassword.$error" show-validation-on-submit>
<span class="help-inline" ng-message="valServerField">{{changePasswordForm.resetPassword.errorMsg}}</span>
</span>
</umb-control-group>
</umb-control-group>
<!-- we need to show the old pass field when the provider cannot retrieve the password -->
<umb-control-group alias="oldPassword" label="@user_oldPassword" ng-if="vm.showOldPass()" required="true">
@@ -62,9 +59,9 @@
</span>
</umb-control-group>
<a href="" ng-click="vm.cancelChange()" ng-show="vm.showCancelBtn()" class="btn btn-small">
<button ng-click="vm.cancelChange()" ng-show="vm.showCancelBtn()" class="btn umb-button__button btn-cancel umb-button--">
<localize key="general_cancel">Cancel</localize>
</a>
</button>
</ng-form>
</div>
@@ -82,6 +82,7 @@
view: "views/dashboard/content/overlays/disable.html",
submitButtonLabel: "Disable",
submitButtonLabelKey: "actions_disable",
submitButtonStyle:"danger",
submit: function (model) {
performDisable();
overlayService.close();
@@ -14,7 +14,7 @@
size="s"
action="vm.disableUrlTracker($event)"
label-key="redirectUrls_disableUrlTracker"
button-style="white">
button-style="danger">
</umb-button>
<umb-button
@@ -23,8 +23,7 @@
size="s"
button-style="success"
action="vm.enableUrlTracker()"
label-key="redirectUrls_enableUrlTracker"
button-style="success">
label-key="redirectUrls_enableUrlTracker">
</umb-button>
</umb-editor-sub-header-section>
@@ -1,15 +0,0 @@
<h3>Install a Starter Site and Skin</h3>
<p>If you haven't already installed one of our Starter Kits, we think you should do that now. This is one of the best ways to start working with Umbraco. After you install a Starter Kit, you can select a skin to make it look great and customize the kit to your liking.</p>
<h4>Starter Kits:</h4>
<div class="dashboardColWrapper">
<div class="dashboardCols">
<div class="dashboardCol">
<ul>
<li><strong><a class="btn-link -underline" href="/install/?installStep=skinning" target="_blank">Simple Starter Kit</a></strong> a bare-bones website that introduces you to a set of well-defined conventions for building an Umbraco website</li>
<li><strong><a class="btn-link -underline" href="/install/?installStep=skinning" target="_blank">Blog Starter Kit</a></strong> a powerful blog kit with all the bells and whistles</li>
<li><strong><a class="btn-link -underline" href="/install/?installStep=skinning" target="_blank">Business Starter Kit</a></strong> a basic business kit to get you up and running today</li>
<li><strong><a class="btn-link -underline" href="/install/?installStep=skinning" target="_blank">Personal Starter Kit</a></strong> a basic personal kit for your own space on the web</li>
</ul>
</div>
</div>
</div>
@@ -1,38 +0,0 @@
<h3>Desktop Media Uploader</h3>
<p><strong>Desktop Media Uploader</strong> is a small desktop application that you can install on your computer which allows you to easily upload media items directly to the media section.</p>
<p>The badge below will auto configure itself based upon whether you already have <strong>Desktop Media Uploader</strong> installed or not.</p>
<p>Just click the <strong>Install Now / Upgrade Now / Launch Now</strong> link to perform that action.</p>
<p>
<div id="dmu-badge">
<p>Download <a class="btn-link -underline" href="dashboard/air/desktopmediauploader.air">Desktop Media Uploader</a> now.</p>
<small>
This application requires Adobe&#174;&nbsp;AIR&#8482; to be installed for <a class="btn-link -underline" href="https://airdownload.adobe.com/air/mac/download/latest/AdobeAIR.dmg">Mac OS</a> or <a class="btn-link -underline" href="https://airdownload.adobe.com/air/win/download/latest/AdobeAIRInstaller.exe">Windows</a>.
</small>
</div>
</p>
<!--
<script type="text/javascript">
// <![CDATA[
var flashvars = {
appid: "org.umbraco.DesktopMediaUploader",
appname: "Desktop Media Uploader",
appversion: "v2.1.0",
appurl: "<%= FullyQualifiedAppPath %>umbraco/dashboard/air/desktopmediauploader.air",
applauncharg: "<%= AppLaunchArg %>",
image: "/umbraco/dashboard/images/dmu-badge.jpg?2.1.0",
airversion: "2.0"
};
var params = {
menu: "false",
wmode: "opaque"
};
var attributes = {
style: "margin-bottom:10px;"
};
swfobject.embedSWF("/umbraco/dashboard/swfs/airinstallbadge.swf", "dmu-badge", "215", "180", "9.0.115", "/umbraco/dashboard/swfs/expressinstall.swf", flashvars, params, attributes);
// ]]>
</script> -->
@@ -1,13 +0,0 @@
<h3>Start here</h3>
<h4>Get started with Media right now</h4>
<p>Use the tool below to upload your images or documents to a media folder.</p>
<h3>Follow these steps:</h3>
<ul>
<li>Click <strong>Install</strong> and follow the on screen instructions to install the <strong>Desktop Media Uploader</strong></li>
<li>Enter your login details for the site and click <strong>Sign In</strong></li>
<li>Choose a media folder to upload files to from the <strong>Upload files to...</strong> dropdown list</li>
<li>Drag the files and folders you wish to upload directly into the <strong>Desktop Media Uploader</strong> application</li>
<li>Click <strong>Upload</strong> to start uploading</li>
</ul>
<p>For a more thorough guide on how to use the <strong>Desktop Media Uploader</strong>, <a class="btn-link -underline" href="https://screenr.com/vXr" target="_blank">checkout this video</a>.</p>
@@ -4,13 +4,15 @@
<umb-box>
<umb-box-content>
<h3>Hours of Umbraco training videos are only a click away</h3>
<p>Want to master Umbraco? Spend a couple of minutes learning some best practices by watching one of these videos about using Umbraco. And visit <a href="https://umbraco.tv" target="_blank">umbraco.tv</a> for even more Umbraco videos</p>
<h3><localize key="settingsDashboardVideos_trainingHeadline">Hours of Umbraco training videos are only a click away</localize></h3>
<localize key="settingsDashboardVideos_trainingDescription">
<p>Want to master Umbraco? Spend a couple of minutes learning some best practices by watching one of these videos about using Umbraco. And visit <a href="http://umbraco.tv" target="_blank">umbraco.tv</a> for even more Umbraco videos</p>
</localize>
</umb-box-content>
</umb-box>
<div ng-show="videos.length">
<h4>To get you started:</h4>
<h4><localize key="settingsDashboardVideos_getStarted">To get you started</localize>:</h4>
<ul class="thumbnails" >
<li class="span2" ng-repeat="video in videos">
<div class="thumbnail" style="margin-right: 20px">
@@ -199,6 +199,7 @@ function ExamineManagementController($scope, $http, $q, $timeout, $location, umb
view: "views/dashboard/settings/overlays/examinemanagement.rebuild.html",
index: index,
submitButtonLabelKey: "general_ok",
submitButtonStyle :"danger",
submit: function (model) {
performRebuild(model.index);
overlayService.close();
@@ -1,13 +1,5 @@
<div id="examineManagement" class="examine-management" ng-controller="Umbraco.Dashboard.ExamineManagementController as vm">
<div ng-if="vm.viewState === 'list'">
<umb-box>
<umb-box-content>
<h3 class="bold">Examine Management</h3>
</umb-box-content>
</umb-box>
</div>
<div ng-show="vm.loading">
<umb-load-indicator></umb-load-indicator>
</div>
@@ -89,7 +81,7 @@
<umb-editor-sub-header>
<umb-editor-sub-header-content-left>
<button type="button" class="umb-package-details__back-action" ng-click="vm.setViewState('list');"><span aria-hidden="true">&larr;</span> <localize key="general_backToOverview">Back to overview</localize></button>
<button type="button" class="umb-package-details__back-action" ng-click="vm.setViewState('list');"><span aria-hidden="true">&larr;</span> <localize key="general_backToOverview">Back to overview</localize></button>
</umb-editor-sub-header-content-left>
</umb-editor-sub-header>
@@ -108,8 +100,12 @@
<div class="umb-panel-group__details-check">
<div class="umb-panel-group__details-check-title">
<div class="umb-panel-group__details-check-name">Search</div>
<div class="umb-panel-group__details-check-description">Search the index and view the results</div>
<div class="umb-panel-group__details-check-name">
<localize key="general_search">Search</localize>
</div>
<div class="umb-panel-group__details-check-description">
<localize key="examineManagement_searchDescription">Search the index and view the results</localize>
</div>
</div>
<div class="umb-panel-group__details-status">
@@ -233,7 +229,7 @@
<div class="umb-panel-group__details-status-text">
<div>{{vm.selectedIndex.healthStatus}}</div>
<div ng-show="!vm.selectedIndex" class="color-red">
The index cannot be read and will need to be rebuilt
<localize key="examineManagement_indexCannotRead">The index cannot be read and will need to be rebuilt</localize>
</div>
<!--<div ng-if="status.description" ng-bind-html="status.description"></div>-->
</div>
@@ -373,7 +369,7 @@
<umb-button ng-show="!vm.selectedIndex.isProcessing && (!vm.selectedIndex.processingAttempts || vm.selectedIndex.processingAttempts < 100)"
disabled="!vm.selectedIndex.canRebuild"
type="button"
button-style="success"
button-style="danger"
action="vm.rebuildIndex(vm.selectedIndex, $event)"
label="Rebuild index"
label-key="examineManagement_rebuildIndex">
@@ -385,13 +381,14 @@
</div>
<div ng-show="vm.selectedIndex.processingAttempts >= 100">
The process is taking longer than expected, check the umbraco log to see if there have been any errors during this operation
<localize key="examineManagement_processIsTakingLonger">The process is taking longer than expected, check the umbraco log to see if there have been any errors during this operation</localize>
</div>
</ng-form>
<div class="umb-panel-group__details-status-action-description" ng-show="!vm.selectedIndex.canRebuild">
This index cannot be rebuilt because it has no assigned <code>IIndexPopulator</code>
<localize key="examineManagement_indexCannotRebuild">This index cannot be rebuilt because it has no assigned </localize>
<code><localize key="examineManagement_iIndexPopulator">IIndexPopulator</localize></code>
</div>
</div>
</div>
@@ -4,78 +4,70 @@
<umb-box>
<umb-box-content>
<div class="flex justify-between items-center">
<h3 class="bold">Health Check</h3>
<umb-button
type="button"
button-style="success"
label="Check All Groups"
action="vm.checkAllGroups(vm.groups)">
</umb-button>
</div>
<div class="umb-healthcheck-help-text">
<p>The health checker evaluates various areas of your site for best practice settings, configuration, potential problems, etc. You can easily fix problems by pressing a button.
You can add your own health checks, have a look at <a href="https://our.umbraco.com/documentation/Extending/Healthcheck/" target="_blank" class="btn-link -underline">the documentation for more information</a> about custom health checks.</p>
<p>
The health checker evaluates various areas of your site for best practice settings, configuration, potential problems, etc. You can easily fix problems by pressing a button.
You can add your own health checks, have a look at <a href="https://our.umbraco.com/documentation/Extending/Healthcheck/" target="_blank" class="btn-link -underline">the documentation for more information</a> about custom health checks.
</p>
</div>
<div class="umb-panel-group__details-status-actions">
<umb-button type="button"
button-style="success"
label="Check All Groups"
action="vm.checkAllGroups(vm.groups)">
</umb-button>
</div>
</umb-box-content>
</umb-box>
<div class="umb-healthcheck">
<div class="umb-air" ng-repeat="group in vm.groups">
<button type="button" class="umb-healthcheck-group" ng-click="vm.openGroup(group);">
<div class="umb-healthcheck-title">{{group.name}}</div>
<div class="umb-healthcheck-title">{{group.name}}</div>
<div class="umb-healthcheck-group__load-container" ng-if="group.loading">
<umb-load-indicator></umb-load-indicator>
<div class="umb-healthcheck-group__load-container" ng-if="group.loading">
<umb-load-indicator></umb-load-indicator>
</div>
<div class="umb-healthcheck-messages"
ng-hide="group.loading || !group.totalSuccess && !group.totalWarning && !group.totalError && !group.totalInfo">
<div class="umb-healthcheck-message" ng-if="group.totalSuccess > 0">
<i class="icon-check color-green" aria-hidden="true"></i>
{{ group.totalSuccess }}
<span class="sr-only">
<localize key="visuallyHiddenTexts_passed">passed</localize>
</span>
</div>
<div
class="umb-healthcheck-messages"
ng-hide="group.loading || !group.totalSuccess && !group.totalWarning && !group.totalError && !group.totalInfo"
>
<div class="umb-healthcheck-message" ng-if="group.totalSuccess > 0">
<i class="icon-check color-green" aria-hidden="true"></i>
{{ group.totalSuccess }}
<span class="sr-only">
<localize key="visuallyHiddenTexts_passed">passed</localize>
</span>
</div>
<div class="umb-healthcheck-message" ng-if="group.totalWarning > 0">
<i class="icon-alert color-orange" aria-hidden="true"></i>
{{ group.totalWarning }}
<span class="sr-only">
<localize key="visuallyHiddenTexts_warning">warning</localize>
</span>
</div>
<div class="umb-healthcheck-message" ng-if="group.totalError > 0">
<i class="icon-delete color-red" aria-hidden="true"></i>
{{ group.totalError }}
<span class="sr-only">
<localize key="visuallyHiddenTexts_failed">failed</localize>
</span>
</div>
<div class="umb-healthcheck-message" ng-if="group.totalInfo > 0">
<i class="umb-healthcheck-status-icon icon-info" aria-hidden="true"></i>
{{ group.totalInfo }}
<span class="sr-only">
<localize key="visuallyHiddenTexts_suggestion">suggestion</localize>
</span>
</div>
<div class="umb-healthcheck-message" ng-if="group.totalWarning > 0">
<i class="icon-alert color-orange" aria-hidden="true"></i>
{{ group.totalWarning }}
<span class="sr-only">
<localize key="visuallyHiddenTexts_warning">warning</localize>
</span>
</div>
<div class="umb-healthcheck-message" ng-if="group.totalError > 0">
<i class="icon-delete color-red" aria-hidden="true"></i>
{{ group.totalError }}
<span class="sr-only">
<localize key="visuallyHiddenTexts_failed">failed</localize>
</span>
</div>
<div class="umb-healthcheck-message" ng-if="group.totalInfo > 0">
<i class="umb-healthcheck-status-icon icon-info" aria-hidden="true"></i>
{{ group.totalInfo }}
<span class="sr-only">
<localize key="visuallyHiddenTexts_suggestion">suggestion</localize>
</span>
</div>
</div>
</button>
</div>
</div>
</div>
<div ng-if="vm.viewState === 'details'">
@@ -88,31 +80,25 @@
</umb-editor-sub-header-content-left>
</umb-editor-sub-header>
<div class="umb-panel-group__details">
<div class="umb-panel-group__details-group">
<div class="umb-panel-group__details-group-title">
<div class="umb-panel-group__details-group-name">{{ vm.selectedGroup.name }}</div>
<umb-button
type="button"
action="vm.checkAllInGroup(vm.selectedGroup, vm.selectedGroup.checks)"
label="Check group">
<umb-button type="button" button-style="success"
action="vm.checkAllInGroup(vm.selectedGroup, vm.selectedGroup.checks)"
label="Check group">
</umb-button>
</div>
<div class="umb-panel-group__details-checks">
<div class="umb-panel-group__details-check" ng-repeat="check in vm.selectedGroup.checks">
<div class="umb-panel-group__details-check-title">
<div class="umb-panel-group__details-check-name">{{ check.name }}</div>
<div class="umb-panel-group__details-check-description">{{ check.description }}</div>
</div>
<div class="umb-panel-group__details-status" ng-repeat="status in check.status">
<div class="umb-panel-group__details-status-icon-container" aria-hidden="true">
<i class="umb-healthcheck-status-icon icon-check color-green" ng-if="status.resultType === 0"></i>
<i class="umb-healthcheck-status-icon icon-alert icon-alert color-yellow" ng-if="status.resultType === 1"></i>
@@ -121,7 +107,6 @@
</div>
<div class="umb-panel-group__details-status-content">
<div class="umb-panel-group__details-status-text">
<span class="sr-only" ng-if="status.resultType === 0">
<localize key="visuallyHiddenTexts_checkPassed">Check passed</localize>:
@@ -145,16 +130,15 @@
<div ng-if="action.valueRequired">
<div><label class="bold">Set new value:</label></div>
<input name="providedValue" type="text" ng-model="action.providedValue" required val-email/>
<input name="providedValue" type="text" ng-model="action.providedValue" required val-email />
</div>
<umb-button
type="button"
button-style="success"
size="s"
disabled="healthCheckAction.providedValue.$invalid"
action="vm.executeAction(check, $parent.$index, action)"
label="{{action.name}}">
<umb-button type="button"
button-style="success"
size="s"
disabled="healthCheckAction.providedValue.$invalid"
action="vm.executeAction(check, $parent.$index, action)"
label="{{action.name}}">
</umb-button>
</ng-form>
@@ -162,9 +146,7 @@
<div class="umb-panel-group__details-status-action-description" ng-if="action.description" ng-bind-html="action.description"></div>
</div>
</div>
</div>
</div>
<div ng-show="check.loading">
@@ -173,13 +155,8 @@
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -3,52 +3,112 @@
<div ng-show="vm.loading || vm.working" style="background: rgba(255, 255, 255, 0.60); position: absolute; left: 0; right: 0; top: 0; bottom: 0;">
<umb-load-indicator></umb-load-indicator>
</div>
<p>
<span ng-show="vm.working">(wait)</span>
<span ng-show="!vm.working">{{vm.status}}</span>
<span ng-show="vm.working">(<localize key="nuCache_wait">wait</localize>)</span>
</p>
<div>
<button type="button" ng-click="vm.verify($event)" class="btn btn-danger">Refresh status</button>
<div class="umb-panel-group__details-group">
<div class="umb-panel-group__details-group-title">
<div class="umb-panel-group__details-group-name">
<localize key="nuCache_publishedCacheStatus">Published Cache Status</localize>
</div>
</div>
<div class="umb-panel-group__details-checks">
<div class="umb-panel-group__details-check">
<div class="umb-panel-group__details-status">
<div class="umb-panel-group__details-status-content">
<div class="umb-panel-group__details-status-text">
<p class="umb-panel-group__details-status-action" ng-show="!vm.working">{{vm.status}}</p>
</div>
<div class="umb-panel-group__details-status-actions">
<div class="umb-panel-group__details-status-action no-background no-left-padding">
<button type="button" ng-click="vm.verify($event)" class="btn btn-danger">
<localize key="nuCache_refreshStatus">Refresh status</localize>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<br />
<div class="umb-panel-group__details-group">
<div class="umb-panel-group__details-group-title">
<div class="umb-panel-group__details-group-name">
<localize key="nuCache_caches">Caches</localize>
</div>
</div>
<div class="umb-panel-group__details-checks">
<div class="umb-panel-group__details-check">
<div class="umb-panel-group__details-check-title">
<div class="umb-panel-group__details-check-name">
<localize key="nuCache_memoryCache">Memory Cache</localize>
</div>
<div class="umb-panel-group__details-check-description">
<localize key="nuCache_memoryCacheDescription">
This button lets you reload the in-memory cache, by entirely reloading it from the database
cache (but it does not rebuild that database cache). This is relatively fast.
Use it when you think that the memory cache has not been properly refreshed, after some events
triggered&mdash;which would indicate a minor Umbraco issue.
(note: triggers the reload on all servers in an LB environment).
</localize>
<h4 class="mt4">Memory Cache</h4>
</div>
<p>
This button lets you reload the in-memory cache, by entirely reloading it from the database
cache (but it does not rebuild that database cache). This is relatively fast.
Use it when you think that the memory cache has not been properly refreshed, after some events
triggered&mdash;which would indicate a minor Umbraco issue.
(note: triggers the reload on all servers in an LB environment).
</p>
<div class="umb-panel-group__details-status-actions">
<div class="umb-panel-group__details-status-action no-background no-left-padding">
<button type="button" ng-click="vm.reload($event)" class="btn btn-danger">
<localize key="nuCache_reload">Reload</localize>
</button>
</div>
</div>
</div>
<div>
<button type="button" ng-click="vm.reload($event)" class="btn btn-danger">Reload</button>
</div>
<h4 class="mt4">Database Cache</h4>
<div class="umb-panel-group__details-check-title top-border">
<div class="umb-panel-group__details-check-name">
<localize key="nuCache_databaseCache">Database Cache</localize>
</div>
<div class="umb-panel-group__details-check-description">
<localize key="nuCache_databaseCacheDescription">
This button lets you rebuild the database cache, ie the content of the cmsContentNu table.
<strong>Rebuilding can be expensive.</strong>
Use it when reloading is not enough, and you think that the database cache has not been
properly generated&mdash;which would indicate some critical Umbraco issue.
</localize>
</div>
<div class="umb-panel-group__details-status-actions">
<div class="umb-panel-group__details-status-action no-background no-left-padding">
<button type="button" ng-click="vm.rebuild($event)" class="btn btn-danger">
<localize key="nuCache_rebuild">Rebuild</localize>
</button>
</div>
</div>
</div>
<p>
This button lets you rebuild the database cache, ie the content of the cmsContentNu table.
<strong>Rebuilding can be expensive.</strong>
Use it when reloading is not enough, and you think that the database cache has not been
properly generated&mdash;which would indicate some critical Umbraco issue.
</p>
<div>
<button type="button" ng-click="vm.rebuild($event)" class="btn btn-danger">Rebuild</button>
</div>
<div class="umb-panel-group__details-check-title top-border">
<div class="umb-panel-group__details-check-name">
<localize key="nuCache_internals">Internals</localize>
</div>
<div class="umb-panel-group__details-check-description">
<localize key="nuCache_internalsDescription">
This button lets you trigger a NuCache snapshots collection (after running a fullCLR GC).
Unless you know what that means, you probably do <em>not</em> need to use it.
</localize>
<h4 class="mt4">Internals</h4>
<p>
This button lets you trigger a NuCache snapshots collection (after running a fullCLR GC).
Unless you know what that means, you probably do <em>not</em> need to use it.
</p>
<div>
<button type="button" ng-click="vm.collect($event)" class="btn btn-danger">Collect</button>
</div>
<div class="umb-panel-group__details-status-actions">
<div class="umb-panel-group__details-status-action no-background no-left-padding">
<button type="button" ng-click="vm.collect($event)" class="btn btn-danger">
<localize key="nuCache_collect">Collect</localize>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -6,39 +6,51 @@
<umb-box ng-hide="vm.loading">
<umb-box-content>
<h3 class="bold">Performance profiling</h3>
<h3 class="bold">
<localize key="profiling_performanceProfiling">Performance profiling</localize>
</h3>
<div ng-show="vm.profilerEnabled">
<div class="mb4">
<p>
Umbraco currently runs in debug mode. This means you can use the built-in performance profiler to assess the performance when rendering pages.
</p>
<p>
If you want to activate the profiler for a specific page rendering, simply add <b>umbDebug=true</b> to the querystring when requesting the page.
</p>
<p>
If you want the profiler to be activated by default for all page renderings, you can use the toggle below.
It will set a cookie in your browser, which then activates the profiler automatically.
In other words, the profiler will only be active by default in <i>your</i> browser - not everyone else's.
</p>
<localize key="profiling_performanceProfilingDescription">
<p>
Umbraco currently runs in debug mode. This means you can use the built-in performance profiler to assess the performance when rendering pages.
</p>
<p>
If you want to activate the profiler for a specific page rendering, simply add <b>umbDebug=true</b> to the querystring when requesting the page.
</p>
<p>
If you want the profiler to be activated by default for all page renderings, you can use the toggle below.
It will set a cookie in your browser, which then activates the profiler automatically.
In other words, the profiler will only be active by default in <i>your</i> browser - not everyone else's.
</p>
</localize>
</div>
<div class="mb4">
<div class="flex items-center">
<umb-toggle checked="vm.alwaysOn" id="profilerAlwaysOn" on-click="vm.toggle()"></umb-toggle>
<label for="profilerAlwaysOn" class="mb0 ml2">Activate the profiler by default</label>
<label for="profilerAlwaysOn" class="mb0 ml2">
<localize key="profiling_activateByDefault">Activate the profiler by default</localize>
</label>
</div>
</div>
<h4>Friendly reminder</h4>
<p>
You should never let a production site run in debug mode. Debug mode is turned off by setting <b>debug="false"</b> on the <b>&lt;compilation /&gt;</b> element in web.config.
</p>
<h4>
<localize key="profiling_reminder">Friendly reminder</localize>
</h4>
<localize key="profiling_reminderDescription">
<p>
You should never let a production site run in debug mode. Debug mode is turned off by setting <b>debug="false"</b> on the <b>&lt;compilation /&gt;</b> element in web.config.
</p>
</localize>
</div>
<div ng-hide="vm.profilerEnabled">
<p>
Umbraco currently does not run in debug mode, so you can't use the built-in profiler. This is how it should be for a production site.
</p>
<p>
Debug mode is turned on by setting <b>debug="true"</b> on the <b>&lt;compilation /&gt;</b> element in web.config.
</p>
<localize key="profiling_profilerEnabledDescription">
<p>
Umbraco currently does not run in debug mode, so you can't use the built-in profiler. This is how it should be for a production site.
</p>
<p>
Debug mode is turned on by setting <b>debug="true"</b> on the <b>&lt;compilation /&gt;</b> element in web.config.
</p>
</localize>
</div>
</umb-box-content>
</umb-box>
@@ -1,11 +1,8 @@
<div id="published" ng-controller="Umbraco.Dashboard.PublishedStatusController as vm">
<umb-box>
<umb-box-content>
<h3 class="bold">Published Cache</h3>
<div ng-show="vm.loading">
<umb-load-indicator></umb-load-indicator>
</div>
<umb-load-indicator ng-show="vm.loading"></umb-load-indicator>
<div ng-include="vm.includeUrl"></div>
<div ng-include="vm.includeUrl"></div>
</umb-box-content>
</umb-box>
</div>
@@ -1,14 +1,30 @@
<umb-box>
<umb-box-content>
<h3 class="bold">Start here</h3>
<p>This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section:</p>
<h5>Find out more:</h5>
<h3 class="bold">
<localize key="settingsDashboard_start">Start here</localize>
</h3>
<localize key="settingsDashboard_startDescription">
<p>This section contains the building blocks for your Umbraco site. Follow the below links to find out more about working with the items in the Settings section:</p>
</localize>:
<h5>
<localize key="settingsDashboard_more">Find out more</localize>:
</h5>
<ul>
<li>Read more about working with the items in Settings <a class="btn-link -underline" href="https://our.umbraco.com/documentation/Getting-Started/Backoffice/Sections/" target="_blank">in the Documentation section</a> of Our Umbraco</li>
<li>Ask a question in the <a class="btn-link -underline" href="https://our.umbraco.com/forum" target="_blank">Community Forum</a></li>
<li>Watch our <a class="btn-link -underline" href="https://umbraco.tv" target="_blank">tutorial videos</a> (some are free, some require a subscription)</li>
<li>Find out about our <a class="btn-link -underline" href="https://umbraco.com/products/" target="_blank">productivity boosting tools and commercial support</a></li>
<li>Find out about real-life <a class="btn-link -underline" href="https://umbraco.com/training/" target="_blank">training and certification</a> opportunities</li>
<li>
<localize key="settingsDashboard_bulletPointOne">Read more about working with the items in Settings <a class="btn-link -underline" href="https://our.umbraco.com/documentation/Getting-Started/Backoffice/Sections/" target="_blank">in the Documentation section</a> of Our Umbraco</localize>
</li>
<li>
<localize key="settingsDashboard_bulletPointTwo">Ask a question in the <a class="btn-link -underline" href="https://our.umbraco.com/forum" target="_blank">Community Forum</a></localize>
</li>
<li>
<localize key="settingsDashboard_bulletPointThree">Watch our <a class="btn-link -underline" href="https://umbraco.tv" target="_blank">tutorial videos</a> (some are free, some require a subscription)</localize>
</li>
<li>
<localize key="settingsDashboard_bulletPointFour">Find out about our <a class="btn-link -underline" href="https://umbraco.com/products/" target="_blank">productivity boosting tools and commercial support</a></localize>
</li>
<li>
<localize key="settingsDashboard_bulletPointFive">Find out about real-life <a class="btn-link -underline" href="https://umbraco.com/training/" target="_blank">training and certification</a> opportunities</localize>
</li>
</ul>
</umb-box-content>
</umb-box>
@@ -1,12 +1,18 @@
<h3>Hours of Umbraco training videos are only a click away</h3>
<p>Want to master Umbraco? Spend a couple of minutes learning some best practices by watching one of these videos about using Umbraco. And visit <a href="http://umbraco.tv" target="_blank">umbraco.tv</a> for even more Umbraco videos</p>
<h3>
<localize key="settingsDashboardVideos_trainingHeadline">Hours of Umbraco training videos are only a click away</localize>
</h3>
<localize key="settingsDashboardVideos_trainingDescription">
<p>Want to master Umbraco? Spend a couple of minutes learning some best practices by watching one of these videos about using Umbraco. And visit <a href="http://umbraco.tv" target="_blank">umbraco.tv</a> for even more Umbraco videos</p>
</localize>
<div class="row-fluid"
ng-init="init('https://umbraco.tv/videos/implementor/chapterrss?sort=no')"
ng-controller="Umbraco.Dashboard.StartupVideosController">
<div ng-show="videos.length">
<h4>To get you started:</h4>
<h4>
<localize key="settingsDashboardVideos_getStarted">To get you started</localize>:
</h4>
<ul class="thumbnails" >
<li class="span2" ng-repeat="video in videos">
<div class="thumbnail" style="margin-right: 20px">
@@ -51,6 +51,12 @@ function DataTypeDeleteController($scope, dataTypeResource, treeService, navigat
navigationService.hideDialog();
};
vm.onReferenceClicked = function(event) {
if (event.metaKey !== true) {
navigationService.hideDialog();
}
};
vm.labels = {};
localizationService
.localize("editdatatype_acceptDeleteConsequence", [$scope.currentNode.name])
@@ -1,4 +1,4 @@
<div class="umb-dialog umb-pane" ng-controller="Umbraco.Editors.DataType.DeleteController as vm">
<div class="umb-dialog umb-pane umb-dialog-datatype-delete" ng-controller="Umbraco.Editors.DataType.DeleteController as vm">
<div class="umb-dialog-body">
<ng-switch on="currentNode.nodeType">
@@ -44,14 +44,14 @@
<table class="table table-condensed table-bordered">
<thead>
<tr>
<th><localize key="general_name">Name</localize></th>
<th class="umb-dialog-datatype-delete__table-head-column-name"><localize key="general_name">Name</localize></th>
<th><localize key="general_properties">Properties</localize></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="relation in vm.references.documentTypes">
<td><span title="{{::relation.name}}({{::relation.alias}})"><i class="umb-table-body__icon {{relation.icon}}"></i>{{::relation.name}}</span></td>
<td><span><span class="red" ng-repeat="property in relation.properties"><i class="icon icon-alert red"></i>{{::property.name}}{{$last ? '' : ', '}}</span></span></td>
<td><a title="{{::relation.name}}({{::relation.alias}})" href="#/settings/documentTypes/edit/{{::relation.id}}" ng-click="vm.onReferenceClicked($event)"><i class="umb-table-body__icon {{relation.icon}}"></i>{{::relation.name}}</a></td>
<td><div><p class="red" ng-repeat="property in relation.properties"><i class="icon icon-alert red"></i>{{::property.name}}</p></div></td>
</tr>
</tbody>
</table>
@@ -68,14 +68,14 @@
<table class="table table-condensed table-bordered">
<thead>
<tr>
<th><localize key="general_name">Name</localize></th>
<th class="umb-dialog-datatype-delete__table-head-column-name"><localize key="general_name">Name</localize></th>
<th><localize key="general_properties">Properties</localize></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="relation in vm.references.mediaTypes">
<td><span title="{{::relation.name}}({{::relation.alias}})"><i class="umb-table-body__icon {{relation.icon}}"></i>{{::relation.name}}</span></td>
<td><span><span class="red" ng-repeat="property in relation.properties"><i class="icon icon-alert red"></i>{{::property.name}}{{$last ? '' : ', '}}</span></span></td>
<td><a title="{{::relation.name}}({{::relation.alias}})" href="#/settings/documentTypes/edit/{{::relation.id}}" ng-click="vm.onReferenceClicked($event)"><i class="umb-table-body__icon {{relation.icon}}"></i>{{::relation.name}}</a></td>
<td><div><p class="red" ng-repeat="property in relation.properties"><i class="icon icon-alert red"></i>{{::property.name}}</p></div></td>
</tr>
</tbody>
</table>
@@ -92,14 +92,14 @@
<table class="table table-condensed table-bordered">
<thead>
<tr>
<th><localize key="general_name">Name</localize></th>
<th class="umb-dialog-datatype-delete__table-head-column-name"><localize key="general_name">Name</localize></th>
<th><localize key="general_properties">Properties</localize></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="relation in vm.references.memberTypes">
<td><span title="{{::relation.name}}({{::relation.alias}})"><i class="umb-table-body__icon {{relation.icon}}"></i>{{::relation.name}}</span></td>
<td><span><span class="red" ng-repeat="property in relation.properties"><i class="icon icon-alert red"></i>{{::property.name}}{{$last ? '' : ', '}}</span></span></td>
<td><a title="{{::relation.name}}({{::relation.alias}})" href="#/settings/documentTypes/edit/{{::relation.id}}" ng-click="vm.onReferenceClicked($event)"><i class="umb-table-body__icon {{relation.icon}}"></i>{{::relation.name}}</a></td>
<td><div><p class="red" ng-repeat="property in relation.properties"><i class="icon icon-alert red"></i>{{::property.name}}</p></div></td>
</tr>
</tbody>
</table>
@@ -68,7 +68,7 @@
<div class="umb-table-cell umb-table__name"><span>{{::reference.name}}</span></div>
<div class="umb-table-cell"><span title="{{::reference.alias}}">{{::reference.alias}}</span></div>
<div class="umb-table-cell --noOverflow"><span>{{::reference.properties | umbCmsJoinArray:', ':'name'}}</span></div>
<div class="umb-table-cell umb-table-cell--nano"><a href="#/settings/documentTypes/edit/{{::reference.id}}"><localize key="general_open">Open</localize></a></div>
<div class="umb-table-cell umb-table-cell--nano"><a href="#/settings/mediaTypes/edit/{{::reference.id}}"><localize key="general_open">Open</localize></a></div>
</div>
</div>
</div>
@@ -98,7 +98,7 @@
<div class="umb-table-cell umb-table__name"><span>{{::reference.name}}</span></div>
<div class="umb-table-cell"><span title="{{::reference.alias}}">{{::reference.alias}}</span></div>
<div class="umb-table-cell --noOverflow"><span>{{::reference.properties | umbCmsJoinArray:', ':'name'}}</span></div>
<div class="umb-table-cell umb-table-cell--nano"><a href="#/settings/documentTypes/edit/{{::reference.id}}"><localize key="general_open">Open</localize></a></div>
<div class="umb-table-cell umb-table-cell--nano"><a href="#/settings/memberTypes/edit/{{::reference.id}}"><localize key="general_open">Open</localize></a></div>
</div>
</div>
</div>
@@ -5,7 +5,7 @@
<localize key="defaultdialogs_confirmdelete">Are you sure you want to delete</localize> <strong>{{currentNode.name}}</strong>?
</p>
<umb-confirm on-confirm="vm.performDelete" on-cancel="vm.cancel">
<umb-confirm on-confirm="vm.performDelete" on-cancel="vm.cancel" confirm-button-style="danger" >
</umb-confirm>
</div>

Some files were not shown because too many files have changed in this diff Show More