Merge branch 'dev-v7' into dev-v7

This commit is contained in:
Sebastiaan Janssen
2018-10-29 12:39:27 +01:00
committed by GitHub
55 changed files with 704 additions and 241 deletions
+1 -2
View File
@@ -1,4 +1,4 @@
_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/temp8/docs/CONTRIBUTING.md) to go to the v8 branch_
_Looking for Umbraco version 8? [Click here](https://github.com/umbraco/Umbraco-CMS/blob/temp8/.github/V8_GETTING_STARTED.md) to go to the v8 branch_
# Contributing to Umbraco CMS
👍🎉 First off, thanks for taking the time to contribute! 🎉👍
@@ -72,7 +72,6 @@ The pull request team consists of a member of Umbraco HQ, [Sebastiaan](https://g
- [Anders Bjerner](https://github.com/abjerner)
- [Dave Woestenborghs](https://github.com/dawoe)
- [Emma Burstow](https://github.com/emmaburstow)
- [Kyle Weems](https://github.com/cssquirrel)
- [Poornima Nayar](https://github.com/poornimanayar)
These wonderful volunteers will provide you with a first reply to your PR, review and test out your changes and might ask more questions. After that they'll let Umbraco HQ know if everything seems okay.
+2 -2
View File
@@ -30,7 +30,7 @@ As an Open Source platform, Umbraco is more than just a CMS. We are transparent
## Trying out Umbraco CMS
[Umbraco Cloud](https://umbraco.com/cloud) is the easiest and fastest way to use Umbraco yet with full support for all your custom .NET code and integrations. You're up and running in less than a minute and your life will be made easier with automated upgrades and a built-in deployment engine. We offer a free 14 day trial, no credit card needed.
[Umbraco Cloud](https://umbraco.com/cloud) is the easiest and fastest way to use Umbraco yet with full support for all your custom .NET code and integrations. You're up and running in less than a minute and your life will be made easier with automated upgrades and a built-in deployment engine. We offer a free 14-day trial, no credit card needed.
If you want to DIY you can [download Umbraco](https://our.umbraco.com/download) either as a ZIP file or via NuGet. It's the same version of Umbraco CMS that powers Umbraco Cloud, but you'll need to find a place to host yourself and handling deployments and upgrades is all down to you.
@@ -47,4 +47,4 @@ Umbraco is contribution focused and community driven. If you want to contribute
Another way you can contribute to Umbraco is by providing issue reports. For information on how to submit an issue report refer to our [online guide for reporting issues](https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/.github/CONTRIBUTING.md).
You can comment and report issues on the [github issue tracker](https://github.com/umbraco/Umbraco-CMS/issues).
Since [September 2018](https://umbraco.com/blog/a-second-take-on-umbraco-issue-tracker-hello-github-issues/) the old issue tracker is in read only mode, but can still be found at [http://issues.umbraco.org](http://issues.umbraco.org).
Since [September 2018](https://umbraco.com/blog/a-second-take-on-umbraco-issue-tracker-hello-github-issues/) the old issue tracker is in read-only mode, but can still be found at [http://issues.umbraco.org](http://issues.umbraco.org).
+1 -1
View File
@@ -9,6 +9,6 @@ IF ERRORLEVEL 1 (
:error
ECHO.
ECHO Can not run build\build.ps1.
ECHO Cannot run build\build.ps1.
ECHO If this is due to a SecurityError then please refer to BUILD.md for help!
ECHO.
@@ -158,9 +158,7 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
Name = indexName,
IndexType = attribute.IndexType,
ColumnName = columnName,
TableName = tableName,
IsClustered = attribute.IndexType == IndexTypes.Clustered,
IsUnique = attribute.IndexType == IndexTypes.UniqueNonClustered
TableName = tableName,
};
if (string.IsNullOrEmpty(attribute.ForColumns) == false)
@@ -174,4 +172,4 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
return definition;
}
}
}
}
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Persistence.DatabaseAnnotations;
@@ -14,9 +15,13 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
public virtual string SchemaName { get; set; }
public virtual string TableName { get; set; }
public virtual string ColumnName { get; set; }
[Obsolete("Use the IndexType property instead and set it to IndexTypes.UniqueNonClustered")]
public virtual bool IsUnique { get; set; }
[Obsolete("Use the IndexType property instead and set it to IndexTypes.Clustered")]
public bool IsClustered { get; set; }
public virtual ICollection<IndexColumnDefinition> Columns { get; set; }
public IndexTypes IndexType { get; set; }
}
}
}
@@ -1,4 +1,5 @@
using System.Data;
using Umbraco.Core.Persistence.DatabaseAnnotations;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions;
using Umbraco.Core.Persistence.Migrations.Syntax.Expressions;
@@ -139,10 +140,12 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column
{
Name = indexName,
SchemaName = Expression.SchemaName,
TableName = Expression.TableName,
IsUnique = true
TableName = Expression.TableName,
IndexType = IndexTypes.UniqueNonClustered
});
index.Index.Columns.Add(new IndexColumnDefinition
{
Name = Expression.Column.Name
@@ -242,4 +245,4 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Column
return this;
}
}
}
}
@@ -1,4 +1,5 @@
using System.Data;
using Umbraco.Core.Persistence.DatabaseAnnotations;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Migrations.Syntax.Alter.Expressions;
using Umbraco.Core.Persistence.Migrations.Syntax.Expressions;
@@ -124,8 +125,8 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table
{
Name = indexName,
SchemaName = Expression.SchemaName,
TableName = Expression.TableName,
IsUnique = true
TableName = Expression.TableName,
IndexType = IndexTypes.UniqueNonClustered
});
index.Index.Columns.Add(new IndexColumnDefinition
@@ -259,4 +260,4 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Alter.Table
return this;
}
}
}
}
@@ -1,4 +1,5 @@
using System.Data;
using Umbraco.Core.Persistence.DatabaseAnnotations;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Migrations.Syntax.Expressions;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -114,8 +115,8 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Column
{
Name = indexName,
SchemaName = Expression.SchemaName,
TableName = Expression.TableName,
IsUnique = true
TableName = Expression.TableName,
IndexType = IndexTypes.UniqueNonClustered
});
index.Index.Columns.Add(new IndexColumnDefinition
@@ -217,4 +218,4 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Column
return this;
}
}
}
}
@@ -47,39 +47,27 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Index
}
ICreateIndexOnColumnSyntax ICreateIndexColumnOptionsSyntax.Unique()
{
Expression.Index.IsUnique = true;
//if it is Unique then it must be unique nonclustered and set the other flags
Expression.Index.IndexType = IndexTypes.UniqueNonClustered;
Expression.Index.IsClustered = false;
{
Expression.Index.IndexType = IndexTypes.UniqueNonClustered;
return this;
}
public ICreateIndexOnColumnSyntax NonClustered()
{
Expression.Index.IndexType = IndexTypes.NonClustered;
Expression.Index.IsClustered = false;
Expression.Index.IndexType = IndexTypes.NonClustered;
Expression.Index.IsUnique = false;
Expression.Index.IndexType = IndexTypes.NonClustered;
return this;
}
public ICreateIndexOnColumnSyntax Clustered()
{
Expression.Index.IndexType = IndexTypes.Clustered;
Expression.Index.IsClustered = true;
//if it is clustered then we have to change the index type set the other flags
Expression.Index.IndexType = IndexTypes.Clustered;
Expression.Index.IsClustered = true;
Expression.Index.IsUnique = false;
return this;
{
Expression.Index.IndexType = IndexTypes.Clustered;
return this;
}
ICreateIndexOnColumnSyntax ICreateIndexOptionsSyntax.Unique()
{
Expression.Index.IndexType = IndexTypes.UniqueNonClustered;
Expression.Index.IsUnique = true;
Expression.Index.IndexType = IndexTypes.UniqueNonClustered;
return this;
}
}
}
}
@@ -1,4 +1,5 @@
using System.Data;
using Umbraco.Core.Persistence.DatabaseAnnotations;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Migrations.Syntax.Create.Expressions;
using Umbraco.Core.Persistence.Migrations.Syntax.Expressions;
@@ -164,8 +165,8 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Table
{
Name = indexName,
SchemaName = Expression.SchemaName,
TableName = Expression.TableName,
IsUnique = true
TableName = Expression.TableName,
IndexType = IndexTypes.UniqueNonClustered
});
index.Index.Columns.Add(new IndexColumnDefinition
@@ -267,4 +268,4 @@ namespace Umbraco.Core.Persistence.Migrations.Syntax.Create.Table
return this;
}
}
}
}
@@ -89,7 +89,7 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
var sqlSyntax = new SqlServerSyntaxProvider();
var indexDefinition = CreateIndexDefinition();
indexDefinition.IsClustered = false;
indexDefinition.IndexType = IndexTypes.Clustered;
var actual = sqlSyntax.Format(indexDefinition);
Assert.AreEqual("CREATE CLUSTERED INDEX [IX_A] ON [TheTable] ([A])", actual);
@@ -159,4 +159,4 @@ WHERE (([umbracoNode].[nodeObjectType] = @0))) x)".Replace(Environment.NewLine,
}
}
}
}
+3
View File
@@ -33,6 +33,9 @@
"clipboard": "1.7.1",
"font-awesome": "~4.7"
},
"resolutions": {
"font-awesome": "~4.7"
},
"install": {
"path": "lib-bower",
"ignore": [
@@ -1,5 +1,5 @@
angular.module("umbraco.directives")
.directive('gridRte', function (tinyMceService, stylesheetResource, angularHelper, assetsService, $q, $timeout) {
.directive('gridRte', function (tinyMceService, stylesheetResource, angularHelper, assetsService, $q, $timeout, eventsService) {
return {
scope: {
uniqueId: '=',
@@ -362,8 +362,16 @@ angular.module("umbraco.directives")
// tinyMceEditor.fire('LoadContent', null);
//};
var tabShownListener = eventsService.on("valTab.tabShown", function (e, args) {
//the tab has been shown, trigger the mceAutoResize (as it could have timed out before the tab was shown)
if (tinyMceEditor !== undefined && tinyMceEditor != null) {
tinyMceEditor.execCommand('mceAutoResize', false, null, null);
}
});
//listen for formSubmitting event (the result is callback used to remove the event subscription)
var unsubscribe = scope.$on("formSubmitting", function () {
var formSubmittingListener = scope.$on("formSubmitting", function () {
//TODO: Here we should parse out the macro rendered content so we can save on a lot of bytes in data xfer
// we do parse it out on the server side but would be nice to do that on the client side before as well.
scope.value = tinyMceEditor ? tinyMceEditor.getContent() : null;
@@ -373,7 +381,8 @@ angular.module("umbraco.directives")
// 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.
scope.$on('$destroy', function () {
unsubscribe();
formSubmittingListener();
eventsService.unsubscribe(tabShownListener);
if (tinyMceEditor !== undefined && tinyMceEditor != null) {
tinyMceEditor.destroy()
}
@@ -6,15 +6,15 @@
* @description Used to show validation warnings for a tab to indicate that the tab content has validations errors in its data.
* In order for this directive to work, the valFormManager directive must be placed on the containing form.
**/
function valTab() {
function valTab(eventsService) {
return {
require: ['^form', '^valFormManager'],
restrict: "A",
link: function (scope, element, attr, ctrs) {
var valFormManager = ctrs[1];
var tabId = "tab" + scope.tab.id;
scope.tabHasError = false;
var tabId = "tab" + scope.tab.id;
scope.tabHasError = false;
//listen for form validation changes
valFormManager.onValidationStatusChanged(function (evt, args) {
@@ -31,8 +31,17 @@ function valTab() {
scope.tabHasError = false;
}
});
var tabShownFunc = function (e) {
var tabContent = element.closest(".umb-panel").find("#" + tabId);
eventsService.emit('valTab.tabShown', { originalEvent: e, tab: scope.tab, content: tabContent });
};
var anchorElement = element.find("a[data-toggle='tab']");
anchorElement.on('shown.bs.tab', tabShownFunc);
scope.$on('$destroy', function () {
anchorElement.off('shown.bs.tab', tabShownFunc);
});
}
};
}
angular.module('umbraco.directives.validation').directive("valTab", valTab);
angular.module('umbraco.directives.validation').directive("valTab", valTab);
@@ -463,7 +463,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo
//if it is not two parts long then this most likely means that it's a legacy action
var js = action.metaData["jsAction"].replace("javascript:", "");
//there's not really a different way to acheive this except for eval
//there's not really a different way to achieve this except for eval
eval(js);
}
else {
@@ -11,7 +11,7 @@
*/
function NavigationController($scope, $rootScope, $location, $log, $routeParams, $timeout, appState, navigationService, keyboardService, dialogService, historyService, eventsService, sectionResource, angularHelper) {
//TODO: Need to think about this and an nicer way to acheive what this is doing.
//TODO: Need to think about this and an nicer way to achieve what this is doing.
//the tree event handler i used to subscribe to the main tree click events
$scope.treeEventHandler = $({});
navigationService.setupTreeEvents($scope.treeEventHandler);
@@ -101,6 +101,7 @@
@import "components/umb-confirm-action.less";
@import "components/umb-keyboard-shortcuts-overview.less";
@import "components/umb-checkbox-list.less";
@import "components/umb-radiobuttons-list.less";
@import "components/umb-locked-field.less";
@import "components/umb-tabs.less";
@import "components/umb-load-indicator.less";
@@ -5,6 +5,10 @@
.umb-overlay & {
width: 500px;
}
p{
margin: 7px 0;
}
}
.umb-prevalues-multivalues__left {
@@ -42,8 +42,8 @@
&.with-labels {
.umb-color-box {
width: 120px;
height: 100%;
width: 130px;
height: auto;
display: flex;
flex-flow: row wrap;
@@ -53,15 +53,21 @@
flex: 0 0 100%;
max-width: 100%;
min-height: 80px;
padding-top: 10px;
padding: 0;
.check_circle {
margin: 15px auto;
}
.umb-color-box__label {
background: @white;
font-size: 14px;
display: flex;
flex-flow: column wrap;
flex: 0 0 100%;
flex: 1 0 100%;
justify-content: flex-end;
padding: 1px 5px;
min-height: 45px;
max-width: 100%;
margin-top: auto;
margin-bottom: -3px;
@@ -0,0 +1,80 @@
.umb-radiobuttons{
&__label{
position: relative;
padding: 0;
&-text{
margin: 0 0 0 32px;
position: relative;
top: 1px;
}
}
&__input{
position: absolute;
top: 0;
left: 0;
opacity: 0;
&:focus ~ .umb-radiobuttons__state{
box-shadow: 0 1px 3px fade(@black, 12%), 0 1px 2px fade(@black, 24%);
}
&:focus:checked ~ .umb-radiobuttons__state{
box-shadow: none;
}
&:checked ~ .umb-radiobuttons__state{
&:before{
width: 100%;
height: 100%;
}
}
&:checked ~ .umb-radiobuttons__state .umb-radiobuttons__icon{
opacity: 1;
}
}
&__state{
display: flex;
flex-wrap: wrap;
border: 1px solid @gray-8;
border-radius: 100%;
width: 22px;
height: 22px;
position: relative;
&:before{
content: "";
background: @green;
width: 0;
height: 0;
transition: .1s ease-out;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
border-radius: 100%;
}
}
&__icon{
color: @white;
text-align: center;
font-size: 15px;
opacity: 0;
transition: .3s ease-out;
&:before{
position: absolute;
top: 2px;
right: 0;
left: 0;
bottom: 0;
margin: auto;
}
}
}
+16 -5
View File
@@ -23,7 +23,7 @@
margin-top: 0px;
margin-bottom: 15px;
font-size: 14px;
color: @gray-7;
color: @gray-7;
}
h5{
@@ -134,7 +134,7 @@ h5.-black {
padding-bottom: 0;
}
.block-form .umb-control-group label .help-block,
.block-form .umb-control-group label .help-block,
.block-form .umb-control-group label small {
font-size: 13px;
padding-top: 2px;
@@ -243,9 +243,9 @@ label:not([for]) {
}
.umb-version {
color: @gray-7;
position: absolute;
bottom: 5px;
color: @gray-7;
position: absolute;
bottom: 5px;
right: 20px;
}
@@ -653,3 +653,14 @@ input[type=checkbox]:checked + .input-label--small {
.bootstrap-datetimepicker-widget td span {
border-radius: 0 !important;
}
.visuallyhidden{
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
padding:0 !important;
border:0 !important;
height: 1px !important;
width: 1px !important;
overflow: hidden;
}
@@ -102,11 +102,11 @@ div.umb-codeeditor {
border: 1px solid @gray-8;
}
div.umb-codeeditor .umb-el-wrap {
padding: 0px;
padding: 0;
}
div.umb-codeeditor .umb-btn-toolbar {
padding: 0px;
margin: 0px;
padding: 0;
margin: 0;
border-bottom: @gray-8 1px solid;
background: @gray-10;
}
@@ -122,7 +122,7 @@ div.umb-codeeditor .umb-btn-toolbar {
position: absolute;
}
}
.mce-tinymce{border: 1px solid @gray-8 !important; border-radius: 0px !important;}
.mce-tinymce{border: 1px solid @gray-8 !important; border-radius: 0 !important;}
.mce-panel{background: @gray-10 !important; border-color: @gray-8 !important;}
.mce-btn-group, .mce-btn{border: none !important; background: none !important;}
.mce-ico{font-size: 12px !important; color: @gray-1 !important;}
@@ -203,7 +203,7 @@ div.umb-codeeditor .umb-btn-toolbar {
}
label {
border: 1px solid #fff;
border: 1px solid @white;
padding: 6px 10px;
font-family: monospace;
border: 1px solid #dfdfe1;
@@ -213,6 +213,99 @@ div.umb-codeeditor .umb-btn-toolbar {
}
}
//
// Image Cropper
// --------------------------------------------------
.umb-prevalues-multivalues.umb-cropsizes{
max-width: none;
width: 100%;
.umb-overlay__form &{
width: 100%;
}
}
.umb-cropsizes{
float: left;
.control-group{
label{
display: block;
}
}
&__add{
display: flex;
align-items: center;
flex-wrap: wrap;
}
&__sortable{
max-width: 500px;
width: 100%;
min-width: 66.6%;
@media (min-width: 1101px) and (max-width: 1300px), (max-width: 930px){
max-width: none;
}
}
&__controls{
margin: 24px 0 0;
}
&__input{
margin: 0 15px 0 0;
width: ~"calc(100% - 15px)";
@media (min-width: 1101px) and (max-width: 1300px), (max-width: 930px){
margin: 0;
width: 100%;
max-width: 220px;
}
&--narrow{
max-width: 95px;
width: 100%;
}
&-wrap{
position: relative;
max-width: 206px;
width: 100%;
@media (min-width: 1101px) and (max-width: 1300px), (max-width: 930px){
max-width: none;
flex: 1 1 100%;
margin: 0 0 20px;
}
&--narrow{
margin: 0 15px 0 0;
max-width: 95px;
width: 100%;
}
&--icon{
padding: 0 15px 0 0;
width: ~"calc(100% + 15px)"; // Use an escape string in order to make use of CSS native calc function instead of the one built into less
&:after{
content:"\00D7";
position: absolute;
bottom: -9px;
top: 0;
margin: auto;
right: 0;
width: 5px;
height: 5px;
}
}
}
}
}
//
// Media picker
@@ -235,6 +328,18 @@ div.umb-codeeditor .umb-btn-toolbar {
}
}
.umb-mediapicker .label{
&__trashed{
background-color: @red;
position: absolute;
top: 50%;
left: 50%;
z-index: 1;
transform: translate3d(-50%,-50%,0);
margin: 0;
}
}
.umb-mediapicker .picked-image {
position: absolute;
bottom: 10px;
@@ -333,7 +438,7 @@ div.umb-codeeditor .umb-btn-toolbar {
background-image: url(../img/checkered-background.png);
}
.umb-sortable-thumbnails li img.trashed {
.umb-sortable-thumbnails li .trashed {
opacity:0.3;
}
@@ -707,8 +812,8 @@ div.umb-codeeditor .umb-btn-toolbar {
.umb-photo-folder .picrow div, .umb-photo-preview{
margin: 0px;
padding: 0px;
margin: 0;
padding: 0;
border: none;
display: inline-block;
vertical-align: top;
@@ -745,9 +850,9 @@ div.umb-codeeditor .umb-btn-toolbar {
//this is a temp hack, to provide selectors in the dialog:
.umb-photo-folder .pic:hover .selector-overlay {
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
bottom: 0;
left: 0;
right: 0;
padding: 5px;
background: @black;
z-index: 100;
@@ -827,7 +932,7 @@ div.umb-codeeditor .umb-btn-toolbar {
.umb-fileupload ul {
list-style: none;
vertical-align: middle;
margin-bottom: 0px;
margin-bottom: 0;
}
.umb-fileupload label {
@@ -6,7 +6,7 @@
<i class="icon icon-check small"></i>
</div>
<div class="umb-color-box__label" ng-if="useLabel">
<div class="umb-color-box__name truncate">{{ color.label }}</div>
<div class="umb-color-box__name truncate">{{ color.label || color.value }}</div>
<div class="umb-color-box__description">#{{ color.value }}</div>
</div>
</div>
@@ -83,10 +83,10 @@
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="success">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-if="!busy">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-show="!busy">
<localize key="general_cancel">Cancel</localize>
</a>
<button class="btn btn-primary" ng-click="copy()" ng-disabled="busy">
<button class="btn btn-primary" ng-click="copy()" ng-disabled="busy || !target">
<localize key="actions_copy">Copy</localize>
</button>
</div>
@@ -73,11 +73,11 @@
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="success">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-if="!busy">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-show="!busy">
<localize key="general_cancel">Cancel</localize>
</a>
<button class="btn btn-primary" ng-click="move()" ng-disabled="busy">
<button class="btn btn-primary" ng-click="move()" ng-disabled="busy || !target">
<localize key="actions_move">Move</localize>
</button>
</div>
</div>
</div>
@@ -44,10 +44,10 @@
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="success">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-if="!busy">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-show="!busy">
<localize key="general_cancel">Cancel</localize>
</a>
<button class="btn btn-primary" ng-click="move()" ng-disabled="busy">
<button class="btn btn-primary" ng-click="move()" ng-disabled="busy || !target">
<localize key="actions_move">Move</localize>
</button>
</div>
@@ -44,10 +44,10 @@
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="success">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-if="!busy">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-show="!busy">
<localize key="general_cancel">Cancel</localize>
</a>
<button class="btn btn-primary" ng-click="copy()" ng-disabled="busy">
<button class="btn btn-primary" ng-click="copy()" ng-disabled="busy || !target">
<localize key="actions_copy">Copy</localize>
</button>
</div>
@@ -44,10 +44,10 @@
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="success">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-if="!busy">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-show="!busy">
<localize key="general_cancel">Cancel</localize>
</a>
<button class="btn btn-primary" ng-click="move()" ng-disabled="busy">
<button class="btn btn-primary" ng-click="move()" ng-disabled="busy || !target">
<localize key="actions_move">Move</localize>
</button>
</div>
@@ -9,7 +9,7 @@
(function() {
'use strict';
function TemplatesController($scope, entityResource, contentTypeHelper, $routeParams) {
function TemplatesController($scope, entityResource, contentTypeHelper, templateResource, $routeParams) {
/* ----------- SCOPE VARIABLES ----------- */
@@ -21,24 +21,53 @@
/* ---------- INIT ---------- */
init();
init(function () {
function init() {
// update placeholder template information on new doc types
if (!$routeParams.notemplate && $scope.model.id === 0) {
vm.updateTemplatePlaceholder = true;
vm.availableTemplates = contentTypeHelper.insertTemplatePlaceholder(vm.availableTemplates);
}
});
function init(callback) {
entityResource.getAll("Template").then(function(templates){
vm.availableTemplates = templates;
// update placeholder template information on new doc types
if (!$routeParams.notemplate && $scope.model.id === 0) {
vm.updateTemplatePlaceholder = true;
vm.availableTemplates = contentTypeHelper.insertTemplatePlaceholder(vm.availableTemplates);
}
callback();
});
}
vm.createTemplate = function () {
templateResource.getScaffold(-1).then(function (template) {
template.alias = $scope.model.alias;
template.name = $scope.model.name;
templateResource.save(template).then(function (savedTemplate) {
init(function () {
var newTemplate = vm.availableTemplates.filter(function (t) { return t.id === savedTemplate.id });
if (newTemplate.length > 0) {
$scope.model.allowedTemplates.push(newTemplate[0]);
if ($scope.model.defaultTemplate === null) {
$scope.model.defaultTemplate = newTemplate[0];
}
}
});
});
});
}
}
angular.module("umbraco").controller("Umbraco.Editors.DocumentType.TemplatesController", TemplatesController);
@@ -16,6 +16,11 @@
alias="model.alias"
update-placeholder="vm.updateTemplatePlaceholder">
</umb-grid-selector>
<button type="button" ng-click="vm.createTemplate()" class="btn btn-info" ng-show="model.allowedTemplates.length == 0">
<i class="icon icon-add"></i>
<localize key="shortcuts_addTemplate">Add template</localize>
</button>
</div>
</div>
@@ -49,8 +49,10 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController",
$scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler);
$scope.move = function () {
$scope.busy = true;
mediaResource.move({ parentId: $scope.target.id, id: node.id })
.then(function (path) {
$scope.busy = false;
$scope.error = false;
$scope.success = true;
@@ -97,4 +99,4 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController",
$scope.miniListView = node;
}
});
});
@@ -49,7 +49,7 @@
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="success">
<a class="btn btn-link" ng-click="nav.hideDialog()"><localize key="general_cancel">Cancel</localize></a>
<button class="btn btn-primary" ng-click="move()"><localize key="actions_move">Move</localize></button>
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-show="!busy"><localize key="general_cancel">Cancel</localize></a>
<button class="btn btn-primary" ng-click="move()" ng-disabled="busy || !target"><localize key="actions_move">Move</localize></button>
</div>
</div>
@@ -44,10 +44,10 @@
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="success">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-if="!busy">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-show="!busy">
<localize key="general_cancel">Cancel</localize>
</a>
<button class="btn btn-primary" ng-click="copy()" ng-disabled="busy">
<button class="btn btn-primary" ng-click="copy()" ng-disabled="busy || !target">
<localize key="actions_copy">Copy</localize>
</button>
</div>
@@ -44,10 +44,10 @@
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-hide="success">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-if="!busy">
<a class="btn btn-link" ng-click="nav.hideDialog()" ng-show="!busy">
<localize key="general_cancel">Cancel</localize>
</a>
<button class="btn btn-primary" ng-click="move()" ng-disabled="busy">
<button class="btn btn-primary" ng-click="move()" ng-disabled="busy || !target">
<localize key="actions_move">Move</localize>
</button>
</div>
@@ -0,0 +1,64 @@
angular.module("umbraco").controller("Umbraco.PrevalueEditors.ColorPickerController",
function ($scope) {
//setup the default config
var config = {
useLabel: false
};
//map the user config
angular.extend(config, $scope.model.config);
//map back to the model
$scope.model.config = config;
$scope.isConfigured = $scope.model.prevalues && _.keys($scope.model.prevalues).length > 0;
$scope.model.items = [];
// Make an array from the dictionary
var items = [];
if (angular.isArray($scope.model.prevalues)) {
for (var i in $scope.model.prevalues) {
var oldValue = $scope.model.prevalues[i];
if (!isValidHex(oldValue.value || oldValue))
continue;
if (oldValue.hasOwnProperty("value")) {
var hexCode = toFullHex(oldValue.value);
items.push({
value: hexCode.substr(1, hexCode.length),
label: oldValue.label,
id: i
});
} else {
var hexCode = toFullHex(oldValue);
items.push({
value: hexCode.substr(1, hexCode.length),
label: oldValue,
id: i
});
}
}
// Now make the editor model the array
$scope.model.items = items;
}
function toFullHex(hex) {
if (hex.length === 4 && hex.charAt(0) === "#") {
hex = "#" + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2) + hex.charAt(3) + hex.charAt(3);
}
return hex.toLowerCase();
}
function isValidHex(str) {
console.log("str", str);
console.log("test", /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(str));
return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(str);
}
});
@@ -0,0 +1,18 @@
<div ng-controller="Umbraco.PrevalueEditors.ColorPickerController">
<div ng-if="!isConfigured">
<localize key="colorpicker_noColors">You haven't defined any colors</localize>
</div>
<umb-color-swatches colors="model.items"
selected-color="model.value"
size="s"
use-label="model.config.useLabel">
</umb-color-swatches>
{{model.items | json}}
<br /><br />
{{model.value}}
<input type="hidden" name="modelValue" ng-model="model.value" />
</div>
@@ -1,10 +1,13 @@
angular.module("umbraco").controller("Umbraco.PrevalueEditors.CropSizesController",
function ($scope, $timeout) {
function ($scope) {
if (!$scope.model.value) {
$scope.model.value = [];
}
$scope.editMode = false;
$scope.setFocus = false;
$scope.remove = function (item, evt) {
evt.preventDefault();
$scope.model.value = _.reject($scope.model.value, function (x) {
@@ -13,32 +16,57 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.CropSizesControlle
};
$scope.edit = function (item, evt) {
evt.preventDefault();
evt.preventDefault();
$scope.editMode = true;
$scope.setFocus = false;
$scope.newItem = item;
};
$scope.cancel = function (evt) {
evt.preventDefault();
evt.preventDefault();
$scope.editMode = false;
$scope.setFocus = true;
$scope.newItem = null;
};
$scope.add = function (evt) {
evt.preventDefault();
$scope.change = function () {
// Listen to the change event and set focus 2 false
if($scope.setFocus){
$scope.setFocus = false;
return;
}
}
if ($scope.newItem && $scope.newItem.alias &&
$scope.add = function (evt) {
evt.preventDefault();
$scope.editMode = false;
$scope.setFocus = true;
if ($scope.newItem && $scope.newItem.alias &&
angular.isNumber($scope.newItem.width) && angular.isNumber($scope.newItem.height) &&
$scope.newItem.width > 0 && $scope.newItem.height > 0) {
var exists = _.find($scope.model.value, function (item) { return $scope.newItem.alias === item.alias; });
var exists = _.find($scope.model.value, function (item) { return $scope.newItem.alias === item.alias; });
if (!exists) {
$scope.model.value.push($scope.newItem);
$scope.newItem = {};
$scope.hasError = false;
$scope.hasError = false;
$scope.cropAdded = false;
return;
}
}
else{
$scope.newItem = null;
$scope.hasError = false;
return;
}
}
//there was an error, do the highlight (will be set back by the directive)
$scope.hasError = true;
};
});
};
});
@@ -1,49 +1,74 @@
<div ng-controller="Umbraco.PrevalueEditors.CropSizesController" class="umb-editor umb-cropsizes">
<div ng-controller="Umbraco.PrevalueEditors.CropSizesController" class="umb-editor umb-prevalues-multivalues umb-cropsizes">
<div class="control-group umb-cropsizes__add">
<div class="control-group" ng-if="model.value.length > 0">
<ul class="unstyled list-icons"
ui-sortable
ng-model="model.value">
<li ng-repeat="node in model.value">
<a href=""><i class="icon icon-delete red hover-show pull-right" ng-click="remove(node, $event)"></i></a>
<i class="icon icon-picture handle hover-hide"></i>
<div class="umb-cropsizes__input-wrap">
<label for="addcropalias"><localize key="general_alias">Alias</localize></label>
<input
id="addcropalias"
name="newItem.alias"
type="text"
ng-model="newItem.alias"
class="umb-cropsizes__input"
val-highlight="{{hasError}}"
localize="placeholder"
placeholder="@general_alias"
focus-when="{{setFocus}}"
ng-change="change()"
/>
</div>
<div class="umb-cropsizes__input-wrap umb-cropsizes__input-wrap--narrow umb-cropsizes__input-wrap--icon">
<label for="addcropwidth"><localize key="general_width">Width</localize></label>
<input
name="newItem.width"
type="number"
localize="placeholder"
placeholder="@general_width"
ng-model="newItem.width"
class="umb-cropsizes__input umb-cropsizes__input--narrow"
val-highlight="{{hasError}}"
id="addcropwidth"
min="0"
pattern="[0-9]*"
/>
</div>
<div class="umb-cropsizes__input-wrap umb-cropsizes__input-wrap--narrow">
<label for="addcropheight"><localize key="general_height">Height</localize></label>
<input
name="newItem.height"
type="number"
localize="placeholder"
placeholder="@general_height"
ng-model="newItem.height"
class="umb-cropsizes__input umb-cropsizes__input--narrow"
val-highlight="{{hasError}}"
id="addcropheight"
min="0"
pattern="[0-9]*"
/>
</div>
<div class="umb-cropsizes__controls">
<button class="btn btn-info add" ng-hide="editMode" ng-click="add($event)"><localize key="general_add">Add</localize></button>
<button class="btn btn-info add" ng-show="editMode" ng-click="add($event)"><localize key="general_update">Update</localize></button>
<a href class="btn btn-link" ng-show="editMode" ng-click="cancel($event)"><localize key="general_cancel">Cancel</localize></a>
</div>
<a href prevent-default ng-click="edit(node, $event)">{{node.alias}}</a>
<br /><small>{{node.width}}px &times; {{node.height}}px</small>
</li>
</ul>
</div>
<div class="form" ng-show="newItem">
<h4><localize key="imagecropper_defineCrop">Define crop</localize></h4>
<p>
<localize key="imagecropper_defineCropDescription">Give the crop an alias and it's default width and height</localize>.
</p>
<div class="control-group">
<label><localize key="general_alias">Alias</localize></label>
<input name="newItem.alias" type="text"
ng-model="newItem.alias" val-highlight="{{hasError}}" />
<div ui-sortable="sortableOptions" class="umb-cropsizes__sortable">
<div class="control-group umb-prevalues-multivalues__listitem" ng-repeat="item in model.value">
<i class="icon icon-navigation handle"></i>
<div class="umb-prevalues-multivalues__left">
<p><span>{{item.alias}}</span> <small>({{item.width}}px &times; {{item.height}}px)</small></p>
</div>
<div class="umb-prevalues-multivalues__right">
<a href="#" prevent-default class="umb-node-preview__action umb-node-preview__action--red" ng-click="edit(item, $event)" class="umb-prevalues-multivalues__action">Edit</a>
<a class="umb-node-preview__action umb-node-preview__action--red" ng-click="remove(item, $event)"><localize key="general_remove">Remove</localize></a>
</div>
</div>
<div class="control-group">
<label><localize key="general_size">Size</localize></label>
<input name="newItem.width" type="number" localize="placeholder" placeholder="@general_width"
ng-model="newItem.width" class="umb-editor-small" val-highlight="{{hasError}}" />
&times;
<input name="newItem.height" type="number" localize="placeholder" placeholder="@general_height"
ng-model="newItem.height" class="umb-editor-small" val-highlight="{{hasError}}" />
</div>
<div class="control-group">
<button class="btn" ng-click="add($event)"><localize key="imagecropper_saveCrop">Save crop</localize></button>
<a href class="btn btn-link" ng-click="cancel($event)"><localize key="general_cancel">Cancel</localize></a>
</div>
</div>
<div class="control-group" ng-hide="newItem">
<button class="btn" ng-click="newItem = {}" prevent-default><localize key="imagecropper_addCrop">Add new crop</localize></button>
</div>
</div>
@@ -58,6 +58,11 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie
items: []
};
$scope.createAllowedButtonSingle = false;
$scope.createAllowedButtonSingleWithBlueprints = false;
$scope.createAllowedButtonMultiWithBlueprints = false;
//when this is null, we don't check permissions
$scope.currentNodePermissions = null;
@@ -598,7 +603,28 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie
id = -1;
}
$scope.listViewAllowedTypes = getContentTypesCallback(id);
//$scope.listViewAllowedTypes = getContentTypesCallback(id);
getContentTypesCallback(id).then(function (listViewAllowedTypes) {
var blueprints = false;
$scope.listViewAllowedTypes = listViewAllowedTypes;
angular.forEach(listViewAllowedTypes, function (allowedType) {
angular.forEach(allowedType.blueprints, function (value, key) {
blueprints = true;
});
});
if (listViewAllowedTypes.length === 1 && blueprints === false) {
$scope.createAllowedButtonSingle = true;
}
if (listViewAllowedTypes.length === 1 && blueprints === true) {
$scope.createAllowedButtonSingleWithBlueprints = true;
}
if (listViewAllowedTypes.length > 1) {
$scope.createAllowedButtonMultiWithBlueprints = true;
}
});
$scope.contentId = id;
$scope.isTrashed = id === "-20" || id === "-21";
@@ -650,6 +676,22 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie
}
}
function createBlank(entityType,docTypeAlias) {
$location
.path("/" + entityType + "/" + entityType + "/edit/" + $scope.contentId)
.search("doctype=" + docTypeAlias + "&create=true");
}
function createFromBlueprint(entityType,docTypeAlias, blueprintId) {
$location
.path("/" + entityType + "/" + entityType + "/edit/" + $scope.contentId)
.search("doctype=" + docTypeAlias + "&create=true&blueprintId=" + blueprintId);
}
$scope.createBlank = createBlank;
$scope.createFromBlueprint = createFromBlueprint;
//GO!
initView();
}
@@ -11,35 +11,85 @@
<umb-editor-sub-header-content-left>
<umb-editor-sub-header-section ng-if="(listViewAllowedTypes && listViewAllowedTypes.length > 0 && !isAnythingSelected()) && (currentNodePermissions == null || currentNodePermissions.canCreate)">
<div class="btn-group" ng-show="listViewAllowedTypes.length > 1">
<div class="btn-group" ng-show="createAllowedButtonSingle">
<a class="btn" ng-click="createBlank(entityType,listViewAllowedTypes[0].alias)">
<localize key="actions_create">Create</localize> {{listViewAllowedTypes[0].name}}
</a>
</div>
<div class="btn-group" ng-show="createAllowedButtonSingleWithBlueprints">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
<span ng-click="createBlank(entityType,listViewAllowedTypes[0].alias)">
<localize key="actions_create">Create</localize> {{listViewAllowedTypes[0].name}}
</span>
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li ng-repeat="(key, value) in listViewAllowedTypes[0].blueprints">
<a ng-click="createFromBlueprint(entityType, listViewAllowedTypes[0].blueprints.alias, key)">
<i class="{{listViewAllowedTypes[0].icon}}"></i>
{{value}}
</a>
</li>
</ul>
</div>
<div class="btn-group" ng-show="createAllowedButtonMultiWithBlueprints">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
<localize key="actions_create">Create</localize>
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li ng-repeat="contentType in listViewAllowedTypes | orderBy:'name':false">
<a href="#/{{entityType}}/{{entityType}}/edit/{{contentId}}?doctype={{contentType.alias}}&create=true">
<i class="icon-{{contentType.cssClass}}"></i>
{{contentType.name}}
<a ng-click="createBlank(entityType,contentType.alias)">
<i class="{{contentType.icon}}"></i>
{{contentType.name}} <span ng-show="contentType.blueprints && contentType.blueprints.length != 0" style="text-transform: lowercase;">(<localize key="blueprints_blankBlueprint">blank</localize>)</span>
</a>
<a ng-repeat="(key, value) in contentType.blueprints" ng-click="createFromBlueprint(entityType,contentType.alias , key)">
&nbsp;&nbsp;<i class="{{contentType.icon}}"></i>
{{value}}
</a>
</li>
</ul>
</div>
<div class="btn-group" ng-show="listViewAllowedTypes.length === 1">
<a class="btn" href="#/{{entityType}}/{{entityType}}/edit/{{contentId}}?doctype={{listViewAllowedTypes[0].alias}}&create=true">
<i class="icon-{{listViewAllowedTypes[0].cssClass}}"></i>
<localize key="actions_create">Create</localize> {{ listViewAllowedTypes[0].name }}
</a>
</div>
<ul class="umb-actions umb-actions-child">
<li ng-repeat="(key, value) in docType.blueprints | orderBy:'name':false">
<a ng-click="createFromBlueprint(key)">
<i class="large {{docType.icon}}"></i>
<span class="menu-label">
{{value}} Kim
</span>
</a>
</li>
<li class="sep" ng-show="allowBlank">
<a ng-click="createBlank(docType)">
<i class="large {{docType.icon}}"></i>
<span class="menu-label">
<localize key="blueprints_blankBlueprint">Blank</localize>
</span>
</a>
</li>
</ul>
</umb-editor-sub-header-section>
<umb-editor-sub-header-section ng-if="isAnythingSelected()">
<umb-button
type="button"
label="Clear selection"
label-key="buttons_clearSelection"
action="clearSelection()"
disabled="actionInProgress">
<umb-button type="button"
label="Clear selection"
label-key="buttons_clearSelection"
action="clearSelection()"
disabled="actionInProgress">
</umb-button>
</umb-editor-sub-header-section>
@@ -16,7 +16,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
}
function setupViewModel() {
$scope.images = [];
$scope.mediaItems = [];
$scope.ids = [];
$scope.isMultiPicker = multiPicker;
@@ -41,7 +41,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
// on whether it is simply resaved or not.
// This is done by remapping the int/guid ids into a new array of items, where we create "Deleted item" placeholders
// when there is no match for a selected id. This will ensure that the values being set on save, are the same as before.
medias = _.map(ids,
function(id) {
var found = _.find(medias,
@@ -72,7 +72,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
media.thumbnail = mediaHelper.resolveFileFromEntity(media, true);
}
$scope.images.push(media);
$scope.mediaItems.push(media);
if ($scope.model.config.idType === "udi") {
$scope.ids.push(media.udi);
@@ -89,7 +89,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
setupViewModel();
$scope.remove = function(index) {
$scope.images.splice(index, 1);
$scope.mediaItems.splice(index, 1);
$scope.ids.splice(index, 1);
$scope.sync();
};
@@ -117,7 +117,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
media.thumbnail = mediaHelper.resolveFileFromEntity(media, true);
}
$scope.images.push(media);
$scope.mediaItems.push(media);
if ($scope.model.config.idType === "udi") {
$scope.ids.push(media.udi);
@@ -145,7 +145,7 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
// content picker. Then we don't have to worry about setting ids, render models, models, we just set one and let the
// watch do all the rest.
$timeout(function(){
angular.forEach($scope.images, function(value, key) {
angular.forEach($scope.mediaItems, function(value, key) {
r.push($scope.model.config.idType === "udi" ? value.udi : value.id);
});
$scope.ids = r;
@@ -1,31 +1,35 @@
<div class="umb-editor umb-mediapicker" ng-controller="Umbraco.PropertyEditors.MediaPickerController">
<p ng-if="(images|filter:{trashed:true}).length == 1"><localize key="mediaPicker_pickedTrashedItem"></localize></p>
<p ng-if="(images|filter:{trashed:true}).length > 1"><localize key="mediaPicker_pickedTrashedItems"></localize></p>
<div data-element="sortable-thumbnails" class="flex flex-wrap error">
<ul ui-sortable="sortableOptions" ng-model="images" class="umb-sortable-thumbnails">
<li data-element="sortable-thumbnail-{{$index}}" class="umb-sortable-thumbnails__wrapper" ng-repeat="image in images track by $index">
<p ng-if="(mediaItems|filter:{trashed:true}).length == 1"><localize key="mediaPicker_pickedTrashedItem"></localize></p>
<p ng-if="(mediaItems|filter:{trashed:true}).length > 1"><localize key="mediaPicker_pickedTrashedItems"></localize></p>
<div data-element="sortable-thumbnails" class="flex flex-wrap error">
<ul ui-sortable="sortableOptions" ng-model="mediaItems" class="umb-sortable-thumbnails">
<li data-element="sortable-thumbnail-{{$index}}" class="umb-sortable-thumbnails__wrapper" ng-repeat="media in mediaItems track by $index">
<p class="label label__trashed" ng-if="media.trashed">
<localize key="mediaPicker_trashed"></localize>
<i class="icon-trash" aria-hidden="true"></i>
</p>
<span class="label trashed" ng-if="image.trashed"><localize key="mediaPicker_trashed"></localize></span>
<!-- IMAGE -->
<img ng-class="{'trashed': image.trashed}" ng-src="{{image.thumbnail}}" alt="" ng-show="image.thumbnail" title="{{image.trashed ? 'Trashed: ' + image.name : image.name}}" />
<img ng-class="{'trashed': media.trashed}" ng-src="{{media.thumbnail}}" alt="" ng-show="media.thumbnail" title="{{media.trashed ? 'Trashed: ' + media.name : media.name}}" />
<!-- SVG -->
<img ng-class="{'trashed': image.trashed}" ng-if="image.metaData.umbracoExtension.Value === 'svg'" ng-src="{{image.metaData.umbracoFile.Value}}" alt="" title="{{image.trashed ? 'Trashed: ' + image.name : image.name}}" />
<img ng-class="{'trashed': image.trashed}" ng-if="image.extension === 'svg'" ng-src="{{image.file}}" alt="" />
<img ng-class="{'trashed': media.trashed}" ng-if="media.metaData.umbracoExtension.Value === 'svg'" ng-src="{{media.metaData.umbracoFile.Value}}" alt="" title="{{media.trashed ? 'Trashed: ' + media.name : media.name}}" />
<img ng-class="{'trashed': media.trashed}" ng-if="media.extension === 'svg'" ng-src="{{media.file}}" alt="" />
<!-- FILE -->
<span class="umb-icon-holder" ng-hide="image.thumbnail || image.metaData.umbracoExtension.Value === 'svg' || image.extension === 'svg'">
<div ng-class="{'trashed': media.trashed}" class="umb-icon-holder" ng-hide="media.thumbnail || media.metaData.umbracoExtension.Value === 'svg' || media.extension === 'svg'">
<span class="file-icon">
<i class="icon {{image.icon}} large"></i>
<span>.{{image.extension}}</span>
<i class="icon {{media.icon}} large"></i>
<span>.{{media.metaData.umbracoExtension.Value}}</span>
</span>
<small>{{image.name}}</small>
</span>
<small>{{media.name}}</small>
</div>
<div class="umb-sortable-thumbnails__actions" data-element="sortable-thumbnail-actions">
<a class="umb-sortable-thumbnails__action" data-element="action-edit" href="" ng-click="goToItem(image)">
<a class="umb-sortable-thumbnails__action" data-element="action-edit" href="" ng-click="goToItem(media)">
<i class="icon icon-edit"></i>
</a>
<a class="umb-sortable-thumbnails__action -red" data-element="action-remove" href="" ng-click="remove($index)">
@@ -34,7 +38,7 @@
</div>
</li>
<li style="border: none;" class="add-wrapper unsortable" ng-if="showAdd()">
<a data-element="sortable-thumbnails-add" href="#" class="add-link" ng-click="add()" ng-class="{'add-link-square': (images.length === 0 || isMultiPicker)}" prevent-default>
<a data-element="sortable-thumbnails-add" href="#" class="add-link" ng-click="add()" ng-class="{'add-link-square': (mediaItems.length === 0 || isMultiPicker)}" prevent-default>
<i class="icon icon-add large"></i>
</a>
</li>
@@ -1,12 +1,17 @@
<div class="umb-editor umb-radiobuttons" ng-controller="Umbraco.PropertyEditors.RadioButtonsController">
<ul class="unstyled">
<li ng-repeat="item in model.config.items">
<label class="radio">
<label class="radio umb-radiobuttons__label">
<input type="radio" name="radiobuttons-{{model.alias}}"
value="{{item.id}}"
ng-model="model.value" />
{{item.value}}
ng-model="model.value"
class="umb-radiobuttons__input" />
<div class="umb-radiobuttons__state">
<i class="umb-radiobuttons__icon icon-check" aria-hidden="true"></i>
<span class="umb-radiobuttons__label-text">{{item.value}}</span>
</div>
</label>
</li>
</ul>
</div>
</div>
@@ -1304,8 +1304,6 @@ To manage your website, simply open the Umbraco back office and start adding con
</area>
<area alias="imagecropper">
<key alias="reset">Reset crop</key>
<key alias="defineCrop">Define crop</key>
<key alias="defineCropDescription">Give the crop an alias and its default width and height</key>
<key alias="saveCrop">Save crop</key>
<key alias="addCrop">Add new crop</key>
<key alias="updateEditCrop">Done</key>
@@ -1302,8 +1302,6 @@ To manage your website, simply open the Umbraco back office and start adding con
</area>
<area alias="imagecropper">
<key alias="reset">Reset crop</key>
<key alias="defineCrop">Define crop</key>
<key alias="defineCropDescription">Give the crop an alias and its default width and height</key>
<key alias="saveCrop">Save crop</key>
<key alias="addCrop">Add new crop</key>
<key alias="updateEditCrop">Done</key>
@@ -1039,8 +1039,6 @@
</area>
<area alias="imagecropper">
<key alias="reset">Reiniciar</key>
<key alias="defineCrop">Definir corte</key>
<key alias="defineCropDescription">Da al corte un alias y su anchura y altura por defecto</key>
<key alias="saveCrop">Guardar corte</key>
<key alias="addCrop">Añadir nuevo corte</key>
</area>
@@ -1286,7 +1286,6 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à
<area alias="imagecropper">
<key alias="reset">Réinitialiser</key>
<key alias="defineCrop">Définir le recadrage</key>
<key alias="defineCropDescription">Donnez un alias au recadrage ainsi que sa largeur et sa hauteur par défaut</key>
<key alias="saveCrop">Sauvegarder le recadrage</key>
<key alias="addCrop">Ajouter un nouveau recadrage</key>
</area>
@@ -1022,8 +1022,6 @@ Naciśnij przycisk <strong>instaluj</strong>, aby zainstalować bazę danych Umb
</area>
<area alias="imagecropper">
<key alias="reset">Resetuj</key>
<key alias="defineCrop">Zdefiniuj przycięcie</key>
<key alias="defineCropDescription">Ustaw alias dla przycięcia, a także jego domyślną szerokość i długość</key>
<key alias="saveCrop">Zapisz przycięcie</key>
<key alias="addCrop">Dodaj nowe przycięcie</key>
</area>
@@ -879,8 +879,6 @@
</area>
<area alias="imagecropper">
<key alias="reset">Сбросить</key>
<key alias="defineCrop">Задать рамку</key>
<key alias="defineCropDescription">Задайте рамке имя (алиас), а также ширину и высоту по-умолчанию</key>
<key alias="saveCrop">Сохранить рамку</key>
<key alias="addCrop">Добавить новую рамку</key>
</area>
@@ -645,8 +645,6 @@
</area>
<area alias="imagecropper">
<key alias="reset">Återställ</key>
<key alias="defineCrop">Definiera beskräning</key>
<key alias="defineCropDescription">Ge beskärningen ett alias och dess standardbredd och -höjd</key>
<key alias="saveCrop">spara beskärning</key>
<key alias="addCrop">Lägg till ny beskärning</key>
</area>
@@ -999,8 +999,6 @@
</area>
<area alias="imagecropper">
<key alias="reset">Reset</key>
<key alias="defineCrop">Define crop</key>
<key alias="defineCropDescription">Give the crop an alias and its default width and height</key>
<key alias="saveCrop">Save crop</key>
<key alias="addCrop">Add new crop</key>
</area>
@@ -209,20 +209,6 @@ namespace Umbraco.Web.Editors
public DocumentTypeCollectionDisplay PostCreateCollection(int parentId, string collectionName, bool collectionCreateTemplate, string collectionItemName, bool collectionItemCreateTemplate, string collectionIcon, string collectionItemIcon)
{
var storeInContainer = false;
var allowUnderDocType = -1;
// check if it's a folder
if (Services.ContentTypeService.GetContentType(parentId) == null)
{
storeInContainer = true;
} else
{
// if it's not a container, we'll change the parentid to the root,
// and use the parent id as the doc type the collection should be allowed under
allowUnderDocType = parentId;
parentId = -1;
}
// create item doctype
var itemDocType = new ContentType(parentId);
itemDocType.Name = collectionItemName;
@@ -260,20 +246,16 @@ namespace Umbraco.Web.Editors
// save collection doctype
Services.ContentTypeService.Save(collectionDocType);
// test if the parent id exist and then allow the collection underneath
if (storeInContainer == false && allowUnderDocType != -1)
// test if the parent exist and then allow the collection underneath
var parentCt = Services.ContentTypeService.GetContentType(parentId);
if (parentCt != null)
{
var parentCt = Services.ContentTypeService.GetContentType(allowUnderDocType);
if (parentCt != null)
{
var allowedCts = parentCt.AllowedContentTypes.ToList();
allowedCts.Add(new ContentTypeSort(collectionDocType.Id, allowedCts.Count()));
parentCt.AllowedContentTypes = allowedCts;
Services.ContentTypeService.Save(parentCt);
}
var allowedCts = parentCt.AllowedContentTypes.ToList();
allowedCts.Add(new ContentTypeSort(collectionDocType.Id, allowedCts.Count()));
parentCt.AllowedContentTypes = allowedCts;
Services.ContentTypeService.Save(parentCt);
}
return new DocumentTypeCollectionDisplay
{
CollectionId = collectionDocType.Id,
@@ -229,7 +229,7 @@ namespace Umbraco.Web.PropertyEditors
internal class ImageCropperPreValueEditor : PreValueEditor
{
[PreValueField("crops", "Crop sizes", "views/propertyeditors/imagecropper/imagecropper.prevalues.html")]
[PreValueField("crops", "Define crops", "views/propertyeditors/imagecropper/imagecropper.prevalues.html", Description = "Give the crop an alias and it's default width and height")]
public string Crops { get; set; }
}
@@ -169,7 +169,7 @@ namespace Umbraco.Web.Templates
/// </param>
/// <returns></returns>
/// <remarks>
/// To acheive this we temporarily change the output text writer of the current HttpResponse, then
/// To achieve this we temporarily change the output text writer of the current HttpResponse, then
/// execute the controller via the handler which innevitably writes the result to the text writer
/// that has been assigned to the response. Then we change the response textwriter back to the original
/// before continuing .
@@ -30,7 +30,7 @@ namespace umbraco.providers.members
/// <summary>
/// Custom Membership Provider for Umbraco Members (User authentication for Frontend applications NOT umbraco CMS)
/// </summary>
[Obsolete("This has been superceded by Umbraco.Web.Security.Providers.MembersMembershipProvider")]
[Obsolete("This has been superseded by Umbraco.Web.Security.Providers.MembersMembershipProvider")]
public class UmbracoMembershipProvider : UmbracoMembershipProviderBase, IUmbracoMemberTypeMembershipProvider
{
public UmbracoMembershipProvider()
@@ -111,7 +111,7 @@ namespace umbraco.providers.members
/// <exception cref="T:System.ArgumentException">The name of the provider has a length of zero.</exception>
public override void Initialize(string name, NameValueCollection config)
{
// Intialize values from web.config
// Initialize values from web.config
if (config == null) throw new ArgumentNullException("config");
if (string.IsNullOrEmpty(name)) name = Constants.Conventions.Member.UmbracoMemberProviderName;
@@ -189,7 +189,7 @@ namespace umbraco.providers.members
/// </returns>
protected override bool PerformChangePassword(string username, string oldPassword, string newPassword)
{
//NOTE: due to backwards compatibilty reasons, this provider doesn't care about the old password and
//NOTE: due to backwards compatibility reasons, this provider doesn't care about the old password and
// allows simply setting the password manually so we don't really care about the old password.
// This is allowed based on the overridden AllowManuallyChangingPassword option.