no message
This commit is contained in:
@@ -68,7 +68,7 @@ namespace Umbraco.Core.Compose
|
||||
{
|
||||
var httpContext = HttpContext.Current == null ? (HttpContextBase) null : new HttpContextWrapper(HttpContext.Current);
|
||||
var ip = httpContext.GetCurrentRequestIpAddress();
|
||||
if (ip.ToLowerInvariant().StartsWith("unknown")) ip = "";
|
||||
if (ip == null || ip.ToLowerInvariant().StartsWith("unknown")) ip = "";
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,10 @@ namespace Umbraco.Core.Manifest
|
||||
partA = "member";
|
||||
partB = member.ContentType.Alias;
|
||||
break;
|
||||
case IContentType contentType:
|
||||
partA = "contentType";
|
||||
partB = contentType.Alias;
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
|
||||
@@ -2,168 +2,441 @@
|
||||
|
||||
namespace Umbraco.Core.Models.PublishedContent
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an item in an array that stores its own index and the total count.
|
||||
/// </summary>
|
||||
/// <typeparam name="TContent">The type of the content.</typeparam>
|
||||
public class IndexedArrayItem<TContent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IndexedArrayItem{TContent}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="index">The index.</param>
|
||||
public IndexedArrayItem(TContent content, int index)
|
||||
{
|
||||
Content = content;
|
||||
Index = index;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The content.
|
||||
/// </value>
|
||||
public TContent Content { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The index.
|
||||
/// </value>
|
||||
public int Index { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total count.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The total count.
|
||||
/// </value>
|
||||
public int TotalCount { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this item is the first.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this item is the first; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsFirst()
|
||||
{
|
||||
return Index == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is the first, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsFirst(string valueIfTrue)
|
||||
{
|
||||
return IsFirst(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is the first, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsFirst(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsFirst() ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(IsFirst() ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this item is not the first.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this item is not the first; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public bool IsNotFirst()
|
||||
{
|
||||
return IsFirst() == false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is not the first, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsNotFirst(string valueIfTrue)
|
||||
{
|
||||
return IsNotFirst(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is not the first, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsNotFirst(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsNotFirst() ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(IsNotFirst() ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this item is at the specified <paramref name="index" />.
|
||||
/// </summary>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this item is at the specified <paramref name="index" />; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsIndex(int index)
|
||||
{
|
||||
return Index == index;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is at the specified <paramref name="index" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsIndex(int index, string valueIfTrue)
|
||||
{
|
||||
return IsIndex(index, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is at the specified <paramref name="index" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsIndex(int index, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsIndex(index) ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(IsIndex(index) ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this item is at an index that can be divided by the specified <paramref name="modulus" />.
|
||||
/// </summary>
|
||||
/// <param name="modulus">The modulus.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this item is at an index that can be divided by the specified <paramref name="modulus" />; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsModZero(int modulus)
|
||||
{
|
||||
return Index % modulus == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is at an index that can be divided by the specified <paramref name="modulus" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="modulus">The modulus.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsModZero(int modulus, string valueIfTrue)
|
||||
{
|
||||
return IsModZero(modulus, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is at an index that can be divided by the specified <paramref name="modulus" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="modulus">The modulus.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsModZero(int modulus, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsModZero(modulus) ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(IsModZero(modulus) ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this item is not at an index that can be divided by the specified <paramref name="modulus" />.
|
||||
/// </summary>
|
||||
/// <param name="modulus">The modulus.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this item is not at an index that can be divided by the specified <paramref name="modulus" />; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public bool IsNotModZero(int modulus)
|
||||
{
|
||||
return IsModZero(modulus) == false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is not at an index that can be divided by the specified <paramref name="modulus" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="modulus">The modulus.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsNotModZero(int modulus, string valueIfTrue)
|
||||
{
|
||||
return IsNotModZero(modulus, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is not at an index that can be divided by the specified <paramref name="modulus" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="modulus">The modulus.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsNotModZero(int modulus, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsNotModZero(modulus) ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(IsNotModZero(modulus) ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this item is not at the specified <paramref name="index" />.
|
||||
/// </summary>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this item is not at the specified <paramref name="index" />; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public bool IsNotIndex(int index)
|
||||
{
|
||||
return IsIndex(index) == false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is not at the specified <paramref name="index" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsNotIndex(int index, string valueIfTrue)
|
||||
{
|
||||
return IsNotIndex(index, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is at the specified <paramref name="index" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsNotIndex(int index, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsNotIndex(index) ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(IsNotIndex(index) ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this item is the last.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this item is the last; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsLast()
|
||||
{
|
||||
return Index == TotalCount - 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is the last, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsLast(string valueIfTrue)
|
||||
{
|
||||
return IsLast(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is the last, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsLast(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsLast() ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(IsLast() ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this item is not the last.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this item is not the last; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public bool IsNotLast()
|
||||
{
|
||||
return IsLast() == false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is not the last, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsNotLast(string valueIfTrue)
|
||||
{
|
||||
return IsNotLast(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is not the last, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsNotLast(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsNotLast() ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(IsNotLast() ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this item is at an even index.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this item is at an even index; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsEven()
|
||||
{
|
||||
return Index % 2 == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is at an even index, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsEven(string valueIfTrue)
|
||||
{
|
||||
return IsEven(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is at an even index, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsEven(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsEven() ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(IsEven() ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this item is at an odd index.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// <c>true</c> if this item is at an odd index; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsOdd()
|
||||
{
|
||||
return Index % 2 == 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is at an odd index, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsOdd(string valueIfTrue)
|
||||
{
|
||||
return IsOdd(valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this item is at an odd index, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public HtmlString IsOdd(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(IsOdd() ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(IsOdd() ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ a.text-success:focus { color: darken(@successText, 10%); }
|
||||
// Headings
|
||||
// -------------------------
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 {
|
||||
margin: (@baseLineHeight / 2) 0;
|
||||
font-family: @headingsFontFamily;
|
||||
font-weight: @headingsFontWeight;
|
||||
@@ -70,21 +70,21 @@ h1, h2, h3, h4, h5, h6 {
|
||||
}
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3 { line-height: @baseLineHeight * 2; }
|
||||
h1, .h1,
|
||||
h2, .h2,
|
||||
h3, .h3 { line-height: @baseLineHeight * 2; }
|
||||
|
||||
h1 { font-size: @baseFontSize * 2.75; } // ~38px
|
||||
h2 { font-size: @baseFontSize * 2.25; } // ~32px
|
||||
h3 { font-size: @baseFontSize * 1.75; } // ~24px
|
||||
h4 { font-size: @baseFontSize * 1.25; } // ~18px
|
||||
h5 { font-size: @baseFontSize; }
|
||||
h6 { font-size: @baseFontSize * 0.85; } // ~12px
|
||||
h1, .h1 { font-size: @baseFontSize * 2.75; } // ~38px
|
||||
h2, .h2 { font-size: @baseFontSize * 2.25; } // ~32px
|
||||
h3, .h3 { font-size: @baseFontSize * 1.75; } // ~24px
|
||||
h4, .h4 { font-size: @baseFontSize * 1.25; } // ~18px
|
||||
h5, .h5 { font-size: @baseFontSize; }
|
||||
h6, .h6 { font-size: @baseFontSize * 0.85; } // ~12px
|
||||
|
||||
h1 small { font-size: @baseFontSize * 1.75; } // ~24px
|
||||
h2 small { font-size: @baseFontSize * 1.25; } // ~18px
|
||||
h3 small { font-size: @baseFontSize; }
|
||||
h4 small { font-size: @baseFontSize; }
|
||||
h1 small, .h1 small { font-size: @baseFontSize * 1.75; } // ~24px
|
||||
h2 small, .h2 small { font-size: @baseFontSize * 1.25; } // ~18px
|
||||
h3 small, .h3 small { font-size: @baseFontSize; }
|
||||
h4 small, .h4 small { font-size: @baseFontSize; }
|
||||
|
||||
|
||||
// Page header
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ace-builds": "1.4.2",
|
||||
"angular": "1.7.9",
|
||||
"angular": "1.8.0",
|
||||
"angular-animate": "1.7.5",
|
||||
"angular-aria": "1.7.9",
|
||||
"angular-chart.js": "^1.1.1",
|
||||
@@ -32,13 +32,13 @@
|
||||
"diff": "3.5.0",
|
||||
"flatpickr": "4.5.2",
|
||||
"font-awesome": "4.7.0",
|
||||
"jquery": "^3.4.1",
|
||||
"jquery": "^3.5.1",
|
||||
"jquery-ui-dist": "1.12.1",
|
||||
"jquery-ui-touch-punch": "0.2.3",
|
||||
"lazyload-js": "1.0.0",
|
||||
"moment": "2.22.2",
|
||||
"ng-file-upload": "12.2.13",
|
||||
"nouislider": "14.1.1",
|
||||
"nouislider": "14.4.0",
|
||||
"npm": "^6.14.0",
|
||||
"signalr": "2.4.0",
|
||||
"spectrum-colorpicker": "1.8.0",
|
||||
|
||||
+1
-2
@@ -1,5 +1,5 @@
|
||||
angular.module("umbraco.directives")
|
||||
.directive('umbContextMenu', function (navigationService, keyboardService) {
|
||||
.directive('umbContextMenu', function (navigationService, keyboardService, backdropService) {
|
||||
return {
|
||||
scope: {
|
||||
menuDialogTitle: "@",
|
||||
@@ -30,7 +30,6 @@ angular.module("umbraco.directives")
|
||||
scope.$on('$destroy', function () {
|
||||
keyboardService.unbind("esc");
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
+1
@@ -274,6 +274,7 @@
|
||||
vm.showEmailResetConfirmation = false;
|
||||
|
||||
if (vm.requestPasswordResetForm.$invalid) {
|
||||
vm.errorMsg = 'Email address cannot be empty';
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ You can easily add you own tours to the Help-drawer or show and start tours from
|
||||
anywhere in the Umbraco backoffice. To see a real world example of a custom tour implementation, install <a href="https://our.umbraco.com/projects/starter-kits/the-starter-kit/">The Starter Kit</a> in Umbraco 7.8
|
||||
|
||||
<h1><b>Extending the help drawer with custom tours</b></h1>
|
||||
The easiet way to add new tours to Umbraco is through the Help-drawer. All it requires is a my-tour.json file.
|
||||
The easiet way to add new tours to Umbraco is through the Help-drawer. All it requires is a my-tour.json file.
|
||||
Place the file in <i>App_Plugins/{MyPackage}/backoffice/tours/{my-tour}.json</i> and it will automatically be
|
||||
picked up by Umbraco and shown in the Help-drawer.
|
||||
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ Use this directive to render an umbraco button. The directive can be used to gen
|
||||
alias: "@?",
|
||||
addEllipsis: "@?",
|
||||
showCaret: "@?",
|
||||
autoFocus: "@?",
|
||||
autoFocus: "<?",
|
||||
hasPopup: "@?",
|
||||
isExpanded: "<?"
|
||||
}
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
var title = data[2] + ": ";
|
||||
if (!scope.isNew) {
|
||||
scope.a11yMessage += " " + scope.editor.content.name;
|
||||
title += scope.content.name;
|
||||
title += scope.editor.content.name;
|
||||
} else {
|
||||
var name = editorState.current.contentTypeName;
|
||||
scope.a11yMessage += " " + name;
|
||||
|
||||
+20
-5
@@ -7,11 +7,12 @@
|
||||
|
||||
var evts = [];
|
||||
var allowedNumberOfVisibleEditors = 3;
|
||||
|
||||
var aboveBackDropCssClass = 'above-backdrop';
|
||||
var sectionId = '#leftcolumn';
|
||||
var isLeftColumnAbove = false;
|
||||
scope.editors = [];
|
||||
|
||||
function addEditor(editor) {
|
||||
|
||||
editor.inFront = true;
|
||||
editor.moveRight = true;
|
||||
editor.level = 0;
|
||||
@@ -19,6 +20,14 @@
|
||||
|
||||
// push the new editor to the dom
|
||||
scope.editors.push(editor);
|
||||
|
||||
if(scope.editors.length === 1){
|
||||
isLeftColumnAbove = $(sectionId).hasClass(aboveBackDropCssClass);
|
||||
|
||||
if(isLeftColumnAbove){
|
||||
$(sectionId).removeClass(aboveBackDropCssClass);
|
||||
}
|
||||
}
|
||||
|
||||
$timeout(() => {
|
||||
editor.moveRight = false;
|
||||
@@ -32,14 +41,20 @@
|
||||
}
|
||||
|
||||
function removeEditor(editor) {
|
||||
|
||||
editor.moveRight = true;
|
||||
|
||||
editor.animating = true;
|
||||
setTimeout(removeEditorFromDOM.bind(this, editor), 400);
|
||||
|
||||
updateEditors(-1);
|
||||
|
||||
|
||||
if(scope.editors.length === 1){
|
||||
if(isLeftColumnAbove){
|
||||
$('#leftcolumn').addClass(aboveBackDropCssClass);
|
||||
}
|
||||
|
||||
isLeftColumnAbove = false;
|
||||
}
|
||||
}
|
||||
|
||||
function revealEditorContent(editor) {
|
||||
@@ -57,7 +72,7 @@
|
||||
if (index !== -1) {
|
||||
scope.editors.splice(index, 1);
|
||||
}
|
||||
|
||||
|
||||
updateEditors();
|
||||
|
||||
scope.$digest();
|
||||
|
||||
+9
-2
@@ -33,8 +33,15 @@ function umbPropEditor(umbPropEditorHelper) {
|
||||
scope.model.alias = Math.random().toString(36).slice(2);
|
||||
}
|
||||
|
||||
scope.propertyEditorView = umbPropEditorHelper.getViewPath(scope.model.view, scope.isPreValue);
|
||||
|
||||
var unbindWatcher = scope.$watch("model.view",
|
||||
function() {
|
||||
scope.propertyEditorView = umbPropEditorHelper.getViewPath(scope.model.view, scope.isPreValue);
|
||||
}
|
||||
);
|
||||
|
||||
scope.$on("$destroy", function () {
|
||||
unbindWatcher();
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
+2
-1
@@ -1,7 +1,7 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
function UmbContextDialog(navigationService, keyboardService, localizationService, overlayService) {
|
||||
function UmbContextDialog(navigationService, keyboardService, localizationService, overlayService, backdropService) {
|
||||
|
||||
function link($scope) {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
});
|
||||
|
||||
function hide() {
|
||||
|
||||
if ($scope.dialog.confirmDiscardChanges) {
|
||||
localizationService.localizeMany(["prompt_unsavedChanges", "prompt_unsavedChangesWarning", "prompt_discardChanges", "prompt_stay"]).then(
|
||||
function (values) {
|
||||
|
||||
+15
-1
@@ -3,7 +3,7 @@
|
||||
* @name umbraco.directives.directive:umbTree
|
||||
* @restrict E
|
||||
**/
|
||||
function umbTreeDirective($q, $rootScope, treeService, notificationsService, userService) {
|
||||
function umbTreeDirective($q, $rootScope, treeService, notificationsService, userService, backdropService) {
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
@@ -319,6 +319,18 @@ function umbTreeDirective($q, $rootScope, treeService, notificationsService, use
|
||||
}
|
||||
}
|
||||
|
||||
// Close any potential backdrop and remove the #leftcolumn modifier class
|
||||
function closeBackdrop() {
|
||||
var aboveClass = 'above-backdrop';
|
||||
var leftColumn = $('#leftcolumn');
|
||||
var isLeftColumnOnTop = leftColumn.hasClass(aboveClass);
|
||||
|
||||
if(isLeftColumnOnTop){
|
||||
backdropService.close();
|
||||
leftColumn.removeClass(aboveClass);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the css classses assigned to the node (div element) */
|
||||
$scope.getNodeCssClass = function (node) {
|
||||
if (!node) {
|
||||
@@ -368,6 +380,8 @@ function umbTreeDirective($q, $rootScope, treeService, notificationsService, use
|
||||
*/
|
||||
$scope.select = function (n, ev) {
|
||||
|
||||
closeBackdrop()
|
||||
|
||||
if (n.metaData && n.metaData.noAccess === true) {
|
||||
ev.preventDefault();
|
||||
return;
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
</example>
|
||||
*/
|
||||
angular.module("umbraco.directives")
|
||||
.directive('umbTreeItem', function(treeService, $timeout, localizationService, eventsService, appState) {
|
||||
.directive('umbTreeItem', function(treeService, $timeout, localizationService, eventsService, appState, navigationService) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
|
||||
+8
-6
@@ -12,16 +12,18 @@
|
||||
|
||||
/* ---------- INIT ---------- */
|
||||
|
||||
const setDataType = (dataType) => {
|
||||
scope.dataType = dataType;
|
||||
listViewPrevalueHelper.setPrevalues(dataType.preValues);
|
||||
}
|
||||
|
||||
const activate = () => {
|
||||
|
||||
if (scope.enableListView) {
|
||||
|
||||
dataTypeResource.getByName(scope.listViewName)
|
||||
.then(dataType => {
|
||||
|
||||
scope.dataType = dataType;
|
||||
|
||||
listViewPrevalueHelper.setPrevalues(dataType.preValues);
|
||||
setDataType(dataType);
|
||||
scope.customListViewCreated = checkForCustomListView();
|
||||
});
|
||||
|
||||
@@ -64,7 +66,7 @@
|
||||
dataTypeResource.createCustomListView(scope.modelAlias).then(dataType => {
|
||||
|
||||
// store data type
|
||||
scope.dataType = dataType;
|
||||
setDataType(dataType);
|
||||
|
||||
// set list view name on scope
|
||||
scope.listViewName = dataType.name;
|
||||
@@ -95,7 +97,7 @@
|
||||
.then(defaultDataType => {
|
||||
|
||||
// store data type
|
||||
scope.dataType = defaultDataType;
|
||||
setDataType(defaultDataType);
|
||||
|
||||
// change state to default list view
|
||||
scope.customListViewCreated = false;
|
||||
|
||||
+87
@@ -118,6 +118,8 @@ For extra details about options and events take a look here: https://refreshless
|
||||
// create new slider
|
||||
noUiSlider.create(sliderInstance, options);
|
||||
|
||||
mergeTooltips(sliderInstance, 15, ' - ');
|
||||
|
||||
if (ctrl.onSetup) {
|
||||
ctrl.onSetup({
|
||||
slider: sliderInstance
|
||||
@@ -200,6 +202,91 @@ For extra details about options and events take a look here: https://refreshless
|
||||
}
|
||||
}
|
||||
|
||||
// Merging overlapping tooltips: https://refreshless.com/nouislider/examples/#section-merging-tooltips
|
||||
|
||||
/**
|
||||
* @param slider HtmlElement with an initialized slider
|
||||
* @param threshold Minimum proximity (in percentages) to merge tooltips
|
||||
* @param separator String joining tooltips
|
||||
*/
|
||||
function mergeTooltips(slider, threshold, separator) {
|
||||
|
||||
var textIsRtl = getComputedStyle(slider).direction === 'rtl';
|
||||
var isRtl = slider.noUiSlider.options.direction === 'rtl';
|
||||
var isVertical = slider.noUiSlider.options.orientation === 'vertical';
|
||||
var tooltips = slider.noUiSlider.getTooltips();
|
||||
var origins = slider.noUiSlider.getOrigins();
|
||||
|
||||
// Move tooltips into the origin element. The default stylesheet handles this.
|
||||
tooltips.forEach(function (tooltip, index) {
|
||||
if (tooltip) {
|
||||
origins[index].appendChild(tooltip);
|
||||
}
|
||||
});
|
||||
|
||||
slider.noUiSlider.on('update', function (values, handle, unencoded, tap, positions) {
|
||||
|
||||
var pools = [[]];
|
||||
var poolPositions = [[]];
|
||||
var poolValues = [[]];
|
||||
var atPool = 0;
|
||||
|
||||
// Assign the first tooltip to the first pool, if the tooltip is configured
|
||||
if (tooltips[0]) {
|
||||
pools[0][0] = 0;
|
||||
poolPositions[0][0] = positions[0];
|
||||
poolValues[0][0] = values[0];
|
||||
}
|
||||
|
||||
for (var i = 1; i < positions.length; i++) {
|
||||
if (!tooltips[i] || (positions[i] - positions[i - 1]) > threshold) {
|
||||
atPool++;
|
||||
pools[atPool] = [];
|
||||
poolValues[atPool] = [];
|
||||
poolPositions[atPool] = [];
|
||||
}
|
||||
|
||||
if (tooltips[i]) {
|
||||
pools[atPool].push(i);
|
||||
poolValues[atPool].push(values[i]);
|
||||
poolPositions[atPool].push(positions[i]);
|
||||
}
|
||||
}
|
||||
|
||||
pools.forEach(function (pool, poolIndex) {
|
||||
var handlesInPool = pool.length;
|
||||
|
||||
for (var j = 0; j < handlesInPool; j++) {
|
||||
var handleNumber = pool[j];
|
||||
|
||||
if (j === handlesInPool - 1) {
|
||||
var offset = 0;
|
||||
|
||||
poolPositions[poolIndex].forEach(function (value) {
|
||||
offset += 1000 - 10 * value;
|
||||
});
|
||||
|
||||
var direction = isVertical ? 'bottom' : 'right';
|
||||
var last = isRtl ? 0 : handlesInPool - 1;
|
||||
var lastOffset = 1000 - 10 * poolPositions[poolIndex][last];
|
||||
offset = (textIsRtl && !isVertical ? 100 : 0) + (offset / handlesInPool) - lastOffset;
|
||||
|
||||
// Filter to unique values
|
||||
var tooltipValues = poolValues[poolIndex].filter((v, i, a) => a.indexOf(v) === i);
|
||||
|
||||
// Center this tooltip over the affected handles
|
||||
tooltips[handleNumber].innerHTML = tooltipValues.join(separator);
|
||||
tooltips[handleNumber].style.display = 'block';
|
||||
tooltips[handleNumber].style[direction] = offset + '%';
|
||||
} else {
|
||||
// Hide this tooltip
|
||||
tooltips[handleNumber].style.display = 'none';
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
angular.module('umbraco.directives').component('umbRangeSlider', umbRangeSlider);
|
||||
|
||||
+23
-20
@@ -20,7 +20,7 @@ TODO
|
||||
|
||||
angular.module("umbraco.directives")
|
||||
.directive('umbFileDropzone',
|
||||
function($timeout, Upload, localizationService, umbRequestHelper) {
|
||||
function ($timeout, Upload, localizationService, umbRequestHelper, overlayService) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
@@ -119,9 +119,8 @@ angular.module("umbraco.directives")
|
||||
//auto-clear the done queue after 3 secs
|
||||
var currentLength = scope.done.length;
|
||||
$timeout(function() {
|
||||
scope.done.splice(0, currentLength);
|
||||
},
|
||||
3000);
|
||||
scope.done.splice(0, currentLength);
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,30 +196,34 @@ angular.module("umbraco.directives")
|
||||
}
|
||||
|
||||
function _chooseMediaType() {
|
||||
scope.mediatypepickerOverlay = {
|
||||
view: "mediatypepicker",
|
||||
title: "Choose media type",
|
||||
acceptedMediatypes: scope.acceptedMediatypes,
|
||||
hideSubmitButton: true,
|
||||
show: true,
|
||||
submit: function(model) {
|
||||
scope.contentTypeAlias = model.selectedType.alias;
|
||||
scope.mediatypepickerOverlay.show = false;
|
||||
scope.mediatypepickerOverlay = null;
|
||||
_processQueueItem();
|
||||
},
|
||||
close: function(oldModel) {
|
||||
|
||||
scope.queue.map(function(file) {
|
||||
const dialog = {
|
||||
view: "itempicker",
|
||||
filter: scope.acceptedMediatypes.length > 15,
|
||||
availableItems: scope.acceptedMediatypes,
|
||||
submit: function (model) {
|
||||
scope.contentTypeAlias = model.selectedItem.alias;
|
||||
_processQueueItem();
|
||||
|
||||
overlayService.close();
|
||||
},
|
||||
close: function () {
|
||||
|
||||
scope.queue.map(function (file) {
|
||||
file.uploadStatus = "error";
|
||||
file.serverErrorMessage = "Cannot upload this file, no mediatype selected";
|
||||
scope.rejected.push(file);
|
||||
});
|
||||
scope.queue = [];
|
||||
scope.mediatypepickerOverlay.show = false;
|
||||
scope.mediatypepickerOverlay = null;
|
||||
|
||||
overlayService.close();
|
||||
}
|
||||
};
|
||||
|
||||
localizationService.localize("defaultdialogs_selectMediaType").then(value => {
|
||||
dialog.title = value;
|
||||
overlayService.open(dialog);
|
||||
});
|
||||
}
|
||||
|
||||
scope.handleFiles = function(files, event) {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* Section navigation and search, and maintain their state for the entire application lifetime
|
||||
*
|
||||
*/
|
||||
function navigationService($routeParams, $location, $q, $injector, eventsService, umbModelMapper, treeService, appState) {
|
||||
function navigationService($routeParams, $location, $q, $injector, eventsService, umbModelMapper, treeService, appState, backdropService) {
|
||||
|
||||
//the promise that will be resolved when the navigation is ready
|
||||
var navReadyPromise = $q.defer();
|
||||
@@ -26,7 +26,10 @@ function navigationService($routeParams, $location, $q, $injector, eventsService
|
||||
navReadyPromise.resolve(mainTreeApi);
|
||||
});
|
||||
|
||||
|
||||
eventsService.on('appState.backdrop', function(e, args){
|
||||
var element = $(args.element);
|
||||
element.addClass('above-backdrop');
|
||||
});
|
||||
|
||||
//A list of query strings defined that when changed will not cause a reload of the route
|
||||
var nonRoutingQueryStrings = ["mculture", "cculture", "csegment", "lq", "sr"];
|
||||
@@ -113,6 +116,17 @@ function navigationService($routeParams, $location, $q, $injector, eventsService
|
||||
}
|
||||
}
|
||||
|
||||
function closeBackdrop() {
|
||||
var aboveClass = 'above-backdrop';
|
||||
var leftColumn = $('#leftcolumn');
|
||||
var isLeftColumnOnTop = leftColumn.hasClass(aboveClass);
|
||||
|
||||
if(isLeftColumnOnTop){
|
||||
backdropService.close();
|
||||
leftColumn.removeClass(aboveClass);
|
||||
}
|
||||
}
|
||||
|
||||
var service = {
|
||||
|
||||
/**
|
||||
@@ -410,12 +424,15 @@ function navigationService($routeParams, $location, $q, $injector, eventsService
|
||||
* @param {Event} event the click event triggering the method, passed from the DOM element
|
||||
*/
|
||||
showMenu: function (args) {
|
||||
|
||||
var self = this;
|
||||
|
||||
var backDropOptions = {
|
||||
'element': $('#leftcolumn')[0]
|
||||
};
|
||||
|
||||
return treeService.getMenu({ treeNode: args.node })
|
||||
.then(function (data) {
|
||||
|
||||
backdropService.open(backDropOptions);
|
||||
//check for a default
|
||||
//NOTE: event will be undefined when a call to hideDialog is made so it won't re-load the default again.
|
||||
// but perhaps there's a better way to deal with with an additional parameter in the args ? it works though.
|
||||
@@ -466,6 +483,7 @@ function navigationService($routeParams, $location, $q, $injector, eventsService
|
||||
appState.setMenuState("currentNode", null);
|
||||
appState.setMenuState("menuActions", []);
|
||||
setMode("tree");
|
||||
closeBackdrop();
|
||||
},
|
||||
|
||||
/** Executes a given menu action */
|
||||
@@ -650,6 +668,7 @@ function navigationService($routeParams, $location, $q, $injector, eventsService
|
||||
if (showMenu) {
|
||||
this.showMenu({ skipDefault: true, node: appState.getMenuState("currentNode") });
|
||||
} else {
|
||||
closeBackdrop();
|
||||
setMode("default");
|
||||
}
|
||||
},
|
||||
@@ -685,6 +704,7 @@ function navigationService($routeParams, $location, $q, $injector, eventsService
|
||||
*/
|
||||
hideNavigation: function () {
|
||||
appState.setMenuState("menuActions", []);
|
||||
closeBackdrop();
|
||||
setMode("default");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -133,7 +133,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
else if (rule.selector[0] !== "." && rule.selector.indexOf(".") > -1) {
|
||||
var split = rule.selector.split(".");
|
||||
r.block = split[0];
|
||||
r.classes = rule.selector.substring(rule.selector.indexOf(".") + 1).replace(".", " ");
|
||||
r.classes = rule.selector.substring(rule.selector.indexOf(".") + 1).replace(/\./g, " ");
|
||||
}
|
||||
else if (rule.selector[0] != "#" && rule.selector.indexOf("#") > -1) {
|
||||
var split = rule.selector.split("#");
|
||||
|
||||
@@ -80,6 +80,10 @@ body.umb-drawer-is-visible #mainwrapper{
|
||||
float: left;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
||||
&.above-backdrop{
|
||||
z-index: 7501;
|
||||
}
|
||||
}
|
||||
|
||||
#navigation {
|
||||
|
||||
@@ -527,7 +527,6 @@ input.umb-group-builder__group-sort-value {
|
||||
text-align: left;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: calc(100% - 48px);
|
||||
min-height: 80px;
|
||||
color: @ui-action-discreet-type;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.umb-property-file-upload {
|
||||
.umb-property-editor--limit-width();
|
||||
|
||||
.umb-upload-button-big {
|
||||
max-width: (@propertyEditorLimitedWidth - 40);
|
||||
display: block;
|
||||
padding: 20px;
|
||||
opacity: 1;
|
||||
|
||||
@@ -26,19 +26,29 @@
|
||||
color: @gray-7;
|
||||
}
|
||||
|
||||
h5{
|
||||
h5, .h5{
|
||||
color: @gray-1;
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
h5.-border-bottom {
|
||||
h1.-border-bottom,
|
||||
h2.-border-bottom,
|
||||
h3.-border-bottom,
|
||||
h4.-border-bottom,
|
||||
h5.-border-bottom,
|
||||
h6.-border-bottom {
|
||||
border-bottom: 1px solid @gray-9;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
h5.-black {
|
||||
h1.-black,
|
||||
h2.-black,
|
||||
h3.-black,
|
||||
h4.-black,
|
||||
h5.-black,
|
||||
h6.-black {
|
||||
color: @black;
|
||||
}
|
||||
|
||||
@@ -200,10 +210,16 @@ h5.-black {
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-editor--infiniteMode .umb-control-group .control-header {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.form-horizontal .umb-control-group .control-header {
|
||||
float: left;
|
||||
width: 160px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 0;
|
||||
text-align: left;
|
||||
|
||||
.control-label {
|
||||
@@ -347,10 +363,16 @@ label:not([for]) {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
table thead a {
|
||||
table thead a,
|
||||
table thead button {
|
||||
color: @gray-2;
|
||||
}
|
||||
|
||||
table thead button:hover,
|
||||
table thead button:focus{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* UI interactions */
|
||||
|
||||
.umb-table tbody.ui-sortable tr
|
||||
|
||||
@@ -448,9 +448,11 @@
|
||||
}
|
||||
|
||||
// in these cases the gradient won't cover the background, so we override
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: @textColorHover;
|
||||
background-color: @hoverColor;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.disabled, &[disabled] {
|
||||
|
||||
@@ -729,6 +729,7 @@
|
||||
// --------------------------------------------------
|
||||
.umb-fileupload {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.umb-fileupload .preview {
|
||||
|
||||
+9
-10
@@ -18,29 +18,28 @@
|
||||
<umb-load-indicator ng-if="vm.loading"></umb-load-indicator>
|
||||
|
||||
<div ng-if="!vm.loading">
|
||||
<a href="" tabindex="0" umb-auto-focus></a>
|
||||
<ul class="umb-card-grid -three-in-row">
|
||||
<li ng-repeat="dataTypeConfig in vm.configs | orderBy:'name'"
|
||||
<li ng-repeat="dataTypeConfig in vm.configs | orderBy:'name' track by $index"
|
||||
data-element="datatypeconfig-{{dataTypeConfig.name}}">
|
||||
<div ng-if="dataTypeConfig.loading" class="umb-card-grid-item__loading">
|
||||
<div class="umb-button__progress"></div>
|
||||
</div>
|
||||
<a class="umb-card-grid-item" href="" ng-click="vm.pickDataType(dataTypeConfig)" title="{{ dataTypeConfig.name }}">
|
||||
<button umb-auto-focus="{{$index === 0}}" class="btn-reset umb-card-grid-item" type="button" ng-click="vm.pickDataType(dataTypeConfig)" title="Select {{ dataTypeConfig.name }}">
|
||||
<span>
|
||||
<i class="{{ dataTypeConfig.icon }}" ng-class="{'icon-autofill': dataTypeConfig.icon == null}"></i>
|
||||
{{ dataTypeConfig.name }}
|
||||
<i class="{{ dataTypeConfig.icon }}" ng-class="{'icon-autofill': dataTypeConfig.icon == null}" aria-hidden="true"></i>
|
||||
<span class="sr-only">Select</span> {{ dataTypeConfig.name }}
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="umb-card-grid -three-in-row">
|
||||
<li>
|
||||
<a class="umb-card-grid-item-slot" href="" ng-click="vm.newDataType()" title="Create a new configuration of {{ model.editor.name }}">
|
||||
<button umb-auto-focus="{{vm.configs.length === 0}}" class="btn-reset umb-card-grid-item-slot" type="button" ng-click="vm.newDataType()" title="Create a new configuration of {{ model.editor.name }}">
|
||||
<span>
|
||||
<i class="icon icon-add"></i>
|
||||
Create new
|
||||
<i class="icon icon-add" aria-hidden="true"></i>
|
||||
Create new <span class="sr-only">configuration of {{ model.editor.name }}</span>
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
+31
-16
@@ -34,16 +34,19 @@
|
||||
|
||||
<div ng-if="vm.loading === false && vm.showDataTypes === true">
|
||||
<div ng-repeat="(key,value) in vm.dataTypes">
|
||||
<h5>{{key | umbCmsTitleCase}}</h5>
|
||||
<h2 class="h5">{{key | umbCmsTitleCase}}</h2>
|
||||
<ul class="umb-card-grid -six-in-row">
|
||||
<li ng-repeat="dataType in value | orderBy:'name'"
|
||||
data-element="datatype-{{dataType.name}}">
|
||||
<a class="umb-card-grid-item" href="" ng-click="vm.viewOptionsForEditor(dataType)" title="{{ dataType.name }}">
|
||||
<li ng-repeat="dataType in value | orderBy:'name'" data-element="datatype-{{dataType.name}}">
|
||||
<button
|
||||
type="button"
|
||||
class="btn-reset umb-card-grid-item"
|
||||
ng-click="vm.viewOptionsForEditor(dataType)"
|
||||
title="{{ dataType.name }}">
|
||||
<span>
|
||||
<i class="{{ dataType.icon }}" ng-class="{'icon-autofill': dataType.icon == null}"></i>
|
||||
<i class="{{ dataType.icon }}" ng-class="{'icon-autofill': dataType.icon == null}" aria-hidden="true"></i>
|
||||
{{ dataType.name }}
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -51,38 +54,50 @@
|
||||
|
||||
<!-- SEARCH RESULTS -->
|
||||
<div ng-if="vm.loading === false && vm.showDataTypes === false && vm.searchResult !== null">
|
||||
<h5 class="-border-bottom -black"><localize key="contentTypeEditor_searchResultSettings"></localize></h5>
|
||||
<h2 class="h5 -border-bottom -black">
|
||||
<localize key="contentTypeEditor_searchResultSettings">Available configurations</localize>
|
||||
</h2>
|
||||
<div ng-repeat="result in vm.searchResult.configs">
|
||||
<div ng-if="result.entries.length > 0">
|
||||
<h5>{{result.group | umbCmsTitleCase}}</h5>
|
||||
<h3 class="h5">{{result.group | umbCmsTitleCase}}</h3>
|
||||
<ul class="umb-card-grid -six-in-row">
|
||||
<li ng-repeat="dataType in result.entries | orderBy:'name'"
|
||||
ng-mouseover="vm.showDetailsOverlay(dataType)">
|
||||
<div ng-if="dataType.loading" class="umb-card-grid-item__loading">
|
||||
<div class="umb-button__progress"></div>
|
||||
</div>
|
||||
<a class="umb-card-grid-item" href="" ng-click="vm.pickDataType(dataType)" title="{{ dataType.name }}">
|
||||
<button
|
||||
type="button"
|
||||
class="btn-reset umb-card-grid-item"
|
||||
ng-click="vm.pickDataType(dataType)"
|
||||
title="{{ dataType.name }}">
|
||||
<span>
|
||||
<i class="{{ dataType.icon }}" ng-class="{'icon-autofill': dataType.icon == null}"></i>
|
||||
<i class="{{ dataType.icon }}" ng-class="{'icon-autofill': dataType.icon == null}" aria-hidden="true"></i>
|
||||
{{ dataType.name }}
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<h5 class="-border-bottom -black"><localize key="contentTypeEditor_searchResultEditors"></localize></h5>
|
||||
<h2 class="h5 -border-bottom -black">
|
||||
<localize key="contentTypeEditor_searchResultEditors">Create a new configuration</localize>
|
||||
</h2>
|
||||
<div ng-repeat="result in vm.searchResult.dataTypes">
|
||||
<div ng-if="result.entries.length > 0">
|
||||
<h5>{{result.group | umbCmsTitleCase}}</h5>
|
||||
<h3 class="h5">{{result.group | umbCmsTitleCase}}</h3>
|
||||
<ul class="umb-card-grid -six-in-row">
|
||||
<li ng-repeat="dataType in result.entries | orderBy:'name'">
|
||||
<a class="umb-card-grid-item" href="" ng-click="vm.pickEditor(dataType)" title="{{ dataType.name }}">
|
||||
<button
|
||||
type="button"
|
||||
class="btn-reset umb-card-grid-item"
|
||||
ng-click="vm.pickEditor(dataType)"
|
||||
title="{{ dataType.name }}">
|
||||
<span>
|
||||
<i class="{{ dataType.icon }}" ng-class="{'icon-autofill': dataType.icon == null}"></i>
|
||||
<i class="{{ dataType.icon }}" ng-class="{'icon-autofill': dataType.icon == null}" aria-hidden="true"></i>
|
||||
{{ dataType.name }}
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
+1
@@ -22,6 +22,7 @@ function MacroPickerController($scope, entityResource, macroResource, umbPropEdi
|
||||
if ($scope.wizardStep === "macroSelect") {
|
||||
editParams(true);
|
||||
} else {
|
||||
$scope.$broadcast("formSubmitting", { scope: $scope });
|
||||
$scope.model.submit($scope.model);
|
||||
}
|
||||
};
|
||||
|
||||
+11
-15
@@ -20,15 +20,14 @@
|
||||
<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"
|
||||
<input type="text"
|
||||
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
|
||||
/>
|
||||
no-dirty-check />
|
||||
|
||||
<div class="form-search__toggle">
|
||||
<umb-checkbox
|
||||
@@ -56,17 +55,15 @@
|
||||
<div class="row umb-control-group" ng-show="!vm.searchOptions.filter">
|
||||
<ul class="umb-breadcrumbs">
|
||||
<li ng-hide="startNodeId != -1" class="umb-breadcrumbs__ancestor">
|
||||
<button type="button" class="umb-breadcrumbs__action umb-outline umb-outline--surronding" ng-click="vm.gotoFolder()" ng-class="{'--current':path.length === 0}">
|
||||
<localize key="treeHeaders_media">Media</localize>
|
||||
</button>
|
||||
<span class="umb-breadcrumbs__separator" aria-hidden="true">/</span>
|
||||
<button type="button" class="umb-breadcrumbs__action umb-outline umb-outline--surronding" ng-click="vm.gotoFolder()" ng-class="{'--current':path.length === 0}">
|
||||
<localize key="treeHeaders_media">Media</localize>
|
||||
</button>
|
||||
<span class="umb-breadcrumbs__separator" aria-hidden="true">/</span>
|
||||
</li>
|
||||
|
||||
<li ng-repeat="item in path" class="umb-breadcrumbs__ancestor">
|
||||
<button type="button" class="umb-breadcrumbs__action umb-outline umb-outline--surronding" ng-click="vm.gotoFolder(item)" ng-class="{'--current':$last}">{{item.name}}</button>
|
||||
<span class="umb-breadcrumbs__separator" aria-hidden="true">/</span>
|
||||
<button type="button" class="umb-breadcrumbs__action umb-outline umb-outline--surronding" ng-click="vm.gotoFolder(item)" ng-class="{'--current':$last}">{{item.name}}</button>
|
||||
<span class="umb-breadcrumbs__separator" aria-hidden="true">/</span>
|
||||
</li>
|
||||
|
||||
<li class="umb-breadcrumbs__ancestor" ng-show="!lockedFolder">
|
||||
<button type="button" class="umb-breadcrumbs__action umb-outline umb-outline--surronding" ng-hide="model.showFolderInput" ng-click="model.showFolderInput = true">
|
||||
<i class="icon icon-add small" aria-hidden="true"></i>
|
||||
@@ -81,11 +78,10 @@
|
||||
ng-model="model.newFolderName"
|
||||
ng-keydown="enterSubmitFolder($event)"
|
||||
ng-blur="vm.submitFolder()"
|
||||
focus-when="{{model.showFolderInput}}"
|
||||
/>
|
||||
focus-when="{{model.showFolderInput}}" />
|
||||
</li>
|
||||
</ul>
|
||||
<div class="umb-loader" ng-if="model.creatingFolder"></div>
|
||||
<umb-loader ng-if="model.creatingFolder"></umb-loader>
|
||||
</div>
|
||||
|
||||
<umb-file-dropzone
|
||||
|
||||
+10
-16
@@ -54,34 +54,32 @@
|
||||
|
||||
<div class="editor-wrapper umb-control-group control-group" ng-model="model.property.editor" val-require-component ng-if="!model.property.locked">
|
||||
|
||||
<a data-element="editor-add" href="" ng-if="!model.property.editor" class="editor-placeholder" hotkey="alt+shift+e" ng-click="vm.openDataTypePicker(model.property)">
|
||||
<button type="button" class="btn-reset editor-placeholder" data-element="editor-add" ng-if="!model.property.editor" hotkey="alt+shift+e" ng-click="vm.openDataTypePicker(model.property)">
|
||||
<localize key="defaultdialogs_selectEditor"></localize>
|
||||
<div ng-messages="model.property.editor" show-validation-on-submit>
|
||||
<span class="umb-validation-label" ng-message="required">Required editor</span>
|
||||
</div>
|
||||
</a>
|
||||
</button>
|
||||
|
||||
<div class="editor clearfix" ng-if="model.property.editor">
|
||||
|
||||
<button class="btn-reset editor-info" ng-click="vm.openDataTypeSettings(model.property)">
|
||||
<button type="button" class="btn-reset editor-info" ng-click="vm.openDataTypeSettings(model.property)">
|
||||
<div class="editor-icon-wrapper">
|
||||
<i class="icon {{ model.property.dataTypeIcon }}" ng-class="{'icon-autofill': model.property.dataTypeIcon == null}"></i>
|
||||
<i class="icon {{ model.property.dataTypeIcon }}" ng-class="{'icon-autofill': model.property.dataTypeIcon == null}" aria-hidden="true"></i>
|
||||
</div>
|
||||
|
||||
<div class="editor-details">
|
||||
<span class="editor-name">{{ model.property.dataTypeName }}</span>
|
||||
<span class="editor-editor">{{ model.property.editor }}</span>
|
||||
</div>
|
||||
|
||||
</button>
|
||||
|
||||
<button class="editor-remove-icon btn-reset pull-right"
|
||||
<button type="button" class="editor-remove-icon btn-reset pull-right"
|
||||
ng-click="vm.openDataTypePicker(model.property)"
|
||||
hotkey="alt+shift+d"
|
||||
localize="title"
|
||||
title="@actions_changeDataType"
|
||||
>
|
||||
<i class="icon icon-wrong"></i>
|
||||
title="@actions_changeDataType">
|
||||
<i class="icon icon-wrong" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -108,8 +106,7 @@
|
||||
placeholder="@validation_mandatoryMessage"
|
||||
ng-model="model.property.validation.mandatoryMessage"
|
||||
ng-if="model.property.validation.mandatory"
|
||||
ng-keypress="vm.submitOnEnter($event)">
|
||||
</input>
|
||||
ng-keypress="vm.submitOnEnter($event)" />
|
||||
|
||||
<label class="mt3">
|
||||
<localize key="validation_customValidation"></localize>
|
||||
@@ -144,8 +141,7 @@
|
||||
<h5><localize key="contentTypeEditor_cultureVariantHeading" /></h5>
|
||||
<umb-toggle data-element="permissions-allow-culture-variant"
|
||||
checked="model.property.allowCultureVariant"
|
||||
on-click="vm.toggleAllowCultureVariants()"
|
||||
>
|
||||
on-click="vm.toggleAllowCultureVariants()">
|
||||
</umb-toggle>
|
||||
|
||||
</div>
|
||||
@@ -155,8 +151,7 @@
|
||||
|
||||
<umb-toggle data-element="permissions-allow-segment-variant"
|
||||
checked="model.property.allowSegmentVariant"
|
||||
on-click="vm.toggleAllowSegmentVariants()"
|
||||
>
|
||||
on-click="vm.toggleAllowSegmentVariants()">
|
||||
</umb-toggle>
|
||||
|
||||
</div>
|
||||
@@ -195,7 +190,6 @@
|
||||
on-click="vm.toggleIsSensitiveData()">
|
||||
</umb-toggle>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
+11
-1
@@ -68,14 +68,20 @@
|
||||
|
||||
if(version && version.versionId) {
|
||||
|
||||
vm.loading = true;
|
||||
|
||||
const culture = $scope.model.node.variants.length > 1 ? vm.currentVersion.language.culture : null;
|
||||
|
||||
contentResource.getRollbackVersion(version.versionId, culture)
|
||||
.then(function(data){
|
||||
.then(function(data) {
|
||||
vm.previousVersion = data;
|
||||
vm.previousVersion.versionId = version.versionId;
|
||||
createDiff(vm.currentVersion, vm.previousVersion);
|
||||
|
||||
vm.loading = false;
|
||||
vm.rollbackButtonDisabled = false;
|
||||
}, function () {
|
||||
vm.loading = false;
|
||||
});
|
||||
|
||||
} else {
|
||||
@@ -118,6 +124,10 @@
|
||||
tab.properties.forEach((property, propertyIndex) => {
|
||||
var oldProperty = previousVersion.tabs[tabIndex].properties[propertyIndex];
|
||||
|
||||
// copy existing properties, so it doesn't manipulate existing properties on page
|
||||
oldProperty = Utilities.copy(oldProperty);
|
||||
property = Utilities.copy(property);
|
||||
|
||||
// we have to make properties storing values as object into strings (Grid, nested content, etc.)
|
||||
if(property.value instanceof Object) {
|
||||
property.value = JSON.stringify(property.value, null, 1);
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
|
||||
<div>
|
||||
|
||||
<h5><localize key="rollback_currentVersion"></localize></h5>
|
||||
<p>{{vm.currentVersion.name}} (Created: {{vm.currentVersion.createDate}})</p>
|
||||
<h5><localize key="rollback_currentVersion">Current version</localize></h5>
|
||||
<p>{{vm.currentVersion.name}} (<localize key="rollback_created">Created</localize>: {{vm.currentVersion.createDate}})</p>
|
||||
|
||||
<h5><localize key="rollback_rollbackTo"></localize></h5>
|
||||
<select
|
||||
@@ -44,9 +44,9 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div ng-if="vm.diff" class="diff" style="border-top: 1px solid #e9e9eb; margin-top: 30px;">
|
||||
<div ng-if="vm.diff && !vm.loading" class="diff" style="border-top: 1px solid #e9e9eb; margin-top: 30px;">
|
||||
|
||||
<h5>Changes</h5>
|
||||
<h5><localize key="rollback_changes">Changes</localize></h5>
|
||||
<small style="margin-bottom: 15px; display: block;"><localize key="rollback_diffHelp"></localize></small>
|
||||
|
||||
<table class="table table-condensed table-bordered">
|
||||
@@ -54,7 +54,7 @@
|
||||
<tr>
|
||||
<td class="bold">Name</td>
|
||||
<td>
|
||||
<span ng-repeat="part in vm.diff.name">
|
||||
<span ng-repeat="part in vm.diff.name track by $id(part)">
|
||||
<ins ng-if="part.added">{{part.value}}</ins>
|
||||
<del ng-if="part.removed">{{part.value}}</del>
|
||||
<span ng-if="!part.added && !part.removed">{{part.value}}</span>
|
||||
@@ -64,7 +64,7 @@
|
||||
<tr ng-repeat="property in vm.diff.properties track by property.alias">
|
||||
<td class="bold">{{property.label}}</td>
|
||||
<td ng-class="{'pre-line': property.isObject, 'word-wrap': !property.isObject}">
|
||||
<span ng-repeat="part in property.diff">
|
||||
<span ng-repeat="part in property.diff track by $id(part)">
|
||||
<ins ng-if="part.added">{{part.value}}</ins>
|
||||
<del ng-if="part.removed">{{part.value}}</del>
|
||||
<span ng-if="!part.added && !part.removed">{{part.value}}</span>
|
||||
|
||||
+25
@@ -19,6 +19,31 @@ function ItemPickerOverlay($scope, localizationService) {
|
||||
$scope.submitForm($scope.model);
|
||||
};
|
||||
|
||||
$scope.tooltip = {
|
||||
show: false,
|
||||
event: null
|
||||
};
|
||||
|
||||
$scope.showTooltip = function(item, $event) {
|
||||
if (!item.tooltip) {
|
||||
$scope.mouseLeave();
|
||||
return;
|
||||
}
|
||||
$scope.tooltip = {
|
||||
show: true,
|
||||
event: $event,
|
||||
text: item.tooltip
|
||||
};
|
||||
}
|
||||
|
||||
$scope.hideTooltip = function () {
|
||||
$scope.tooltip = {
|
||||
show: false,
|
||||
event: null,
|
||||
text: null
|
||||
};
|
||||
}
|
||||
|
||||
onInit();
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<button class="umb-card-grid-item btn-reset" ng-click="selectItem(availableItem)">
|
||||
<span>
|
||||
<i class="{{ availableItem.icon }}"></i>
|
||||
{{ availableItem.name }}
|
||||
<span ng-mouseover="showTooltip(availableItem, $event)" ng-mouseleave="hideTooltip()">{{ availableItem.name }}</span>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
@@ -51,4 +51,8 @@
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<umb-tooltip ng-if="tooltip.show" event="tooltip.event">
|
||||
{{ tooltip.text }}
|
||||
</umb-tooltip>
|
||||
</div>
|
||||
|
||||
@@ -5,13 +5,9 @@
|
||||
|
||||
<div class='umb-modalcolumn-body'>
|
||||
<ul class="umb-actions">
|
||||
<li data-element="action-{{action.alias}}" ng-click="executeMenuItem(action)" class="umb-action" ng-class="{sep:action.separator, '-opens-dialog': action.opensDialog}" ng-repeat="action in menuActions">
|
||||
<button class="umb-action-link btn-reset umb-outline" prevent-default umb-auto-focus ng-if="$index === 0">
|
||||
<i class="icon icon-{{action.cssclass}}"></i>
|
||||
<span class="menu-label">{{action.name}}</span>
|
||||
</button>
|
||||
<button class="umb-action-link btn-reset umb-outline" prevent-default ng-if="$index !== 0">
|
||||
<i class="icon icon-{{action.cssclass}}"></i>
|
||||
<li data-element="action-{{action.alias}}" class="umb-action" ng-class="{sep:action.separator, '-opens-dialog': action.opensDialog}" ng-repeat="action in menuActions">
|
||||
<button type="button" umb-auto-focus="{{$index === 0}}" ng-click="executeMenuItem(action)" class="umb-action-link btn-reset umb-outline" prevent-default>
|
||||
<i class="icon icon-{{action.cssclass}}" aria-hidden="true"></i>
|
||||
<span class="menu-label">{{action.name}}</span>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<small style="font-size: 13px;">{{vm.invitedUserPasswordModel.passwordPolicyText}}</small>
|
||||
</label>
|
||||
<input type="password" ng-model="vm.invitedUserPasswordModel.password" name="password" id="umb-passwordOne" class="-full-width-input" umb-auto-focus required val-server-field="value" ng-minlength="{{vm.invitedUserPasswordModel.passwordPolicies.minPasswordLength}}" />
|
||||
<span ng-messages="inviteUserPasswordForm.password.$error" show-validation-on-submit >
|
||||
<span ng-messages="inviteUserPasswordForm.password.$error" show-validation-on-submit>
|
||||
<span class="help-inline" ng-message="required"><localize key="user_passwordIsBlank">Your new password cannot be blank!</localize></span>
|
||||
<span class="help-inline" ng-message="minlength">Minimum {{vm.invitedUserPasswordModel.passwordPolicies.minPasswordLength}} characters</span>
|
||||
<span class="help-inline" ng-message="valServerField">{{inviteUserPasswordForm.password.errorMsg}}</span>
|
||||
@@ -33,7 +33,7 @@
|
||||
<div class="control-group" ng-class="{error: vm.setPasswordForm.confirmPassword.$invalid}">
|
||||
<label for="umb-confirmPasswordOne"><localize key="user_confirmNewPassword">Confirm new password</localize></label>
|
||||
<input type="password" ng-model="vm.invitedUserPasswordModel.confirmPassword" name="confirmPassword" id="umb-confirmPasswordOne" class="-full-width-input" required val-compare="password" />
|
||||
<span ng-messages="inviteUserPasswordForm.confirmPassword.$error" show-validation-on-submit >
|
||||
<span ng-messages="inviteUserPasswordForm.confirmPassword.$error" show-validation-on-submit>
|
||||
<span class="help-inline" ng-message="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" ng-message="valCompare"><localize key="user_passwordMismatch">The confirmed password doesn't match the new password!</localize></span>
|
||||
</span>
|
||||
@@ -41,11 +41,10 @@
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between items-center">
|
||||
<umb-button
|
||||
type="submit"
|
||||
button-style="success"
|
||||
state="vm.invitedUserPasswordModel.buttonState"
|
||||
label="Save password">
|
||||
<umb-button type="submit"
|
||||
button-style="success"
|
||||
state="vm.invitedUserPasswordModel.buttonState"
|
||||
label="Save password">
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
@@ -58,11 +57,10 @@
|
||||
|
||||
<ng-form name="vm.avatarForm">
|
||||
|
||||
<umb-progress-bar
|
||||
style="max-width: 100px; margin-bottom: 5px;"
|
||||
ng-show="vm.avatarFile.uploadStatus === 'uploading'"
|
||||
progress="{{ vm.avatarFile.uploadProgress }}"
|
||||
size="s">
|
||||
<umb-progress-bar style="max-width: 100px; margin-bottom: 5px;"
|
||||
ng-show="vm.avatarFile.uploadStatus === 'uploading'"
|
||||
progress="{{ vm.avatarFile.uploadProgress }}"
|
||||
size="s">
|
||||
</umb-progress-bar>
|
||||
|
||||
<div class="umb-info-local-item text-error mt3" ng-if="vm.avatarFile.uploadStatus === 'error'">
|
||||
@@ -70,19 +68,18 @@
|
||||
</div>
|
||||
|
||||
<a class="umb-avatar-btn"
|
||||
ngf-select
|
||||
ng-model="vm.avatarFile.filesHolder"
|
||||
ngf-change="vm.changeAvatar($files, $event)"
|
||||
ngf-multiple="false"
|
||||
ngf-pattern="{{vm.avatarFile.acceptedFileTypes}}"
|
||||
ngf-max-size="{{ vm.avatarFile.maxFileSize }}">
|
||||
ngf-select
|
||||
ng-model="vm.avatarFile.filesHolder"
|
||||
ngf-change="vm.changeAvatar($files, $event)"
|
||||
ngf-multiple="false"
|
||||
ngf-pattern="{{vm.avatarFile.acceptedFileTypes}}"
|
||||
ngf-max-size="{{ vm.avatarFile.maxFileSize }}">
|
||||
|
||||
<umb-avatar
|
||||
color="gray"
|
||||
size="xl"
|
||||
unknown-char="+"
|
||||
img-src="{{vm.invitedUser.avatars[3]}}"
|
||||
img-srcset="{{vm.invitedUser.avatars[4]}} 2x, {{invitedUser.avatars[4]}} 3x">
|
||||
<umb-avatar color="gray"
|
||||
size="xl"
|
||||
unknown-char="+"
|
||||
img-src="{{vm.invitedUser.avatars[3]}}"
|
||||
img-srcset="{{vm.invitedUser.avatars[4]}} 2x, {{invitedUser.avatars[4]}} 3x">
|
||||
</umb-avatar>
|
||||
</a>
|
||||
|
||||
@@ -94,11 +91,10 @@
|
||||
<localize key="user_userinviteAvatarMessage"></localize>
|
||||
</p>
|
||||
<div class="flex justify-center items-center">
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="success"
|
||||
label="Done"
|
||||
action="vm.getStarted()">
|
||||
<umb-button type="button"
|
||||
button-style="success"
|
||||
label="Done"
|
||||
action="vm.getStarted()">
|
||||
</umb-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -153,7 +149,7 @@
|
||||
</div>
|
||||
<div class="control-group" ng-class="{error: vm.loginForm.username.$invalid}">
|
||||
<label for="umb-username">{{vm.labels.usernameLabel}}</label>
|
||||
<input type="text" ng-model="vm.login" name="username" id="umb-username" class="-full-width-input" placeholder="{{vm.labels.usernamePlaceholder}}" focus-when="{{vm.view === 'login'}}" aria-required="true"/>
|
||||
<input type="text" ng-model="vm.login" name="username" id="umb-username" class="-full-width-input" placeholder="{{vm.labels.usernamePlaceholder}}" focus-when="{{vm.view === 'login'}}" aria-required="true" />
|
||||
</div>
|
||||
|
||||
<div class="control-group" ng-class="{error: vm.loginForm.password.$invalid}">
|
||||
@@ -188,21 +184,21 @@
|
||||
</p>
|
||||
|
||||
<form method="POST" name="vm.requestPasswordResetForm" ng-submit="vm.requestPasswordResetSubmit(email)">
|
||||
<div class="control-group" ng-class="{error: requestPasswordResetForm.email.$invalid}">
|
||||
<div class="control-group" ng-class="{error: vm.requestPasswordResetForm.email.$invalid}">
|
||||
<label for="umb-email"><localize key="general_email">Email</localize></label>
|
||||
<input type="email" val-email ng-model="email" name="email" id="umb-email" class="-full-width-input" localize="placeholder" placeholder="@placeholders_email" focus-when="{{vm.view === 'request-password-reset'}}" />
|
||||
</div>
|
||||
|
||||
<div class="control-group" ng-show="requestPasswordResetForm.$invalid">
|
||||
<div class="text-error">{{errorMsg}}</div>
|
||||
<div ng-messages="vm.requestPasswordResetForm.$error" class="control-group" ng-show="vm.requestPasswordResetForm.$invalid">
|
||||
<p ng-message="auth" class="text-error" role="alert" tabindex="0">{{vm.errorMsg}}</p>
|
||||
</div>
|
||||
|
||||
<div class="control-group" ng-show="vm.showEmailResetConfirmation">
|
||||
<div class="text-info" role="alert">
|
||||
<p tabindex="0">
|
||||
<localize key="login_requestPasswordResetConfirmation">An email with password reset instructions will be sent to the specified address if it matched our records</localize>
|
||||
</p>
|
||||
</div>
|
||||
<localize key="login_requestPasswordResetConfirmation">An email with password reset instructions will be sent to the specified address if it matched our records</localize>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between items-center">
|
||||
@@ -231,16 +227,16 @@
|
||||
<input type="password" ng-model="vm.confirmPassword" name="confirmPassword" id="umb-confirmPasswordThree" class="-full-width-input" localize="placeholder" placeholder="@placeholders_confirmPassword" />
|
||||
</div>
|
||||
|
||||
<div ng-hide="vm.resetComplete" class="control-group" ng-show="vm.setPasswordForm.$invalid">
|
||||
<div class="text-error">{{vm.errorMsg}}</div>
|
||||
<div ng-messages="vm.setPasswordForm.$error" class="control-group" ng-show="vm.setPasswordForm.$invalid">
|
||||
<p ng-message="auth" class="text-error" role="alert" tabindex="0">{{vm.errorMsg}}</p>
|
||||
</div>
|
||||
|
||||
<div class="control-group" ng-show="vm.showSetPasswordConfirmation">
|
||||
<div class="text-info">
|
||||
<p tabindex="0">
|
||||
<localize key="login_setPasswordConfirmation">Your new password has been set and you may now use it to log in.</localize>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between items-center">
|
||||
<button ng-hide="vm.resetComplete" type="submit" class="btn btn-success" val-trigger-change="#login .form input"><localize key="general_submit">Submit</localize></button>
|
||||
<a class="muted" href="#" prevent-default ng-click="vm.showLogin()"><localize key="login_returnToLogin">Return to login form</localize></a>
|
||||
@@ -251,7 +247,7 @@
|
||||
|
||||
<div ng-show="vm.view == 'password-reset-code-expired'">
|
||||
<div class="text-error" ng-repeat="error in vm.resetPasswordCodeInfo.errors">
|
||||
<span>{{error}}</span>
|
||||
<p class="text-error">{{error}}</p>
|
||||
</div>
|
||||
|
||||
<div class="switch-view">
|
||||
|
||||
@@ -5,18 +5,16 @@
|
||||
<umb-box ng-if="currentUrls" data-element="node-info-urls">
|
||||
<umb-box-header title-key="general_links"></umb-box-header>
|
||||
<umb-box-content class="block-form">
|
||||
<ul class="nav nav-stacked" style="margin-bottom: 0;">
|
||||
<ul class="nav nav-stacked mb0">
|
||||
<li ng-repeat="url in currentUrls">
|
||||
<a href="{{url.text}}" target="_blank" ng-if="url.isUrl">
|
||||
<span ng-if="currentUrlsHaveMultipleCultures && url.culture" style="font-size: 13px; color: #cccccc; width: 50px;display: inline-block">{{url.culture}}</span>
|
||||
<i class="icon icon-out"></i>
|
||||
<i class="icon icon-out" aria-hidden="true"></i>
|
||||
<span>{{url.text}}</span>
|
||||
</a>
|
||||
<div ng-if="!url.isUrl" style="margin-top: 4px;">
|
||||
|
||||
<span ng-if="currentUrlsHaveMultipleCultures && url.culture" style="font-size: 13px; color: #cccccc; width: 50px;display: inline-block">{{url.culture}}</span>
|
||||
<em>{{url.text}}</em>
|
||||
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -32,7 +30,10 @@
|
||||
<p><localize key="redirectUrls_panelInformation" class="ng-isolate-scope ng-scope">The following URLs redirect to this content item:</localize></p>
|
||||
<ul class="nav nav-stacked" style="margin-bottom: 0;">
|
||||
<li ng-repeat="redirectUrl in redirectUrls">
|
||||
<a href="{{redirectUrl.originalUrl}}" target="_blank"><i ng-class="value.icon" class="icon-out"></i> {{redirectUrl.originalUrl}}</a>
|
||||
<a href="{{redirectUrl.originalUrl}}" target="_blank">
|
||||
<i ng-class="value.icon" class="icon-out" aria-hidden="true"></i>
|
||||
{{redirectUrl.originalUrl}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -42,9 +43,8 @@
|
||||
|
||||
<umb-box data-element="node-info-history">
|
||||
|
||||
<umb-box-header
|
||||
title="{{historyLabel}}">
|
||||
|
||||
<umb-box-header title="{{historyLabel}}">
|
||||
|
||||
<umb-button
|
||||
ng-hide="node.trashed"
|
||||
type="button"
|
||||
@@ -104,8 +104,7 @@
|
||||
<span>
|
||||
<localize key="auditTrails_{{ item.logType | lowercase }}" tokens="[item.parameters]">{{ item.comment }}</localize>
|
||||
</span>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -12,16 +12,16 @@
|
||||
<div class="flex items-center" style="flex: 1;">
|
||||
|
||||
<ng-form data-element="editor-icon" name="iconForm">
|
||||
<button
|
||||
type="button" class="umb-panel-header-icon"
|
||||
ng-if="!hideIcon"
|
||||
ng-click="openIconPicker()"
|
||||
<button
|
||||
type="button" class="umb-panel-header-icon"
|
||||
ng-if="!hideIcon"
|
||||
ng-click="openIconPicker()"
|
||||
ng-class="{'-placeholder': $parent.icon==='' || $parent.icon===null}"
|
||||
title="{{$parent.icon}}">
|
||||
<i class="icon {{$parent.icon}}" ng-if="$parent.icon!=='' && $parent.icon!==null" aria-hidden="true"></i>
|
||||
<div class="umb-panel-header-icon-text" ng-if="$parent.icon==='' || $parent.icon===null">
|
||||
<span class="umb-panel-header-icon-text" ng-if="$parent.icon==='' || $parent.icon===null">
|
||||
<localize key="settings_addIcon">Add icon</localize>
|
||||
</div>
|
||||
</span>
|
||||
</button>
|
||||
</ng-form>
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div class="umb-panel-header-name" ng-if="nameLocked" title="{{key}}">{{ name }}</div>
|
||||
<h1 class="umb-panel-header-name" id="editor-headline-{{$id}}" ng-if="nameLocked" title="{{key}}">{{ name }}</h1>
|
||||
|
||||
<input data-element="editor-description"
|
||||
no-password-manager
|
||||
@@ -78,7 +78,7 @@
|
||||
ng-if="!hideDescription && !descriptionLocked"
|
||||
ng-model="$parent.description"/>
|
||||
|
||||
<div class="umb-panel-header-locked-description" ng-if="descriptionLocked">{{ description }}</div>
|
||||
<p class="umb-panel-header-locked-description" id="editor-description-{{$id}}" ng-if="descriptionLocked">{{ description }}</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -240,7 +240,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<ng-form inert class="umb-group-builder__property-preview-form" name="propertyEditorPreviewForm" umb-disable-form-validation ng-click="editPropertyTypeSettings(property, tab)">
|
||||
<ng-form inert class="umb-group-builder__property-preview-form" name="propertyEditorPreviewForm" umb-disable-form-validation ng-click="editPropertyTypeSettings(property, tab)" tabindex="-1">
|
||||
<umb-property-editor
|
||||
ng-if="property.view !== undefined"
|
||||
model="property"
|
||||
|
||||
@@ -104,11 +104,4 @@
|
||||
|
||||
</ng-form>
|
||||
|
||||
<umb-overlay
|
||||
ng-if="mediatypepickerOverlay.show"
|
||||
model="mediatypepickerOverlay"
|
||||
view="mediatypepickerOverlay.view"
|
||||
position="right">
|
||||
</umb-overlay>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -92,6 +92,8 @@ function contentCreateController($scope,
|
||||
} else {
|
||||
createBlank(docType);
|
||||
}
|
||||
|
||||
navigationService.hideDialog();
|
||||
}
|
||||
|
||||
function createFromBlueprint(blueprintId) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function ContentSortController($scope, $filter, $routeParams, contentResource, navigationService) {
|
||||
function ContentSortController($scope, $filter, $routeParams, contentResource, navigationService, eventsService) {
|
||||
|
||||
var vm = this;
|
||||
var id = $scope.currentNode.id;
|
||||
@@ -50,6 +50,7 @@
|
||||
navigationService.syncTree({ tree: "content", path: $scope.currentNode.path, forceReload: true })
|
||||
.then(() => navigationService.reloadNode($scope.currentNode));
|
||||
|
||||
eventsService.emit("sortCompleted", { id: id });
|
||||
vm.saveButtonState = "success";
|
||||
}, function(error) {
|
||||
vm.error = error;
|
||||
|
||||
@@ -1,37 +1,35 @@
|
||||
<div ng-controller="Umbraco.Editors.Content.SortController as vm" ng-cloak>
|
||||
|
||||
|
||||
<div class="umb-dialog-body with-footer sort-order">
|
||||
|
||||
|
||||
<div class="umb-pane">
|
||||
|
||||
<div ng-if="vm.error">
|
||||
<div class="alert alert-error">
|
||||
<div>{{vm.error.errorMsg}}</div>
|
||||
</div>
|
||||
<div ng-if="vm.error" class="alert alert-error">
|
||||
<p>{{vm.error.errorMsg}}</p>
|
||||
</div>
|
||||
|
||||
|
||||
<umb-load-indicator
|
||||
ng-show="vm.loading">
|
||||
</umb-load-indicator>
|
||||
|
||||
|
||||
<div ng-if="!vm.loading">
|
||||
<p class="abstract"><localize key="sort_sortHelp"></localize></p>
|
||||
<p class="abstract"><localize key="sort_sortHelp">Drag the different items up or down below to set how they should be arranged. Or click the column headers to sort the entire collection of items</localize></p>
|
||||
<table class="table table-condensed table-sortable" ng-if="vm.children">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<a ng-href="#" ng-click="vm.sort('name')" prevent-default>
|
||||
<localize key="general_name"></localize>
|
||||
<span ng-if="vm.sortOrder.column === 'name'">
|
||||
<button type="button" class="btn-reset" ng-click="vm.sort('name')">
|
||||
<b><localize key="general_name">Name</localize></b>
|
||||
<span ng-if="vm.sortOrder.column === 'name'" aria-hidden="true">
|
||||
<i ng-if="vm.sortOrder.reverse" class="icon-navigation-up"></i>
|
||||
<i ng-if="!vm.sortOrder.reverse" class="icon-navigation-down"></i>
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</th>
|
||||
<th>
|
||||
<a ng-href="#" ng-click="vm.sort('createDate')" prevent-default>
|
||||
<localize key="sort_sortCreationDate"></localize>
|
||||
<span ng-if="vm.sortOrder.column === 'createDate'">
|
||||
<button type="button" class="btn-reset" ng-click="vm.sort('createDate')">
|
||||
<b><localize key="sort_sortCreationDate">Creation date</localize></b>
|
||||
<span ng-if="vm.sortOrder.column === 'createDate'" aria-hidden="true">
|
||||
<i ng-if="vm.sortOrder.reverse" class="icon-navigation-up"></i>
|
||||
<i ng-if="!vm.sortOrder.reverse" class="icon-navigation-down"></i>
|
||||
</span>
|
||||
@@ -51,14 +49,14 @@
|
||||
<umb-empty-state
|
||||
ng-if="!vm.children"
|
||||
position="center">
|
||||
<localize key="sort_sortEmptyState"></localize>
|
||||
<localize key="sort_sortEmptyState">This node has no child nodes to sort</localize>
|
||||
</umb-empty-state>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar">
|
||||
<umb-button
|
||||
type="button"
|
||||
@@ -68,12 +66,12 @@
|
||||
</umb-button>
|
||||
<umb-button
|
||||
ng-if="vm.children"
|
||||
type="button"
|
||||
type="button"
|
||||
action="vm.save()"
|
||||
state="vm.saveButtonState"
|
||||
button-style="success"
|
||||
label-key="buttons_save">
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
vm.page.loading = false;
|
||||
vm.page.saveButtonState = "init";
|
||||
vm.page.navigation = [];
|
||||
|
||||
|
||||
var labelKeys = [
|
||||
"general_design",
|
||||
"general_listView",
|
||||
@@ -92,33 +92,6 @@
|
||||
vm.labels.addTemplate = values[13];
|
||||
vm.labels.allowCultureVariants = values[14];
|
||||
|
||||
var buttons = [
|
||||
{
|
||||
"name": vm.labels.design,
|
||||
"alias": "design",
|
||||
"icon": "icon-document-dashed-line",
|
||||
"view": "views/documenttypes/views/design/design.html"
|
||||
},
|
||||
{
|
||||
"name": vm.labels.listview,
|
||||
"alias": "listView",
|
||||
"icon": "icon-list",
|
||||
"view": "views/documenttypes/views/listview/listview.html"
|
||||
},
|
||||
{
|
||||
"name": vm.labels.permissions,
|
||||
"alias": "permissions",
|
||||
"icon": "icon-keychain",
|
||||
"view": "views/documenttypes/views/permissions/permissions.html"
|
||||
},
|
||||
{
|
||||
"name": vm.labels.templates,
|
||||
"alias": "templates",
|
||||
"icon": "icon-layout",
|
||||
"view": "views/documenttypes/views/templates/templates.html"
|
||||
}
|
||||
];
|
||||
|
||||
vm.page.keyboardShortcutsOverview = [
|
||||
{
|
||||
"name": vm.labels.sections,
|
||||
@@ -187,9 +160,6 @@
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
loadButtons(buttons);
|
||||
|
||||
});
|
||||
|
||||
contentTypeHelper.checkModelsBuilderStatus().then(function (result) {
|
||||
@@ -279,25 +249,25 @@
|
||||
contentTypeResource.getById(documentTypeId).then(function (dt) {
|
||||
init(dt);
|
||||
// we don't need to sync the tree in infinite mode
|
||||
if(!infiniteMode) {
|
||||
if (!infiniteMode) {
|
||||
syncTreeNode(vm.contentType, dt.path, true);
|
||||
}
|
||||
vm.page.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function loadButtons(buttons) {
|
||||
function loadButtons() {
|
||||
vm.page.navigation = vm.contentType.apps;
|
||||
|
||||
angular.forEach(buttons,
|
||||
function (val, index) {
|
||||
if (disableTemplates === true) {
|
||||
Utilities.forEach(vm.contentType.apps,
|
||||
(app, index) => {
|
||||
if (app.alias === "templates") {
|
||||
vm.page.navigation.splice(index, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (disableTemplates === true && val.alias === "templates") {
|
||||
buttons.splice(index, 1);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
vm.page.navigation = buttons;
|
||||
initializeActiveNavigationPanel();
|
||||
}
|
||||
|
||||
@@ -307,16 +277,14 @@
|
||||
var initialViewSetFromRouteParams = false;
|
||||
var view = $routeParams.view;
|
||||
if (view) {
|
||||
var viewPath = "views/documenttypes/views/" + view + "/" + view + ".html";
|
||||
for (var i = 0; i < vm.page.navigation.length; i++) {
|
||||
if (vm.page.navigation[i].view === viewPath) {
|
||||
if (vm.page.navigation[i].alias.localeCompare(view, undefined, { sensitivity: 'accent' }) === 0) {
|
||||
vm.page.navigation[i].active = true;
|
||||
initialViewSetFromRouteParams = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (initialViewSetFromRouteParams === false) {
|
||||
vm.page.navigation[0].active = true;
|
||||
}
|
||||
@@ -379,18 +347,17 @@
|
||||
}).then(function (data) {
|
||||
//success
|
||||
// we don't need to sync the tree in infinite mode
|
||||
if(!infiniteMode) {
|
||||
if (!infiniteMode) {
|
||||
syncTreeNode(vm.contentType, data.path);
|
||||
}
|
||||
|
||||
// emit event
|
||||
var args = { documentType: vm.contentType };
|
||||
eventsService.emit("editors.documentType.saved", args);
|
||||
|
||||
|
||||
vm.page.saveButtonState = "success";
|
||||
|
||||
if(infiniteMode && $scope.model.submit) {
|
||||
$scope.model.documentTypeKey = vm.contentType.key;
|
||||
if (infiniteMode && $scope.model.submit) {
|
||||
$scope.model.documentTypeAlias = vm.contentType.alias;
|
||||
$scope.model.submit($scope.model);
|
||||
}
|
||||
@@ -447,10 +414,12 @@
|
||||
// convert icons for content type
|
||||
convertLegacyIcons(contentType);
|
||||
|
||||
//set a shared state
|
||||
editorState.set(contentType);
|
||||
|
||||
vm.contentType = contentType;
|
||||
|
||||
//set a shared state
|
||||
editorState.set(vm.contentType);
|
||||
|
||||
loadButtons();
|
||||
}
|
||||
|
||||
/** Syncs the template alias for new doc types before saving if a template is to be created */
|
||||
@@ -526,11 +495,10 @@
|
||||
if (treeExists) {
|
||||
navigationService.syncTree({ tree: "templates", path: [], forceReload: true })
|
||||
.then(function (syncArgs) {
|
||||
navigationService.reloadNode(syncArgs.node)
|
||||
}
|
||||
);
|
||||
navigationService.reloadNode(syncArgs.node);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
@@ -41,25 +41,22 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a data-element="editor-add" href="" ng-if="!model.parameter.editor" class="editor-placeholder" hotkey="alt+shift+e" ng-click="vm.openMacroParameterPicker(model.parameter)">
|
||||
<button type="button" class="btn-reset editor-placeholder" data-element="editor-add" ng-if="!model.parameter.editor" hotkey="alt+shift+e" ng-click="vm.openMacroParameterPicker(model.parameter)">
|
||||
<localize key="shortcuts_addEditor"></localize>
|
||||
</a>
|
||||
</button>
|
||||
|
||||
<div class="editor clearfix" ng-if="model.parameter.editor">
|
||||
|
||||
<div class="editor-details">
|
||||
<button class="btn-reset editor-info" ng-click="vm.openMacroParameterPicker(model.parameter)">
|
||||
<button type="button" class="btn-reset editor-info" ng-click="vm.openMacroParameterPicker(model.parameter)">
|
||||
<div class="editor-icon-wrapper">
|
||||
<i class="icon {{ model.parameter.dataTypeIcon }}" ng-class="{'icon-autofill': model.parameter.dataTypeIcon == null}" aria-hidden="true"></i>
|
||||
</div>
|
||||
|
||||
<div class="editor-icon-wrapper">
|
||||
<i class="icon {{model.parameter.dataTypeIcon}}" ng-class="{'icon-autofill': model.parameter.dataTypeIcon == null}"></i>
|
||||
</div>
|
||||
|
||||
<div class="editor-details">
|
||||
<a href="" class="editor-name">{{model.parameter.dataTypeName}}</a>
|
||||
<a href="" class="editor-editor">{{model.parameter.editor}}</a>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="editor-details">
|
||||
<span class="editor-name">{{ model.parameter.dataTypeName }}</span>
|
||||
<span class="editor-editor">{{ model.parameter.editor }}</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -21,15 +21,15 @@
|
||||
on-edit="model.openViewPicker()"
|
||||
on-remove="model.removeMacroView()">
|
||||
</umb-node-preview>
|
||||
|
||||
<input type="hidden" ng-model="mandatoryViewValidator" ng-required="!model.macro.node" />
|
||||
|
||||
<a href=""
|
||||
ng-show="!model.macro.node"
|
||||
class="umb-node-preview-add"
|
||||
ng-click="model.openViewPicker()"
|
||||
prevent-default>
|
||||
<button type="button"
|
||||
class="umb-node-preview-add"
|
||||
ng-show="!model.macro.node"
|
||||
ng-click="model.openViewPicker()">
|
||||
<localize key="general_add">Add</localize>
|
||||
</a>
|
||||
</button>
|
||||
|
||||
</umb-control-group>
|
||||
</umb-box-content>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function MediaSortController($scope, $filter, mediaResource, navigationService) {
|
||||
function MediaSortController($scope, $filter, mediaResource, navigationService, eventsService) {
|
||||
|
||||
var vm = this;
|
||||
var id = $scope.currentNode.id;
|
||||
@@ -50,6 +50,7 @@
|
||||
navigationService.syncTree({ tree: "media", path: $scope.currentNode.path, forceReload: true })
|
||||
.then(() => navigationService.reloadNode($scope.currentNode));
|
||||
|
||||
eventsService.emit("sortCompleted", { id: id });
|
||||
vm.saveButtonState = "success";
|
||||
}, function(error) {
|
||||
vm.error = error;
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
<div ng-controller="Umbraco.Editors.Media.SortController as vm" ng-cloak>
|
||||
|
||||
|
||||
<div class="umb-dialog-body with-footer sort-order">
|
||||
|
||||
|
||||
<div class="umb-pane">
|
||||
|
||||
<div ng-if="vm.error">
|
||||
<div class="alert alert-error">
|
||||
<div>{{vm.error.errorMsg}}</div>
|
||||
</div>
|
||||
<div ng-if="vm.error" class="alert alert-error">
|
||||
<p>{{vm.error.errorMsg}}</p>
|
||||
</div>
|
||||
|
||||
<umb-load-indicator
|
||||
@@ -15,27 +13,27 @@
|
||||
</umb-load-indicator>
|
||||
|
||||
<div ng-if="!vm.loading">
|
||||
<p class="abstract"><localize key="sort_sortHelp"></localize></p>
|
||||
<p class="abstract"><localize key="sort_sortHelp">Drag the different items up or down below to set how they should be arranged. Or click the column headers to sort the entire collection of items</localize></p>
|
||||
<table class="table table-condensed table-sortable" ng-if="vm.children">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<a ng-href="#" ng-click="vm.sort('name')" prevent-default>
|
||||
<localize key="general_name"></localize>
|
||||
<span ng-if="vm.sortOrder.column === 'name'">
|
||||
<button type="button" class="btn-reset" ng-click="vm.sort('name')">
|
||||
<b><localize key="general_name">Name</localize></b>
|
||||
<span ng-if="vm.sortOrder.column === 'name'" aria-hidden="true">
|
||||
<i ng-if="vm.sortOrder.reverse" class="icon-navigation-up"></i>
|
||||
<i ng-if="!vm.sortOrder.reverse" class="icon-navigation-down"></i>
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</th>
|
||||
<th>
|
||||
<a ng-href="#" ng-click="vm.sort('createDate')" prevent-default>
|
||||
<localize key="sort_sortCreationDate"></localize>
|
||||
<span ng-if="vm.sortOrder.column === 'createDate'">
|
||||
<button type="button" class="btn-reset" ng-click="vm.sort('createDate')">
|
||||
<b><localize key="sort_sortCreationDate">Creation date</localize></b>
|
||||
<span ng-if="vm.sortOrder.column === 'createDate'" aria-hidden="true">
|
||||
<i ng-if="vm.sortOrder.reverse" class="icon-navigation-up"></i>
|
||||
<i ng-if="!vm.sortOrder.reverse" class="icon-navigation-down"></i>
|
||||
</span>
|
||||
</a>
|
||||
</button>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -68,7 +66,7 @@
|
||||
</umb-button>
|
||||
<umb-button
|
||||
ng-if="vm.children"
|
||||
type="button"
|
||||
type="button"
|
||||
action="vm.save()"
|
||||
state="vm.saveButtonState"
|
||||
button-style="success"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
ng-model="model.value"
|
||||
ng-required="model.validation.mandatory"
|
||||
aria-required="{{model.validation.mandatory}}"
|
||||
id="{{model.alias}}"
|
||||
val-server="value"
|
||||
fix-number min="{{model.config.min}}" max="{{model.config.max}}" step="{{model.config.step}}" />
|
||||
|
||||
|
||||
@@ -318,25 +318,26 @@ angular.module("umbraco")
|
||||
// Add items overlay menu
|
||||
// *********************************************
|
||||
$scope.openEditorOverlay = function (event, area, index, key) {
|
||||
var title = "";
|
||||
localizationService.localize("grid_insertControl").then(function (value) {
|
||||
title = value;
|
||||
overlayService.open({
|
||||
view: "itempicker",
|
||||
filter: area.$allowedEditors.length > 15,
|
||||
title: title,
|
||||
availableItems: area.$allowedEditors,
|
||||
event: event,
|
||||
submit: function (model) {
|
||||
if (model.selectedItem) {
|
||||
$scope.addControl(model.selectedItem, area, index);
|
||||
overlayService.close();
|
||||
}
|
||||
},
|
||||
close: function () {
|
||||
|
||||
const dialog = {
|
||||
view: "itempicker",
|
||||
filter: area.$allowedEditors.length > 15,
|
||||
availableItems: area.$allowedEditors,
|
||||
event: event,
|
||||
submit: function (model) {
|
||||
if (model.selectedItem) {
|
||||
$scope.addControl(model.selectedItem, area, index);
|
||||
overlayService.close();
|
||||
}
|
||||
});
|
||||
},
|
||||
close: function () {
|
||||
overlayService.close();
|
||||
}
|
||||
};
|
||||
|
||||
localizationService.localize("grid_insertControl").then(value => {
|
||||
dialog.title = value;
|
||||
overlayService.open(dialog);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -251,7 +251,9 @@
|
||||
|
||||
<button
|
||||
class="iconBox btn-reset"
|
||||
ng-click="toggleAddRow()"
|
||||
type="button"
|
||||
title="{{ section.$allowedLayouts.length == 1 ? section.$allowedLayouts[0].label || section.$allowedLayouts[0].name : '' }}"
|
||||
ng-click="section.$allowedLayouts.length == 1 ? addRow(section, section.$allowedLayouts[0]) : toggleAddRow()"
|
||||
ng-if="!showRowConfigurations">
|
||||
|
||||
<i class="icon icon-add" ></i>
|
||||
|
||||
+3
-4
@@ -53,10 +53,9 @@ function includePropsPreValsController($rootScope, $scope, localizationService,
|
||||
$scope.errorMsg = "";
|
||||
}
|
||||
|
||||
$scope.removeField = function(e) {
|
||||
$scope.model.value = _.reject($scope.model.value, function (x) {
|
||||
return x.alias === e.alias;
|
||||
});
|
||||
$scope.removeField = function (e) {
|
||||
var index = $scope.model.value.indexOf(e);
|
||||
$scope.model.value.splice(index, 1);
|
||||
}
|
||||
|
||||
//now we'll localize these strings, for some reason the directive doesn't work inside of the select group with an ng-model declared
|
||||
|
||||
+14
-1
@@ -1,4 +1,4 @@
|
||||
function listViewController($scope, $interpolate, $routeParams, $injector, $timeout, currentUserResource, notificationsService, iconHelper, editorState, localizationService, appState, $location, listViewHelper, navigationService, editorService, overlayService, languageResource, mediaHelper) {
|
||||
function listViewController($scope, $interpolate, $routeParams, $injector, $timeout, currentUserResource, notificationsService, iconHelper, editorState, localizationService, appState, $location, listViewHelper, navigationService, editorService, overlayService, languageResource, mediaHelper, eventsService) {
|
||||
|
||||
//this is a quick check to see if we're in create mode, if so just exit - we cannot show children for content
|
||||
// that isn't created yet, if we continue this will use the parent id in the route params which isn't what
|
||||
@@ -838,6 +838,19 @@ function listViewController($scope, $interpolate, $routeParams, $injector, $time
|
||||
$scope.toggleDropdown = toggleDropdown;
|
||||
$scope.leaveDropdown = leaveDropdown;
|
||||
|
||||
// if this listview has sort order in it, make sure it is updated when sorting is performed on the current content
|
||||
if (_.find($scope.options.includeProperties, property => property.alias === "sortOrder")) {
|
||||
var eventSubscription = eventsService.on("sortCompleted", function (e, args) {
|
||||
if (parseInt(args.id) === parseInt($scope.contentId)) {
|
||||
$scope.reloadView($scope.contentId);
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
eventsService.unsubscribe(eventSubscription);
|
||||
});
|
||||
}
|
||||
|
||||
//GO!
|
||||
initView();
|
||||
}
|
||||
|
||||
+7
-16
@@ -46,7 +46,7 @@ function sortByPreValsController($rootScope, $scope, localizationService, editor
|
||||
var systemFields = [
|
||||
{ value: "SortOrder", key: "general_sort" },
|
||||
{ value: "Name", key: "general_name" },
|
||||
{ value: "VersionDate", key: "content_updateDate" },
|
||||
{ value: "UpdateDate", key: "content_updateDate" },
|
||||
{ value: "Updater", key: "content_updatedBy" },
|
||||
{ value: "CreateDate", key: "content_createDate" },
|
||||
{ value: "Owner", key: "content_createBy" },
|
||||
@@ -57,28 +57,19 @@ function sortByPreValsController($rootScope, $scope, localizationService, editor
|
||||
];
|
||||
_.each(systemFields, function (e) {
|
||||
localizationService.localize(e.key).then(function (v) {
|
||||
|
||||
var sortByListValue = findFromSortByFields(e.value);
|
||||
if (sortByListValue) {
|
||||
sortByListValue.name = v;
|
||||
switch (e.value) {
|
||||
case "Updater":
|
||||
e.name += " (Content only)";
|
||||
break;
|
||||
case "Published":
|
||||
e.name += " (Content only)";
|
||||
break;
|
||||
case "Email":
|
||||
e.name += " (Members only)";
|
||||
break;
|
||||
case "Username":
|
||||
e.name += " (Members only)";
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
_.each($scope.sortByFields, function (sortByField) {
|
||||
if (!sortByField.name) {
|
||||
sortByField.name = "(" + sortByField.value + ")";
|
||||
}
|
||||
});
|
||||
|
||||
// Check existing model value is available in list and ensure a value is set
|
||||
var existingValue = findFromSortByFields($scope.model.value);
|
||||
if (existingValue) {
|
||||
|
||||
+2
-1
@@ -228,7 +228,8 @@
|
||||
vm.overlayMenu.availableItems.push({
|
||||
alias: scaffold.contentTypeAlias,
|
||||
name: scaffold.contentTypeName,
|
||||
icon: iconHelper.convertFromLegacyIcon(scaffold.icon)
|
||||
icon: iconHelper.convertFromLegacyIcon(scaffold.icon),
|
||||
tooltip: scaffold.documentType.description
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
<ul class="nav nav-stacked">
|
||||
<li ng-repeat="value in renderModel">
|
||||
<a href="{{getUrl(value.url)}}" prevent-default="{{value.url.indexOf('/') == -1}}" target="{{value.urlTarget}}">
|
||||
<i ng-class="value.icon"></i>
|
||||
<span ng-if="value.linkText">{{value.linkText}}</span>
|
||||
<span ng-if="!value.linkText">{{value.url}}</span>
|
||||
<i ng-class="value.icon" aria-hidden="true"></i>
|
||||
<span>{{value.linkText || value.url}}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1098,10 +1098,13 @@ Mange hilsner fra Umbraco robotten
|
||||
<key alias="customCrop">Brugerdefineret</key>
|
||||
</area>
|
||||
<area alias="rollback">
|
||||
<key alias="changes">Ændringer</key>
|
||||
<key alias="created">Oprettet</key>
|
||||
<key alias="headline">Vælg en version at sammenligne med den nuværende version</key>
|
||||
<key alias="currentVersion">Nuværende version</key>
|
||||
<key alias="diffHelp"><![CDATA[Her vises forskellene mellem den nuværende version og den valgte version<br /><del>Rød</del> tekst vil ikke blive vist i den valgte version. <ins>Grøn betyder tilføjet</ins>]]></key>
|
||||
<key alias="documentRolledBack">Dokument tilbagerullet</key>
|
||||
<key alias="headline">Vælg en version at sammenligne med den nuværende version</key>
|
||||
<key alias="htmlHelp">Her vises den valgte version som html. Hvis du ønsker at se forskellen mellem de 2 versioner på samme tid, brug 'diff'-oversigten</key>
|
||||
<key alias="rollbackTo">Tilbagerulning til</key>
|
||||
<key alias="selectVersion">Vælg version</key>
|
||||
|
||||
@@ -1345,10 +1345,12 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="customCrop">User defined</key>
|
||||
</area>
|
||||
<area alias="rollback">
|
||||
<key alias="headline">Select a version to compare with the current version</key>
|
||||
<key alias="changes">Changes</key>
|
||||
<key alias="created">Created</key>
|
||||
<key alias="currentVersion">Current version</key>
|
||||
<key alias="diffHelp"><![CDATA[This shows the differences between the current version and the selected version<br /><del>Red</del> text will not be shown in the selected version. , <ins>green means added</ins>]]></key>
|
||||
<key alias="documentRolledBack">Document has been rolled back</key>
|
||||
<key alias="headline">Select a version to compare with the current version</key>
|
||||
<key alias="htmlHelp">This displays the selected version as HTML, if you wish to see the difference between 2 versions at the same time, use the diff view</key>
|
||||
<key alias="rollbackTo">Rollback to</key>
|
||||
<key alias="selectVersion">Select version</key>
|
||||
|
||||
@@ -1353,10 +1353,13 @@ To manage your website, simply open the Umbraco back office and start adding con
|
||||
<key alias="customCrop">User defined</key>
|
||||
</area>
|
||||
<area alias="rollback">
|
||||
<key alias="changes">Changes</key>
|
||||
<key alias="created">Created</key>
|
||||
<key alias="headline">Select a version to compare with the current version</key>
|
||||
<key alias="currentVersion">Current version</key>
|
||||
<key alias="diffHelp"><![CDATA[This shows the differences between the current version and the selected version<br /><del>Red</del> text will not be shown in the selected version. , <ins>green means added</ins>]]></key>
|
||||
<key alias="documentRolledBack">Document has been rolled back</key>
|
||||
<key alias="headline">Select a version to compare with the current version</key>
|
||||
<key alias="htmlHelp">This displays the selected version as HTML, if you wish to see the difference between 2 versions at the same time, use the diff view</key>
|
||||
<key alias="rollbackTo">Rollback to</key>
|
||||
<key alias="selectVersion">Select version</key>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
|
||||
|
||||
|
||||
<!--
|
||||
<!--
|
||||
Defines transforms that apply to web.Template.config when creating the Debug web.config.
|
||||
|
||||
This file should contain changes that need to go into the Debug config (the one that everybody
|
||||
@@ -13,14 +12,6 @@
|
||||
file everytime Umbraco builds.
|
||||
-->
|
||||
|
||||
<configSections>
|
||||
<section name="Examine" xdt:Transform="Remove" xdt:Locator="Match(name)" />
|
||||
<section name="ExamineLuceneIndexSets" xdt:Transform="Remove" xdt:Locator="Match(name)" />
|
||||
</configSections>
|
||||
|
||||
<Examine xdt:Transform="Remove" />
|
||||
<ExamineLuceneIndexSets xdt:Transform="Remove" />
|
||||
|
||||
<appSettings>
|
||||
<add key="Umbraco.TestData.Enabled" xdt:Transform="Remove" xdt:Locator="Match(key)"/>
|
||||
<add key="Umbraco.TestData.Enabled" value="true" xdt:Transform="Insert" />
|
||||
|
||||
@@ -30,9 +30,6 @@ namespace Umbraco.Web.ContentApps
|
||||
Weight = Weight
|
||||
});
|
||||
|
||||
case IContent _:
|
||||
return null;
|
||||
|
||||
case IMedia media when !media.ContentType.IsContainer || media.Properties.Count > 0:
|
||||
return _mediaApp ?? (_mediaApp = new ContentApp
|
||||
{
|
||||
@@ -43,9 +40,6 @@ namespace Umbraco.Web.ContentApps
|
||||
Weight = Weight
|
||||
});
|
||||
|
||||
case IMedia _:
|
||||
return null;
|
||||
|
||||
case IMember _:
|
||||
return _memberApp ?? (_memberApp = new ContentApp
|
||||
{
|
||||
@@ -57,7 +51,7 @@ namespace Umbraco.Web.ContentApps
|
||||
});
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"Object type {o.GetType()} is not supported here.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Umbraco.Web.ContentApps
|
||||
});
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"Object type {o.GetType()} is not supported here.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.ContentEditing;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Web.ContentApps
|
||||
{
|
||||
internal class ContentTypeDesignContentAppFactory : IContentAppFactory
|
||||
{
|
||||
private const int Weight = -200;
|
||||
|
||||
private ContentApp _contentTypeApp;
|
||||
|
||||
public ContentApp GetContentAppFor(object source, IEnumerable<IReadOnlyUserGroup> userGroups)
|
||||
{
|
||||
switch (source)
|
||||
{
|
||||
case IContentType _:
|
||||
return _contentTypeApp ?? (_contentTypeApp = new ContentApp()
|
||||
{
|
||||
Alias = "design",
|
||||
Name = "Design",
|
||||
Icon = "icon-document-dashed-line",
|
||||
View = "views/documenttypes/views/design/design.html",
|
||||
Weight = Weight
|
||||
});
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.ContentEditing;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Web.ContentApps
|
||||
{
|
||||
internal class ContentTypeListViewContentAppFactory : IContentAppFactory
|
||||
{
|
||||
private const int Weight = -180;
|
||||
|
||||
private ContentApp _contentTypeApp;
|
||||
|
||||
public ContentApp GetContentAppFor(object source, IEnumerable<IReadOnlyUserGroup> userGroups)
|
||||
{
|
||||
switch (source)
|
||||
{
|
||||
case IContentType _:
|
||||
return _contentTypeApp ?? (_contentTypeApp = new ContentApp()
|
||||
{
|
||||
Alias = "listView",
|
||||
Name = "List view",
|
||||
Icon = "icon-list",
|
||||
View = "views/documenttypes/views/listview/listview.html",
|
||||
Weight = Weight
|
||||
});
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.ContentEditing;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Web.ContentApps
|
||||
{
|
||||
internal class ContentTypePermissionsContentAppFactory : IContentAppFactory
|
||||
{
|
||||
private const int Weight = -160;
|
||||
|
||||
private ContentApp _contentTypeApp;
|
||||
|
||||
public ContentApp GetContentAppFor(object source, IEnumerable<IReadOnlyUserGroup> userGroups)
|
||||
{
|
||||
switch (source)
|
||||
{
|
||||
case IContentType _:
|
||||
return _contentTypeApp ?? (_contentTypeApp = new ContentApp()
|
||||
{
|
||||
Alias = "permissions",
|
||||
Name = "Permissions",
|
||||
Icon = "icon-keychain",
|
||||
View = "views/documenttypes/views/permissions/permissions.html",
|
||||
Weight = Weight
|
||||
});
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.ContentEditing;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Web.ContentApps
|
||||
{
|
||||
internal class ContentTypeTemplatesContentAppFactory : IContentAppFactory
|
||||
{
|
||||
private const int Weight = -140;
|
||||
|
||||
private ContentApp _contentTypeApp;
|
||||
|
||||
public ContentApp GetContentAppFor(object source, IEnumerable<IReadOnlyUserGroup> userGroups)
|
||||
{
|
||||
switch (source)
|
||||
{
|
||||
case IContentType _:
|
||||
return _contentTypeApp ?? (_contentTypeApp = new ContentApp()
|
||||
{
|
||||
Alias = "templates",
|
||||
Name = "Templates",
|
||||
Icon = "icon-layout",
|
||||
View = "views/documenttypes/views/templates/templates.html",
|
||||
Weight = Weight
|
||||
});
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,10 +45,8 @@ namespace Umbraco.Web.ContentApps
|
||||
entityType = "media";
|
||||
dtdId = Core.Constants.DataTypes.DefaultMediaListView;
|
||||
break;
|
||||
case IMember member:
|
||||
return null;
|
||||
default:
|
||||
throw new NotSupportedException($"Object type {o.GetType()} is not supported here.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return CreateContentApp(_dataTypeService, _propertyEditors, entityType, contentTypeAlias, dtdId);
|
||||
|
||||
@@ -551,7 +551,6 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[FileUploadCleanupFilter(false)]
|
||||
public async Task<ContentTypeImportModel> Upload()
|
||||
{
|
||||
if (Request.Content.IsMimeMultipartContent() == false)
|
||||
@@ -577,20 +576,28 @@ namespace Umbraco.Web.Editors
|
||||
var fileName = file.Headers.ContentDisposition.FileName.Trim('\"');
|
||||
var ext = fileName.Substring(fileName.LastIndexOf('.') + 1).ToLower();
|
||||
|
||||
// renaming the file because MultipartFormDataStreamProvider has created a random fileName instead of using the name from the
|
||||
// content-disposition for more than 6 years now. Creating a CustomMultipartDataStreamProvider deriving from MultipartFormDataStreamProvider
|
||||
// seems like a cleaner option, but I'm not sure where to put it and renaming only takes one line of code.
|
||||
System.IO.File.Move(result.FileData[0].LocalFileName, root + "\\" + fileName);
|
||||
var destFileName = root + "\\" + fileName;
|
||||
try
|
||||
{
|
||||
// due to a bug before 8.7.0 we didn't delete temp files, so we need to make sure to delete before
|
||||
// moving else you get errors and the upload fails without a message in the UI (there's a JS error)
|
||||
if(System.IO.File.Exists(destFileName))
|
||||
System.IO.File.Delete(destFileName);
|
||||
|
||||
// renaming the file because MultipartFormDataStreamProvider has created a random fileName instead of using the name from the
|
||||
// content-disposition for more than 6 years now. Creating a CustomMultipartDataStreamProvider deriving from MultipartFormDataStreamProvider
|
||||
// seems like a cleaner option, but I'm not sure where to put it and renaming only takes one line of code.
|
||||
System.IO.File.Move(result.FileData[0].LocalFileName, destFileName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error<ContentTypeController>(ex, "Error uploading udt file to App_Data: {File}", destFileName);
|
||||
}
|
||||
|
||||
if (ext.InvariantEquals("udt"))
|
||||
{
|
||||
model.TempFileName = Path.Combine(root, fileName);
|
||||
|
||||
model.UploadedFiles.Add(new ContentPropertyFile
|
||||
{
|
||||
TempFilePath = model.TempFileName
|
||||
});
|
||||
|
||||
var xd = new XmlDocument
|
||||
{
|
||||
XmlResolver = null
|
||||
|
||||
@@ -142,7 +142,7 @@ namespace Umbraco.Web.Editors
|
||||
//need to create a specific content result formatted as HTML since this controller has been configured
|
||||
//with only json formatters.
|
||||
result.Content = new StringContent(
|
||||
_componentRenderer.RenderMacro(pageId, m.Alias, macroParams).ToString(),
|
||||
_componentRenderer.RenderMacroForContent(publishedContent, m.Alias, macroParams).ToString(),
|
||||
Encoding.UTF8,
|
||||
"text/html");
|
||||
|
||||
|
||||
@@ -253,12 +253,12 @@ namespace Umbraco.Web
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to create a new form to execute in the Umbraco request pipeline against a locally declared controller
|
||||
/// Helper method to create a new form to execute in the Umbraco request pipeline against a locally declared controller.
|
||||
/// </summary>
|
||||
/// <param name="html"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <param name="controllerName"></param>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="html">The HTML helper.</param>
|
||||
/// <param name="action">Name of the action.</param>
|
||||
/// <param name="controllerName">Name of the controller.</param>
|
||||
/// <param name="method">The method.</param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName, FormMethod method)
|
||||
{
|
||||
@@ -315,9 +315,9 @@ namespace Umbraco.Web
|
||||
/// <param name="method"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName,
|
||||
object additionalRouteVals,
|
||||
object htmlAttributes,
|
||||
FormMethod method)
|
||||
object additionalRouteVals,
|
||||
object htmlAttributes,
|
||||
FormMethod method)
|
||||
{
|
||||
return html.BeginUmbracoForm(action, controllerName, additionalRouteVals, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), method);
|
||||
}
|
||||
@@ -332,8 +332,8 @@ namespace Umbraco.Web
|
||||
/// <param name="htmlAttributes"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName,
|
||||
object additionalRouteVals,
|
||||
object htmlAttributes)
|
||||
object additionalRouteVals,
|
||||
object htmlAttributes)
|
||||
{
|
||||
return html.BeginUmbracoForm(action, controllerName, additionalRouteVals, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
|
||||
}
|
||||
@@ -349,9 +349,9 @@ namespace Umbraco.Web
|
||||
/// <param name="method"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName,
|
||||
object additionalRouteVals,
|
||||
IDictionary<string, object> htmlAttributes,
|
||||
FormMethod method)
|
||||
object additionalRouteVals,
|
||||
IDictionary<string, object> htmlAttributes,
|
||||
FormMethod method)
|
||||
{
|
||||
if (action == null) throw new ArgumentNullException(nameof(action));
|
||||
if (string.IsNullOrWhiteSpace(action)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(action));
|
||||
@@ -371,8 +371,8 @@ namespace Umbraco.Web
|
||||
/// <param name="htmlAttributes"></param>
|
||||
/// <returns></returns>
|
||||
public static MvcForm BeginUmbracoForm(this HtmlHelper html, string action, string controllerName,
|
||||
object additionalRouteVals,
|
||||
IDictionary<string, object> htmlAttributes)
|
||||
object additionalRouteVals,
|
||||
IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
if (action == null) throw new ArgumentNullException(nameof(action));
|
||||
if (string.IsNullOrWhiteSpace(action)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(action));
|
||||
@@ -840,19 +840,32 @@ namespace Umbraco.Web
|
||||
#region If
|
||||
|
||||
/// <summary>
|
||||
/// If the test is true, the string valueIfTrue will be returned, otherwise the valueIfFalse will be returned.
|
||||
/// If <paramref name="test" /> is <c>true</c>, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
public static IHtmlString If(this HtmlHelper html, bool test, string valueIfTrue, string valueIfFalse)
|
||||
/// <param name="html">The HTML helper.</param>
|
||||
/// <param name="test">If set to <c>true</c> returns <paramref name="valueIfTrue" />; otherwise, <see cref="string.Empty" />.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
public static IHtmlString If(this HtmlHelper html, bool test, string valueIfTrue)
|
||||
{
|
||||
return test ? new HtmlString(valueIfTrue) : new HtmlString(valueIfFalse);
|
||||
return If(html, test, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the test is true, the string valueIfTrue will be returned, otherwise the valueIfFalse will be returned.
|
||||
/// If <paramref name="test" /> is <c>true</c>, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
public static IHtmlString If(this HtmlHelper html, bool test, string valueIfTrue)
|
||||
/// <param name="html">The HTML helper.</param>
|
||||
/// <param name="test">If set to <c>true</c> returns <paramref name="valueIfTrue" />; otherwise, <paramref name="valueIfFalse" />.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
public static IHtmlString If(this HtmlHelper html, bool test, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return test ? new HtmlString(valueIfTrue) : new HtmlString(string.Empty);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(test ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -862,16 +875,32 @@ namespace Umbraco.Web
|
||||
private static readonly HtmlStringUtilities StringUtilities = new HtmlStringUtilities();
|
||||
|
||||
/// <summary>
|
||||
/// Replaces text line breaks with HTML line breaks
|
||||
/// Replaces text line breaks with HTML line breaks.
|
||||
/// </summary>
|
||||
/// <param name="helper"></param>
|
||||
/// <param name="helper">The HTML helper.</param>
|
||||
/// <param name="text">The text.</param>
|
||||
/// <returns>The text with text line breaks replaced with HTML line breaks (<br/>)</returns>
|
||||
/// <returns>
|
||||
/// The text with text line breaks replaced with HTML line breaks (<c><br /></c>).
|
||||
/// </returns>
|
||||
[Obsolete("This method doesn't HTML encode the text. Use ReplaceLineBreaks instead.")]
|
||||
public static IHtmlString ReplaceLineBreaksForHtml(this HtmlHelper helper, string text)
|
||||
{
|
||||
return StringUtilities.ReplaceLineBreaksForHtml(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HTML encodes the text and replaces text line breaks with HTML line breaks.
|
||||
/// </summary>
|
||||
/// <param name="helper">The HTML helper.</param>
|
||||
/// <param name="text">The text.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded text with text line breaks replaced with HTML line breaks (<c><br /></c>).
|
||||
/// </returns>
|
||||
public static IHtmlString ReplaceLineBreaks(this HtmlHelper helper, string text)
|
||||
{
|
||||
return StringUtilities.ReplaceLineBreaks(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a hash based on the text string passed in. This method will detect the
|
||||
/// security requirements (is FIPS enabled) and return an appropriate hash.
|
||||
|
||||
@@ -16,21 +16,25 @@ namespace Umbraco.Web
|
||||
public sealed class HtmlStringUtilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Replaces text line breaks with HTML line breaks
|
||||
/// Replaces text line breaks with HTML line breaks.
|
||||
/// </summary>
|
||||
/// <param name="text">The text.</param>
|
||||
/// <returns>The text with text line breaks replaced with HTML line breaks (<c><br /></c>).
|
||||
/// <returns>
|
||||
/// The text with text line breaks replaced with HTML line breaks (<c><br /></c>).
|
||||
/// </returns>
|
||||
[Obsolete("This method doesn't HTML encode the text. Use ReplaceLineBreaks instead.")]
|
||||
public HtmlString ReplaceLineBreaksForHtml(string text)
|
||||
{
|
||||
return new HtmlString(text.Replace("\r\n", @"<br />").Replace("\n", @"<br />").Replace("\r", @"<br />"));
|
||||
return new HtmlString(text.Replace("\r\n", @"<br />").Replace("\n", @"<br />").Replace("\r", @"<br />"));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// HTML encodes the text and replaces text line breaks with HTML line breaks.
|
||||
/// </summary>
|
||||
/// <param name="text">The text.</param>
|
||||
/// <returns>The HTML encoded text with text line breaks replaced with HTML line breaks (<c><br /></c>).</returns>
|
||||
/// <returns>
|
||||
/// The HTML encoded text with text line breaks replaced with HTML line breaks (<c><br /></c>).
|
||||
/// </returns>
|
||||
public IHtmlString ReplaceLineBreaks(string text)
|
||||
{
|
||||
var value = HttpUtility.HtmlEncode(text)?
|
||||
|
||||
@@ -42,5 +42,18 @@ namespace Umbraco.Web
|
||||
/// <param name="parameters">The parameters.</param>
|
||||
/// <returns></returns>
|
||||
IHtmlString RenderMacro(int contentId, string alias, IDictionary<string, object> parameters);
|
||||
|
||||
/// <summary>
|
||||
/// Renders the macro with the specified alias, passing in the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="content">An IPublishedContent to use for the context for the macro rendering</param>
|
||||
/// <param name="alias">The alias.</param>
|
||||
/// <param name="parameters">The parameters.</param>
|
||||
/// <returns>A raw HTML string of the macro output</returns>
|
||||
/// <remarks>
|
||||
/// Currently only used when the node is unpublished and unable to get the contentId item from the
|
||||
/// content cache as its unpublished. This deals with taking in a preview/draft version of the content node
|
||||
/// </remarks>
|
||||
IHtmlString RenderMacroForContent(IPublishedContent content, string alias, IDictionary<string, object> parameters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Models.ContentEditing
|
||||
{
|
||||
@@ -27,5 +28,8 @@ namespace Umbraco.Web.Models.ContentEditing
|
||||
[DataMember(Name = "allowSegmentVariant")]
|
||||
public bool AllowSegmentVariant { get; set; }
|
||||
|
||||
[DataMember(Name = "apps")]
|
||||
public IEnumerable<ContentApp> ContentApps { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.Editors;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
[DataContract(Name = "contentTypeImportModel")]
|
||||
public class ContentTypeImportModel : INotificationModel, IHaveUploadedFiles
|
||||
public class ContentTypeImportModel : INotificationModel
|
||||
{
|
||||
[DataMember(Name = "alias")]
|
||||
public string Alias { get; set; }
|
||||
@@ -19,7 +18,5 @@ namespace Umbraco.Web.Models
|
||||
|
||||
[DataMember(Name = "tempFileName")]
|
||||
public string TempFileName { get; set; }
|
||||
|
||||
public List<ContentPropertyFile> UploadedFiles => new List<ContentPropertyFile>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using Umbraco.Core;
|
||||
using Umbraco.Core.Mapping;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.ContentEditing;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.ContentApps;
|
||||
@@ -81,7 +82,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
return urlHelper.GetUmbracoApiService<MemberTreeController>(controller => controller.GetTreeNode(source.Key.ToString("N"), null));
|
||||
}
|
||||
|
||||
public IEnumerable<ContentApp> GetContentApps(IContentBase source)
|
||||
public IEnumerable<ContentApp> GetContentApps(IUmbracoEntity source)
|
||||
{
|
||||
var apps = _contentAppDefinitions.GetContentAppsFor(source).ToArray();
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
/// </summary>
|
||||
internal class ContentTypeMapDefinition : IMapDefinition
|
||||
{
|
||||
private readonly CommonMapper _commonMapper;
|
||||
private readonly PropertyEditorCollection _propertyEditors;
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IFileService _fileService;
|
||||
@@ -25,10 +26,11 @@ namespace Umbraco.Web.Models.Mapping
|
||||
private readonly IMemberTypeService _memberTypeService;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public ContentTypeMapDefinition(PropertyEditorCollection propertyEditors, IDataTypeService dataTypeService, IFileService fileService,
|
||||
public ContentTypeMapDefinition(CommonMapper commonMapper, PropertyEditorCollection propertyEditors, IDataTypeService dataTypeService, IFileService fileService,
|
||||
IContentTypeService contentTypeService, IMediaTypeService mediaTypeService, IMemberTypeService memberTypeService,
|
||||
ILogger logger)
|
||||
{
|
||||
_commonMapper = commonMapper;
|
||||
_propertyEditors = propertyEditors;
|
||||
_dataTypeService = dataTypeService;
|
||||
_fileService = fileService;
|
||||
@@ -122,6 +124,7 @@ namespace Umbraco.Web.Models.Mapping
|
||||
|
||||
target.AllowCultureVariant = source.VariesByCulture();
|
||||
target.AllowSegmentVariant = source.VariesBySegment();
|
||||
target.ContentApps = _commonMapper.GetContentApps(source);
|
||||
|
||||
//sync templates
|
||||
target.AllowedTemplates = context.MapEnumerable<ITemplate, EntityBasic>(source.AllowedTemplates);
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Web.Mvc
|
||||
|
||||
public void WriteToHtmlTextWriter(System.Web.UI.HtmlTextWriter html)
|
||||
{
|
||||
html.Write(Content);
|
||||
html.WriteEncodedText(Content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,29 +287,82 @@ namespace Umbraco.Web
|
||||
return content.Id == other.Id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is equal to <paramref name="other" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static HtmlString IsEqual(this IPublishedContent content, IPublishedContent other, string valueIfTrue)
|
||||
{
|
||||
return content.IsEqual(other, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is equal to <paramref name="other" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static HtmlString IsEqual(this IPublishedContent content, IPublishedContent other, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsEqual(other) ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(content.IsEqual(other) ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is not equal to <paramref name="other" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static bool IsNotEqual(this IPublishedContent content, IPublishedContent other)
|
||||
{
|
||||
return content.IsEqual(other) == false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is not equal to <paramref name="other" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static HtmlString IsNotEqual(this IPublishedContent content, IPublishedContent other, string valueIfTrue)
|
||||
{
|
||||
return content.IsNotEqual(other, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is not equal to <paramref name="other" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static HtmlString IsNotEqual(this IPublishedContent content, IPublishedContent other, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsNotEqual(other) ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(content.IsNotEqual(other) ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -321,14 +374,35 @@ namespace Umbraco.Web
|
||||
return other.Level < content.Level && content.Path.InvariantStartsWith(other.Path.EnsureEndsWith(','));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is a decendant of <paramref name="other" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static HtmlString IsDescendant(this IPublishedContent content, IPublishedContent other, string valueIfTrue)
|
||||
{
|
||||
return content.IsDescendant(other, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is a decendant of <paramref name="other" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static HtmlString IsDescendant(this IPublishedContent content, IPublishedContent other, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsDescendant(other) ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(content.IsDescendant(other) ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
public static bool IsDescendantOrSelf(this IPublishedContent content, IPublishedContent other)
|
||||
@@ -336,14 +410,35 @@ namespace Umbraco.Web
|
||||
return content.Path.InvariantEquals(other.Path) || content.IsDescendant(other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is a decendant of <paramref name="other" /> or are the same, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static HtmlString IsDescendantOrSelf(this IPublishedContent content, IPublishedContent other, string valueIfTrue)
|
||||
{
|
||||
return content.IsDescendantOrSelf(other, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is a decendant of <paramref name="other" /> or are the same, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static HtmlString IsDescendantOrSelf(this IPublishedContent content, IPublishedContent other, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsDescendantOrSelf(other) ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(content.IsDescendantOrSelf(other) ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
public static bool IsAncestor(this IPublishedContent content, IPublishedContent other)
|
||||
@@ -351,14 +446,35 @@ namespace Umbraco.Web
|
||||
return content.Level < other.Level && other.Path.InvariantStartsWith(content.Path.EnsureEndsWith(','));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is an ancestor of <paramref name="other" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static HtmlString IsAncestor(this IPublishedContent content, IPublishedContent other, string valueIfTrue)
|
||||
{
|
||||
return content.IsAncestor(other, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is an ancestor of <paramref name="other" />, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static HtmlString IsAncestor(this IPublishedContent content, IPublishedContent other, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsAncestor(other) ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(content.IsAncestor(other) ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
public static bool IsAncestorOrSelf(this IPublishedContent content, IPublishedContent other)
|
||||
@@ -366,14 +482,35 @@ namespace Umbraco.Web
|
||||
return other.Path.InvariantEquals(content.Path) || content.IsAncestor(other);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is an ancestor of <paramref name="other" /> or are the same, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <see cref="string.Empty" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static HtmlString IsAncestorOrSelf(this IPublishedContent content, IPublishedContent other, string valueIfTrue)
|
||||
{
|
||||
return content.IsAncestorOrSelf(other, valueIfTrue, string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the specified <paramref name="content" /> is an ancestor of <paramref name="other" /> or are the same, the HTML encoded <paramref name="valueIfTrue" /> will be returned; otherwise, <paramref name="valueIfFalse" />.
|
||||
/// </summary>
|
||||
/// <param name="content">The content.</param>
|
||||
/// <param name="other">The other content.</param>
|
||||
/// <param name="valueIfTrue">The value if <c>true</c>.</param>
|
||||
/// <param name="valueIfFalse">The value if <c>false</c>.</param>
|
||||
/// <returns>
|
||||
/// The HTML encoded value.
|
||||
/// </returns>
|
||||
// TODO: This method should be removed or moved to an extension method on HtmlHelper.
|
||||
public static HtmlString IsAncestorOrSelf(this IPublishedContent content, IPublishedContent other, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return new HtmlString(content.IsAncestorOrSelf(other) ? valueIfTrue : valueIfFalse);
|
||||
return new HtmlString(HttpUtility.HtmlEncode(content.IsAncestorOrSelf(other) ? valueIfTrue : valueIfFalse));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -239,7 +239,11 @@ namespace Umbraco.Web.Runtime
|
||||
composition.ContentApps()
|
||||
.Append<ListViewContentAppFactory>()
|
||||
.Append<ContentEditorContentAppFactory>()
|
||||
.Append<ContentInfoContentAppFactory>();
|
||||
.Append<ContentInfoContentAppFactory>()
|
||||
.Append<ContentTypeDesignContentAppFactory>()
|
||||
.Append<ContentTypeListViewContentAppFactory>()
|
||||
.Append<ContentTypePermissionsContentAppFactory>()
|
||||
.Append<ContentTypeTemplatesContentAppFactory>();
|
||||
|
||||
// register back office sections in the order we want them rendered
|
||||
composition.Sections()
|
||||
|
||||
@@ -136,6 +136,10 @@
|
||||
<Compile Include="Composing\CompositionExtensions\Installer.cs" />
|
||||
<Compile Include="Composing\LightInject\LightInjectContainer.cs" />
|
||||
<Compile Include="Compose\BackOfficeUserAuditEventsComponent.cs" />
|
||||
<Compile Include="ContentApps\ContentTypeTemplatesContentAppFactory.cs" />
|
||||
<Compile Include="ContentApps\ContentTypePermissionsContentAppFactory.cs" />
|
||||
<Compile Include="ContentApps\ContentTypeListViewContentAppFactory.cs" />
|
||||
<Compile Include="ContentApps\ContentTypeDesignContentAppFactory.cs" />
|
||||
<Compile Include="ContentApps\ListViewContentAppFactory.cs" />
|
||||
<Compile Include="Dashboards\ContentDashboard.cs" />
|
||||
<Compile Include="Dashboards\DashboardCollection.cs" />
|
||||
|
||||
@@ -102,6 +102,15 @@ namespace Umbraco.Web
|
||||
return RenderMacro(content, alias, parameters);
|
||||
}
|
||||
|
||||
|
||||
public IHtmlString RenderMacroForContent(IPublishedContent content, string alias, IDictionary<string, object> parameters)
|
||||
{
|
||||
if(content == null)
|
||||
throw new InvalidOperationException("Cannot render a macro, IPublishedContent is null");
|
||||
|
||||
return RenderMacro(content, alias, parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renders the macro with the specified alias, passing in the specified parameters.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user