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
21 changed files with 72 additions and 562 deletions
@@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System.Web.Security;
using Newtonsoft.Json;
using Umbraco.Core;
using System;
@@ -30,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>
@@ -143,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
@@ -32,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;
@@ -34,12 +34,6 @@ 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; }
@@ -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,4 +1,4 @@
using System.Reflection;
[assembly: AssemblyVersion("1.13.1")]
[assembly: AssemblyFileVersion("1.13.1")]
[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);
}
@@ -216,7 +215,7 @@ namespace Archetype.PropertyEditors
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 -1
View File
@@ -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, "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;
+39 -322
View File
@@ -1,9 +1,6 @@
{{VERSION}}
angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, $filter, assetsService, angularHelper, notificationsService, $timeout, fileManager, entityResource, archetypeService, archetypeLabelService, archetypeCacheService, archetypePropertyEditorResource) {
// Variables.
var draggedParent;
//$scope.model.value = "";
$scope.model.hideLabel = $scope.model.config.hideLabel == 1;
@@ -46,201 +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;
}
// 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) {
@@ -323,11 +155,6 @@ 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);
}
@@ -349,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);
}
}
@@ -382,20 +196,18 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
$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 () {
@@ -414,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 () {
@@ -442,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) {
@@ -538,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
@@ -565,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 = [];
@@ -612,12 +406,6 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($sc
//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;
@@ -669,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)
@@ -736,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 () {
@@ -793,8 +581,6 @@ 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;
});
});
@@ -811,73 +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 targetFieldsets = targetScope.model.config.fieldsets;
var model = sourceScope.fieldsetConfigModel;
var canRemove = sourceScope.canRemove();
var canAdd = targetScope.canAdd();
var valid = canRemove && canAdd;
valid = valid && modelMatchesAnyFieldset(model, targetFieldsets);
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;
}
});
+2 -8
View File
@@ -72,14 +72,8 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c
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;
+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 -5
View File
@@ -51,9 +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."
"settings": "Indstillinger"
}
+1 -5
View File
@@ -51,9 +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."
"settings": "Indstillinger"
}
-2
View File
@@ -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
View File
@@ -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
View File
@@ -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",
-20
View File
@@ -337,28 +337,8 @@
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 {
min-height: 42px;
border: 1px dashed #dddddd;
margin-top: 5px;
}
}
.archetypeEditor, .archetypeConfig {
+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 = [];
}
}
});
@@ -30,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 -27
View File
@@ -1,17 +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>
<!-- Fieldsets. -->
<ul ui-sortable="sortableOptions" class="archetypeSortable" ng-class="{archetypeEmpty: model.value.fieldsets.length === 0 || sortingLastItem()}" 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}">
@@ -56,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">
@@ -80,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>
@@ -100,8 +77,12 @@
</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()">
<h5>
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "Archetype",
"version": "1.13.1",
"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/",