From dd453fc66aa9cd2843eb8b1ebe5dbb0700b039bf Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Wed, 12 Mar 2014 17:13:23 -0600 Subject: [PATCH 01/17] PVC: Return empty Archetype instead of null when empty/errors --- .../PropertyConverters/ArchetypeValueConverter.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs b/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs index 949f9dd..a8bfc8b 100644 --- a/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs +++ b/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs @@ -37,8 +37,10 @@ namespace Archetype.Umbraco.PropertyConverters public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) { + var defaultValue = new Models.Archetype(); + if (source == null) - return null; + return defaultValue; var sourceString = source.ToString(); @@ -79,11 +81,11 @@ namespace Archetype.Umbraco.PropertyConverters } catch (Exception ex) { - return null; + return defaultValue; } } - return sourceString; + return defaultValue; } internal ArchetypePreValue GetArchetypePreValueFromDataTypeId(int dataTypeId) From 512edaeaf908ccb72fabb8e44e3a0b042a748af1 Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Wed, 12 Mar 2014 17:36:15 -0600 Subject: [PATCH 02/17] Make Archetype Model enumerable to simplify usage, make Fieldsets internal --- .../Umbraco.Archetype/Models/Archetype.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/Umbraco/Umbraco.Archetype/Models/Archetype.cs b/app/Umbraco/Umbraco.Archetype/Models/Archetype.cs index 1c920bf..207e9f6 100644 --- a/app/Umbraco/Umbraco.Archetype/Models/Archetype.cs +++ b/app/Umbraco/Umbraco.Archetype/Models/Archetype.cs @@ -1,16 +1,28 @@ -using System.Collections.Generic; +using System.Collections; +using System.Collections.Generic; using Newtonsoft.Json; namespace Archetype.Umbraco.Models { - public class Archetype + [JsonObject] + public class Archetype : IEnumerable
{ [JsonProperty("fieldsets")] - public IEnumerable
Fieldsets { get; set; } + internal IEnumerable
Fieldsets { get; set; } public Archetype() { Fieldsets = new List
(); } + + public IEnumerator
GetEnumerator() + { + return this.Fieldsets.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } } } From 30d0d11af03b578cfc0ff96e501006f6048d3eef Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Thu, 13 Mar 2014 00:40:56 -0600 Subject: [PATCH 03/17] Fix typo in label --- app/views/archetype.config.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/archetype.config.html b/app/views/archetype.config.html index 7420820..c80bf10 100644 --- a/app/views/archetype.config.html +++ b/app/views/archetype.config.html @@ -98,7 +98,7 @@
- +
From 0a65c1a8434a517185d67e9a64be84615ed93f40 Mon Sep 17 00:00:00 2001 From: Dillon Morton Date: Fri, 14 Mar 2014 17:34:16 -0600 Subject: [PATCH 04/17] Fix repeater button bugs --- app/less/archetype.less | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/app/less/archetype.less b/app/less/archetype.less index fb0a7c1..eb7370f 100644 --- a/app/less/archetype.less +++ b/app/less/archetype.less @@ -13,14 +13,14 @@ } .archetypeEditor .archetypeFieldsetLabel { - padding-left: 3px; - width: 98%; + position: relative; + width: 100%%; .label-sub { padding: 8px 0; display: inline-block; &.module-label { - width: 89%; + width: 100%; } } @@ -46,7 +46,8 @@ } .caret { - margin: 8px 1px 0 7px; + margin: 8px 1px 0 15px; + &.caret-right { border-bottom: 4px solid transparent; border-top: 4px solid transparent; @@ -84,8 +85,11 @@ margin-left: 0; } -.archetypeEditor, .archetypeConfig{ - .archetypeEditorControls{ +.archetypeEditor, +.archetypeConfig { + .archetypeEditorControls { + float: right; + i { cursor: pointer; &.handle { @@ -95,7 +99,16 @@ } } -.archetypeConfig .archetypeEditorControls { float: right; } +.archetypeEditor .archetypeEditorControls { + float: none; + position: absolute; + right: 15px; + top: 0; +} + +.archetypeConfig .archetypeEditorControls { + float: right; +} .archetypeEditor form { margin-left:20px; From 35ea62dff10b97739700009c859067524c075c4c Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Fri, 14 Mar 2014 20:15:19 -0600 Subject: [PATCH 05/17] Add "Hide Label" option for full-width Archetypes --- app/controllers/controller.js | 1 + app/package.manifest | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/app/controllers/controller.js b/app/controllers/controller.js index 1b1b850..d1e8c19 100644 --- a/app/controllers/controller.js +++ b/app/controllers/controller.js @@ -1,6 +1,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, assetsService, angularHelper, notificationsService, $timeout) { //$scope.model.value = ""; + $scope.model.hideLabel = $scope.model.config.hideLabel == 1; //get a reference to the current form var form = angularHelper.getCurrentForm($scope); diff --git a/app/package.manifest b/app/package.manifest index edf1d6d..3632228 100644 --- a/app/package.manifest +++ b/app/package.manifest @@ -19,6 +19,12 @@ type: "Required" } ] + }, + { + label: "Hide Label", + description: "Hide the Umbraco property title and description, making the Archetype span the entire page width", + key: "hideLabel", + view: "boolean" } ] } From 363e61434937083eeaf57301ddb8b681d4096bc3 Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Fri, 14 Mar 2014 22:28:27 -0600 Subject: [PATCH 06/17] Allow single rows to be collapsed Previously, you couldn't collapse a single row by itself, it was always expanded. Now you can collapse it, but it's still expanded on the initial page load. --- app/controllers/controller.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controllers/controller.js b/app/controllers/controller.js index 1b1b850..93d50c9 100644 --- a/app/controllers/controller.js +++ b/app/controllers/controller.js @@ -152,16 +152,16 @@ } _.each($scope.archetypeRenderModel.fieldsets, function(fieldset){ - if($scope.archetypeRenderModel.fieldsets.length == 1 && fieldset.remove == false) - { - fieldset.collapse = false; - return; - } - fieldset.collapse = true; }); - if(iniState) + if(!fieldset && $scope.archetypeRenderModel.fieldsets.length == 1 && $scope.archetypeRenderModel.fieldsets[0].remove == false) + { + $scope.archetypeRenderModel.fieldsets[0].collapse = false; + return; + } + + if(iniState && fieldset) { fieldset.collapse = !iniState; } From 504a3b5c045dd716d259854947a8b2bd458f7882 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 17 Mar 2014 15:04:52 +0000 Subject: [PATCH 07/17] Added methods `HasProperty` and `HasValue` Added methods to the `Fieldset` object for checking if a property exists and/or if it has a value. --- app/Umbraco/Umbraco.Archetype/Models/Fieldset.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/Umbraco/Umbraco.Archetype/Models/Fieldset.cs b/app/Umbraco/Umbraco.Archetype/Models/Fieldset.cs index 934a51d..23dec2d 100644 --- a/app/Umbraco/Umbraco.Archetype/Models/Fieldset.cs +++ b/app/Umbraco/Umbraco.Archetype/Models/Fieldset.cs @@ -35,6 +35,20 @@ namespace Archetype.Umbraco.Models return property.GetValue(); } + public bool HasProperty(string propertyAlias) + { + return GetProperty(propertyAlias) != null; + } + + public bool HasValue(string propertyAlias) + { + var property = GetProperty(propertyAlias); + if (property == null) + return false; + + return !string.IsNullOrEmpty(property.Value.ToString()); + } + private Property GetProperty(string propertyAlias) { return Properties.FirstOrDefault(p => p.Alias.InvariantEquals(propertyAlias)); From e374a9f01bc2ca4e785ac176901fa2519d07697e Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Mon, 17 Mar 2014 19:04:10 -0600 Subject: [PATCH 08/17] Cleanup Gruntfile, streamline copy tasks grunt watch:dev -> grunt watch --- Gruntfile.js | 109 +++++++++++++++++++++------------------------------ README.md | 12 +++--- package.json | 3 ++ 3 files changed, 52 insertions(+), 72 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 50084a6..3c6223a 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,36 +1,45 @@ module.exports = function(grunt) { + require('load-grunt-tasks')(grunt); + var path = require('path') + grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), pkgMeta: grunt.file.readJSON('pkg/meta.json'), - dest: 'dist', + dest: (grunt.option('target') || 'dist') + '/App_Plugins/Archetype', package_dir: 'pkg', package_temp_dir: '<%= package_dir %>/tmp/', csProj: 'app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj', watch: { + options: { + spawn: false + }, + less: { files: ['app/less/*.less', 'lib/**/*.less'], - tasks: ['less:build'], - options: { - spawn: false - } + tasks: ['less:dist'], }, js: { files: ['app/**/*.js', 'lib/**/*.js'], tasks: ['concat', 'jshint'], - options: { - spawn: false - } }, - dev: { - files: ['app/**', '!app/Umbraco/**', 'app/Umbraco/**/*.dll'], - tasks: ['deploy'], - options: { - spawn: false - } + views: { + files: ['/app/views/**/*'], + tasks: ['copy:views'] + }, + + dll: { + files: ['app/Umbraco/**/*.dll'], + tasks: ['copy:dll'], + } + }, + + touch: { + webconfig: { + src: ['<%= grunt.option("target") %>\\Web.config'] } }, @@ -44,7 +53,7 @@ module.exports = function(grunt) { }, less: { - build: { + dist: { options: { paths: ["app/less", "lib/less", "vendor"], }, @@ -58,7 +67,7 @@ module.exports = function(grunt) { options: { stripBanners: false }, - application: { + dist: { src: [ 'app/controllers/controller.js', 'app/controllers/config.controller.js', @@ -79,7 +88,7 @@ module.exports = function(grunt) { }, template: { - 'nuget_manifest': { + 'nuspec': { 'options': { 'data': { name: '<%= pkgMeta.name %>', @@ -104,42 +113,31 @@ module.exports = function(grunt) { }, copy: { - build: { - files: [ - {expand: true, cwd: 'app/', src: ['package.manifest'], dest: '<%= dest %>', flatten: true}, - {expand: true, cwd: 'app/views/', src: ['archetype.html', 'archetype.config.html'], dest: '<%= dest %>/views', flatten: true}, - {expand: true, cwd: 'app/config/', src: ['propertyEditors.views.js'], dest: '<%= dest %>/js', flatten: true}, - {expand: true, cwd: 'app/langs/', src: ['**'], dest: '<%= dest %>/langs', flatten: true}, - {expand: true, cwd: 'app/Umbraco/Umbraco.Archetype/bin/Debug/', src: ['Archetype.dll', 'Archetype.pdb'], dest: '<%= dest %>/bin', flatten: true} + views: { + files: [ + {expand: true, cwd: 'app/views/', src: ['archetype.html', 'archetype.config.html'], dest: '<%= dest %>/views', flatten: true} ] }, - deploy: { + config: { files: [ - {expand: true, cwd: '<%= dest %>/', src: ['**/*', "!bin", "!bin/**/*"], dest: '<%= grunt.option("target") %>\\App_Plugins\\Archetype', flatten: false}, - {expand: true, cwd: '<%= dest %>/', src: ['bin/**/*'], dest: '<%= grunt.option("target") %>', flatten: false}, + {expand: true, cwd: 'app/', src: ['package.manifest'], dest: '<%= dest %>', flatten: true}, + {expand: true, cwd: 'app/config/', src: ['propertyEditors.views.js'], dest: '<%= dest %>/config', flatten: true}, + {expand: true, cwd: 'app/langs/', src: ['**'], dest: '<%= dest %>/langs', flatten: true} ] }, - nuget_prepare: { + nuget: { files: [ - {expand: true, cwd: '<%= dest %>/', src: ['**/*', '!bin', '!bin/*'], dest: '<%= package_temp_dir %>/nuget/content/App_Plugins/Archetype', flatten: false}, - {expand: true, cwd: '<%= dest %>/', src: ['bin/**/*.dll'], dest: '<%= package_temp_dir %>/nuget/lib/net40/', flatten: true} + {expand: true, cwd: '<%= dest %>', src: ['**/*', '!bin', '!bin/*'], dest: '<%= package_temp_dir %>/nuget/content', flatten: false}, + {expand: true, cwd: '<%= dest %>/bin', src: ['*.dll'], dest: '<%= package_temp_dir %>/nuget/lib/net40', flatten: true} ] }, - umbracopackage: { + umbraco: { files: [ - {expand: true, cwd: '<%= dest %>/', src: ['**/*', '!bin', "!bin/*"], dest: 'pkg/tmp/umbraco/App_Plugins/Archetype', flatten: false}, - {expand: true, cwd: '<%= dest %>/', src: ['bin/**/*.dll'], dest: 'pkg/tmp/umbraco', flatten: false} + {expand: true, cwd: '<%= dest %>', src: ['**/*'], dest: 'pkg/tmp/umbraco', flatten: false} ] } }, - touch: { - options: {}, - webconfig: { - src: ['<%= grunt.option("target") %>\\Web.config'] - } - }, - umbracoPackage: { options: { name: "<%= pkgMeta.name %>", @@ -174,7 +172,7 @@ module.exports = function(grunt) { }, msbuild: { - dev: { + dist: { src: ["<%= csProj %>"], options: { projectConfiguration: 'Debug', @@ -184,6 +182,7 @@ module.exports = function(grunt) { buildParameters: { WarningLevel: 2, NoWarn: 1607, + OutputPath: path.resolve("<%= dest %>") + "/../../bin" }, verbosity: 'quiet' } @@ -192,29 +191,9 @@ module.exports = function(grunt) { }); - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-contrib-less'); - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-contrib-concat'); - grunt.loadNpmTasks('grunt-contrib-copy'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-nuget'); - grunt.loadNpmTasks('grunt-template'); - grunt.loadNpmTasks('grunt-touch'); - grunt.loadNpmTasks('grunt-msbuild'); - grunt.loadNpmTasks('grunt-dotnet-assembly-info'); - grunt.loadTasks('tasks'); - - - grunt.registerTask('package', ['clean:package_artifacts', 'default', 'package:nuget', 'package:umbraco']); - grunt.registerTask('package:nuget', ['copy:nuget_prepare', 'template:nuget_manifest', 'nugetpack', 'clean:package_temp']); - grunt.registerTask('package:umbraco', ['copy:umbracopackage', 'umbracoPackage', 'clean:package_temp']); - grunt.registerTask('touchwebconfigifenabled', function() { if (grunt.option("touch")) grunt.task.run("touch:webconfig") }); - grunt.registerTask('deploy', ['default', 'copy:deploy', 'touchwebconfigifenabled']); - grunt.registerTask('css:build', ['less']); - grunt.registerTask('js:build', ['concat']); - grunt.registerTask('cs:build', ['assemblyinfo', 'msbuild:dev']); - grunt.registerTask('default', ['clean', 'css:build', 'js:build', 'copy:build', 'cs:build']); + grunt.registerTask('default', ['clean', 'less', 'concat', 'cs:build', 'copy:config', 'copy:views']); + grunt.registerTask('cs:build', ['assemblyinfo', 'msbuild:dist']); + grunt.registerTask('nuget', ['copy:nuget', 'template:nuspec', 'nugetpack', 'clean:package_temp']); + grunt.registerTask('umbraco', ['copy:umbraco', 'umbracoPackage', 'clean:package_temp']); }; diff --git a/README.md b/README.md index 9aa5bc3..9b7bf2a 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,10 @@ Want to contribute to Archetype? You'll want to use Grunt (our task runner) to npm install ### Build ### - grunt + grunt # Compiles to `/dist/` + grunt --target="D:\path\to\umbraco\site" + grunt watch + grunt watch --target="D:\path\to\umbraco\site" -### Deploy ### - grunt deploy --target=C:\\path\\to\\umbraco\\site - grunt watch:dev --target=C:\\path\to\\umbraco\\site - -Add `--touch` to either command to automatically touch the web.config on a deploy - +Add `--touch` to either command to automatically touch the web.config on a deploy \ No newline at end of file diff --git a/package.json b/package.json index 8f01d88..a14b280 100644 --- a/package.json +++ b/package.json @@ -26,5 +26,8 @@ "repository": { "type": "git", "url": "https://github.com/imulus/Archetype.git" + }, + "dependencies": { + "load-grunt-tasks": "~0.4.0" } } From 0830290bf1b94d4b8bf5cad9e847347f6ae2ff13 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Tue, 18 Mar 2014 13:03:46 +0000 Subject: [PATCH 09/17] Adds the "Enable Collapsing?" property to the `ArchetypePreValue` model. Closes #87 --- app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs b/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs index 69ce09d..1a7e4a2 100644 --- a/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs +++ b/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs @@ -14,6 +14,9 @@ namespace Archetype.Umbraco.Models [JsonProperty("enableMultipleFieldsets")] public bool EnableMultipleFieldsets { get; set; } + [JsonProperty("enableCollapsing")] + public bool EnableCollapsing { get; set; } + [JsonProperty("hideFieldsetControls")] public bool HideFieldsetControls { get; set; } From 73e8712ad82e53c86879e61e8294a43f834a2ab3 Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Mon, 17 Mar 2014 19:05:46 -0600 Subject: [PATCH 10/17] Cleanup / update Gruntfile * Use proper grunt-umbraco-package task * Use new structure for --target, eliminate deploy step by making `dist` configurable * Move package files to /config/ * Cleanup watch/copy tasks, add atBegin: true * Prevent "cleaning" non-local destinations (dangerous?) * Cleanup full/base path config * Whitespace, misc --- .gitignore | 2 +- Gruntfile.js | 337 +++++++++++++++------------ {pkg => config}/meta.json | 0 {app => config}/package.manifest | 0 {pkg/nuget => config}/package.nuspec | 0 {pkg/umbraco => config}/package.xml | 0 {pkg/umbraco => config}/readme.txt | 0 package.json | 10 +- tasks/umbraco_package.js | 76 ------ 9 files changed, 189 insertions(+), 236 deletions(-) rename {pkg => config}/meta.json (100%) rename {app => config}/package.manifest (100%) rename {pkg/nuget => config}/package.nuspec (100%) rename {pkg/umbraco => config}/package.xml (100%) rename {pkg/umbraco => config}/readme.txt (100%) delete mode 100644 tasks/umbraco_package.js diff --git a/.gitignore b/.gitignore index 3598fad..1bb174e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,7 @@ $RECYCLE.BIN/ app/less/*.css dist/ node_modules/ -pkg/tmp/ +tmp/ pkg/*.nupkg pkg/*.zip diff --git a/Gruntfile.js b/Gruntfile.js index 3c6223a..a26446f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -4,36 +4,186 @@ module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), - pkgMeta: grunt.file.readJSON('pkg/meta.json'), - dest: (grunt.option('target') || 'dist') + '/App_Plugins/Archetype', - package_dir: 'pkg', - package_temp_dir: '<%= package_dir %>/tmp/', - csProj: 'app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj', - + pkgMeta: grunt.file.readJSON('config/meta.json'), + dest: grunt.option('target') || 'dist', + basePath: path.join('<%= dest %>', 'App_Plugins', '<%= pkgMeta.name %>'), watch: { options: { - spawn: false + spawn: false, + atBegin: true }, less: { - files: ['app/less/*.less', 'lib/**/*.less'], - tasks: ['less:dist'], + files: ['app/**/*.less'], + tasks: ['less:dist'] }, js: { - files: ['app/**/*.js', 'lib/**/*.js'], - tasks: ['concat', 'jshint'], + files: ['app/**/*.js'], + tasks: ['concat:dist'] }, - views: { - files: ['/app/views/**/*'], - tasks: ['copy:views'] + html: { + files: ['app/**/*.html'], + tasks: ['copy:html'] + }, + + config: { + files: ['config/package.manifest'], + tasks: ['copy:config'] }, dll: { files: ['app/Umbraco/**/*.dll'], - tasks: ['copy:dll'], + tasks: ['copy:dll'] + } + }, + + less: { + dist: { + options: { + paths: ["app/less", "lib/less", "vendor"], + }, + files: { + '<%= basePath %>/css/archetype.css': 'app/less/archetype.less', + } + } + }, + + concat: { + options: { + stripBanners: false + }, + dist: { + src: [ + 'app/controllers/controller.js', + 'app/controllers/config.controller.js', + 'app/directives/archetypeproperty.js', + 'app/directives/localize.js', + 'app/services/localization.js', + 'app/resources/propertyeditor.js' + ], + dest: '<%= basePath %>/js/archetype.js' + } + }, + + copy: { + html: { + cwd: 'app/views/', + src: ['archetype.html', 'archetype.config.html'], + dest: '<%= basePath %>/views', + expand: true + }, + dll: { + cwd: 'app/Umbraco/Umbraco.Archetype/bin/Debug/', + src: '*.*', + dest: '<%= dest %>/bin/', + expand: true + }, + config: { + files: [ + { + cwd: 'config/', + src: ['package.manifest'], + dest: '<%= basePath %>', + expand: true + }, + { + cwd: 'app/config/', + src: ['propertyEditors.views.js'], + dest: '<%= basePath %>/js', + expand: true + }, + { + cwd: 'app/langs/', + src: ['**'], + dest: '<%= basePath %>/langs', + expand: true + } + ] + }, + nuget: { + files: [ + { + cwd: '<%= dest %>', + src: ['**/*', '!bin', '!bin/*'], + dest: 'tmp/nuget/content', + expand: true + }, + { + cwd: '<%= dest %>/bin', + src: ['*.dll'], + dest: 'tmp/nuget/lib/net40', + expand: true + } + ] + }, + umbraco: { + cwd: '<%= dest %>', + src: '**/*', + dest: 'tmp/umbraco', + expand: true + } + }, + + nugetpack: { + dist: { + src: 'tmp/nuget/package.nuspec', + dest: 'pkg' + } + }, + + template: { + 'nuspec': { + 'options': { + 'data': { + name: '<%= pkgMeta.name %>', + version: '<%= pkgMeta.version %>', + url: '<%= pkgMeta.url %>', + license: '<%= pkgMeta.license %>', + licenseUrl: '<%= pkgMeta.licenseUrl %>', + author: '<%= pkgMeta.author %>', + authorUrl: '<%= pkgMeta.authorUrl %>', + + files: [{ path: 'tmp/nuget/**', target: 'content/App_Plugins/Archetype'}] + } + }, + 'files': { + 'tmp/nuget/package.nuspec': ['config/package.nuspec'] + } + } + }, + + umbracoPackage: { + options: { + name: "<%= pkgMeta.name %>", + version: '<%= pkgMeta.version %>', + url: '<%= pkgMeta.url %>', + license: '<%= pkgMeta.license %>', + licenseUrl: '<%= pkgMeta.licenseUrl %>', + author: '<%= pkgMeta.author %>', + authorUrl: '<%= pkgMeta.authorUrl %>', + manifest: 'config/package.xml', + readme: 'config/readme.txt', + sourceDir: 'tmp/umbraco', + outputDir: 'pkg', + } + }, + + clean: { + build: '<%= grunt.config("basePath").substring(0, 4) == "dist" ? "dist/**/*" : "null" %>', + tmp: ['pkg/tmp'] + }, + + assemblyinfo: { + options: { + files: ['app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj'], + filename: 'VersionInfo.cs', + info: { + version: '<%= (pkgMeta.version.indexOf("-") ? pkgMeta.version.substring(0, pkgMeta.version.indexOf("-")) : pkgMeta.version) %>', + fileVersion: '<%= pkgMeta.version %>' + } } }, @@ -52,148 +202,29 @@ module.exports = function(grunt) { } }, - less: { - dist: { - options: { - paths: ["app/less", "lib/less", "vendor"], - }, - files: { - '<%= dest %>/css/archetype.css': 'app/less/archetype.less', - } - } - }, - - concat: { - options: { - stripBanners: false - }, - dist: { - src: [ - 'app/controllers/controller.js', - 'app/controllers/config.controller.js', - 'app/directives/archetypeproperty.js', - 'app/directives/localize.js', - 'app/services/localization.js', - 'app/resources/propertyeditor.js' - ], - dest: '<%= dest %>/js/archetype.js' - } - }, - - nugetpack: { - dist: { - src: '<%= package_temp_dir %>/nuget/package.nuspec', - dest: '<%= package_dir %>' - } - }, - - template: { - 'nuspec': { - 'options': { - 'data': { - name: '<%= pkgMeta.name %>', - version: '<%= pkgMeta.version %>', - url: '<%= pkgMeta.url %>', - license: '<%= pkgMeta.license %>', - licenseUrl: '<%= pkgMeta.licenseUrl %>', - author: '<%= pkgMeta.author %>', - authorUrl: '<%= pkgMeta.authorUrl %>', - - files: [{ path: '..\\..\\..\\<%= package_temp_dir %>\\nuget\\**', target: 'content\\App_Plugins\\Archetype'}] - } - }, - 'files': { - '<%= package_temp_dir %>/nuget/package.nuspec': ['<%= package_dir %>/nuget/package.nuspec'] - } - } - }, - - clean: { - build: ['<%= dest %>'] - }, - - copy: { - views: { - files: [ - {expand: true, cwd: 'app/views/', src: ['archetype.html', 'archetype.config.html'], dest: '<%= dest %>/views', flatten: true} - ] - }, - config: { - files: [ - {expand: true, cwd: 'app/', src: ['package.manifest'], dest: '<%= dest %>', flatten: true}, - {expand: true, cwd: 'app/config/', src: ['propertyEditors.views.js'], dest: '<%= dest %>/config', flatten: true}, - {expand: true, cwd: 'app/langs/', src: ['**'], dest: '<%= dest %>/langs', flatten: true} - ] - }, - nuget: { - files: [ - {expand: true, cwd: '<%= dest %>', src: ['**/*', '!bin', '!bin/*'], dest: '<%= package_temp_dir %>/nuget/content', flatten: false}, - {expand: true, cwd: '<%= dest %>/bin', src: ['*.dll'], dest: '<%= package_temp_dir %>/nuget/lib/net40', flatten: true} - ] - }, - umbraco: { - files: [ - {expand: true, cwd: '<%= dest %>', src: ['**/*'], dest: 'pkg/tmp/umbraco', flatten: false} - ] - } - }, - - umbracoPackage: { - options: { - name: "<%= pkgMeta.name %>", - version: '<%= pkgMeta.version %>', - url: '<%= pkgMeta.url %>', - license: '<%= pkgMeta.license %>', - licenseUrl: '<%= pkgMeta.licenseUrl %>', - author: '<%= pkgMeta.author %>', - authorUrl: '<%= pkgMeta.authorUrl %>', - manifest: 'pkg/umbraco/package.xml', - readme: 'pkg/umbraco/readme.txt', - sourceDir: 'pkg/tmp/umbraco', - outputDir: 'pkg', - } - }, - - clean: { - build: ['<%= dest %>'], - package_temp: ['pkg/tmp'], - package_artifacts: ['pkg/*.zip', 'pkg/*.nupkg'], - }, - - assemblyinfo: { - options: { - files: ['<%= csProj %>'], - filename: 'VersionInfo.cs', - info: { - version: '<%= (pkgMeta.version.indexOf("-") ? pkgMeta.version.substring(0, pkgMeta.version.indexOf("-")) : pkgMeta.version) %>', - fileVersion: '<%= pkgMeta.version %>' - } - } - }, - msbuild: { - dist: { - src: ["<%= csProj %>"], - options: { - projectConfiguration: 'Debug', - targets: ['Clean', 'Rebuild'], - stdout: true, - maxCpuCount: 4, - buildParameters: { - WarningLevel: 2, - NoWarn: 1607, - OutputPath: path.resolve("<%= dest %>") + "/../../bin" - }, - verbosity: 'quiet' - } + options: { + stdout: true, + verbosity: 'quiet', + maxCpuCount: 4, + buildParameters: { + WarningLevel: 2, + NoWarn: 1607 } + }, + dist: { + src: ['app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj'], + options: { + projectConfiguration: 'Release', + targets: ['Clean', 'Rebuild'], + } + } } }); - grunt.registerTask('default', ['clean', 'less', 'concat', 'cs:build', 'copy:config', 'copy:views']); - grunt.registerTask('cs:build', ['assemblyinfo', 'msbuild:dist']); - grunt.registerTask('nuget', ['copy:nuget', 'template:nuspec', 'nugetpack', 'clean:package_temp']); - grunt.registerTask('umbraco', ['copy:umbraco', 'umbracoPackage', 'clean:package_temp']); -}; + grunt.registerTask('default', ['clean', 'less', 'concat', 'assemblyinfo', 'msbuild:dist', 'copy:dll', 'copy:config', 'copy:html']); + grunt.registerTask('nuget', ['clean:tmp', 'default', 'copy:nuget', 'template:nuspec', 'nugetpack', 'clean:tmp']); + grunt.registerTask('umbraco', ['clean:tmp', 'default', 'copy:umbraco', 'umbracoPackage', 'clean:tmp']); +}; \ No newline at end of file diff --git a/pkg/meta.json b/config/meta.json similarity index 100% rename from pkg/meta.json rename to config/meta.json diff --git a/app/package.manifest b/config/package.manifest similarity index 100% rename from app/package.manifest rename to config/package.manifest diff --git a/pkg/nuget/package.nuspec b/config/package.nuspec similarity index 100% rename from pkg/nuget/package.nuspec rename to config/package.nuspec diff --git a/pkg/umbraco/package.xml b/config/package.xml similarity index 100% rename from pkg/umbraco/package.xml rename to config/package.xml diff --git a/pkg/umbraco/readme.txt b/config/readme.txt similarity index 100% rename from pkg/umbraco/readme.txt rename to config/readme.txt diff --git a/package.json b/package.json index a14b280..336ec4a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "archetype", "version": "0.0.0", - "devDependencies": { + "dependencies": { "grunt": "~0.4.2", "bower": "~1.2.8", "grunt-contrib-copy": "~0.5.0", @@ -18,16 +18,14 @@ "rimraf": "~2.2.5", "grunt-nuget": "~0.1.1", "grunt-template": "~0.2.2", - "grunt-touch": "~0.1.0", "fs-extra": "~0.8.1", "grunt-msbuild": "~0.1.9", - "grunt-dotnet-assembly-info": "~1.0.9" + "grunt-dotnet-assembly-info": "~1.0.9", + "load-grunt-tasks": "~0.4.0", + "grunt-umbraco-package": "0.0.5" }, "repository": { "type": "git", "url": "https://github.com/imulus/Archetype.git" - }, - "dependencies": { - "load-grunt-tasks": "~0.4.0" } } diff --git a/tasks/umbraco_package.js b/tasks/umbraco_package.js deleted file mode 100644 index e16d16d..0000000 --- a/tasks/umbraco_package.js +++ /dev/null @@ -1,76 +0,0 @@ -module.exports = function(grunt) { - grunt.registerTask('umbracoPackage', 'Create Umbraco Package', function() { - grunt.config.requires('umbracoPackage.options.name'); - grunt.config.requires('umbracoPackage.options.version'); - grunt.config.requires('umbracoPackage.options.license'); - grunt.config.requires('umbracoPackage.options.licenseUrl'); - grunt.config.requires('umbracoPackage.options.url'); - grunt.config.requires('umbracoPackage.options.author'); - grunt.config.requires('umbracoPackage.options.authorUrl'); - grunt.config.requires('umbracoPackage.options.manifest'); - grunt.config.requires('umbracoPackage.options.readme'); - grunt.config.requires('umbracoPackage.options.outputDir'); - grunt.config.requires('umbracoPackage.options.sourceDir'); - - var Guid = require('guid'); - var path = require('path'); - var rimraf = require('rimraf'); - var AdmZip = require('adm-zip'); - var fs = require('fs-extra'); - - var options = this.options({ - minimumUmbracoVersion: '', - files: [], - cwd: '/' - }); - - var packageFileName = options.name + "_" + options.version + ".zip" - - // Gather files - var filesToPackage = []; - getFilesRecursive(options.sourceDir); - filesToPackage = filesToPackage.map(function(f) { - return { guid: Guid.create(), dir: f.dir.replace(options.sourceDir, ''), name: f.name, ext: f.name.split('.').pop() }; - }); - - // Create temp folder for package zip source - var guidFolder = Guid.create().toString(); - var newDirName = path.join(options.sourceDir, "..\\" + guidFolder); - fs.mkdirSync(newDirName); - newDirName = path.join(newDirName, guidFolder); - fs.mkdirSync(newDirName); - - // Copy flatten structure, with files renamed as . - filesToPackage.forEach(function(f) { - var newFileName = f.name == "package.xml" ? f.name : f.guid.toString() + '.' + f.ext; - fs.copySync(path.join(options.sourceDir, f.dir, f.name), path.join(newDirName, newFileName)); - }); - - // Load / transform XML Manifest - options.files = filesToPackage; - options.readmeContents = grunt.file.read(options.readme); - var manifest = grunt.file.read(options.manifest); - manifest = grunt.template.process(manifest, {data: options}); - grunt.file.write(path.join(options.sourceDir, "..\\", guidFolder, guidFolder, "package.xml"), manifest); // TODO: Probably shouldn't use sourceDir - what if under source control - - // Zip - var zip = new AdmZip(); - zip.addLocalFolder(path.join(options.sourceDir, "..\\", guidFolder)); - zip.writeZip(path.join(options.outputDir, packageFileName)) - - function getFilesRecursive(dir) { - var files = fs.readdirSync(dir); - for (var i in files) { - if (!files.hasOwnProperty(i)) continue; - - var name = dir+'/'+files[i]; - if (fs.statSync(name).isDirectory()) { - getFilesRecursive(name); - } else { - filesToPackage.push({ dir: dir, name: files[i]}); - } - } - } - - }); -}; \ No newline at end of file From e87e84eb5b009f25f0a14cb201e2836a346add58 Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Tue, 18 Mar 2014 22:59:06 -0600 Subject: [PATCH 11/17] Explain build details in README --- README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9b7bf2a..5565d10 100644 --- a/README.md +++ b/README.md @@ -20,10 +20,16 @@ Want to contribute to Archetype? You'll want to use Grunt (our task runner) to npm install ### Build ### - grunt # Compiles to `/dist/` - grunt --target="D:\path\to\umbraco\site" + grunt + + Builds the project to `/dist/`. These files can be dropped into an Umbraco 7 site, or you can build directly to a site using: + + grunt --target="D:\inetpub\mysite" + +You can also watch for changes using: grunt watch - grunt watch --target="D:\path\to\umbraco\site" + grunt watch --target="D:\inetpub\mysite" + Add `--touch` to either command to automatically touch the web.config on a deploy \ No newline at end of file From 3521543f17e3fbc4caba366a51a019f9cb6153e1 Mon Sep 17 00:00:00 2001 From: Andrey Shchekin Date: Fri, 28 Mar 2014 18:11:40 +1300 Subject: [PATCH 12/17] Changed data types storage to store guids instead of ids. --- .../Api/ArchetypeDataTypeController.cs | 14 ++++-- .../Models/ArchetypePreValueProperty.cs | 10 ++-- .../ArchetypeValueConverter.cs | 47 +++++++++++-------- app/controllers/config.controller.js | 8 ++-- app/directives/archetypeproperty.js | 4 +- app/resources/propertyeditor.js | 12 ++--- app/views/archetype.config.html | 4 +- 7 files changed, 54 insertions(+), 45 deletions(-) diff --git a/app/Umbraco/Umbraco.Archetype/Api/ArchetypeDataTypeController.cs b/app/Umbraco/Umbraco.Archetype/Api/ArchetypeDataTypeController.cs index 6bdb7ce..ef6cf0e 100644 --- a/app/Umbraco/Umbraco.Archetype/Api/ArchetypeDataTypeController.cs +++ b/app/Umbraco/Umbraco.Archetype/Api/ArchetypeDataTypeController.cs @@ -1,4 +1,6 @@ -using System.Net; +using System; +using System.Linq; +using System.Net; using System.Web.Http; using AutoMapper; using Umbraco.Core.Models; @@ -11,9 +13,15 @@ namespace Archetype.Umbraco.Api [PluginController("ArchetypeApi")] public class ArchetypeDataTypeController : UmbracoAuthorizedJsonController { - public object GetById(int id) + public object GetAll() { - var dataType = Services.DataTypeService.GetDataTypeDefinitionById(id); + var dataTypes = Services.DataTypeService.GetAllDataTypeDefinitions(); + return dataTypes.Select(t => new { guid = t.Key, name = t.Name }); + } + + public object GetByGuid(Guid guid) + { + var dataType = Services.DataTypeService.GetDataTypeDefinitionById(guid); if (dataType == null) { throw new HttpResponseException(HttpStatusCode.NotFound); diff --git a/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValueProperty.cs b/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValueProperty.cs index c8c13e4..e2cc12b 100644 --- a/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValueProperty.cs +++ b/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValueProperty.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json; +using System; +using Newtonsoft.Json; namespace Archetype.Umbraco.Models { @@ -18,12 +19,9 @@ namespace Archetype.Umbraco.Models [JsonProperty("helpText")] public string HelpText { get; set; } - - [JsonProperty("dataTypeId")] - public int DataTypeId { get; set; } - + [JsonProperty("dataTypeGuid")] - public string DataTypeGuid { get; set; } + public Guid DataTypeGuid { get; set; } [JsonProperty("propertyEditorAlias")] public string PropertyEditorAlias { get; set; } diff --git a/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs b/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs index a8bfc8b..95a0411 100644 --- a/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs +++ b/app/Umbraco/Umbraco.Archetype/PropertyConverters/ArchetypeValueConverter.cs @@ -1,13 +1,15 @@ -using System; +using System; +using System.Collections.Generic; using System.Linq; using Archetype.Umbraco.Extensions; using Archetype.Umbraco.Models; using Newtonsoft.Json; -using Umbraco.Core; +using Umbraco.Core; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; -using Umbraco.Core.Services; - +using Umbraco.Core.Services; + namespace Archetype.Umbraco.PropertyConverters { /* based on the Tim Geyssens sample at: https://github.com/TimGeyssens/MatrixPropEditor/blob/master/SamplePropertyValueConverter/SamplePropertyValueConverter/MatrixValueConverter.cs */ @@ -54,8 +56,9 @@ namespace Archetype.Umbraco.PropertyConverters try { // Get list of configured properties and their types - // and map them to the deserialized archetype model - var preValue = GetArchetypePreValueFromDataTypeId(propertyType.DataTypeId); + // and map them to the deserialized archetype model + var dataTypeCache = new Dictionary(); + var preValue = GetArchetypePreValueFromDataTypeId(propertyType.DataTypeId, dataTypeCache); foreach (var fieldset in preValue.Fieldsets) { var fieldsetAlias = fieldset.Alias; @@ -64,9 +67,9 @@ namespace Archetype.Umbraco.PropertyConverters foreach (var property in fieldset.Properties) { var propertyAlias = property.Alias; - foreach (var propertyInst in fieldsetInst.Properties.Where(x => x.Alias == propertyAlias)) - { - propertyInst.DataTypeId = property.DataTypeId; + foreach (var propertyInst in fieldsetInst.Properties.Where(x => x.Alias == propertyAlias)) + { + propertyInst.DataTypeId = GetDataTypeByGuid(property.DataTypeGuid, dataTypeCache).Id; propertyInst.PropertyEditorAlias = property.PropertyEditorAlias; } } @@ -86,9 +89,9 @@ namespace Archetype.Umbraco.PropertyConverters } return defaultValue; - } - - internal ArchetypePreValue GetArchetypePreValueFromDataTypeId(int dataTypeId) + } + + private ArchetypePreValue GetArchetypePreValueFromDataTypeId(int dataTypeId, IDictionary dataTypeCache) { var preValues = Services.DataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeId); @@ -102,18 +105,22 @@ namespace Archetype.Umbraco.PropertyConverters { foreach (var property in fieldset.Properties) { - // Lookup the properties property editor alias - // (See if we've already looked it up first though to save a database hit) - var propertyWithSameDataType = config.Fieldsets.SelectMany(x => x.Properties) - .FirstOrDefault(x => x.DataTypeId == property.DataTypeId && !string.IsNullOrWhiteSpace(x.PropertyEditorAlias)); - - property.PropertyEditorAlias = propertyWithSameDataType != null - ? propertyWithSameDataType.PropertyEditorAlias - : Services.DataTypeService.GetDataTypeDefinitionById(property.DataTypeId).PropertyEditorAlias; + property.PropertyEditorAlias = GetDataTypeByGuid(property.DataTypeGuid, dataTypeCache).PropertyEditorAlias; } } return config; + } + + private IDataTypeDefinition GetDataTypeByGuid(Guid guid, IDictionary cache) + { + IDataTypeDefinition dataType; + if (cache.TryGetValue(guid, out dataType)) + return dataType; + + dataType = Services.DataTypeService.GetDataTypeDefinitionById(guid); + cache[guid] = dataType; + return dataType; } } } diff --git a/app/controllers/config.controller.js b/app/controllers/config.controller.js index 0a3828f..dd955e3 100644 --- a/app/controllers/config.controller.js +++ b/app/controllers/config.controller.js @@ -4,7 +4,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio //console.log($scope.model.value); //define empty items - var newPropertyModel = '{"alias": "", "remove": false, "collapse": false, "label": "", "helpText": "", "dataTypeId": "-88", "value": ""}'; + 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 + ']}'; var defaultFieldsetConfigModel = JSON.parse('{"showAdvancedOptions": false, "hideFieldsetToolbar": false, "enableMultipleFieldsets": false, "hideFieldsetControls": false, "hidePropertyLabel": false, "maxFieldsets": null, "enableCollapsing": true, "fieldsets": [' + newFieldsetModel + ']}'); @@ -166,12 +166,12 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio return countVisibleProperty(fieldset) > 1; } - $scope.getDataTypeNameById = function (id) { + $scope.getDataTypeNameByGuid = function (guid) { if ($scope.availableDataTypes == null) // Might not be initialized yet? return ""; - + var dataType = _.find($scope.availableDataTypes, function(d) { - return d.id == id; + return d.guid == guid; }); return dataType == null ? "" : dataType.name; diff --git a/app/directives/archetypeproperty.js b/app/directives/archetypeproperty.js index 5286fca..b867e74 100644 --- a/app/directives/archetypeproperty.js +++ b/app/directives/archetypeproperty.js @@ -51,7 +51,7 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c var configFieldsetModel = getFieldsetByAlias(scope.archetypeConfig.fieldsets, scope.fieldset.alias); var view = ""; var label = configFieldsetModel.properties[scope.propertyConfigIndex].label; - var dataTypeId = configFieldsetModel.properties[scope.propertyConfigIndex].dataTypeId; + var dataTypeGuid = configFieldsetModel.properties[scope.propertyConfigIndex].dataTypeGuid; var config = null; var alias = configFieldsetModel.properties[scope.propertyConfigIndex].alias; var defaultValue = configFieldsetModel.properties[scope.propertyConfigIndex].value; @@ -61,7 +61,7 @@ angular.module("umbraco.directives").directive('archetypeProperty', function ($c defaultValue = jsonOrString(defaultValue, scope.archetypeConfig.developerMode, "defaultValue"); //grab info for the selected datatype, prepare for view - archetypePropertyEditorResource.getDataType(dataTypeId).then(function (data) { + archetypePropertyEditorResource.getDataType(dataTypeGuid).then(function (data) { //transform preValues array into object expected by propertyeditor views var configObj = {}; _.each(data.preValues, function(p) { diff --git a/app/resources/propertyeditor.js b/app/resources/propertyeditor.js index 0a1cc9b..954a6f8 100644 --- a/app/resources/propertyeditor.js +++ b/app/resources/propertyeditor.js @@ -3,16 +3,12 @@ angular.module('umbraco.resources').factory('archetypePropertyEditorResource', f getAllDataTypes: function() { // Hack - grab DataTypes from Tree API, as `dataTypeService.getAll()` isn't implemented yet return umbRequestHelper.resourcePromise( - $http.get("/umbraco/backoffice/UmbracoTrees/DataTypeTree/GetNodes?id=-1&application=developer&tree=&isDialog=false"), 'Failed to retrieve datatypes from tree service' - ).then(function (data) { - return data.map(function(d) { - return { "id": d.id, "name": d.name } - }); - }); + $http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetAll"), 'Failed to retrieve datatypes from tree service' + ); }, - getDataType: function(id) { + getDataType: function(guid) { return umbRequestHelper.resourcePromise( - $http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetById?id=" + id), 'Failed to retrieve datatype' + $http.get("/umbraco/backoffice/ArchetypeApi/ArchetypeDataType/GetByGuid?guid=" + guid), 'Failed to retrieve datatype' ); }, getPropertyEditorMapping: function(alias) { diff --git a/app/views/archetype.config.html b/app/views/archetype.config.html index c80bf10..d021e7e 100644 --- a/app/views/archetype.config.html +++ b/app/views/archetype.config.html @@ -37,7 +37,7 @@
- {{property.label}} ({{property.alias}}) - {{getDataTypeNameById(property.dataTypeId)}} + {{property.label}} ({{property.alias}}) - {{getDataTypeNameByGuid(property.dataTypeGuid)}}
@@ -54,7 +54,7 @@
- +
From ddd01b4745b1ed369bd35244280c58de655eb161 Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Sat, 29 Mar 2014 18:10:01 -0600 Subject: [PATCH 13/17] Update test to match new converter behavior (null -> empty Archetype) --- .../PropertyValueConverterTests.cs | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/app/Umbraco/Archetype.Tests/PropertyValueConverter/PropertyValueConverterTests.cs b/app/Umbraco/Archetype.Tests/PropertyValueConverter/PropertyValueConverterTests.cs index 710be06..6329a4d 100644 --- a/app/Umbraco/Archetype.Tests/PropertyValueConverter/PropertyValueConverterTests.cs +++ b/app/Umbraco/Archetype.Tests/PropertyValueConverter/PropertyValueConverterTests.cs @@ -24,32 +24,30 @@ namespace Archetype.Tests.PropertyValueConverter } [Test] - public void Returns_Null_When_Data_Is_Null() + [TestCase(null)] + [TestCase("")] + public void Returns_Empty_Archetype_When_Data_Is_Null_Or_Empty(object data) { - var converter = new ArchetypeValueConverter(); - var result = converter.ConvertDataToSource(null, null, false); - - Assert.IsNull(result); - } - - [Test] - public void Returns_Empty_String_When_Data_Is_Empty_String() - { - var data = ""; var converter = new ArchetypeValueConverter(); var result = converter.ConvertDataToSource(null, data, false); - Assert.AreEqual("", result); + Assert.AreEqual(result.GetType(), typeof (Archetype.Umbraco.Models.Archetype)); + + var fieldsets = (Archetype.Umbraco.Models.Archetype) result; + Assert.IsTrue(fieldsets.Count() == 0); } [Test] - public void Returns_Original_String_When_Data_Is_Invalid_Json() + public void Returns_Empty_Archetype_When_Data_Is_Invalid_Json() { var data = "{ invalid"; var converter = new ArchetypeValueConverter(); var result = converter.ConvertDataToSource(null, data, false); - Assert.AreEqual(data, result); + Assert.AreEqual(result.GetType(), typeof (Archetype.Umbraco.Models.Archetype)); + + var fieldsets = (Archetype.Umbraco.Models.Archetype) result; + Assert.IsTrue(fieldsets.Count() == 0); } [Test] From 4a319b9ed4a2dba36353416f87c8a2a8c15399fc Mon Sep 17 00:00:00 2001 From: Tom Fulton Date: Sat, 29 Mar 2014 23:49:23 -0600 Subject: [PATCH 14/17] Extract & Wrap PropertyValueConverter method to fix tests Unable to access PropertyValueConverterResolver.Current from a test, so wrapping in a quick check for UmbracoContext. Probably not the best fix, but wasn't sure best way or if overkill to create an abstraction. Also extracted the logic that finds/executes PropertyValueConverters to make testing easier. --- .../Archetype.Tests/Archetype.Tests.csproj | 146 +++++++++++++++++- app/Umbraco/Archetype.Tests/packages.config | 21 +++ .../Archetype.Umbraco.csproj | 1 + .../Umbraco.Archetype/Models/Property.cs | 43 ++++-- 4 files changed, 193 insertions(+), 18 deletions(-) diff --git a/app/Umbraco/Archetype.Tests/Archetype.Tests.csproj b/app/Umbraco/Archetype.Tests/Archetype.Tests.csproj index df29425..a4f49a2 100644 --- a/app/Umbraco/Archetype.Tests/Archetype.Tests.csproj +++ b/app/Umbraco/Archetype.Tests/Archetype.Tests.csproj @@ -31,22 +31,166 @@ 4 + + ..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.dll + + + ..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.Net4.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\businesslogic.dll + + + ..\packages\ClientDependency.1.7.1.2\lib\ClientDependency.Core.dll + + + ..\packages\ClientDependency-Mvc.1.7.0.4\lib\ClientDependency.Core.Mvc.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\cms.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\controls.dll + + + ..\packages\xmlrpcnet.2.5.0\lib\net20\CookComputing.XmlRpcV2.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\Examine.dll + + + ..\packages\HtmlAgilityPack.1.4.6\lib\Net45\HtmlAgilityPack.dll + + + ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll + + + False + ..\packages\UmbracoCms.Core.7.0.1\lib\interfaces.dll + + + False + ..\packages\UmbracoCms.Core.7.0.1\lib\log4net.dll + + + ..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\Microsoft.ApplicationBlocks.Data.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\Microsoft.Web.Helpers.dll + + + True + ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + ..\packages\Microsoft.AspNet.Mvc.FixedDisplayModes.1.0.1\lib\net40\Microsoft.Web.Mvc.FixedDisplayModes.dll + + + ..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll + ..\packages\Moq.4.2.1312.1622\lib\net40\Moq.dll + + ..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll + + + ..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll + ..\packages\NUnit.2.6.3\lib\nunit.framework.dll + + ..\packages\UmbracoCms.Core.7.0.1\lib\SQLCE4Umbraco.dll + + + True + ..\packages\UmbracoCms.Core.7.0.1\lib\System.Data.SqlServerCe.dll + + + True + ..\packages\UmbracoCms.Core.7.0.1\lib\System.Data.SqlServerCe.Entity.dll + + + + ..\packages\Microsoft.AspNet.WebApi.Client.4.0.30506.0\lib\net40\System.Net.Http.Formatting.dll + + + + True + ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll + + + ..\packages\Microsoft.AspNet.WebApi.Core.4.0.30506.0\lib\net40\System.Web.Http.dll + + + ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll + + + True + ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll + + + False + ..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll + True + + + True + ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.dll + + + True + ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Deployment.dll + + + True + ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll + - + + ..\packages\UmbracoCms.Core.7.0.1\lib\TidyNet.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\umbraco.dll + + + False ..\packages\UmbracoCms.Core.7.0.1\lib\Umbraco.Core.dll + + ..\packages\UmbracoCms.Core.7.0.1\lib\umbraco.DataLayer.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\umbraco.editorControls.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\umbraco.MacroEngines.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\umbraco.providers.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\Umbraco.Web.UI.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\umbraco.XmlSerializers.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\UmbracoExamine.dll + + + ..\packages\UmbracoCms.Core.7.0.1\lib\UrlRewritingNet.UrlRewriter.dll + diff --git a/app/Umbraco/Archetype.Tests/packages.config b/app/Umbraco/Archetype.Tests/packages.config index c90677c..41531cd 100644 --- a/app/Umbraco/Archetype.Tests/packages.config +++ b/app/Umbraco/Archetype.Tests/packages.config @@ -1,5 +1,26 @@  + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj b/app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj index 05ed8ed..5f6c903 100644 --- a/app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj +++ b/app/Umbraco/Umbraco.Archetype/Archetype.Umbraco.csproj @@ -136,6 +136,7 @@ False + False ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll diff --git a/app/Umbraco/Umbraco.Archetype/Models/Property.cs b/app/Umbraco/Umbraco.Archetype/Models/Property.cs index 09605b7..a3c4522 100644 --- a/app/Umbraco/Umbraco.Archetype/Models/Property.cs +++ b/app/Umbraco/Umbraco.Archetype/Models/Property.cs @@ -1,9 +1,11 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using Newtonsoft.Json; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; +using Umbraco.Web; namespace Archetype.Umbraco.Models { @@ -30,14 +32,26 @@ namespace Archetype.Umbraco.Models if (Value is T) return (T)Value; - // Umbraco has the concept of a IPropertyEditorValueConverter which it - // also queries for property resolvers. However I'm not sure what these - // are for, nor can I find any implementations in core, so am currently - // just ignoring these when looking up converters. - // NB: IPropertyEditorValueConverter not to be confused with - // IPropertyValueConverter which are the ones most people are creating + // Try Umbraco's PropertyValueConverters + var converters = UmbracoContext.Current != null ? PropertyValueConvertersResolver.Current.Converters : Enumerable.Empty(); + if (converters.Any()) + { + var convertedAttempt = TryConvertWithPropertyValueConverters(Value, converters); + if (convertedAttempt.Success) + return convertedAttempt.Result; + } + + // No PropertyValueConverters matched, so try a regular type conversion + var convertAttempt2 = Value.TryConvertTo(); + if (convertAttempt2.Success) + return convertAttempt2.Result; + + return default(T); + } + + private Attempt TryConvertWithPropertyValueConverters(object value, IEnumerable converters) + { var properyType = CreateDummyPropertyType(DataTypeId, PropertyEditorAlias); - var converters = PropertyValueConvertersResolver.Current.Converters.ToArray(); // In umbraco, there are default value converters that try to convert the // value if all else fails. The problem is, they are also in the list of @@ -49,24 +63,19 @@ namespace Archetype.Umbraco.Models foreach (var converter in converters.Where(x => x.IsConverter(properyType))) { // Convert the type using a found value converter - var value2 = converter.ConvertDataToSource(properyType, Value, false); + var value2 = converter.ConvertDataToSource(properyType, value, false); // If the value is of type T, just return it if (value2 is T) - return (T)value2; + return Attempt.Succeed((T)value2); // Value is not final value type, so try a regular type conversion aswell var convertAttempt = value2.TryConvertTo(); if (convertAttempt.Success) - return convertAttempt.Result; + return Attempt.Succeed(convertAttempt.Result); } - // Value is not final value type, so try a regular type conversion - var convertAttempt2 = Value.TryConvertTo(); - if (convertAttempt2.Success) - return convertAttempt2.Result; - - return default(T); + return Attempt.Fail(); } private PublishedPropertyType CreateDummyPropertyType(int dataTypeId, string propertyEditorAlias) From b9a0852c4f0de38efe98da1d1d0d84fbda188798 Mon Sep 17 00:00:00 2001 From: Andrey Shchekin Date: Wed, 2 Apr 2014 14:26:35 +1300 Subject: [PATCH 15/17] Added a "start with Add button" option that shows "+ Add" instead of default fieldset. --- .../Models/ArchetypePreValue.cs | 5 +- app/controllers/config.controller.js | 68 +++++++++---------- app/controllers/controller.js | 60 +++++++++------- app/less/archetype.less | 10 ++- app/views/archetype.config.html | 10 ++- app/views/archetype.html | 9 ++- 6 files changed, 99 insertions(+), 63 deletions(-) diff --git a/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs b/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs index 1a7e4a2..653af0e 100644 --- a/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs +++ b/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs @@ -6,7 +6,10 @@ namespace Archetype.Umbraco.Models public class ArchetypePreValue { [JsonProperty("showAdvancedOptions")] - public bool ShowAdvancedOptions { get; set; } + public bool ShowAdvancedOptions { get; set; } + + [JsonProperty("startWithAddButton")] + public bool StartWithAddButton { get; set; } [JsonProperty("hideFieldsetToolbar")] public bool HideFieldsetToolbar { get; set; } diff --git a/app/controllers/config.controller.js b/app/controllers/config.controller.js index 0a3828f..08c02a8 100644 --- a/app/controllers/config.controller.js +++ b/app/controllers/config.controller.js @@ -1,19 +1,19 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", function ($scope, $http, assetsService, dialogService, archetypePropertyEditorResource) { - - //$scope.model.value = ""; - //console.log($scope.model.value); + + //$scope.model.value = ""; + //console.log($scope.model.value); //define empty items var newPropertyModel = '{"alias": "", "remove": false, "collapse": false, "label": "", "helpText": "", "dataTypeId": "-88", "value": ""}'; var newFieldsetModel = '{"alias": "", "remove": false, "collapse": false, "labelTemplate": "", "icon": "", "label": "", "properties": [' + newPropertyModel + ']}'; - var defaultFieldsetConfigModel = JSON.parse('{"showAdvancedOptions": false, "hideFieldsetToolbar": false, "enableMultipleFieldsets": false, "hideFieldsetControls": false, "hidePropertyLabel": false, "maxFieldsets": null, "enableCollapsing": true, "fieldsets": [' + newFieldsetModel + ']}'); + var defaultFieldsetConfigModel = JSON.parse('{"showAdvancedOptions": false, "startWithAddButton": false, "hideFieldsetToolbar": false, "enableMultipleFieldsets": false, "hideFieldsetControls": false, "hidePropertyLabel": false, "maxFieldsets": null, "enableCollapsing": true, "fieldsets": [' + newFieldsetModel + ']}'); //ini the model $scope.model.value = $scope.model.value || defaultFieldsetConfigModel; - + //ini the render model initConfigRenderModel(); - + //get the available datatypes archetypePropertyEditorResource.getAllDataTypes().then(function(data) { $scope.availableDataTypes = data; @@ -40,16 +40,16 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio } }; - + //function that determines how to manage expanding/collapsing fieldsets $scope.focusFieldset = function(fieldset){ var iniState; - + if(fieldset) { iniState = fieldset.collapse; } - + _.each($scope.archetypeConfigRenderModel.fieldsets, function(fieldset){ if($scope.archetypeConfigRenderModel.fieldsets.length == 1 && fieldset.remove == false) { @@ -66,7 +66,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio fieldset.collapse = false; } }); - + if(iniState) { fieldset.collapse = !iniState; @@ -79,7 +79,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio //function that determines how to manage expanding/collapsing properties $scope.focusProperty = function(properties, property){ var iniState; - + if(property) { iniState = property.collapse; @@ -95,7 +95,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio property.collapse = false; } }); - + if(iniState) { property.collapse = !iniState; @@ -106,24 +106,24 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio _.each($scope.archetypeConfigRenderModel.fieldsets, function(fieldset){ $scope.focusProperty(fieldset.properties); }); - + //setup JSON.stringify helpers $scope.archetypeConfigRenderModel.toString = stringify; - + //encapsulate stringify (should be built into browsers, not sure of IE support) function stringify() { return JSON.stringify(this); } - + //watch for changes $scope.$watch('archetypeConfigRenderModel', function (v) { //console.log(v); - if (typeof v === 'string') { + if (typeof v === 'string') { $scope.archetypeConfigRenderModel = JSON.parse(v); $scope.archetypeConfigRenderModel.toString = stringify; } }); - + $scope.autoPopulateAlias = function(s) { var modelType = s.hasOwnProperty('fieldset') ? 'fieldset' : 'property'; var modelProperty = s[modelType]; @@ -144,7 +144,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio //helper that returns if an item can be removed $scope.canRemoveFieldset = function () - { + { return countVisibleFieldset() > 1; } @@ -153,10 +153,10 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio { return countVisibleFieldset() > 1; } - + //helper that returns if an item can be removed $scope.canRemoveProperty = function (fieldset) - { + { return countVisibleProperty(fieldset) > 1; } @@ -176,7 +176,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio return dataType == null ? "" : dataType.name; } - + //helper to count what is visible function countVisibleFieldset() { @@ -190,7 +190,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio return count; } - + //determines how many properties are visible function countVisibleProperty(fieldset) { @@ -204,13 +204,13 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio return count; } - + //handles a fieldset add $scope.addFieldsetRow = function ($index, $event) { $scope.archetypeConfigRenderModel.fieldsets.splice($index + 1, 0, JSON.parse(newFieldsetModel)); $scope.focusFieldset(); } - + //rather than splice the archetypeConfigRenderModel, we're hiding this and cleaning onFormSubmitting $scope.removeFieldsetRow = function ($index) { if ($scope.canRemoveFieldset()) { @@ -219,12 +219,12 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio } } } - + //handles a property add $scope.addPropertyRow = function (fieldset, $index) { fieldset.properties.splice($index + 1, 0, JSON.parse(newPropertyModel)); } - + //rather than splice the archetypeConfigRenderModel, we're hiding this and cleaning onFormSubmitting $scope.removePropertyRow = function (fieldset, $index) { if ($scope.canRemoveProperty(fieldset)) { @@ -233,7 +233,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio } } } - + //helper to ini the render model function initConfigRenderModel() { @@ -257,38 +257,38 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio }); }); } - + //sync things up on save $scope.$on("formSubmitting", function (ev, args) { syncModelToRenderModel(); }); - + //helper to sync the model to the renderModel function syncModelToRenderModel() { $scope.model.value = $scope.archetypeConfigRenderModel; var fieldsets = []; - + _.each($scope.archetypeConfigRenderModel.fieldsets, function(fieldset){ //check fieldsets if (!fieldset.remove) { fieldsets.push(fieldset); - + var properties = []; _.each(fieldset.properties, function(property){ if (!property.remove) { properties.push(property); - } + } }); fieldset.properties = properties; } }); - + $scope.model.value.fieldsets = fieldsets; } - + //archetype css assetsService.loadCss("/App_Plugins/Archetype/css/archetype.css"); }); diff --git a/app/controllers/controller.js b/app/controllers/controller.js index f89e0a9..9ceb769 100644 --- a/app/controllers/controller.js +++ b/app/controllers/controller.js @@ -1,5 +1,5 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, assetsService, angularHelper, notificationsService, $timeout) { - + //$scope.model.value = ""; $scope.model.hideLabel = $scope.model.config.hideLabel == 1; @@ -8,14 +8,14 @@ //set the config equal to our prevalue config $scope.model.config = $scope.model.config.archetypeConfig; - + //ini the model - $scope.model.value = $scope.model.value || { fieldsets: [getEmptyRenderFieldset($scope.model.config.fieldsets[0])] }; + $scope.model.value = $scope.model.value || getDefaultModel($scope.model.config); //ini the render model $scope.archetypeRenderModel = {}; initArchetypeRenderModel(); - + //helper to get $eval the labelTemplate $scope.getFieldsetTitle = function(fieldsetConfigModel, fieldsetIndex) { var fieldset = $scope.archetypeRenderModel.fieldsets[fieldsetIndex]; @@ -100,8 +100,9 @@ //helper that returns if an item can be removed $scope.canRemove = function () - { - return countVisible() > 1; + { + return countVisible() > 1 + || $scope.model.config.startWithAddButton; } //helper that returns if an item can be sorted @@ -110,6 +111,12 @@ return countVisible() > 1; } + //helpers for determining if the add button should be shown + $scope.showAddButton = function () { + return $scope.model.config.startWithAddButton + && countVisible() === 0; + } + //helper, ini the render model from the server (model.value) function initArchetypeRenderModel() { $scope.archetypeRenderModel = removeNulls($scope.model.value); @@ -119,7 +126,7 @@ fieldset.remove = false; fieldset.collapse = false; fieldset.isValid = true; - }); + }); } //helper to get the correct fieldset from config @@ -136,7 +143,7 @@ }); return (typeof property !== 'undefined') ? property.value : ''; }; - + //helper for expanding/collapsing fieldsets $scope.focusFieldset = function(fieldset){ fixDisableSelection(); @@ -144,30 +151,30 @@ if (!$scope.model.config.enableCollapsing) { return; } - + var iniState; - + if(fieldset) { iniState = fieldset.collapse; } - + _.each($scope.archetypeRenderModel.fieldsets, function(fieldset){ fieldset.collapse = true; }); - + if(!fieldset && $scope.archetypeRenderModel.fieldsets.length == 1 && $scope.archetypeRenderModel.fieldsets[0].remove == false) { $scope.archetypeRenderModel.fieldsets[0].collapse = false; return; } - + if(iniState && fieldset) { fieldset.collapse = !iniState; } } - + //ini the fieldset expand/collapse $scope.focusFieldset(); @@ -241,7 +248,7 @@ if(propertyConfig){ delete property.isValid; } - else + else { //need to remove the whole property tempFieldset.properties.splice(index, 1); @@ -253,10 +260,17 @@ } } + // helper to get initial model if none was provided + function getDefaultModel(config) { + if (config.startWithAddButton) + return { fieldsets: [] }; + + return { fieldsets: [getEmptyRenderFieldset(config.fieldsets[0])] }; + } + //helper to add an empty fieldset to the render model - function getEmptyRenderFieldset (fieldsetModel) - { - return JSON.parse('{"alias": "' + fieldsetModel.alias + '", "remove": false, "isValid": true, "properties": []}'); + function getEmptyRenderFieldset (fieldsetModel) { + return {alias: fieldsetModel.alias, remove: false, isValid: true, properties: []}; } //helper to ensure no nulls make it into the model @@ -268,7 +282,7 @@ removeNulls(model); } }); - + return model; } } @@ -277,9 +291,9 @@ function fixDisableSelection() { $timeout(function() { $('.archetypeEditor .controls') - .bind('mousedown.ui-disableSelection selectstart.ui-disableSelection', function(e) { + .bind('mousedown.ui-disableSelection selectstart.ui-disableSelection', function(e) { e.stopImmediatePropagation(); - }); + }); }, 1000); } @@ -307,7 +321,7 @@ { notificationsService.warning("Cannot Save Document", "The document could not be saved because of missing required fields.") } - else + else { syncModelToRenderModel(); } @@ -316,7 +330,7 @@ //custom js if ($scope.model.config.customJsPath) { assetsService.loadJs($scope.model.config.customJsPath); - } + } //archetype css assetsService.loadCss("/App_Plugins/Archetype/css/archetype.css"); diff --git a/app/less/archetype.less b/app/less/archetype.less index eb7370f..215aac8 100644 --- a/app/less/archetype.less +++ b/app/less/archetype.less @@ -36,7 +36,7 @@ cursor: pointer; label { - span { + span { text-decoration: underline; } &:hover { @@ -297,6 +297,14 @@ } } +.archetypeEditor .archetypeAddButton:hover { + text-decoration: none; + + .archetypeAddButtonText { + text-decoration: underline; + } +} + .ui-sortable-placeholder { visibility: visible !important; background-color: #d0e7f1 !important; diff --git a/app/views/archetype.config.html b/app/views/archetype.config.html index c80bf10..a5e3b0f 100644 --- a/app/views/archetype.config.html +++ b/app/views/archetype.config.html @@ -27,7 +27,7 @@
-
+
  • @@ -81,6 +81,10 @@
+
+ + +
@@ -96,11 +100,11 @@
-
+
-
+
diff --git a/app/views/archetype.html b/app/views/archetype.html index b565237..f20cde2 100644 --- a/app/views/archetype.html +++ b/app/views/archetype.html @@ -9,7 +9,7 @@
-
    +
    • @@ -49,4 +49,11 @@
    + + From d7432d1f9519c91d07180012d9e6080405da7620 Mon Sep 17 00:00:00 2001 From: Kevin Giszewski Date: Thu, 3 Apr 2014 11:44:18 -0400 Subject: [PATCH 16/17] Update the GUID, seems to not default properly at times --- app/controllers/config.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/config.controller.js b/app/controllers/config.controller.js index dd955e3..3c8f03d 100644 --- a/app/controllers/config.controller.js +++ b/app/controllers/config.controller.js @@ -4,7 +4,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio //console.log($scope.model.value); //define empty items - var newPropertyModel = '{"alias": "", "remove": false, "collapse": false, "label": "", "helpText": "", "dataTypeGuid": "0CC0EBA1-9960-42C9-BF9B-60E150B429AE", "value": ""}'; + 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 + ']}'; var defaultFieldsetConfigModel = JSON.parse('{"showAdvancedOptions": false, "hideFieldsetToolbar": false, "enableMultipleFieldsets": false, "hideFieldsetControls": false, "hidePropertyLabel": false, "maxFieldsets": null, "enableCollapsing": true, "fieldsets": [' + newFieldsetModel + ']}'); From 7ddc74d75b4bc48c2418354dd113705e8ca6d189 Mon Sep 17 00:00:00 2001 From: Kevin Giszewski Date: Thu, 3 Apr 2014 12:04:45 -0400 Subject: [PATCH 17/17] Fix a glitch that won't let a single fieldset be removed if multiple FS's are configured with the 'Start with Add' option --- app/views/archetype.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/archetype.html b/app/views/archetype.html index f20cde2..bf31438 100644 --- a/app/views/archetype.html +++ b/app/views/archetype.html @@ -24,7 +24,7 @@ -
    +