Compare commits

..

2 Commits

Author SHA1 Message Date
kgiszewski dc3c1a72a8 Add some null checks 2016-05-03 10:11:13 -04:00
kgiszewski 3a30c7ba40 Force tostring if a value is present 2016-05-02 13:59:58 -04:00
51 changed files with 214 additions and 1544 deletions
+1 -2
View File
@@ -62,5 +62,4 @@ VersionInfo.cs
.builds
.svn
.hg
.hgignore
app/Umbraco/.vs/config/applicationhost.config
.hgignore
+2 -5
View File
@@ -85,7 +85,6 @@ module.exports = function(grunt) {
'app/controllers/controller_versioned.js',
'app/controllers/config.controller.js',
'app/controllers/config.dialog.controller.js',
'app/controllers/config.global.controller.js',
'app/directives/archetypeproperty.js',
'app/directives/archetypesubmitwatcher.js',
'app/directives/archetypecustomview.js',
@@ -96,8 +95,7 @@ module.exports = function(grunt) {
'app/resources/archetypePropertyEditorResource.js',
'app/services/archetypeService.js',
'app/services/archetypeLabelService.js',
'app/services/archetypeCacheService.js',
'app/services/archetypeGlobalConfigService.js'
'app/services/archetypeCacheService.js'
],
dest: '<%= basePath %>/js/archetype.js'
}
@@ -271,8 +269,7 @@ module.exports = function(grunt) {
'app/controllers/*.js',
'!app/controllers/controller.js',
'!app/controllers/config.controller.js',
'!app/controllers/config.dialog.controller.js',
'!app/controllers/config.global.controller.js'
'!app/controllers/config.dialog.controller.js'
],
less: [
'app/less/*.less',
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2016 Kevin Giszewski LLC
Copyright (c) 2014 Imulus
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
+2 -8
View File
@@ -10,23 +10,17 @@ Install the selected <a href='https://github.com/imulus/Archetype/releases'>rele
## Official Docs ##
https://github.com/kgiszewski/ArchetypeManual
Get up and running in 15 minutes! https://www.youtube.com/watch?v=79LksNwGjLk
## News and Updates ##
##News and Updates##
Follow us on Twitter https://twitter.com/ArchetypeKit
## Core Team ##
##Core Team##
* Kevin Giszewski (founder/project lead) - University of Notre Dame - https://kevin.giszewski.com/
* Tom Fulton (founder) - Tonic - http://hellotonic.com/
* Lee Kelleher - Umbrella - http://www.umbrellainc.co.uk/
* Matt Brailsford - The Outfield - http://www.theoutfield.co.uk/
* Kenn Jacobsen - Vertica - http://kennjacobsen.dk/
## Donate!
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=KBKWLURGLGU6L)
This project is funded by the core team members' time only. We don't charge for Archetype but it does take quite a bit of effort to keep it up-to-date with Umbraco core changes. If you're making a few bucks off of Archetype, we wouldn't refuse a donation :)
## Contribute ##
Want to contribute to Archetype? You'll want to use Grunt (our task runner) to help you integrate with a local copy of Umbraco.
@@ -263,7 +263,6 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PropertyValueConverter\PropertyValueConverterTests.cs" />
<Compile Include="PublishedContent\ArchetypePublishedContentTests.cs" />
<Compile Include="PublishedContent\TypeConverterTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
@@ -1,68 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Archetype.Models;
using Archetype.PropertyConverters;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models;
namespace Archetype.Tests.PublishedContent
{
[TestFixture]
public class TypeConverterTests
{
private ArchetypeModel _archetype;
[TestFixtureSetUp]
public void Init()
{
var archetypeJson = System.IO.File.ReadAllText("..\\..\\Data\\sample-1.json");
var converter = new ArchetypeValueConverter();
_archetype = (ArchetypeModel)converter.ConvertDataToSource(null, archetypeJson, false);
}
[TestCase(typeof(ArchetypeModel), true)]
[TestCase(typeof(ArchetypePublishedContentSet), true)]
[TestCase(typeof(IEnumerable<IPublishedContent>), true)]
[TestCase(typeof(string), true)]
[TestCase(typeof(int), false)]
[TestCase(typeof(ArchetypeFieldsetModel), false)]
public void ArchetypeModel_ConvertsTo_EnumerablePublishedContent(Type destinationType, bool expected)
{
Assert.IsNotNull(_archetype);
var attempt = _archetype.TryConvertTo(destinationType);
Assert.That(attempt.Success, Is.EqualTo(expected));
if (attempt.Success)
{
Assert.IsNotNull(attempt.Result);
Assert.That(attempt.Result, Is.InstanceOf(destinationType));
}
}
[TestCase(typeof(ArchetypeFieldsetModel), true)]
[TestCase(typeof(ArchetypePublishedContent), true)]
[TestCase(typeof(IPublishedContent), true)]
[TestCase(typeof(string), true)]
[TestCase(typeof(int), false)]
[TestCase(typeof(ArchetypeModel), false)]
public void ArchetypeFieldsetModel_ConvertsTo_PublishedContent(Type destinationType, bool expected)
{
CollectionAssert.IsNotEmpty(_archetype.Fieldsets);
var attempt = _archetype.First().TryConvertTo(destinationType);
Assert.That(attempt.Success, Is.EqualTo(expected));
if (attempt.Success)
{
Assert.IsNotNull(attempt.Result);
Assert.That(attempt.Result, Is.InstanceOf(destinationType));
}
}
}
}
@@ -1,7 +1,9 @@
using System.Collections.Generic;
using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Web.Http;
using AutoMapper;
using Umbraco.Core.Models;
@@ -9,14 +11,12 @@ using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc;
using Umbraco.Web.Editors;
using Archetype.Extensions;
using Archetype.Models;
namespace Archetype.Api
{
/// <summary>
/// Controller that handles datatype related interactions.
/// </summary>
/// <seealso cref="Umbraco.Web.Editors.UmbracoAuthorizedJsonController" />
[PluginController("ArchetypeApi")]
public class ArchetypeDataTypeController : UmbracoAuthorizedJsonController
{
@@ -24,14 +24,14 @@ namespace Archetype.Api
{
return
global::Umbraco.Core.PropertyEditors.PropertyEditorResolver.Current.PropertyEditors
.Select(x => new { defaultPreValues = x.DefaultPreValuesForArchetype(), alias = x.Alias, view = x.ValueEditor.View });
.Select(x => new {defaultPreValues = x.DefaultPreValuesForArchetype(), alias = x.Alias, view = x.ValueEditor.View});
}
/// <summary>
/// Gets all datatypes.
/// </summary>
/// <returns></returns>
public object GetAll()
public object GetAll()
{
var dataTypes = Services.DataTypeService.GetAllDataTypeDefinitions();
return dataTypes.Select(t => new { guid = t.Key, name = t.Name });
@@ -68,14 +68,11 @@ namespace Archetype.Api
public object GetByGuid(Guid guid, string contentTypeAlias, string propertyTypeAlias, string archetypeAlias, int nodeId)
{
var dataType = Services.DataTypeService.GetDataTypeDefinitionById(guid);
if (dataType == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
var dataTypeDisplay = Mapper.Map<IDataTypeDefinition, DataTypeDisplay>(dataType);
return new { selectedEditor = dataTypeDisplay.SelectedEditor, preValues = dataTypeDisplay.PreValues, contentTypeAlias = contentTypeAlias, propertyTypeAlias = propertyTypeAlias, archetypeAlias = archetypeAlias, nodeId = nodeId };
}
@@ -85,58 +82,19 @@ namespace Archetype.Api
/// <returns></returns>
public object GetDllVersion()
{
return new { dllVersion = ArchetypeHelper.Instance.DllVersion() };
return new {dllVersion = _version()};
}
/// <summary>
/// Globals the settings.
/// Gets the DLL version from the file.
/// </summary>
/// <returns>System.Object.</returns>
[HttpGet]
public object GlobalSettings()
/// <returns></returns>
private string _version()
{
return new
{
isCheckingForUpdates = ArchetypeGlobalSettings.Instance.CheckForUpdates
};
}
var asm = Assembly.GetExecutingAssembly();
var fvi = FileVersionInfo.GetVersionInfo(asm.Location);
/// <summary>
/// Sets the check for updates.
/// </summary>
/// <param name="isChecking">if set to <c>true</c> [is checking].</param>
[HttpPost]
public void SetCheckForUpdates([FromBody] bool isChecking)
{
ArchetypeGlobalSettings.Instance.CheckForUpdates = isChecking;
ArchetypeGlobalSettings.Instance.Save();
}
/// <summary>
/// Checks for updates.
/// </summary>
/// <returns>System.Object.</returns>
[HttpPost]
public object CheckForUpdates()
{
if (!ArchetypeGlobalSettings.Instance.CheckForUpdates)
{
return new
{
isUpdateAvailable = false
};
}
var updateNotificationModel = ArchetypeHelper.Instance.CheckForUpdates();
return new
{
isUpdateAvailable = updateNotificationModel.IsUpdateAvailable,
headline = updateNotificationModel.Headline,
type = updateNotificationModel.Type,
message = updateNotificationModel.Message,
url = updateNotificationModel.Url
};
return fvi.FileVersion;
}
}
}
@@ -129,7 +129,6 @@
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>False</Private>
@@ -239,8 +238,6 @@
<Compile Include="Extensions\ArchetypePropertyModelExtensions.cs" />
<Compile Include="Extensions\PropertyEditorExtensions.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
<Compile Include="Models\ArchetypeConfigFileModel.cs" />
<Compile Include="Models\ArchetypeGlobalSettings.cs" />
<Compile Include="Models\ArchetypeModel.cs" />
<Compile Include="Models\ArchetypePreValue.cs" />
<Compile Include="Models\ArchetypePreValueFieldset.cs" />
@@ -251,13 +248,10 @@
<Compile Include="Models\ArchetypePublishedContent.cs" />
<Compile Include="Models\ArchetypePublishedContentSet.cs" />
<Compile Include="Models\ArchetypePublishedProperty.cs" />
<Compile Include="Models\ArchetypeUpdateNotification.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\VersionInfo.cs" />
<Compile Include="PropertyConverters\ArchetypeValueConverter.cs" />
<Compile Include="PropertyEditors\ArchetypePropertyEditor.cs" />
<Compile Include="TypeConverters\ArchetypeFieldsetModelConverter.cs" />
<Compile Include="TypeConverters\ArchetypeModelConverter.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
@@ -12,8 +12,5 @@
public const string CacheKey_DataTypeByGuid = "";
public const string CacheKey_PreValueFromDataTypeId = "Archetype_GetArchetypePreValueFromDataTypeId_";
public const string UmbracoVersionAlias = "umbracoConfigurationStatus";
public const string NotificationUrl = "https://api.gizmo42.com/v1/archetype/check-for-updates";
}
}
@@ -1,21 +1,12 @@
using System;
using System.Configuration;
using System.Linq;
using System.Net.Http;
using System.Text;
using Archetype.Models;
using Newtonsoft.Json;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using System.Reflection;
using System.Diagnostics;
using System.Net;
/// <summary>
/// The Extensions namespace.
/// </summary>
namespace Archetype.Extensions
{
/// <summary>
@@ -23,52 +14,20 @@ namespace Archetype.Extensions
/// </summary>
public class ArchetypeHelper
{
/// <summary>
/// The json settings
/// </summary>
protected JsonSerializerSettings _jsonSettings;
/// <summary>
/// The application
/// </summary>
protected ApplicationContext _app;
/// <summary>
/// The pad lock
/// </summary>
private static readonly object _padLock = new object();
/// <summary>
/// The instance
/// </summary>
private static ArchetypeHelper _instance = new ArchetypeHelper();
private static readonly ArchetypeHelper _instance = new ArchetypeHelper();
internal static ArchetypeHelper Instance { get { return _instance; } }
/// <summary>
/// Gets the instance.
/// Initializes a new instance of the <see cref="ArchetypeHelper"/> class.
/// </summary>
/// <value>The instance.</value>
internal static ArchetypeHelper Instance {
get
{
if (_instance == null)
{
lock (_padLock)
{
if (_instance == null)
{
_instance = new ArchetypeHelper();
}
}
}
return _instance;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="ArchetypeHelper" /> class.
/// </summary>
private ArchetypeHelper()
internal ArchetypeHelper()
{
var dcr = new Newtonsoft.Json.Serialization.DefaultContractResolver();
dcr.DefaultMembersSearchFlags |= BindingFlags.NonPublic;
dcr.DefaultMembersSearchFlags |= System.Reflection.BindingFlags.NonPublic;
_jsonSettings = new JsonSerializerSettings { ContractResolver = dcr };
_app = ApplicationContext.Current;
@@ -77,7 +36,9 @@ namespace Archetype.Extensions
/// <summary>
/// Gets the json serializer settings.
/// </summary>
/// <value>The json serializer settings.</value>
/// <value>
/// The json serializer settings.
/// </value>
internal JsonSerializerSettings JsonSerializerSettings { get { return _jsonSettings; } }
/// <summary>
@@ -85,7 +46,7 @@ namespace Archetype.Extensions
/// </summary>
/// <param name="sourceJson">The source JSON.</param>
/// <param name="dataTypePreValues">The data type pre values.</param>
/// <returns>ArchetypeModel.</returns>
/// <returns></returns>
internal ArchetypeModel DeserializeJsonToArchetype(string sourceJson, PreValueCollection dataTypePreValues)
{
try
@@ -117,7 +78,7 @@ namespace Archetype.Extensions
/// <param name="sourceJson">The source JSON.</param>
/// <param name="dataTypeId">The data type identifier.</param>
/// <param name="hostContentType">Type of the host content.</param>
/// <returns>ArchetypeModel.</returns>
/// <returns></returns>
internal ArchetypeModel DeserializeJsonToArchetype(string sourceJson, int dataTypeId, PublishedContentType hostContentType = null)
{
try
@@ -137,7 +98,7 @@ namespace Archetype.Extensions
return archetype;
}
catch (Exception ex)
catch
{
return new ArchetypeModel();
}
@@ -147,66 +108,21 @@ namespace Archetype.Extensions
/// Determines whether datatypeId has had it's PVC overridden.
/// </summary>
/// <param name="dataTypeId">The data type identifier.</param>
/// <returns><c>true</c> if [is property value converter overridden] [the specified data type identifier]; otherwise, <c>false</c>.</returns>
/// <returns></returns>
internal bool IsPropertyValueConverterOverridden(int dataTypeId)
{
var prevalues = GetArchetypePreValueFromDataTypeId(dataTypeId);
if (prevalues == null)
return false;
return prevalues.OverrideDefaultPropertyValueConverter;
}
/// <summary>
/// Checks for updates.
/// </summary>
/// <returns>ArchetypeUpdateNotification.</returns>
internal ArchetypeUpdateNotification CheckForUpdates()
{
try
{
using (var client = new HttpClient())
{
var content = new StringContent(JsonConvert.SerializeObject(new
{
umbracoVersion = ConfigurationManager.AppSettings[Constants.UmbracoVersionAlias],
archetypeVersion = DllVersion(),
id = ArchetypeGlobalSettings.Instance.Id
}), Encoding.UTF8, "application/json");
client.DefaultRequestHeaders.Add("x-api-key-id", ArchetypeGlobalSettings.Instance.ApiKey.ToString());
var response = client.PostAsync(new Uri(Constants.NotificationUrl), content).Result;
if (response.StatusCode == HttpStatusCode.OK)
{
var responseString = response.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<ArchetypeUpdateNotification>(responseString);
}
return new ArchetypeUpdateNotification
{
IsUpdateAvailable = false
};
}
}
catch (Exception ex)
{
//if anything goes wrong let's make sure we don't break their site
return new ArchetypeUpdateNotification
{
IsUpdateAvailable = false
};
}
}
/// <summary>
/// Gets the archetype pre value from data type identifier.
/// </summary>
/// <param name="dataTypeId">The data type identifier.</param>
/// <returns>ArchetypePreValue.</returns>
/// <returns></returns>
private ArchetypePreValue GetArchetypePreValueFromDataTypeId(int dataTypeId)
{
return _app.ApplicationCache.RuntimeCache.GetCacheItem(
@@ -231,7 +147,7 @@ namespace Archetype.Extensions
/// Gets the archetype pre value from pre values collection.
/// </summary>
/// <param name="dataTypePreValues">The data type pre values.</param>
/// <returns>ArchetypePreValue.</returns>
/// <returns></returns>
private ArchetypePreValue GetArchetypePreValueFromPreValuesCollection(PreValueCollection dataTypePreValues)
{
var preValueAsString = dataTypePreValues.PreValuesAsDictionary.First().Value.Value;
@@ -243,7 +159,7 @@ namespace Archetype.Extensions
/// Gets the data type by unique identifier.
/// </summary>
/// <param name="guid">The unique identifier.</param>
/// <returns>IDataTypeDefinition.</returns>
/// <returns></returns>
internal IDataTypeDefinition GetDataTypeByGuid(Guid guid)
{
return (IDataTypeDefinition)ApplicationContext.Current.ApplicationCache.RuntimeCache.GetCacheItem(
@@ -256,7 +172,6 @@ namespace Archetype.Extensions
/// </summary>
/// <param name="archetype">The Archetype to add the additional metadata to</param>
/// <param name="preValue">The configuration of the Archetype</param>
/// <param name="hostContentType">Type of the host content.</param>
private void RetrieveAdditionalProperties(ref ArchetypeModel archetype, ArchetypePreValue preValue, PublishedContentType hostContentType = null)
{
foreach (var fieldset in preValue.Fieldsets)
@@ -282,6 +197,7 @@ namespace Archetype.Extensions
/// <summary>
/// Retrieves additional metadata that isn't available on the stored model of an ArchetypePreValue
/// </summary>
/// <param name="archetype">The Archetype to add the additional metadata to</param>
/// <param name="preValue">The configuration of the Archetype</param>
private void RetrieveAdditionalProperties(ref ArchetypePreValue preValue)
{
@@ -293,18 +209,5 @@ namespace Archetype.Extensions
}
}
}
/// <summary>
/// Gets the DLL version from the file.
/// </summary>
/// <returns>System.String.</returns>
internal string DllVersion()
{
var asm = Assembly.GetExecutingAssembly();
var fvi = FileVersionInfo.GetVersionInfo(asm.Location);
return fvi.FileVersion;
}
}
}
@@ -1,10 +0,0 @@
using System;
namespace Archetype.Models
{
public class ArchetypeConfigFileModel
{
public Guid Id { get; set; }
public bool CheckForUpdates { get; set; }
}
}
@@ -1,18 +1,14 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web.Security;
using Archetype.TypeConverters;
using Newtonsoft.Json;
using Umbraco.Core;
using System;
namespace Archetype.Models
{
/// <summary>
/// Model that represents a fieldset stored as content JSON.
/// </summary>
[TypeConverter(typeof(ArchetypeFieldsetModelConverter))]
public class ArchetypeFieldsetModel
{
[JsonProperty("alias")]
@@ -33,9 +29,6 @@ namespace Archetype.Models
[JsonProperty("expireDate")]
public DateTime? ExpireDate { get; set; }
[JsonProperty("allowedMemberGroups")]
public string AllowedMemberGroups { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="ArchetypeFieldsetModel"/> class.
/// </summary>
@@ -66,7 +59,7 @@ namespace Archetype.Models
{
var property = GetProperty(propertyAlias);
if (IsEmptyProperty(property))
if (IsEmptyProperty(property))
{
return default(T);
}
@@ -90,7 +83,7 @@ namespace Archetype.Models
{
var property = GetProperty(propertyAlias);
if (IsEmptyProperty(property))
if (IsEmptyProperty(property))
{
return defaultValue;
}
@@ -103,7 +96,7 @@ namespace Archetype.Models
/// </summary>
/// <param name="property">The property.</param>
/// <returns></returns>
private bool IsEmptyProperty(ArchetypePropertyModel property)
private bool IsEmptyProperty(ArchetypePropertyModel property)
{
return (property == null || property.Value == null || string.IsNullOrEmpty(property.Value.ToString()));
}
@@ -146,26 +139,11 @@ namespace Archetype.Models
/// Is this fieldset disabled, either explicitly or by other means?
/// </summary>
/// <returns>true if this fieldset is disabled, false otherwise</returns>
internal bool IsAvailable()
internal bool IsDisabled()
{
// explicitly disabled or implicitly disabled through publishing?
var disabled = Disabled
return Disabled
|| (ReleaseDate.HasValue && ReleaseDate > DateTime.UtcNow)
|| (ExpireDate.HasValue && DateTime.UtcNow > ExpireDate);
if (disabled)
{
// yes - the fieldset is not available
return false;
}
// limitation on member group access?
if (string.IsNullOrEmpty(AllowedMemberGroups))
{
// no - the fieldset is available
return true;
}
// maybe - the fieldset is available if the current member is a member of the configured member groups
var currentUserGroups = Roles.GetRolesForUser() ?? new string[0];
return currentUserGroups.ContainsAny(AllowedMemberGroups.Split(','));
}
#endregion
@@ -1,134 +0,0 @@
using System;
using System.IO;
using System.Text;
using Newtonsoft.Json;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Archetype.Models
{
public class ArchetypeGlobalSettings
{
public bool CheckForUpdates { get; set; }
public Guid Id { get; set; }
public Guid ApiKey = _getApiKey();
private static ArchetypeGlobalSettings _instance;
private static string _pathToConfig = @"~/Config/Archetype.config.js";
private static readonly string _mappedPathToConfig = IOHelper.MapPath(_pathToConfig);
private static object _padLock = new object();
private ArchetypeGlobalSettings()
{
}
public static ArchetypeGlobalSettings Instance
{
get
{
if (_instance == null)
{
lock (_padLock)
{
if (_instance == null)
{
_instance = new ArchetypeGlobalSettings();
_loadSettingsFromConfigFile();
}
}
}
return _instance;
}
}
public void Save()
{
lock (_padLock)
{
//write to JSON
var configFileModel = new ArchetypeConfigFileModel
{
Id = _instance.Id,
CheckForUpdates = _instance.CheckForUpdates
};
var serializedJson = JsonConvert.SerializeObject(configFileModel, Formatting.Indented);
File.WriteAllText(_mappedPathToConfig, serializedJson);
}
}
private static void _loadSettingsFromConfigFile()
{
try
{
if (File.Exists(_mappedPathToConfig))
{
//load
var deserializedConfigFile = JsonConvert.DeserializeObject<ArchetypeConfigFileModel>(File.ReadAllText(_mappedPathToConfig));
if (deserializedConfigFile != null)
{
_instance.Id = deserializedConfigFile.Id;
_instance.CheckForUpdates = deserializedConfigFile.CheckForUpdates;
}
else
{
_createNewConfigFile("Config file model was null!");
}
}
else
{
_createNewConfigFile("Config file was missing!");
}
}
catch (Exception ex)
{
LogHelper.Error<ArchetypeGlobalSettings>(ex.Message, ex);
_createNewConfigFile("Exception!");
}
}
private static void _createNewConfigFile(string reason)
{
//write a new file with defaults
LogHelper.Info<ArchetypeGlobalSettings>(string.Format("Generating a new config file reason: {0}", reason));
_instance.Id = Guid.NewGuid();
_instance.CheckForUpdates = true;
_instance.Save();
}
private static Guid _getApiKey()
{
//this is just obfuscation and an attempt to keep out most but not the determined hacker
var array = new []
{
"RTA4MUZDRjA=",
"NzkzQS1BRDIw",
"OTI3QjFDNjkwQTYy",
"MjI0OQ=="
};
return new Guid(string.Format("{0}-{1}-{3}-{2}",
_decodeBase64(array[0]),
_decodeBase64(array[1]),
_decodeBase64(array[2]),
_decodeBase64(array[3])
));
}
private static string _decodeBase64(string input)
{
return Encoding.UTF8.GetString(Convert.FromBase64String(input));
}
}
}
@@ -1,9 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Archetype.TypeConverters;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -13,7 +11,6 @@ namespace Archetype.Models
/// Model that represents an entire Archetype.
/// </summary>
[JsonObject]
[TypeConverter(typeof(ArchetypeModelConverter))]
public class ArchetypeModel : IEnumerable<ArchetypeFieldsetModel>
{
[JsonProperty("fieldsets")]
@@ -35,7 +32,7 @@ namespace Archetype.Models
/// </returns>
public IEnumerator<ArchetypeFieldsetModel> GetEnumerator()
{
return this.Fieldsets.Where(f => f.IsAvailable()).GetEnumerator();
return this.Fieldsets.Where(f => f.IsDisabled() == false).GetEnumerator();
}
//possibly obsolete?
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
@@ -25,9 +25,6 @@ namespace Archetype.Models
[JsonProperty("enableCollapsing")]
public bool EnableCollapsing { get; set; }
[JsonProperty("enableMultipleOpen")]
public bool EnableMultipleOpen { get; set; }
[JsonProperty("enableCloning")]
public bool EnableCloning { get; set; }
@@ -37,21 +34,12 @@ namespace Archetype.Models
[JsonProperty("enablePublishing")]
public bool EnablePublishing { get; set; }
[JsonProperty("enableCrossDragging")]
public bool EnableCrossDragging { get; set; }
[JsonProperty("enableMemberGroups")]
public bool EnableMemberGroups { get; set; }
[JsonProperty("hideFieldsetControls")]
public bool HideFieldsetControls { get; set; }
[JsonProperty("hidePropertyLabel")]
public bool HidePropertyLabel { get; set; }
[JsonProperty("minFieldsets", NullValueHandling = NullValueHandling.Ignore)]
public int MinFieldsets { get; set; }
[JsonProperty("maxFieldsets", NullValueHandling = NullValueHandling.Ignore)]
public int MaxFieldsets { get; set; }
@@ -26,9 +26,6 @@ namespace Archetype.Models
[JsonProperty("label")]
public string Label { get; set; }
[JsonProperty("previewImage")]
public string PreviewImage { get; set; }
[JsonProperty("properties")]
public IEnumerable<ArchetypePreValueProperty> Properties { get; set; }
@@ -98,7 +98,7 @@ namespace Archetype.Models
public bool IsDraft
{
get { return _fieldset.IsAvailable() == false; }
get { return _fieldset.IsDisabled(); }
}
public PublishedItemType ItemType
@@ -19,7 +19,7 @@ namespace Archetype.Models
var count = archetype.Fieldsets.Count();
_items = archetype.Fieldsets
.Where(x => x.IsAvailable())
.Where(x => x.IsDisabled() == false)
.Select(x => new ArchetypePublishedContent(x, this))
.ToArray();
}
@@ -1,6 +1,5 @@
using System;
using Archetype.Extensions;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
@@ -25,22 +24,14 @@ namespace Archetype.Models
_property = property;
_rawValue = property.Value;
// #418 - need to wrap this in a try/catch to prevent orphaned properties from breaking everything
try
{
_propertyType = property.CreateDummyPropertyType();
_propertyType = property.CreateDummyPropertyType();
if (_propertyType != null)
{
_sourceValue = new Lazy<object>(() => _propertyType.ConvertDataToSource(_rawValue, preview));
_objectValue = new Lazy<object>(() => _propertyType.ConvertSourceToObject(_sourceValue.Value, preview));
_xpathValue = new Lazy<object>(() => _propertyType.ConvertSourceToXPath(_sourceValue.Value, preview));
}
}
catch(Exception ex)
{
LogHelper.Warn<ArchetypePublishedProperty>(string.Format("Could not create an IPublishedProperty for property: {0} - the error was: {1}", property.Alias, ex.Message));
}
if (_propertyType != null)
{
_sourceValue = new Lazy<object>(() => _propertyType.ConvertDataToSource(_rawValue, preview));
_objectValue = new Lazy<object>(() => _propertyType.ConvertSourceToObject(_sourceValue.Value, preview));
_xpathValue = new Lazy<object>(() => _propertyType.ConvertSourceToXPath(_sourceValue.Value, preview));
}
}
internal ArchetypePropertyModel ArchetypeProperty
@@ -1,11 +0,0 @@
namespace Archetype.Models
{
public class ArchetypeUpdateNotification
{
public bool IsUpdateAvailable { get; set; }
public string Headline { get; set; }
public string Type { get; set; }
public string Message { get; set; }
public string Url { get; set; }
}
}
@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("Archetype")]
[assembly: AssemblyDescription("Archetype's supporting code library for Umbraco")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Kevin Giszewski LLC")]
[assembly: AssemblyCompany("Imulus")]
[assembly: AssemblyProduct("Archetype")]
[assembly: AssemblyCopyright("MIT Licensed")]
[assembly: AssemblyTrademark("")]
@@ -1,4 +1,4 @@
using System.Reflection;
[assembly: AssemblyVersion("1.16.0")]
[assembly: AssemblyFileVersion("1.16.0")]
[assembly: AssemblyVersion("1.13.0")]
[assembly: AssemblyFileVersion("1.13.0")]
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Archetype.Extensions;
using Archetype.Models;
using ClientDependency.Core;
using Newtonsoft.Json;
using Umbraco.Core;
@@ -96,7 +95,7 @@ namespace Archetype.PropertyEditors
if(propDef == null || propDef.DataTypeGuid == null) continue;
var dtd = ArchetypeHelper.Instance.GetDataTypeByGuid(Guid.Parse(propDef.DataTypeGuid));
var propType = new PropertyType(dtd) {Alias = propDef.Alias};
var prop = new Property(propType, propDef.Value);
var prop = new Property(propType, (propDef.Value != null) ? propDef.Value.ToString() : null);
var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
propDef.Value = propEditor.ValueEditor.ConvertDbToString(prop, propType, dataTypeService);
}
@@ -136,7 +135,7 @@ namespace Archetype.PropertyEditors
{
var dtd = ArchetypeHelper.Instance.GetDataTypeByGuid(Guid.Parse(propDef.DataTypeGuid));
var propType = new PropertyType(dtd) {Alias = propDef.Alias};
var prop = new Property(propType, propDef.Value);
var prop = new Property(propType, (propDef.Value != null) ? propDef.Value.ToString() : null);
var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
propDef.Value = propEditor.ValueEditor.ConvertDbToEditor(prop, propType, dataTypeService);
}
@@ -206,32 +205,17 @@ namespace Archetype.PropertyEditors
else if (propDef.EditorState != null && propDef.EditorState.FileNames != null && propDef.EditorState.FileNames.Any())
{
// pass the uploaded files that belongs to this property (if any) to the value editor
var propertyFiles = propDef.EditorState.FileNames.Select(fileName =>
uploadedFiles.FirstOrDefault(u => u.FileName != null &&
// #384, #389 and #394 - look for "safe" file names (using the ToSafeFileName() extension)
// - for backwards compatibility we'll look for the raw filename as well as the "safe" file name
(u.FileName.Equals(fileName, StringComparison.OrdinalIgnoreCase) || u.FileName.Equals(fileName.ToSafeFileName(), StringComparison.OrdinalIgnoreCase))
)
).Where(f => f != null).ToList();
var propertyFiles = propDef.EditorState.FileNames.Select(f => uploadedFiles.FirstOrDefault(u => u.FileName == f)).Where(f => f != null).ToList();
if(propertyFiles.Any())
{
additionalData["files"] = propertyFiles;
}
}
}
// #397 - pass along "cuid" and "puid" (part of the Umbraco 7.6 scheme)
if(editorValue.AdditionalData.ContainsKey("cuid"))
{
additionalData["cuid"] = editorValue.AdditionalData["cuid"];
}
if(editorValue.AdditionalData.ContainsKey("puid"))
{
additionalData["puid"] = editorValue.AdditionalData["puid"];
}
var propData = new ContentPropertyData(propDef.Value, preValues, additionalData);
var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias);
// make sure to send the current property value (if any) to the PE ValueEditor
propDef.Value = propEditor.ValueEditor.ConvertEditorToDb(propData, currentProperty != null ? currentProperty.Value : null);
propDef.Value = propEditor.ValueEditor.ConvertEditorToDb(propData, currentProperty != null ? (currentProperty.Value != null) ? currentProperty.Value.ToString() : null : null);
}
catch (Exception ex)
{
@@ -1,39 +0,0 @@
using System;
using System.ComponentModel;
using System.Globalization;
using Archetype.Extensions;
using Archetype.Models;
using Umbraco.Core.Models;
namespace Archetype.TypeConverters
{
public class ArchetypeFieldsetModelConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(IPublishedContent) ||
destinationType == typeof(ArchetypePublishedContent))
{
return true;
}
if (destinationType == typeof(string))
{
// NOTE: The converter needs to return false here, otherwise `ArchetypeHelper.DeserializeJsonToArchetype` fails.
return false;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (value is ArchetypeFieldsetModel && (destinationType == typeof(IPublishedContent) || destinationType == typeof(ArchetypePublishedContent)))
{
return ((ArchetypeFieldsetModel)value).ToPublishedContent();
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
}
@@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using Archetype.Extensions;
using Archetype.Models;
using Umbraco.Core.Models;
namespace Archetype.TypeConverters
{
public class ArchetypeModelConverter : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(ArchetypePublishedContentSet) ||
destinationType == typeof(IEnumerable<IPublishedContent>))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (value is ArchetypeModel && (destinationType == typeof(ArchetypePublishedContentSet) || destinationType == typeof(IEnumerable<IPublishedContent>)))
{
return ((ArchetypeModel)value).ToPublishedContentSet();
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
}
+13 -26
View File
@@ -1,4 +1,4 @@
angular.module("umbraco").controller("Imulus.ArchetypeConfigController", function ($scope, $http, assetsService, dialogService, archetypePropertyEditorResource, archetypeGlobalConfigService, notificationsService) {
angular.module("umbraco").controller("Imulus.ArchetypeConfigController", function ($scope, $http, assetsService, dialogService, archetypePropertyEditorResource) {
//$scope.model.value = "";
//console.log($scope.model.value);
@@ -6,7 +6,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
//define empty items
var newPropertyModel = '{"alias": "", "remove": false, "collapse": false, "label": "", "helpText": "", "dataTypeGuid": "0cc0eba1-9960-42c9-bf9b-60e150b429ae", "value": ""}';
var newFieldsetModel = '{"alias": "", "remove": false, "collapse": false, "labelTemplate": "", "icon": "", "label": "", "properties": [' + newPropertyModel + '], "group": null}';
var defaultFieldsetConfigModel = JSON.parse('{"showAdvancedOptions": false, "startWithAddButton": false, "hideFieldsetToolbar": false, "enableMultipleFieldsets": false, "hideFieldsetControls": false, "hidePropertyLabel": false, "maxFieldsets": null, "enableCollapsing": true, "enableMultipleOpen": true, "enableCloning": false, "enableDisabling": true, "enableDeepDatatypeRequests": false, "enablePublishing": false, "enableMemberGroups": false, "enableCrossDragging": false, "fieldsets": [' + newFieldsetModel + '], "fieldsetGroups": []}');
var defaultFieldsetConfigModel = JSON.parse('{"showAdvancedOptions": false, "startWithAddButton": false, "hideFieldsetToolbar": false, "enableMultipleFieldsets": false, "hideFieldsetControls": false, "hidePropertyLabel": false, "maxFieldsets": null, "enableCollapsing": true, "enableCloning": false, "enableDisabling": true, "enableDeepDatatypeRequests": false, "enablePublishing": false, "fieldsets": [' + newFieldsetModel + '], "fieldsetGroups": []}');
//ini the model
$scope.model.value = $scope.model.value || defaultFieldsetConfigModel;
@@ -16,17 +16,6 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
archetypePropertyEditorResource.getDllVersion().then(function(data){
$scope.dllVersion = data.dllVersion;
});
archetypeGlobalConfigService.checkForUpdates().then(function(data) {
if(data.isUpdateAvailable) {
notificationsService.add({
headline: data.headline,
type: data.type,
message: data.message,
url: data.url
});
}
});
//ini the render model
initConfigRenderModel();
@@ -58,12 +47,6 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
}
};
// added to track loaded fieldsets
$scope.loadedFieldsets = [];
$scope.isLoaded = function (fieldset) {
return $scope.loadedFieldsets.indexOf(fieldset) >= 0;
}
//function that determines how to manage expanding/collapsing fieldsets
$scope.focusFieldset = function(fieldset){
var iniState;
@@ -77,7 +60,6 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
if($scope.archetypeConfigRenderModel.fieldsets.length == 1 && fieldset.remove == false)
{
fieldset.collapse = false;
$scope.loadedFieldsets.push(fieldset);
return;
}
@@ -88,14 +70,12 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
else
{
fieldset.collapse = false;
$scope.loadedFieldsets.push(fieldset);
}
});
if(iniState)
{
fieldset.collapse = !iniState;
$scope.loadedFieldsets.push(fieldset);
}
}
@@ -143,20 +123,27 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio
//watch for changes
$scope.$watch('archetypeConfigRenderModel', function (v) {
//console.log(v);
if (typeof v === 'string') {
$scope.archetypeConfigRenderModel = JSON.parse(v);
$scope.archetypeConfigRenderModel.toString = stringify;
}
});
$scope.autoPopulateAlias = function (modelProperty) {
if (modelProperty && !modelProperty.aliasIsDirty) {
$scope.autoPopulateAlias = function(s) {
var modelType = s.hasOwnProperty('fieldset') ? 'fieldset' : 'property';
var modelProperty = s[modelType];
if (!modelProperty.aliasIsDirty) {
modelProperty.alias = modelProperty.label.toUmbracoAlias();
}
}
$scope.markAliasDirty = function (modelProperty) {
if (modelProperty && !modelProperty.aliasIsDirty) {
$scope.markAliasDirty = function(s) {
var modelType = s.hasOwnProperty('fieldset') ? 'fieldset' : 'property';
var modelProperty = s[modelType];
if (!modelProperty.aliasIsDirty) {
modelProperty.aliasIsDirty = true;;
}
}
@@ -1,5 +1,4 @@
angular.module('umbraco').controller('ArchetypeConfigOptionsController', function ($scope) {
//handles a fieldset group add
$scope.addFieldsetGroup = function () {
$scope.dialogData.model.fieldsetGroups.push({ name: "" });
@@ -1,21 +0,0 @@
angular.module('umbraco').controller('ArchetypeConfigGlobalOptionsController', function ($scope, archetypeGlobalConfigService) {
$scope.globalSettings = {};
$scope.confirmCheckNewVersionChange = function() {
archetypeGlobalConfigService.setCheckForUpdates($scope.globalSettings.checkForNewVersion);
}
function getGlobalSettings()
{
archetypeGlobalConfigService.globalSettings().then(function(data) {
$scope.globalSettings.checkForNewVersion = data.isCheckingForUpdates;
});
}
init();
function init()
{
getGlobalSettings();
}
});
+53 -402
View File
@@ -1,8 +1,5 @@
{{VERSION}}
angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, $filter, $interpolate, assetsService, angularHelper, notificationsService, $timeout, fileManager, entityResource, archetypeService, archetypeLabelService, archetypeCacheService, archetypePropertyEditorResource, archetypeLocalizationService) {
// Variables.
var draggedParent;
angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, $filter, assetsService, angularHelper, notificationsService, $timeout, fileManager, entityResource, archetypeService, archetypeLabelService, archetypeCacheService, archetypePropertyEditorResource) {
//$scope.model.value = "";
$scope.model.hideLabel = $scope.model.config.hideLabel == 1;
@@ -46,211 +43,36 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
return archetypeLabelService.getFieldsetTitle($scope, fieldsetConfigModel, fieldsetIndex);
}
var draggedRteSettings;
var rteClass = ".umb-rte textarea";
//sort config
$scope.sortableOptions = {
axis: 'y',
cursor: "move",
handle: ".handle",
tolerance: "pointer",
activate: function(ev, ui) {
// Variables.
var parentItem = ui.item.parent();
var thisElement = parentItem[0];
var targetElement = ev.target;
var targetItem = angular.element(targetElement);
// The source of the drag can always be dropped back onto.
if (targetElement === thisElement) {
return;
}
// Variables.
var sourceScope = ui.item.scope();
var targetScope = targetItem.scope();
var valid = canMove(sourceScope, targetScope);
// If the sortable can't be moved to the target Archetype, disable
// the target Archetype's sortable temporarily.
if (!valid) {
var targetSortable = getSortableWidgetInstance(targetItem);
targetSortable.disable();
parentItem.sortable("refresh");
archetypeService.rememberDisabledSortable(targetSortable);
}
},
start: function(ev, ui) {
archetypeService.storeEditors(ui.item.parent());
$scope.$apply(function() {
draggedParent = ui.item.parent();
draggedParent.scope().doingSort = true;
draggedRteSettings = {};
$(rteClass, ui.item.parent()).each(function () {
var id = $(this).attr("id");
draggedRteSettings[id] = _.findWhere(tinyMCE.editors, { id: id }).settings;
tinymce.execCommand('mceRemoveEditor', false, id);
$(this).css("visibility", "hidden");
});
},
update: function (ev, ui) {
// Variables.
var targetScope = ui.item.sortable.droptarget.scope();
var sourceScope = ui.item.scope();
var sameScope = sourceScope === targetScope;
var sourceIndex = ui.item.sortable.index;
// Special constraints for when moving between Archetypes.
// If sourceScope is populated, we are in the first of the two updates (when
// moving between lists, ui-sortable calls the update function twice).
if (sourceScope && !sameScope) {
// Variables.
var valid = canMove(sourceScope, targetScope);
// If update isn't allowed, cancel the drag operation.
if (!valid) {
ui.item.sortable.cancel();
return;
}
// Clear the validations for this item.
clearValidations(ui.item.parent());
clearValidations(ui.item.sortable.droptarget);
// Reset "isValid" on the properties and fieldsets.
var fieldsetGroups = [
$scope.model.value.fieldsets,
targetScope.model.value.fieldsets
];
_.each(fieldsetGroups, function(fieldsets) {
recurseProperties(function(property, fieldset) {
property.isValid = true;
fieldset.isValid = true;
}, fieldsets);
});
// Move the activated fieldset to the target Archetype.
var movedFieldset = $scope.model.value.fieldsets[sourceIndex];
var loadedIndex = $scope.loadedFieldsets.indexOf(movedFieldset);
if (loadedIndex >= 0) {
$scope.loadedFieldsets.splice(loadedIndex, 1);
if (targetScope.loadedFieldsets.indexOf(movedFieldset) < 0) {
targetScope.loadedFieldsets.push(movedFieldset);
}
}
}
// Set scope dirty.
$scope.setDirty();
},
stop: function (ev, ui) {
// Done sorting.
draggedParent.scope().doingSort = false;
// Enable disabled sortables.
archetypeService.enableSortables();
// Restore rich text editors.
var parent = null;
var target = ui.item.sortable.droptarget;
if (target) {
parent = target.parent();
}
archetypeService.restoreEditors(parent);
$(rteClass, ui.item.parent()).each(function () {
var id = $(this).attr("id");
draggedRteSettings[id] = draggedRteSettings[id] || _.findWhere(tinyMCE.editors, { id: id }).settings;
tinyMCE.execCommand("mceRemoveEditor", false, id);
tinyMCE.init(draggedRteSettings[id]);
});
}
};
// Clears the Angular validations in an Archetype.
function clearValidations(el) {
var combined = $(".archetypeSortable", el).add(el);
combined.each(function(index, item) {
var $item = angular.element(item);
var cont = $item.controller("ngModel");
var err = cont.$error;
var keys = Object.keys(err);
for (var i = 0; i < keys.length; i++) {
cont.$setValidity(keys[i], true);
}
});
}
// Enable cross-archetype dragging?
if ($scope.model.config.enableCrossDragging) {
$scope.sortableOptions.connectWith = ".archetypeSortable:not(.invalid)";
}
// Checks if the specified model's properties match all of the properties in any of
// the specified fieldsets, while also checking if the fieldset aliases match.
// This is an indicator of the compatibility of a fieldset model with a collection
// of fieldset configurations.
function modelMatchesAnyFieldset(model, fieldsets) {
// Loop through fieldsets to find a match.
for (var i = 0; i < fieldsets.length; i++) {
var fieldset = fieldsets[i];
// Confirm that this configured fielset contains exactly
// the same properties as those that were supplied.
var valid =
// Does the alias match?
model.alias === fieldset.alias &&
// Does this fieldset have all the properties?
arePropertiesSubset(model.properties, fieldset.properties) &&
// Does the property array have all the fieldset properties?
arePropertiesSubset(fieldset.properties, model.properties);
// Match found?
if (valid) {
return true;
}
}
// No match found.
return false;
}
// Checks if the specified array of fieldsets contains the specified fieldset.
function arrayContainsFieldset(fieldset, fieldsets) {
for (var i = 0; i < fieldsets.length; i++) {
if (fieldsets[i] === fieldset) {
return true;
}
}
return false;
}
// Confirms that an array of properties is a subset of another array of properties.
function arePropertiesSubset(subset, superset) {
// Loop through the subset of properties.
for (var j = 0; j < subset.length; j++) {
var subProperty = subset[j];
var matchedProp = false;
// Loop through the superset to find a matching property from the subset.
for (var k = 0; k < superset.length; k++) {
var superProperty = superset[k];
if (superProperty.alias === subProperty.alias &&
superProperty.dataTypeGuid === subProperty.dataTypeGuid) {
matchedProp = true;
break;
}
}
// If no matching property could be found, the array is not a subset.
if (!matchedProp) {
return false;
}
}
// The array is a subset.
return true;
}
//handles a fieldset add
$scope.openFieldsetPicker = function ($index, event) {
if ($scope.canAdd() == false) {
@@ -264,8 +86,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
alias: fieldset.alias,
label: fieldset.label,
icon: (fieldset.icon || "icon-document-dashed-line"), // default icon if none is chosen
group: fieldset.group ? fieldset.group.name : null,
previewImage: fieldset.previewImage
group: fieldset.group ? fieldset.group.name : null
});
});
// sanity check
@@ -305,22 +126,13 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
$scope.closeFieldsetPicker = function () {
$scope.overlayMenu.show = false;
$scope.overlayMenu.fieldsetPreview = null;
};
$scope.pickFieldset = function (fieldsetAlias, $index) {
$scope.closeFieldsetPicker();
$scope.addRow(fieldsetAlias, $index);
};
$scope.openFieldsetPreview = function (fieldset) {
$scope.overlayMenu.fieldsetPreview = fieldset;
}
$scope.closeFieldsetPreview = function () {
$scope.overlayMenu.fieldsetPreview = null;
}
$scope.addRow = function (fieldsetAlias, $index) {
if ($scope.canAdd()) {
if ($scope.model.config.fieldsets) {
@@ -343,14 +155,8 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
$scope.$broadcast("archetypeAddFieldset", {index: $index, visible: countVisible()});
newFieldset.collapse = $scope.model.config.enableCollapsing ? true : false;
// If the fieldset is not collapsed, it should be instantly loaded.
if (!newFieldset.collapse) {
$scope.loadedFieldsets.push(newFieldset);
}
$scope.focusFieldset(newFieldset);
$scope.handleMandatoryValidation();
}
}
@@ -360,7 +166,6 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
$scope.setDirty();
$scope.model.value.fieldsets.splice($index, 1);
$scope.$broadcast("archetypeRemoveFieldset", {index: $index});
$scope.handleMandatoryValidation();
}
}
}
@@ -371,24 +176,11 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
if(newFieldset) {
// Regenerate the temporary ID on each nested fieldset.
// This is done because no two fieldsets should have the same
// temporary ID.
recurseProperties(function(property) {
archetypeService.ensureTemporaryId(property, true);
}, [newFieldset]);
$scope.model.value.fieldsets.splice($index + 1, 0, newFieldset);
$scope.setDirty();
newFieldset.collapse = $scope.model.config.enableCollapsing ? true : false;
// If the fieldset is not collapsed, it should be instantly loaded.
if (!newFieldset.collapse) {
$scope.loadedFieldsets.push(newFieldset);
}
$scope.focusFieldset(newFieldset);
}
}
@@ -398,27 +190,24 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
fieldset.disabled = !fieldset.disabled;
// explicitly set the form as dirty when manipulating the enabled/disabled state of a fieldset
$scope.setDirty();
$scope.handleMandatoryValidation();
}
//helpers for determining if a user can do something
$scope.canAdd = function () {
if ($scope.model.config.maxFieldsets)
{
var visibleCount = countVisible();
var maxFieldsets = $scope.model.config.maxFieldsets;
return visibleCount < maxFieldsets;
return countVisible() < $scope.model.config.maxFieldsets;
}
return true;
};
}
//helper that returns if an item can be removed
$scope.canRemove = function () {
return countVisible() > 1
|| ($scope.model.config.maxFieldsets == 1 && $scope.model.config.fieldsets.length > 1)
|| $scope.model.config.startWithAddButton;
};
}
$scope.canClone = function () {
@@ -437,16 +226,8 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
//helper that returns if an item can be sorted
$scope.canSort = function ()
{
// Sorting can occur if there are multiple fieldsets, or if there is only one
// fieldset that can be removed (in which case it can be sorted into an entirely
// different Archetype).
return countVisible() > 1 || $scope.canRemove();
};
//helper that returns if an item is the last and it's being sorted.
$scope.sortingLastItem = function() {
return $scope.doingSort && $scope.model.value.fieldsets.length <= 1;
};
return countVisible() > 1;
}
//helper that returns if an item can be disabled
$scope.canDisable = function () {
@@ -465,14 +246,10 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
return $scope.model.config.enablePublishing;
}
$scope.canUseMemberGroups = function() {
return $scope.model.config.enableMemberGroups;
}
//helper that returns if the "misc fieldset configuration" section should be visible
$scope.canConfigure = function () {
// currently the "misc fieldset configuration" section contains the publishing and the member groups setup
return $scope.canPublish() || $scope.canUseMemberGroups();
// currently the only thing in the "misc fieldset configuration" section is the publishing setup
return $scope.canPublish();
}
$scope.showDisableIcon = function (fieldset) {
@@ -524,30 +301,10 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
return $scope.isDisabledByPublishing(fieldset);
}
$scope.numberOfEnabledFieldsets = function () {
if (!$scope.model.value.fieldsets) {
return 0;
}
return _.filter($scope.model.value.fieldsets, function (f) {
return $scope.isDisabled(f) == false;
}).length;
}
//helper, ini the render model from the server (model.value)
function init() {
$scope.model.value = removeNulls($scope.model.value);
addDefaultProperties($scope.model.value.fieldsets);
$timeout(function () {
$scope.handleMandatoryValidation();
}, 50);
// localize the message for minimum fieldsets validation errors
archetypeLocalizationService.localize("minFieldsetsMessage").then(function (value) {
value = value || "You must add minimum {{minFieldsets}} items";
var exp = $interpolate(value);
$scope.minFieldsetsMessage = exp({ minFieldsets: $scope.model.config.minFieldsets });
});
}
function addDefaultProperties(fieldsets)
@@ -581,12 +338,6 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
view: "datepicker",
value: fromUtc(fieldset.expireDate)
};
// create model for allowed member groups
fieldset.allowedMemberGroupsModel = {
alias: _.uniqueId("archetypeAllowedMemberGroups_"),
view: "membergrouppicker",
value: fieldset.allowedMemberGroups
};
}
//helper to get the correct fieldset from config
@@ -608,10 +359,10 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
{
if(typeof fieldset.collapse === "undefined")
{
fieldset.collapse = $scope.model.config.enableCollapsing ? true : false;
fieldset.collapse = true;
}
return fieldset.collapse;
};
}
// added to track loaded fieldsets
$scope.loadedFieldsets = [];
@@ -627,17 +378,17 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
return;
}
// collapse all other fieldsets if "multiple open fieldsets" is not enabled
if(!$scope.model.config.enableMultipleOpen)
var iniState;
if(fieldset)
{
_.each($scope.model.value.fieldsets, function (f) {
if(f != fieldset)
{
f.collapse = true;
}
});
iniState = fieldset.collapse;
}
_.each($scope.model.value.fieldsets, function(fieldset){
fieldset.collapse = true;
});
if(!fieldset && $scope.model.value.fieldsets.length == 1)
{
$scope.model.value.fieldsets[0].collapse = false;
@@ -645,25 +396,16 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
return;
}
if(fieldset)
if(iniState && fieldset)
{
fieldset.collapse = !fieldset.collapse;
if($scope.loadedFieldsets.indexOf(fieldset) < 0)
{
$scope.loadedFieldsets.push(fieldset);
}
fieldset.collapse = !iniState;
$scope.loadedFieldsets.push(fieldset);
}
}
//ini the fieldset expand/collapse
$scope.focusFieldset();
// Fieldsets which cannot be collapsed should start expanded.
_.each($scope.model.value.fieldsets, function(fieldset) {
fieldset.collapse = $scope.model.config.enableCollapsing;
});
$scope.loadedFieldsets = _.where($scope.model.value.fieldsets, { collapse: false });
//developerMode helpers
$scope.model.value.toString = stringify;
@@ -715,9 +457,6 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
$scope.activeSubmitWatcher = 0;
// init loaded fieldsets tracking
_.each($scope.model.value.fieldsets, function (fieldset) {
fieldset.collapse = $scope.model.config.enableCollapsing ? true : false;
});
$scope.loadedFieldsets = _.where($scope.model.value.fieldsets, { collapse: false });
// create properties needed for the backoffice to work (data that is not serialized to DB)
@@ -782,21 +521,24 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
//helper to lookup validity when given a fieldset
$scope.getFieldsetValidity = function (fieldset) {
if (fieldset.isValid == false) {
return false;
}
// Variables.
var valid = true;
// Recursive validation of nested fieldsets.
recurseFieldsets(function(item) {
if (item.isValid === false) {
valid = false;
// recursive validation of nested fieldsets
var nestedFieldsetsValid = true;
_.each(fieldset.properties, function (property) {
if (property != null && property.value != null && property.propertyEditorAlias == "Imulus.Archetype") {
_.each(property.value.fieldsets, function (inner) {
if ($scope.getFieldsetValidity(inner) == false) {
nestedFieldsetsValid = false;
}
});
}
}, [fieldset]);
});
// Were all the nested fieldsets valid?
return valid;
};
return nestedFieldsetsValid;
}
// helper to force the current form into the dirty state
$scope.setDirty = function () {
@@ -805,13 +547,6 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
}
}
$scope.minFieldsetsFulfilled = function () {
if (!$scope.model.config.minFieldsets) {
return true;
}
return $scope.numberOfEnabledFieldsets() >= $scope.model.config.minFieldsets;
}
//custom js
if ($scope.model.config.customJsPath) {
assetsService.loadJs($scope.model.config.customJsPath);
@@ -846,21 +581,9 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
// extract the publish configuration from the fieldsets (and convert local datetimes to UTC)
fieldset.releaseDate = toUtc(fieldset.releaseDateModel.value);
fieldset.expireDate = toUtc(fieldset.expireDateModel.value);
// extract the allowed member groups
fieldset.allowedMemberGroups = fieldset.allowedMemberGroupsModel.value;
});
});
// handle mandatory validation of the entire Archetype
// - no fieldsets = not valid
$scope.handleMandatoryValidation = function() {
var valid = true;
if ($scope.model.validation && $scope.model.validation.mandatory) {
valid = $scope.numberOfEnabledFieldsets() > 0;
}
$scope.model.mandatoryValidation = valid ? "valid" : null;
}
function toUtc(date) {
if (!date) {
return null;
@@ -874,76 +597,4 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
}
return moment(moment.utc(date).toDate()).format("YYYY-MM-DD HH:mm:ss")
}
// Serializes and deserializes an item to return a snapshot of that item (e.g., so it is not
// changed before being inspected). Useful when troubleshooting.
// Modified from: http://stackoverflow.com/a/11616993/2052963
function jsonSnapshot(item) {
var cache = [];
var stringItem = JSON.stringify(item, function(key, value) {
if (typeof value === "object" && value !== null) {
if (cache.indexOf(value) !== -1) {
return "[Removed Circular Reference Item]";
}
cache.push(value);
}
return value;
});
return JSON.parse(stringItem);
}
// Recursively processes each Archetype fieldset.
function recurseFieldsets(fn, fieldsets) {
if (!fieldsets || !fieldsets.length) {
return;
}
_.each(fieldsets, function(fieldset) {
fn(fieldset);
_.each(fieldset.properties, function (property) {
if (property != null && property.value != null && property.propertyEditorAlias === "Imulus.Archetype") {
recurseFieldsets(fn, property.value.fieldsets);
}
});
});
}
// Recursively processes each Archetype fieldset property.
function recurseProperties(fn, fieldsets) {
recurseFieldsets(function(fieldset) {
_.each(fieldset.properties, function (property) {
fn(property, fieldset);
});
}, fieldsets);
}
// Indicates whether or not the fieldset can be moved between the source and target scope.
// The source scope is the scope of the fieldset being dragged.
// The target scope is the scope of the Archetype to drop into.
function canMove(sourceScope, targetScope) {
var targetFieldsetConfigs = targetScope.model.config.fieldsets;
var targetFieldsets = targetScope.model.value.fieldsets;
var sourceFieldset = sourceScope.fieldset;
var sameArchetype = arrayContainsFieldset(sourceFieldset, targetFieldsets);
var model = sourceScope.fieldsetConfigModel;
var canRemove = sourceScope.canRemove();
var canAdd = targetScope.canAdd();
var valid = sameArchetype || (canRemove && canAdd);
valid = valid && modelMatchesAnyFieldset(model, targetFieldsetConfigs);
return valid;
}
// This is an alternative to: element.sortable("instance")
// Workaround for this issue: https://github.com/imulus/Archetype/pull/356#issuecomment-218527910
// Snagged from this pull request: https://github.com/angular-ui/ui-sortable/pull/319
// More technical details here: https://github.com/angular-ui/ui-sortable/issues/316
function getSortableWidgetInstance(element) {
// this is a fix to support jquery-ui prior to v1.11.x
// otherwise we should be using `element.sortable('instance')`
var data = element.data('ui-sortable');
if (data && typeof data === 'object' && data.widgetFullName === 'ui-sortable') {
return data;
}
return null;
}
});
+11 -19
View File
@@ -65,22 +65,15 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
if (!scope.renderModelPropertyIndex)
{
var propertyValue = { alias: alias, value: defaultValue };
archetypeService.getFieldset(scope).properties.push(propertyValue);
archetypeService.getFieldset(scope).properties.push(JSON.parse('{"alias": "' + alias + '", "value": "' + defaultValue + '"}'));
scope.renderModelPropertyIndex = archetypeService.getPropertyIndexByAlias(archetypeService.getFieldset(scope).properties, alias);
}
scope.renderModel = {};
scope.model.value = archetypeService.getFieldsetProperty(scope).value;
// init the property editor state (while ensuring the temporary ID is retained
// from any prior initializations).
var fieldsetProperty = archetypeService.getFieldsetProperty(scope);
var oldState = fieldsetProperty.editorState;
archetypeService.ensureTemporaryId(fieldsetProperty);
if (oldState) {
fieldsetProperty.editorState.temporaryId = oldState.temporaryId;
}
//init the property editor state
archetypeService.getFieldsetProperty(scope).editorState = {};
//set the config from the prevalues
scope.model.config = config;
@@ -124,17 +117,16 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
});
scope.$on('archetypeFormSubmitting', function (ev, args) {
// #385 - revert the changes made in #311 to avoid publishing invalid fieldsets (leaving the code from #311 here, in case we figure out how to re-introduce "save as draft")
// if(args.action !== 'save') {
// validate all fieldset properties
_.each(scope.fieldset.properties, function (property) {
archetypeService.validateProperty(scope.fieldset, property, configFieldsetModel);
});
if(args.action !== 'save') {
// validate all fieldset properties
_.each(scope.fieldset.properties, function (property) {
archetypeService.validateProperty(scope.fieldset, property, configFieldsetModel);
});
var validationKey = "validation-f" + scope.fieldsetIndex;
var validationKey = "validation-f" + scope.fieldsetIndex;
ngModelCtrl.$setValidity(validationKey, scope.fieldset.isValid);
// }
ngModelCtrl.$setValidity(validationKey, scope.fieldset.isValid);
}
// did the value change (if it did, it most likely did so during the "formSubmitting" event)
var property = archetypeService.getFieldsetProperty(scope);
+3 -3
View File
@@ -13,7 +13,7 @@ var ArchetypeSampleLabelTemplates = (function() {
var id = value.split(",")[0];
if (id) {
var entity = scope.services.archetypeCacheService.getEntityById(scope, id, args.entityType);
var entity = scope.services.archetypeLabelService.getEntityById(scope, id, args.entityType);
if(entity) {
return entity[args.propertyName];
@@ -34,13 +34,13 @@ var ArchetypeSampleLabelTemplates = (function() {
switch (value.type) {
case "content":
if(value.typeData.contentId) {
entity = scope.services.archetypeCacheService.getEntityById(scope, value.typeData.contentId, "Document");
entity = scope.services.archetypeLabelService.getEntityById(scope, value.typeData.contentId, "Document");
}
break;
case "media":
if(value.typeData.mediaId) {
entity = scope.services.archetypeCacheService.getEntityById(scope, value.typeData.mediaId, "Media");
entity = scope.services.archetypeLabelService.getEntityById(scope, value.typeData.mediaId, "Media");
}
break;
+1 -8
View File
@@ -51,12 +51,5 @@
"publishHelpText": "Konfigurér udgivelses- og udløbsdato for dette element",
"publishReleaseDate": "Udgivelsesdato",
"publishExpireDate": "Udløbsdato",
"settings": "Indstillinger",
"enableMemberGroups": "Aktivér medlems-grupper",
"enableMemerGroupsDescription": "Tillad at fieldsets kun vises for specifikke medlems-grupper",
"allowedMemberGroups": "Tilladte medlems-grupper",
"allowedMemberGroupsHelpText": "Vælg de medlems-grupper, der skal kunne se dette element. Hvis der ikke er valgt nogen, kan alle se elementet.",
"previewFieldsetOpen": "(se eksempel)",
"previewFieldsetHeader": "Eksempel: ",
"previewFieldsetClose": "(luk eksempel)"
"settings": "Indstillinger"
}
+1 -8
View File
@@ -51,12 +51,5 @@
"publishHelpText": "Konfigurér udgivelses- og udløbsdato for dette element",
"publishReleaseDate": "Udgivelsesdato",
"publishExpireDate": "Udløbsdato",
"settings": "Indstillinger",
"enableMemberGroups": "Aktivér medlems-grupper",
"enableMemerGroupsDescription": "Tillad at fieldsets kun vises for specifikke medlems-grupper",
"allowedMemberGroups": "Tilladte medlems-grupper",
"allowedMemberGroupsHelpText": "Vælg de medlems-grupper, der skal kunne se dette element. Hvis der ikke er valgt nogen, kan alle se elementet.",
"previewFieldsetOpen": "(se eksempel)",
"previewFieldsetHeader": "Eksempel: ",
"previewFieldsetClose": "(luk eksempel)"
"settings": "Indstillinger"
}
+2 -4
View File
@@ -11,7 +11,7 @@
"maxFieldsets": "Max Fieldsets",
"maxFieldsetsDescription": "How many Fieldsets are allowed? Entering '1' will disable the controls. Default is unlimited.",
"enableMultipleFieldsets": "Enable Multiple Fieldsets?",
"enableMultipleFieldsetsDescription": "Allows multiple types of fieldsets within this Archetype.",
"enableMultipleFieldsetsDescription": "Allows multiple types of fieldsets within this archetype.",
"hideFieldsetToolbar": "Hide Fieldset Toolbar?",
"hideFieldsetToolbarDescription": "Hides the fieldset toolbar that appears when more than one fieldset model appears.",
"customWrapperClass": "Custom Wrapper Class",
@@ -23,7 +23,7 @@
"toggleDeveloperMode": "Toggle Developer Mode",
"toggleDeveloperModeDescription": "Turn on for developer options.",
"configModel": "Config Model",
"configModelDescription": "Be careful editing the text below, it controls the schema for this Archetype.",
"configModelDescription": "Be careful editing the text below, it controls the schema for this archetype.",
"helpText": "Help Text",
"defaultValue": "Default Value",
"dataType": "DataType",
@@ -41,8 +41,6 @@
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning.",
"enableCrossDragging":"Enable Cross-Archetype Dragging?",
"enableCrossDraggingDescription":"Allows fieldsets to be dragged into other Archetypes.",
"fieldsetGroups":"Fieldset groups",
"fieldsetGroupsDescription":"If you have a lot of fieldsets to choose from, you may want to consider grouping them in the fieldset picker. Once you have created your groups here, a group picker will be displayed in the fieldset editor and you can assign your fieldsets to their respective groups.",
"fieldsetGroupName":"Name",
+2 -4
View File
@@ -11,7 +11,7 @@
"maxFieldsets": "Max Fieldsets",
"maxFieldsetsDescription": "How many Fieldsets are allowed? Entering '1' will disable the controls. Default is unlimited.",
"enableMultipleFieldsets": "Enable Multiple Fieldsets?",
"enableMultipleFieldsetsDescription": "Allows multiple types of fieldsets within this Archetype.",
"enableMultipleFieldsetsDescription": "Allows multiple types of fieldsets within this archetype.",
"hideFieldsetToolbar": "Hide Fieldset Toolbar?",
"hideFieldsetToolbarDescription": "Hides the fieldset toolbar that appears when more than one fieldset model appears.",
"customWrapperClass": "Custom Wrapper Class",
@@ -23,7 +23,7 @@
"toggleDeveloperMode": "Toggle Developer Mode",
"toggleDeveloperModeDescription": "Turn on for developer options.",
"configModel": "Config Model",
"configModelDescription": "Be careful editing the text below, it controls the schema for this Archetype.",
"configModelDescription": "Be careful editing the text below, it controls the schema for this archetype.",
"helpText": "Help Text",
"defaultValue": "Default Value",
"dataType": "DataType",
@@ -41,8 +41,6 @@
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning.",
"enableCrossDragging":"Enable Cross-Archetype Dragging?",
"enableCrossDraggingDescription":"Allows fieldsets to be dragged into other Archetypes.",
"fieldsetGroups":"Fieldset groups",
"fieldsetGroupsDescription":"If you have a lot of fieldsets to choose from, you may want to consider grouping them in the fieldset picker. Once you have created your groups here, a group picker will be displayed in the fieldset editor and you can assign your fieldsets to their respective groups.",
"fieldsetGroupName":"Name",
+2 -4
View File
@@ -11,7 +11,7 @@
"maxFieldsets": "Max Fieldsets",
"maxFieldsetsDescription": "How many Fieldsets are allowed? Entering '1' will disable the controls. Default is unlimited.",
"enableMultipleFieldsets": "Enable Multiple Fieldsets?",
"enableMultipleFieldsetsDescription": "Allows multiple types of fieldsets within this Archetype.",
"enableMultipleFieldsetsDescription": "Allows multiple types of fieldsets within this archetype.",
"hideFieldsetToolbar": "Hide Fieldset Toolbar?",
"hideFieldsetToolbarDescription": "Hides the fieldset toolbar that appears when more than one fieldset model appears.",
"customWrapperClass": "Custom Wrapper Class",
@@ -23,7 +23,7 @@
"toggleDeveloperMode": "Toggle Developer Mode",
"toggleDeveloperModeDescription": "Turn on for developer options.",
"configModel": "Config Model",
"configModelDescription": "Be careful editing the text below, it controls the schema for this Archetype.",
"configModelDescription": "Be careful editing the text below, it controls the schema for this archetype.",
"helpText": "Help Text",
"defaultValue": "Default Value",
"dataType": "DataType",
@@ -41,8 +41,6 @@
"overrideDefaultConverter":"Override Default Property Value Converter?",
"enableCloning":"Enable Cloning?",
"enableCloningDescription":"Enable Fieldset Cloning.",
"enableCrossDragging":"Enable Cross-Archetype Dragging?",
"enableCrossDraggingDescription":"Allows fieldsets to be dragged into other Archetypes.",
"fieldsetGroups":"Fieldset groups",
"fieldsetGroupsDescription":"If you have a lot of fieldsets to choose from, you may want to consider grouping them in the fieldset picker. Once you have created your groups here, a group picker will be displayed in the fieldset editor and you can assign your fieldsets to their respective groups.",
"fieldsetGroupName":"Name",
+9 -84
View File
@@ -249,7 +249,7 @@
.archetypeAddButton {
color: #ddd;
.icon {
vertical-align: middle;
vertical-align: text-top;
}
&:hover {
color: #333;
@@ -290,12 +290,6 @@
overflow: visible;
vertical-align: top;
height: 90px;
.fieldsetPreviewOpen {
font-style: italic;
a:hover {
text-decoration: underline;
}
}
}
ul.groups {
display: block;
@@ -316,24 +310,6 @@
}
}
}
.fieldsetPreview {
.fieldsetPreviewClose {
font-style: italic;
font-size: 12px;
text-align: center;
}
.fieldsetPreviewImage {
padding: 6px 0px;
img {
height: auto;
max-width: 100%;
vertical-align: middle;
border: 0;
cursor: zoom-in;
}
}
}
}
.settingsWrapper {
@@ -357,33 +333,10 @@
}
}
}
.settings {
padding: 14px;
background-color: #f8f8f8;
overflow: hidden;
.allowedGroups {
.umb-membergrouppicker a {
i {
padding-right: 0;
font-size: inherit;
}
&:hover i {
color: #333;
}
}
}
}
}
// Necessary to ensure empty lists can be dropped onto when sorting nested fieldsets.
.archetypeSortable.archetypeEmpty {
&.archetypeCrossDraggable {
min-height: 42px;
border: 1px dashed #dddddd;
margin-top: 5px;
}
}
}
@@ -392,7 +345,6 @@
.archetypeEditorControls {
float: right;
}
.archetypeEditorControls, .archetypeFieldsetGroups {
i {
cursor: pointer;
@@ -418,10 +370,10 @@
small {
margin-left: 5px;
}
a {
float: right;
img {
width: 35px;
}
@@ -431,26 +383,6 @@
.manual-link {
color: blue;
}
.donate-link {
font-weight: 700;
}
.sponsors {
padding-bottom: 10px;
margin-bottom: 5px;
margin-left: 5px;
display: inline-table;
float: right;
a {
float: none;
}
h4 {
border-bottom: 1px solid #ccc;
}
}
ul {
list-style: none;
@@ -471,8 +403,6 @@
.archetypeFieldsets {
margin-left: 0;
border-top: 5px solid;
padding-top: 5px;
}
.archetypeFieldsetWrapper {
@@ -489,8 +419,7 @@
.archetypeFieldsetOption {
margin-bottom: 15px;
margin-right: 15px;
input[type=text] {
input[type=text]{
max-width: 100%;
width: 100%;
}
@@ -508,7 +437,7 @@
margin-bottom: 5px;
}
label {
label{
width: 400px;
}
}
@@ -548,7 +477,7 @@
label {
width: 100%;
}
input[type=text] {
width: 100%;
}
@@ -583,10 +512,10 @@
}
}
}
}
}
}
.archetypeMaxFieldsets {
.archetypeMaxFieldsets{
border: 1px solid #ddd;
width: 40px;
text-align: right;
@@ -599,7 +528,7 @@
.archetypePropertyCollapser {
margin-top: 10px;
div {
margin-bottom: 10px;
margin-right: 15px;
@@ -613,10 +542,6 @@
.fieldsetIcon {
margin-right: 10px;
}
small {
color: #817f85;
}
}
.ui-sortable-placeholder {
+1 -29
View File
@@ -73,34 +73,6 @@ angular.module('umbraco.services').factory('archetypeCacheService', function (ar
}
return null;
},
getEntityByUmbracoId: function(scope, udi, type) {
var cachedEntity = _.find(entityCache, function (e){
return e.udi == udi;
});
if(cachedEntity) {
return cachedEntity;
}
//go get it from server
if (!isEntityLookupLoading) {
isEntityLookupLoading = true;
scope.resources.entityResource.getByIds([udi], type).then(function (entities) {
// prevent infinite lookups with a default entity
var entity = entities.length > 0 ? entities[0] : { udi: udi, name: "" };
entityCache.push(entity);
isEntityLookupLoading = false;
return entity;
});
}
return null;
}
}
}
});
@@ -1,19 +0,0 @@
angular.module('umbraco.services').factory('archetypeGlobalConfigService', function ($q, $http, umbRequestHelper) {
return {
globalSettings: function () {
return umbRequestHelper.resourcePromise(
$http.get("backoffice/ArchetypeApi/ArchetypeDataType/globalSettings"), 'Failed to get whether or not we are checking for updates!'
);
},
setCheckForUpdates: function (isChecking) {
return umbRequestHelper.resourcePromise(
$http.post("backoffice/ArchetypeApi/ArchetypeDataType/SetCheckForUpdates", isChecking), 'Failed to update check status!'
);
},
checkForUpdates: function () {
return umbRequestHelper.resourcePromise(
$http.post("backoffice/ArchetypeApi/ArchetypeDataType/checkForUpdates", { }), 'Failed to check for updates!'
);
}
}
});
+3 -83
View File
@@ -19,6 +19,7 @@ angular.module('umbraco.services').factory('archetypeLabelService', function (ar
}
function getNativeLabel(datatype, value, scope) {
switch (datatype.selectedEditor) {
case "Imulus.UrlPicker":
return imulusUrlPicker(value, scope, {});
@@ -26,22 +27,13 @@ angular.module('umbraco.services').factory('archetypeLabelService', function (ar
return coreTinyMce(value, scope, {});
case "Umbraco.MultiNodeTreePicker":
return coreMntp(value, scope, datatype);
case "Umbraco.MultiNodeTreePicker2":
return coreMntpV2(value, scope, datatype);
case "Umbraco.MultipleMediaPicker":
case "Umbraco.MediaPicker":
return coreMediaPicker(value, scope, datatype);
case "Umbraco.MediaPicker2":
return coreMediaPickerV2(value, scope, datatype);
case "Umbraco.DropDown":
return coreDropdown(value, scope, datatype);
case "RJP.MultiUrlPicker":
return rjpMultiUrlPicker(value, scope, {});
case "Umbraco.ContentPickerAlias":
return coreContentPicker(value, scope, datatype);
case "Umbraco.ContentPicker2":
return coreContentPickerV2(value, scope, datatype);
default:
default:
return "";
}
}
@@ -95,39 +87,6 @@ angular.module('umbraco.services').factory('archetypeLabelService', function (ar
return entityArray.join(', ');
}
function coreMntpV2(value, scope, args) {
var ids = value.split(',');
if (ids.length == 0) {
return "";
}
var type = "document";
switch(args.preValues[0].value.type) {
case 'content':
type = 'document';
break;
case 'media':
type = 'media';
break;
case 'member':
type = 'member';
break;
default:
break;
}
var entity;
_.each(ids, function (id) {
if(id && !entity) {
entity = archetypeCacheService.getEntityByUmbracoId(scope, id, type);
}
});
return (entity != null ? entity.name : "") + (ids.length > 1 ? ", ..." : "");
}
function coreMediaPicker(value, scope, args) {
if(value) {
var entity = archetypeCacheService.getEntityById(scope, value, "media");
@@ -140,42 +99,6 @@ angular.module('umbraco.services').factory('archetypeLabelService', function (ar
return "";
}
function coreMediaPickerV2(value, scope, args) {
if(value) {
var entity = archetypeCacheService.getEntityByUmbracoId(scope, value, "media");
if(entity) {
return entity.name;
}
}
return "";
}
function coreContentPicker(value, scope, args) {
if (value) {
var entity = archetypeCacheService.getEntityById(scope, value, "document");
if (entity) {
return entity.name;
}
}
return "";
}
function coreContentPickerV2(value, scope, args) {
if (value) {
var entity = archetypeCacheService.getEntityByUmbracoId(scope, value, "document");
if (entity) {
return entity.name;
}
}
return "";
}
function imulusUrlPicker(value, scope, args) {
if(!args.propertyName) {
@@ -346,10 +269,7 @@ angular.module('umbraco.services').factory('archetypeLabelService', function (ar
if(!templateLabelValue) {
templateLabelValue = "";
}
// handle collapsing dollar signs in labels (#387)
if (templateLabelValue.indexOf("$$") >= 0) {
templateLabelValue = templateLabelValue.replace(/\$\$/g, "$$$$$$$$");
}
parsedTemplate = parsedTemplate.replace(match, templateLabelValue);
});
+5 -121
View File
@@ -1,11 +1,4 @@
angular.module('umbraco.services').factory('archetypeService', function () {
// Variables.
var draggedRteArchetype;
var rteClass = ".archetypeEditor .umb-rte textarea";
var editorSettings = {};
var disabledSortables = [];
//public
return {
//helper that returns a JS ojbect from 'value' string or the original string
@@ -51,7 +44,7 @@ angular.module('umbraco.services').factory('archetypeService', function () {
return property.alias == alias;
});
},
getUniquePropertyAlias: function (currentScope, propertyAliasParts, excludeUniqueId) {
getUniquePropertyAlias: function (currentScope, propertyAliasParts) {
if (currentScope.hasOwnProperty('fieldsetIndex') && currentScope.hasOwnProperty('property') && currentScope.hasOwnProperty('propertyConfigIndex'))
{
var currentPropertyAlias = "f" + currentScope.fieldsetIndex + "-" + currentScope.property.alias + "-p" + currentScope.propertyConfigIndex;
@@ -64,23 +57,15 @@ angular.module('umbraco.services').factory('archetypeService', function () {
}
if (currentScope.$parent)
this.getUniquePropertyAlias(currentScope.$parent, propertyAliasParts, true);
this.getUniquePropertyAlias(currentScope.$parent, propertyAliasParts);
var reversed = _.unique(propertyAliasParts).reverse();
if (!excludeUniqueId) {
reversed.push(_.uniqueId("u-"));
}
return reversed.join("-");
return _.unique(propertyAliasParts).reverse().join("-");
},
getFieldset: function(scope) {
var renderModel = scope.archetypeRenderModel;
return renderModel ? renderModel.fieldsets[scope.fieldsetIndex] : null;
return scope.archetypeRenderModel.fieldsets[scope.fieldsetIndex];
},
getFieldsetProperty: function (scope) {
var fieldset = this.getFieldset(scope);
return fieldset ? fieldset.properties[scope.renderModelPropertyIndex] : null;
return this.getFieldset(scope).properties[scope.renderModelPropertyIndex];
},
setFieldsetValidity: function (fieldset) {
// mark the entire fieldset as invalid if there are any invalid properties in the fieldset, otherwise mark it as valid
@@ -114,107 +99,6 @@ angular.module('umbraco.services').factory('archetypeService', function () {
// it's the Umbraco way to hide the invalid state when altering an invalid property, even if the new value isn't valid either
property.isValid = true;
this.setFieldsetValidity(fieldset);
},
// This stores the rich text editors in all Archetypes (e.g., during a drag operation).
// Typically, the editors will be restored after the drag completes.
storeEditors: function (element) {
// If there are not tinyMCE editors, this may be undefined.
if (typeof tinyMCE === "undefined") {
return;
}
// Variables.
var self = this;
draggedRteArchetype = element;
// Empty the stored settings.
editorSettings = {};
// For fast lookups, store each editor by the element ID.
var editorsById = {};
for (var i = 0; i < tinyMCE.editors.length; i++) {
var tempEditor = tinyMCE.editors[i];
editorsById[tempEditor.id] = tempEditor;
}
// Process each rich text editor.
$(rteClass).each(function() {
// Variables.
var id = $(this).attr("id");
var editor = editorsById[id];
// Get the property's temporary ID.
var scope = angular.element(this).scope().$parent;
var property = self.getFieldsetProperty(scope);
var tempId = property ? property.editorState.temporaryId : null;
// Store the editor settings by the temporary ID?
if (editor && editor.settings && tempId) {
editorSettings[tempId] = editor.settings;
}
});
},
// This restores the rich text editors in the specified Archetype
// (e.g., after a drop drop operation).
restoreEditors: function(element) {
// If there are not tinyMCE editors, this may be undefined.
if (typeof tinyMCE === "undefined") {
return;
}
// Variables.
var bothElements = element
? element.add(draggedRteArchetype)
: draggedRteArchetype;
var self = this;
// Process each RTE in both Archetypes.
$(rteClass, bothElements).each(function () {
// Variables.
var id = $(this).attr("id");
// Get the stored editor settings.
var scope = angular.element(this).scope().$parent;
var property = self.getFieldsetProperty(scope);
var tempId = property ? property.editorState.temporaryId : null;
var settings = editorSettings[tempId];
// Remove and reinitialize the editor.
if (settings) {
tinyMCE.execCommand("mceRemoveEditor", false, id);
tinyMCE.init(settings);
}
});
},
// Ensures the specified property has a temporary ID in its editor state,
// optionally forcing one to be regenerated (if specified).
ensureTemporaryId: function(property, regenerateId) {
if (!property.editorState) {
property.editorState = {};
}
var editorState = property.editorState;
if (!editorState.temporaryId || regenerateId) {
editorState.temporaryId = _.uniqueId("property-temp-id-");
}
},
// Remembers a sortable that has been disabled (so it can be enabled later).
rememberDisabledSortable: function(sortable) {
disabledSortables.push(sortable);
},
// Enables all of the sortables that were disabled.
enableSortables: function() {
_.each(disabledSortables, function(sortable) {
sortable.enable();
});
disabledSortables = [];
}
}
});
@@ -11,11 +11,9 @@
<div>
<label for="archetypeOverrideDefaultConverter"><input type="checkbox" id="archetypeOverrideDefaultConverter" ng-model="dialogData.model.overrideDefaultPropertyValueConverter" /><archetype-localize key="overrideDefaultConverter">Override Default Property Value Converter?</archetype-localize><small><archetype-localize key="overrideDefaultConverterDescription">Check this if you wish to use your own custom property value converter.</archetype-localize></small></label>
</div>
<div ng-controller="ArchetypeConfigGlobalOptionsController">
<label for="archetypeCheckForNewVersion"><input type="checkbox" id="archetypeCheckForNewVersion" ng-model="globalSettings.checkForNewVersion" ng-click="confirmCheckNewVersionChange();" /><archetype-localize key="checkForNewVersion">Automatically check for newer versions?</archetype-localize><small><archetype-localize key="checkForNewVersionDescription">Check this if you wish to be notified when a newer version of Archetype is available. This is a application level setting.</archetype-localize></small></label>
</div>
<div>
<label for="archetypeAdvancedOptionsConfigModel"><archetype-localize key="configModel">Config Model</archetype-localize><small><archetype-localize key="configModelDescription">Be careful editing the text below, it controls the schema for this Archetype.</archetype-localize></small></label>
<label for="archetypeAdvancedOptionsConfigModel"><archetype-localize key="configModel">Config Model</archetype-localize><small><archetype-localize key="configModelDescription">Be careful editing the text below, it controls the schema for this archetype.</archetype-localize></small></label>
<textarea class="archetypeDeveloperModel" id="archetypeAdvancedOptionsConfigModel" ng-model="dialogData.model" ng-change="dialogData.modelChanged = true"></textarea>
</div>
</div>
@@ -11,13 +11,6 @@
<div>
<label for="archetypeAdvancedOptionsCollapsing"><input type="checkbox" id="archetypeAdvancedOptionsCollapsing" ng-model="dialogData.model.enableCollapsing"/><archetype-localize key="enableCollapsing">Enable Collapsing?</archetype-localize><small><archetype-localize key="enableCollapsingDescription">Enable fieldset collapsing.</archetype-localize></small></label>
</div>
<div>
<label for="archetypeAdvancedOptionsMultipleOpen"><input type="checkbox" id="archetypeAdvancedOptionsMultipleOpen" ng-model="dialogData.model.enableMultipleOpen" /><archetype-localize key="enableMultipleOpen">Enable Multiple Open Fieldsets?</archetype-localize><small><archetype-localize key="enableMultipleOpenDescription">When fieldset collapsing is enabled, this allows multiple fieldsets to be open at the same time.</archetype-localize></small></label>
</div>
<div>
<label for="archetypeAdvancedOptionsMinFieldsets"><archetype-localize key="minFieldsets">Min Fieldsets</archetype-localize><small><archetype-localize key="minFieldsetsDescription">How many Fieldsets are required? Default is none.</archetype-localize></small></label>
<input type="number" id="archetypeAdvancedOptionsMinFieldsets" class="archetypeMaxFieldsets" ng-model="dialogData.model.minFieldsets" />
</div>
<div>
<label for="archetypeAdvancedOptionsMaxFieldsets"><archetype-localize key="maxFieldsets">Max Fieldsets</archetype-localize><small><archetype-localize key="maxFieldsetsDescription">How many Fieldsets are allowed? Entering '1' will disable the controls. Default is unlimited.</archetype-localize></small></label>
<input type="number" id="archetypeAdvancedOptionsMaxFieldsets" class="archetypeMaxFieldsets" ng-model="dialogData.model.maxFieldsets"/>
@@ -37,12 +30,6 @@
<div>
<label for="archetypeAdvancedOptionsPublishing"><input type="checkbox" id="archetypeAdvancedOptionsPublishing" ng-model="dialogData.model.enablePublishing" /><archetype-localize key="enablePublishing">Enable Fieldset Publishing?</archetype-localize><small><archetype-localize key="enablePublishingDescription">Allows fieldsets to be automatically published and/or unpublished.</archetype-localize></small></label>
</div>
<div>
<label for="archetypeAdvancedOptionsCrossDragging"><input type="checkbox" id="archetypeAdvancedOptionsCrossDragging" ng-model="dialogData.model.enableCrossDragging" /><archetype-localize key="enableCrossDragging">Enable Cross-Archetype Dragging?</archetype-localize><small><archetype-localize key="enableCrossDraggingDescription">Allows fieldsets to be dragged into other Archetypes.</archetype-localize></small></label>
</div>
<div>
<label for="archetypeAdvancedOptionsMemberGroups"><input type="checkbox" id="archetypeAdvancedOptionsMemberGroups" ng-model="dialogData.model.enableMemberGroups" /><archetype-localize key="enableMemberGroups">Enable Member Group Access?</archetype-localize><small><archetype-localize key="enableMemerGroupsDescription">Allows fieldsets to be displayed for specified member groups only.</archetype-localize></small></label>
</div>
<h4><archetype-localize key="multipleFieldsets">Multiple fieldsets</archetype-localize></h4>
<div>
+8 -25
View File
@@ -1,17 +1,8 @@
{{VERSION_HTML}}
<div class="archetypeConfig" ng-controller="Imulus.ArchetypeConfigController">
<h2 class="archetype-headline"><img src="../App_Plugins/Archetype/assets/logo_50.png"/>Archetype<small>{{dllVersion}}</small></h2>
<p>At a minimum your Archetype needs at least one fieldset with at least one property. Please use the link below for the full manual. We would really love a donation if you find Archetype useful. Your company can also sponsor a sprint!</p>
<p>
<a class="manual-link" href="https://github.com/kgiszewski/ArchetypeManual" target="_blank">Archetype Manual</a> |
<a class="manual-link" href="https://github.com/kgiszewski/Archetype/blob/master/Terms%20of%20Service.md" target="_blank">Terms of Service</a> |
<a class="manual-link" href="https://www.youtube.com/watch?v=79LksNwGjLk" target="_blank">Quick Start Video</a> |
<a class="manual-link" href="https://twitter.com/archetypekit" target="_blank">Twitter</a> |
<a class="manual-link" href="https://github.com/kgiszewski/Archetype" target="_blank">GitHub</a> |
<a class="manual-link" href="https://github.com/kgiszewski/Archetype/blob/master/Sponsors.md" target="_blank">Become a sponsor</a> |
<a class="manual-link donate-link" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=KBKWLURGLGU6L" target="_blank">Donate!</a>
</p>
<h2 class="archetype-headline"><img src="../App_Plugins/Archetype/assets/logo_50.png"/>Archetype<small>{{dllVersion}}</small><a href="https://twitter.com/archetypekit" target="_blank"><img src="../App_Plugins/Archetype/assets/twitter.png"/></a></h2>
<p>At a minimum your Archetype needs at least one fieldset with at least one property. You can configure it to allow for multiple types of fieldsets within a single Archetype and you can even add another Archetype as a property. Please use the link below for the full manual:</p>
<p><a class="manual-link" href="https://github.com/kgiszewski/ArchetypeManual" target="_blank">Archetype Manual</a></p>
<ul class="archetypeFieldsets" ui-sortable="sortableOptions" ng-model="archetypeConfigRenderModel.fieldsets">
<li ng-repeat="fieldset in archetypeConfigRenderModel.fieldsets" ng-hide="fieldset.remove">
<div class="archetypeFieldsetWrapper" >
@@ -21,16 +12,14 @@
<i class="icon icon-navigation handle" ng-show="canSortFieldset()"></i>
</div>
<div class="archetypeFieldsetTitle" ng-click="focusFieldset(fieldset)">{{fieldset.label}}</div>
<div class="archetypeFieldsetCollapser" ng-hide="fieldset.collapse && fieldset.label" ng-if="isLoaded(fieldset)">
<div class="archetypeFieldsetCollapser" ng-hide="fieldset.collapse && fieldset.label">
<div class="archetypeFieldsetOption">
<label for="archetypeFieldLabel_{{$index}}"><archetype-localize key="label">Label</archetype-localize></label>
<input type="text" id="archetypeFieldLabel_{{$index}}" ng-model="fieldset.label" on-keyup="autoPopulateAlias(fieldset)" />
<small>The label shown to the editors when adding a new fieldset.</small>
<input type="text" id="archetypeFieldLabel_{{$index}}" ng-model="fieldset.label" on-keyup="autoPopulateAlias(this)" />
</div>
<div class="archetypeFieldsetOption">
<label for="archetypeFieldAlias_{{$index}}"><archetype-localize key="alias">Alias</archetype-localize></label>
<input type="text" id="archetypeFieldAlias_{{$index}}" ng-model="fieldset.alias" on-keyup="markAliasDirty(fieldset)" required/>
<small>The alias used to identify the fieldset when rendering.</small>
<input type="text" id="archetypeFieldAlias_{{$index}}" ng-model="fieldset.alias" on-keyup="markAliasDirty(this)" required/>
</div>
<div class="archetypeFieldsetOption" ng-show="archetypeConfigRenderModel.fieldsetGroups.length">
<label for="archetypeFieldsetGroup_{{$index}}"><archetype-localize key="fieldsetGroup">Group</archetype-localize></label>
@@ -39,12 +28,6 @@
<div class="archetypeFieldsetOption">
<label for="archetypeFieldLabelTemplate_{{$index}}"><archetype-localize key="labelTemplate">Label Template</archetype-localize></label>
<input type="text" id="archetypeFieldLabelTemplate_{{$index}}" ng-model="fieldset.labelTemplate" />
<small>Generates labels per fieldset. Can contain property aliases, e.g. "Article: &#123;&#123;title&#125;&#125;".</small>
</div>
<div class="archetypeFieldsetOption">
<label for="archetypeFieldPreview_{{$index}}">Preview image</label>
<input type="text" id="archetypeFieldPreview_{{$index}}" ng-model="fieldset.previewImage" on-keyup="markAliasDirty(fieldset)" />
<small>A relative path to a preview image, e.g. "/assets/fieldset.png".</small>
</div>
<div class="archetypeFieldsetOption" ng-show="archetypeConfigRenderModel.enableMultipleFieldsets">
<label for="archetypeFieldIcon_{{$index}}"><archetype-localize key="icon">Icon</archetype-localize></label>
@@ -67,11 +50,11 @@
<div class="archetypePropertyCollapser" ng-hide="property.collapse && property.label">
<div>
<label for="archetypePropertyLabel_{{$parent.$index}}_{{$index}}"><archetype-localize key="label">Label</archetype-localize></label>
<input type="text" id="archetypePropertyLabel_{{$parent.$index}}_{{$index}}" ng-model="property.label" on-keyup="autoPopulateAlias(property)"/>
<input type="text" id="archetypePropertyLabel_{{$parent.$index}}_{{$index}}" ng-model="property.label" on-keyup="autoPopulateAlias(this)"/>
</div>
<div>
<label for="archetypePropertyAlias_{{$parent.$index}}_{{$index}}"><archetype-localize key="alias">Alias</archetype-localize></label>
<input type="text" id="archetypePropertyAlias_{{$parent.$index}}_{{$index}}" ng-model="property.alias" on-keyup="markAliasDirty(property)" required/>
<input type="text" id="archetypePropertyAlias_{{$parent.$index}}_{{$index}}" ng-model="property.alias" on-keyup="markAliasDirty(this)" required/>
</div>
<div>
<label for="archetypePropertyHelpText_{{$parent.$index}}_{{$index}}"><archetype-localize key="helpText">Help Text</archetype-localize></label>
+25 -73
View File
@@ -1,25 +1,7 @@
{{VERSION_HTML}}
<div class="archetypeEditor ng-class:model.config.customCssClass">
<textarea class="archetypeDeveloperModel" ng-show="model.config.developerMode" ng-model="model.value"></textarea>
<!-- "Add" button. -->
<div ng-show="showAddButton()">
<a class="archetypeAddButton" ng-click="openFieldsetPicker(0, $event)" prevent-default>
<i class="icon icon-add"></i>
<archetype-localize key="addFieldset">Add an item</archetype-localize>
</a>
</div>
<!-- Mandatory validation. -->
<input type="hidden" name="archetypeMandatory" ng-model="model.mandatoryValidation" ng-required="model.validation.mandatory" />
<div><span class="help-inline" val-msg-for="archetypeMandatory" val-toggle-msg="required"><archetype-localize key="required">Required</archetype-localize></span></div>
<!-- Min fieldsets validation. -->
<input type="hidden" name="archetypeMinFieldsets" ng-model="model.mandatoryMinFieldsets" ng-required="!minFieldsetsFulfilled()" />
<div><span class="help-inline" val-msg-for="archetypeMinFieldsets" val-toggle-msg="required">{{minFieldsetsMessage}}</span></div>
<!-- Fieldsets. -->
<ul ui-sortable="sortableOptions" class="archetypeSortable" ng-class="{archetypeEmpty: model.value.fieldsets.length === 0 || sortingLastItem(), archetypeCrossDraggable: model.config.enableCrossDragging}" ng-model="model.value.fieldsets">
<ul ui-sortable="sortableOptions" ng-model="model.value.fieldsets" ng-show="!showAddButton()">
<li ng-repeat="fieldset in model.value.fieldsets">
<fieldset ng-class="['archetype-fieldset-' + fieldset.alias, (getFieldsetValidity(fieldset) == false ? 'archetypeFieldsetError' : '')]" ng-init="fieldsetConfigModel = getConfigFieldsetByAlias(fieldset.alias)">
<div class="archetypeFieldsetLabel" ng-class="{enableCollapsing: model.config.enableCollapsing}">
@@ -64,7 +46,7 @@
</div>
<div class="settings" ng-show="showSettings">
<!-- misc fieldset settings go here -->
<div ng-if="fieldset.releaseDateModel" ng-show="canPublish()" class="control-group">
<div ng-if="fieldset.releaseDateModel" ng-show="canPublish()">
<label ng-hide="model.config.hidePropertyLabels == '1'" class="control-label">
<span><archetype-localize key="publish">Publishing</archetype-localize></span>
<div class="archetypeFieldsetHelpText">
@@ -88,19 +70,6 @@
<archetype-submit-watcher active-submit-watcher="activeSubmitWatcher" load-callback="submitWatcherOnLoad" submit-callback="submitWatcherOnSubmit"></archetype-submit-watcher>
</div>
</div>
<div ng-if="fieldset.allowedMemberGroupsModel" ng-show="canUseMemberGroups()" class="control-group allowedGroups">
<label ng-hide="model.config.hidePropertyLabels == '1'" class="control-label">
<span><archetype-localize key="allowedMemberGroups">Allowed member groups</archetype-localize></span>
<div class="archetypeFieldsetHelpText">
<small><archetype-localize key="allowedMemberGroupsHelpText">Choose the member groups that should be allowed to see this item. Leave empty to allow all member groups.</archetype-localize></small>
</div>
</label>
<div ng-class="[(model.config.hidePropertyLabels == '1' ? 'controls-no-label' : 'controls')]">
<umb-editor model="fieldset.allowedMemberGroupsModel"></umb-editor>
</div>
<!-- we need a submit watcher here to make sure the allowed member groups are saved back to the model -->
<archetype-submit-watcher active-submit-watcher="activeSubmitWatcher" load-callback="submitWatcherOnLoad" submit-callback="submitWatcherOnSubmit"></archetype-submit-watcher>
</div>
</div>
</div>
</form>
@@ -108,49 +77,32 @@
</fieldset>
</li>
</ul>
<!-- Fieldset picker. -->
<div ng-show="showAddButton()">
<a class="archetypeAddButton" ng-click="openFieldsetPicker(0, $event)" prevent-default>
<i class="icon icon-add"></i>
<archetype-localize key="addFieldset">Add an item</archetype-localize>
</a>
</div>
<div class="usky-grid fieldsetPicker" ng-class="{withGroups: overlayMenu.fieldsetGroups.length > 1}" ng-if="overlayMenu.show">
<div class="cell-tools-menu" ng-style="overlayMenu.style" delayed-mouseleave="closeFieldsetPicker()" archetype-click-outside="closeFieldsetPicker()">
<div ng-show="!overlayMenu.fieldsetPreview">
<h5>
<archetype-localize key="addFieldset">Add an item</archetype-localize>
</h5>
<ul class="groups" ng-show="overlayMenu.fieldsetGroups.length > 1">
<li ng-repeat="fieldsetGroup in overlayMenu.fieldsetGroups" ng-class="{active: fieldsetGroup == overlayMenu.activeFieldsetGroup}">
<a ng-click="overlayMenu.activeFieldsetGroup = fieldsetGroup">
{{fieldsetGroup.name}}
</a>
</li>
</ul>
<ul class="elements">
<li ng-repeat="fieldset in overlayMenu.activeFieldsetGroup.fieldsets">
<a ng-click="pickFieldset(fieldset.alias, overlayMenu.index)" href>
<i class="icon {{fieldset.icon}}"></i>
{{fieldset.label}}
</a>
<div class="fieldsetPreviewOpen" ng-if="fieldset.previewImage">
<a href ng-click="openFieldsetPreview(fieldset)"><archetype-localize key="previewFieldsetOpen">(see preview)</archetype-localize></a>
</div>
</li>
</ul>
</div>
<div ng-show="overlayMenu.fieldsetPreview" class="fieldsetPreview">
<h5>
<archetype-localize key="previewFieldsetHeader">Preview: </archetype-localize>{{overlayMenu.fieldsetPreview.label}}
</h5>
<div class="fieldsetPreviewClose">
<a href ng-click="closeFieldsetPreview()"><archetype-localize key="previewFieldsetClose">(close preview)</archetype-localize></a>
</div>
<div class="fieldsetPreviewImage">
<a href="{{overlayMenu.fieldsetPreview.previewImage}}" target="_blank">
<img ng-src="{{overlayMenu.fieldsetPreview.previewImage}}" />
<h5>
<archetype-localize key="addFieldset">Add an item</archetype-localize>
</h5>
<ul class="groups" ng-show="overlayMenu.fieldsetGroups.length > 1">
<li ng-repeat="fieldsetGroup in overlayMenu.fieldsetGroups" ng-class="{active: fieldsetGroup == overlayMenu.activeFieldsetGroup}">
<a ng-click="overlayMenu.activeFieldsetGroup = fieldsetGroup">
{{fieldsetGroup.name}}
</a>
</div>
<div class="fieldsetPreviewClose">
<a href ng-click="closeFieldsetPreview()"><archetype-localize key="previewFieldsetClose">(close preview)</archetype-localize></a>
</div>
</div>
</li>
</ul>
<ul class="elements">
<li ng-repeat="fieldset in overlayMenu.activeFieldsetGroup.fieldsets">
<a ng-click="pickFieldset(fieldset.alias, overlayMenu.index)" href>
<i class="icon {{fieldset.icon}}"></i>
{{fieldset.label}}
</a>
</li>
</ul>
</div>
</div>
</div>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

+4 -4
View File
@@ -1,9 +1,9 @@
{
"name": "Archetype",
"version": "1.16.0",
"url": "http://github.com/kgiszewski/archetype/",
"author": "Kevin Giszewski - Tom Fulton - Lee Kelleher - Matt Brailsford - Kenn Jacobsen - Nicholas Westby - Et. Al.",
"authorUrl": "http://github.com/kgiszewski/archetype/",
"version": "1.13.0",
"url": "http://github.com/imulus/archetype/",
"author": "Imulus - Kevin Giszewski - Tom Fulton - Lee Kelleher - Matt Brailsford - Kenn Jacobsen - Et. Al.",
"authorUrl": "http://imulus.com/",
"license": "MIT",
"licenseUrl": "http://opensource.org/licenses/MIT"
}
+4 -4
View File
@@ -4,12 +4,12 @@
<id>Archetype</id>
<version><%= version %></version>
<title><%= name %></title>
<authors>kgiszewski, tomfulton</authors>
<owners>kgiszewski, tomfulton</owners>
<projectUrl>http://github.com/kgiszewski/archetype</projectUrl>
<authors>imulus, kgiszewski, tomfulton</authors>
<owners>imulus, kgiszewski, tomfulton</owners>
<projectUrl>http://github.com/imulus/archetype</projectUrl>
<description><![CDATA[Archetype for Umbraco]]></description>
<tags>umbraco</tags>
<iconUrl>http://imulus.github.io/Archetype/images/logo.png</iconUrl>
<iconUrl>http://github.com/imulus/archetype/raw/master/assets/logo.png</iconUrl>
<licenseUrl><%= licenseUrl %></licenseUrl>
<dependencies>
<dependency id="Archetype.Binaries" version="<%= version %>" />
+4 -4
View File
@@ -4,12 +4,12 @@
<id>Archetype.Binaries</id>
<version><%= version %></version>
<title><%= name %></title>
<authors>kgiszewski, tomfulton</authors>
<owners>kgiszewski, tomfulton</owners>
<projectUrl>http://github.com/kgiszewski/archetype</projectUrl>
<authors>imulus, kgiszewski, tomfulton</authors>
<owners>imulus, kgiszewski, tomfulton</owners>
<projectUrl>http://github.com/imulus/archetype</projectUrl>
<description><![CDATA[Archetype binaries for Umbraco]]></description>
<tags>umbraco</tags>
<iconUrl>http://imulus.github.io/Archetype/images/logo.png</iconUrl>
<iconUrl>http://github.com/imulus/archetype/raw/master/assets/logo.png</iconUrl>
<licenseUrl><%= licenseUrl %></licenseUrl>
<dependencies>
<dependency id="UmbracoCms.Core" version="7.2.2" />
+2 -2
View File
@@ -6,10 +6,10 @@
<title><%= name %></title>
<authors>leekelleher</authors>
<owners>kgiszewski, leekelleher</owners>
<projectUrl>http://github.com/kgiszewski/archetype</projectUrl>
<projectUrl>http://github.com/imulus/archetype</projectUrl>
<description><![CDATA[Archetype Courier extension for Umbraco]]></description>
<tags>umbraco</tags>
<iconUrl>http://imulus.github.io/Archetype/images/logo.png</iconUrl>
<iconUrl>http://github.com/imulus/archetype/raw/master/assets/logo.png</iconUrl>
<licenseUrl><%= licenseUrl %></licenseUrl>
<dependencies>
<dependency id="Archetype.Binaries" version="<%= version %>" />