Merge branch 'v8/dev' into v8/feature/mb-embed
This commit is contained in:
@@ -11,5 +11,6 @@
|
||||
public const string TemplateFrontEndCacheKey = "template";
|
||||
|
||||
public const string MacroContentCacheKey = "macroContent_"; // used in MacroRenderers
|
||||
public const string MacroFromAliasCacheKey = "macroFromAlias_";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -1565,4 +1571,4 @@
|
||||
<Folder Include="Auditing\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -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>
|
||||
|
||||
9
src/Umbraco.Examine/IUmbracoContentIndex.cs
Normal file
9
src/Umbraco.Examine/IUmbracoContentIndex.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Examine;
|
||||
|
||||
namespace Umbraco.Examine
|
||||
{
|
||||
public interface IUmbracoContentIndex : IIndex
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
9
src/Umbraco.Examine/IUmbracoMemberIndex.cs
Normal file
9
src/Umbraco.Examine/IUmbracoMemberIndex.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Examine;
|
||||
|
||||
namespace Umbraco.Examine
|
||||
{
|
||||
public interface IUmbracoMemberIndex : IIndex
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,22 +195,55 @@ 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;
|
||||
});
|
||||
}
|
||||
|
||||
scope.goBack = function () {
|
||||
if (scope.onBack) {
|
||||
@@ -247,6 +280,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 +346,6 @@ Use this directive to construct a header inside the main editor window.
|
||||
icon: "=",
|
||||
hideIcon: "@",
|
||||
alias: "=",
|
||||
aliasLocked: "<",
|
||||
hideAlias: "=",
|
||||
description: "=",
|
||||
hideDescription: "@",
|
||||
@@ -271,7 +354,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();
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
}
|
||||
}
|
||||
@@ -12,4 +12,9 @@
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-panel-group__details-status-action{
|
||||
background-color:transparent;
|
||||
padding-left:0;
|
||||
}
|
||||
}
|
||||
|
||||
13
src/Umbraco.Web.UI.Client/src/less/dashboards/nucache.less
Normal file
13
src/Umbraco.Web.UI.Client/src/less/dashboards/nucache.less
Normal file
@@ -0,0 +1,13 @@
|
||||
#nuCache {
|
||||
.no-background {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.top-border {
|
||||
border-top: 2px solid #f3f3f5;
|
||||
}
|
||||
|
||||
.no-left-padding {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
20
src/Umbraco.Web.UI.Client/src/less/filter-toggle.less
Normal file
20
src/Umbraco.Web.UI.Client/src/less/filter-toggle.less
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()"
|
||||
|
||||
@@ -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® AIR™ 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>
|
||||
@@ -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">←</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">←</span> <localize key="general_backToOverview">Back to overview</localize></button>
|
||||
</umb-editor-sub-header-content-left>
|
||||
</umb-editor-sub-header>
|
||||
|
||||
@@ -373,7 +365,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">
|
||||
|
||||
@@ -3,52 +3,86 @@
|
||||
<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>
|
||||
</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">Published Cache Status</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">Refresh status</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">Caches</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">Memory Cache</div>
|
||||
<div class="umb-panel-group__details-check-description">
|
||||
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—which would indicate a minor Umbraco issue.
|
||||
(note: triggers the reload on all servers in an LB environment).
|
||||
</div>
|
||||
|
||||
<h4 class="mt4">Memory Cache</h4>
|
||||
<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">Reload</button>
|
||||
</div>
|
||||
</div>
|
||||
</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—which would indicate a minor Umbraco issue.
|
||||
(note: triggers the reload on all servers in an LB environment).
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<button type="button" ng-click="vm.reload($event)" class="btn btn-danger">Reload</button>
|
||||
</div>
|
||||
<div class="umb-panel-group__details-check-title top-border">
|
||||
<div class="umb-panel-group__details-check-name">Database Cache</div>
|
||||
<div class="umb-panel-group__details-check-description">
|
||||
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—which would indicate some critical Umbraco issue.
|
||||
</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">Rebuild</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 class="mt4">Database Cache</h4>
|
||||
|
||||
<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—which would indicate some critical Umbraco issue.
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<button type="button" ng-click="vm.rebuild($event)" class="btn btn-danger">Rebuild</button>
|
||||
</div>
|
||||
|
||||
<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 class="umb-panel-group__details-check-title top-border">
|
||||
<div class="umb-panel-group__details-check-name">Internals</div>
|
||||
<div class="umb-panel-group__details-check-description">
|
||||
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.
|
||||
</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">Collect</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -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,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><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><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><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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -12,6 +12,10 @@ function DictionaryEditController($scope, $routeParams, $location, dictionaryRes
|
||||
|
||||
//setup scope vars
|
||||
vm.nameDirty = false;
|
||||
vm.header = {};
|
||||
vm.header.editorfor = "template_insertDictionaryItem";
|
||||
vm.header.setPageTitle = true;
|
||||
|
||||
vm.page = {};
|
||||
vm.page.loading = false;
|
||||
vm.page.nameLocked = false;
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
hide-description="true"
|
||||
hide-alias="true"
|
||||
on-back="vm.back()"
|
||||
show-back-button="vm.showBackButton">
|
||||
show-back-button="vm.showBackButton"
|
||||
editorfor="vm.header.editorfor"
|
||||
setpagetitle="vm.header.setPageTitle">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container class="form-horizontal">
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<i class="large icon icon-thumbnail-list"></i>
|
||||
<span class="menu-label">
|
||||
Document Type Collection...
|
||||
<!-- <localize key="content_documentType_collection">Document Type Collection</localize>-->
|
||||
<!--<localize key="content_documentType_collection">Document Type Collection</localize>-->
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
@@ -82,22 +82,26 @@
|
||||
<umb-control-group>
|
||||
<label for="collectionName" class="control-label">Name of the Parent Document Type</label>
|
||||
<input type="text" name="collectionName" id="collectionName" ng-model="model.collectionName" class="umb-textstring textstring input-block-level" umb-auto-focus required />
|
||||
<span ng-if="model.disableTemplates === false">
|
||||
<input id="collectionCreateTemplate" name="collectionCreateTemplate" type="checkbox" ng-model="model.collectionCreateTemplate" style="margin-top: 0;" />
|
||||
<label for="collectionCreateTemplate" style="margin-bottom: 0; padding-left: 2px;">Create template for the Parent Document Type</label>
|
||||
</span>
|
||||
|
||||
<umb-checkbox ng-if="model.disableTemplates === false"
|
||||
name="collectionCreateTemplate"
|
||||
model="model.collectionCreateTemplate"
|
||||
text="Create template for the Parent Document Type" />
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group>
|
||||
<label for="collectionItemName" class="control-label">Name of the Item Document Type</label>
|
||||
<input type="text" name="collectionItemName" id="collectionItemName" ng-model="model.collectionItemName" class="umb-textstring textstring input-block-level" required />
|
||||
<span ng-if="model.disableTemplates === false">
|
||||
<input id="collectionItemCreateTemplate" name="collectionItemCreateTemplate" type="checkbox" ng-model="model.collectionItemCreateTemplate" style="margin-top: 0;" />
|
||||
<label for="collectionItemCreateTemplate" style="margin-bottom: 0; padding-left: 2px;">Create template for the Item Document Type</label>
|
||||
</span>
|
||||
|
||||
<umb-checkbox ng-if="model.disableTemplates === false"
|
||||
name="collectionItemCreateTemplate"
|
||||
model="model.collectionItemCreateTemplate"
|
||||
text="Create template for the Item Document Type" />
|
||||
</umb-control-group>
|
||||
|
||||
<button type="submit" class="btn btn-primary"><localize key="general_create">Create</localize></button>
|
||||
<div class="mt3">
|
||||
<button type="submit" class="btn btn-primary"><localize key="general_create">Create</localize></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
vm.currentNode = null;
|
||||
vm.contentType = {};
|
||||
vm.header = {};
|
||||
vm.header.editorfor = "content_documentType";
|
||||
vm.header.setPageTitle = true;
|
||||
vm.labels = {};
|
||||
vm.submitButtonKey = "buttons_save";
|
||||
vm.generateModelsKey = "buttons_saveAndGenerateModels";
|
||||
@@ -33,7 +36,7 @@
|
||||
vm.page.loading = false;
|
||||
vm.page.saveButtonState = "init";
|
||||
vm.page.navigation = [];
|
||||
|
||||
|
||||
var labelKeys = [
|
||||
"general_design",
|
||||
"general_listView",
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
key="vm.contentType.key"
|
||||
description="vm.contentType.description"
|
||||
navigation="vm.page.navigation"
|
||||
icon="vm.contentType.icon">
|
||||
icon="vm.contentType.icon"
|
||||
editorfor="vm.header.editorfor"
|
||||
setpagetitle="vm.header.setPageTitle">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container class="editors-document-type-container">
|
||||
|
||||
@@ -286,10 +286,11 @@
|
||||
function deleteSavedSearch(searchItem) {
|
||||
|
||||
var overlay = {
|
||||
title: "Delete Search",
|
||||
subtitle: "Are you sure you wish to delete",
|
||||
title: "Delete Saved Search",
|
||||
subtitle: "Are you sure you wish to delete?",
|
||||
closeButtonLabel: "Cancel",
|
||||
submitButtonLabel: "Delete Search",
|
||||
submitButtonLabel: "Delete Saved Search",
|
||||
submitButtonStyle: "danger",
|
||||
view: "default",
|
||||
submit: function (model) {
|
||||
//Resource call with two params (name & query)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div data-element="editor-logs" ng-controller="Umbraco.Editors.LogViewer.SearchController as vm" class="clearfix">
|
||||
<div data-element="editor-logs" ng-controller="Umbraco.Editors.LogViewer.SearchController as vm" class="clearfix umb-logviewer-search">
|
||||
|
||||
<umb-editor-view footer="false">
|
||||
|
||||
@@ -22,14 +22,22 @@
|
||||
<umb-editor-sub-header-content-left class="flex-auto flex-wrap">
|
||||
|
||||
<!-- Log Level filter -->
|
||||
<div class="flex" style="position: relative;">
|
||||
<a class="btn btn-link dropdown-toggle flex mb2" href="" ng-click="vm.page.showLevelFilter = !vm.page.showLevelFilter">
|
||||
<span>Log Levels:</span>
|
||||
<span class="bold truncate dib" style="margin-left: 5px; margin-right: 3px; max-width: 150px;">{{ vm.getFilterName(vm.logLevels) }}</span>
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<div class="flex log-viewer-filter" style="position: relative;">
|
||||
<button
|
||||
type="button"
|
||||
class="btn-link dropdown-toggle flex mb2 filter-toggle"
|
||||
ng-click="vm.page.showLevelFilter = !vm.page.showLevelFilter"
|
||||
aria-haspopup="true"
|
||||
aria-expanded="{{vm.page.showLevelFilter === undefined ? false : vm.page.showLevelFilter}}"
|
||||
>
|
||||
<span>
|
||||
<localize key="logViewer_logLevels">Log Levels</localize>:
|
||||
</span>
|
||||
<span class="filter-toggle__level truncate">{{ vm.getFilterName(vm.logLevels) }}</span>
|
||||
<span class="filter-toggle__icon caret" aria-hidden="true"></span>
|
||||
</button>
|
||||
<umb-dropdown class="pull-left" ng-if="vm.page.showLevelFilter" on-close="vm.page.showLevelFilter = false;">
|
||||
<umb-dropdown-item ng-repeat="level in vm.logLevels" style="padding: 8px 20px 8px 16px;">
|
||||
<umb-dropdown-item ng-repeat="level in vm.logLevels" class="dropdown-item">
|
||||
<div class="flex items-center">
|
||||
<umb-checkbox input-id="loglevel-{{$index}}" name="loglevel" model="level.selected" on-change="vm.setLogLevelFilter(level)" />
|
||||
<label for="loglevel-{{$index}}">
|
||||
@@ -40,29 +48,31 @@
|
||||
</umb-dropdown>
|
||||
</div>
|
||||
|
||||
<div class="flex" style="width:100%;">
|
||||
<div class="flex-auto" style="position:relative;">
|
||||
<div class="flex search-box">
|
||||
<div class="flex-auto">
|
||||
<!-- Search/expression filter -->
|
||||
<input class="form-control search-input" type="text" ng-model="vm.logOptions.filterExpression" style="width:100%; padding-right: 160px;" placeholder="Search logs…" />
|
||||
<input class="form-control search-input" type="text" ng-model="vm.logOptions.filterExpression" placeholder="Search logs..." />
|
||||
|
||||
<!-- Save Search & Clear Search icon buttons -->
|
||||
<ins class="icon-rate" ng-show="vm.checkForSavedSearch()" ng-click="vm.addToSavedSearches()" style="position: absolute; top: 0; line-height: 32px; right: 140px; color: #fdb45c; cursor: pointer;"> </ins>
|
||||
<ins class="icon-wrong" ng-show="vm.logOptions.filterExpression" ng-click="vm.resetSearch()" style="position: absolute; top: 0; line-height: 32px; right: 120px; color: #bbbabf; cursor: pointer;"> </ins>
|
||||
<ins class="icon-rate" ng-show="vm.checkForSavedSearch()" ng-click="vm.addToSavedSearches()"> </ins>
|
||||
<ins class="icon-wrong" ng-show="vm.logOptions.filterExpression" ng-click="vm.resetSearch()"> </ins>
|
||||
|
||||
<!-- Saved Searches -->
|
||||
<a class="umb-variant-switcher__toggle ng-scope" href="" ng-click="vm.dropdownOpen = !vm.dropdownOpen" style="top: 1px; right: 0; position: absolute;">
|
||||
<span class="ng-binding">Saved Searches</span>
|
||||
<ins class="umb-variant-switcher__expand icon-navigation-down" ng-class="{'icon-navigation-down': !vm.dropdownOpen, 'icon-navigation-up': vm.dropdownOpen}" style="margin-top: 0;"></ins>
|
||||
<a class="umb-variant-switcher__toggle ng-scope" href="" ng-click="vm.dropdownOpen = !vm.dropdownOpen">
|
||||
<span class="ng-binding">
|
||||
<localize key="logViewer_savedSearches">Saved Searches</localize>
|
||||
</span>
|
||||
<ins class="umb-variant-switcher__expand icon-navigation-down" ng-class="{'icon-navigation-down': !vm.dropdownOpen, 'icon-navigation-up': vm.dropdownOpen}"></ins>
|
||||
</a>
|
||||
|
||||
<!-- Saved Searches Dropdown -->
|
||||
<umb-dropdown ng-if="vm.dropdownOpen" style="width: 100%; max-height: 250px; overflow-y: scroll; margin-top: -10px;" on-close="vm.dropdownOpen = false" umb-keyboard-list>
|
||||
<umb-dropdown ng-if="vm.dropdownOpen" class="saved-searches" on-close="vm.dropdownOpen = false" umb-keyboard-list>
|
||||
<umb-dropdown-item class="umb-variant-switcher__item" ng-class="{'umb-variant-switcher_item--current': variant.active}" ng-repeat="search in vm.searches">
|
||||
<a href="" class="umb-variant-switcher__name-wrapper" ng-click="vm.selectSearch(search)" prevent-default>
|
||||
<span class="umb-variant-switcher__name">{{search.name}}</span>
|
||||
<span>{{ search.query }}</span>
|
||||
</a>
|
||||
<a href=""><span><i class="icon icon-trash text-error" title="Delete this search" ng-click="vm.deleteSavedSearch(search)"></i></span></a>
|
||||
<a href=""><span><i class="icon icon-trash text-error" localize="title" title="@logViewer_deleteThisSearch" ng-click="vm.deleteSavedSearch(search)"></i></span></a>
|
||||
</umb-dropdown-item>
|
||||
</umb-dropdown>
|
||||
</div>
|
||||
@@ -79,16 +89,14 @@
|
||||
</umb-editor-sub-header>
|
||||
</form>
|
||||
|
||||
<div ng-if="!vm.loading">
|
||||
|
||||
<div>
|
||||
<div ng-if="!vm.loading" class="log-items">
|
||||
|
||||
<!-- Loader for the main logs content when paging -->
|
||||
<umb-load-indicator ng-if="vm.logsLoading"></umb-load-indicator>
|
||||
|
||||
<!-- Empty states -->
|
||||
<umb-empty-state ng-if="vm.logItems.totalItems === 0" position="center">
|
||||
<localize key="general_searchNoResult"></localize>
|
||||
<localize key="general_searchNoResult">Sorry, we can not find what you are looking for.</localize>
|
||||
</umb-empty-state>
|
||||
|
||||
<!-- Main Log Table -->
|
||||
@@ -96,19 +104,19 @@
|
||||
<umb-box-content class="block-form">
|
||||
|
||||
<div ng-if="vm.logItems.totalItems > 0">
|
||||
Total Items: {{ vm.logItems.totalItems }}
|
||||
<localize key="logViewer_totalItems">Total Items</localize>: {{ vm.logItems.totalItems }}
|
||||
</div>
|
||||
|
||||
<table class="table table-hover" style="table-layout: fixed;" ng-if="vm.logItems.totalItems > 0">
|
||||
<table class="table table-hover" ng-if="vm.logItems.totalItems > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20%;" ng-click="vm.toggleOrderBy()">
|
||||
Timestamp
|
||||
<th ng-click="vm.toggleOrderBy()">
|
||||
<localize key="logViewer_timestamp">Timestamp</localize>
|
||||
<ins class="icon-navigation-down" ng-class="{'icon-navigation-down': vm.logOptions.orderDirection === 'Descending', 'icon-navigation-up': vm.logOptions.orderDirection !== 'Descending'}"> </ins>
|
||||
</th>
|
||||
<th style="width: 15%;">Level</th>
|
||||
<th style="width: 20%;">Machine</th>
|
||||
<th>Message</th>
|
||||
<th><localize key="logViewer_level">Level</localize></th>
|
||||
<th><localize key="logViewer_machine">Machine</localize></th>
|
||||
<th><localize key="logViewer_message">Message</localize></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -116,22 +124,22 @@
|
||||
<td>{{ log.Timestamp | date:'medium' }}</td>
|
||||
<td><umb-badge size="s" color="{{ log.logTypeColor }}">{{ log.Level }}</umb-badge></td>
|
||||
<td><small>{{ log.Properties.MachineName.Value }}</small></td>
|
||||
<td style="word-break: break-word;">{{ log.RenderedMessage }}</td>
|
||||
<td>{{ log.RenderedMessage }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Log Details (Exception & Properties) -->
|
||||
<tr ng-repeat-end ng-if="log.open">
|
||||
<td colspan="4">
|
||||
<div ng-if="log.Exception" style="border-left:4px solid #D42054; padding:0 10px 10px 10px; box-shadow:rgba(0,0,0,0.07) 2px 2px 10px">
|
||||
<h3 class="text-error">Exception</h3>
|
||||
<p style="white-space: pre-wrap;">{{ log.Exception }}</p>
|
||||
<div ng-if="log.Exception"class="exception">
|
||||
<h3 class="text-error"><localize key="logViewer_exception">Exception</localize></h3>
|
||||
<p class="exception-message">{{ log.Exception }}</p>
|
||||
</div>
|
||||
|
||||
<h3>Properties</h3>
|
||||
<h3><localize key="logViewer_properties">Properties</localize></h3>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Timestamp</th>
|
||||
<th><localize key="logViewer_timestamp">Timestamp</localize></th>
|
||||
<td>{{log.Timestamp}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -141,10 +149,10 @@
|
||||
<tr ng-repeat="(key, val) in log.Properties">
|
||||
<th>{{key}}</th>
|
||||
<td ng-switch on="key">
|
||||
<a ng-switch-when="HttpRequestNumber" ng-click="vm.findItem(key, val.Value)" title="Find Logs with Request ID">{{val.Value}} <i class="icon-search"></i></a>
|
||||
<a ng-switch-when="SourceContext" ng-click="vm.findItem(key, val.Value)" title="Find Logs with Namespace">{{val.Value}} <i class="icon-search"></i></a>
|
||||
<a ng-switch-when="MachineName" ng-click="vm.findItem(key, val.Value)" title="Find Logs with Machine Name">{{val.Value}} <i class="icon-search"></i></a>
|
||||
<a ng-switch-when="RequestUrl" href="{{val.Value}}" target="_blank" rel="noopener" title="Open">{{val.Value}} <i class="icon-link"></i></a>
|
||||
<a ng-switch-when="HttpRequestNumber" ng-click="vm.findItem(key, val.Value)" localize="title" title="@logViewer_findLogsWithRequestId">{{val.Value}} <i class="icon-search"></i></a>
|
||||
<a ng-switch-when="SourceContext" ng-click="vm.findItem(key, val.Value)" localize="title" title="@logViewer_findLogsWithNamespace">{{val.Value}} <i class="icon-search"></i></a>
|
||||
<a ng-switch-when="MachineName" ng-click="vm.findItem(key, val.Value)" localize="title" title="@logViewer_findLogsWithMachineName">{{val.Value}} <i class="icon-search"></i></a>
|
||||
<a ng-switch-when="RequestUrl" href="{{val.Value}}" target="_blank" rel="noopener" localize="title" title="@logViewer_Open">{{val.Value}} <i class="icon-link"></i></a>
|
||||
<span ng-switch-default>{{val.Value}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -159,41 +167,42 @@
|
||||
|
||||
<umb-dropdown ng-if="log.searchDropdownOpen" on-close="log.searchDropdownOpen = false">
|
||||
<umb-dropdown-item>
|
||||
<a ng-href="https://www.google.com/search?q={{ log.RenderedMessage }}" target="_blank" title="Search this message with Google">
|
||||
<img src="https://www.google.com/favicon.ico" width="16" height="16" /> Search With Google
|
||||
<a ng-href="https://www.google.com/search?q={{ log.RenderedMessage }}" target="_blank" localize="title" title="@logViewer_searchThisMessageWithGoogle">
|
||||
<img src="https://www.google.com/favicon.ico" width="16" height="16" alt="" /> <localize key="logViewer_searchWithGoogle">Search With Google</localize>
|
||||
</a>
|
||||
</umb-dropdown-item>
|
||||
|
||||
<umb-dropdown-item>
|
||||
<a ng-href="https://www.bing.com/search?q={{ log.RenderedMessage }}" target="_blank" title="Search this message with Bing">
|
||||
<img src="https://www.bing.com/favicon.ico" width="16" height="16" /> Search With Bing
|
||||
<a ng-href="https://www.bing.com/search?q={{ log.RenderedMessage }}" target="_blank" localize="title" title="@logViewer_searchThisMessageWithBing">
|
||||
<img src="https://www.bing.com/favicon.ico" width="16" height="16" alt="" /> <localize key="logViewer_searchWithBing">Search With Bing</localize>
|
||||
</a>
|
||||
</umb-dropdown-item>
|
||||
|
||||
<umb-dropdown-item>
|
||||
<a ng-href="https://our.umbraco.com/search?q={{ log.RenderedMessage }}&content=wiki,forum,documentation" target="_blank" title="Search this message on Our Umbraco forums and docs">
|
||||
<img src="https://our.umbraco.com/assets/images/app-icons/favicon.png" width="16" height="16" /> Search Our Umbraco
|
||||
<a ng-href="https://our.umbraco.com/search?q={{ log.RenderedMessage }}&content=wiki,forum,documentation" target="_blank" localize="title" title="@logViewer_searchThisMessageOnOurUmbracoForumsAndDocs">
|
||||
<img src="https://our.umbraco.com/assets/images/app-icons/favicon.png" width="16" height="16" alt="" /> <localize key="logViewer_searchOurUmbraco">Search Our Umbraco</localize>
|
||||
</a>
|
||||
</umb-dropdown-item>
|
||||
|
||||
<umb-dropdown-item>
|
||||
<a ng-href="https://www.google.co.uk/?q=site:our.umbraco.com {{ log.RenderedMessage }}&safe=off#q=site:our.umbraco.com {{ log.RenderedMessage }} {{ log.Properties['SourceContext'].Value }}&safe=off" target="_blank" title="Search Our Umbraco forums using Google">
|
||||
<img src="https://www.google.com/favicon.ico" width="16" height="16" /> Search Our Umbraco with Google
|
||||
<a ng-href="https://www.google.co.uk/?q=site:our.umbraco.com {{ log.RenderedMessage }}&safe=off#q=site:our.umbraco.com {{ log.RenderedMessage }} {{ log.Properties['SourceContext'].Value }}&safe=off" target="_blank" localize="title" title="@logViewer_searchOurUmbracoForumsUsingGoogle">
|
||||
<img src="https://www.google.com/favicon.ico" width="16" height="16" alt="" /> <localize key="logViewer_searchOurUmbracoWithGoogle">Search Our Umbraco with Google</localize>
|
||||
</a>
|
||||
</umb-dropdown-item>
|
||||
|
||||
<umb-dropdown-item>
|
||||
<a ng-href="https://github.com/umbraco/Umbraco-CMS/search?q={{ log.Properties['SourceContext'].Value }}" target="_blank" title="Search within Umbraco source code on Github">
|
||||
<img src="https://www.github.com/favicon.ico" width="16" height="16" /> Search Umbraco Source
|
||||
<a ng-href="https://github.com/umbraco/Umbraco-CMS/search?q={{ log.Properties['SourceContext'].Value }}" target="_blank" localize="title" title="@logViewer_searchWithinUmbracoSourceCodeOnGithub">
|
||||
<img src="https://www.github.com/favicon.ico" width="16" height="16" alt="" /> <localize key="logViewer_searchUmbracoSource">Search Umbraco Source</localize>
|
||||
</a>
|
||||
</umb-dropdown-item>
|
||||
|
||||
<umb-dropdown-item>
|
||||
<a ng-href="https://github.com/umbraco/Umbraco-CMS/issues?q={{ log.Properties['SourceContext'].Value }}" target="_blank" title="Search Umbraco Issues on Github">
|
||||
<img src="https://www.github.com/favicon.ico" width="16" height="16" /> Search Umbraco Issues
|
||||
<a ng-href="https://github.com/umbraco/Umbraco-CMS/issues?q={{ log.Properties['SourceContext'].Value }}" target="_blank" localize="title" title="@logViewer_searchUmbracoIssuesOnGithub">
|
||||
<img src="https://www.github.com/favicon.ico" width="16" height="16" alt="" /> <localize key="logViewer_searchUmbracoIssues">Search Umbraco Issues</localize>
|
||||
</a>
|
||||
</umb-dropdown-item>
|
||||
</umb-dropdown>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
@@ -213,7 +222,7 @@
|
||||
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</umb-editor-container>
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
navigation="content.apps"
|
||||
on-select-navigation-item="appChanged(item)"
|
||||
show-back-button="showBack()"
|
||||
on-back="onBack()">
|
||||
on-back="onBack()"
|
||||
setpagetitle="header.setPageTitle">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
|
||||
@@ -35,7 +35,8 @@ function mediaEditController($scope, $routeParams, $q, appState, mediaResource,
|
||||
//setup scope vars
|
||||
$scope.currentSection = appState.getSectionState("currentSection");
|
||||
$scope.currentNode = null; //the editors affiliated node
|
||||
|
||||
$scope.header = {};
|
||||
$scope.header.setPageTitle = $scope.currentSection ==="media";
|
||||
$scope.page = {};
|
||||
$scope.page.loading = false;
|
||||
$scope.page.menu = {};
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
vm.close = close;
|
||||
|
||||
vm.currentNode = null;
|
||||
vm.header = {};
|
||||
vm.header.editorfor = "content_mediatype";
|
||||
vm.header.setPageTitle = true;
|
||||
vm.contentType = {};
|
||||
vm.page = {};
|
||||
vm.page.loading = false;
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
key="vm.contentType.key"
|
||||
description="vm.contentType.description"
|
||||
navigation="vm.page.navigation"
|
||||
icon="vm.contentType.icon">
|
||||
icon="vm.contentType.icon"
|
||||
editorfor="vm.header.editorfor"
|
||||
setpagetitle="vm.header.setPageTitle">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container class="editors-document-type-container">
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
hide-description="true"
|
||||
hide-alias="true"
|
||||
show-back-button="showBack()"
|
||||
on-back="onBack()">
|
||||
on-back="onBack()"
|
||||
editorfor="header.editorfor"
|
||||
setpagetitle="header.setPageTitle">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container class="form-horizontal">
|
||||
|
||||
@@ -14,6 +14,10 @@ function MemberEditController($scope, $routeParams, $location, appState, memberR
|
||||
var listName = infiniteMode ? $scope.model.listname : $routeParams.listName;
|
||||
var docType = infiniteMode ? $scope.model.doctype : $routeParams.doctype;
|
||||
|
||||
$scope.header = {};
|
||||
$scope.header.editorfor = "visuallyHiddenTexts_newMember";
|
||||
$scope.header.setPageTitle = true;
|
||||
|
||||
//setup scope vars
|
||||
$scope.page = {};
|
||||
$scope.page.loading = true;
|
||||
|
||||
@@ -11,6 +11,9 @@ function MemberGroupsEditController($scope, $routeParams, appState, navigationSe
|
||||
//setup scope vars
|
||||
$scope.page = {};
|
||||
$scope.page.loading = false;
|
||||
$scope.header = {};
|
||||
$scope.header.editorfor = "content_membergroup";
|
||||
$scope.header.setPageTitle = true;
|
||||
$scope.page.menu = {};
|
||||
$scope.page.menu.currentSection = appState.getSectionState("currentSection");
|
||||
$scope.page.menu.currentNode = null;
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
name-locked="page.nameLocked"
|
||||
hide-icon="true"
|
||||
hide-description="true"
|
||||
hide-alias="true">
|
||||
hide-alias="true"
|
||||
editorfor="header.editorfor"
|
||||
setpagetitle="header.setPageTitle">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container class="form-horizontal">
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
var vm = this;
|
||||
|
||||
vm.save = save;
|
||||
|
||||
vm.editorfor = "visuallyHiddenTexts_newMember";
|
||||
vm.header = {};
|
||||
vm.header.editorfor = "content_membergroup";
|
||||
vm.header.setPageTitle = true;
|
||||
vm.currentNode = null;
|
||||
vm.contentType = {};
|
||||
vm.page = {};
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
alias="vm.contentType.alias"
|
||||
description="vm.contentType.description"
|
||||
navigation="vm.page.navigation"
|
||||
icon="vm.contentType.icon">
|
||||
icon="vm.contentType.icon"
|
||||
editorfor="vm.header.editorfor"
|
||||
setpagetitle="vm.header.setPageTitle">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container class="editors-document-type-container">
|
||||
|
||||
@@ -37,10 +37,10 @@
|
||||
|
||||
vm.labels = {};
|
||||
|
||||
vm.versionRegex = /^(\d+\.)(\d+\.)(\*|\d+)$/;
|
||||
vm.versionRegex = /^(\d+\.)(\d+\.)(\*|\d+)$/;
|
||||
|
||||
function onInit() {
|
||||
|
||||
|
||||
if (create) {
|
||||
// Pre populate package with some values
|
||||
packageResource.getEmpty().then(scaffold => {
|
||||
@@ -53,8 +53,9 @@
|
||||
vm.loading = false;
|
||||
});
|
||||
|
||||
localizationService.localize("general_create").then(function (value) {
|
||||
vm.labels.button = value;
|
||||
localizationService.localizeMany(["general_create", "packager_includeAllChildNodes"]).then(function (values) {
|
||||
vm.labels.button = values[0];
|
||||
vm.labels.includeAllChildNodes = values[1];
|
||||
});
|
||||
} else {
|
||||
// Load package
|
||||
@@ -77,11 +78,11 @@
|
||||
|
||||
});
|
||||
|
||||
|
||||
localizationService.localizeMany(["buttons_save", "packager_includeAllChildNodes"]).then(function (values) {
|
||||
vm.labels.button = values[0];
|
||||
vm.labels.includeAllChildNodes = values[1];
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,8 +202,8 @@
|
||||
//don't add a browser history for this
|
||||
$location.replace();
|
||||
}
|
||||
|
||||
}, function(err){
|
||||
|
||||
}, function (err) {
|
||||
formHelper.handleError(err);
|
||||
vm.buttonState = "error";
|
||||
});
|
||||
@@ -215,14 +216,14 @@
|
||||
|
||||
function openContentPicker() {
|
||||
const contentPicker = {
|
||||
submit: function(model) {
|
||||
if(model.selection && model.selection.length > 0) {
|
||||
submit: function (model) {
|
||||
if (model.selection && model.selection.length > 0) {
|
||||
vm.package.contentNodeId = model.selection[0].id.toString();
|
||||
vm.contentNodeDisplayModel = model.selection[0];
|
||||
}
|
||||
editorService.close();
|
||||
},
|
||||
close: function() {
|
||||
close: function () {
|
||||
editorService.close();
|
||||
}
|
||||
};
|
||||
@@ -240,25 +241,25 @@
|
||||
entityType: "file",
|
||||
multiPicker: true,
|
||||
isDialog: true,
|
||||
select: function(node) {
|
||||
select: function (node) {
|
||||
node.selected = !node.selected;
|
||||
|
||||
const id = decodeURIComponent(node.id.replace(/\+/g, " "));
|
||||
const index = selection.indexOf(id);
|
||||
|
||||
if(node.selected) {
|
||||
if(index === -1) {
|
||||
if (node.selected) {
|
||||
if (index === -1) {
|
||||
selection.push(id);
|
||||
}
|
||||
} else {
|
||||
selection.splice(index, 1);
|
||||
}
|
||||
},
|
||||
submit: function() {
|
||||
submit: function () {
|
||||
vm.package.files = selection;
|
||||
editorService.close();
|
||||
},
|
||||
close: function() {
|
||||
close: function () {
|
||||
editorService.close();
|
||||
}
|
||||
};
|
||||
@@ -283,12 +284,12 @@
|
||||
}
|
||||
},
|
||||
filterCssClass: "not-allowed",
|
||||
select: function(node) {
|
||||
select: function (node) {
|
||||
const id = decodeURIComponent(node.id.replace(/\+/g, " "));
|
||||
vm.package.packageView = id;
|
||||
editorService.close();
|
||||
},
|
||||
close: function() {
|
||||
close: function () {
|
||||
editorService.close();
|
||||
}
|
||||
};
|
||||
@@ -384,7 +385,7 @@
|
||||
}
|
||||
|
||||
function buildContributorsEditor(pkg) {
|
||||
|
||||
|
||||
vm.contributorsEditor = {
|
||||
alias: "contributors",
|
||||
editor: "Umbraco.MultipleTextstring",
|
||||
|
||||
@@ -97,10 +97,15 @@
|
||||
</div>
|
||||
|
||||
<div class="umb-info-local-item mt4 flex items-center flex-column" ng-if="vm.installState.status == ''">
|
||||
<label for="confirm-uninstall" class="umb-package-installer-label">
|
||||
<input type="checkbox" id="confirm-uninstall" ng-model="vm.package.confirmUninstall" required no-dirty-check>
|
||||
<strong class="label-text"><localize key="packager_packageUninstallConfirm">Confirm package uninstall</localize></strong>
|
||||
</label>
|
||||
|
||||
<umb-checkbox
|
||||
css-class="-small-text -bold"
|
||||
model="vm.package.confirmUninstall"
|
||||
text="Confirm package uninstall"
|
||||
label-key="packager_packageUninstallConfirm"
|
||||
required="true">
|
||||
</umb-checkbox>
|
||||
|
||||
<umb-button
|
||||
class="mt3"
|
||||
type="button"
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.header = {};
|
||||
vm.header.editorfor = "visuallyHiddenTexts_newPartialViewMacro";
|
||||
vm.header.setPageTitle = true;
|
||||
vm.page = {};
|
||||
vm.page.loading = true;
|
||||
vm.partialViewMacroFile = {};
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
hide-alias="true"
|
||||
description="vm.partialViewMacro.virtualPath"
|
||||
description-locked="true"
|
||||
hide-icon="true">
|
||||
hide-icon="true"
|
||||
editorfor="vm.header.editorfor"
|
||||
setpagetitle="vm.header.setPageTitle">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
|
||||
vm.close = close;
|
||||
|
||||
vm.header = {};
|
||||
vm.header.editorfor = "visuallyHiddenTexts_newPartialView";
|
||||
vm.header.setPageTitle = true;
|
||||
|
||||
vm.page = {};
|
||||
vm.page.loading = true;
|
||||
vm.partialView = {};
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
hide-alias="true"
|
||||
description="vm.partialView.virtualPath"
|
||||
description-locked="true"
|
||||
hide-icon="true">
|
||||
hide-icon="true"
|
||||
editorfor="vm.header.editorfor"
|
||||
setpagetitle="vm.header.setPageTitle">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
|
||||
@@ -78,17 +78,17 @@
|
||||
|
||||
|
||||
<umb-control-group hide-label="true">
|
||||
<ul class="unstyled">
|
||||
<li>
|
||||
<label>
|
||||
<input type="checkbox"
|
||||
ng-model="currentSection.allowAll"
|
||||
style="float: left; margin-right: 10px;"
|
||||
ng-change="toggleAllowed(currentSection)" />
|
||||
<localize key="grid_allowAllRowConfigurations"/>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<umb-toggle
|
||||
class="umb-toggle-group-item__toggle"
|
||||
checked="currentSection.allowAll"
|
||||
on-click="currentSection.allowAll = !currentSection.allowAll"
|
||||
show-labels="true"
|
||||
label-position="right"
|
||||
label-off="Allow all row configurations"
|
||||
label-on="Allow all row configurations"
|
||||
style="margin-left: 18px">
|
||||
</umb-toggle>
|
||||
|
||||
<div ng-if="currentSection.allowAll === false">
|
||||
<hr />
|
||||
|
||||
@@ -73,7 +73,10 @@ angular.module("umbraco")
|
||||
ui.item.find(".umb-rte").each(function (key, value) {
|
||||
// remove all RTEs in the dragged row and save their settings
|
||||
var rteId = value.id;
|
||||
draggedRteSettings[rteId] = _.findWhere(tinyMCE.editors, { id: rteId }).settings;
|
||||
var editor = _.findWhere(tinyMCE.editors, { id: rteId });
|
||||
if (editor) {
|
||||
draggedRteSettings[rteId] = editor.settings;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -85,9 +88,17 @@ angular.module("umbraco")
|
||||
// reset all RTEs affected by the dragging
|
||||
ui.item.parents(".umb-column").find(".umb-rte").each(function (key, value) {
|
||||
var rteId = value.id;
|
||||
draggedRteSettings[rteId] = draggedRteSettings[rteId] || _.findWhere(tinyMCE.editors, { id: rteId }).settings;
|
||||
tinyMCE.execCommand("mceRemoveEditor", false, rteId);
|
||||
tinyMCE.init(draggedRteSettings[rteId]);
|
||||
var settings = draggedRteSettings[rteId];
|
||||
if (!settings) {
|
||||
var editor = _.findWhere(tinyMCE.editors, { id: rteId });
|
||||
if (editor) {
|
||||
settings = editor.settings;
|
||||
}
|
||||
}
|
||||
if (settings) {
|
||||
tinyMCE.execCommand("mceRemoveEditor", false, rteId);
|
||||
tinyMCE.init(settings);
|
||||
}
|
||||
});
|
||||
currentForm.$setDirty();
|
||||
}
|
||||
|
||||
@@ -170,8 +170,11 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
"clipboardService",
|
||||
"eventsService",
|
||||
"overlayService",
|
||||
"$routeParams",
|
||||
"editorState",
|
||||
"propertyEditorService",
|
||||
|
||||
function ($scope, $interpolate, $filter, $timeout, contentResource, localizationService, iconHelper, clipboardService, eventsService, overlayService, $routeParams, editorState) {
|
||||
function ($scope, $interpolate, $filter, $timeout, contentResource, localizationService, iconHelper, clipboardService, eventsService, overlayService, $routeParams, editorState, propertyEditorService) {
|
||||
|
||||
var contentTypeAliases = [];
|
||||
_.each($scope.model.config.contentTypes, function (contentType) {
|
||||
@@ -208,6 +211,39 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
$scope.labels.content_createEmpty = data[1];
|
||||
});
|
||||
|
||||
|
||||
|
||||
var copyAllEntries = function() {
|
||||
|
||||
syncCurrentNode();
|
||||
|
||||
// list aliases
|
||||
var aliases = $scope.nodes.map((node) => node.contentTypeAlias);
|
||||
|
||||
// remove dublicates
|
||||
aliases = aliases.filter((item, index) => aliases.indexOf(item) === index);
|
||||
|
||||
// Retrive variant name
|
||||
var culture = $routeParams.cculture ? $routeParams.cculture : $routeParams.mculture;
|
||||
var activeVariant = _.find(editorState.current.variants, function (v) {
|
||||
return !v.language || v.language.culture === culture;
|
||||
});
|
||||
|
||||
localizationService.localize("clipboard_labelForArrayOfItemsFrom", [$scope.model.label, activeVariant.name]).then(function(data) {
|
||||
clipboardService.copyArray("elementTypeArray", aliases, $scope.nodes, data, "icon-thumbnail-list", $scope.model.id);
|
||||
});
|
||||
}
|
||||
|
||||
var copyAllEntriesAction = {
|
||||
labelKey: 'clipboard_labelForCopyAllEntries',
|
||||
labelTokens: [$scope.model.label],
|
||||
icon: 'documents',
|
||||
method: copyAllEntries,
|
||||
isDisabled: true
|
||||
}
|
||||
|
||||
|
||||
|
||||
// helper to force the current form into the dirty state
|
||||
$scope.setDirty = function () {
|
||||
if ($scope.propertyForm) {
|
||||
@@ -237,7 +273,13 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
view: "itempicker",
|
||||
event: $event,
|
||||
clickPasteItem: function(item) {
|
||||
$scope.pasteFromClipboard(item.data);
|
||||
if (item.type === "elementTypeArray") {
|
||||
_.each(item.data, function (entry) {
|
||||
$scope.pasteFromClipboard(entry);
|
||||
});
|
||||
} else {
|
||||
$scope.pasteFromClipboard(item.data);
|
||||
}
|
||||
$scope.overlayMenu.show = false;
|
||||
$scope.overlayMenu = null;
|
||||
},
|
||||
@@ -271,13 +313,24 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
$scope.overlayMenu.size = $scope.overlayMenu.availableItems.length > 6 ? "medium" : "small";
|
||||
|
||||
$scope.overlayMenu.pasteItems = [];
|
||||
var availableNodesForPaste = clipboardService.retriveDataOfType("elementType", contentTypeAliases);
|
||||
_.each(availableNodesForPaste, function (node) {
|
||||
|
||||
var singleEntriesForPaste = clipboardService.retriveEntriesOfType("elementType", contentTypeAliases);
|
||||
_.each(singleEntriesForPaste, function (entry) {
|
||||
$scope.overlayMenu.pasteItems.push({
|
||||
alias: node.contentTypeAlias,
|
||||
name: node.name, //contentTypeName
|
||||
data: node,
|
||||
icon: iconHelper.convertFromLegacyIcon(node.icon)
|
||||
type: "elementType",
|
||||
name: entry.label,
|
||||
data: entry.data,
|
||||
icon: entry.icon
|
||||
});
|
||||
});
|
||||
|
||||
var arrayEntriesForPaste = clipboardService.retriveEntriesOfType("elementTypeArray", contentTypeAliases);
|
||||
_.each(arrayEntriesForPaste, function (entry) {
|
||||
$scope.overlayMenu.pasteItems.push({
|
||||
type: "elementTypeArray",
|
||||
name: entry.label,
|
||||
data: entry.data,
|
||||
icon: entry.icon
|
||||
});
|
||||
});
|
||||
|
||||
@@ -287,6 +340,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
$event.stopPropagation();
|
||||
$event.preventDefault();
|
||||
clipboardService.clearEntriesOfType("elementType", contentTypeAliases);
|
||||
clipboardService.clearEntriesOfType("elementTypeArray", contentTypeAliases);
|
||||
$scope.overlayMenu.pasteItems = [];// This dialog is not connected via the clipboardService events, so we need to update manually.
|
||||
};
|
||||
|
||||
@@ -313,10 +367,6 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
updateModel();
|
||||
};
|
||||
$scope.requestDeleteNode = function (idx) {
|
||||
if ($scope.nodes.length <= $scope.model.config.minItems) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($scope.model.config.confirmDeletes === true) {
|
||||
localizationService.localizeMany(["content_nestedContentDeleteItem", "general_delete", "general_cancel", "contentTypeEditor_yesDelete"]).then(function (data) {
|
||||
const overlay = {
|
||||
@@ -452,6 +502,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
$event.stopPropagation();
|
||||
}
|
||||
|
||||
|
||||
$scope.pasteFromClipboard = function(newNode) {
|
||||
|
||||
if (newNode === undefined) {
|
||||
@@ -469,7 +520,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
}
|
||||
|
||||
function checkAbilityToPasteContent() {
|
||||
$scope.showPaste = clipboardService.hasEntriesOfType("elementType", contentTypeAliases);
|
||||
$scope.showPaste = clipboardService.hasEntriesOfType("elementType", contentTypeAliases) || clipboardService.hasEntriesOfType("elementTypeArray", contentTypeAliases);
|
||||
}
|
||||
|
||||
eventsService.on("clipboardService.storageUpdate", checkAbilityToPasteContent);
|
||||
@@ -544,8 +595,8 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce min items
|
||||
if ($scope.nodes.length < $scope.model.config.minItems) {
|
||||
// Auto-fill with elementTypes, but only if we have one type to choose from, and if this property is empty.
|
||||
if ($scope.singleMode === true && $scope.nodes.length === 0 && $scope.model.config.minItems > 0) {
|
||||
for (var i = $scope.nodes.length; i < $scope.model.config.minItems; i++) {
|
||||
$scope.addNode($scope.scaffolds[0].contentTypeAlias);
|
||||
}
|
||||
@@ -558,6 +609,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
|
||||
$scope.inited = true;
|
||||
|
||||
updatePropertyActionStates();
|
||||
checkAbilityToPasteContent();
|
||||
}
|
||||
}
|
||||
@@ -614,6 +666,9 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function syncCurrentNode() {
|
||||
if ($scope.realCurrentNode) {
|
||||
$scope.$broadcast("ncSyncVal", { key: $scope.realCurrentNode.key });
|
||||
@@ -630,6 +685,12 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
}
|
||||
$scope.model.value = newValues;
|
||||
}
|
||||
|
||||
updatePropertyActionStates();
|
||||
}
|
||||
|
||||
function updatePropertyActionStates() {
|
||||
copyAllEntriesAction.isDisabled = $scope.model.value.length === 0;
|
||||
}
|
||||
|
||||
$scope.$watch("currentNode", function (newVal) {
|
||||
@@ -637,12 +698,43 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
$scope.realCurrentNode = newVal;
|
||||
});
|
||||
|
||||
|
||||
var api = {};
|
||||
api.propertyActions = [
|
||||
copyAllEntriesAction
|
||||
];
|
||||
|
||||
propertyEditorService.exposeAPI($scope, api);// must be executed at a state where the API is set.
|
||||
|
||||
var unsubscribe = $scope.$on("formSubmitting", function (ev, args) {
|
||||
updateModel();
|
||||
});
|
||||
|
||||
var watcher = $scope.$watch(
|
||||
function () {
|
||||
return $scope.nodes.length;
|
||||
},
|
||||
function () {
|
||||
//Validate!
|
||||
if ($scope.nodes.length < $scope.minItems) {
|
||||
$scope.nestedContentForm.minCount.$setValidity("minCount", false);
|
||||
}
|
||||
else {
|
||||
$scope.nestedContentForm.minCount.$setValidity("minCount", true);
|
||||
}
|
||||
|
||||
if ($scope.nodes.length > $scope.maxItems) {
|
||||
$scope.nestedContentForm.maxCount.$setValidity("maxCount", false);
|
||||
}
|
||||
else {
|
||||
$scope.nestedContentForm.maxCount.$setValidity("maxCount", true);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$scope.$on("$destroy", function () {
|
||||
unsubscribe();
|
||||
watcher();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<umb-load-indicator ng-if="!inited"></umb-load-indicator>
|
||||
|
||||
<ng-form ng-if="inited">
|
||||
<ng-form name="nestedContentForm">
|
||||
|
||||
<div class="umb-nested-content__items" ng-hide="nodes.length === 0" ui-sortable="sortableOptions" ng-model="nodes">
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<a class="umb-nested-content__icon umb-nested-content__icon--copy" title="{{copyIconTitle}}" ng-click="clickCopy($event, node);" ng-if="showCopy" prevent-default>
|
||||
<i class="icon icon-documents"></i>
|
||||
</a>
|
||||
<a class="umb-nested-content__icon umb-nested-content__icon--delete" localize="title" title="general_delete" ng-class="{ 'umb-nested-content__icon--disabled': $parent.nodes.length <= $parent.minItems }" ng-click="$parent.requestDeleteNode($index); $event.stopPropagation();" prevent-default>
|
||||
<a class="umb-nested-content__icon umb-nested-content__icon--delete" localize="title" title="general_delete" ng-click="$parent.requestDeleteNode($index); $event.stopPropagation();" prevent-default>
|
||||
<i class="icon icon-trash"></i>
|
||||
</a>
|
||||
</div>
|
||||
@@ -38,10 +38,26 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-nested-content__footer-bar" ng-hide="hasContentTypes === false || nodes.length >= maxItems">
|
||||
<a href class="umb-nested-content__add-content" ng-class="{ '--disabled': !scaffolds.length }" ng-click="openNodeTypePicker($event)" prevent-default>
|
||||
<div class="umb-nested-content__footer-bar" ng-hide="hasContentTypes === false">
|
||||
<button class="btn-reset umb-nested-content__add-content umb-focus" ng-class="{ '--disabled': (!scaffolds.length || nodes.length >= maxItems) }" ng-click="openNodeTypePicker($event)" prevent-default>
|
||||
<localize key="grid_addElement"></localize>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<!--These are here because we need ng-form fields to validate against-->
|
||||
<input type="hidden" name="minCount" ng-model="nodes" />
|
||||
<input type="hidden" name="maxCount" ng-model="nodes" />
|
||||
|
||||
<div ng-messages="nestedContentForm.minCount.$error" show-validation-on-submit>
|
||||
<div class="help text-error" ng-message="minCount">
|
||||
<localize key="validation_entriesShort" tokens="[minItems, minItems - nodes.length]" watch-tokens="true">Minimum %0% entries, needs <strong>%1%</strong> more.</localize>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-if="nestedContentForm.minCount.$error === true || nodes.length > maxItems">
|
||||
<div class="help text-error">
|
||||
<localize key="validation_entriesExceed" tokens="[maxItems, nodes.length - maxItems]" watch-tokens="true">Maximum %0% entries, <strong>%1%</strong> too many.</localize>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ng-form>
|
||||
|
||||
@@ -101,6 +101,10 @@ angular.module("umbraco")
|
||||
}
|
||||
});
|
||||
|
||||
$scope.focus = function () {
|
||||
tinyMceEditor.focus();
|
||||
}
|
||||
|
||||
//when the element is disposed we need to unsubscribe!
|
||||
// NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom
|
||||
// element might still be there even after the modal has been hidden.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<umb-load-indicator ng-if="isLoading"></umb-load-indicator>
|
||||
|
||||
<div class="umb-rte-editor-con">
|
||||
<input type="text" id="{{model.alias}}" ng-focus="focus()" style="position:absolute;top:0;width:0;height:0;" />
|
||||
<div id="{{textAreaHtmlId}}" class="umb-rte-editor" ng-style="{ width: containerWidth, height: containerHeight, overflow: containerOverflow}"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user