Merge branch 'temp-U4-11218' into temp-v8-UI-infinite-editing
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp50</s:String></wpf:ResourceDictionary>
|
||||
<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp70</s:String></wpf:ResourceDictionary>
|
||||
@@ -16,6 +16,7 @@
|
||||
"tests"
|
||||
],
|
||||
"dependencies": {
|
||||
"signalr": "^2.2.1",
|
||||
"typeahead.js": "~0.10.5",
|
||||
"underscore": "~1.7.0",
|
||||
"rgrove-lazyload": "*",
|
||||
@@ -42,7 +43,12 @@
|
||||
"codemirror"
|
||||
],
|
||||
"sources": {
|
||||
"moment": "bower_components/moment/min/moment-with-locales.js",
|
||||
"moment": [
|
||||
"bower_components/moment/min/moment.min.js",
|
||||
"bower_components/moment/min/moment-with-locales.js",
|
||||
"bower_components/moment/min/moment-with-locales.min.js",
|
||||
"bower_components/moment/locale/*.js"
|
||||
],
|
||||
"underscore": [
|
||||
"bower_components/underscore/underscore-min.js",
|
||||
"bower_components/underscore/underscore-min.map"
|
||||
|
||||
@@ -1,605 +0,0 @@
|
||||
module.exports = function (grunt) {
|
||||
|
||||
|
||||
|
||||
// Default task.
|
||||
grunt.registerTask('default', ['jshint:dev', 'build', 'karma:unit']);
|
||||
grunt.registerTask('dev', ['jshint:dev', 'build-dev', 'webserver', 'open:dev', 'watch']);
|
||||
grunt.registerTask('docserve', ['docs:api', 'connect:docserver', 'open:docs', 'watch:docs']);
|
||||
grunt.registerTask('vs', ['jshint:dev', 'build-dev', 'watch']);
|
||||
|
||||
//TODO: Too much watching, this brings windows to it's knees when in dev mode
|
||||
//run by the watch task
|
||||
grunt.registerTask('watch-js', ['jshint:dev', 'concat', 'copy:app', 'copy:mocks', 'copy:canvasdesigner', 'copy:vs', 'karma:unit']);
|
||||
grunt.registerTask('watch-less', ['recess:build', 'recess:installer', 'recess:nonodes', 'recess:canvasdesigner', 'postcss', 'copy:canvasdesigner', 'copy:assets', 'copy:vs']);
|
||||
grunt.registerTask('watch-html', ['copy:views', 'copy:vs']);
|
||||
grunt.registerTask('watch-installer', ['concat:install', 'concat:installJs', 'copy:installer', 'copy:vs']);
|
||||
grunt.registerTask('watch-canvasdesigner', ['copy:canvasdesigner', 'concat:canvasdesignerJs', 'copy:vs']);
|
||||
grunt.registerTask('watch-test', ['jshint:dev', 'karma:unit']);
|
||||
|
||||
//triggered from grunt
|
||||
grunt.registerTask('build', ['concat', 'recess:build', 'recess:installer', 'recess:nonodes', 'recess:canvasdesigner', 'postcss', 'bower-install-simple', 'bower', 'copy', 'clean:post']);
|
||||
|
||||
//triggered from grunt dev vs or grunt vs
|
||||
grunt.registerTask('build-dev', ['clean:pre', 'concat', 'recess:build', 'recess:installer', 'recess:nonodes', 'postcss', 'bower-install-simple', 'bower', 'copy']);
|
||||
|
||||
//utillity tasks
|
||||
grunt.registerTask('docs', ['ngdocs']);
|
||||
grunt.registerTask('webserver', ['connect:devserver']);
|
||||
|
||||
|
||||
// Print a timestamp (useful for when watching)
|
||||
grunt.registerTask('timestamp', function () {
|
||||
grunt.log.subhead(Date());
|
||||
});
|
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({
|
||||
buildVersion: grunt.option('buildversion') || '7',
|
||||
connect: {
|
||||
devserver: {
|
||||
options: {
|
||||
port: 9990,
|
||||
hostname: '0.0.0.0',
|
||||
base: './build',
|
||||
middleware: function(connect, options) {
|
||||
return [
|
||||
//uncomment to enable CSP
|
||||
// util.csp(),
|
||||
//util.rewrite(),
|
||||
connect.favicon('images/favicon.ico'),
|
||||
connect.static(options.base),
|
||||
connect.directory(options.base)
|
||||
];
|
||||
}
|
||||
}
|
||||
},
|
||||
testserver: {},
|
||||
docserver: {
|
||||
options: {
|
||||
port: 8880,
|
||||
hostname: '0.0.0.0',
|
||||
base: './docs/api',
|
||||
middleware: function(connect, options) {
|
||||
return [
|
||||
//uncomment to enable CSP
|
||||
// util.csp(),
|
||||
//util.rewrite(),
|
||||
connect.static(options.base),
|
||||
connect.directory(options.base)
|
||||
];
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
open: {
|
||||
dev: {
|
||||
path: 'http://localhost:9990/belle/'
|
||||
},
|
||||
docs: {
|
||||
path: 'http://localhost:8880/index.html'
|
||||
}
|
||||
},
|
||||
|
||||
distdir: 'build/belle',
|
||||
vsdir: '../Umbraco.Web.UI/umbraco',
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
banner:
|
||||
'/*! <%= pkg.title || pkg.name %>\n' +
|
||||
'<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' +
|
||||
' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>;\n' +
|
||||
' * Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>\n */\n',
|
||||
src: {
|
||||
js: ['src/**/*.js', 'src/*.js'],
|
||||
|
||||
common: ['src/common/**/*.js'],
|
||||
controllers: ['src/**/*.controller.js'],
|
||||
|
||||
specs: ['test/**/*.spec.js'],
|
||||
scenarios: ['test/**/*.scenario.js'],
|
||||
samples: ['sample files/*.js'],
|
||||
html: ['src/index.html', 'src/install.html'],
|
||||
|
||||
everything: ['src/**/*.*', 'test/**/*.*', 'docs/**/*.*'],
|
||||
|
||||
tpl: {
|
||||
app: ['src/views/**/*.html'],
|
||||
common: ['src/common/**/*.tpl.html']
|
||||
},
|
||||
less: ['src/less/belle.less'], // recess:build doesn't accept ** in its file patterns
|
||||
prod: ['<%= distdir %>/js/*.js']
|
||||
},
|
||||
|
||||
clean: {
|
||||
pre: ['<%= distdir %>/*'],
|
||||
post: ['<%= distdir %>/js/*.dev.js']
|
||||
},
|
||||
|
||||
copy: {
|
||||
assets: {
|
||||
files: [{ dest: '<%= distdir %>/assets', src: '**', expand: true, cwd: 'src/assets/' }]
|
||||
},
|
||||
|
||||
config: {
|
||||
files: [{ dest: '<%= distdir %>/../config', src: '**', expand: true, cwd: 'src/config/' }]
|
||||
},
|
||||
|
||||
installer: {
|
||||
files: [{ dest: '<%= distdir %>/views/install', src: '**/*.html', expand: true, cwd: 'src/installer/steps' }]
|
||||
},
|
||||
|
||||
canvasdesigner: {
|
||||
files: [
|
||||
{ dest: '<%= distdir %>/preview', src: '**/*.html', expand: true, cwd: 'src/canvasdesigner' },
|
||||
{ dest: '<%= distdir %>/preview/editors', src: '**/*.html', expand: true, cwd: 'src/canvasdesigner/editors' },
|
||||
{ dest: '<%= distdir %>/assets/less', src: '**/*.less', expand: true, cwd: 'src/canvasdesigner/editors' },
|
||||
{ dest: '<%= distdir %>/js', src: 'canvasdesigner.config.js', expand: true, cwd: 'src/canvasdesigner/config' },
|
||||
{ dest: '<%= distdir %>/js', src: 'canvasdesigner.palettes.js', expand: true, cwd: 'src/canvasdesigner/config' },
|
||||
{ dest: '<%= distdir %>/js', src: 'canvasdesigner.front.js', expand: true, cwd: 'src/canvasdesigner' }
|
||||
]
|
||||
},
|
||||
|
||||
vendor: {
|
||||
files: [{ dest: '<%= distdir %>/lib', src: '**', expand: true, cwd: 'lib/' }]
|
||||
},
|
||||
|
||||
views: {
|
||||
files: [{ dest: '<%= distdir %>/views', src: ['**/*.*', '!**/*.controller.js'], expand: true, cwd: 'src/views' }]
|
||||
},
|
||||
|
||||
app: {
|
||||
files: [
|
||||
{ dest: '<%= distdir %>/js', src: '*.js', expand: true, cwd: 'src/' }
|
||||
]
|
||||
},
|
||||
|
||||
mocks: {
|
||||
files: [{ dest: '<%= distdir %>/js', src: '*.js', expand: true, cwd: 'src/common/mocks/' }]
|
||||
},
|
||||
|
||||
vs: {
|
||||
files: [
|
||||
//everything except the index.html root file!
|
||||
//then we need to figure out how to not copy all the test stuff either!?
|
||||
{ dest: '<%= vsdir %>/assets', src: '**', expand: true, cwd: '<%= distdir %>/assets' },
|
||||
{ dest: '<%= vsdir %>/js', src: '**', expand: true, cwd: '<%= distdir %>/js' },
|
||||
{ dest: '<%= vsdir %>/views', src: '**', expand: true, cwd: '<%= distdir %>/views' },
|
||||
{ dest: '<%= vsdir %>/preview', src: '**', expand: true, cwd: '<%= distdir %>/preview' },
|
||||
{ dest: '<%= vsdir %>/lib', src: '**', expand: true, cwd: '<%= distdir %>/lib' }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
karma: {
|
||||
unit: { configFile: 'test/config/karma.conf.js', keepalive: true },
|
||||
e2e: { configFile: 'test/config/e2e.js', keepalive: true },
|
||||
watch: { configFile: 'test/config/unit.js', singleRun: false, autoWatch: true, keepalive: true }
|
||||
},
|
||||
|
||||
concat: {
|
||||
index: {
|
||||
src: ['src/index.html'],
|
||||
dest: '<%= distdir %>/index.html',
|
||||
options: {
|
||||
process: true
|
||||
}
|
||||
},
|
||||
install: {
|
||||
src: ['src/installer/installer.html'],
|
||||
dest: '<%= distdir %>/installer.html',
|
||||
options: {
|
||||
process: true
|
||||
}
|
||||
},
|
||||
|
||||
installJs: {
|
||||
src: ['src/installer/**/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.installer.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
canvasdesignerJs: {
|
||||
src: ['src/canvasdesigner/canvasdesigner.global.js', 'src/canvasdesigner/canvasdesigner.controller.js', 'src/canvasdesigner/editors/*.js', 'src/canvasdesigner/lib/*.js'],
|
||||
dest: '<%= distdir %>/js/canvasdesigner.panel.js'
|
||||
},
|
||||
|
||||
controllers: {
|
||||
src: ['src/controllers/**/*.controller.js', 'src/views/**/*.controller.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.controllers.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
services: {
|
||||
src: ['src/common/services/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.services.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
security: {
|
||||
src: ['src/common/security/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.security.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
resources: {
|
||||
src: ['src/common/resources/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.resources.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
testing: {
|
||||
src: ['src/common/mocks/*/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.testing.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
directives: {
|
||||
src: ['src/common/directives/**/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.directives.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
filters: {
|
||||
src: ['src/common/filters/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.filters.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
uglify: {
|
||||
options: {
|
||||
mangle: true
|
||||
},
|
||||
combine: {
|
||||
files: {
|
||||
'<%= distdir %>/js/umbraco.min.js': ['<%= distdir %>/js/umbraco.*.js']
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
recess: {
|
||||
build: {
|
||||
files: {
|
||||
'<%= distdir %>/assets/css/<%= pkg.name %>.css':
|
||||
['<%= src.less %>']
|
||||
},
|
||||
options: {
|
||||
compile: true,
|
||||
compress: true
|
||||
}
|
||||
},
|
||||
nonodes: {
|
||||
files: {
|
||||
'<%= distdir %>/assets/css/nonodes.style.min.css':
|
||||
['src/less/pages/nonodes.less']
|
||||
},
|
||||
options: {
|
||||
compile: true,
|
||||
compress: true
|
||||
}
|
||||
},
|
||||
installer: {
|
||||
files: {
|
||||
'<%= distdir %>/assets/css/installer.css':
|
||||
['src/less/installer.less']
|
||||
},
|
||||
options: {
|
||||
compile: true,
|
||||
compress: true
|
||||
}
|
||||
},
|
||||
canvasdesigner: {
|
||||
files: {
|
||||
'<%= distdir %>/assets/css/canvasdesigner.css':
|
||||
['src/less/canvas-designer.less', 'src/less/helveticons.less']
|
||||
},
|
||||
options: {
|
||||
compile: true,
|
||||
compress: true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
postcss: {
|
||||
options: {
|
||||
processors: [
|
||||
// add vendor prefixes
|
||||
require('autoprefixer-core')({
|
||||
browsers: 'last 2 versions'
|
||||
})
|
||||
]
|
||||
},
|
||||
dist: {
|
||||
src: '<%= distdir %>/assets/css/<%= pkg.name %>.css'
|
||||
}
|
||||
},
|
||||
|
||||
ngTemplateCache: {
|
||||
views: {
|
||||
files: {
|
||||
'<%= distdir %>/js/umbraco.views.js': 'src/views/**/*.html'
|
||||
},
|
||||
options: {
|
||||
trim: 'src/',
|
||||
module: 'umbraco.views'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
docs: {
|
||||
files: ['docs/src/**/*.md'],
|
||||
tasks: ['watch-docs', 'timestamp']
|
||||
},
|
||||
css: {
|
||||
files: 'src/**/*.less',
|
||||
tasks: ['watch-less', 'timestamp'],
|
||||
options: {
|
||||
livereload: true,
|
||||
},
|
||||
},
|
||||
js: {
|
||||
files: ['src/**/*.js', 'src/*.js'],
|
||||
tasks: ['watch-js', 'timestamp'],
|
||||
},
|
||||
test: {
|
||||
files: ['test/**/*.js'],
|
||||
tasks: ['watch-test', 'timestamp'],
|
||||
},
|
||||
installer: {
|
||||
files: ['src/installer/**/*.*'],
|
||||
tasks: ['watch-installer', 'timestamp'],
|
||||
},
|
||||
canvasdesigner: {
|
||||
files: ['src/canvasdesigner/**/*.*'],
|
||||
tasks: ['watch-canvasdesigner', 'timestamp'],
|
||||
},
|
||||
html: {
|
||||
files: ['src/views/**/*.html', 'src/*.html'],
|
||||
tasks: ['watch-html', 'timestamp']
|
||||
},
|
||||
options: {
|
||||
interval: 500
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
ngdocs: {
|
||||
options: {
|
||||
dest: 'docs/api',
|
||||
startPage: '/api',
|
||||
title: "Umbraco Backoffice UI API Documentation",
|
||||
html5Mode: false,
|
||||
styles: [
|
||||
'docs/umb-docs.css'
|
||||
],
|
||||
image: "https://our.umbraco.org/assets/images/logo.svg"
|
||||
},
|
||||
api: {
|
||||
src: ['src/common/**/*.js', 'docs/src/api/**/*.ngdoc'],
|
||||
title: 'API Documentation'
|
||||
},
|
||||
tutorials: {
|
||||
src: [],
|
||||
title: ''
|
||||
}
|
||||
},
|
||||
|
||||
eslint:{
|
||||
src: ['<%= src.common %>','<%= src.controllers %>'],
|
||||
options: {quiet: true}
|
||||
},
|
||||
|
||||
jshint: {
|
||||
dev: {
|
||||
files: {
|
||||
src: ['<%= src.common %>']
|
||||
},
|
||||
options: {
|
||||
curly: true,
|
||||
eqeqeq: true,
|
||||
immed: true,
|
||||
latedef: "nofunc",
|
||||
newcap: true,
|
||||
noarg: true,
|
||||
sub: true,
|
||||
boss: true,
|
||||
//NOTE: This is required so it doesn't barf on reserved words like delete when doing $http.delete
|
||||
es5: true,
|
||||
eqnull: true,
|
||||
//NOTE: we need to use eval sometimes so ignore it
|
||||
evil: true,
|
||||
//NOTE: we need to check for strings such as "javascript:" so don't throw errors regarding those
|
||||
scripturl: true,
|
||||
//NOTE: we ignore tabs vs spaces because enforcing that causes lots of errors depending on the text editor being used
|
||||
smarttabs: true,
|
||||
globals: {}
|
||||
}
|
||||
},
|
||||
build: {
|
||||
files: {
|
||||
src: ['<%= src.prod %>']
|
||||
},
|
||||
options: {
|
||||
curly: true,
|
||||
eqeqeq: true,
|
||||
immed: true,
|
||||
latedef: "nofunc",
|
||||
newcap: true,
|
||||
noarg: true,
|
||||
sub: true,
|
||||
boss: true,
|
||||
//NOTE: This is required so it doesn't barf on reserved words like delete when doing $http.delete
|
||||
es5: true,
|
||||
eqnull: true,
|
||||
//NOTE: we need to use eval sometimes so ignore it
|
||||
evil: true,
|
||||
//NOTE: we need to check for strings such as "javascript:" so don't throw errors regarding those
|
||||
scripturl: true,
|
||||
//NOTE: we ignore tabs vs spaces because enforcing that causes lots of errors depending on the text editor being used
|
||||
smarttabs: true,
|
||||
globalstrict: true,
|
||||
globals: { $: false, jQuery: false, define: false, require: false, window: false }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
bower: {
|
||||
dev: {
|
||||
dest: '<%= distdir %>/lib',
|
||||
options: {
|
||||
expand: true,
|
||||
ignorePackages: ['bootstrap'],
|
||||
packageSpecific: {
|
||||
'moment': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['min/moment-with-locales.js']
|
||||
},
|
||||
'typeahead.js': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['dist/typeahead.bundle.min.js']
|
||||
},
|
||||
'underscore': {
|
||||
files: ['underscore-min.js', 'underscore-min.map']
|
||||
},
|
||||
'rgrove-lazyload': {
|
||||
files: ['lazyload.js']
|
||||
},
|
||||
'bootstrap-social': {
|
||||
files: ['bootstrap-social.css']
|
||||
},
|
||||
'font-awesome': {
|
||||
files: ['css/font-awesome.min.css', 'fonts/*']
|
||||
},
|
||||
"jquery": {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['dist/jquery.min.js', 'dist/jquery.min.map']
|
||||
},
|
||||
'jquery-ui': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['jquery-ui.min.js']
|
||||
},
|
||||
'jquery-migrate': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['jquery-migrate.min.js']
|
||||
},
|
||||
'tinymce': {
|
||||
files: ['plugins/**', 'themes/**', 'tinymce.min.js']
|
||||
},
|
||||
'angular-dynamic-locale': {
|
||||
files: ['tmhDynamicLocale.min.js', 'tmhDynamicLocale.min.js.map']
|
||||
},
|
||||
'ng-file-upload': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['ng-file-upload.min.js']
|
||||
},
|
||||
'angular-local-storage': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['dist/angular-local-storage.min.js']
|
||||
},
|
||||
'codemirror': {
|
||||
files: [
|
||||
'lib/codemirror.js',
|
||||
'lib/codemirror.css',
|
||||
|
||||
'mode/css/*',
|
||||
'mode/javascript/*',
|
||||
'mode/xml/*',
|
||||
'mode/htmlmixed/*',
|
||||
|
||||
'addon/search/*',
|
||||
'addon/edit/*',
|
||||
'addon/selection/*',
|
||||
'addon/dialog/*'
|
||||
]
|
||||
},
|
||||
'ace-builds': {
|
||||
files: [
|
||||
'src-min-noconflict/ace.js',
|
||||
|
||||
'src-min-noconflict/ext-language_tools.js',
|
||||
'src-min-noconflict/ext-searchbox.js',
|
||||
'src-min-noconflict/ext-settings_menu.js',
|
||||
|
||||
'src-min-noconflict/snippets/text.js',
|
||||
'src-min-noconflict/snippets/javascript.js',
|
||||
|
||||
'src-min-noconflict/theme-chrome.js',
|
||||
|
||||
'src-min-noconflict/mode-razor.js',
|
||||
'src-min-noconflict/mode-javascript.js',
|
||||
|
||||
'src-min-noconflict/worker-javascript.js',
|
||||
]
|
||||
},
|
||||
'clipboard': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['dist/clipboard.min.js']
|
||||
},
|
||||
'angular-moment': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['angular-moment.min.js']
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
options: {
|
||||
expand: true
|
||||
}
|
||||
},
|
||||
|
||||
"bower-install-simple": {
|
||||
options: {
|
||||
color: true
|
||||
},
|
||||
"dev": {}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-recess');
|
||||
grunt.loadNpmTasks('grunt-postcss');
|
||||
|
||||
grunt.loadNpmTasks('grunt-karma');
|
||||
|
||||
grunt.loadNpmTasks('grunt-open');
|
||||
grunt.loadNpmTasks('grunt-contrib-connect');
|
||||
grunt.loadNpmTasks("grunt-bower-install-simple");
|
||||
grunt.loadNpmTasks('grunt-bower');
|
||||
grunt.loadNpmTasks('grunt-ngdocs');
|
||||
|
||||
grunt.loadNpmTasks('grunt-eslint');
|
||||
grunt.loadNpmTasks('grunt-hustler');
|
||||
};
|
||||
@@ -73,7 +73,6 @@ var sources = {
|
||||
js: {
|
||||
preview: { files: ["src/canvasdesigner/**/*.js"], out: "umbraco.canvasdesigner.js" },
|
||||
installer: { files: ["src/installer/**/*.js"], out: "umbraco.installer.js" },
|
||||
|
||||
controllers: { files: ["src/{views,controllers}/**/*.controller.js"], out: "umbraco.controllers.js" },
|
||||
directives: { files: ["src/common/directives/**/*.js"], out: "umbraco.directives.js" },
|
||||
filters: { files: ["src/common/filters/**/*.js"], out: "umbraco.filters.js" },
|
||||
@@ -85,8 +84,7 @@ var sources = {
|
||||
//selectors for copying all views into the build
|
||||
//processed in the views task
|
||||
views:{
|
||||
umbraco: {files: ["src/views/**/*html"], folder: ""},
|
||||
preview: { files: ["src/canvasdesigner/**/*.html"], folder: "../preview"},
|
||||
umbraco: {files: ["src/views/**/*.html"], folder: ""},
|
||||
installer: {files: ["src/installer/steps/*.html"], folder: "install"}
|
||||
},
|
||||
|
||||
|
||||
@@ -330,6 +330,19 @@
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
if (!Object.toBoolean) {
|
||||
|
||||
/** Converts a string/integer/bool to true/false */
|
||||
Object.toBoolean = function (obj) {
|
||||
if ((typeof obj) === "boolean") {
|
||||
return obj;
|
||||
}
|
||||
if (obj === "1" || obj === 1 || obj === "true") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
})();
|
||||
})();
|
||||
|
||||
@@ -106,6 +106,9 @@ Umbraco.Sys.registerNamespace("Umbraco.Application");
|
||||
treeService.clearCache();
|
||||
});
|
||||
},
|
||||
childNodeCreated: function() {
|
||||
//no-op, just needs to be here for legacy reasons
|
||||
},
|
||||
reloadActionNode: function () {
|
||||
angularHelper.safeApply($rootScope, function() {
|
||||
var currentMenuNode = appState.getMenuState("currentNode");
|
||||
@@ -187,20 +190,6 @@ Umbraco.Sys.registerNamespace("Umbraco.Application");
|
||||
var actions = {
|
||||
openDashboard : function(section){
|
||||
navService.changeSection(section);
|
||||
},
|
||||
actionDisable: function () {
|
||||
localizationService.localize("defaultdialogs_confirmdisable").then(function (txtConfirmDisable) {
|
||||
var currentMenuNode = UmbClientMgr.mainTree().getActionNode();
|
||||
if (currentMenuNode) {
|
||||
if (confirm(txtConfirmDisable + ' "' + UmbClientMgr.mainTree().getActionNode().nodeName + '"?\n\n')) {
|
||||
angularHelper.safeApply($rootScope, function () {
|
||||
usersResource.disableUsers(currentMenuNode.nodeId).then(function () {
|
||||
UmbClientMgr.mainTree().syncTree("-1," + currentMenuNode.nodeId, true);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
38
src/Umbraco.Web.UI.Client/lib/umbraco/legacytreeicons.css
Normal file
38
src/Umbraco.Web.UI.Client/lib/umbraco/legacytreeicons.css
Normal file
@@ -0,0 +1,38 @@
|
||||
.sprTreeDeveloperCacheItem {background-position: -6px -8px ! important;}
|
||||
.sprTreeDeveloperCacheTypes {background-position: -6px -40px ! important;}
|
||||
.sprTreeDeveloperMacro {background-position: -6px -72px ! important;}
|
||||
.sprTreeDeveloperPython {background-position: -6px -104px ! important; width: 15px; height: 15px}
|
||||
.sprTreeDeveloperRegistry {background-position: -6px -135px ! important;}
|
||||
.sprTreeDoc {background-position: -6px -199px ! important;}
|
||||
.sprTreeDoc2 {background-position: -6px -231px ! important;}
|
||||
.sprTreeDoc3 {background-position: -6px -263px ! important;}
|
||||
.sprTreeDoc4 {background-position: -6px -295px ! important;}
|
||||
.sprTreeDoc5 {background-position: -6px -327px ! important;}
|
||||
.sprTreeDocPic {background-position: -6px -359px ! important;}
|
||||
.sprTreeFolder {background-position: -6px -391px ! important;}
|
||||
.sprTreeFolder_o {background-position: -6px -423px ! important;}
|
||||
.sprTreeMediaFile {background-position: -6px -455px ! important;}
|
||||
.sprTreeMediaMovie {background-position: -6px -487px ! important;}
|
||||
.sprTreemediaFile {background-position: -6px -519px ! important;}
|
||||
.sprTreeMediaPhoto {background-position: -6px -551px ! important;}
|
||||
.sprTreeMember {background-position: -6px -583px ! important;}
|
||||
.sprTreeMemberGroup {background-position: -6px -615px ! important;}
|
||||
.sprTreeMemberType {background-position: -6px -647px ! important;}
|
||||
.sprTreeNewsletter {background-position: -6px -679px ! important;}
|
||||
.sprTreePackage {background-position: -6px -711px ! important;}
|
||||
.sprTreeRepository {background-position: -6px -743px ! important;}
|
||||
.sprTreeSettingAgent {background-position: -6px -775px ! important;}
|
||||
.sprTreeSettingCss {background-position: -6px -807px ! important;}
|
||||
.sprTreeSettingCssItem {background-position: -6px -839px ! important;}
|
||||
.sprTreeSettingDataType {background-position: -6px -871px ! important;}
|
||||
.sprTreeSettingDataTypeChild {background-position: -6px -903px ! important;}
|
||||
.sprTreeSettingDomain {background-position: -6px -935px ! important;}
|
||||
.sprTreeSettingLanguage {background-position: -6px -967px ! important;}
|
||||
.sprTreeSettingScript {background-position: -6px -999px ! important;}
|
||||
.sprTreeSettingTemplate {background-position: -6px -1031px ! important;}
|
||||
.sprTreeSettingXml {background-position: -6px -1063px ! important;}
|
||||
.sprTreeStatistik {background-position: -6px -1095px ! important;}
|
||||
.sprTreeUser {background-position: -6px -1127px ! important;}
|
||||
.sprTreeUserGroup {background-position: -6px -1159px ! important;}
|
||||
.sprTreeUserType {background-position: -6px -1191px ! important;}
|
||||
.sprNew{background-position: -6px -339px;}
|
||||
9006
src/Umbraco.Web.UI.Client/package-lock.json
generated
Normal file
9006
src/Umbraco.Web.UI.Client/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
"author": "Umbraco HQ",
|
||||
"name": "umbraco",
|
||||
"homepage": "https://github.com/umbraco/umbraco-cms/",
|
||||
"version": "7.1.2",
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -27,9 +27,9 @@
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-connect": "5.0.0",
|
||||
"gulp-less": "^3.1.0",
|
||||
"gulp-less": "^3.5.0",
|
||||
"gulp-ngdocs": "^0.3.0",
|
||||
"gulp-open": "^2.0.0",
|
||||
"gulp-open": "^2.1.0",
|
||||
"gulp-postcss": "^6.2.0",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-sort": "^2.0.0",
|
||||
@@ -38,11 +38,11 @@
|
||||
"gulp-wrap-js": "^0.4.1",
|
||||
"jasmine-core": "2.5.2",
|
||||
"karma": "^1.7.0",
|
||||
"karma-jasmine": "^1.1.0",
|
||||
"karma-jasmine": "^1.1.1",
|
||||
"karma-phantomjs-launcher": "^1.0.4",
|
||||
"less": "^2.6.1",
|
||||
"lodash": "^4.16.3",
|
||||
"less": "^2.7.3",
|
||||
"lodash": "^4.17.5",
|
||||
"merge-stream": "^1.0.1",
|
||||
"run-sequence": "^2.1.0"
|
||||
"run-sequence": "^2.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,12 +22,21 @@ var packages = angular.module("umbraco.packages", []);
|
||||
//module is initilized.
|
||||
angular.module("umbraco.views", ["umbraco.viewcache"]);
|
||||
angular.module("umbraco.viewcache", [])
|
||||
.run(function($rootScope, $templateCache) {
|
||||
.run(function ($rootScope, $templateCache, localStorageService) {
|
||||
/** For debug mode, always clear template cache to cut down on
|
||||
dev frustration and chrome cache on templates */
|
||||
if (Umbraco.Sys.ServerVariables.isDebuggingEnabled) {
|
||||
$templateCache.removeAll();
|
||||
}
|
||||
else {
|
||||
var storedVersion = localStorageService.get("umbVersion");
|
||||
if (!storedVersion || storedVersion !== Umbraco.Sys.ServerVariables.application.cacheBuster) {
|
||||
//if the stored version doesn't match our cache bust version, clear the template cache
|
||||
$templateCache.removeAll();
|
||||
//store the current version
|
||||
localStorageService.set("umbVersion", Umbraco.Sys.ServerVariables.application.cacheBuster);
|
||||
}
|
||||
}
|
||||
})
|
||||
.config([
|
||||
//This ensures that all of our angular views are cache busted, if the path starts with views/ and ends with .html, then
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 386 KiB After Width: | Height: | Size: 184 KiB |
@@ -1,20 +1,20 @@
|
||||
|
||||
LazyLoad.js([
|
||||
'../lib/jquery/jquery.min.js',
|
||||
'../lib/jquery-ui/jquery-ui.min.js',
|
||||
'../lib/angular/1.1.5/angular.min.js',
|
||||
'../lib/underscore/underscore-min.js',
|
||||
'../lib/umbraco/Extensions.js',
|
||||
'../js/app.js',
|
||||
'../js/umbraco.resources.js',
|
||||
'../js/umbraco.services.js',
|
||||
'../js/umbraco.security.js',
|
||||
'../ServerVariables',
|
||||
'../lib/spectrum/spectrum.js',
|
||||
'../js/umbraco.canvasdesigner.js',
|
||||
'../js/canvasdesigner.panel.js'
|
||||
'../lib/jquery/jquery.min.js',
|
||||
'../lib/angular/1.1.5/angular.min.js',
|
||||
'../lib/underscore/underscore-min.js',
|
||||
'../lib/umbraco/Extensions.js',
|
||||
'../js/app.js',
|
||||
'../js/umbraco.resources.js',
|
||||
'../js/umbraco.services.js',
|
||||
'../js/umbraco.security.js',
|
||||
'../ServerVariables',
|
||||
'../lib/spectrum/spectrum.js',
|
||||
'../lib/signalr/jquery.signalR.js',
|
||||
'/umbraco/BackOffice/signalr/hubs',
|
||||
'../js/umbraco.canvasdesigner.js'
|
||||
], function () {
|
||||
jQuery(document).ready(function () {
|
||||
angular.bootstrap(document, ['Umbraco.canvasdesigner']);
|
||||
});
|
||||
jQuery(document).ready(function () {
|
||||
angular.bootstrap(document, ['Umbraco.canvasdesigner']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -492,6 +492,26 @@ var app = angular.module("Umbraco.canvasdesigner", ['colorpicker', 'ui.slider',
|
||||
}, 100);
|
||||
}, true);
|
||||
|
||||
// signalr hub
|
||||
var previewHub = $.connection.previewHub;
|
||||
|
||||
previewHub.client.refreshed = function (message, sender) {
|
||||
console.log("Notified by SignalR preview hub (" + message+ ").");
|
||||
|
||||
if ($scope.pageId != message) {
|
||||
console.log("Not a notification for us (" + $scope.pageId + ").");
|
||||
return;
|
||||
}
|
||||
|
||||
var resultFrame = document.getElementById("resultFrame");
|
||||
var iframe = (resultFrame.contentWindow || resultFrame.contentDocument);
|
||||
//setTimeout(function() { iframe.location.reload(); }, 1000);
|
||||
iframe.location.reload();
|
||||
};
|
||||
|
||||
$.connection.hub.start()
|
||||
.done(function () { console.log("Connected to SignalR preview hub (ID=" + $.connection.hub.id + ")"); })
|
||||
.fail(function () { console.log("Could not connect to SignalR preview hub."); });
|
||||
})
|
||||
|
||||
.directive('onFinishRenderFilters', function ($timeout) {
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
|
||||
<div ng-controller="Umbraco.canvasdesigner.background">
|
||||
|
||||
<div class="box-slider">
|
||||
<div colorpicker ng-model="item.values.color"></div>
|
||||
</div>
|
||||
|
||||
<div class="box-slider">
|
||||
<div class="imagePickerPreview" ng-click="open(item.values)" style="background-image:{{ item.values.imageorpattern }}">
|
||||
<i ng-if="item.values.imageorpattern == ''" class="icon icon-picture"></i>
|
||||
<i ng-if="item.values.imageorpattern != ''" class="icon icon-delete" ng-click="item.values.imageorpattern = ''"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/ng-template" id="mediaPickerModal.html">
|
||||
|
||||
<div ng-controller="canvasdesigner.mediaPickerModal">
|
||||
|
||||
<div class="modal-header bodyCanvasdesignerImagePicker ng-scope">
|
||||
<ul class="breadcrumb">
|
||||
<li ng-if="startNodeId == -1">
|
||||
<a href="" ng-click="gotoFolder()">Media</a>
|
||||
</li>
|
||||
|
||||
<!-- ngRepeat: item in path -->
|
||||
<li ng-repeat="item in currentPath" class="ng-scope">
|
||||
/ <a ng-if="currentFolder.id == item.id" href="" ng-class="{disabled:currentFolder.id == item.id}">{{ item.name }}</a>
|
||||
<a ng-if="currentFolder.id != item.id" ng-click="gotoFolder(item)">{{ item.name }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="modal-body bodyCanvasdesignerImagePicker">
|
||||
<ul class="canvasdesignerImagePicker">
|
||||
<li>
|
||||
<ul class="media-items">
|
||||
<li ng-repeat="child in currentFolder.children | orderBy:'isFolder':true">
|
||||
<div ng-if="!child.isFolder" class="media-preview" ng-class="{selected:selectedMedia.id == child.id}" ng-click="selectMedia(child)" style="background-image: url({{ child.thumbnail }})"></div>
|
||||
<div ng-if="child.isFolder" class="media-preview" ng-click="selectMedia(child)">
|
||||
<i class="icon icon-folder folder"><p class="folder-name">{{child.name}}</p></i>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<a class="btn" href="#" ng-click="cancelAndClose()">Cancel</a>
|
||||
<a class="btn btn-success" href="#" ng-click="submitAndClose()">Done</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</script>
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
<div ng-controller="Umbraco.canvasdesigner.border" class="bordereditor">
|
||||
|
||||
<div class="box-slider">
|
||||
<ul class="box-preview">
|
||||
<li ng-repeat="border in borderList" class="border-{{border}}" ng-class="{selected: selectedBorder.name == border}" ng-click="setselectedBorder(border)"></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="box-slider" ng-repeat="border in borderList" ng-show="selectedBorder.name == border">
|
||||
<div colorpicker ng-model="item.values[(border !== 'all' ? border : '') + 'bordercolor']"></div>
|
||||
<select class="borderStyleSelect" ng-model="selectedBorder.type" ng-options="bordertype for bordertype in bordertypes"></select>
|
||||
<!--<i ng-if="selectedBorder.color != ''" ng-click="selectedBorder.color= ''" class="icon icon-delete colorPickerDelete"></i>-->
|
||||
</div>
|
||||
|
||||
<div class="box-slider">
|
||||
<div ui-slider min="0" max="40" step="1" ng-model="selectedBorder.size"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
<div class="box-slider">
|
||||
<div colorpicker ng-model="item.values.color"></div>
|
||||
</div>
|
||||
@@ -1,34 +0,0 @@
|
||||
|
||||
<div ng-controller="Umbraco.canvasdesigner.googlefontpicker">
|
||||
|
||||
<div class="box-slider">
|
||||
<div class="fontFamilyPickerPreview" ng-click="open(item.values)" ng-style="setStyleVariant()">
|
||||
<span>Aa</span>
|
||||
{{ item.values.fontFamily }}
|
||||
<i ng-if="item.values.fontFamily != ''" ng-click="item.values.fontFamily = ''" class="icon icon-delete fontPickerDelete"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/ng-template" id="googlefontdialog.html">
|
||||
|
||||
<div ng-controller="googlefontdialog.controller">
|
||||
|
||||
<div class="modal-header canvasdesigner-fontfamilypicker">
|
||||
<select class="font-list" ng-model="selectedFont" ng-change="showFontPreview(selectedFont)" ng-options="font as font.fontFamily group by font.fontType for font in fonts"></select>
|
||||
<select class="variant-list" ng-model="selectedFont.variant" ng-change="showFontPreview(selectedFont,selectedFont.variant)" ng-options="variant for variant in selectedFont.variants" />
|
||||
</div>
|
||||
|
||||
<div class="modal-body canvasdesigner-fontfamilypicker">
|
||||
<span class="show" ng-style="setStyleVariant()">Aa Bb Cc 1 2 3 4… <br />The quick brown fox jumps over the lazy dog…</span>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<a class="btn" href="#" ng-click="cancelAndClose()">Cancel</a>
|
||||
<a class="btn btn-success" href="#" ng-click="submitAndClose()">Done</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</script>
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
<div ng-controller="Umbraco.canvasdesigner.gridRow">
|
||||
|
||||
<div class="box-slider">
|
||||
<input type="checkbox" ng-model="item.values.fullsize" /><label>Full size</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
<div ng-controller="Umbraco.canvasdesigner.layout">
|
||||
|
||||
<div class="box-slider">
|
||||
<input type="radio" ng-model="item.values.layout" value="box"> Box
|
||||
<input type="radio" ng-model="item.values.layout" value="wide"> Wide
|
||||
<input type="radio" ng-model="item.values.layout" value="full"> Full
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
<div ng-controller="Umbraco.canvasdesigner.margin">
|
||||
|
||||
<div class="box-slider">
|
||||
<ul class="box-preview">
|
||||
<li ng-repeat="margin in marginList" class="border-{{margin}}" ng-class="{selected: selectedmargin.name == margin}" ng-click="setSelectedmargin(margin)"></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="box-slider">
|
||||
<div ui-slider min="0" max="400" step="1" ng-model="selectedmargin.value"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
<div ng-controller="Umbraco.canvasdesigner.padding">
|
||||
|
||||
<div class="box-slider">
|
||||
<ul class="box-preview">
|
||||
<li ng-repeat="padding in paddingList" class="border-{{padding}}" ng-class="{selected: selectedpadding.name == padding}" ng-click="setSelectedpadding(padding)"></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="box-slider">
|
||||
<div ui-slider min="0" max="400" step="1" ng-model="selectedpadding.value"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
<div ng-controller="Umbraco.canvasdesigner.radius">
|
||||
|
||||
<div class="box-slider">
|
||||
<ul class="box-preview">
|
||||
|
||||
<li ng-repeat="radius in radiusList" ng-class="{selected: selectedradius.name == radius}" ng-click="setSelectedradius(radius)">
|
||||
<span ng-show="radius == 'topleft' || radius == 'all'" class="radius-top-left"></span>
|
||||
<span ng-show="radius == 'topright' || radius == 'all'" class="radius-top-right"></span>
|
||||
<span ng-show="radius == 'bottomleft' || radius == 'all'" class="radius-bottom-left"></span>
|
||||
<span ng-show="radius == 'bottomright' || radius == 'all'" class="radius-bottom-right"></span>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="box-slider">
|
||||
<div ui-slider min="0" max="40" step="1" ng-model="selectedradius.value"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
<div ng-controller="Umbraco.canvasdesigner.shadow">
|
||||
|
||||
<div class="box-slider">
|
||||
<div ui-slider min="0" max="100" step="1" ng-model="item.values.shadow"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
<div ng-controller="Umbraco.canvasdesigner.slider">
|
||||
|
||||
<div class="box-slider">
|
||||
<div ui-slider min="{{item.min}}" max="{{item.max}}" step="1" ng-model="item.values.slider"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -1,165 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Umbraco Canvas Designer</title>
|
||||
<link href="../assets/css/canvasdesigner.css" type="text/css" rel="stylesheet" />
|
||||
<link href="../lib/spectrum/spectrum.css" type="text/css" rel="stylesheet" />
|
||||
<link href="../lib/jquery-ui/jquery-ui-1.10.4.custom.min.css" type="text/css" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body id="canvasdesignerPanel" ng-mouseover="outlinePositionHide()" ng-class="{ leftOpen: (showStyleEditor || showPalettePicker) && !showDevicesPreview }" ng-controller="Umbraco.canvasdesignerController">
|
||||
|
||||
<div class="wait" ng-show="!frameLoaded"></div>
|
||||
|
||||
<div id="demo-iframe-wrapper" ng-show="frameLoaded" class="{{previewDevice.css}}">
|
||||
<iframe id="resultFrame" ng-src="{{pageUrl}}" frameborder="0" iframe-is-loaded></iframe>
|
||||
</div>
|
||||
|
||||
<div class="canvasdesigner" ng-init="showDevicesPreview = true; showPalettePicker = true" ng-mouseenter="positionSelectedHide()">
|
||||
|
||||
<div class="fix-left-menu selected">
|
||||
|
||||
<div class="avatar">
|
||||
<img
|
||||
ng-src="../assets/img/application/logo.png"
|
||||
ng-srcset="../assets/img/application/logo@2x.png 2x,
|
||||
../assets/img/application/logo@3x.png 3x" />
|
||||
</div>
|
||||
|
||||
<ul class="sections" ng-class="{selected: showDevicesPreview}">
|
||||
<li ng-repeat="device in devices" ng-class="{ current:previewDevice==device }" ng-click="updatePreviewDevice(device)">
|
||||
<a href="#"><i class="icon {{device.icon}}" title="{{device.title}}"></i><span></span></a>
|
||||
</li>
|
||||
<li ng-click="closePreviewDevice()" ng-if="enableCanvasdesigner > 0">
|
||||
<a href="" class="more-options">
|
||||
<i></i>
|
||||
<i></i>
|
||||
<i></i>
|
||||
</a>
|
||||
</li>
|
||||
<li ng-click="exitPreview()">
|
||||
<a href="#" title="Exit Preview"><i class="icon icon-wrong"></i><span> </span></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="sections" ng-class="{selected: !showDevicesPreview}" ng-if="enableCanvasdesigner > 0">
|
||||
<li ng-click="openPreviewDevice()">
|
||||
<a href="#"><i class="icon {{previewDevice.icon}}"></i><span>Preview</span></a>
|
||||
</li>
|
||||
<li ng-click="openPalettePicker()" ng-class=" { current:showPalettePicker }">
|
||||
<a href="#"><i class="icon icon-palette"></i><span>Palette</span></a>
|
||||
</li>
|
||||
<li ng-click="openStyleEditor()" ng-class=" { current:showStyleEditor }">
|
||||
<a href="#"><i class="icon icon-paint-roller"></i><span>UI Designer</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="main-panel" ng-class="{selected: !showDevicesPreview && ( showPalettePicker || showStyleEditor )}">
|
||||
|
||||
<div class="header">
|
||||
<h3>Palette Style</h3>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<ul class="samples">
|
||||
<li ng-repeat="palette in canvasdesignerPalette">
|
||||
<a href="#" ng-click="refreshCanvasdesignerByPalette(palette)">
|
||||
<h4>{{palette.name}}</h4>
|
||||
<ul class="samples">
|
||||
<li style="background-color:{{palette.color1}}"></li>
|
||||
<li style="background-color:{{palette.color2}}"></li>
|
||||
<li style="background-color:{{palette.color3}}"></li>
|
||||
<li style="background-color:{{palette.color4}}"></li>
|
||||
<li style="background-color:{{palette.color5}}"></li>
|
||||
</ul>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-success" ng-click="saveStyle()">Save Style</a>
|
||||
<a class="btn btn-success dropdown-toggle" ng-click="opendropdown = !opendropdown">
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" ng-init="opendropdown = false" ng-show="opendropdown">
|
||||
<li><a ng-click="createStyle();opendropdown = false">Create Page Style</a></li>
|
||||
<li><a ng-click="deleteCanvasdesigner();opendropdown = false">Reset page style</a></li>
|
||||
<li><a ng-click="makePreset();opendropdown = false">Make preset</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="main-panel" ng-class="{selected: !showDevicesPreview && showStyleEditor}">
|
||||
|
||||
<div ng-show="!currentSelected">
|
||||
<div class="header">
|
||||
<h3>Select</h3>
|
||||
</div>
|
||||
<div class="content">
|
||||
<ul class="samples">
|
||||
<li ng-repeat="configItem in canvasdesignerModel.configs"
|
||||
ng-mousemove="refreshOutlinePosition(configItem)"
|
||||
ng-class="{hover: configItem.highlighted == true}"
|
||||
ng-mouseenter="setCurrentHighlighted(configItem)"
|
||||
ng-mouseleave="configItem.highlighted = false"
|
||||
ng-click="setCurrentSelected(configItem)">
|
||||
{{configItem.name}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="configItem in canvasdesignerModel.configs" ng-show="currentSelected && currentSelected.name.toLowerCase() == configItem.name.toLowerCase()
|
||||
&& currentSelected.schema.toLowerCase() == configItem.schema.toLowerCase()" on-finish-render-filters>
|
||||
<div class="header">
|
||||
<h3><i class="icon icon-list" ng-click="outlineSelectedHide()"></i> {{configItem.name}}</h3>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="editor-category" ng-repeat="category in getCategories(configItem)" ng-show="hasEditor(configItem.editors, category)">
|
||||
<h4 class="panel-title" ng-click="setSelectedCategory(category)">
|
||||
{{category}}
|
||||
<i class="icon icon-remove small right" ng-show="categoriesVisibility[category] === true"></i>
|
||||
<i class="icon icon-add small right" ng-hide="categoriesVisibility[category] === true"></i>
|
||||
</h4>
|
||||
<div class="canvasdesigner-panel-container" ng-show="categoriesVisibility[category] === true">
|
||||
<div class="canvasdesigner-panel-property" ng-repeat="item in configItem.editors" ng-show="item.category == category">
|
||||
<h5>{{item.name}} <i class="icon icon-help-alt"></i></h5>
|
||||
<div ng-include="'../preview/editors/' + item.type + '.html'"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-success" ng-click="saveStyle()">Save Style</a>
|
||||
<a class="btn btn-success dropdown-toggle" ng-click="opendropdown = !opendropdown">
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" ng-init="opendropdown = false" ng-show="opendropdown">
|
||||
<li><a ng-click="createStyle();opendropdown = false">Create Page Style</a></li>
|
||||
<li><a ng-click="deleteCanvasdesigner();opendropdown = false">Reset page style</a></li>
|
||||
<li><a ng-click="makePreset();opendropdown = false">Make preset</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="float-panel"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="speechbubble">
|
||||
<p>Styles saved and published</p>
|
||||
</div>
|
||||
|
||||
<script src="../lib/rgrove-lazyload/lazyload.js"></script>
|
||||
<script src="../js/canvasdesigner.loader.js"></script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -64,14 +64,19 @@
|
||||
};
|
||||
|
||||
scope.avatarClick = function () {
|
||||
scope.userDialog = {
|
||||
view: "user",
|
||||
show: true,
|
||||
close: function (oldModel) {
|
||||
scope.userDialog.show = false;
|
||||
scope.userDialog = null;
|
||||
}
|
||||
};
|
||||
if(!scope.userDialog) {
|
||||
scope.userDialog = {
|
||||
view: "user",
|
||||
show: true,
|
||||
close: function (oldModel) {
|
||||
scope.userDialog.show = false;
|
||||
scope.userDialog = null;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
scope.userDialog.show = false;
|
||||
scope.userDialog = null;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -125,6 +125,12 @@ Use this directive to render an umbraco button. The directive can be used to gen
|
||||
|
||||
});
|
||||
|
||||
scope.clickButton = function(event) {
|
||||
if(scope.action) {
|
||||
scope.action({$event: event});
|
||||
}
|
||||
};
|
||||
|
||||
scope.$on('$destroy', function() {
|
||||
unbindStateWatcher();
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,8 @@
|
||||
var evts = [];
|
||||
var isInfoTab = false;
|
||||
scope.publishStatus = {};
|
||||
|
||||
scope.disableTemplates = Umbraco.Sys.ServerVariables.features.disabledFeatures.disableTemplates;
|
||||
|
||||
function onInit() {
|
||||
|
||||
@@ -50,7 +52,7 @@
|
||||
|
||||
scope.openDocumentType = function (documentType) {
|
||||
var url = "/settings/documenttypes/edit/" + documentType.id;
|
||||
$location.path(url);
|
||||
$location.url(url);
|
||||
};
|
||||
|
||||
scope.updateTemplate = function (templateAlias) {
|
||||
@@ -134,13 +136,13 @@
|
||||
}
|
||||
|
||||
// published node
|
||||
if(node.hasPublishedVersion === true && node.publishDate && node.published === true) {
|
||||
if(node.publishDate && node.published === true) {
|
||||
scope.publishStatus.label = localizationService.localize("content_published");
|
||||
scope.publishStatus.color = "success";
|
||||
}
|
||||
|
||||
// published node with pending changes
|
||||
if(node.hasPublishedVersion === true && node.publishDate && node.published === false) {
|
||||
if (node.edited === true && node.publishDate) {
|
||||
scope.publishStatus.label = localizationService.localize("content_publishedPendingChanges");
|
||||
scope.publishStatus.color = "success"
|
||||
}
|
||||
@@ -149,8 +151,17 @@
|
||||
|
||||
function setPublishDate(date) {
|
||||
|
||||
if (!date) {
|
||||
return;
|
||||
}
|
||||
|
||||
//The date being passed in here is the user's local date/time that they have selected
|
||||
//we need to convert this date back to the server date on the model.
|
||||
|
||||
var serverTime = dateHelper.convertToServerStringTime(moment(date), Umbraco.Sys.ServerVariables.application.serverTimeOffset);
|
||||
|
||||
// update publish value
|
||||
scope.node.releaseDate = date;
|
||||
scope.node.releaseDate = serverTime;
|
||||
|
||||
// make sure dates are formatted to the user's locale
|
||||
formatDatesToLocal();
|
||||
@@ -174,8 +185,17 @@
|
||||
|
||||
function setUnpublishDate(date) {
|
||||
|
||||
if (!date) {
|
||||
return;
|
||||
}
|
||||
|
||||
//The date being passed in here is the user's local date/time that they have selected
|
||||
//we need to convert this date back to the server date on the model.
|
||||
|
||||
var serverTime = dateHelper.convertToServerStringTime(moment(date), Umbraco.Sys.ServerVariables.application.serverTimeOffset);
|
||||
|
||||
// update publish value
|
||||
scope.node.removeDate = date;
|
||||
scope.node.removeDate = serverTime;
|
||||
|
||||
// make sure dates are formatted to the user's locale
|
||||
formatDatesToLocal();
|
||||
@@ -223,7 +243,7 @@
|
||||
// load audit trail when on the info tab
|
||||
evts.push(eventsService.on("app.tabChange", function (event, args) {
|
||||
$timeout(function(){
|
||||
if (args.id === -1) {
|
||||
if (args.alias === "info") {
|
||||
isInfoTab = true;
|
||||
loadAuditTrail();
|
||||
} else {
|
||||
|
||||
@@ -204,7 +204,7 @@ Use this directive to construct a header inside the main editor window.
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
function EditorHeaderDirective(iconHelper) {
|
||||
function EditorHeaderDirective(iconHelper, $location) {
|
||||
|
||||
function link(scope, el, attr, ctrl) {
|
||||
|
||||
@@ -246,12 +246,9 @@ Use this directive to construct a header inside the main editor window.
|
||||
}
|
||||
};
|
||||
|
||||
scope.selectVariant = function(event, variant) {
|
||||
console.log("selec variant called");
|
||||
if(scope.onSelectVariant) {
|
||||
scope.onSelectVariant({"variant": variant});
|
||||
scope.vm.dropdownOpen = false;
|
||||
}
|
||||
scope.selectVariant = function (event, variant) {
|
||||
scope.vm.dropdownOpen = false;
|
||||
$location.search({ languageId: variant.language.id });
|
||||
};
|
||||
|
||||
scope.openIconPicker = function() {
|
||||
@@ -324,7 +321,6 @@ Use this directive to construct a header inside the main editor window.
|
||||
hideDescription: "@",
|
||||
descriptionLocked: "@",
|
||||
variants: "=",
|
||||
onSelectVariant: "&",
|
||||
navigation: "=",
|
||||
key: "=",
|
||||
onBack: "&?",
|
||||
|
||||
@@ -1,64 +1,64 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function EditorNavigationDirective() {
|
||||
function EditorNavigationDirective(eventsService) {
|
||||
|
||||
function link(scope, el, attr, ctrl) {
|
||||
function link(scope, el, attr, ctrl) {
|
||||
|
||||
scope.showNavigation = true;
|
||||
scope.showNavigation = true;
|
||||
|
||||
scope.clickNavigationItem = function(selectedItem) {
|
||||
setItemToActive(selectedItem);
|
||||
runItemAction(selectedItem);
|
||||
};
|
||||
scope.clickNavigationItem = function (selectedItem) {
|
||||
setItemToActive(selectedItem);
|
||||
runItemAction(selectedItem);
|
||||
eventsService.emit("app.tabChange", selectedItem);
|
||||
};
|
||||
|
||||
function runItemAction(selectedItem) {
|
||||
if (selectedItem.action) {
|
||||
selectedItem.action(selectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
function setItemToActive(selectedItem) {
|
||||
// set all other views to inactive
|
||||
if (selectedItem.view) {
|
||||
|
||||
for (var index = 0; index < scope.navigation.length; index++) {
|
||||
var item = scope.navigation[index];
|
||||
item.active = false;
|
||||
}
|
||||
|
||||
// set view to active
|
||||
selectedItem.active = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function activate() {
|
||||
|
||||
// hide navigation if there is only 1 item
|
||||
if (scope.navigation.length <= 1) {
|
||||
scope.showNavigation = false;
|
||||
function runItemAction(selectedItem) {
|
||||
if (selectedItem.action) {
|
||||
selectedItem.action(selectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
function setItemToActive(selectedItem) {
|
||||
// set all other views to inactive
|
||||
if (selectedItem.view) {
|
||||
|
||||
activate();
|
||||
for (var index = 0; index < scope.navigation.length; index++) {
|
||||
var item = scope.navigation[index];
|
||||
item.active = false;
|
||||
}
|
||||
|
||||
}
|
||||
// set view to active
|
||||
selectedItem.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
var directive = {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
templateUrl: 'views/components/editor/umb-editor-navigation.html',
|
||||
scope: {
|
||||
navigation: "="
|
||||
},
|
||||
link: link
|
||||
};
|
||||
function activate() {
|
||||
|
||||
return directive;
|
||||
}
|
||||
// hide navigation if there is only 1 item
|
||||
if (scope.navigation.length <= 1) {
|
||||
scope.showNavigation = false;
|
||||
}
|
||||
|
||||
angular.module('umbraco.directives.html').directive('umbEditorNavigation', EditorNavigationDirective);
|
||||
}
|
||||
|
||||
activate();
|
||||
|
||||
}
|
||||
|
||||
var directive = {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
templateUrl: 'views/components/editor/umb-editor-navigation.html',
|
||||
scope: {
|
||||
navigation: "="
|
||||
},
|
||||
link: link
|
||||
};
|
||||
|
||||
return directive;
|
||||
}
|
||||
|
||||
angular.module('umbraco.directives.html').directive('umbEditorNavigation', EditorNavigationDirective);
|
||||
|
||||
})();
|
||||
|
||||
@@ -115,7 +115,9 @@ angular.module("umbraco.directives")
|
||||
toolbar: toolbar,
|
||||
content_css: stylesheets,
|
||||
style_formats: styleFormats,
|
||||
autoresize_bottom_margin: 0
|
||||
autoresize_bottom_margin: 0,
|
||||
//see http://archive.tinymce.com/wiki.php/Configuration:cache_suffix
|
||||
cache_suffix: "?umb__rnd=" + Umbraco.Sys.ServerVariables.application.cacheBuster
|
||||
};
|
||||
|
||||
|
||||
@@ -143,6 +145,12 @@ angular.module("umbraco.directives")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (val === "true") {
|
||||
tinyMceConfig.customConfig[i] = true;
|
||||
}
|
||||
if (val === "false") {
|
||||
tinyMceConfig.customConfig[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
angular.extend(baseLineConfigObj, tinyMceConfig.customConfig);
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
</pre>
|
||||
|
||||
<h1>General Options</h1>
|
||||
Lorem ipsum dolor sit amet..
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -74,7 +73,7 @@ Lorem ipsum dolor sit amet..
|
||||
<td>Set the title of the overlay.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>model.subTitle</td>
|
||||
<td>model.subtitle</td>
|
||||
<td>String</td>
|
||||
<td>Set the subtitle of the overlay.</td>
|
||||
</tr>
|
||||
@@ -88,6 +87,11 @@ Lorem ipsum dolor sit amet..
|
||||
<td>String</td>
|
||||
<td>Set an alternate submit button label key for localized texts</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>model.submitButtonState</td>
|
||||
<td>String</td>
|
||||
<td>Set the state for the submit button</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>model.hideSubmitButton</td>
|
||||
<td>Boolean</td>
|
||||
@@ -408,7 +412,7 @@ Opens an overlay to show a custom YSOD. </br>
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
function OverlayDirective($timeout, formHelper, overlayHelper, localizationService) {
|
||||
function OverlayDirective($timeout, formHelper, overlayHelper, localizationService, $q) {
|
||||
|
||||
function link(scope, el, attr, ctrl) {
|
||||
|
||||
@@ -439,7 +443,7 @@ Opens an overlay to show a custom YSOD. </br>
|
||||
// this has to be done inside a timeout to ensure the destroy
|
||||
// event on other overlays is run before registering a new one
|
||||
registerOverlay();
|
||||
|
||||
|
||||
setOverlayIndent();
|
||||
|
||||
});
|
||||
@@ -496,6 +500,7 @@ Opens an overlay to show a custom YSOD. </br>
|
||||
var activeElementType = document.activeElement.tagName;
|
||||
var clickableElements = ["A", "BUTTON"];
|
||||
var submitOnEnter = document.activeElement.hasAttribute("overlay-submit-on-enter");
|
||||
var submitOnEnterValue = submitOnEnter ? document.activeElement.getAttribute("overlay-submit-on-enter") : "";
|
||||
|
||||
if(clickableElements.indexOf(activeElementType) === 0) {
|
||||
document.activeElement.click();
|
||||
@@ -503,7 +508,9 @@ Opens an overlay to show a custom YSOD. </br>
|
||||
} else if(activeElementType === "TEXTAREA" && !submitOnEnter) {
|
||||
|
||||
|
||||
} else {
|
||||
} else if (submitOnEnter && submitOnEnterValue === "false") {
|
||||
// don't do anything
|
||||
}else {
|
||||
scope.$apply(function () {
|
||||
scope.submitForm(scope.model);
|
||||
});
|
||||
@@ -554,8 +561,8 @@ Opens an overlay to show a custom YSOD. </br>
|
||||
var overlayWidth = el.context.clientWidth;
|
||||
|
||||
el.css('width', overlayWidth - indentSize);
|
||||
|
||||
if(scope.position === "center" || scope.position === "target") {
|
||||
|
||||
if(scope.position === "center" && overlayIndex > 0 || scope.position === "target" && overlayIndex > 0) {
|
||||
var overlayTopPosition = el.context.offsetTop;
|
||||
el.css('top', overlayTopPosition + indentSize);
|
||||
}
|
||||
@@ -630,15 +637,22 @@ Opens an overlay to show a custom YSOD. </br>
|
||||
|
||||
scope.submitForm = function(model) {
|
||||
if(scope.model.submit) {
|
||||
if (formHelper.submitForm({scope: scope})) {
|
||||
formHelper.resetForm({ scope: scope });
|
||||
|
||||
if(scope.model.confirmSubmit && scope.model.confirmSubmit.enable && !scope.directive.enableConfirmButton) {
|
||||
scope.model.submit(model, modelCopy, scope.directive.enableConfirmButton);
|
||||
} else {
|
||||
unregisterOverlay();
|
||||
scope.model.submit(model, modelCopy, scope.directive.enableConfirmButton);
|
||||
}
|
||||
if (formHelper.submitForm({ scope: scope, skipValidation: scope.model.skipFormValidation})) {
|
||||
|
||||
if (scope.model.confirmSubmit && scope.model.confirmSubmit.enable && !scope.directive.enableConfirmButton) {
|
||||
//wrap in a when since we don't know if this is a promise or not
|
||||
$q.when(scope.model.submit(model, modelCopy, scope.directive.enableConfirmButton)).then(
|
||||
function() {
|
||||
formHelper.resetForm({ scope: scope });
|
||||
}, angular.noop);
|
||||
} else {
|
||||
unregisterOverlay();
|
||||
//wrap in a when since we don't know if this is a promise or not
|
||||
$q.when(scope.model.submit(model, modelCopy, scope.directive.enableConfirmButton)).then(
|
||||
function() {
|
||||
formHelper.resetForm({ scope: scope });
|
||||
}, angular.noop);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,29 +4,32 @@
|
||||
* @restrict E
|
||||
**/
|
||||
angular.module("umbraco.directives")
|
||||
.directive('umbProperty', function (umbPropEditorHelper) {
|
||||
.directive('umbProperty', function (umbPropEditorHelper, userService) {
|
||||
return {
|
||||
scope: {
|
||||
property: "="
|
||||
},
|
||||
transclude: true,
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
replace: true,
|
||||
templateUrl: 'views/components/property/umb-property.html',
|
||||
link: function(scope) {
|
||||
scope.propertyAlias = Umbraco.Sys.ServerVariables.isDebuggingEnabled === true ? scope.property.alias : null;
|
||||
link: function (scope) {
|
||||
userService.getCurrentUser().then(function (u) {
|
||||
var isAdmin = u.userGroups.indexOf('admin') !== -1;
|
||||
scope.propertyAlias = (Umbraco.Sys.ServerVariables.isDebuggingEnabled === true || isAdmin) ? scope.property.alias : null;
|
||||
});
|
||||
},
|
||||
//Define a controller for this directive to expose APIs to other directives
|
||||
controller: function ($scope, $timeout) {
|
||||
|
||||
|
||||
var self = this;
|
||||
|
||||
//set the API properties/methods
|
||||
|
||||
|
||||
self.property = $scope.property;
|
||||
self.setPropertyError = function(errorMsg) {
|
||||
self.setPropertyError = function (errorMsg) {
|
||||
$scope.property.propertyErrorMessage = errorMsg;
|
||||
};
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@@ -420,8 +420,8 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat
|
||||
emitEvent("treeNodeAltSelect", { element: elem, tree: scope.tree, node: n, event: ev });
|
||||
};
|
||||
|
||||
//watch for section changes
|
||||
scope.$watch("section", function (newVal, oldVal) {
|
||||
//watch for section changes and customtreeparams changes
|
||||
scope.$watchCollection("[section, customtreeparams]", function (newVal, oldVal) {
|
||||
|
||||
if (!scope.tree) {
|
||||
loadTree();
|
||||
@@ -440,7 +440,7 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat
|
||||
//clear any active trees to reset lookups
|
||||
lastSection = newVal;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
setupExternalEvents();
|
||||
loadTree();
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
function link(scope, el, attr, ngModel) {
|
||||
|
||||
// Load in ace library
|
||||
assetsService.load(['lib/ace-builds/src-min-noconflict/ace.js', 'lib/ace-builds/src-min-noconflict/ext-language_tools.js']).then(function () {
|
||||
assetsService.load(['lib/ace-builds/src-min-noconflict/ace.js', 'lib/ace-builds/src-min-noconflict/ext-language_tools.js'], scope).then(function () {
|
||||
if (angular.isUndefined(window.ace)) {
|
||||
throw new Error('ui-ace need ace to work... (o rly?)');
|
||||
} else {
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
var clipboard;
|
||||
var target = element[0];
|
||||
|
||||
assetsService.loadJs("lib/clipboard/clipboard.min.js")
|
||||
assetsService.loadJs("lib/clipboard/clipboard.min.js", scope)
|
||||
.then(function () {
|
||||
|
||||
if(scope.umbClipboardTarget) {
|
||||
|
||||
@@ -92,10 +92,10 @@ Use this directive to render a date time picker
|
||||
scope.hasTranscludedContent = element.find('.js-datePicker__transcluded-content')[0].children.length > 0;
|
||||
|
||||
// load css file for the date picker
|
||||
assetsService.loadCss('lib/datetimepicker/bootstrap-datetimepicker.min.css');
|
||||
assetsService.loadCss('lib/datetimepicker/bootstrap-datetimepicker.min.css', scope);
|
||||
|
||||
// load the js file for the date picker
|
||||
assetsService.loadJs('lib/datetimepicker/bootstrap-datetimepicker.js').then(function () {
|
||||
assetsService.loadJs('lib/datetimepicker/bootstrap-datetimepicker.js', scope).then(function () {
|
||||
// init date picker
|
||||
initDatePicker();
|
||||
});
|
||||
|
||||
@@ -489,7 +489,7 @@
|
||||
|
||||
scope.editPropertyTypeSettings = function(property, group) {
|
||||
|
||||
if (!property.inherited && !property.locked) {
|
||||
if (!property.inherited) {
|
||||
|
||||
scope.propertySettingsDialogModel = {};
|
||||
scope.propertySettingsDialogModel.title = "Property settings";
|
||||
@@ -547,6 +547,7 @@
|
||||
property.validation.pattern = oldModel.property.validation.pattern;
|
||||
property.showOnMemberProfile = oldModel.property.showOnMemberProfile;
|
||||
property.memberCanEdit = oldModel.property.memberCanEdit;
|
||||
property.isSensitiveValue = oldModel.property.isSensitiveValue;
|
||||
|
||||
// because we set state to active, to show a preview, we have to check if has been filled out
|
||||
// label is required so if it is not filled we know it is a placeholder
|
||||
|
||||
@@ -10,12 +10,12 @@ function noDirtyCheck() {
|
||||
require: 'ngModel',
|
||||
link: function (scope, elm, attrs, ctrl) {
|
||||
|
||||
elm.focus(function () {
|
||||
scope.$watch(function() {
|
||||
ctrl.$pristine = false;
|
||||
});
|
||||
});
|
||||
|
||||
var alwaysFalse = {
|
||||
get: function () { return false; },
|
||||
set: function () { }
|
||||
};
|
||||
Object.defineProperty(ctrl, '$pristine', alwaysFalse);
|
||||
Object.defineProperty(ctrl, '$dirty', alwaysFalse);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -255,8 +255,6 @@ angular.module('umbraco.mocks').
|
||||
"errors_missingTitle": "Please enter a title",
|
||||
"errors_missingType": "Please choose a type",
|
||||
"errors_pictureResizeBiggerThanOrg": "You're about to make the picture larger than the original size. Are you sure that you want to proceed?",
|
||||
"errors_pythonErrorHeader": "Error in python script",
|
||||
"errors_pythonErrorText": "The python script has not been saved, because it contained error(s)",
|
||||
"errors_startNodeDoesNotExists": "Startnode deleted, please contact your administrator",
|
||||
"errors_stylesMustMarkBeforeSelect": "Please mark content before changing style",
|
||||
"errors_stylesNoStylesOnPage": "No active styles available",
|
||||
@@ -596,10 +594,6 @@ angular.module('umbraco.mocks').
|
||||
"speechBubbles_fileSavedHeader": "File saved",
|
||||
"speechBubbles_fileSavedText": "File saved without any errors",
|
||||
"speechBubbles_languageSaved": "Language saved",
|
||||
"speechBubbles_pythonErrorHeader": "Python script not saved",
|
||||
"speechBubbles_pythonErrorText": "Python script could not be saved due to error",
|
||||
"speechBubbles_pythonSavedHeader": "Python script saved",
|
||||
"speechBubbles_pythonSavedText": "No errors in python script",
|
||||
"speechBubbles_templateErrorHeader": "Template not saved",
|
||||
"speechBubbles_templateErrorText": "Please make sure that you do not have 2 templates with the same alias",
|
||||
"speechBubbles_templateSavedHeader": "Template saved",
|
||||
@@ -702,7 +696,6 @@ angular.module('umbraco.mocks').
|
||||
"treeHeaders_nodeTypes": "Document Types",
|
||||
"treeHeaders_packager": "Packages",
|
||||
"treeHeaders_packages": "Packages",
|
||||
"treeHeaders_python": "Python Files",
|
||||
"treeHeaders_repositories": "Install from repository",
|
||||
"treeHeaders_runway": "Install Runway",
|
||||
"treeHeaders_runwayModules": "Runway modules",
|
||||
|
||||
@@ -71,7 +71,7 @@ function authResource($q, $http, umbRequestHelper, angularHelper) {
|
||||
performLogin: function (username, password) {
|
||||
|
||||
if (!username || !password) {
|
||||
return angularHelper.rejectedPromise({
|
||||
return $q.reject({
|
||||
errorMsg: 'Username or password cannot be empty'
|
||||
});
|
||||
}
|
||||
@@ -125,7 +125,7 @@ function authResource($q, $http, umbRequestHelper, angularHelper) {
|
||||
performRequestPasswordReset: function (email) {
|
||||
|
||||
if (!email) {
|
||||
return angularHelper.rejectedPromise({
|
||||
return $q.reject({
|
||||
errorMsg: 'Email address cannot be empty'
|
||||
});
|
||||
}
|
||||
@@ -135,7 +135,7 @@ function authResource($q, $http, umbRequestHelper, angularHelper) {
|
||||
// be done properly.
|
||||
var emailRegex = /\S+@\S+\.\S+/;
|
||||
if (!emailRegex.test(email)) {
|
||||
return angularHelper.rejectedPromise({
|
||||
return $q.reject({
|
||||
errorMsg: 'Email address is not valid'
|
||||
});
|
||||
}
|
||||
@@ -173,13 +173,13 @@ function authResource($q, $http, umbRequestHelper, angularHelper) {
|
||||
performValidatePasswordResetCode: function (userId, resetCode) {
|
||||
|
||||
if (!userId) {
|
||||
return angularHelper.rejectedPromise({
|
||||
return $q.reject({
|
||||
errorMsg: 'User Id cannot be empty'
|
||||
});
|
||||
}
|
||||
|
||||
if (!resetCode) {
|
||||
return angularHelper.rejectedPromise({
|
||||
return $q.reject({
|
||||
errorMsg: 'Reset code cannot be empty'
|
||||
});
|
||||
}
|
||||
@@ -238,25 +238,25 @@ function authResource($q, $http, umbRequestHelper, angularHelper) {
|
||||
performSetPassword: function (userId, password, confirmPassword, resetCode) {
|
||||
|
||||
if (userId === undefined || userId === null) {
|
||||
return angularHelper.rejectedPromise({
|
||||
return $q.reject({
|
||||
errorMsg: 'User Id cannot be empty'
|
||||
});
|
||||
}
|
||||
|
||||
if (!password) {
|
||||
return angularHelper.rejectedPromise({
|
||||
return $q.reject({
|
||||
errorMsg: 'Password cannot be empty'
|
||||
});
|
||||
}
|
||||
|
||||
if (password !== confirmPassword) {
|
||||
return angularHelper.rejectedPromise({
|
||||
return $q.reject({
|
||||
errorMsg: 'Password and confirmation do not match'
|
||||
});
|
||||
}
|
||||
|
||||
if (!resetCode) {
|
||||
return angularHelper.rejectedPromise({
|
||||
return $q.reject({
|
||||
errorMsg: 'Reset code cannot be empty'
|
||||
});
|
||||
}
|
||||
@@ -276,7 +276,7 @@ function authResource($q, $http, umbRequestHelper, angularHelper) {
|
||||
|
||||
unlinkLogin: function (loginProvider, providerKey) {
|
||||
if (!loginProvider || !providerKey) {
|
||||
return angularHelper.rejectedPromise({
|
||||
return $q.reject({
|
||||
errorMsg: 'loginProvider or providerKey cannot be empty'
|
||||
});
|
||||
}
|
||||
|
||||
@@ -313,17 +313,18 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* @param {Int} id id of content item to return
|
||||
* @param {Int} id id of content item to return
|
||||
* @param {Int} languageId optional ID of the language to retrieve the item in
|
||||
* @returns {Promise} resourcePromise object containing the content item.
|
||||
*
|
||||
*/
|
||||
getById: function (id) {
|
||||
getById: function (id, languageId) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentApiBaseUrl",
|
||||
"GetById",
|
||||
[{ id: id }])),
|
||||
{ id: id, languageId: languageId })),
|
||||
'Failed to retrieve data for content id ' + id);
|
||||
},
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ function currentUserResource($q, $http, umbRequestHelper, umbDataFormatter) {
|
||||
saveTourStatus: function (tourStatus) {
|
||||
|
||||
if (!tourStatus) {
|
||||
return angularHelper.rejectedPromise({ errorMsg: 'tourStatus cannot be empty' });
|
||||
return $q.reject({ errorMsg: 'tourStatus cannot be empty' });
|
||||
}
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
@@ -37,7 +37,7 @@ function currentUserResource($q, $http, umbRequestHelper, umbDataFormatter) {
|
||||
performSetInvitedUserPassword: function (newPassword) {
|
||||
|
||||
if (!newPassword) {
|
||||
return angularHelper.rejectedPromise({ errorMsg: 'newPassword cannot be empty' });
|
||||
return $q.reject({ errorMsg: 'newPassword cannot be empty' });
|
||||
}
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name umbraco.resources.languageResource
|
||||
* @description Handles retrieving and updating language data
|
||||
**/
|
||||
function languageResource($http, umbRequestHelper) {
|
||||
return {
|
||||
|
||||
getCultures: function() {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"languageApiBaseUrl",
|
||||
"GetAllCultures")),
|
||||
"Failed to get cultures");
|
||||
},
|
||||
|
||||
getAll: function () {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"languageApiBaseUrl",
|
||||
"GetAllLanguages")),
|
||||
"Failed to get languages");
|
||||
},
|
||||
|
||||
getById: function (id) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"languageApiBaseUrl",
|
||||
"GetLanguage",
|
||||
{ id: id })),
|
||||
"Failed to get language with id " + id);
|
||||
},
|
||||
|
||||
save: function (lang) {
|
||||
if (!lang)
|
||||
throw "'lang' parameter cannot be null";
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"languageApiBaseUrl",
|
||||
"SaveLanguage"), lang),
|
||||
"Failed to save language " + lang.id);
|
||||
},
|
||||
|
||||
deleteById: function (id) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"languageApiBaseUrl",
|
||||
"DeleteLanguage",
|
||||
{ id: id })),
|
||||
"Failed to delete item " + id);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
angular.module('umbraco.resources').factory('languageResource', languageResource);
|
||||
@@ -493,7 +493,7 @@ function mediaResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
* @methodOf umbraco.resources.mediaResource
|
||||
*
|
||||
* @description
|
||||
* Empties the media recycle bin
|
||||
* Paginated search for media items starting on the supplied nodeId
|
||||
*
|
||||
* ##usage
|
||||
* <pre>
|
||||
@@ -506,7 +506,7 @@ function mediaResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
* @param {string} query The search query
|
||||
* @param {int} pageNumber The page number
|
||||
* @param {int} pageSize The number of media items on a page
|
||||
* @param {int} searchFrom Id to search from
|
||||
* @param {int} searchFrom NodeId to search from (-1 for root)
|
||||
* @returns {Promise} resourcePromise object.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -10,8 +10,8 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
|
||||
return umbRequestHelper.postSaveContent({
|
||||
restApiUrl: umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"PostSave"),
|
||||
"memberApiBaseUrl",
|
||||
"PostSave"),
|
||||
content: content,
|
||||
action: action,
|
||||
files: files,
|
||||
@@ -22,8 +22,7 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
getPagedResults: function (memberTypeAlias, options) {
|
||||
getPagedResults: function(memberTypeAlias, options) {
|
||||
|
||||
if (memberTypeAlias === 'all-members') {
|
||||
memberTypeAlias = null;
|
||||
@@ -67,35 +66,35 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
}
|
||||
|
||||
var params = [
|
||||
{ pageNumber: options.pageNumber },
|
||||
{ pageSize: options.pageSize },
|
||||
{ orderBy: options.orderBy },
|
||||
{ orderDirection: options.orderDirection },
|
||||
{ orderBySystemField: toBool(options.orderBySystemField) },
|
||||
{ filter: options.filter }
|
||||
{ pageNumber: options.pageNumber },
|
||||
{ pageSize: options.pageSize },
|
||||
{ orderBy: options.orderBy },
|
||||
{ orderDirection: options.orderDirection },
|
||||
{ orderBySystemField: toBool(options.orderBySystemField) },
|
||||
{ filter: options.filter }
|
||||
];
|
||||
if (memberTypeAlias != null) {
|
||||
params.push({ memberTypeAlias: memberTypeAlias });
|
||||
}
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"GetPagedResults",
|
||||
params)),
|
||||
'Failed to retrieve member paged result');
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"GetPagedResults",
|
||||
params)),
|
||||
'Failed to retrieve member paged result');
|
||||
},
|
||||
|
||||
getListNode: function (listName) {
|
||||
getListNode: function(listName) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"GetListNodeDisplay",
|
||||
[{ listName: listName }])),
|
||||
'Failed to retrieve data for member list ' + listName);
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"GetListNodeDisplay",
|
||||
[{ listName: listName }])),
|
||||
'Failed to retrieve data for member list ' + listName);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -119,15 +118,15 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
* @returns {Promise} resourcePromise object containing the member item.
|
||||
*
|
||||
*/
|
||||
getByKey: function (key) {
|
||||
getByKey: function(key) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"GetByKey",
|
||||
[{ key: key }])),
|
||||
'Failed to retrieve data for member id ' + key);
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"GetByKey",
|
||||
[{ key: key }])),
|
||||
'Failed to retrieve data for member id ' + key);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -150,14 +149,14 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
* @returns {Promise} resourcePromise object.
|
||||
*
|
||||
*/
|
||||
deleteByKey: function (key) {
|
||||
deleteByKey: function(key) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"DeleteByKey",
|
||||
[{ key: key }])),
|
||||
'Failed to delete item ' + key);
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"DeleteByKey",
|
||||
[{ key: key }])),
|
||||
'Failed to delete item ' + key);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -190,24 +189,24 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
* @returns {Promise} resourcePromise object containing the member scaffold.
|
||||
*
|
||||
*/
|
||||
getScaffold: function (alias) {
|
||||
getScaffold: function(alias) {
|
||||
|
||||
if (alias) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"GetEmpty",
|
||||
[{ contentTypeAlias: alias }])),
|
||||
'Failed to retrieve data for empty member item type ' + alias);
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"GetEmpty",
|
||||
[{ contentTypeAlias: alias }])),
|
||||
'Failed to retrieve data for empty member item type ' + alias);
|
||||
}
|
||||
else {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"GetEmpty")),
|
||||
'Failed to retrieve data for empty member item type ' + alias);
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"GetEmpty")),
|
||||
'Failed to retrieve data for empty member item type ' + alias);
|
||||
}
|
||||
|
||||
},
|
||||
@@ -240,7 +239,7 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
* @returns {Promise} resourcePromise object containing the saved media item.
|
||||
*
|
||||
*/
|
||||
save: function (member, isNew, files) {
|
||||
save: function(member, isNew, files) {
|
||||
return saveMember(member, "save" + (isNew ? "New" : ""), files);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name umbraco.resources.memberGroupResource
|
||||
* @description Loads in data for member groups
|
||||
**/
|
||||
function memberGroupResource($q, $http, umbRequestHelper) {
|
||||
|
||||
return {
|
||||
|
||||
//return all member types
|
||||
getGroups: function () {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberGroupApiBaseUrl",
|
||||
"GetAllGroups")),
|
||||
"Failed to retrieve data for member groups");
|
||||
},
|
||||
|
||||
getById: function (id) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberGroupApiBaseUrl",
|
||||
"GetById",
|
||||
[{ id: id }])),
|
||||
"Failed to retrieve member group");
|
||||
},
|
||||
|
||||
deleteById: function (id) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberGroupApiBaseUrl",
|
||||
"DeleteById",
|
||||
[{ id: id }])),
|
||||
"Failed to delete member group");
|
||||
},
|
||||
|
||||
getScaffold: function() {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"memberGroupApiBaseUrl",
|
||||
"GetEmpty")),
|
||||
"Failed to retrieve data for member group");
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.memberGroupResource#save
|
||||
* @methodOf umbraco.resources.memberGroupResource
|
||||
*
|
||||
* @description
|
||||
* Saves or update a member group
|
||||
*
|
||||
* @param {Object} member group object to create/update
|
||||
* @returns {Promise} resourcePromise object.
|
||||
*
|
||||
*/
|
||||
save: function (memberGroup) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(umbRequestHelper.getApiUrl("memberGroupApiBaseUrl", "PostSave"), memberGroup),
|
||||
"Failed to save data for member group, id: " + memberGroup.id);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.resources').factory('memberGroupResource', memberGroupResource);
|
||||
@@ -8,26 +8,7 @@
|
||||
*/
|
||||
function angularHelper($log, $q) {
|
||||
return {
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name umbraco.services.angularHelper#rejectedPromise
|
||||
* @methodOf umbraco.services.angularHelper
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
* In some situations we need to return a promise as a rejection, normally based on invalid data. This
|
||||
* is a wrapper to do that so we can save on writing a bit of code.
|
||||
*
|
||||
* @param {object} objReject The object to send back with the promise rejection
|
||||
*/
|
||||
rejectedPromise: function (objReject) {
|
||||
var deferred = $q.defer();
|
||||
//return an error object including the error message for UI
|
||||
deferred.reject(objReject);
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name safeApply
|
||||
@@ -153,4 +134,4 @@ function angularHelper($log, $q) {
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.services').factory('angularHelper', angularHelper);
|
||||
angular.module('umbraco.services').factory('angularHelper', angularHelper);
|
||||
|
||||
@@ -129,14 +129,12 @@ angular.module('umbraco.services')
|
||||
asset.state = "loading";
|
||||
LazyLoad.css(appendRnd(path), function () {
|
||||
if (!scope) {
|
||||
asset.state = "loaded";
|
||||
asset.deferred.resolve(true);
|
||||
} else {
|
||||
asset.state = "loaded";
|
||||
angularHelper.safeApply(scope, function () {
|
||||
asset.deferred.resolve(true);
|
||||
});
|
||||
scope = $rootScope;
|
||||
}
|
||||
asset.state = "loaded";
|
||||
angularHelper.safeApply(scope, function () {
|
||||
asset.deferred.resolve(true);
|
||||
});
|
||||
});
|
||||
} else if (asset.state === "loaded") {
|
||||
asset.deferred.resolve(true);
|
||||
@@ -171,14 +169,12 @@ angular.module('umbraco.services')
|
||||
|
||||
LazyLoad.js(appendRnd(path), function () {
|
||||
if (!scope) {
|
||||
asset.state = "loaded";
|
||||
asset.deferred.resolve(true);
|
||||
} else {
|
||||
asset.state = "loaded";
|
||||
angularHelper.safeApply(scope, function () {
|
||||
asset.deferred.resolve(true);
|
||||
});
|
||||
scope = $rootScope;
|
||||
}
|
||||
asset.state = "loaded";
|
||||
angularHelper.safeApply(scope, function () {
|
||||
asset.deferred.resolve(true);
|
||||
});
|
||||
});
|
||||
|
||||
} else if (asset.state === "loaded") {
|
||||
@@ -234,8 +230,7 @@ angular.module('umbraco.services')
|
||||
assets.push(asset);
|
||||
}
|
||||
|
||||
//we need to always push to the promises collection to monitor correct
|
||||
//execution
|
||||
//we need to always push to the promises collection to monitor correct execution
|
||||
promises.push(asset.deferred.promise);
|
||||
}
|
||||
});
|
||||
@@ -256,8 +251,7 @@ angular.module('umbraco.services')
|
||||
function assetLoaded(asset) {
|
||||
asset.state = "loaded";
|
||||
if (!scope) {
|
||||
asset.deferred.resolve(true);
|
||||
return;
|
||||
scope = $rootScope;
|
||||
}
|
||||
angularHelper.safeApply(scope,
|
||||
function () {
|
||||
@@ -280,4 +274,4 @@ angular.module('umbraco.services')
|
||||
};
|
||||
|
||||
return service;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -40,9 +40,6 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
|
||||
if (!args.content) {
|
||||
throw "args.content is not defined";
|
||||
}
|
||||
if (!args.statusMessage) {
|
||||
throw "args.statusMessage is not defined";
|
||||
}
|
||||
if (!args.saveMethod) {
|
||||
throw "args.saveMethod is not defined";
|
||||
}
|
||||
@@ -54,13 +51,11 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
|
||||
//we will use the default one for content if not specified
|
||||
var rebindCallback = args.rebindCallback === undefined ? self.reBindChangedProperties : args.rebindCallback;
|
||||
|
||||
var deferred = $q.defer();
|
||||
|
||||
if (!args.scope.busy && formHelper.submitForm({ scope: args.scope, statusMessage: args.statusMessage, action: args.action })) {
|
||||
if (!args.scope.busy && formHelper.submitForm({ scope: args.scope, action: args.action })) {
|
||||
|
||||
args.scope.busy = true;
|
||||
|
||||
args.saveMethod(args.content, $routeParams.create, fileManager.getFiles())
|
||||
return args.saveMethod(args.content, $routeParams.create, fileManager.getFiles())
|
||||
.then(function (data) {
|
||||
|
||||
formHelper.resetForm({ scope: args.scope, notifications: data.notifications });
|
||||
@@ -74,7 +69,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
|
||||
});
|
||||
|
||||
args.scope.busy = false;
|
||||
deferred.resolve(data);
|
||||
return $q.when(data);
|
||||
|
||||
}, function (err) {
|
||||
self.handleSaveError({
|
||||
@@ -91,14 +86,13 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
|
||||
}
|
||||
}
|
||||
args.scope.busy = false;
|
||||
deferred.reject(err);
|
||||
return $q.reject(err);
|
||||
});
|
||||
}
|
||||
else {
|
||||
deferred.reject();
|
||||
return $q.reject();
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
|
||||
},
|
||||
|
||||
/** Used by the content editor and media editor to add an info tab to the tabs array (normally known as the properties tab) */
|
||||
@@ -159,7 +153,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
|
||||
//publish action
|
||||
return {
|
||||
letter: ch,
|
||||
labelKey: "buttons_saveAndPublish",
|
||||
labelKey: args.content.variants && args.content.variants.length > 1 ? "buttons_saveAndPublishMany" : "buttons_saveAndPublish",
|
||||
handler: args.methods.saveAndPublish,
|
||||
hotKey: "ctrl+p",
|
||||
hotKeyWhenHidden: true,
|
||||
@@ -440,7 +434,25 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
|
||||
|
||||
//a method to ignore built-in prop changes
|
||||
var shouldIgnore = function(propName) {
|
||||
return _.some(["tabs", "notifications", "ModelState", "tabs", "properties"], function(i) {
|
||||
return _.some([
|
||||
"tabs",
|
||||
"notifications",
|
||||
"ModelState",
|
||||
"tabs",
|
||||
"properties",
|
||||
"apps",
|
||||
"createDateFormatted",
|
||||
"releaseDateYear",
|
||||
"releaseDateMonth",
|
||||
"releaseDateDayNumber",
|
||||
"releaseDateDay",
|
||||
"releaseDateTime",
|
||||
"removeDateYear",
|
||||
"removeDateMonth",
|
||||
"removeDateDayNumber",
|
||||
"removeDateDay",
|
||||
"removeDateTime",
|
||||
], function (i) {
|
||||
return i === propName;
|
||||
});
|
||||
};
|
||||
@@ -489,6 +501,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica
|
||||
*
|
||||
* @description
|
||||
* A function to handle what happens when we have validation issues from the server side
|
||||
*
|
||||
*/
|
||||
handleSaveError: function (args) {
|
||||
|
||||
|
||||
@@ -40,20 +40,12 @@ function formHelper(angularHelper, serverValidationManager, $timeout, notificati
|
||||
else {
|
||||
currentForm = args.formCtrl;
|
||||
}
|
||||
//if no statusPropertyName is set we'll default to formStatus.
|
||||
if (!args.statusPropertyName) {
|
||||
args.statusPropertyName = "formStatus";
|
||||
}
|
||||
//if no statusTimeout is set, we'll default to 2500 ms
|
||||
if (!args.statusTimeout) {
|
||||
args.statusTimeout = 2500;
|
||||
}
|
||||
|
||||
//the first thing any form must do is broadcast the formSubmitting event
|
||||
args.scope.$broadcast("formSubmitting", { scope: args.scope, action: args.action });
|
||||
|
||||
//then check if the form is valid
|
||||
if (!args.skipValidation) {
|
||||
if (!args.skipValidation) {
|
||||
if (currentForm.$invalid) {
|
||||
return false;
|
||||
}
|
||||
@@ -62,16 +54,6 @@ function formHelper(angularHelper, serverValidationManager, $timeout, notificati
|
||||
//reset the server validations
|
||||
serverValidationManager.reset();
|
||||
|
||||
//check if a form status should be set on the scope
|
||||
if (args.statusMessage) {
|
||||
args.scope[args.statusPropertyName] = args.statusMessage;
|
||||
|
||||
//clear the message after the timeout
|
||||
$timeout(function () {
|
||||
args.scope[args.statusPropertyName] = undefined;
|
||||
}, args.statusTimeout);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
@@ -95,14 +77,7 @@ function formHelper(angularHelper, serverValidationManager, $timeout, notificati
|
||||
throw "args.scope cannot be null";
|
||||
}
|
||||
|
||||
//if no statusPropertyName is set we'll default to formStatus.
|
||||
if (!args.statusPropertyName) {
|
||||
args.statusPropertyName = "formStatus";
|
||||
}
|
||||
//clear the status
|
||||
args.scope[args.statusPropertyName] = null;
|
||||
|
||||
this.showNotifications(args);
|
||||
this.showNotifications(args);
|
||||
|
||||
args.scope.$broadcast("formSubmitted", { scope: args.scope });
|
||||
},
|
||||
@@ -216,4 +191,4 @@ function formHelper(angularHelper, serverValidationManager, $timeout, notificati
|
||||
}
|
||||
};
|
||||
}
|
||||
angular.module('umbraco.services').factory('formHelper', formHelper);
|
||||
angular.module('umbraco.services').factory('formHelper', formHelper);
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function javascriptLibraryService($q, $http, umbRequestHelper) {
|
||||
|
||||
var existingLocales = [];
|
||||
|
||||
function getSupportedLocalesForMoment() {
|
||||
var deferred = $q.defer();
|
||||
|
||||
if (existingLocales.length === 0) {
|
||||
umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"backOfficeAssetsApiBaseUrl",
|
||||
"GetSupportedMomentLocales")),
|
||||
"Failed to get cultures").then(function(locales) {
|
||||
existingLocales = locales;
|
||||
deferred.resolve(existingLocales);
|
||||
});
|
||||
} else {
|
||||
deferred.resolve(existingLocales);
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
var service = {
|
||||
getSupportedLocalesForMoment: getSupportedLocalesForMoment
|
||||
};
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
angular.module("umbraco.services").factory("javascriptLibraryService", javascriptLibraryService);
|
||||
|
||||
})();
|
||||
@@ -181,11 +181,13 @@
|
||||
|
||||
var firstAllowedLayout = {};
|
||||
|
||||
for (var i = 0; layouts.length > i; i++) {
|
||||
var layout = layouts[i];
|
||||
if (layout.selected === true) {
|
||||
firstAllowedLayout = layout;
|
||||
break;
|
||||
if (layouts != null) {
|
||||
for (var i = 0; layouts.length > i; i++) {
|
||||
var layout = layouts[i];
|
||||
if (layout.selected === true) {
|
||||
firstAllowedLayout = layout;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,10 +8,39 @@
|
||||
* @description
|
||||
* Defines the methods that are called when menu items declare only an action to execute
|
||||
*/
|
||||
function umbracoMenuActions($q, treeService, $location, navigationService, appState) {
|
||||
function umbracoMenuActions($q, treeService, $location, navigationService, appState, localizationService, userResource, umbRequestHelper, notificationsService) {
|
||||
|
||||
return {
|
||||
|
||||
"ExportMember": function(args) {
|
||||
var url = umbRequestHelper.getApiUrl(
|
||||
"memberApiBaseUrl",
|
||||
"ExportMemberData",
|
||||
[{ key: args.entity.id }]);
|
||||
|
||||
umbRequestHelper.downloadFile(url).then(function() {
|
||||
localizationService.localize("speechBubbles_memberExportedSuccess").then(function (value) {
|
||||
notificationsService.success(value);
|
||||
})
|
||||
}, function(data) {
|
||||
localizationService.localize("speechBubbles_memberExportedError").then(function (value) {
|
||||
notificationsService.error(value);
|
||||
})
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
"DisableUser": function(args) {
|
||||
localizationService.localize("defaultdialogs_confirmdisable").then(function (txtConfirmDisable) {
|
||||
var currentMenuNode = UmbClientMgr.mainTree().getActionNode();
|
||||
if (confirm(txtConfirmDisable + ' "' + args.entity.name + '"?\n\n')) {
|
||||
userResource.disableUser(args.entity.id).then(function () {
|
||||
navigationService.syncTree({ tree: args.treeAlias, path: [args.entity.parentId, args.entity.id], forceReload: true });
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.services.umbracoMenuActions#RefreshNode
|
||||
|
||||
@@ -288,13 +288,16 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo
|
||||
throw "args.tree cannot be null";
|
||||
}
|
||||
|
||||
if (mainTreeEventHandler) {
|
||||
//returns a promise
|
||||
return mainTreeEventHandler.syncTree(args);
|
||||
if (mainTreeEventHandler) {
|
||||
|
||||
if (mainTreeEventHandler.syncTree) {
|
||||
//returns a promise,
|
||||
return mainTreeEventHandler.syncTree(args);
|
||||
}
|
||||
}
|
||||
|
||||
//couldn't sync
|
||||
return angularHelper.rejectedPromise();
|
||||
return $q.reject();
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
@ngdoc service
|
||||
* @name umbraco.services.overlayService
|
||||
*
|
||||
* @description
|
||||
* <b>Added in Umbraco 8.0</b>. Application-wide service for handling overlays.
|
||||
*/
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function overlayService(eventsService, backdropService) {
|
||||
|
||||
function open(overlay) {
|
||||
if(!overlay.position) {
|
||||
overlay.position = "center";
|
||||
}
|
||||
overlay.show = true;
|
||||
backdropService.open();
|
||||
eventsService.emit("appState.overlay", overlay);
|
||||
}
|
||||
|
||||
function close() {
|
||||
backdropService.close();
|
||||
eventsService.emit("appState.overlay", null);
|
||||
}
|
||||
|
||||
var service = {
|
||||
open: open,
|
||||
close: close
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco.services").factory("overlayService", overlayService);
|
||||
|
||||
})();
|
||||
@@ -56,7 +56,7 @@
|
||||
});
|
||||
|
||||
var saveProperties = _.map(realProperties, function (p) {
|
||||
var saveProperty = _.pick(p, 'id', 'alias', 'description', 'validation', 'label', 'sortOrder', 'dataTypeId', 'groupId', 'memberCanEdit', 'showOnMemberProfile');
|
||||
var saveProperty = _.pick(p, 'id', 'alias', 'description', 'validation', 'label', 'sortOrder', 'dataTypeId', 'groupId', 'memberCanEdit', 'showOnMemberProfile', 'isSensitiveData');
|
||||
return saveProperty;
|
||||
});
|
||||
|
||||
@@ -267,10 +267,10 @@
|
||||
// by looking at the key
|
||||
switch (foundAlias[0]) {
|
||||
case "umbracoMemberLockedOut":
|
||||
saveModel.isLockedOut = prop.value.toString() === "1" ? true : false;
|
||||
saveModel.isLockedOut = prop.value ? (prop.value.toString() === "1" ? true : false) : false;
|
||||
break;
|
||||
case "umbracoMemberApproved":
|
||||
saveModel.isApproved = prop.value.toString() === "1" ? true : false;
|
||||
saveModel.isApproved = prop.value ? (prop.value.toString() === "1" ? true : false) : true;
|
||||
break;
|
||||
case "umbracoMemberComments":
|
||||
saveModel.comments = prop.value;
|
||||
@@ -304,14 +304,14 @@
|
||||
_.each(tab.properties, function (prop) {
|
||||
|
||||
//don't include the custom generic tab properties
|
||||
if (!prop.alias.startsWith("_umb_")) {
|
||||
//don't include a property that is marked readonly
|
||||
if (!prop.alias.startsWith("_umb_") && !prop.readonly) {
|
||||
saveModel.properties.push({
|
||||
id: prop.id,
|
||||
alias: prop.alias,
|
||||
value: prop.value
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -324,6 +324,22 @@
|
||||
//this is basically the same as for media but we need to explicitly add some extra properties
|
||||
var saveModel = this.formatMediaPostData(displayModel, action);
|
||||
|
||||
//get the selected variant and build the additional published variants
|
||||
saveModel.publishVariations = [];
|
||||
_.each(displayModel.variants,
|
||||
function (d) {
|
||||
//set the selected variant if this is current
|
||||
if (d.current === true) {
|
||||
saveModel.languageId = d.language.id;
|
||||
}
|
||||
if (d.publish === true) {
|
||||
saveModel.publishVariations.push({
|
||||
languageId: d.language.id,
|
||||
segment: d.segment
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var propExpireDate = displayModel.removeDate;
|
||||
var propReleaseDate = displayModel.releaseDate;
|
||||
var propTemplate = displayModel.template;
|
||||
@@ -338,4 +354,4 @@
|
||||
}
|
||||
angular.module('umbraco.services').factory('umbDataFormatter', umbDataFormatter);
|
||||
|
||||
})();
|
||||
})();
|
||||
|
||||
@@ -333,6 +333,122 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
|
||||
failureCallback.apply(this, [data, status, headers, config]);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Downloads a file to the client using AJAX/XHR
|
||||
* Based on an implementation here: web.student.tuwien.ac.at/~e0427417/jsdownload.html
|
||||
* See https://stackoverflow.com/a/24129082/694494
|
||||
*/
|
||||
downloadFile : function (httpPath) {
|
||||
|
||||
var deferred = $q.defer();
|
||||
|
||||
// Use an arraybuffer
|
||||
$http.get(httpPath, { responseType: 'arraybuffer' })
|
||||
.success(function (data, status, headers) {
|
||||
|
||||
var octetStreamMime = 'application/octet-stream';
|
||||
var success = false;
|
||||
|
||||
// Get the headers
|
||||
headers = headers();
|
||||
|
||||
// Get the filename from the x-filename header or default to "download.bin"
|
||||
var filename = headers['x-filename'] || 'download.bin';
|
||||
|
||||
// Determine the content type from the header or default to "application/octet-stream"
|
||||
var contentType = headers['content-type'] || octetStreamMime;
|
||||
|
||||
try {
|
||||
// Try using msSaveBlob if supported
|
||||
console.log("Trying saveBlob method ...");
|
||||
var blob = new Blob([data], { type: contentType });
|
||||
if (navigator.msSaveBlob)
|
||||
navigator.msSaveBlob(blob, filename);
|
||||
else {
|
||||
// Try using other saveBlob implementations, if available
|
||||
var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;
|
||||
if (saveBlob === undefined) throw "Not supported";
|
||||
saveBlob(blob, filename);
|
||||
}
|
||||
console.log("saveBlob succeeded");
|
||||
success = true;
|
||||
} catch (ex) {
|
||||
console.log("saveBlob method failed with the following exception:");
|
||||
console.log(ex);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
// Get the blob url creator
|
||||
var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
|
||||
if (urlCreator) {
|
||||
// Try to use a download link
|
||||
var link = document.createElement('a');
|
||||
if ('download' in link) {
|
||||
// Try to simulate a click
|
||||
try {
|
||||
// Prepare a blob URL
|
||||
console.log("Trying download link method with simulated click ...");
|
||||
var blob = new Blob([data], { type: contentType });
|
||||
var url = urlCreator.createObjectURL(blob);
|
||||
link.setAttribute('href', url);
|
||||
|
||||
// Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
|
||||
link.setAttribute("download", filename);
|
||||
|
||||
// Simulate clicking the download link
|
||||
var event = document.createEvent('MouseEvents');
|
||||
event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||
link.dispatchEvent(event);
|
||||
console.log("Download link method with simulated click succeeded");
|
||||
success = true;
|
||||
|
||||
} catch (ex) {
|
||||
console.log("Download link method with simulated click failed with the following exception:");
|
||||
console.log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
// Fallback to window.location method
|
||||
try {
|
||||
// Prepare a blob URL
|
||||
// Use application/octet-stream when using window.location to force download
|
||||
console.log("Trying download link method with window.location ...");
|
||||
var blob = new Blob([data], { type: octetStreamMime });
|
||||
var url = urlCreator.createObjectURL(blob);
|
||||
window.location = url;
|
||||
console.log("Download link method with window.location succeeded");
|
||||
success = true;
|
||||
} catch (ex) {
|
||||
console.log("Download link method with window.location failed with the following exception:");
|
||||
console.log(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
// Fallback to window.open method
|
||||
console.log("No methods worked for saving the arraybuffer, using last resort window.open");
|
||||
window.open(httpPath, '_blank', '');
|
||||
}
|
||||
|
||||
deferred.resolve();
|
||||
})
|
||||
.error(function (data, status) {
|
||||
console.log("Request failed with status: " + status);
|
||||
|
||||
deferred.reject({
|
||||
errorMsg: "An error occurred downloading the file",
|
||||
data: data,
|
||||
status: status
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,285 +1,325 @@
|
||||
angular.module('umbraco.services')
|
||||
.factory('userService', function ($rootScope, eventsService, $q, $location, $log, securityRetryQueue, authResource, dialogService, $timeout, angularHelper, $http) {
|
||||
.factory('userService', function ($rootScope, eventsService, $q, $location, $log, securityRetryQueue, authResource, assetsService, dialogService, $timeout, angularHelper, $http, javascriptLibraryService) {
|
||||
|
||||
var currentUser = null;
|
||||
var lastUserId = null;
|
||||
var loginDialog = null;
|
||||
var currentUser = null;
|
||||
var lastUserId = null;
|
||||
var loginDialog = null;
|
||||
|
||||
//this tracks the last date/time that the user's remainingAuthSeconds was updated from the server
|
||||
// this is used so that we know when to go and get the user's remaining seconds directly.
|
||||
var lastServerTimeoutSet = null;
|
||||
//this tracks the last date/time that the user's remainingAuthSeconds was updated from the server
|
||||
// this is used so that we know when to go and get the user's remaining seconds directly.
|
||||
var lastServerTimeoutSet = null;
|
||||
|
||||
function openLoginDialog(isTimedOut) {
|
||||
if (!loginDialog) {
|
||||
loginDialog = dialogService.open({
|
||||
function openLoginDialog(isTimedOut) {
|
||||
if (!loginDialog) {
|
||||
loginDialog = dialogService.open({
|
||||
|
||||
//very special flag which means that global events cannot close this dialog
|
||||
manualClose: true,
|
||||
//very special flag which means that global events cannot close this dialog
|
||||
manualClose: true,
|
||||
|
||||
template: 'views/common/dialogs/login.html',
|
||||
modalClass: "login-overlay",
|
||||
animation: "slide",
|
||||
show: true,
|
||||
callback: onLoginDialogClose,
|
||||
dialogData: {
|
||||
isTimedOut: isTimedOut
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onLoginDialogClose(success) {
|
||||
loginDialog = null;
|
||||
|
||||
if (success) {
|
||||
securityRetryQueue.retryAll(currentUser.name);
|
||||
}
|
||||
else {
|
||||
securityRetryQueue.cancelAll();
|
||||
$location.path('/');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
This methods will set the current user when it is resolved and
|
||||
will then start the counter to count in-memory how many seconds they have
|
||||
remaining on the auth session
|
||||
*/
|
||||
function setCurrentUser(usr) {
|
||||
if (!usr.remainingAuthSeconds) {
|
||||
throw "The user object is invalid, the remainingAuthSeconds is required.";
|
||||
}
|
||||
currentUser = usr;
|
||||
lastServerTimeoutSet = new Date();
|
||||
//start the timer
|
||||
countdownUserTimeout();
|
||||
}
|
||||
|
||||
/**
|
||||
Method to count down the current user's timeout seconds,
|
||||
this will continually count down their current remaining seconds every 5 seconds until
|
||||
there are no more seconds remaining.
|
||||
*/
|
||||
function countdownUserTimeout() {
|
||||
|
||||
$timeout(function () {
|
||||
|
||||
if (currentUser) {
|
||||
//countdown by 5 seconds since that is how long our timer is for.
|
||||
currentUser.remainingAuthSeconds -= 5;
|
||||
|
||||
//if there are more than 30 remaining seconds, recurse!
|
||||
if (currentUser.remainingAuthSeconds > 30) {
|
||||
|
||||
//we need to check when the last time the timeout was set from the server, if
|
||||
// it has been more than 30 seconds then we'll manually go and retrieve it from the
|
||||
// server - this helps to keep our local countdown in check with the true timeout.
|
||||
if (lastServerTimeoutSet != null) {
|
||||
var now = new Date();
|
||||
var seconds = (now.getTime() - lastServerTimeoutSet.getTime()) / 1000;
|
||||
|
||||
if (seconds > 30) {
|
||||
|
||||
//first we'll set the lastServerTimeoutSet to null - this is so we don't get back in to this loop while we
|
||||
// wait for a response from the server otherwise we'll be making double/triple/etc... calls while we wait.
|
||||
lastServerTimeoutSet = null;
|
||||
|
||||
//now go get it from the server
|
||||
//NOTE: the safeApply because our timeout is set to not run digests (performance reasons)
|
||||
angularHelper.safeApply($rootScope, function () {
|
||||
authResource.getRemainingTimeoutSeconds().then(function (result) {
|
||||
setUserTimeoutInternal(result);
|
||||
});
|
||||
template: 'views/common/dialogs/login.html',
|
||||
modalClass: "login-overlay",
|
||||
animation: "slide",
|
||||
show: true,
|
||||
callback: onLoginDialogClose,
|
||||
dialogData: {
|
||||
isTimedOut: isTimedOut
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//recurse the countdown!
|
||||
countdownUserTimeout();
|
||||
}
|
||||
else {
|
||||
function onLoginDialogClose(success) {
|
||||
loginDialog = null;
|
||||
|
||||
//we are either timed out or very close to timing out so we need to show the login dialog.
|
||||
if (Umbraco.Sys.ServerVariables.umbracoSettings.keepUserLoggedIn !== true) {
|
||||
//NOTE: the safeApply because our timeout is set to not run digests (performance reasons)
|
||||
angularHelper.safeApply($rootScope, function () {
|
||||
try {
|
||||
//NOTE: We are calling this again so that the server can create a log that the timeout has expired, we
|
||||
// don't actually care about this result.
|
||||
authResource.getRemainingTimeoutSeconds();
|
||||
}
|
||||
finally {
|
||||
userAuthExpired();
|
||||
}
|
||||
});
|
||||
if (success) {
|
||||
securityRetryQueue.retryAll(currentUser.name);
|
||||
}
|
||||
else {
|
||||
//we've got less than 30 seconds remaining so let's check the server
|
||||
|
||||
if (lastServerTimeoutSet != null) {
|
||||
//first we'll set the lastServerTimeoutSet to null - this is so we don't get back in to this loop while we
|
||||
// wait for a response from the server otherwise we'll be making double/triple/etc... calls while we wait.
|
||||
lastServerTimeoutSet = null;
|
||||
|
||||
//now go get it from the server
|
||||
//NOTE: the safeApply because our timeout is set to not run digests (performance reasons)
|
||||
angularHelper.safeApply($rootScope, function () {
|
||||
authResource.getRemainingTimeoutSeconds().then(function (result) {
|
||||
setUserTimeoutInternal(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//recurse the countdown!
|
||||
countdownUserTimeout();
|
||||
|
||||
securityRetryQueue.cancelAll();
|
||||
$location.path('/');
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 5000, //every 5 seconds
|
||||
false); //false = do NOT execute a digest for every iteration
|
||||
}
|
||||
|
||||
/** Called to update the current user's timeout */
|
||||
function setUserTimeoutInternal(newTimeout) {
|
||||
|
||||
|
||||
var asNumber = parseFloat(newTimeout);
|
||||
if (!isNaN(asNumber) && currentUser && angular.isNumber(asNumber)) {
|
||||
currentUser.remainingAuthSeconds = newTimeout;
|
||||
lastServerTimeoutSet = new Date();
|
||||
}
|
||||
}
|
||||
|
||||
/** resets all user data, broadcasts the notAuthenticated event and shows the login dialog */
|
||||
function userAuthExpired(isLogout) {
|
||||
//store the last user id and clear the user
|
||||
if (currentUser && currentUser.id !== undefined) {
|
||||
lastUserId = currentUser.id;
|
||||
}
|
||||
|
||||
if (currentUser) {
|
||||
currentUser.remainingAuthSeconds = 0;
|
||||
}
|
||||
|
||||
lastServerTimeoutSet = null;
|
||||
currentUser = null;
|
||||
|
||||
//broadcast a global event that the user is no longer logged in
|
||||
eventsService.emit("app.notAuthenticated");
|
||||
|
||||
openLoginDialog(isLogout === undefined ? true : !isLogout);
|
||||
}
|
||||
|
||||
// Register a handler for when an item is added to the retry queue
|
||||
securityRetryQueue.onItemAddedCallbacks.push(function (retryItem) {
|
||||
if (securityRetryQueue.hasMore()) {
|
||||
userAuthExpired();
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
/** Internal method to display the login dialog */
|
||||
_showLoginDialog: function () {
|
||||
openLoginDialog();
|
||||
},
|
||||
/** Returns a promise, sends a request to the server to check if the current cookie is authorized */
|
||||
isAuthenticated: function () {
|
||||
//if we've got a current user then just return true
|
||||
if (currentUser) {
|
||||
var deferred = $q.defer();
|
||||
deferred.resolve(true);
|
||||
return deferred.promise;
|
||||
/**
|
||||
This methods will set the current user when it is resolved and
|
||||
will then start the counter to count in-memory how many seconds they have
|
||||
remaining on the auth session
|
||||
*/
|
||||
function setCurrentUser(usr) {
|
||||
if (!usr.remainingAuthSeconds) {
|
||||
throw "The user object is invalid, the remainingAuthSeconds is required.";
|
||||
}
|
||||
currentUser = usr;
|
||||
lastServerTimeoutSet = new Date();
|
||||
//start the timer
|
||||
countdownUserTimeout();
|
||||
}
|
||||
return authResource.isAuthenticated();
|
||||
},
|
||||
|
||||
/** Returns a promise, sends a request to the server to validate the credentials */
|
||||
authenticate: function (login, password) {
|
||||
/**
|
||||
Method to count down the current user's timeout seconds,
|
||||
this will continually count down their current remaining seconds every 5 seconds until
|
||||
there are no more seconds remaining.
|
||||
*/
|
||||
function countdownUserTimeout() {
|
||||
|
||||
return authResource.performLogin(login, password)
|
||||
.then(this.setAuthenticationSuccessful);
|
||||
},
|
||||
setAuthenticationSuccessful: function (data) {
|
||||
$timeout(function () {
|
||||
|
||||
//when it's successful, return the user data
|
||||
setCurrentUser(data);
|
||||
if (currentUser) {
|
||||
//countdown by 5 seconds since that is how long our timer is for.
|
||||
currentUser.remainingAuthSeconds -= 5;
|
||||
|
||||
var result = { user: data, authenticated: true, lastUserId: lastUserId, loginType: "credentials" };
|
||||
//if there are more than 30 remaining seconds, recurse!
|
||||
if (currentUser.remainingAuthSeconds > 30) {
|
||||
|
||||
//broadcast a global event
|
||||
eventsService.emit("app.authenticated", result);
|
||||
return result;
|
||||
},
|
||||
//we need to check when the last time the timeout was set from the server, if
|
||||
// it has been more than 30 seconds then we'll manually go and retrieve it from the
|
||||
// server - this helps to keep our local countdown in check with the true timeout.
|
||||
if (lastServerTimeoutSet != null) {
|
||||
var now = new Date();
|
||||
var seconds = (now.getTime() - lastServerTimeoutSet.getTime()) / 1000;
|
||||
|
||||
/** Logs the user out
|
||||
*/
|
||||
logout: function () {
|
||||
if (seconds > 30) {
|
||||
|
||||
return authResource.performLogout()
|
||||
.then(function (data) {
|
||||
userAuthExpired();
|
||||
//done!
|
||||
return null;
|
||||
});
|
||||
},
|
||||
//first we'll set the lastServerTimeoutSet to null - this is so we don't get back in to this loop while we
|
||||
// wait for a response from the server otherwise we'll be making double/triple/etc... calls while we wait.
|
||||
lastServerTimeoutSet = null;
|
||||
|
||||
/** Refreshes the current user data with the data stored for the user on the server and returns it */
|
||||
refreshCurrentUser: function() {
|
||||
var deferred = $q.defer();
|
||||
//now go get it from the server
|
||||
//NOTE: the safeApply because our timeout is set to not run digests (performance reasons)
|
||||
angularHelper.safeApply($rootScope, function () {
|
||||
authResource.getRemainingTimeoutSeconds().then(function (result) {
|
||||
setUserTimeoutInternal(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
authResource.getCurrentUser()
|
||||
.then(function (data) {
|
||||
//recurse the countdown!
|
||||
countdownUserTimeout();
|
||||
}
|
||||
else {
|
||||
|
||||
var result = { user: data, authenticated: true, lastUserId: lastUserId, loginType: "implicit" };
|
||||
|
||||
setCurrentUser(data);
|
||||
//we are either timed out or very close to timing out so we need to show the login dialog.
|
||||
if (Umbraco.Sys.ServerVariables.umbracoSettings.keepUserLoggedIn !== true) {
|
||||
//NOTE: the safeApply because our timeout is set to not run digests (performance reasons)
|
||||
angularHelper.safeApply($rootScope, function () {
|
||||
try {
|
||||
//NOTE: We are calling this again so that the server can create a log that the timeout has expired, we
|
||||
// don't actually care about this result.
|
||||
authResource.getRemainingTimeoutSeconds();
|
||||
}
|
||||
finally {
|
||||
userAuthExpired();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
//we've got less than 30 seconds remaining so let's check the server
|
||||
|
||||
deferred.resolve(currentUser);
|
||||
}, function () {
|
||||
//it failed, so they are not logged in
|
||||
deferred.reject();
|
||||
});
|
||||
if (lastServerTimeoutSet != null) {
|
||||
//first we'll set the lastServerTimeoutSet to null - this is so we don't get back in to this loop while we
|
||||
// wait for a response from the server otherwise we'll be making double/triple/etc... calls while we wait.
|
||||
lastServerTimeoutSet = null;
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
//now go get it from the server
|
||||
//NOTE: the safeApply because our timeout is set to not run digests (performance reasons)
|
||||
angularHelper.safeApply($rootScope, function () {
|
||||
authResource.getRemainingTimeoutSeconds().then(function (result) {
|
||||
setUserTimeoutInternal(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** Returns the current user object in a promise */
|
||||
getCurrentUser: function (args) {
|
||||
var deferred = $q.defer();
|
||||
//recurse the countdown!
|
||||
countdownUserTimeout();
|
||||
|
||||
if (!currentUser) {
|
||||
authResource.getCurrentUser()
|
||||
.then(function (data) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 5000, //every 5 seconds
|
||||
false); //false = do NOT execute a digest for every iteration
|
||||
}
|
||||
|
||||
var result = { user: data, authenticated: true, lastUserId: lastUserId, loginType: "implicit" };
|
||||
/** Called to update the current user's timeout */
|
||||
function setUserTimeoutInternal(newTimeout) {
|
||||
|
||||
if (args && args.broadcastEvent) {
|
||||
//broadcast a global event, will inform listening controllers to load in the user specific data
|
||||
|
||||
var asNumber = parseFloat(newTimeout);
|
||||
if (!isNaN(asNumber) && currentUser && angular.isNumber(asNumber)) {
|
||||
currentUser.remainingAuthSeconds = newTimeout;
|
||||
lastServerTimeoutSet = new Date();
|
||||
}
|
||||
}
|
||||
|
||||
/** resets all user data, broadcasts the notAuthenticated event and shows the login dialog */
|
||||
function userAuthExpired(isLogout) {
|
||||
//store the last user id and clear the user
|
||||
if (currentUser && currentUser.id !== undefined) {
|
||||
lastUserId = currentUser.id;
|
||||
}
|
||||
|
||||
if (currentUser) {
|
||||
currentUser.remainingAuthSeconds = 0;
|
||||
}
|
||||
|
||||
lastServerTimeoutSet = null;
|
||||
currentUser = null;
|
||||
|
||||
//broadcast a global event that the user is no longer logged in
|
||||
eventsService.emit("app.notAuthenticated");
|
||||
|
||||
openLoginDialog(isLogout === undefined ? true : !isLogout);
|
||||
}
|
||||
|
||||
// Register a handler for when an item is added to the retry queue
|
||||
securityRetryQueue.onItemAddedCallbacks.push(function (retryItem) {
|
||||
if (securityRetryQueue.hasMore()) {
|
||||
userAuthExpired();
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
/** Internal method to display the login dialog */
|
||||
_showLoginDialog: function () {
|
||||
openLoginDialog();
|
||||
},
|
||||
/** Returns a promise, sends a request to the server to check if the current cookie is authorized */
|
||||
isAuthenticated: function () {
|
||||
//if we've got a current user then just return true
|
||||
if (currentUser) {
|
||||
var deferred = $q.defer();
|
||||
deferred.resolve(true);
|
||||
return deferred.promise;
|
||||
}
|
||||
return authResource.isAuthenticated();
|
||||
},
|
||||
|
||||
/** Returns a promise, sends a request to the server to validate the credentials */
|
||||
authenticate: function (login, password) {
|
||||
|
||||
return authResource.performLogin(login, password)
|
||||
.then(this.setAuthenticationSuccessful);
|
||||
},
|
||||
setAuthenticationSuccessful: function (data) {
|
||||
|
||||
//when it's successful, return the user data
|
||||
setCurrentUser(data);
|
||||
|
||||
var result = { user: data, authenticated: true, lastUserId: lastUserId, loginType: "credentials" };
|
||||
|
||||
//broadcast a global event
|
||||
eventsService.emit("app.authenticated", result);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
setCurrentUser(data);
|
||||
/** Logs the user out
|
||||
*/
|
||||
logout: function () {
|
||||
|
||||
deferred.resolve(currentUser);
|
||||
}, function () {
|
||||
//it failed, so they are not logged in
|
||||
deferred.reject();
|
||||
});
|
||||
return authResource.performLogout()
|
||||
.then(function (data) {
|
||||
userAuthExpired();
|
||||
//done!
|
||||
return null;
|
||||
});
|
||||
},
|
||||
|
||||
}
|
||||
else {
|
||||
deferred.resolve(currentUser);
|
||||
}
|
||||
/** Refreshes the current user data with the data stored for the user on the server and returns it */
|
||||
refreshCurrentUser: function () {
|
||||
var deferred = $q.defer();
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
authResource.getCurrentUser()
|
||||
.then(function (data) {
|
||||
|
||||
/** Called whenever a server request is made that contains a x-umb-user-seconds response header for which we can update the user's remaining timeout seconds */
|
||||
setUserTimeout: function (newTimeout) {
|
||||
setUserTimeoutInternal(newTimeout);
|
||||
}
|
||||
};
|
||||
var result = { user: data, authenticated: true, lastUserId: lastUserId, loginType: "implicit" };
|
||||
|
||||
});
|
||||
setCurrentUser(data);
|
||||
|
||||
deferred.resolve(currentUser);
|
||||
}, function () {
|
||||
//it failed, so they are not logged in
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/** Returns the current user object in a promise */
|
||||
getCurrentUser: function (args) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
if (!currentUser) {
|
||||
authResource.getCurrentUser()
|
||||
.then(function (data) {
|
||||
|
||||
var result = { user: data, authenticated: true, lastUserId: lastUserId, loginType: "implicit" };
|
||||
|
||||
if (args && args.broadcastEvent) {
|
||||
//broadcast a global event, will inform listening controllers to load in the user specific data
|
||||
eventsService.emit("app.authenticated", result);
|
||||
}
|
||||
|
||||
setCurrentUser(data);
|
||||
|
||||
deferred.resolve(currentUser);
|
||||
}, function () {
|
||||
//it failed, so they are not logged in
|
||||
deferred.reject();
|
||||
});
|
||||
|
||||
}
|
||||
else {
|
||||
deferred.resolve(currentUser);
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/** Loads the Moment.js Locale for the current user. */
|
||||
loadMomentLocaleForCurrentUser: function () {
|
||||
|
||||
function loadLocales(currentUser, supportedLocales) {
|
||||
var locale = currentUser.locale.toLowerCase();
|
||||
if (locale !== 'en-us') {
|
||||
var localeUrls = [];
|
||||
if (supportedLocales.indexOf(locale + '.js') > -1) {
|
||||
localeUrls.push('lib/moment/' + locale + '.js');
|
||||
}
|
||||
if (locale.indexOf('-') > -1) {
|
||||
var majorLocale = locale.split('-')[0] + '.js';
|
||||
if (supportedLocales.indexOf(majorLocale) > -1) {
|
||||
localeUrls.push('lib/moment/' + majorLocale);
|
||||
}
|
||||
}
|
||||
return assetsService.load(localeUrls, $rootScope);
|
||||
}
|
||||
else {
|
||||
//return a noop promise
|
||||
var deferred = $q.defer();
|
||||
var promise = deferred.promise;
|
||||
deferred.resolve(true);
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
|
||||
var promises = {
|
||||
currentUser: this.getCurrentUser(),
|
||||
supportedLocales: javascriptLibraryService.getSupportedLocalesForMoment()
|
||||
}
|
||||
|
||||
return $q.all(promises).then(function (values) {
|
||||
return loadLocales(values.currentUser, values.supportedLocales);
|
||||
});
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
/** Called whenever a server request is made that contains a x-umb-user-seconds response header for which we can update the user's remaining timeout seconds */
|
||||
setUserTimeout: function (newTimeout) {
|
||||
setUserTimeoutInternal(newTimeout);
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
@@ -1,79 +1,79 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function usersHelperService(localizationService) {
|
||||
|
||||
var userStates = [
|
||||
{ "name": "All", "key": "All"} ,
|
||||
{ "value": 0, "name": "Active", "key": "Active", "color": "success" },
|
||||
{ "value": 1, "name": "Disabled", "key": "Disabled", "color": "danger" },
|
||||
{ "value": 2, "name": "Locked out", "key": "LockedOut", "color": "danger" },
|
||||
{ "value": 3, "name": "Invited", "key": "Invited", "color": "warning" }
|
||||
];
|
||||
|
||||
angular.forEach(userStates, function (userState) {
|
||||
var key = "user_state" + userState.key;
|
||||
localizationService.localize(key).then(function (value) {
|
||||
var reg = /^\[[\S\s]*]$/g;
|
||||
var result = reg.test(value);
|
||||
if (result === false) {
|
||||
// Only translate if key exists
|
||||
userState.name = value;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function getUserStateFromValue(value) {
|
||||
var foundUserState;
|
||||
angular.forEach(userStates, function (userState) {
|
||||
if(userState.value === value) {
|
||||
foundUserState = userState;
|
||||
}
|
||||
});
|
||||
return foundUserState;
|
||||
}
|
||||
|
||||
function getUserStateByKey(key) {
|
||||
var foundUserState;
|
||||
angular.forEach(userStates, function (userState) {
|
||||
if(userState.key === key) {
|
||||
foundUserState = userState;
|
||||
}
|
||||
});
|
||||
return foundUserState;
|
||||
}
|
||||
|
||||
function getUserStatesFilter(userStatesObject) {
|
||||
|
||||
var userStatesFilter = [];
|
||||
|
||||
for (var key in userStatesObject) {
|
||||
if (userStatesObject.hasOwnProperty(key)) {
|
||||
var userState = getUserStateByKey(key);
|
||||
if(userState) {
|
||||
userState.count = userStatesObject[key];
|
||||
userStatesFilter.push(userState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return userStatesFilter;
|
||||
|
||||
}
|
||||
|
||||
////////////
|
||||
|
||||
var service = {
|
||||
getUserStateFromValue: getUserStateFromValue,
|
||||
getUserStateByKey: getUserStateByKey,
|
||||
getUserStatesFilter: getUserStatesFilter
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
}
|
||||
|
||||
angular.module('umbraco.services').factory('usersHelper', usersHelperService);
|
||||
|
||||
|
||||
})();
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function usersHelperService(localizationService) {
|
||||
|
||||
var userStates = [
|
||||
{ "name": "All", "key": "All"} ,
|
||||
{ "value": 0, "name": "Active", "key": "Active", "color": "success" },
|
||||
{ "value": 1, "name": "Disabled", "key": "Disabled", "color": "danger" },
|
||||
{ "value": 2, "name": "Locked out", "key": "LockedOut", "color": "danger" },
|
||||
{ "value": 3, "name": "Invited", "key": "Invited", "color": "warning" }
|
||||
];
|
||||
|
||||
angular.forEach(userStates, function (userState) {
|
||||
var key = "user_state" + userState.key;
|
||||
localizationService.localize(key).then(function (value) {
|
||||
var reg = /^\[[\S\s]*]$/g;
|
||||
var result = reg.test(value);
|
||||
if (result === false) {
|
||||
// Only translate if key exists
|
||||
userState.name = value;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function getUserStateFromValue(value) {
|
||||
var foundUserState;
|
||||
angular.forEach(userStates, function (userState) {
|
||||
if(userState.value === value) {
|
||||
foundUserState = userState;
|
||||
}
|
||||
});
|
||||
return foundUserState;
|
||||
}
|
||||
|
||||
function getUserStateByKey(key) {
|
||||
var foundUserState;
|
||||
angular.forEach(userStates, function (userState) {
|
||||
if(userState.key === key) {
|
||||
foundUserState = userState;
|
||||
}
|
||||
});
|
||||
return foundUserState;
|
||||
}
|
||||
|
||||
function getUserStatesFilter(userStatesObject) {
|
||||
|
||||
var userStatesFilter = [];
|
||||
|
||||
for (var key in userStatesObject) {
|
||||
if (userStatesObject.hasOwnProperty(key)) {
|
||||
var userState = getUserStateByKey(key);
|
||||
if(userState) {
|
||||
userState.count = userStatesObject[key];
|
||||
userStatesFilter.push(userState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return userStatesFilter;
|
||||
|
||||
}
|
||||
|
||||
////////////
|
||||
|
||||
var service = {
|
||||
getUserStateFromValue: getUserStateFromValue,
|
||||
getUserStateByKey: getUserStateByKey,
|
||||
getUserStatesFilter: getUserStatesFilter
|
||||
};
|
||||
|
||||
return service;
|
||||
|
||||
}
|
||||
|
||||
angular.module('umbraco.services').factory('usersHelper', usersHelperService);
|
||||
|
||||
|
||||
})();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $
|
||||
$scope.authenticated = null;
|
||||
$scope.touchDevice = appState.getGlobalState("touchDevice");
|
||||
$scope.editors = [];
|
||||
|
||||
$scope.overlay = {};
|
||||
|
||||
$scope.removeNotification = function (index) {
|
||||
notificationsService.remove(index);
|
||||
@@ -112,6 +112,7 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $
|
||||
};
|
||||
}));
|
||||
|
||||
// events for drawer
|
||||
// manage the help dialog by subscribing to the showHelp appState
|
||||
$scope.drawer = {};
|
||||
evts.push(eventsService.on("appState.drawerState.changed", function (e, args) {
|
||||
@@ -129,6 +130,12 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $
|
||||
}
|
||||
}));
|
||||
|
||||
// events for overlays
|
||||
evts.push(eventsService.on("appState.overlay", function (name, args) {
|
||||
$scope.overlay = args;
|
||||
}));
|
||||
|
||||
// events for tours
|
||||
evts.push(eventsService.on("appState.tour.start", function (name, args) {
|
||||
$scope.tour = args;
|
||||
$scope.tour.show = true;
|
||||
@@ -142,6 +149,7 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $
|
||||
$scope.tour = null;
|
||||
}));
|
||||
|
||||
// events for backdrop
|
||||
evts.push(eventsService.on("appState.backdrop", function (name, args) {
|
||||
$scope.backdrop = args;
|
||||
}));
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* @param {navigationService} navigationService A reference to the navigationService
|
||||
*/
|
||||
function NavigationController($scope, $rootScope, $location, $log, $routeParams, $timeout, appState, navigationService, keyboardService, dialogService, historyService, eventsService, sectionResource, angularHelper) {
|
||||
function NavigationController($scope, $rootScope, $location, $log, $routeParams, $timeout, appState, navigationService, keyboardService, dialogService, historyService, eventsService, sectionResource, angularHelper, languageResource) {
|
||||
|
||||
//TODO: Need to think about this and an nicer way to acheive what this is doing.
|
||||
//the tree event handler i used to subscribe to the main tree click events
|
||||
@@ -31,6 +31,10 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams,
|
||||
$scope.menuDialogTitle = null;
|
||||
$scope.menuActions = [];
|
||||
$scope.menuNode = null;
|
||||
$scope.languages = [];
|
||||
$scope.selectedLanguage = {};
|
||||
$scope.page = {};
|
||||
$scope.page.languageSelectorIsOpen = false;
|
||||
|
||||
$scope.currentSection = appState.getSectionState("currentSection");
|
||||
$scope.showNavigation = appState.getGlobalState("showNavigation");
|
||||
@@ -98,6 +102,19 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams,
|
||||
}
|
||||
}));
|
||||
|
||||
// Listen for language updates
|
||||
evts.push(eventsService.on("editors.languages.languageDeleted", function(e, args) {
|
||||
languageResource.getAll().then(function(languages) {
|
||||
$scope.languages = languages;
|
||||
});
|
||||
}));
|
||||
|
||||
evts.push(eventsService.on("editors.languages.languageCreated", function(e, args) {
|
||||
languageResource.getAll().then(function(languages) {
|
||||
$scope.languages = languages;
|
||||
});
|
||||
}));
|
||||
|
||||
//This reacts to clicks passed to the body element which emits a global call to close all dialogs
|
||||
evts.push(eventsService.on("app.closeDialogs", function(event) {
|
||||
if (appState.getGlobalState("stickyNavigation")) {
|
||||
@@ -115,8 +132,28 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams,
|
||||
//when the application is ready and the user is authorized setup the data
|
||||
evts.push(eventsService.on("app.ready", function(evt, data) {
|
||||
$scope.authenticated = true;
|
||||
|
||||
// load languages
|
||||
languageResource.getAll().then(function(languages) {
|
||||
$scope.languages = languages;
|
||||
|
||||
// select the default language
|
||||
$scope.languages.forEach(function(language) {
|
||||
if(language.isDefault) {
|
||||
$scope.selectLanguage(language);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}));
|
||||
|
||||
$scope.selectLanguage = function(language, languages) {
|
||||
$scope.selectedLanguage = language;
|
||||
// close the language selector
|
||||
$scope.page.languageSelectorIsOpen = false;
|
||||
};
|
||||
|
||||
//this reacts to the options item in the tree
|
||||
//todo, migrate to nav service
|
||||
$scope.searchShowMenu = function (ev, args) {
|
||||
@@ -155,8 +192,8 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams,
|
||||
}
|
||||
};
|
||||
|
||||
$scope.test = function() {
|
||||
$scope.open = !$scope.open;
|
||||
$scope.toggleLanguageSelector = function() {
|
||||
$scope.page.languageSelectorIsOpen = !$scope.page.languageSelectorIsOpen;
|
||||
};
|
||||
|
||||
//ensure to unregister from all events!
|
||||
|
||||
@@ -18,14 +18,26 @@ app.run(['userService', '$log', '$rootScope', '$location', 'queryStrings', 'navi
|
||||
eventsService.on("app.authenticated", function(evt, data) {
|
||||
|
||||
assetsService._loadInitAssets().then(function() {
|
||||
|
||||
//Register all of the tours on the server
|
||||
tourService.registerAllTours().then(function (dashboards) {
|
||||
appReady(data);
|
||||
}, function(){
|
||||
appReady(data);
|
||||
});
|
||||
|
||||
// Loads the user's locale settings for Moment.
|
||||
userService.loadMomentLocaleForCurrentUser().then(function() {
|
||||
|
||||
//Register all of the tours on the server
|
||||
tourService.registerAllTours().then(function () {
|
||||
appReady(data);
|
||||
|
||||
// Auto start intro tour
|
||||
tourService.getTourByAlias("umbIntroIntroduction").then(function (introTour) {
|
||||
// start intro tour if it hasn't been completed or disabled
|
||||
if (introTour && introTour.disabled !== true && introTour.completed !== true) {
|
||||
tourService.startTour(introTour);
|
||||
}
|
||||
});
|
||||
|
||||
}, function(){
|
||||
appReady(data);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
<div>
|
||||
<h1>Upgrading Umbraco</h1>
|
||||
<p>
|
||||
Welcome to the Umbraco installer. You see this screen because your Umbraco installation needs a quick upgrade of its database and files, which will ensure your website is kept as fast, secure and up to date as possible.
|
||||
Welcome to the Umbraco installer. You see this screen because your Umbraco installation needs a quick upgrade
|
||||
of its database and files, which will ensure your website is kept as fast, secure and up to date as possible.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To read a report of changes between your current version <strong>{{installer.current.model.currentVersion}}</strong> and this version you're upgrading to <strong>{{installer.current.model.newVersion}}</strong>
|
||||
Detected current version <strong>{{installer.current.model.currentVersion}}</strong> ({{installer.current.model.currentState}}),
|
||||
which needs to be upgraded to <strong>{{installer.current.model.newVersion}}</strong> ({{installer.current.model.newState}}).
|
||||
To compare versions and read a report of changes between versions, use the <em>View Report</em> button below.
|
||||
</p>
|
||||
<p>
|
||||
<a ng-href="{{installer.current.model.reportUrl}}" target="_blank" class="btn btn-info">View Report</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Simply click <strong>continue</strong> below to be guided through the rest of the upgrade
|
||||
Simply click <strong>continue</strong> below to be guided through the rest of the upgrade.
|
||||
</p>
|
||||
<p>
|
||||
<button class="btn btn-success" ng-click="install()">Continue</button>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
angular.module("umbraco.install").controller("Umbraco.Install.UserController", function($scope, installerService) {
|
||||
|
||||
$scope.passwordPattern = /.*/;
|
||||
$scope.installer.current.model.subscribeToNewsLetter = true;
|
||||
$scope.installer.current.model.subscribeToNewsLetter = false;
|
||||
|
||||
if ($scope.installer.current.model.minNonAlphaNumericLength > 0) {
|
||||
var exp = "";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div ng-controller="Umbraco.Install.UserController">
|
||||
<h1>Install Umbraco 7</h1>
|
||||
<h1>Install Umbraco 8 (alpha)</h1>
|
||||
|
||||
<p>Enter your name, email and password to install Umbraco 7 with its default settings, alternatively you can customize your installation</p>
|
||||
<p>Enter your name, email and password to install Umbraco 8 with its default settings, alternatively you can customize your installation</p>
|
||||
|
||||
<form name="myForm" class="form-horizontal" novalidate ng-submit="validateAndInstall();">
|
||||
|
||||
|
||||
@@ -67,15 +67,14 @@
|
||||
}
|
||||
|
||||
.alert-form {
|
||||
background-color: @gray-10;
|
||||
background-color: @white;
|
||||
border: 1px solid @gray-3 !important;
|
||||
color: @gray-3;
|
||||
box-shadow: 0 -1px 6px 0 rgba(0,0,0,0.16);
|
||||
}
|
||||
|
||||
.alert-form.-no-border {
|
||||
border: none !important;
|
||||
margin-left: 1px;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.alert-form h4 {
|
||||
|
||||
@@ -62,10 +62,6 @@ body.umb-drawer-is-visible #mainwrapper{
|
||||
margin: 0
|
||||
}
|
||||
|
||||
#contentwrapper {
|
||||
top: @appHeaderHeight;
|
||||
}
|
||||
|
||||
#umb-notifications-wrapper {
|
||||
left: 80px;
|
||||
}
|
||||
@@ -87,7 +83,7 @@ body.umb-drawer-is-visible #mainwrapper{
|
||||
z-index: 1100;
|
||||
float: left;
|
||||
position: absolute;
|
||||
top: @appHeaderHeight;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
#navigation {
|
||||
@@ -98,17 +94,18 @@ body.umb-drawer-is-visible #mainwrapper{
|
||||
z-index: 100;
|
||||
background: @white;
|
||||
height: 100%;
|
||||
|
||||
}
|
||||
|
||||
.navigation-inner-container{
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
border-right: 1px solid @gray-8;
|
||||
z-index: 100;
|
||||
.navigation-inner-container {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
border-right: 1px solid @gray-9;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#dialog {
|
||||
@@ -124,6 +121,7 @@ body.umb-drawer-is-visible #mainwrapper{
|
||||
padding: 0px;
|
||||
z-index: 100 !important;
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#tree .umb-tree {
|
||||
|
||||
@@ -82,12 +82,15 @@
|
||||
|
||||
// Umbraco Components
|
||||
@import "components/application/umb-app-header.less";
|
||||
@import "components/application/umb-app-content.less";
|
||||
@import "components/application/umb-tour.less";
|
||||
@import "components/application/umb-backdrop.less";
|
||||
@import "components/application/umb-drawer.less";
|
||||
@import "components/application/umb-language-picker.less";
|
||||
@import "components/application/umb-dashboard.less";
|
||||
|
||||
@import "components/html/umb-expansion-panel.less";
|
||||
@import "components/html/umb-alert.less";
|
||||
|
||||
@import "components/editor.less";
|
||||
@import "components/overlays.less";
|
||||
@@ -173,6 +176,9 @@
|
||||
//used for property editors
|
||||
@import "property-editors.less";
|
||||
|
||||
//used for prevalue editors
|
||||
@import "components/prevalues/multivalues.less";
|
||||
|
||||
|
||||
@import "typeahead.less";
|
||||
@import "hacks.less";
|
||||
@@ -180,4 +186,4 @@
|
||||
@import "healthcheck.less";
|
||||
|
||||
// cleanup properties.less when it is done
|
||||
@import "properties.less";
|
||||
@import "properties.less";
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.umb-app-content {
|
||||
position: absolute;
|
||||
top: @appHeaderHeight;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
z-index: @zindexOverlayBackdrop;
|
||||
top: 0;
|
||||
left: 0;
|
||||
pointer-events: none;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
.umb-dashboard {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.umb-dashboard__header {
|
||||
padding: 20px 20px 0 20px;
|
||||
border-bottom: 1px solid @gray-9;
|
||||
}
|
||||
|
||||
.umb-dashboard__content {
|
||||
padding: 20px;
|
||||
overflow: auto;
|
||||
}
|
||||
@@ -1,15 +1,17 @@
|
||||
.umb-language-picker {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
z-index: @zindexDropdown;
|
||||
}
|
||||
|
||||
.umb-language-picker__toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 15px 20px;
|
||||
padding: 0 20px;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid @gray-9;
|
||||
height: 50px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.umb-language-picker__toggle:hover {
|
||||
@@ -24,9 +26,12 @@
|
||||
.umb-language-picker__dropdown {
|
||||
width: 100%;
|
||||
background: @white;
|
||||
box-shadow: 0 5px 5px rgba(0,0,0,.2);
|
||||
box-shadow: 0 3px 6px rgba(0,0,0,.16);
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
border-radius: 0 0 3px 3px;
|
||||
max-height: 200px;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.umb-language-picker__dropdown a {
|
||||
|
||||
@@ -185,3 +185,30 @@
|
||||
border: none !important;
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.umb-training-videos {
|
||||
display: grid;
|
||||
grid-gap: 10px;
|
||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||
}
|
||||
|
||||
.umb-training-video {
|
||||
background: @white;
|
||||
box-shadow: 0 1px 1px 0 rgba(0,0,0,0.16);
|
||||
border-radius: @baseBorderRadius;
|
||||
transition: box-shadow 0.1s ease-in-out, border 0.1s ease-in-out;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.umb-training-video:hover {
|
||||
box-shadow: 0 3px 6px 0 rgba(0,0,0,0.16);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.umb-training-video__label {
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -100,9 +100,9 @@ input.umb-editor-header__name-input {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
width: 100%;
|
||||
padding: 0 15px;
|
||||
background: @gray-10;
|
||||
border-radius: 3px;
|
||||
padding: 0 10px;
|
||||
background: @white;
|
||||
border: 1px solid @gray-8;
|
||||
&:hover {
|
||||
background-color: @gray-10;
|
||||
border: 1px solid @gray-8;
|
||||
@@ -127,15 +127,17 @@ a.umb-editor-header__close-split-view:hover {
|
||||
.umb-variant-switcher__toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 15px;
|
||||
padding: 0 10px;
|
||||
text-decoration: none !important;
|
||||
font-size: 13px;
|
||||
border-left: none;
|
||||
color: @gray-4;
|
||||
background-color: @gray-10;
|
||||
background-color: @white;
|
||||
border: 1px solid @gray-8;
|
||||
border-left: none;
|
||||
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
|
||||
margin-left: -1px;
|
||||
&:hover {
|
||||
background-color: @gray-9;
|
||||
background-color: @gray-10;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +159,11 @@ a.umb-editor-header__close-split-view:hover {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.umb-variant-switcher_item--current .umb-variant-switcher__name-wrapper {
|
||||
background-color: @gray-10;
|
||||
border-left: 2px solid @turquoise;
|
||||
}
|
||||
|
||||
.umb-variant-switcher__item:hover,
|
||||
.umb-variant-switcher__item:focus,
|
||||
.umb-variant-switcher__name-wrapper:hover,
|
||||
@@ -172,11 +179,11 @@ a.umb-editor-header__close-split-view:hover {
|
||||
|
||||
.umb-variant-switcher__name-wrapper {
|
||||
font-size: 14px;
|
||||
padding: 5px 20px;
|
||||
flex: 1;
|
||||
cursor: pointer;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
padding-top: 6px !important;
|
||||
padding-bottom: 6px !important;
|
||||
border-left: 2px solid transparent;
|
||||
}
|
||||
|
||||
.umb-variant-switcher__name {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
.umb-alert {
|
||||
padding: 15px;
|
||||
box-sizing: border-box;
|
||||
background-color: @turquoise-washed;
|
||||
border: 1px solid @turquoise;
|
||||
}
|
||||
|
||||
.umb-alert--info {
|
||||
background-color: @turquoise-washed;
|
||||
border: 1px solid @turquoise;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
//border: 1px solid @gray-8;
|
||||
background: @white;
|
||||
border-radius: 3px;
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.16);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.umb-notifications {
|
||||
z-index: 1000;
|
||||
position: absolute;
|
||||
bottom: 52px;
|
||||
bottom: @editorFooterHeight;
|
||||
left: 0;
|
||||
right: 0;
|
||||
border-bottom: none;
|
||||
|
||||
@@ -75,21 +75,35 @@
|
||||
/* ---------- OVERLAY CENTER ---------- */
|
||||
.umb-overlay.umb-overlay-center {
|
||||
position: absolute;
|
||||
width: 600px;
|
||||
height: 500px;
|
||||
top: 10px;
|
||||
width: 500px;
|
||||
height: auto;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: @baseBorderRadius;
|
||||
}
|
||||
|
||||
.umb-overlay.umb-overlay-center .umb-overlay-header {
|
||||
text-align: center;
|
||||
border: none;
|
||||
background: transparent;
|
||||
padding: 20px 20px 0 20px;
|
||||
}
|
||||
|
||||
.umb-overlay.umb-overlay-center .umb-overlay__form {
|
||||
max-height: 80vh;
|
||||
}
|
||||
|
||||
.umb-overlay.umb-overlay-center .umb-overlay-container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.umb-overlay.umb-overlay-center .umb-overlay-drawer {
|
||||
border: none;
|
||||
background: transparent;
|
||||
padding: 0 20px 20px 20px;
|
||||
}
|
||||
|
||||
/* ---------- OVERLAY TARGET ---------- */
|
||||
.umb-overlay.umb-overlay-target {
|
||||
width: 400px;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
height: 100%;
|
||||
background-color: rgba(255, 255, 255, 0.50);
|
||||
z-index: @zindexOverlayBackdrop;
|
||||
top: 0;
|
||||
top: @appHeaderHeight;
|
||||
left: 0;
|
||||
animation: fadeIn 0.2s;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
.umb-prevalues-multivalues {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.umb-prevalues-multivalues__left {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.umb-prevalues-multivalues__right {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.umb-prevalues-multivalues__add {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.umb-prevalues-multivalues__add input {
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
.umb-prevalues-multivalues__add input {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.umb-prevalues-multivalues__add button {
|
||||
margin: 0 6px 0 0;
|
||||
float: right
|
||||
}
|
||||
|
||||
.umb-prevalues-multivalues__listitem {
|
||||
display: flex;
|
||||
padding: 6px;
|
||||
margin: 10px 0px !important;
|
||||
background: #F3F3F5;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.umb-prevalues-multivalues__listitem i {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 5px
|
||||
}
|
||||
|
||||
.umb-prevalues-multivalues__listitem a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.umb-prevalues-multivalues__listitem input {
|
||||
width: 295px;
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
.umb-box-header {
|
||||
padding: 10px 20px;
|
||||
border-bottom: 1px solid @gray-9;
|
||||
}
|
||||
|
||||
.umb-box-header-title {
|
||||
@@ -24,5 +25,4 @@
|
||||
|
||||
.umb-box-content {
|
||||
padding: 20px;
|
||||
border-top: 1px solid @gray-9;
|
||||
}
|
||||
@@ -280,7 +280,6 @@
|
||||
.umb-grid .umb-control {
|
||||
position: relative;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
@@ -426,103 +426,114 @@ input.umb-group-builder__group-title-input {
|
||||
|
||||
.content-type-editor-dialog.edit-property-settings {
|
||||
|
||||
.validation-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.validation-label {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
font-size: 12px;
|
||||
color: @red;
|
||||
transform: translate(0, -50%);
|
||||
}
|
||||
|
||||
textarea.editor-label {
|
||||
border-color:transparent;
|
||||
box-shadow: none;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 0;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
resize: none;
|
||||
line-height: 1.5em;
|
||||
padding-left: 0;
|
||||
border: none;
|
||||
&:focus {
|
||||
outline: none;
|
||||
box-shadow: none !important;
|
||||
.validation-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.editor-placeholder {
|
||||
border: 1px dashed @gray-8;
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
line-height: 80px;
|
||||
text-align: center;
|
||||
display: block;
|
||||
border-radius: 5px;
|
||||
color: @gray-3;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: @turquoise-d1;
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.editor {
|
||||
margin-bottom: 10px;
|
||||
.editor-icon-wrapper {
|
||||
border: 1px solid @gray-8;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
line-height: 60px;
|
||||
border-radius: 5px;
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
.icon {
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
.editor-details {
|
||||
float: left;
|
||||
margin-top: 10px;
|
||||
.editor-name {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
}
|
||||
.editor-editor {
|
||||
display: block;
|
||||
.validation-label {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
color: @red;
|
||||
transform: translate(0, -50%);
|
||||
}
|
||||
.editor-settings-icon {
|
||||
font-size: 18px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
textarea.editor-label {
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 0;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
resize: none;
|
||||
line-height: 1.5em;
|
||||
padding-left: 0;
|
||||
border: none;
|
||||
|
||||
.editor-description,
|
||||
.editor-validation-pattern {
|
||||
min-width: 100%;
|
||||
min-height: 25px;
|
||||
resize: none;
|
||||
box-sizing: border-box;
|
||||
border: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
&:focus {
|
||||
outline: none;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-dropdown {
|
||||
width: 100%;
|
||||
}
|
||||
.editor-placeholder {
|
||||
border: 1px dashed @gray-8;
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
line-height: 80px;
|
||||
text-align: center;
|
||||
display: block;
|
||||
border-radius: 5px;
|
||||
color: @gray-3;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: @turquoise-d1;
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.editor {
|
||||
margin-bottom: 10px;
|
||||
|
||||
.editor-icon-wrapper {
|
||||
border: 1px solid @gray-8;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
line-height: 60px;
|
||||
border-radius: 5px;
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
|
||||
.icon {
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
.editor-details {
|
||||
float: left;
|
||||
margin-top: 10px;
|
||||
|
||||
.editor-name {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.editor-editor {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.editor-settings-icon {
|
||||
font-size: 18px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.editor-description,
|
||||
.editor-validation-pattern {
|
||||
min-width: 100%;
|
||||
min-height: 25px;
|
||||
resize: none;
|
||||
box-sizing: border-box;
|
||||
border: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.umb-dropdown {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
label.checkbox.no-indent {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
.umb-list--condensed {
|
||||
.umb-list-item {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-list-item {
|
||||
border-bottom: 1px solid @gray-9;
|
||||
padding-top: 15px;
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
}
|
||||
50% {
|
||||
transform: scale(1);
|
||||
background: white;
|
||||
background: transparent;
|
||||
}
|
||||
100% {
|
||||
transform: scale(0.5);
|
||||
|
||||
@@ -1,15 +1,3 @@
|
||||
.umb-nav-tabs {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.umb-nav-tabs.-padding-left {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.umb-tab-content {
|
||||
padding-top: 20px;
|
||||
position: relative;
|
||||
top: 22px;
|
||||
border-top: 1px solid @purple-l3;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
padding: 7px 0;
|
||||
}
|
||||
|
||||
.umb-permission--disabled {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.umb-permission:last-of-type {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
@@ -24,17 +24,18 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
background: @gray-10;
|
||||
background: @white;
|
||||
border-radius: 3px;
|
||||
padding: 15px 10px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
border: 1px solid @gray-8;
|
||||
box-shadow: 0 1px 1px 0 rgba(0,0,0,0.16);
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.umb-healthcheck-group:hover {
|
||||
border: 1px solid @turquoise;
|
||||
box-shadow: 0 3px 6px 0 rgba(0,0,0,0.16);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -60,7 +61,7 @@
|
||||
|
||||
.umb-healthcheck-message {
|
||||
position: relative;
|
||||
background: @white;
|
||||
background: @gray-10;
|
||||
border-radius: 50px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -125,6 +126,12 @@
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.umb-healthcheck-group__details-group {
|
||||
background: @white;
|
||||
box-shadow: 0 1px 1px 0 rgba(0,0,0,0.16);
|
||||
border-radius: @baseBorderRadius;
|
||||
}
|
||||
|
||||
.umb-healthcheck-group__details-group-title {
|
||||
background-color: @purple-l1;
|
||||
padding: 10px 20px;
|
||||
@@ -141,9 +148,9 @@
|
||||
}
|
||||
|
||||
.umb-healthcheck-group__details-checks {
|
||||
border: 1px solid @gray-8;
|
||||
border-top: none;
|
||||
border-radius: 0 0 3px 3px;
|
||||
background: @white;
|
||||
}
|
||||
|
||||
.umb-healthcheck-group__details-check {
|
||||
@@ -152,14 +159,13 @@
|
||||
|
||||
.umb-healthcheck-group__details-check-title {
|
||||
padding: 15px 20px;
|
||||
background-color: @gray-10;
|
||||
}
|
||||
|
||||
.umb-healthcheck-group__details-check-name {
|
||||
font-size: 15px;
|
||||
color: @black;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.umb-healthcheck-group__details-check-description {
|
||||
@@ -171,7 +177,7 @@
|
||||
.umb-healthcheck-group__details-status {
|
||||
padding: 15px 0;
|
||||
display: flex;
|
||||
border-bottom: 2px solid @gray-10;
|
||||
border-top: 2px solid @gray-10;
|
||||
}
|
||||
|
||||
.umb-healthcheck-group__details-status-overlay {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
min-height: 100%;
|
||||
}
|
||||
.shadow {
|
||||
box-shadow: 3px 0px 7px @gray-8;
|
||||
box-shadow: 3px 0px 7px rgba(0,0,0,0.16);
|
||||
}
|
||||
|
||||
.umb-scrollable, .umb-auto-overflow {
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
}
|
||||
|
||||
.umb-modalcolumn-header {
|
||||
background: @gray-10;
|
||||
border-bottom: 1px solid @purple-l3;
|
||||
height: 94px;
|
||||
padding: 5px 20px 0px 20px;
|
||||
border-bottom: 1px solid @gray-9;
|
||||
height: @editorHeaderHeight;
|
||||
box-sizing: border-box;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
@@ -19,13 +21,12 @@
|
||||
white-space: nowrap;
|
||||
font-size: @fontSizeLarge;
|
||||
font-weight: 400;
|
||||
padding-top: 10px !important;
|
||||
}
|
||||
|
||||
.umb-modalcolumn-body {
|
||||
padding: 0px;
|
||||
background: @white;
|
||||
top: 100px;
|
||||
top: @editorHeaderHeight;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
@@ -181,7 +182,7 @@
|
||||
width: 640px !important;
|
||||
}
|
||||
.umb-modal i {
|
||||
font-size: 14px;
|
||||
font-size: 20px;
|
||||
}
|
||||
.umb-modal .breadcrumb {
|
||||
background: none;
|
||||
|
||||
@@ -109,11 +109,7 @@
|
||||
}
|
||||
.nav-tabs > li > a,
|
||||
.nav-pills > li > a {
|
||||
padding-right: 8px;
|
||||
padding-left: 8px;
|
||||
margin-right: 2px;
|
||||
line-height: 14px; // keeps the overall height an even number
|
||||
border-radius: 3px 3px 0 0;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
// TABS
|
||||
@@ -121,26 +117,24 @@
|
||||
|
||||
// Give the tabs something to sit on
|
||||
.nav-tabs {
|
||||
border-bottom: 1px solid @purple-l3;
|
||||
// border-bottom: 1px solid @gray-9;
|
||||
}
|
||||
// Make the list-items overlay the bottom border
|
||||
.nav-tabs > li {
|
||||
margin-bottom: -1px;
|
||||
// margin-bottom: -1px;
|
||||
}
|
||||
// Actual tabs (as links)
|
||||
.nav-tabs > li > a {
|
||||
color: @gray-3;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 4px;
|
||||
line-height: @baseLineHeight;
|
||||
border: 1px solid transparent;
|
||||
border-bottom: 2px solid transparent;
|
||||
padding-bottom: 15px;
|
||||
|
||||
&:hover {
|
||||
color: @black;
|
||||
}
|
||||
&:hover,
|
||||
&:focus {
|
||||
border-color: transparent transparent @purple-l3;
|
||||
// border-color: transparent transparent @purple-l3;
|
||||
}
|
||||
}
|
||||
// Active state, and it's :hover/:focus to override normal :hover/:focus
|
||||
@@ -148,9 +142,7 @@
|
||||
.nav-tabs > .active > a:hover,
|
||||
.nav-tabs > .active > a:focus {
|
||||
color: @black;
|
||||
background-color: @bodyBackground;
|
||||
border: 1px solid @purple-l3;
|
||||
border-bottom-color: transparent;
|
||||
border-bottom-color: @turquoise;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
@@ -175,10 +167,6 @@
|
||||
.show-validation .nav-tabs > li.active.error > a:focus {
|
||||
}
|
||||
|
||||
.umb-nav-tabs {
|
||||
margin: -8px 0 0 0;
|
||||
}
|
||||
|
||||
// PILLS
|
||||
// -----
|
||||
|
||||
@@ -247,6 +235,8 @@
|
||||
.dropdown-menu {
|
||||
border-radius: @dropdownBorderRadius;
|
||||
box-shadow: 0 5px 20px rgba(0,0,0,.3);
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
// fix dropdown with checkbox + long text in label
|
||||
|
||||
@@ -74,10 +74,6 @@
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.login-overlay .btn-success {
|
||||
padding: 12px 24px;
|
||||
}
|
||||
|
||||
.login-overlay .form label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@@ -428,10 +428,6 @@
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.umb-panel-header .umb-nav-tabs {
|
||||
bottom: -1px;
|
||||
}
|
||||
|
||||
input.umb-panel-header-name-input.name-is-empty {
|
||||
border: 1px dashed @gray-8;
|
||||
background: @white;
|
||||
|
||||
@@ -40,6 +40,16 @@
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.umb-contentpicker__min-max-help {
|
||||
font-size: 13px;
|
||||
margin-top: 5px;
|
||||
color: @gray-4;
|
||||
}
|
||||
|
||||
.show-validation .umb-contentpicker__min-max-help {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.umb-contentpicker small {
|
||||
|
||||
&:not(:last-child) {
|
||||
@@ -203,10 +213,22 @@ ul.color-picker li a {
|
||||
|
||||
|
||||
|
||||
.umb-thumbnails{
|
||||
position: relative;
|
||||
.umb-thumbnails {
|
||||
position: relative;
|
||||
display: flex;
|
||||
-ms-flex-direction: row;
|
||||
-webkit-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-ms-flex-wrap: wrap;
|
||||
-webkit-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.umb-thumbnails > li.icon {
|
||||
width: 14%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.umb-thumbnails i{margin: auto;}
|
||||
.umb-thumbnails a{
|
||||
@@ -243,7 +265,7 @@ ul.color-picker li a {
|
||||
|
||||
.umb-mediapicker .umb-sortable-thumbnails li {
|
||||
flex-direction: column;
|
||||
margin: 0 5px 0 0;
|
||||
margin: 0 5px 5px 0;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
@@ -282,8 +304,8 @@ ul.color-picker li a {
|
||||
}
|
||||
|
||||
.umb-sortable-thumbnails .umb-sortable-thumbnails__wrapper {
|
||||
width: 120px;
|
||||
height: 114px;
|
||||
width: 124px;
|
||||
height: 124px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@@ -298,6 +320,12 @@ ul.color-picker li a {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.umb-sortable-thumbnails.ui-sortable:not(.ui-sortable-disabled) {
|
||||
> li:not(.unsortable) {
|
||||
cursor: move;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-sortable-thumbnails li:hover .umb-sortable-thumbnails__actions {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
|
||||
@@ -13,22 +13,20 @@ table {
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
table thead {
|
||||
background-color: @gray-10;
|
||||
}
|
||||
|
||||
|
||||
// BASELINE STYLES
|
||||
// ---------------
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
margin-bottom: @baseLineHeight;
|
||||
border: 1px solid @gray-8;
|
||||
box-shadow: 0 1px 1px 0 rgba(0,0,0,0.16);
|
||||
background: @tableBackground;
|
||||
border-radius: @baseBorderRadius;
|
||||
font-size: 14px;
|
||||
// Cells
|
||||
th,
|
||||
td {
|
||||
padding: 10px 8px;
|
||||
padding: 10px 20px;
|
||||
line-height: @baseLineHeight;
|
||||
text-align: left;
|
||||
border-top: 1px solid @tableBorder;
|
||||
@@ -38,6 +36,9 @@ table thead {
|
||||
}
|
||||
// Bottom align for column headings
|
||||
thead th {
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
color: @gray-3;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
// Remove top border from thead by default
|
||||
@@ -81,6 +82,7 @@ table thead {
|
||||
border-collapse: separate; // Done so we can round those corners!
|
||||
*border-collapse: collapse; // IE7 can't round corners anyway
|
||||
border-left: 0;
|
||||
box-shadow: none;
|
||||
.border-radius(@baseBorderRadius);
|
||||
th,
|
||||
td {
|
||||
|
||||
@@ -100,6 +100,27 @@
|
||||
.color-green, .color-green i{color: @green-d1 !important;}
|
||||
.color-yellow, .color-yellow i{color: @yellow-d1 !important;}
|
||||
|
||||
/* Colors based on http://zavoloklom.github.io/material-design-color-palette/colors.html */
|
||||
.color-black, .color-black i { color: #000 !important; }
|
||||
.color-blue-grey, .color-blue-grey i { color: #607d8b !important; }
|
||||
.color-grey, .color-grey i { color: #9e9e9e !important; }
|
||||
.color-brown, .color-brown i { color: #795548 !important; }
|
||||
.color-blue, .color-blue i { color: #2196f3 !important; }
|
||||
.color-light-blue, .color-light-blue i {color: #03a9f4 !important; }
|
||||
.color-cyan, .color-cyan i { color: #00bcd4 !important; }
|
||||
.color-green, .color-green i { color: #4caf50 !important; }
|
||||
.color-light-green, .color-light-green i {color: #8bc34a !important; }
|
||||
.color-lime, .color-lime i { color: #cddc39 !important; }
|
||||
.color-yellow, .color-yellow i { color: #ffeb3b !important; }
|
||||
.color-amber, .color-amber i { color: #ffc107 !important; }
|
||||
.color-orange, .color-orange i { color: #ff9800 !important; }
|
||||
.color-deep-orange, .color-deep-orange i { color: #ff5722 !important; }
|
||||
.color-red, .color-red i { color: #f44336 !important; }
|
||||
.color-pink, .color-pink i { color: #e91e63 !important; }
|
||||
.color-purple,.color-purple i { color: #9c27b0 !important; }
|
||||
.color-deep-purple, .color-deep-purple i { color: #673ab7 !important; }
|
||||
.color-indigo, .color-indigo i { color: #3f51b5 !important; }
|
||||
|
||||
|
||||
// Scaffolding
|
||||
// -------------------------
|
||||
@@ -154,10 +175,10 @@
|
||||
|
||||
// Tables
|
||||
// -------------------------
|
||||
@tableBackground: transparent; // overall background-color
|
||||
@tableBackground: @white; // overall background-color
|
||||
@tableBackgroundAccent: @gray-10; // for striping
|
||||
@tableBackgroundHover: @gray-10; // for hover
|
||||
@tableBorder: @gray-8; // table and cell border
|
||||
@tableBorder: @gray-9; // table and cell border
|
||||
|
||||
// Buttons
|
||||
// -------------------------
|
||||
@@ -231,6 +252,7 @@
|
||||
// -------------------------
|
||||
// Used for a bird's eye view of components dependent on the z-axis
|
||||
// Try to avoid customizing these :)
|
||||
@zIndexTree: 100;
|
||||
@zindexDropdown: 1000;
|
||||
@zindexPopover: 1010;
|
||||
@zindexTooltip: 1030;
|
||||
|
||||
@@ -1,51 +1,41 @@
|
||||
<div ng-controller="Umbraco.DashboardController">
|
||||
|
||||
<umb-load-indicator ng-if="page.loading"></umb-load-indicator>
|
||||
<form name="dashboardForm" val-form-manager>
|
||||
|
||||
<form
|
||||
ng-show="!page.loading"
|
||||
class="umb-dashboard"
|
||||
val-form-manager>
|
||||
<umb-load-indicator ng-show="page.loading"></umb-load-indicator>
|
||||
|
||||
<umb-editor-view
|
||||
footer="false"
|
||||
umb-tabs>
|
||||
<div class="umb-dashboard" ng-if="!page.loading">
|
||||
|
||||
<umb-editor-header
|
||||
name="dashboard.name"
|
||||
name-locked="page.nameLocked"
|
||||
tabs="dashboard.tabs"
|
||||
hide-icon="true"
|
||||
hide-description="true"
|
||||
hide-alias="true">
|
||||
</umb-editor-header>
|
||||
<div class="umb-dashboard__header" ng-show="dashboard.tabs.length > 1">
|
||||
<umb-tabs-nav ng-if="dashboard.tabs" model="dashboard.tabs" style="margin-bottom: 0;"></umb-tabs-nav>
|
||||
</div>
|
||||
|
||||
<umb-editor-container>
|
||||
<div class="umb-dashboard__content">
|
||||
|
||||
<umb-tabs-content view="true">
|
||||
<umb-tab id="tab{{tab.id}}" ng-repeat="tab in dashboard.tabs" rel="{{tab.id}}">
|
||||
<umb-tabs-content view="true">
|
||||
<umb-tab id="tab{{tab.id}}" ng-repeat="tab in dashboard.tabs" rel="{{tab.id}}" class="row-fluid">
|
||||
|
||||
<div ng-repeat="property in tab.properties" ng-switch on="property.serverSide">
|
||||
|
||||
<div class="clearfix" ng-switch-when="false">
|
||||
<h3 ng-show="property.caption">{{property.caption}}</h3>
|
||||
<div ng-include="property.path"></div>
|
||||
</div>
|
||||
|
||||
<div class="umb-dashboard-control clearfix" ng-switch-when="true">
|
||||
<h3 ng-show="property.caption">{{property.caption}}</h3>
|
||||
<iframe ng-src="dashboard/usercontrolproxy.aspx?ctrl={{ property.path}}"></iframe>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</umb-tab>
|
||||
</umb-tabs-content>
|
||||
|
||||
<div ng-repeat="property in tab.properties" ng-switch on="property.serverSide">
|
||||
</div>
|
||||
|
||||
<div class="span12 clearfix" ng-switch-when="false">
|
||||
<h3 ng-show="property.caption">{{property.caption}}</h3>
|
||||
<div ng-include="property.path"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="span12 umb-dashboard-control clearfix" ng-switch-when="true">
|
||||
<h3 ng-show="property.caption">{{property.caption}}</h3>
|
||||
|
||||
<iframe ng-src="dashboard/usercontrolproxy.aspx?ctrl={{ property.path}}"></iframe>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</umb-tab>
|
||||
</umb-tabs-content>
|
||||
|
||||
</umb-editor-container>
|
||||
|
||||
</umb-editor-view>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user