diff --git a/UmbracoPackages/App_Plugins/brothers.uNesting/package.manifest b/UmbracoPackages/App_Plugins/brothers.uNesting/package.manifest
index 7c748b6..e7c9b1e 100644
--- a/UmbracoPackages/App_Plugins/brothers.uNesting/package.manifest
+++ b/UmbracoPackages/App_Plugins/brothers.uNesting/package.manifest
@@ -1,6 +1,7 @@
{
"javascript": [
- "~/App_Plugins/brothers.uNesting/uNesting.js"
+ "~/App_Plugins/brothers.uNesting/uNesting.js",
+ "~/App_Plugins/brothers.uNesting/uNesting.directives.js"
],
"css": [
"~/App_Plugins/brothers.uNesting/uNesting.css"
diff --git a/UmbracoPackages/App_Plugins/brothers.uNesting/uNesting.css b/UmbracoPackages/App_Plugins/brothers.uNesting/uNesting.css
index 9d44f97..f948ff6 100644
--- a/UmbracoPackages/App_Plugins/brothers.uNesting/uNesting.css
+++ b/UmbracoPackages/App_Plugins/brothers.uNesting/uNesting.css
@@ -90,7 +90,7 @@
position: relative;
margin-top: 1px;
padding: 20px 0;
- color: #1b264f;
+ color: #000;
border-radius: 3px 3px 0 0;
border-bottom: none;
background: none;
@@ -107,8 +107,7 @@
top: 50%;
margin-top: -12px;
left: 3px;
- font-size: 1.4rem;
- z-index: 1;
+ font-size: 20px;
}
.unesting-item-header-content.--has-icon
@@ -130,15 +129,15 @@
bottom: -15px;
}
-.unesting-item-header:hover .unesting-item-header-inner .unesting-item-header-content
+/*.unesting-item-header:hover .unesting-item-header-inner .unesting-item-header-content
{
padding-right: 130px;
-}
+}*/
.unesting-item-header-content
{
line-height: 20px;
- color: #1b264f;
+ color: #000;
white-space: nowrap;
position: relative;
}
@@ -189,9 +188,10 @@ un-config
{
position: absolute;
right: 0;
- top: 50%;
+ top: 0;
+ bottom: 0;
+ align-items: center;
padding: 5px;
- margin-top: -22px;
display: flex;
grid-gap: 8px;
}
@@ -200,6 +200,7 @@ un-config
{
transition: opacity .12s ease-in-out;
opacity: 0;
+ background: white;
}
.unesting-item-header:hover .unesting-icons > *
@@ -215,11 +216,11 @@ un-config
height: 32px;
justify-content: center;
align-items: center;
- border-radius: 20px;
- border: 1px solid #e9e9eb;
+ border-radius: 16px;
cursor: pointer;
- color: #1b264f;
+ color: #000;
transition: background 0.12s ease;
+ border: 1px solid #f6f6f7;
}
.unesting-icon.is-negative:hover
@@ -241,7 +242,7 @@ un-config
height: 3px;
width: 3px;
border-radius: 50%;
- background: #1b264f;
+ background: #000;
display: inline-block;
margin: 0 1px;
opacity: .6;
@@ -280,7 +281,7 @@ un-config
.unesting-content > .umb-pane
{
- margin: 30px 20px;
+ margin: 30px 20px 30px 20px;
}
.unesting-item.is-active > .unesting-content
@@ -324,9 +325,14 @@ un-config
border-bottom-color: #e9e9eb;
}
+.unesting-item .unesting-item .unesting-icons > *
+{
+ background: #faf8f8;
+ border-color: #e9e9eb;
+}
+
/* media */
-
.unesting-media
{
display: flex;
@@ -431,7 +437,7 @@ un-config
background: #f6f4f4;
border-radius: 4px;
width: 180px;
- min-height: 60px;
+ /*min-height: 60px;*/
max-height: 65px;
padding: 10px 15px;
display: block;
@@ -444,7 +450,7 @@ un-config
font-size: 14px;
white-space: nowrap;
text-overflow: ellipsis;
- color: #1b264f;
+ color: #333;
height: 20px;
overflow: hidden;
margin-bottom: 5px;
@@ -514,7 +520,7 @@ un-config
{
display: block;
font-size: 14px;
- color: #1b264f;
+ color: #000;
font-weight: 600;
margin-bottom: 4px;
}
@@ -531,9 +537,9 @@ un-config
/* doctypepicker */
-.unesting-doctype-textarea
+.unesting-doctype-template
{
- width: 100%;
+ width: 400px;
height: 64px;
max-height: 200px;
min-height: 32px;
@@ -572,7 +578,7 @@ un-config
.unesting-item[unesting-alias="newsletterHeadline"] .unesting-text-partial[unesting-index="0"]
{
font-size: 16px;
- color: #1b264f;
+ color: #000;
font-weight: 600;
}
@@ -594,9 +600,12 @@ un-config
content: '“';
}
+.umb-nested-content-property-container
+{
+ margin-bottom: 12px;
+}
/* generic overrides */
-
.btn-info
{
color: #454957;
diff --git a/UmbracoPackages/App_Plugins/brothers.uNesting/uNesting.directives.js b/UmbracoPackages/App_Plugins/brothers.uNesting/uNesting.directives.js
new file mode 100644
index 0000000..f1ea618
--- /dev/null
+++ b/UmbracoPackages/App_Plugins/brothers.uNesting/uNesting.directives.js
@@ -0,0 +1,457 @@
+
+
+angular.module('umbraco.directives').directive('unContent', function ($compile)
+{
+ return {
+ restrict: 'E',
+ scope: {
+ item: '=',
+ node: '=',
+ config: '='
+ },
+ link: function (scope, element)
+ {
+ // get template
+ var template = scope.config && scope.config.nameTemplate ? scope.config.nameTemplate : null;
+
+ // compile & render template
+ function render()
+ {
+ // merge element values into local scope
+ angular.merge(scope, scope.item);
+
+ // nothing when no template is specified
+ if (!template)
+ {
+ element.html('');
+ //element.html(scope.node.documentType.description);
+ return;
+ }
+
+ // create html and compile
+ element.html(template);
+ $compile(element.contents())(scope);
+ }
+
+ //scope.$watch('item', function (value)
+ //{
+ // render();
+ //});
+
+ // first-time rendering
+ render();
+ }
+ };
+});
+
+
+angular.module('umbraco.directives').directive('unMedia', function ($http, $compile, umbRequestHelper)
+{
+ var sizes = {
+ small: 'width=30&height=30&mode=crop&quality=60',
+ medium: 'width=60&height=60&mode=crop&quality=60',
+ large: 'width=100&height=100&mode=crop&quality=60',
+ wide: 'width=100&height=60&mode=crop&quality=60',
+ high: 'width=60&height=100&mode=crop&quality=60'
+ };
+
+ return {
+ restrict: 'E',
+ scope: {
+ model: '=',
+ key: '@',
+ titleKey: '@',
+ limit: '@',
+ size: '@',
+ hideLabel: '@'
+ },
+
+ template: '
',
+
+ link: function (scope, element)
+ {
+ scope._size = sizes[scope.size] ? scope.size : 'medium';
+
+ var resize = sizes[scope._size];
+ var limit = scope.limit || 5;
+ scope.media = [];
+
+ var titleCache = {};
+
+
+ // compile & render template
+ function render()
+ {
+ var ids = scope.model;
+
+ if (!scope.model)
+ {
+ return;
+ }
+
+ if (_.isArray(scope.model))
+ {
+ if (typeof scope.model[0] !== 'string' && !scope.key)
+ {
+ console.error("You need the property for nested media");
+ return;
+ }
+
+ ids = _.map(scope.model, function (item)
+ {
+ if (typeof item === 'string')
+ {
+ return item;
+ }
+
+ var value = item[scope.key];
+
+ if (scope.titleKey)
+ {
+ titleCache[value] = item[scope.titleKey];
+ }
+
+ return value;
+ }).join(',');
+ }
+
+ ids = _.filter(ids.split(','), function (id) { return !!id; });
+ scope.count = ids.length;
+
+ var query = "ids=" + ids.slice(0, limit).join('&ids=');
+ var url = $http.get(Umbraco.Sys.ServerVariables.umbracoSettings.umbracoPath + "/backoffice/UmbracoApi/Unesting/GetMediaByUdis?" + query);
+
+ umbRequestHelper.resourcePromise(url, 'Failed to retrieve data for media ids').then(function (result)
+ {
+ _.each(result, function (src, id)
+ {
+ scope.media.push({
+ id: id,
+ src: src + "?" + resize,
+ title: titleCache[id]
+ });
+ });
+
+ // hide label if requested
+ if (scope.media.length > 0 && (scope.hideLabel === true || scope.hideLabel === 'true' || scope.hideLabel === '1'))
+ {
+ element.closest('.unesting-item-header').addClass('no-label');
+ }
+ });
+ }
+
+ render();
+ }
+ };
+});
+
+
+
+angular.module('umbraco.directives').directive('unText', function ($filter)
+{
+ return {
+ restrict: 'E',
+ scope: {
+ model: '=',
+ maxLines: '@',
+ hideLabel: '@'
+ },
+
+ template: '' +
+ '' +
+ '
',
+
+ link: function (scope, element)
+ {
+ scope.maxLines = +scope.maxLines || 2;
+ scope.items = [];
+
+ if (!scope.model)
+ {
+ return;
+ }
+
+ // hide label if requested
+ if (scope.hideLabel === true || scope.hideLabel === 'true' || scope.hideLabel === '1')
+ {
+ element.closest('.unesting-item-header').addClass('no-label');
+ }
+
+ var partials = _.filter(!_.isArray(scope.model) ? [scope.model] : scope.model, function (text) { return !!text; });
+
+ scope.items = _.map(partials, function (text)
+ {
+ return $filter('unHtml')(text, 1000);
+ });
+ }
+ };
+});
+
+
+
+angular.module('umbraco.directives').directive('unBoxes', function ($compile)
+{
+ return {
+ restrict: 'E',
+ scope: {
+ model: '=',
+ key: '@',
+ titleKey: '@',
+ limit: '@',
+ size: '@',
+ hideLabel: '@'
+ },
+
+ template: '' +
+ '
' +
+ '{{item.headline | unHtml }}' +
+ '{{item.text | unHtml:200 }}' +
+ '
' +
+ '
+{{count - items.length}}' +
+ '
',
+
+ link: function (scope, element)
+ {
+ var maxLines = {
+ medium: 3,
+ large: 6
+ };
+
+ scope.size = maxLines[scope.size] ? scope.size : 'medium';
+ var limit = +scope.limit || 3;
+ scope.items = [];
+
+ if (!scope.model)
+ {
+ return;
+ }
+
+ // hide label if requested
+ if (scope.hideLabel === true || scope.hideLabel === 'true' || scope.hideLabel === '1')
+ {
+ element.closest('.unesting-item-header').addClass('no-label');
+ }
+
+ if (!_.isArray(scope.model))
+ {
+ console.error("The model has to be an array");
+ return;
+ }
+
+ if (_.isObject(scope.model[0]) && !scope.key)
+ {
+ console.error("You need the property for nested elements");
+ return;
+ }
+
+ var items = [];
+ _.each(scope.model, function (item)
+ {
+ var max = maxLines[scope.size];
+
+ if (item)
+ {
+ if (typeof item === 'string')
+ {
+ items.push({
+ maxLines: max,
+ text: item
+ });
+ }
+
+ var headline = item[scope.titleKey];
+
+ items.push({
+ maxLines: headline ? max - 1 : max,
+ headline: headline,
+ text: item[scope.key]
+ });
+ }
+ });
+
+ scope.items = items.slice(0, limit);
+ scope.count = items.length;
+ }
+ };
+});
+
+
+
+angular.module('umbraco.directives').directive('unFigure', function ($filter)
+{
+ return {
+ restrict: 'E',
+ scope: {
+ image: '=',
+ text: '=',
+ headline: '=',
+ size: '@',
+ maxLines: '@',
+ hideLabel: '@'
+ },
+
+ template: '',
+
+ link: function (scope, element)
+ {
+ scope.hasContent = !!(scope.text || scope.headline || scope.image);
+
+ // hide label if requested
+ if (scope.hideLabel === true || scope.hideLabel === 'true' || scope.hideLabel === '1')
+ {
+ element.closest('.unesting-item-header').toggleClass('no-label', scope.hasContent);
+ }
+
+ // calculate max lines
+ scope.maxLines = +scope.maxLines || 3;
+ if (scope.headline)
+ {
+ scope.maxLines -= 1;
+ }
+ }
+ };
+});
+
+
+
+angular.module('umbraco.directives').directive('unConfig', function ($filter)
+{
+ return {
+ restrict: 'E',
+ scope: {
+ hideLabel: '@',
+ asColumns: '@'
+ },
+
+ template: '',
+
+ link: function (scope, element)
+ {
+ if (scope.hideLabel === true || scope.hideLabel === 'true' || scope.hideLabel === '1')
+ {
+ element.closest('.unesting-item-header').addClass('no-label');
+ }
+ if (scope.asColumns === true || scope.asColumns === 'true' || scope.asColumns === '1')
+ {
+ element.closest('.unesting-item-header').addClass('as-columns');
+ }
+ }
+ };
+});
+
+
+
+angular.module("umbraco.directives").directive('uNestingContentEditor', [
+
+ function ()
+ {
+ var link = function ($scope)
+ {
+ // Clone the model because some property editors
+ // do weird things like updating and config values
+ // so we want to ensure we start from a fresh every
+ // time, we'll just sync the value back when we need to
+ $scope.model = angular.copy($scope.ngModel);
+ $scope.nodeContext = $scope.model;
+
+ // Find the selected tab
+ var selectedTab = $scope.model.variants[0].tabs[0];
+
+ if ($scope.tabAlias)
+ {
+ angular.forEach($scope.model.variants[0].tabs, function (tab)
+ {
+ if (tab.alias.toLowerCase() === $scope.tabAlias.toLowerCase())
+ {
+ selectedTab = tab;
+ return;
+ }
+ });
+ }
+
+ $scope.tabs = $scope.model.variants[0].tabs;
+
+ var contentTab = _.find($scope.tabs, function (tab)
+ {
+ var alias = tab.alias.toLowerCase();
+ return tab.id !== 0 && alias !== 'unestingsettings' && (!$scope.tabAlias || alias === $scope.tabAlias.toLowerCase());
+ });
+
+ $scope.contentProperties = _.filter(contentTab.properties, function (prop)
+ {
+ return prop.propertyAlias.toLowerCase() !== 'unestinghide';
+ });
+
+ //var settingsTab = _.find($scope.tabs, function (tab)
+ //{
+ // var alias = tab.alias.toLowerCase();
+ // return tab.id !== 0 && alias === 'unestingsettings';
+ //});
+
+ //$scope.settingsProperties = settingsTab ? settingsTab.properties : [];
+ $scope.settingsProperties = [];
+
+ // Listen for sync request
+ var unsubscribe = $scope.$on("ncSyncVal", function (ev, args)
+ {
+ if (args.key === $scope.model.key)
+ {
+ // Tell inner controls we are submitting
+ $scope.$broadcast("formSubmitting", { scope: $scope });
+
+ // Sync the values back
+ angular.forEach($scope.ngModel.variants[0].tabs, function (tab)
+ {
+ if (tab.alias.toLowerCase() === selectedTab.alias.toLowerCase())
+ {
+
+ var localPropsMap = selectedTab.properties.reduce(function (map, obj)
+ {
+ map[obj.alias] = obj;
+ return map;
+ }, {});
+
+ angular.forEach(tab.properties, function (prop)
+ {
+ if (localPropsMap.hasOwnProperty(prop.alias))
+ {
+ prop.value = localPropsMap[prop.alias].value;
+ }
+ });
+
+ }
+ });
+ }
+ });
+
+ $scope.$on('$destroy', function ()
+ {
+ unsubscribe();
+ });
+ };
+
+ return {
+ restrict: "E",
+ replace: true,
+ templateUrl: Umbraco.Sys.ServerVariables.umbracoSettings.umbracoPath + "/views/propertyeditors/nestedcontent/nestedcontent.editor.html",
+ scope: {
+ ngModel: '=',
+ tabAlias: '='
+ },
+ link: link
+ };
+
+ }
+]);
\ No newline at end of file
diff --git a/UmbracoPackages/App_Plugins/brothers.uNesting/uNesting.docTypePicker.html b/UmbracoPackages/App_Plugins/brothers.uNesting/uNesting.docTypePicker.html
index 82e6275..ef3ae4f 100644
--- a/UmbracoPackages/App_Plugins/brothers.uNesting/uNesting.docTypePicker.html
+++ b/UmbracoPackages/App_Plugins/brothers.uNesting/uNesting.docTypePicker.html
@@ -32,7 +32,8 @@
ng-model="config.ncTabAlias" required>
-
+
+
|
|