Merge remote-tracking branch 'origin/v8/dev' into grid-editor-name-templates
This commit is contained in:
@@ -3,26 +3,26 @@
|
||||
module.exports = {
|
||||
sources: {
|
||||
|
||||
//less files used by backoffice and preview
|
||||
//processed in the less task
|
||||
// less files used by backoffice and preview
|
||||
// processed in the less task
|
||||
less: {
|
||||
installer: { files: ["./src/less/installer.less"], out: "installer.css" },
|
||||
nonodes: { files: ["./src/less/pages/nonodes.less"], out: "nonodes.style.min.css"},
|
||||
preview: { files: ["./src/less/canvas-designer.less"], out: "canvasdesigner.css" },
|
||||
umbraco: { files: ["./src/less/belle.less"], out: "umbraco.css" },
|
||||
rteContent: { files: ["./src/less/rte-content.less"], out: "rte-content.css" }
|
||||
installer: { files: "./src/less/installer.less", watch: "./src/less/**/*.less", out: "installer.css" },
|
||||
nonodes: { files: "./src/less/pages/nonodes.less", watch: "./src/less/**/*.less", out: "nonodes.style.min.css"},
|
||||
preview: { files: "./src/less/canvas-designer.less", watch: "./src/less/**/*.less", out: "canvasdesigner.css" },
|
||||
umbraco: { files: "./src/less/belle.less", watch: "./src/less/**/*.less", out: "umbraco.css" },
|
||||
rteContent: { files: "./src/less/rte-content.less", watch: "./src/less/**/*.less", out: "rte-content.css" }
|
||||
},
|
||||
|
||||
//js files for backoffie
|
||||
//processed in the js task
|
||||
// js files for backoffice
|
||||
// processed in the js task
|
||||
js: {
|
||||
preview: { files: ["./src/preview/**/*.js"], out: "umbraco.preview.js" },
|
||||
installer: { files: ["./src/installer/**/*.js"], out: "umbraco.installer.js" },
|
||||
filters: { files: ["./src/common/filters/**/*.js"], out: "umbraco.filters.js" },
|
||||
resources: { files: ["./src/common/resources/**/*.js"], out: "umbraco.resources.js" },
|
||||
services: { files: ["./src/common/services/**/*.js"], out: "umbraco.services.js" },
|
||||
security: { files: ["./src/common/interceptors/**/*.js"], out: "umbraco.interceptors.js" },
|
||||
|
||||
preview: { files: "./src/preview/**/*.js", out: "umbraco.preview.js" },
|
||||
installer: { files: "./src/installer/**/*.js", out: "umbraco.installer.js" },
|
||||
filters: { files: "./src/common/filters/**/*.js", out: "umbraco.filters.js" },
|
||||
resources: { files: "./src/common/resources/**/*.js", out: "umbraco.resources.js" },
|
||||
services: { files: "./src/common/services/**/*.js", out: "umbraco.services.js" },
|
||||
security: { files: "./src/common/interceptors/**/*.js", out: "umbraco.interceptors.js" },
|
||||
|
||||
//the controllers for views
|
||||
controllers: {
|
||||
files: [
|
||||
@@ -42,13 +42,16 @@ module.exports = {
|
||||
],
|
||||
out: "umbraco.directives.js"
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
//selectors for copying all views into the build
|
||||
//processed in the views task
|
||||
views:{
|
||||
umbraco: {files: ["./src/views/**/*.html"], folder: ""},
|
||||
installer: {files: ["./src/installer/steps/*.html"], folder: "install/"}
|
||||
views: {files: "./src/views/**/*.html", folder: ""},
|
||||
directives: {files: "./src/common/directives/**/*.html", folder: ""},
|
||||
components: {files: "./src/common/components/**/*.html", folder: ""},
|
||||
installer: {files: "./src/installer/steps/*.html", folder: "install/"}
|
||||
},
|
||||
|
||||
//globs for file-watching
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
var onlyScripts = require('./util/scriptFilter');
|
||||
var tasks = fs.readdirSync('./gulp/tasks/').filter(onlyScripts);
|
||||
|
||||
tasks.forEach(function(task) {
|
||||
require('./tasks/' + task);
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var config = require('../config');
|
||||
var gulp = require('gulp');
|
||||
var runSequence = require('run-sequence');
|
||||
|
||||
// Build - build the files ready for production
|
||||
gulp.task('build', function(cb) {
|
||||
runSequence(["js", "dependencies", "less", "views"], "test:unit", cb);
|
||||
});
|
||||
@@ -10,7 +10,7 @@ var imagemin = require('gulp-imagemin');
|
||||
/**************************
|
||||
* Task processes and copies all dependencies, either installed by npm or stored locally in the project
|
||||
**************************/
|
||||
gulp.task('dependencies', function () {
|
||||
function dependencies() {
|
||||
|
||||
//as we do multiple things in this task, we merge the multiple streams
|
||||
var stream = new MergeStream();
|
||||
@@ -244,21 +244,21 @@ gulp.task('dependencies', function () {
|
||||
nodeModules.forEach(module => {
|
||||
stream.add(
|
||||
gulp.src(module.src,
|
||||
{ base: module.base })
|
||||
{ base: module.base, allowEmpty: true })
|
||||
.pipe(gulp.dest(config.root + config.targets.lib + "/" + module.name))
|
||||
);
|
||||
});
|
||||
|
||||
//copy over libs which are not on npm (/lib)
|
||||
stream.add(
|
||||
gulp.src(config.sources.globs.lib)
|
||||
gulp.src(config.sources.globs.lib, { allowEmpty: true })
|
||||
.pipe(gulp.dest(config.root + config.targets.lib))
|
||||
);
|
||||
|
||||
//Copies all static assets into /root / assets folder
|
||||
//css, fonts and image files
|
||||
|
||||
var assetsTask = gulp.src(config.sources.globs.assets);
|
||||
var assetsTask = gulp.src(config.sources.globs.assets, { allowEmpty: true });
|
||||
if (global.isProd === true) {
|
||||
assetsTask = assetsTask.pipe(imagemin([
|
||||
imagemin.gifsicle({interlaced: true}),
|
||||
@@ -277,21 +277,23 @@ gulp.task('dependencies', function () {
|
||||
stream.add(assetsTask);
|
||||
|
||||
// Copies all the less files related to the preview into their folder
|
||||
//these are not pre-processed as preview has its own less combiler client side
|
||||
//these are not pre-processed as preview has its own less compiler client side
|
||||
stream.add(
|
||||
gulp.src("src/canvasdesigner/editors/*.less")
|
||||
gulp.src("src/canvasdesigner/editors/*.less", { allowEmpty: true })
|
||||
.pipe(gulp.dest(config.root + config.targets.assets + "/less"))
|
||||
);
|
||||
|
||||
// Todo: check if we need these fileSize
|
||||
// TODO: check if we need these fileSize
|
||||
stream.add(
|
||||
gulp.src("src/views/propertyeditors/grid/config/*.*")
|
||||
gulp.src("src/views/propertyeditors/grid/config/*.*", { allowEmpty: true })
|
||||
.pipe(gulp.dest(config.root + config.targets.views + "/propertyeditors/grid/config"))
|
||||
);
|
||||
stream.add(
|
||||
gulp.src("src/views/dashboard/default/*.jpg")
|
||||
gulp.src("src/views/dashboard/default/*.jpg", { allowEmpty: true })
|
||||
.pipe(gulp.dest(config.root + config.targets.views + "/dashboard/default"))
|
||||
);
|
||||
|
||||
return stream;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = { dependencies: dependencies };
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var config = require('../config');
|
||||
var gulp = require('gulp');
|
||||
var runSequence = require('run-sequence');
|
||||
|
||||
// Dev - build the files ready for development and start watchers
|
||||
gulp.task('dev', function (cb) {
|
||||
|
||||
global.isProd = false;
|
||||
|
||||
runSequence(["dependencies", "js", "less", "views"], "watch", cb);
|
||||
});
|
||||
@@ -9,21 +9,24 @@ var MergeStream = require('merge-stream');
|
||||
var processJs = require('../util/processJs');
|
||||
|
||||
/**************************
|
||||
* Copies all angular JS files into their seperate umbraco.*.js file
|
||||
* Copies all angular JS files into their separate umbraco.*.js file
|
||||
**************************/
|
||||
gulp.task('js', function () {
|
||||
function js() {
|
||||
|
||||
//we run multiple streams, so merge them all together
|
||||
var stream = new MergeStream();
|
||||
|
||||
stream.add(
|
||||
gulp.src(config.sources.globs.js)
|
||||
.pipe(gulp.dest(config.root + config.targets.js))
|
||||
);
|
||||
gulp.src(config.sources.globs.js).pipe( gulp.dest(config.root + config.targets.js) )
|
||||
);
|
||||
|
||||
_.forEach(config.sources.js, function (group) {
|
||||
stream.add (processJs(group.files, group.out) );
|
||||
});
|
||||
_.forEach(config.sources.js, function (group) {
|
||||
stream.add(
|
||||
processJs(group.files, group.out)
|
||||
);
|
||||
});
|
||||
|
||||
return stream;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = { js: js };
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
var config = require('../config');
|
||||
var gulp = require('gulp');
|
||||
|
||||
var _ = require('lodash');
|
||||
var MergeStream = require('merge-stream');
|
||||
|
||||
var processLess = require('../util/processLess');
|
||||
|
||||
gulp.task('less', function () {
|
||||
function less() {
|
||||
|
||||
var stream = new MergeStream();
|
||||
|
||||
@@ -17,4 +16,6 @@ gulp.task('less', function () {
|
||||
});
|
||||
|
||||
return stream;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = { less: less };
|
||||
|
||||
22
src/Umbraco.Web.UI.Client/gulp/tasks/removeProductionMode.js
Normal file
22
src/Umbraco.Web.UI.Client/gulp/tasks/removeProductionMode.js
Normal file
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
var gulp = require('gulp');
|
||||
var through2 = require('through2');
|
||||
|
||||
function createEmptyStream() {
|
||||
var pass = through2.obj();
|
||||
process.nextTick(pass.end.bind(pass));
|
||||
return pass;
|
||||
}
|
||||
|
||||
/**************************
|
||||
* Copies all angular JS files into their separate umbraco.*.js file
|
||||
**************************/
|
||||
function removeProductionMode() {
|
||||
|
||||
global.isProd = false;
|
||||
|
||||
return createEmptyStream();
|
||||
};
|
||||
|
||||
module.exports = { removeProductionMode: removeProductionMode };
|
||||
@@ -1,32 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
var config = require('../config');
|
||||
var gulp = require('gulp');
|
||||
var karmaServer = require('karma').Server;
|
||||
var runSequence = require('run-sequence');
|
||||
|
||||
/**************************
|
||||
* Build tests
|
||||
**************************/
|
||||
|
||||
// Karma test
|
||||
gulp.task('runTests', function(cb) {
|
||||
runSequence("js", "test:unit", cb);
|
||||
});
|
||||
function testUnit() {
|
||||
|
||||
gulp.task('test:unit', function () {
|
||||
|
||||
new karmaServer({
|
||||
return new karmaServer({
|
||||
configFile: __dirname + "/../../test/config/karma.conf.js",
|
||||
keepalive: true
|
||||
})
|
||||
.start();
|
||||
});
|
||||
};
|
||||
|
||||
gulp.task('test:e2e', function() {
|
||||
new karmaServer({
|
||||
function testE2e() {
|
||||
return new karmaServer({
|
||||
configFile: __dirname + "/../../test/config/e2e.js",
|
||||
keepalive: true
|
||||
})
|
||||
.start();
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = { testUnit: testUnit, testE2e: testE2e };
|
||||
|
||||
@@ -6,7 +6,7 @@ var gulp = require('gulp');
|
||||
var _ = require('lodash');
|
||||
var MergeStream = require('merge-stream');
|
||||
|
||||
gulp.task('views', function () {
|
||||
function views() {
|
||||
|
||||
var stream = new MergeStream();
|
||||
|
||||
@@ -22,4 +22,7 @@ gulp.task('views', function () {
|
||||
});
|
||||
|
||||
return stream;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = { views: views };
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
var config = require('../config');
|
||||
var gulp = require('gulp');
|
||||
|
||||
var _ = require('lodash');
|
||||
var MergeStream = require('merge-stream');
|
||||
|
||||
var processJs = require('../util/processJs');
|
||||
|
||||
var watch = require('gulp-watch');
|
||||
|
||||
gulp.task('watch', function () {
|
||||
|
||||
var stream = new MergeStream();
|
||||
var watchInterval = 500;
|
||||
|
||||
//Setup a watcher for all groups of javascript files
|
||||
_.forEach(config.sources.js, function (group) {
|
||||
|
||||
if(group.watch !== false){
|
||||
|
||||
stream.add(
|
||||
|
||||
watch(group.files, { ignoreInitial: true, interval: watchInterval }, function (file) {
|
||||
|
||||
console.info(file.path + " has changed, added to: " + group.out);
|
||||
processJs(group.files, group.out);
|
||||
|
||||
})
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
stream.add(
|
||||
//watch all less files and trigger the less task
|
||||
watch(config.sources.globs.less, { ignoreInitial: true, interval: watchInterval }, function () {
|
||||
gulp.run(['less']);
|
||||
})
|
||||
);
|
||||
|
||||
//watch all views - copy single file changes
|
||||
stream.add(
|
||||
watch(config.sources.globs.views, { interval: watchInterval })
|
||||
.pipe(gulp.dest(config.root + config.targets.views))
|
||||
);
|
||||
|
||||
//watch all app js files that will not be merged - copy single file changes
|
||||
stream.add(
|
||||
watch(config.sources.globs.js, { interval: watchInterval })
|
||||
.pipe(gulp.dest(config.root + config.targets.js))
|
||||
);
|
||||
|
||||
return stream;
|
||||
});
|
||||
49
src/Umbraco.Web.UI.Client/gulp/tasks/watchTask.js
Normal file
49
src/Umbraco.Web.UI.Client/gulp/tasks/watchTask.js
Normal file
@@ -0,0 +1,49 @@
|
||||
'use strict';
|
||||
|
||||
const config = require('../config');
|
||||
const {watch, parallel, dest, src} = require('gulp');
|
||||
|
||||
var _ = require('lodash');
|
||||
var MergeStream = require('merge-stream');
|
||||
|
||||
var processJs = require('../util/processJs');
|
||||
var processLess = require('../util/processLess');
|
||||
|
||||
//const { less } = require('./less');
|
||||
//const { views } = require('./views');
|
||||
|
||||
|
||||
function watchTask(cb) {
|
||||
|
||||
var watchInterval = 500;
|
||||
|
||||
//Setup a watcher for all groups of JS files
|
||||
_.forEach(config.sources.js, function (group) {
|
||||
if(group.watch !== false) {
|
||||
watch(group.files, { ignoreInitial: true, interval: watchInterval }, function JS_Group_Compile() { return processJs(group.files, group.out) });
|
||||
}
|
||||
});
|
||||
|
||||
//Setup a watcher for all groups of LESS files
|
||||
_.forEach(config.sources.less, function (group) {
|
||||
if(group.watch !== false) {
|
||||
watch(group.watch, { ignoreInitial: true, interval: watchInterval }, function Less_Group_Compile() { processLess(group.files, group.out) });
|
||||
}
|
||||
});
|
||||
|
||||
//Setup a watcher for all groups of view files
|
||||
var viewWatcher;
|
||||
_.forEach(config.sources.views, function (group) {
|
||||
if(group.watch !== false) {
|
||||
viewWatcher = watch(group.files, { ignoreInitial: true, interval: watchInterval });
|
||||
viewWatcher.on('change', function(path, stats) {
|
||||
console.log("copying " + group.files + " to " + config.root + config.targets.views + group.folder);
|
||||
src(group.files).pipe( dest(config.root + config.targets.views + group.folder) )
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return cb();
|
||||
};
|
||||
|
||||
module.exports = { watchTask: watchTask };
|
||||
@@ -11,6 +11,8 @@ var embedTemplates = require('gulp-angular-embed-templates');
|
||||
|
||||
module.exports = function (files, out) {
|
||||
|
||||
console.log("JS: ", files, " -> ", config.root + config.targets.js + out)
|
||||
|
||||
var task = gulp.src(files);
|
||||
|
||||
// check for js errors
|
||||
|
||||
@@ -15,7 +15,9 @@ module.exports = function(files, out) {
|
||||
autoprefixer,
|
||||
cssnano({zindex: false})
|
||||
];
|
||||
|
||||
|
||||
console.log("LESS: ", files, " -> ", config.root + config.targets.js + out)
|
||||
|
||||
var task = gulp.src(files)
|
||||
.pipe(less())
|
||||
.pipe(cleanCss())
|
||||
|
||||
@@ -1,16 +1,49 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
* gulpfile.js
|
||||
* ===========
|
||||
* Rather than manage one giant configuration file responsible
|
||||
* for creating multiple tasks, each task has been broken out into
|
||||
* its own file in gulp/tasks. Any file in that folder gets automatically
|
||||
* required by the loop in ./gulp/index.js (required below).
|
||||
*
|
||||
* To add a new task, simply add a new task file to gulp/tasks.
|
||||
*/
|
||||
* gulpfile.js
|
||||
* ===========
|
||||
* This is now using Gulp 4, each child task is now a child function in its own corresponding file.
|
||||
*
|
||||
* To add a new task, simply add a new task file to gulp/tasks folder, add a require statement below to include the one or more methods
|
||||
* and then add the exports command to add the new item into the task menu.
|
||||
*/
|
||||
|
||||
global.isProd = true;
|
||||
|
||||
require('./gulp');
|
||||
const { src, dest, series, parallel, lastRun } = require('gulp');
|
||||
|
||||
const { dependencies } = require('./gulp/tasks/dependencies');
|
||||
const { js } = require('./gulp/tasks/js');
|
||||
const { less } = require('./gulp/tasks/less');
|
||||
const { testE2e, testUnit } = require('./gulp/tasks/test');
|
||||
const { views } = require('./gulp/tasks/views');
|
||||
const { watchTask } = require('./gulp/tasks/watchTask');
|
||||
const { removeProductionMode } = require('./gulp/tasks/removeProductionMode');
|
||||
|
||||
// Load local overwrites, can be used to overwrite paths in your local setup.
|
||||
var fs = require('fs');
|
||||
var onlyScripts = require('./gulp/util/scriptFilter');
|
||||
try {
|
||||
if (fs.existsSync('./gulp/overwrites/')) {
|
||||
var overwrites = fs.readdirSync('./gulp/overwrites/').filter(onlyScripts);
|
||||
overwrites.forEach(function(overwrite) {
|
||||
require('./gulp/overwrites/' + overwrite);
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
|
||||
// ***********************************************************
|
||||
// These Exports are the new way of defining Tasks in Gulp 4.x
|
||||
// ***********************************************************
|
||||
exports.build = series(parallel(dependencies, js, less, views), testUnit);
|
||||
exports.dev = series(parallel(dependencies, js, less, views), watchTask);
|
||||
exports.fastdev = series(removeProductionMode, parallel(dependencies, js, less, views), watchTask);
|
||||
exports.watch = series(watchTask);
|
||||
//
|
||||
exports.runTests = series(js, testUnit);
|
||||
exports.testUnit = series(testUnit);
|
||||
exports.testE2e = series(testE2e);
|
||||
|
||||
5346
src/Umbraco.Web.UI.Client/package-lock.json
generated
5346
src/Umbraco.Web.UI.Client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,80 +1,84 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test": "karma start test/config/karma.conf.js --singlerun",
|
||||
"build": "gulp build",
|
||||
"dev": "gulp dev",
|
||||
"fastdev": "gulp fastdev"
|
||||
},
|
||||
"dependencies": {
|
||||
"ace-builds": "1.4.2",
|
||||
"angular": "1.7.5",
|
||||
"angular-animate": "1.7.5",
|
||||
"angular-aria": "1.7.5",
|
||||
"angular-chart.js": "^1.1.1",
|
||||
"angular-cookies": "1.7.5",
|
||||
"angular-dynamic-locale": "0.1.37",
|
||||
"angular-i18n": "1.7.5",
|
||||
"angular-local-storage": "0.7.1",
|
||||
"angular-messages": "1.7.5",
|
||||
"angular-mocks": "1.7.5",
|
||||
"angular-route": "1.7.5",
|
||||
"angular-sanitize": "1.7.5",
|
||||
"angular-touch": "1.7.5",
|
||||
"angular-ui-sortable": "0.19.0",
|
||||
"animejs": "2.2.0",
|
||||
"bootstrap-social": "5.1.1",
|
||||
"chart.js": "^2.7.3",
|
||||
"clipboard": "2.0.4",
|
||||
"diff": "3.5.0",
|
||||
"flatpickr": "4.5.2",
|
||||
"font-awesome": "4.7.0",
|
||||
"jquery": "^3.4.0",
|
||||
"jquery-ui-dist": "1.12.1",
|
||||
"jquery-ui-touch-punch": "0.2.3",
|
||||
"lazyload-js": "1.0.0",
|
||||
"moment": "2.22.2",
|
||||
"ng-file-upload": "12.2.13",
|
||||
"nouislider": "14.0.2",
|
||||
"npm": "^6.4.1",
|
||||
"signalr": "2.4.0",
|
||||
"spectrum-colorpicker": "1.8.0",
|
||||
"tinymce": "4.9.2",
|
||||
"typeahead.js": "0.11.1",
|
||||
"underscore": "1.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.1.6",
|
||||
"@babel/preset-env": "7.1.6",
|
||||
"autoprefixer": "9.3.1",
|
||||
"cssnano": "4.1.7",
|
||||
"fs": "0.0.2",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-angular-embed-templates": "^2.3.0",
|
||||
"gulp-babel": "8.0.0",
|
||||
"gulp-clean-css": "4.0.0",
|
||||
"gulp-cli": "^2.0.1",
|
||||
"gulp-concat": "2.6.1",
|
||||
"gulp-eslint": "^5.0.0",
|
||||
"gulp-imagemin": "^4.1.0",
|
||||
"gulp-less": "4.0.1",
|
||||
"gulp-notify": "^3.0.0",
|
||||
"gulp-postcss": "8.0.0",
|
||||
"gulp-rename": "1.4.0",
|
||||
"gulp-sort": "2.0.0",
|
||||
"gulp-watch": "5.0.1",
|
||||
"gulp-wrap": "0.14.0",
|
||||
"gulp-wrap-js": "0.4.1",
|
||||
"jasmine-core": "3.3.0",
|
||||
"karma": "3.1.1",
|
||||
"karma-jasmine": "2.0.1",
|
||||
"karma-junit-reporter": "^1.2.0",
|
||||
"karma-phantomjs-launcher": "1.0.4",
|
||||
"less": "3.9.0",
|
||||
"lodash": "4.17.13",
|
||||
"marked": "^0.6.1",
|
||||
"merge-stream": "1.0.1",
|
||||
"run-sequence": "2.2.1",
|
||||
"caniuse-lite": "^1.0.30000966"
|
||||
}
|
||||
}
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"test": "gulp runTests",
|
||||
"unit": "gulp testUnit",
|
||||
"e2e": "gulp testE2e",
|
||||
"build": "gulp build",
|
||||
"dev": "gulp dev",
|
||||
"fastdev": "gulp fastdev",
|
||||
"watch": "gulp watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"ace-builds": "1.4.2",
|
||||
"angular": "1.7.5",
|
||||
"angular-animate": "1.7.5",
|
||||
"angular-aria": "1.7.5",
|
||||
"angular-chart.js": "^1.1.1",
|
||||
"angular-cookies": "1.7.5",
|
||||
"angular-dynamic-locale": "0.1.37",
|
||||
"angular-i18n": "1.7.5",
|
||||
"angular-local-storage": "0.7.1",
|
||||
"angular-messages": "1.7.5",
|
||||
"angular-mocks": "1.7.5",
|
||||
"angular-route": "1.7.5",
|
||||
"angular-sanitize": "1.7.5",
|
||||
"angular-touch": "1.7.5",
|
||||
"angular-ui-sortable": "0.19.0",
|
||||
"animejs": "2.2.0",
|
||||
"bootstrap-social": "5.1.1",
|
||||
"chart.js": "^2.8.0",
|
||||
"clipboard": "2.0.4",
|
||||
"diff": "3.5.0",
|
||||
"flatpickr": "4.5.2",
|
||||
"font-awesome": "4.7.0",
|
||||
"jquery": "^3.4.1",
|
||||
"jquery-ui-dist": "1.12.1",
|
||||
"jquery-ui-touch-punch": "0.2.3",
|
||||
"lazyload-js": "1.0.0",
|
||||
"moment": "2.22.2",
|
||||
"ng-file-upload": "12.2.13",
|
||||
"nouislider": "14.0.2",
|
||||
"npm": "6.12.0",
|
||||
"signalr": "2.4.0",
|
||||
"spectrum-colorpicker": "1.8.0",
|
||||
"tinymce": "4.9.2",
|
||||
"typeahead.js": "0.11.1",
|
||||
"underscore": "1.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.6.4",
|
||||
"@babel/preset-env": "7.6.3",
|
||||
"autoprefixer": "9.6.5",
|
||||
"caniuse-lite": "^1.0.30001002",
|
||||
"cssnano": "4.1.10",
|
||||
"fs": "0.0.2",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-angular-embed-templates": "^2.3.0",
|
||||
"gulp-babel": "8.0.0",
|
||||
"gulp-clean-css": "4.2.0",
|
||||
"gulp-cli": "^2.2.0",
|
||||
"gulp-concat": "2.6.1",
|
||||
"gulp-eslint": "6.0.0",
|
||||
"gulp-imagemin": "6.1.1",
|
||||
"gulp-less": "4.0.1",
|
||||
"gulp-notify": "^3.0.0",
|
||||
"gulp-postcss": "8.0.0",
|
||||
"gulp-rename": "1.4.0",
|
||||
"gulp-sort": "2.0.0",
|
||||
"gulp-watch": "5.0.1",
|
||||
"gulp-wrap": "0.15.0",
|
||||
"gulp-wrap-js": "0.4.1",
|
||||
"jasmine-core": "3.5.0",
|
||||
"karma": "4.4.1",
|
||||
"karma-jasmine": "2.0.1",
|
||||
"karma-junit-reporter": "2.0.1",
|
||||
"karma-phantomjs-launcher": "1.0.4",
|
||||
"karma-spec-reporter": "0.0.32",
|
||||
"less": "3.10.3",
|
||||
"lodash": "4.17.15",
|
||||
"marked": "^0.7.0",
|
||||
"merge-stream": "2.0.0",
|
||||
"run-sequence": "2.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
@param {string} value Set the value of the radiobutton.
|
||||
@param {string} name Set the name of the radiobutton.
|
||||
@param {string} text Set the text for the radiobutton label.
|
||||
@param {string} labelKey Set a dictinary/localization string for the checkbox label
|
||||
@param {boolean} disabled Set the radiobutton to be disabled.
|
||||
@param {boolean} required Set the radiobutton to be required.
|
||||
@param {callback} onChange Callback when the value of the radiobutton change by interaction.
|
||||
@@ -39,15 +40,27 @@
|
||||
|
||||
var vm = this;
|
||||
|
||||
vm.$onInit = onInit;
|
||||
vm.change = change;
|
||||
|
||||
function onInit() {
|
||||
// If a labelKey is passed let's update the returned text if it's does not contain an opening square bracket [
|
||||
if (vm.labelKey) {
|
||||
localizationService.localize(vm.labelKey).then(function (data) {
|
||||
if(data.indexOf('[') === -1){
|
||||
vm.text = data;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function change() {
|
||||
if (vm.onChange) {
|
||||
$timeout(function () {
|
||||
vm.onChange({ model: vm.model, value: vm.value });
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var component = {
|
||||
@@ -60,6 +73,7 @@
|
||||
value: "@",
|
||||
name: "@",
|
||||
text: "@",
|
||||
labelKey: "@?",
|
||||
disabled: "<",
|
||||
required: "<",
|
||||
onChange: "&?"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/**
|
||||
@ngdoc directive
|
||||
@name umbraco.directives.directive:umbOverlay*
|
||||
@deprecated
|
||||
@restrict E
|
||||
|
||||
@@ -131,13 +131,24 @@ Use this directive to render a date time picker
|
||||
return console.warn('Unable to find any flatpickr installation');
|
||||
}
|
||||
|
||||
var fpInstance;
|
||||
|
||||
setUpCallbacks();
|
||||
|
||||
if (!ctrl.options.locale) {
|
||||
ctrl.options.locale = userLocale;
|
||||
}
|
||||
|
||||
var fpInstance = new fpLib(element, ctrl.options);
|
||||
// handle special keydown events
|
||||
ctrl.options.onKeyDown = function (selectedDates, dateStr, instance, event) {
|
||||
var code = event.keyCode || event.which;
|
||||
if (code === 13) {
|
||||
// close the datepicker on enter (this happens when entering time)
|
||||
fpInstance.close()
|
||||
}
|
||||
};
|
||||
|
||||
fpInstance = new fpLib(element, ctrl.options);
|
||||
|
||||
if (ctrl.onSetup) {
|
||||
ctrl.onSetup({
|
||||
|
||||
@@ -419,7 +419,7 @@
|
||||
};
|
||||
|
||||
scope.canRemoveGroup = function(group){
|
||||
return _.find(group.properties, function(property) { return property.locked === true; }) == null;
|
||||
return group.inherited !== true && _.find(group.properties, function(property) { return property.locked === true; }) == null;
|
||||
}
|
||||
|
||||
scope.removeGroup = function(groupIndex) {
|
||||
@@ -475,6 +475,23 @@
|
||||
|
||||
/* ---------- PROPERTIES ---------- */
|
||||
|
||||
scope.addPropertyToActiveGroup = function () {
|
||||
var group = _.find(scope.model.groups, group => group.tabState === "active");
|
||||
if (!group && scope.model.groups.length) {
|
||||
group = scope.model.groups[0];
|
||||
}
|
||||
|
||||
if (!group || !group.name) {
|
||||
return;
|
||||
}
|
||||
|
||||
var property = _.find(group.properties, property => property.propertyState === "init");
|
||||
if (!property) {
|
||||
return;
|
||||
}
|
||||
scope.addProperty(property, group);
|
||||
}
|
||||
|
||||
scope.addProperty = function(property, group) {
|
||||
|
||||
// set property sort order
|
||||
|
||||
@@ -1,161 +1,143 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function ListViewSettingsDirective(dataTypeResource, dataTypeHelper, listViewPrevalueHelper) {
|
||||
function ListViewSettingsDirective(dataTypeResource, dataTypeHelper, editorService, listViewPrevalueHelper) {
|
||||
|
||||
function link(scope) {
|
||||
function link(scope) {
|
||||
|
||||
scope.dataType = {};
|
||||
scope.editDataTypeSettings = false;
|
||||
scope.customListViewCreated = false;
|
||||
scope.dataType = {};
|
||||
scope.customListViewCreated = false;
|
||||
|
||||
const checkForCustomListView = () => scope.dataType.name === "List View - " + scope.modelAlias;
|
||||
|
||||
/* ---------- INIT ---------- */
|
||||
/* ---------- INIT ---------- */
|
||||
|
||||
function activate() {
|
||||
const activate = () => {
|
||||
|
||||
if(scope.enableListView) {
|
||||
if (scope.enableListView) {
|
||||
|
||||
dataTypeResource.getByName(scope.listViewName)
|
||||
.then(function(dataType) {
|
||||
dataTypeResource.getByName(scope.listViewName)
|
||||
.then(dataType => {
|
||||
|
||||
scope.dataType = dataType;
|
||||
scope.dataType = dataType;
|
||||
|
||||
listViewPrevalueHelper.setPrevalues(dataType.preValues);
|
||||
scope.customListViewCreated = checkForCustomListView();
|
||||
});
|
||||
|
||||
} else {
|
||||
scope.dataType = {};
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------- LIST VIEW SETTINGS --------- */
|
||||
const showSettingsOverlay = () => {
|
||||
const overlay = {
|
||||
view: 'views/components/umb-list-view-settings-overlay.html',
|
||||
hideDescription: true,
|
||||
hideIcon: true,
|
||||
size: 'medium',
|
||||
dataType: scope.dataType,
|
||||
title: 'List view settings',
|
||||
submit: model => {
|
||||
const preValues = dataTypeHelper.createPreValueProps(model.dataType.preValues);
|
||||
|
||||
// store data type
|
||||
dataTypeResource.save(model.dataType, preValues, false)
|
||||
.then(dataType => scope.dataType = dataType);
|
||||
|
||||
editorService.close();
|
||||
},
|
||||
close: () => editorService.close()
|
||||
};
|
||||
|
||||
editorService.open(overlay);
|
||||
};
|
||||
|
||||
|
||||
/* ---------- CUSTOM LIST VIEW ---------- */
|
||||
|
||||
scope.createCustomListViewDataType = () => {
|
||||
|
||||
scope.loading = true;
|
||||
|
||||
dataTypeResource.createCustomListView(scope.modelAlias).then(dataType => {
|
||||
|
||||
// store data type
|
||||
scope.dataType = dataType;
|
||||
|
||||
// set list view name on scope
|
||||
scope.listViewName = dataType.name;
|
||||
|
||||
// change state to custom list view
|
||||
scope.customListViewCreated = true;
|
||||
|
||||
// show settings overlay
|
||||
showSettingsOverlay();
|
||||
|
||||
scope.loading = false;
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
scope.removeCustomListDataType = () => {
|
||||
|
||||
scope.loading = true;
|
||||
|
||||
// delete custom list view data type
|
||||
dataTypeResource.deleteById(scope.dataType.id).then(dataType => {
|
||||
|
||||
// set list view name on scope
|
||||
scope.listViewName = `List View - ${scope.contentType === 'documentType' ? 'Content' : 'Media'}`;
|
||||
|
||||
// get default data type
|
||||
dataTypeResource.getByName(scope.listViewName)
|
||||
.then(defaultDataType => {
|
||||
|
||||
// store data type
|
||||
scope.dataType = defaultDataType;
|
||||
|
||||
// change state to default list view
|
||||
scope.customListViewCreated = false;
|
||||
|
||||
scope.loading = false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
scope.toggle = () => scope.enableListView = !scope.enableListView;
|
||||
scope.showSettingsOverlay = () => showSettingsOverlay();
|
||||
|
||||
|
||||
/* ----------- SCOPE WATCHERS ----------- */
|
||||
const unbindEnableListViewWatcher = scope.$watch('enableListView', newValue => {
|
||||
|
||||
if (newValue !== undefined) {
|
||||
activate();
|
||||
}
|
||||
|
||||
listViewPrevalueHelper.setPrevalues(dataType.preValues);
|
||||
scope.customListViewCreated = checkForCustomListView();
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
scope.dataType = {};
|
||||
|
||||
// clean up
|
||||
scope.$on('$destroy', () => unbindEnableListViewWatcher());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ----------- LIST VIEW SETTINGS --------- */
|
||||
|
||||
scope.toggleEditListViewDataTypeSettings = function() {
|
||||
scope.editDataTypeSettings = !scope.editDataTypeSettings;
|
||||
};
|
||||
|
||||
scope.saveListViewDataType = function() {
|
||||
|
||||
var preValues = dataTypeHelper.createPreValueProps(scope.dataType.preValues);
|
||||
|
||||
dataTypeResource.save(scope.dataType, preValues, false).then(function(dataType) {
|
||||
|
||||
// store data type
|
||||
scope.dataType = dataType;
|
||||
|
||||
// hide settings panel
|
||||
scope.editDataTypeSettings = false;
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* ---------- CUSTOM LIST VIEW ---------- */
|
||||
|
||||
scope.createCustomListViewDataType = function() {
|
||||
|
||||
dataTypeResource.createCustomListView(scope.modelAlias).then(function(dataType) {
|
||||
|
||||
// store data type
|
||||
scope.dataType = dataType;
|
||||
|
||||
// set list view name on scope
|
||||
scope.listViewName = dataType.name;
|
||||
|
||||
// change state to custom list view
|
||||
scope.customListViewCreated = true;
|
||||
|
||||
// show settings panel
|
||||
scope.editDataTypeSettings = true;
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
scope.removeCustomListDataType = function() {
|
||||
|
||||
scope.editDataTypeSettings = false;
|
||||
|
||||
// delete custom list view data type
|
||||
dataTypeResource.deleteById(scope.dataType.id).then(function(dataType) {
|
||||
|
||||
// set list view name on scope
|
||||
if(scope.contentType === "documentType") {
|
||||
|
||||
scope.listViewName = "List View - Content";
|
||||
|
||||
} else if(scope.contentType === "mediaType") {
|
||||
|
||||
scope.listViewName = "List View - Media";
|
||||
|
||||
}
|
||||
|
||||
// get default data type
|
||||
dataTypeResource.getByName(scope.listViewName)
|
||||
.then(function(dataType) {
|
||||
|
||||
// store data type
|
||||
scope.dataType = dataType;
|
||||
|
||||
// change state to default list view
|
||||
scope.customListViewCreated = false;
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
scope.toggle = function(){
|
||||
if(scope.enableListView){
|
||||
scope.enableListView = false;
|
||||
return;
|
||||
}
|
||||
scope.enableListView = true;
|
||||
};
|
||||
|
||||
/* ----------- SCOPE WATCHERS ----------- */
|
||||
var unbindEnableListViewWatcher = scope.$watch('enableListView', function(newValue){
|
||||
|
||||
if(newValue !== undefined) {
|
||||
activate();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// clean up
|
||||
scope.$on('$destroy', function(){
|
||||
unbindEnableListViewWatcher();
|
||||
});
|
||||
|
||||
/* ----------- METHODS ---------- */
|
||||
|
||||
function checkForCustomListView() {
|
||||
return scope.dataType.name === "List View - " + scope.modelAlias;
|
||||
}
|
||||
var directive = {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
templateUrl: 'views/components/umb-list-view-settings.html',
|
||||
scope: {
|
||||
enableListView: "=",
|
||||
listViewName: "=",
|
||||
modelAlias: "=",
|
||||
contentType: "@"
|
||||
},
|
||||
link: link
|
||||
};
|
||||
|
||||
return directive;
|
||||
}
|
||||
|
||||
var directive = {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
templateUrl: 'views/components/umb-list-view-settings.html',
|
||||
scope: {
|
||||
enableListView: "=",
|
||||
listViewName: "=",
|
||||
modelAlias: "=",
|
||||
contentType: "@"
|
||||
},
|
||||
link: link
|
||||
};
|
||||
|
||||
return directive;
|
||||
}
|
||||
|
||||
angular.module('umbraco.directives').directive('umbListViewSettings', ListViewSettingsDirective);
|
||||
angular.module('umbraco.directives').directive('umbListViewSettings', ListViewSettingsDirective);
|
||||
|
||||
})();
|
||||
|
||||
@@ -17,9 +17,9 @@ angular.module("umbraco.directives")
|
||||
var observer = new MutationObserver(domChange);
|
||||
|
||||
// Options for the observer (which mutations to observe)
|
||||
var config = { attributes: true, childList: true, subtree: false };
|
||||
var config = { attributes: true, childList: true, subtree: true };
|
||||
|
||||
function domChange(mutationsList, observer){
|
||||
function domChange(mutationsList, observer) {
|
||||
for(var mutation of mutationsList) {
|
||||
|
||||
//DOM items have been added or removed
|
||||
@@ -43,4 +43,4 @@ angular.module("umbraco.directives")
|
||||
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@@ -251,7 +251,7 @@ When building a custom infinite editor view you can use the same components as a
|
||||
*
|
||||
* @param {Object} editor rendering options
|
||||
* @param {String} editor.view Path to view
|
||||
* @param {String} editor.size Sets the size of the editor ("small"). If nothing is set it will use full width.
|
||||
* @param {String} editor.size Sets the size of the editor ("small" || "medium"). If nothing is set it will use full width.
|
||||
*/
|
||||
function open(editor) {
|
||||
|
||||
@@ -567,6 +567,7 @@ When building a custom infinite editor view you can use the same components as a
|
||||
* @param {Boolean} editor.multiPicker Pick one or multiple items
|
||||
* @param {Boolean} editor.onlyImages Only display files that have an image file-extension
|
||||
* @param {Boolean} editor.disableFolderSelect Disable folder selection
|
||||
* @param {Boolean} editor.disableFocalPoint Disable focal point editor for selected media
|
||||
* @param {Array} editor.updatedMediaNodes A list of ids for media items that have been updated through the media picker
|
||||
* @param {Callback} editor.submit Submits the editor
|
||||
* @param {Callback} editor.close Closes the editor
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
'[tabindex]',
|
||||
'audio[controls]',
|
||||
'video[controls]',
|
||||
'[contenteditable]:not([contenteditable="false"])'
|
||||
'[contenteditable]:not([contenteditable="false"])',
|
||||
'iframe[data-mce-style]'
|
||||
];
|
||||
var candidateSelector = candidateSelectors.join(',');
|
||||
|
||||
|
||||
@@ -1489,6 +1489,7 @@ function tinyMceService($rootScope, $q, imageHelper, $locale, $http, $timeout, s
|
||||
onlyImages: true,
|
||||
showDetails: true,
|
||||
disableFolderSelect: true,
|
||||
disableFocalPoint: true,
|
||||
startNodeId: startNodeId,
|
||||
startNodeIsVirtual: startNodeIsVirtual,
|
||||
dataTypeKey: args.model.dataTypeKey,
|
||||
|
||||
@@ -338,3 +338,31 @@ input[type="submit"].btn {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Icon buttons
|
||||
// ------------------------------
|
||||
|
||||
// 31 July 19, Nathan Woulfe says: Reset styles for cases where button shows an icon only (eg edit/remove property on document type)
|
||||
// This is lifted from umb-group-builder.less
|
||||
|
||||
.btn-icon {
|
||||
border: none;
|
||||
|
||||
font-size: 18px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
color: @ui-icon;
|
||||
|
||||
margin: 0;
|
||||
padding: 5px 10px;
|
||||
width: auto;
|
||||
overflow: visible;
|
||||
background: transparent;
|
||||
line-height: normal;
|
||||
outline: 0;
|
||||
-webkit-appearance: none;
|
||||
|
||||
&:hover, &:focus {
|
||||
color: @ui-icon-hover;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,82 +1,86 @@
|
||||
.umb-editors {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
.absolute();
|
||||
overflow: hidden;
|
||||
|
||||
.umb-editor {
|
||||
box-shadow: 0px 0 30px 0 rgba(0,0,0,.3);
|
||||
}
|
||||
}
|
||||
|
||||
.umb-editor {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
.absolute();
|
||||
background: @brownGrayLight;
|
||||
z-index: @zIndexEditor;
|
||||
}
|
||||
|
||||
.umb-editor--infiniteMode {
|
||||
transform: none;
|
||||
will-change: transform;
|
||||
transition: transform 400ms ease-in-out;
|
||||
&.moveRight {
|
||||
transform: translateX(110%);
|
||||
&--infiniteMode {
|
||||
transform: none;
|
||||
will-change: transform;
|
||||
transition: transform 400ms ease-in-out;
|
||||
|
||||
&.umb-editor--moveRight {
|
||||
transform: translateX(110%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.umb-editor--outOfRange {
|
||||
transform: none;
|
||||
display: none;
|
||||
will-change: auto;
|
||||
transition: display 0s 320ms;
|
||||
}
|
||||
.umb-editor--level0 {
|
||||
transform: none;
|
||||
}
|
||||
.umb-editor--level1 {
|
||||
transform: translateX(60px);
|
||||
}
|
||||
.umb-editor--level2 {
|
||||
transform: translateX(120px);
|
||||
}
|
||||
.umb-editor--level3 {
|
||||
transform: translateX(180px);
|
||||
}
|
||||
|
||||
.umb-editor--n1 {
|
||||
right:60px;
|
||||
}
|
||||
.umb-editor--n2 {
|
||||
right:120px;
|
||||
}
|
||||
.umb-editor--n3 {
|
||||
right:180px;
|
||||
}
|
||||
|
||||
// hide all infinite editors by default
|
||||
// will be shown through animation
|
||||
.umb-editors .umb-editor {
|
||||
box-shadow: 0px 0 30px 0 rgba(0,0,0,.3);
|
||||
}
|
||||
|
||||
.umb-editor--small {
|
||||
width: 500px;
|
||||
will-change: transform;
|
||||
left: auto;
|
||||
&--outOfRange {
|
||||
transform: none;
|
||||
display: none;
|
||||
will-change: auto;
|
||||
transition: display 0s 320ms;
|
||||
}
|
||||
|
||||
.umb-editor-container {
|
||||
max-width: 500px;
|
||||
&--level0 {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
// use a loop to build the editor levels
|
||||
@iterations: 3;
|
||||
@step: 60px;
|
||||
|
||||
.level-loop (@i) when (@i > 0) {
|
||||
@x: @i * @step;
|
||||
.umb-editor--level@{i} {
|
||||
transform: translateX(@x);
|
||||
}
|
||||
|
||||
.umb-editor--n@{i} {
|
||||
right:@x;
|
||||
}
|
||||
|
||||
.level-loop(@i - 1);
|
||||
}
|
||||
|
||||
.level-loop(@iterations);
|
||||
|
||||
// and also use a loop to build editor sizes - easily extended with new sizes by adding to the map
|
||||
@editorSizes:
|
||||
small 500px,
|
||||
medium 800px;
|
||||
|
||||
.create-editor-sizes(@iterator:1) when(@iterator <= length(@editorSizes)) {
|
||||
.umb-editor {
|
||||
@size: extract(extract(@editorSizes, @iterator), 1);
|
||||
@value: extract(extract(@editorSizes, @iterator), 2);
|
||||
|
||||
&--@{size} {
|
||||
width: @value;
|
||||
will-change: transform;
|
||||
left: auto;
|
||||
|
||||
.umb-editor--container {
|
||||
max-width: @value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.create-editor-sizes(@iterator + 1);
|
||||
}
|
||||
|
||||
.create-editor-sizes();
|
||||
|
||||
.umb-editor__overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
.absolute();
|
||||
background: rgba(0,0,0,0.4);
|
||||
z-index: @zIndexEditor;
|
||||
visibility: hidden;
|
||||
@@ -85,7 +89,7 @@
|
||||
}
|
||||
|
||||
#contentcolumn > .umb-editor__overlay,
|
||||
.--notInFront .umb-editor__overlay {
|
||||
.umb-editor--notInFront .umb-editor__overlay {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition: opacity 320ms 20ms, visibility 0s;
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
}
|
||||
|
||||
.umb-overlay .umb-overlay-header {
|
||||
border-bottom: 1px solid @purple-l3;
|
||||
border-bottom: 1px solid @gray-9;
|
||||
margin-top: 0;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
padding: 20px 30px 0;
|
||||
padding: 20px 20px 0;
|
||||
}
|
||||
|
||||
.umb-overlay__section-header {
|
||||
@@ -48,11 +48,11 @@
|
||||
}
|
||||
|
||||
.umb-overlay__title {
|
||||
font-size: @fontSizeLarge;
|
||||
font-size: 16px;
|
||||
color: @black;
|
||||
line-height: 20px;
|
||||
line-height: 16px;
|
||||
font-weight: bold;
|
||||
margin: 7px 0;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.umb-overlay__subtitle {
|
||||
@@ -66,8 +66,8 @@
|
||||
flex-shrink: 1;
|
||||
flex-basis: auto;
|
||||
position: relative;
|
||||
padding: 0 30px;
|
||||
margin-bottom: 10px;
|
||||
padding: 20px;
|
||||
background: @white;
|
||||
max-height: calc(100vh - 170px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
@@ -75,11 +75,11 @@
|
||||
.umb-overlay-drawer {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
flex-basis: 31px;
|
||||
padding: 10px 20px;
|
||||
flex-basis: 33px;
|
||||
padding: 8px 20px;
|
||||
margin: 0;
|
||||
background: @gray-10;
|
||||
border-top: 1px solid @purple-l3;
|
||||
background: @white;
|
||||
border-top: 1px solid @gray-9;
|
||||
}
|
||||
|
||||
.umb-overlay-drawer.-auto-height {
|
||||
@@ -140,7 +140,6 @@
|
||||
.umb-overlay.umb-overlay-target .umb-overlay-drawer {
|
||||
border: none;
|
||||
background: transparent;
|
||||
padding: 0 30px 20px;
|
||||
}
|
||||
|
||||
/* ---------- OVERLAY RIGHT ---------- */
|
||||
@@ -158,7 +157,7 @@
|
||||
}
|
||||
|
||||
.umb-overlay.umb-overlay-right .umb-overlay-header {
|
||||
flex-basis: 100px;
|
||||
flex-basis: 70px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,14 @@
|
||||
|
||||
.umb-breadcrumbs__ancestor {
|
||||
display: flex;
|
||||
min-height: 25px;
|
||||
}
|
||||
|
||||
.umb-breadcrumbs__action {
|
||||
background: transparent;
|
||||
border: 0 none;
|
||||
padding: 0;
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
||||
.umb-breadcrumbs__ancestor-link,
|
||||
@@ -38,7 +46,6 @@
|
||||
|
||||
input.umb-breadcrumbs__add-ancestor {
|
||||
height: 25px;
|
||||
margin-top: -2px;
|
||||
margin-left: 3px;
|
||||
margin: 0 0 0 3px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
&__text {
|
||||
margin: 0 0 0 26px;
|
||||
position: relative;
|
||||
top: 0;
|
||||
top: 1px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
|
||||
|
||||
&:hover ~ .umb-form-check__state .umb-form-check__check {
|
||||
border-color: @inputBorderFocus;
|
||||
}
|
||||
@@ -36,7 +36,7 @@
|
||||
background: @ui-option-type-hover;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&:checked ~ .umb-form-check__state {
|
||||
.umb-form-check__check {
|
||||
// This only happens if the state has a radiobutton modifier
|
||||
@@ -62,8 +62,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.tabbing-active &.umb-form-check--radiobutton &__input:focus ~ .umb-form-check__state .umb-form-check__check {
|
||||
//outline: 2px solid @inputBorderTabFocus;
|
||||
border: 2px solid @inputBorderTabFocus;
|
||||
@@ -76,6 +75,11 @@
|
||||
border-color: white;
|
||||
}
|
||||
|
||||
// add spacing between when flexed/inline, equal to the width of the input
|
||||
.flex & + & {
|
||||
margin-left:@checkboxWidth;
|
||||
}
|
||||
|
||||
&__state {
|
||||
display: flex;
|
||||
height: 18px;
|
||||
|
||||
@@ -367,7 +367,6 @@ input.umb-group-builder__group-title-input:disabled:hover {
|
||||
overflow: visible;
|
||||
background: transparent;
|
||||
line-height: normal;
|
||||
outline: 0;
|
||||
-webkit-appearance: none;
|
||||
|
||||
&:hover, &:focus {
|
||||
|
||||
@@ -1,54 +1,76 @@
|
||||
.umb-list-view-settings__box {
|
||||
background: @gray-10;
|
||||
border: 1px solid @gray-7;
|
||||
display: flex;
|
||||
animation: fadeIn 0.5s;
|
||||
padding: 15px;
|
||||
position: relative;
|
||||
background: @gray-10;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
padding: 15px;
|
||||
position: relative;
|
||||
border-radius: @baseBorderRadius;
|
||||
|
||||
.btn-link {
|
||||
font-size: 13px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-list-view-settings__trigger {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.umb-list-view-settings__box.-open {
|
||||
border-bottom: transparent;
|
||||
}
|
||||
|
||||
.umb-list-view-settings__content {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.umb-list-view-settings__list-view-icon {
|
||||
font-size: 20px;
|
||||
color: @gray-7;
|
||||
margin-right: 10px;
|
||||
font-size: 20px;
|
||||
color: @gray-7;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.umb-list-view-settings__name {
|
||||
margin-right: 5px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
float: left;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.umb-list-view-settings__create-new {
|
||||
font-size: 13px;
|
||||
color: @ui-action-type;
|
||||
}
|
||||
|
||||
.umb-list-view-settings__create-new:hover {
|
||||
color: @ui-action-type-hover;
|
||||
border-color: @ui-action-type-hover;
|
||||
color: @ui-action-type;
|
||||
}
|
||||
|
||||
.umb-list-view-settings__remove-new {
|
||||
font-size: 13px;
|
||||
color: @red;
|
||||
color: @red;
|
||||
}
|
||||
|
||||
.umb-list-view-settings__settings {
|
||||
border: 1px dashed @gray-7;
|
||||
border-top: none;
|
||||
padding: 20px;
|
||||
// display `columns displayed` table as a list-view layout
|
||||
.umb-list-view-settings__overlay {
|
||||
|
||||
.btn {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
tbody tr {
|
||||
background: @gray-10;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px 15px 10px 0;
|
||||
|
||||
&:first-child {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.ui-sortable-handle {
|
||||
min-height: 37px;
|
||||
display: flex;
|
||||
width:0;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,8 +234,46 @@
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.form-horizontal .umb-nested-content--narrow .controls-row
|
||||
{
|
||||
.umb-nested-content__placeholder {
|
||||
height: 22px;
|
||||
padding: 4px 6px;
|
||||
border: 1px dashed #d8d7d9;
|
||||
background: 0 0;
|
||||
cursor: pointer;
|
||||
color: #1b264f;
|
||||
-webkit-animation: fadeIn .5s;
|
||||
animation: fadeIn .5s;
|
||||
text-align: center;
|
||||
|
||||
&--selected {
|
||||
border: 1px solid #d8d7d9;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
.umb-nested-content__placeholder-name{
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.umb-nested-content__placeholder:hover {
|
||||
color: #2152a3;
|
||||
border-color: #2152a3;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.umb-nested-content__placeholder-icon-holder {
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.umb-nested-content__placeholder-icon {
|
||||
font-size: 18px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
.form-horizontal .umb-nested-content--narrow .controls-row {
|
||||
margin-left: 40% !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -203,9 +203,9 @@
|
||||
.list-view-layout__name-text {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
|
||||
.list-view-layout__system {
|
||||
font-size: 10px;
|
||||
font-size: 10px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@@ -236,6 +236,8 @@
|
||||
}
|
||||
|
||||
.list-view-add-layout {
|
||||
width:100%;
|
||||
background:0 0;
|
||||
margin-top: 10px;
|
||||
color: @ui-action-discreet-type;
|
||||
border: 1px dashed @ui-action-discreet-border;
|
||||
|
||||
@@ -116,8 +116,9 @@ h5.-black {
|
||||
margin: 20px;
|
||||
}
|
||||
.umb-control-group {
|
||||
border-bottom: 1px solid @gray-11;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid @gray-11;
|
||||
padding-bottom: 20px;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.umb-control-group.-no-border {
|
||||
|
||||
@@ -308,7 +308,14 @@
|
||||
opacity: @opacity / 100;
|
||||
}
|
||||
|
||||
|
||||
// Position
|
||||
.absolute() {
|
||||
position:absolute;
|
||||
top:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
left:0;
|
||||
}
|
||||
|
||||
// BACKGROUNDS
|
||||
// --------------------------------------------------
|
||||
|
||||
@@ -83,10 +83,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
.umb-rte .mce-fullscreen {
|
||||
position:absolute;
|
||||
}
|
||||
|
||||
.umb-rte .mce-toolbar .mce-btn-group {
|
||||
padding: 0;
|
||||
}
|
||||
@@ -165,3 +161,7 @@
|
||||
border: 1px solid #d8d7d9;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.mce-fullscreen {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ ul.sections-tray {
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
position: relative;
|
||||
outline: none;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
@@ -131,6 +132,13 @@ ul.sections-tray {
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&:focus .section__name {
|
||||
.tabbing-active & {
|
||||
border: 1px solid;
|
||||
border-color: @gray-9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
function CompositionsController($scope, $location, $filter, overlayService) {
|
||||
function CompositionsController($scope, $location, $filter, overlayService, localizationService) {
|
||||
|
||||
var vm = this;
|
||||
var oldModel = null;
|
||||
@@ -68,19 +68,23 @@
|
||||
or the confirm checkbox has been checked */
|
||||
if (compositionRemoved) {
|
||||
vm.allowSubmit = false;
|
||||
const dialog = {
|
||||
view: "views/common/infiniteeditors/compositions/overlays/confirmremove.html",
|
||||
submitButtonLabelKey: "general_ok",
|
||||
closeButtonLabelKey: "general_cancel",
|
||||
submit: function (model) {
|
||||
$scope.model.submit($scope.model);
|
||||
overlayService.close();
|
||||
},
|
||||
close: function () {
|
||||
overlayService.close();
|
||||
}
|
||||
};
|
||||
overlayService.open(dialog);
|
||||
localizationService.localize("general_remove").then(function(value) {
|
||||
const dialog = {
|
||||
view: "views/common/infiniteeditors/compositions/overlays/confirmremove.html",
|
||||
title: value,
|
||||
submitButtonLabelKey: "general_ok",
|
||||
submitButtonStyle: "danger",
|
||||
closeButtonLabelKey: "general_cancel",
|
||||
submit: function (model) {
|
||||
$scope.model.submit($scope.model);
|
||||
overlayService.close();
|
||||
},
|
||||
close: function () {
|
||||
overlayService.close();
|
||||
}
|
||||
};
|
||||
overlayService.open(dialog);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<div>
|
||||
|
||||
<h5 class="red"><i class="icon-alert"></i>Warning</h5>
|
||||
<p>Removing a composition will delete all the associated property data. Once you save the document type there's no way back, are you sure?</p>
|
||||
<div class="umb-alert umb-alert--warning mb2">
|
||||
<localize key="contentTypeEditor_compositionRemoveWarning"></localize>
|
||||
</div>
|
||||
|
||||
<localize key="defaultdialogs_confirmSure"></localize>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -48,13 +48,14 @@
|
||||
<li ng-repeat="systemDataType in value | orderBy:'name'"
|
||||
data-element="editor-{{systemDataType.name}}"
|
||||
ng-mouseover="vm.showDetailsOverlay(systemDataType)"
|
||||
ng-click="vm.pickEditor(systemDataType)">
|
||||
<a class="umb-card-grid-item" href="" title="{{ systemDataType.name }}">
|
||||
ng-click="vm.pickEditor(systemDataType)"
|
||||
class="cursor-pointer">
|
||||
<span class="umb-card-grid-item" title="{{ systemDataType.name }}">
|
||||
<span>
|
||||
<i class="{{ systemDataType.icon }}" ng-class="{'icon-autofill': systemDataType.icon == null}"></i>
|
||||
{{ systemDataType.name }}
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -66,16 +67,17 @@
|
||||
<li ng-repeat="dataType in value | orderBy:'name'"
|
||||
data-element="editor-{{dataType.name}}"
|
||||
ng-mouseover="vm.showDetailsOverlay(dataType)"
|
||||
ng-click="vm.pickDataType(dataType)">
|
||||
ng-click="vm.pickDataType(dataType)"
|
||||
class="cursor-pointer">
|
||||
<div ng-if="dataType.loading" class="umb-card-grid-item__loading">
|
||||
<div class="umb-button__progress"></div>
|
||||
</div>
|
||||
<a class="umb-card-grid-item" href="" title="{{ dataType.name }}">
|
||||
<span class="umb-card-grid-item" title="{{ dataType.name }}">
|
||||
<span>
|
||||
<i class="{{ dataType.icon }}" ng-class="{'icon-autofill': dataType.icon == null}"></i>
|
||||
{{ dataType.name }}
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -93,16 +95,17 @@
|
||||
<ul class="umb-card-grid -four-in-row" ng-mouseleave="vm.hideDetailsOverlay()">
|
||||
<li ng-repeat="dataType in result.dataTypes | orderBy:'name'"
|
||||
ng-mouseover="vm.showDetailsOverlay(dataType)"
|
||||
ng-click="vm.pickDataType(dataType)">
|
||||
ng-click="vm.pickDataType(dataType)"
|
||||
class="cursor-pointer">
|
||||
<div ng-if="dataType.loading" class="umb-card-grid-item__loading">
|
||||
<div class="umb-button__progress"></div>
|
||||
</div>
|
||||
<a class="umb-card-grid-item" href="" title="{{dataType.name}}">
|
||||
<span class="umb-card-grid-item" title="{{dataType.name}}">
|
||||
<span>
|
||||
<i class="{{dataType.icon}}" ng-class="{'icon-autofill': dataType.icon == null}"></i>
|
||||
{{dataType.name}}
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -116,13 +119,14 @@
|
||||
<ul class="umb-card-grid -four-in-row" ng-mouseleave="vm.hideDetailsOverlay()">
|
||||
<li ng-repeat="systemDataType in result.dataTypes | orderBy:'name'"
|
||||
ng-mouseover="vm.showDetailsOverlay(systemDataType)"
|
||||
ng-click="vm.pickEditor(systemDataType)">
|
||||
<a class="umb-card-grid-item" href="" title="{{systemDataType.name}}">
|
||||
ng-click="vm.pickEditor(systemDataType)"
|
||||
class="cursor-pointer">
|
||||
<span class="umb-card-grid-item" title="{{systemDataType.name}}">
|
||||
<span>
|
||||
<i class="{{systemDataType.icon}}" ng-class="{'icon-autofill': systemDataType.icon == null}"></i>
|
||||
{{systemDataType.name}}
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
placeholder="@general_url"
|
||||
class="umb-property-editor umb-textstring"
|
||||
ng-model="model.target.url"
|
||||
umb-auto-focus
|
||||
ng-disabled="model.target.id || model.target.udi" />
|
||||
</umb-control-group>
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ angular.module("umbraco")
|
||||
var dialogOptions = $scope.model;
|
||||
|
||||
$scope.disableFolderSelect = (dialogOptions.disableFolderSelect && dialogOptions.disableFolderSelect !== "0") ? true : false;
|
||||
$scope.disableFocalPoint = (dialogOptions.disableFocalPoint && dialogOptions.disableFocalPoint !== "0") ? true : false;
|
||||
$scope.onlyImages = (dialogOptions.onlyImages && dialogOptions.onlyImages !== "0") ? true : false;
|
||||
$scope.onlyFolders = (dialogOptions.onlyFolders && dialogOptions.onlyFolders !== "0") ? true : false;
|
||||
$scope.showDetails = (dialogOptions.showDetails && dialogOptions.showDetails !== "0") ? true : false;
|
||||
@@ -137,7 +138,8 @@ angular.module("umbraco")
|
||||
$scope.target = node;
|
||||
if (ensureWithinStartNode(node)) {
|
||||
selectMedia(node);
|
||||
$scope.target.url = mediaHelper.resolveFile(node);
|
||||
$scope.target.url = mediaHelper.resolveFileFromEntity(node);
|
||||
$scope.target.thumbnail = mediaHelper.resolveFileFromEntity(node, true);
|
||||
$scope.target.altText = altText;
|
||||
openDetailsDialog();
|
||||
}
|
||||
@@ -333,22 +335,26 @@ angular.module("umbraco")
|
||||
}
|
||||
|
||||
function openDetailsDialog() {
|
||||
localizationService.localize("defaultdialogs_editSelectedMedia").then(function (data) {
|
||||
vm.mediaPickerDetailsOverlay = {
|
||||
show: true,
|
||||
title: data,
|
||||
disableFocalPoint: $scope.disableFocalPoint,
|
||||
submit: function (model) {
|
||||
$scope.model.selection.push($scope.target);
|
||||
$scope.model.submit($scope.model);
|
||||
|
||||
vm.mediaPickerDetailsOverlay = {
|
||||
show: true,
|
||||
submit: function (model) {
|
||||
vm.mediaPickerDetailsOverlay.show = false;
|
||||
vm.mediaPickerDetailsOverlay = null;
|
||||
},
|
||||
close: function (oldModel) {
|
||||
vm.mediaPickerDetailsOverlay.show = false;
|
||||
vm.mediaPickerDetailsOverlay = null;
|
||||
|
||||
$scope.model.selection.push($scope.target);
|
||||
$scope.model.submit($scope.model);
|
||||
|
||||
vm.mediaPickerDetailsOverlay.show = false;
|
||||
vm.mediaPickerDetailsOverlay = null;
|
||||
},
|
||||
close: function (oldModel) {
|
||||
vm.mediaPickerDetailsOverlay.show = false;
|
||||
vm.mediaPickerDetailsOverlay = null;
|
||||
}
|
||||
};
|
||||
close();
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
var debounceSearchMedia = _.debounce(function () {
|
||||
|
||||
@@ -1,198 +1,224 @@
|
||||
<div ng-controller="Umbraco.Editors.MediaPickerController as vm">
|
||||
<umb-editor-view >
|
||||
<umb-editor-view >
|
||||
|
||||
<umb-editor-header
|
||||
name="model.title"
|
||||
name-locked="true"
|
||||
hide-alias="true"
|
||||
hide-icon="true"
|
||||
hide-description="true">
|
||||
</umb-editor-header>
|
||||
<umb-editor-header
|
||||
name="model.title"
|
||||
name-locked="true"
|
||||
hide-alias="true"
|
||||
hide-icon="true"
|
||||
hide-description="true">
|
||||
</umb-editor-header>
|
||||
|
||||
<umb-editor-container>
|
||||
<umb-editor-container>
|
||||
|
||||
<form id="fileupload" method="POST" enctype="multipart/form-data" umb-image-upload="options">
|
||||
<form id="fileupload" method="POST" enctype="multipart/form-data" umb-image-upload="options">
|
||||
|
||||
<div on-drag-leave="vm.dragLeave()" on-drag-end="vm.dragLeave()" on-drag-enter="vm.dragEnter()">
|
||||
<div on-drag-leave="vm.dragLeave()" on-drag-end="vm.dragLeave()" on-drag-enter="vm.dragEnter()">
|
||||
|
||||
<div class="umb-control-group umb-mediapicker-upload">
|
||||
<div class="umb-control-group umb-mediapicker-upload">
|
||||
|
||||
<umb-load-indicator
|
||||
ng-if="vm.loading">
|
||||
</umb-load-indicator>
|
||||
<umb-load-indicator
|
||||
ng-if="vm.loading">
|
||||
</umb-load-indicator>
|
||||
|
||||
<div class="form-search">
|
||||
<i class="icon-search" aria-hidden="true"></i>
|
||||
<input class="umb-search-field search-query -full-width-input"
|
||||
ng-model="vm.searchOptions.filter"
|
||||
localize="placeholder"
|
||||
placeholder="@placeholders_search"
|
||||
ng-change="vm.changeSearch()"
|
||||
type="text"
|
||||
no-dirty-check />
|
||||
<div class="form-search">
|
||||
<i class="icon-search" aria-hidden="true"></i>
|
||||
<input class="umb-search-field search-query -full-width-input"
|
||||
ng-model="vm.searchOptions.filter"
|
||||
localize="placeholder"
|
||||
placeholder="@placeholders_search"
|
||||
ng-change="vm.changeSearch()"
|
||||
type="text"
|
||||
umb-auto-focus
|
||||
no-dirty-check
|
||||
/>
|
||||
|
||||
<div class="form-search__toggle">
|
||||
<label>
|
||||
<input type="checkbox" ng-model="showChilds" ng-change="vm.toggle()" />
|
||||
<localize key="general_includeFromsubFolders">Include subfolders in search</localize>
|
||||
</label>
|
||||
<div class="form-search__toggle">
|
||||
<umb-checkbox
|
||||
model="showChilds"
|
||||
on-change="vm.toggle()"
|
||||
text="Include subfolders in search"
|
||||
label-key="general_includeFromsubFolders">
|
||||
</umb-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="upload-button">
|
||||
<umb-button
|
||||
type="button"
|
||||
label-key="general_upload"
|
||||
action="vm.upload()"
|
||||
disabled="lockedFolder"
|
||||
button-style="action">
|
||||
</umb-button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="upload-button">
|
||||
<umb-button
|
||||
type="button"
|
||||
label-key="general_upload"
|
||||
action="vm.upload()"
|
||||
disabled="lockedFolder"
|
||||
button-style="action">
|
||||
</umb-button>
|
||||
<div class="row umb-control-group" ng-show="!vm.searchOptions.filter">
|
||||
<ul class="umb-breadcrumbs">
|
||||
<li ng-hide="startNodeId != -1" class="umb-breadcrumbs__ancestor">
|
||||
<button type="button" class="umb-breadcrumbs__action" ng-click="vm.gotoFolder()">
|
||||
<localize key="treeHeaders_media">Media</localize>
|
||||
</button>
|
||||
<span class="umb-breadcrumbs__separator" aria-hidden="true">/</span>
|
||||
</li>
|
||||
|
||||
<li ng-repeat="item in path" class="umb-breadcrumbs__ancestor">
|
||||
<button type="button" class="umb-breadcrumbs__action" ng-click="vm.gotoFolder(item)">{{item.name}}</button>
|
||||
<span class="umb-breadcrumbs__separator" aria-hidden="true">/</span>
|
||||
</li>
|
||||
|
||||
<li class="umb-breadcrumbs__ancestor" ng-show="!lockedFolder">
|
||||
<button type="button" class="umb-breadcrumbs__action" ng-hide="model.showFolderInput" ng-click="model.showFolderInput = true">
|
||||
<i class="icon icon-add small" aria-hidden="true"></i>
|
||||
<span class="sr-only">
|
||||
<localize key="visuallyHiddenTexts_createNewFolder">Create new folder</localize>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<input type="text"
|
||||
class="umb-breadcrumbs__add-ancestor"
|
||||
ng-show="model.showFolderInput"
|
||||
ng-model="model.newFolderName"
|
||||
ng-keydown="enterSubmitFolder($event)"
|
||||
ng-blur="vm.submitFolder()"
|
||||
focus-when="{{model.showFolderInput}}"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="umb-loader" ng-if="model.creatingFolder"></div>
|
||||
</div>
|
||||
|
||||
<umb-file-dropzone
|
||||
ng-if="vm.acceptedMediatypes.length > 0 && !vm.loading && !lockedFolder"
|
||||
accepted-mediatypes="vm.acceptedMediatypes"
|
||||
parent-id="{{currentFolder.id}}"
|
||||
files-uploaded="vm.onUploadComplete"
|
||||
files-queued="vm.onFilesQueue"
|
||||
accept="{{vm.acceptedFileTypes}}"
|
||||
max-file-size="{{vm.maxFileSize}}"
|
||||
hide-dropzone="{{ !activeDrag && (images.length > 0 || vm.searchOptions.filter !== '') }}"
|
||||
compact="{{ images.length > 0 }}">
|
||||
</umb-file-dropzone>
|
||||
|
||||
<umb-media-grid
|
||||
ng-if="!vm.loading"
|
||||
items="images"
|
||||
on-click="vm.clickHandler"
|
||||
on-click-name="vm.clickItemName"
|
||||
on-click-edit="vm.editMediaItem(item)"
|
||||
allow-on-click-edit="{{allowMediaEdit}}"
|
||||
item-max-width="150"
|
||||
item-max-height="150"
|
||||
item-min-width="100"
|
||||
item-min-height="100"
|
||||
disable-folder-select={{disableFolderSelect}}
|
||||
only-images={{onlyImages}}
|
||||
only-folders={{onlyFolders}}
|
||||
include-sub-folders={{showChilds}}
|
||||
current-folder-id="{{currentFolder.id}}">
|
||||
</umb-media-grid>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<umb-pagination
|
||||
ng-if="vm.searchOptions.totalPages > 0 && !vm.loading"
|
||||
page-number="vm.searchOptions.pageNumber"
|
||||
total-pages="vm.searchOptions.totalPages"
|
||||
on-change="vm.changePagination(pageNumber)">
|
||||
</umb-pagination>
|
||||
</div>
|
||||
|
||||
<umb-empty-state ng-if="vm.searchOptions.filter && images.length === 0 && !vm.loading && !activeDrag" position="center">
|
||||
<localize key="general_searchNoResult"></localize>
|
||||
</umb-empty-state>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row umb-control-group" ng-show="!vm.searchOptions.filter">
|
||||
<ul class="umb-breadcrumbs">
|
||||
<li ng-hide="startNodeId != -1" class="umb-breadcrumbs__ancestor">
|
||||
<a href ng-click="vm.gotoFolder()" prevent-default><localize key="treeHeaders_media">Media</localize></a>
|
||||
<span class="umb-breadcrumbs__separator">/</span>
|
||||
</li>
|
||||
|
||||
<li ng-repeat="item in path" class="umb-breadcrumbs__ancestor">
|
||||
<a href ng-click="vm.gotoFolder(item)" prevent-default>{{item.name}}</a>
|
||||
<span class="umb-breadcrumbs__separator">/</span>
|
||||
</li>
|
||||
|
||||
<li class="umb-breadcrumbs__ancestor" ng-show="!lockedFolder">
|
||||
<a role="button" aria-label="Create new folder" ng-hide="model.showFolderInput" ng-click="model.showFolderInput = true">
|
||||
<i class="icon icon-add small"></i>
|
||||
</a>
|
||||
|
||||
<input type="text" class="umb-breadcrumbs__add-ancestor" ng-show="model.showFolderInput" ng-model="model.newFolderName" ng-keydown="enterSubmitFolder($event)"
|
||||
ng-blur="vm.submitFolder()" focus-when="{{model.showFolderInput}}" />
|
||||
</li>
|
||||
</ul>
|
||||
<div class="umb-loader" ng-if="model.creatingFolder"></div>
|
||||
<umb-overlay ng-if="vm.mediaPickerDetailsOverlay.show" model="vm.mediaPickerDetailsOverlay" position="right">
|
||||
|
||||
<div class="umb-control-group" ng-if="!target.id">
|
||||
<h5>
|
||||
<localize key="@general_url"></localize>
|
||||
</h5>
|
||||
<input type="text" localize="placeholder" placeholder="@general_url" class="umb-property-editor umb-textstring" ng-model="target.url" />
|
||||
</div>
|
||||
|
||||
<umb-file-dropzone
|
||||
ng-if="vm.acceptedMediatypes.length > 0 && !vm.loading && !lockedFolder"
|
||||
accepted-mediatypes="vm.acceptedMediatypes"
|
||||
parent-id="{{currentFolder.id}}"
|
||||
files-uploaded="vm.onUploadComplete"
|
||||
files-queued="vm.onFilesQueue"
|
||||
accept="{{vm.acceptedFileTypes}}"
|
||||
max-file-size="{{vm.maxFileSize}}"
|
||||
hide-dropzone="{{ !activeDrag && (images.length > 0 || vm.searchOptions.filter !== '') }}"
|
||||
compact="{{ images.length > 0 }}">
|
||||
</umb-file-dropzone>
|
||||
|
||||
<umb-media-grid
|
||||
ng-if="!vm.loading"
|
||||
items="images"
|
||||
on-click="vm.clickHandler"
|
||||
on-click-name="vm.clickItemName"
|
||||
on-click-edit="vm.editMediaItem(item)"
|
||||
allow-on-click-edit="{{allowMediaEdit}}"
|
||||
item-max-width="150"
|
||||
item-max-height="150"
|
||||
item-min-width="100"
|
||||
item-min-height="100"
|
||||
disable-folder-select={{disableFolderSelect}}
|
||||
only-images={{onlyImages}}
|
||||
only-folders={{onlyFolders}}
|
||||
include-sub-folders={{showChilds}}
|
||||
current-folder-id="{{currentFolder.id}}">
|
||||
</umb-media-grid>
|
||||
|
||||
<div class="flex justify-center">
|
||||
<umb-pagination
|
||||
ng-if="vm.searchOptions.totalPages > 0 && !vm.loading"
|
||||
page-number="vm.searchOptions.pageNumber"
|
||||
total-pages="vm.searchOptions.totalPages"
|
||||
on-change="vm.changePagination(pageNumber)">
|
||||
</umb-pagination>
|
||||
<div class="umb-control-group">
|
||||
<h5>
|
||||
<localize key="@content_altTextOptional"></localize>
|
||||
</h5>
|
||||
<input type="text" class="umb-property-editor umb-textstring" ng-model="target.altText" />
|
||||
</div>
|
||||
|
||||
<umb-empty-state ng-if="vm.searchOptions.filter && images.length === 0 && !vm.loading && !activeDrag" position="center">
|
||||
<localize key="general_searchNoResult"></localize>
|
||||
</umb-empty-state>
|
||||
|
||||
</div>
|
||||
|
||||
<umb-overlay ng-if="vm.mediaPickerDetailsOverlay.show" model="vm.mediaPickerDetailsOverlay" position="right">
|
||||
|
||||
<div class="umb-control-group">
|
||||
|
||||
<div ng-if="target.url">
|
||||
<umb-image-gravity
|
||||
src="target.url"
|
||||
center="target.focalPoint"
|
||||
on-value-changed="vm.focalPointChanged(left, top)">
|
||||
</umb-image-gravity>
|
||||
</div>
|
||||
|
||||
<div ng-if="cropSize">
|
||||
|
||||
<div ng-if="vm.mediaPickerDetailsOverlay.disableFocalPoint && target.thumbnail">
|
||||
<h5>
|
||||
<localize key="general_preview">Preview</localize>
|
||||
</h5>
|
||||
|
||||
<umb-image-thumbnail center="target.focalPoint"
|
||||
src="target.url"
|
||||
height="{{cropSize.height}}"
|
||||
width="{{cropSize.width}}"
|
||||
max-size="400">
|
||||
</umb-image-thumbnail>
|
||||
<img ng-src="{{target.thumbnail}}" alt="{{target.name}}" />
|
||||
</div>
|
||||
|
||||
<div ng-if="!vm.mediaPickerDetailsOverlay.disableFocalPoint">
|
||||
<h5>
|
||||
<localize key="@general_focalPoint">Focal point</localize>
|
||||
</h5>
|
||||
|
||||
<div ng-if="target.url">
|
||||
<umb-image-gravity src="target.url"
|
||||
center="target.focalPoint"
|
||||
on-value-changed="vm.focalPointChanged(left, top)">
|
||||
</umb-image-gravity>
|
||||
</div>
|
||||
|
||||
<div ng-if="cropSize">
|
||||
|
||||
<h5>
|
||||
<localize key="general_preview">Preview</localize>
|
||||
</h5>
|
||||
|
||||
<umb-image-thumbnail center="target.focalPoint"
|
||||
src="target.url"
|
||||
height="{{cropSize.height}}"
|
||||
width="{{cropSize.width}}"
|
||||
max-size="400">
|
||||
</umb-image-thumbnail>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</umb-overlay>
|
||||
|
||||
<div class="umb-control-group">
|
||||
<label>
|
||||
<localize key="@general_url"></localize>
|
||||
</label>
|
||||
<input type="text" localize="placeholder" placeholder="@general_url" class="umb-property-editor umb-textstring" ng-model="target.url"
|
||||
ng-disabled="target.id" />
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="umb-control-group">
|
||||
<label>
|
||||
<localize key="@content_altTextOptional"></localize>
|
||||
</label>
|
||||
<input type="text" class="umb-property-editor umb-textstring" ng-model="target.altText" />
|
||||
</div>
|
||||
</umb-editor-container>
|
||||
|
||||
<umb-editor-footer>
|
||||
<umb-editor-footer-content-right>
|
||||
|
||||
</umb-overlay>
|
||||
<umb-button
|
||||
action="vm.close()"
|
||||
button-style="link"
|
||||
shortcut="esc"
|
||||
label-key="general_close"
|
||||
type="button">
|
||||
</umb-button>
|
||||
|
||||
</form>
|
||||
<umb-button
|
||||
button-style="success"
|
||||
label-key="buttons_select"
|
||||
type="button"
|
||||
disabled="model.selection.length === 0"
|
||||
action="vm.submit(model)">
|
||||
</umb-button>
|
||||
|
||||
</umb-editor-container>
|
||||
</umb-editor-footer-content-right>
|
||||
</umb-editor-footer>
|
||||
|
||||
<umb-editor-footer>
|
||||
<umb-editor-footer-content-right>
|
||||
</umb-editor-view>
|
||||
|
||||
<umb-button
|
||||
action="vm.close()"
|
||||
button-style="link"
|
||||
shortcut="esc"
|
||||
label-key="general_close"
|
||||
type="button">
|
||||
</umb-button>
|
||||
|
||||
<umb-button
|
||||
button-style="success"
|
||||
label-key="buttons_select"
|
||||
type="button"
|
||||
disabled="model.selection.length === 0"
|
||||
action="vm.submit(model)">
|
||||
</umb-button>
|
||||
|
||||
</umb-editor-footer-content-right>
|
||||
</umb-editor-footer>
|
||||
|
||||
</umb-editor-view>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
</li>
|
||||
|
||||
<li data-element="section-expand" class="expand" ng-class="{ 'open': showTray === true }" ng-show="needTray">
|
||||
<a href ng-click="trayClick()"><i></i><i></i><i></i></a>
|
||||
<a href="#" ng-click="trayClick()" prevent-default>
|
||||
<span class="section__name"><i></i><i></i><i></i></span>
|
||||
</a>
|
||||
|
||||
<ul id="applications-tray" class="sections-tray shadow-depth-2" ng-if="showTray" on-outside-click="trayClick()">
|
||||
<li ng-repeat="section in sections | limitTo: overflowingSections" ng-class="{current: section.alias == currentSection}">
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
ng-class="{'name-is-empty': $parent.name===null || $parent.name===''}"
|
||||
ng-disabled="nameDisabled"
|
||||
umb-auto-focus
|
||||
focus-on-filled="true"
|
||||
val-server-field="{{serverValidationNameField}}"
|
||||
required
|
||||
aria-required="true"
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
ng-model="name"
|
||||
ng-class="{'name-is-empty': $parent.name===null || $parent.name===''}"
|
||||
umb-auto-focus
|
||||
focus-on-filled="true"
|
||||
val-server-field="Name"
|
||||
required
|
||||
autocomplete="off" />
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
<div class="umb-editor"
|
||||
ng-repeat="model in editors"
|
||||
ng-class="{'umb-editor--small': model.size === 'small',
|
||||
'umb-editor--medium': model.size === 'medium',
|
||||
'umb-editor--animating': model.animating,
|
||||
'--notInFront': model.inFront !== true,
|
||||
'umb-editor--notInFront': model.inFront !== true,
|
||||
'umb-editor--infiniteMode': model.infiniteMode,
|
||||
'moveRight': model.moveRight,
|
||||
'umb-editor--moveRight': model.moveRight,
|
||||
'umb-editor--n0': model.styleIndex === 0,
|
||||
'umb-editor--n1': model.styleIndex === 1,
|
||||
'umb-editor--n2': model.styleIndex === 2,
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<ul role="tablist" class="umb-tabs-nav">
|
||||
<li class="umb-tab" role="tab" aria-selected="true" tabindex="0" ng-repeat="tab in vm.tabs | limitTo: vm.maxTabs" data-element="tab-{{tab.alias}}" ng-class="{'umb-tab--active': tab.active, 'umb-tab--error': tabHasError}" val-tab>
|
||||
<a ng-href="" ng-click="vm.clickTab($event, tab)">{{ tab.label }}</a>
|
||||
<li ng-click="vm.clickTab($event, tab)" class="umb-tab" role="tab" aria-selected="true" tabindex="0" ng-repeat="tab in vm.tabs | limitTo: vm.maxTabs" data-element="tab-{{tab.alias}}" ng-class="{'umb-tab--active': tab.active, 'umb-tab--error': tabHasError}" val-tab>
|
||||
<a>{{ tab.label }}</a>
|
||||
</li>
|
||||
|
||||
<li data-element="tab-expand" class="umb-tab umb-tab--expand" ng-class="{ 'open': vm.showTray }" ng-show="vm.needTray">
|
||||
<a ng-href="" ng-click="vm.toggleTray()"><i></i><i></i><i></i></a>
|
||||
<li data-element="tab-expand" class="umb-tab umb-tab--expand" tabindex="0" ng-click="vm.toggleTray()" ng-class="{ 'open': vm.showTray }" ng-show="vm.needTray">
|
||||
<a ng-href=""><i></i><i></i><i></i></a>
|
||||
<umb-dropdown class="umb-tabs-tray" ng-if="vm.showTray" on-close="vm.hideTray()">
|
||||
<umb-dropdown-item ng-repeat="tab in vm.tabs | limitTo: vm.overflowingTabs" ng-class="{'umb-tabs-tray-item--active': tab.active}">
|
||||
<a ng-href="" href="" ng-click="vm.clickTab($event, tab)">{{ tab.label }}</a>
|
||||
<umb-dropdown-item ng-repeat="tab in vm.tabs | limitTo: vm.overflowingTabs" ng-class="{'umb-tabs-tray-item--active': tab.active}" tabindex="0" ng-click="vm.clickTab($event, tab)">
|
||||
<a ng-href="">{{ tab.label }}</a>
|
||||
</umb-dropdown-item>
|
||||
</umb-dropdown>
|
||||
</li>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<li class="umb-tree-item" data-element="tree-item-{{::node.dataElement}}" ng-class="getNodeCssClass(node)" on-right-click="altSelect(node, $event)">
|
||||
<div class="umb-tree-item__inner" ng-swipe-right="options(node, $event)" ng-dblclick="load(node)" >
|
||||
<div class="umb-tree-item__inner" ng-swipe-right="options(node, $event)" ng-dblclick="load(node)" tabindex="-1">
|
||||
<button data-element="tree-item-expand"
|
||||
class="umb-tree-item__arrow umb-outline btn-reset"
|
||||
ng-class="{'icon-navigation-right': !node.expanded || node.metaData.isContainer, 'icon-navigation-down': node.expanded && !node.metaData.isContainer}"
|
||||
@@ -9,7 +9,7 @@
|
||||
<span class="sr-only">Expand child items for {{node.name}}</span>
|
||||
</button>
|
||||
|
||||
<i class="icon umb-tree-icon sprTree" ng-class="::node.cssClass" title="{{::node.title}}" ng-click="select(node, $event)" ng-style="::node.style"></i>
|
||||
<i class="icon umb-tree-icon sprTree" ng-class="::node.cssClass" title="{{::node.title}}" ng-click="select(node, $event)" ng-style="::node.style" tabindex="-1"></i>
|
||||
<span class="umb-tree-item__annotation"></span>
|
||||
<a class="umb-tree-item__label umb-outline" ng-href="#/{{::node.routePath}}" ng-click="select(node, $event)" title="{{::node.title}}">{{node.name}}</a>
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
<localize key="contentTypeEditor_noGroups"></localize>
|
||||
</div>
|
||||
|
||||
<a ng-if="!sortingMode" hotkey="alt+shift+p" ng-click="addPropertyToActiveGroup()"></a>
|
||||
|
||||
<ul class="umb-group-builder__groups" ui-sortable="sortableOptionsGroup" ng-model="model.groups">
|
||||
|
||||
<li ng-repeat="tab in model.groups" ng-class="{'umb-group-builder__group-sortable': sortingMode}" data-element="group-{{tab.name}}">
|
||||
@@ -47,7 +49,7 @@
|
||||
</a>
|
||||
|
||||
<!-- TAB ACTIVE OR INACTIVE STATE -->
|
||||
<div class="umb-group-builder__group" ng-if="tab.tabState !== 'init'" ng-class="{'-active':tab.tabState=='active', '-inherited': tab.inherited, 'umb-group-builder__group-handle -sortable': sortingMode && !tab.inherited}" ng-click="activateGroup(tab)">
|
||||
<div class="umb-group-builder__group" ng-if="tab.tabState !== 'init'" ng-class="{'-active':tab.tabState=='active', '-inherited': tab.inherited, 'umb-group-builder__group-handle -sortable': sortingMode && !tab.inherited}" tabindex="0" ng-focus="activateGroup(tab)">
|
||||
|
||||
<div class="umb-group-builder__group-title-wrapper">
|
||||
|
||||
@@ -119,8 +121,6 @@
|
||||
data-element="property-add"
|
||||
class="umb-group-builder__group-add-property"
|
||||
ng-if="property.propertyState=='init' && !sortingMode"
|
||||
hotkey="alt+shift+p"
|
||||
hotkey-when="{{tab.tabState === 'active' && property.propertyState=='init'}}"
|
||||
ng-click="addProperty(property, tab)"
|
||||
ng-focus="activateGroup(tab)"
|
||||
focus-when="{{property.focus}}">
|
||||
@@ -135,7 +135,7 @@
|
||||
<ng-form name="propertyTypeForm">
|
||||
<div class="control-group -no-margin" ng-if="!sortingMode">
|
||||
|
||||
<div class="umb-group-builder__property-meta-alias" ng-if="property.inherited || property.locked">{{ property.alias }}</div>
|
||||
<div class="umb-group-builder__property-meta-alias umb-locked-field__text cursor-not-allowed" style="padding-left: 1px" ng-if="property.inherited || property.locked">{{ property.alias }}</div>
|
||||
<umb-locked-field
|
||||
ng-if="!property.inherited && !property.locked"
|
||||
locked="locked"
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<umb-editor-view>
|
||||
<umb-editor-header
|
||||
name="model.title"
|
||||
name-locked="true"
|
||||
hide-alias="true"
|
||||
hide-description="model.hideDescription"
|
||||
hide-icon="model.hideIcon">
|
||||
</umb-editor-header>
|
||||
<umb-editor-container class="umb-list-view-settings__overlay">
|
||||
<form name="listViewSettingsForm" novalidate val-form-manager>
|
||||
<umb-box>
|
||||
<umb-box-content>
|
||||
<!-- list view settings -->
|
||||
<umb-property property="preValue" ng-repeat="preValue in model.dataType.preValues">
|
||||
<umb-property-editor model="preValue" is-pre-value="true"></umb-property-editor>
|
||||
</umb-property>
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
</form>
|
||||
</umb-editor-container>
|
||||
<umb-editor-footer>
|
||||
<umb-editor-footer-content-right>
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="link"
|
||||
label-key="general_close"
|
||||
action="model.close()">
|
||||
</umb-button>
|
||||
<umb-button
|
||||
type="button"
|
||||
button-style="success"
|
||||
label-key="buttons_saveListView"
|
||||
action="model.submit(model)">
|
||||
</umb-button>
|
||||
</umb-editor-footer-content-right>
|
||||
</umb-editor-footer>
|
||||
</umb-editor-view>
|
||||
@@ -9,35 +9,41 @@
|
||||
</div>
|
||||
|
||||
<!-- list view enabled -->
|
||||
<div ng-if="enableListView">
|
||||
<div class="umb-list-view-settings__box" ng-class="{'-open': editDataTypeSettings}">
|
||||
|
||||
<div class="umb-list-view-settings__content">
|
||||
<div ng-if="enableListView" class="flex">
|
||||
<div class="umb-list-view-settings__box">
|
||||
<div class="flex">
|
||||
<i class="umb-list-view-settings__list-view-icon icon-list"></i>
|
||||
<div>
|
||||
<div>
|
||||
<div class="umb-list-view-settings__name">{{ dataType.name }} <em ng-if="!customListViewCreated">(<localize key="general_default">default</localize>)</em></div>
|
||||
<a href="" ng-click="toggleEditListViewDataTypeSettings()"><i class="umb-list-view-settings__settings-icon icon-settings"></i></a>
|
||||
<div class="umb-list-view-settings__name">
|
||||
{{ dataType.name }}
|
||||
<em ng-if="!customListViewCreated">(<localize key="general_default">default</localize>)</em>
|
||||
</div>
|
||||
<a href="" class="umb-list-view-settings__create-new" ng-if="!customListViewCreated" ng-click="createCustomListViewDataType()"><localize key="editcontenttype_createListView">Create custom list view</localize></a>
|
||||
<a href="" class="umb-list-view-settings__remove-new" ng-if="customListViewCreated" ng-click="removeCustomListDataType()"><localize key="editcontenttype_removeListView">Remove custom list view</localize></a>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-link umb-list-view-settings__create-new"
|
||||
ng-if="!customListViewCreated"
|
||||
ng-click="createCustomListViewDataType()">
|
||||
<localize key="editcontenttype_createListView">Create custom list view</localize>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-link umb-list-view-settings__remove-new"
|
||||
ng-if="customListViewCreated"
|
||||
ng-click="removeCustomListDataType()">
|
||||
<localize key="editcontenttype_removeListView">Remove custom list view</localize>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- list view settings -->
|
||||
<div class="umb-list-view-settings__settings form-horizontal" ng-if="editDataTypeSettings" ng-class="{'-open': editDataTypeSettings}">
|
||||
|
||||
<umb-property property="preValue" ng-repeat="preValue in dataType.preValues">
|
||||
<umb-property-editor model="preValue" is-pre-value="true"></umb-property-editor>
|
||||
</umb-property>
|
||||
|
||||
<div class="text-right">
|
||||
<button type="button" class="btn btn-link" ng-click="toggleEditListViewDataTypeSettings()"><localize key="general_close">Close</localize></button>
|
||||
<button type="button" class="btn btn-success" ng-click="saveListViewDataType()"><localize key="buttons_saveListView"></localize></button>
|
||||
<umb-load-indicator ng-show="loading"></umb-load-indicator>
|
||||
</div>
|
||||
<div class="umb-group-builder__property-actions">
|
||||
<div class="umb-group-builder__property-action">
|
||||
<button
|
||||
class="btn-icon icon-settings"
|
||||
ng-click="showSettingsOverlay()"
|
||||
aria-label="Edit"></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
function ContentSortController($scope, $filter, $routeParams, contentResource, navigationService) {
|
||||
|
||||
var vm = this;
|
||||
var parentId = $scope.currentNode.parentId ? $scope.currentNode.parentId : "-1";
|
||||
var id = $scope.currentNode.id;
|
||||
|
||||
vm.loading = false;
|
||||
@@ -42,7 +41,7 @@
|
||||
vm.saveButtonState = "busy";
|
||||
|
||||
var args = {
|
||||
parentId: parentId,
|
||||
parentId: id,
|
||||
sortedIds: _.map(vm.children, function(child){ return child.id; })
|
||||
};
|
||||
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
text="{{ variant.language.name }}"
|
||||
/>
|
||||
<div>
|
||||
<strong ng-if="variant.language.isMandatory" class="umb-control-required">*</strong>
|
||||
|
||||
<span class="db umb-list-item__description umb-list-item__description--checkbox" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-if="variant.language.isMandatory"> - </span>
|
||||
|
||||
@@ -48,8 +48,6 @@
|
||||
|
||||
<div>
|
||||
<span class="db umb-list-item__description umb-list-item__description--checkbox" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<span>{{variant.language.name}}</span>
|
||||
|
||||
<span class="db umb-list-item__description" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-if="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
|
||||
@@ -60,6 +58,7 @@
|
||||
</span>
|
||||
|
||||
<umb-variant-notification-list notifications="variant.notifications"></umb-variant-notification-list>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -29,10 +29,9 @@
|
||||
/>
|
||||
|
||||
<div>
|
||||
<strong ng-if="variant.language.isMandatory" class="umb-control-required">*</strong>
|
||||
|
||||
<span class="db" ng-if="!saveVariantSelectorForm.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state class="umb-list-item__description umb-list-item__description--checkbox" variant="variant"></umb-variant-state>
|
||||
<span class="db umb-list-item__description umb-list-item__description--checkbox" ng-if="!saveVariantSelectorForm.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-if="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
|
||||
</span>
|
||||
|
||||
<span class="db" ng-messages="saveVariantSelectorForm.saveVariantSelector.$error" show-validation-on-submit>
|
||||
|
||||
@@ -24,10 +24,9 @@
|
||||
/>
|
||||
|
||||
<div>
|
||||
<strong ng-if="variant.language.isMandatory" class="umb-control-required">*</strong>
|
||||
|
||||
<span class="db" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state class="umb-list-item__description umb-list-item__description--checkbox" variant="variant"></umb-variant-state>
|
||||
<span class="db umb-list-item__description umb-list-item__description--checkbox" ng-if="!publishVariantSelectorForm.publishVariantSelector.$invalid && !(variant.notifications && variant.notifications.length > 0)">
|
||||
<umb-variant-state variant="variant"></umb-variant-state>
|
||||
<span ng-if="variant.language.isMandatory"> - <localize key="languages_mandatoryLanguage"></localize></span>
|
||||
</span>
|
||||
|
||||
<span class="db" ng-messages="publishVariantSelectorForm.publishVariantSelector.$error" show-validation-on-submit>
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
</umb-dropdown-item>
|
||||
|
||||
<umb-dropdown-item>
|
||||
<a ng-href="https://www.google.co.uk/?q=site:our.umbraco.org {{ log.RenderedMessage }}&safe=off#q=site:our.umbraco.org {{ log.RenderedMessage }} {{ log.Properties['SourceContext'].Value }}&safe=off" target="_blank" title="Search Our Umbraco forums using Google">
|
||||
<a ng-href="https://www.google.co.uk/?q=site:our.umbraco.com {{ log.RenderedMessage }}&safe=off#q=site:our.umbraco.com {{ log.RenderedMessage }} {{ log.Properties['SourceContext'].Value }}&safe=off" target="_blank" title="Search Our Umbraco forums using Google">
|
||||
<img src="https://www.google.com/favicon.ico" width="16" height="16" /> Search Our Umbraco with Google
|
||||
</a>
|
||||
</umb-dropdown-item>
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
function MediaSortController($scope, $filter, mediaResource, navigationService) {
|
||||
|
||||
var vm = this;
|
||||
var parentId = $scope.currentNode.parentId ? $scope.currentNode.parentId : "-1";
|
||||
var id = $scope.currentNode.id;
|
||||
|
||||
vm.loading = false;
|
||||
@@ -42,7 +41,7 @@
|
||||
vm.saveButtonState = "busy";
|
||||
|
||||
var args = {
|
||||
parentId: parentId,
|
||||
parentId: id,
|
||||
sortedIds: _.map(vm.children, function(child){ return child.id; })
|
||||
};
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
view: "views/packages/overlays/delete.html",
|
||||
package: createdPackage,
|
||||
submitButtonLabelKey: "contentTypeEditor_yesDelete",
|
||||
submitButtonStyle:"danger",
|
||||
submit: function (model) {
|
||||
performDelete(index, createdPackage);
|
||||
overlayService.close();
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
<div class="umb-package-details__owner-profile-avatar">
|
||||
<umb-avatar
|
||||
size="m"
|
||||
img-src="{{ 'https://our.umbraco.org' + vm.package.ownerInfo.ownerAvatar }}">
|
||||
img-src="{{ 'https://our.umbraco.com' + vm.package.ownerInfo.ownerAvatar }}">
|
||||
</umb-avatar>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -69,9 +69,17 @@
|
||||
}).then(function (saved) {
|
||||
// create macro if needed
|
||||
if($routeParams.create && $routeParams.nomacro !== "true") {
|
||||
macroResource.createPartialViewMacroWithFile(saved.virtualPath, saved.name).then(function(created) {
|
||||
macroResource.createPartialViewMacroWithFile(saved.virtualPath, saved.name).then(function (created) {
|
||||
navigationService.syncTree({
|
||||
tree: "macros",
|
||||
path: '-1,new',
|
||||
forceReload: true,
|
||||
activate: false
|
||||
});
|
||||
completeSave(saved);
|
||||
}, angular.noop);
|
||||
|
||||
|
||||
} else {
|
||||
completeSave(saved);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,11 @@ function TreeSourceTypePickerController($scope, contentTypeResource, mediaTypeRe
|
||||
|
||||
var editor = {
|
||||
multiPicker: true,
|
||||
filterCssClass: "not-allowed not-published",
|
||||
filter: function (item) {
|
||||
// filter out folders (containers), element types (for content) and already selected items
|
||||
return item.nodeType === "container" || item.metaData.isElement || !!_.findWhere(vm.itemTypes, { udi: item.udi });
|
||||
},
|
||||
submit: function (model) {
|
||||
var newItemTypes = _.map(model.selection,
|
||||
function(selected) {
|
||||
|
||||
@@ -2,24 +2,24 @@
|
||||
<div class="control-group">
|
||||
|
||||
<select ng-model="selectedField" ng-change="changeField()" val-highlight="{{hasError}}">
|
||||
<option ng-repeat="field in systemFields" value="_system_{{field.value}}">{{field.name}}</option>
|
||||
<option ng-repeat="field in systemFields" value="_system_{{field.value}}" ng-bind="field.name"></option>
|
||||
<option class="select-dash" disabled="disabled">----</option>
|
||||
<option ng-repeat="alias in propertyAliases" value="{{alias}}">{{alias}}</option>
|
||||
<option ng-repeat="alias in propertyAliases" value="{{alias}}" ng-bind="alias"></option>
|
||||
</select>
|
||||
<button type="button" class="btn" ng-click="addField()">
|
||||
<localize key="general_add">Add</localize>
|
||||
</button>
|
||||
<span class="help-inline">{{errorMsg}}</span>
|
||||
<span class="help-inline" ng-bind="errorMsg"</span>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<table ng-show="model.value.length > 0" class="table">
|
||||
<table ng-show="model.value.length > 0">
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width:20px;"></td>
|
||||
<th style="width:220px;">Alias</th>
|
||||
<td></td>
|
||||
<th>Alias</th>
|
||||
<th>Header</th>
|
||||
<th><localize key="template_template">Template</localize></th>
|
||||
<td style="width:100px;"></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody ui-sortable="sortableOptions" ng-model="model.value">
|
||||
@@ -28,11 +28,11 @@
|
||||
<i class="icon icon-navigation handle"></i>
|
||||
</td>
|
||||
<td>
|
||||
<span class="alias-value" ng-if="!val.isSystem">{{val.alias}}</span>
|
||||
<span class="alias-value" ng-if="val.isSystem == 1">
|
||||
{{val.alias}}
|
||||
</span>
|
||||
<em ng-show="val.isSystem == 1"><small>(system field)</small></em>
|
||||
<div class="list-view-layout__name flex-column content-start">
|
||||
<span class="list-view-layout__name-text" ng-if="!val.isSystem" ng-bind="val.alias"></span>
|
||||
<span class="list-view-layout__name-text" ng-if="val.isSystem == 1" ng-bind="val.alias"></span>
|
||||
<span class="list-view-layout__system" ng-show="val.isSystem == 1">(system field)</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ng-form name="headerForm" ng-if="!val.isSystem">
|
||||
@@ -52,7 +52,7 @@
|
||||
</ng-form>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-danger" ng-click="removeField(val)">Remove</button>
|
||||
<button type="button" class="btn-icon icon-trash" ng-click="removeField(val)" aria-label="Remove"></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
<div class="list-view-layout" ng-repeat="layout in model.value">
|
||||
|
||||
<i class="icon-navigation list-view-layout__sort-handle"></i>
|
||||
<i class="icon-navigation list-view-layout__sort-handle" aria-label="Sort"></i>
|
||||
|
||||
<div>
|
||||
|
||||
<a ng-if="layout.isSystem !== 1" href="" ng-click="vm.openIconPicker(layout)" class="list-view-layout__icon" umb-auto-focus>
|
||||
<button ng-if="layout.isSystem !== 1" type="button" ng-click="vm.openIconPicker(layout)" class="list-view-layout__icon" umb-auto-focus>
|
||||
<i class="{{ layout.icon }}"></i>
|
||||
</a>
|
||||
</button>
|
||||
|
||||
<div ng-if="layout.isSystem === 1" class="list-view-layout__icon">
|
||||
<i class="{{ layout.icon }}"></i>
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input ng-if="layout.isSystem === 1" type="checkbox" ng-model="layout.selected" />
|
||||
<umb-checkbox ng-if="layout.isSystem === 1" model="layout.selected" />
|
||||
<div class="list-view-layout__remove" ng-if="layout.isSystem !== 1">
|
||||
<i class="icon-trash" ng-click="vm.showPrompt(layout)"></i>
|
||||
<umb-confirm-action
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<a href="" class="list-view-add-layout" ng-click="vm.addLayout()">Add layout</a>
|
||||
<button type="button" class="list-view-add-layout" ng-click="vm.addLayout()">Add layout</button>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
<div>
|
||||
<ng-form name="listViewOrderDirectionForm">
|
||||
<label class="radio">
|
||||
<input type="radio" name="orderDirection" value="asc" ng-model="model.value" />
|
||||
Ascending <code>[a-z]</code>
|
||||
</label>
|
||||
<label class="radio">
|
||||
<input type="radio" name="orderDirection" value="desc" ng-model="model.value" />
|
||||
Descending <code>[z-a]</code>
|
||||
</label>
|
||||
<ng-form name="listViewOrderDirectionForm" class="flex">
|
||||
<umb-radiobutton name="orderDirection" value="asc" model="model.value" text="Ascending [a-z]" required></umb-radiobutton>
|
||||
<umb-radiobutton name="orderDirection" value="desc" model="model.value" text="Descending [z-a]" required></umb-radiobutton>
|
||||
|
||||
<span ng-messages="listViewOrderDirectionForm.orderDirection.$error" show-validation-on-submit >
|
||||
<span ng-messages="listViewOrderDirectionForm.orderDirection.$error" show-validation-on-submit>
|
||||
<span class="help-inline" ng-message="required">Required</span>
|
||||
</span>
|
||||
</ng-form>
|
||||
|
||||
@@ -2,8 +2,46 @@
|
||||
|
||||
"$scope",
|
||||
"Umbraco.PropertyEditors.NestedContent.Resources",
|
||||
"overlayService",
|
||||
"localizationService",
|
||||
"iconHelper",
|
||||
|
||||
function ($scope, ncResources, overlayService, localizationService, iconHelper) {
|
||||
var selectElementTypeModalTitle = "";
|
||||
|
||||
$scope.elemTypeTabs = [];
|
||||
|
||||
|
||||
init();
|
||||
|
||||
|
||||
function init() {
|
||||
localizationService.localize("content_nestedContentSelectElementTypeModalTitle").then(function (value) {
|
||||
selectElementTypeModalTitle = value;
|
||||
});
|
||||
|
||||
ncResources.getContentTypes().then(function (elemTypes) {
|
||||
$scope.model.elemTypes = elemTypes;
|
||||
|
||||
// convert legacy icons
|
||||
iconHelper.formatContentTypeIcons($scope.model.elemTypes);
|
||||
|
||||
// Count doctype name occurrences
|
||||
var elTypeNameOccurrences= _.countBy(elemTypes, 'name');
|
||||
|
||||
// Populate document type tab dictionary
|
||||
// And append alias to name if multiple doctypes have the same name
|
||||
elemTypes.forEach(function (value) {
|
||||
$scope.elemTypeTabs[value.alias] = value.tabs;
|
||||
|
||||
if (elTypeNameOccurrences[value.name] > 1) {
|
||||
value.name += " (" + value.alias + ")";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function ($scope, ncResources) {
|
||||
|
||||
$scope.add = function () {
|
||||
$scope.model.value.push({
|
||||
@@ -57,42 +95,66 @@
|
||||
}
|
||||
};
|
||||
|
||||
$scope.docTypeTabs = {};
|
||||
|
||||
ncResources.getContentTypes().then(function (docTypes) {
|
||||
$scope.model.docTypes = docTypes;
|
||||
|
||||
// Count doctype name occurrences
|
||||
var docTypeNameOccurrences = _.countBy(docTypes, 'name');
|
||||
|
||||
// Populate document type tab dictionary
|
||||
// And append alias to name if multiple doctypes have the same name
|
||||
docTypes.forEach(function (value) {
|
||||
$scope.docTypeTabs[value.alias] = value.tabs;
|
||||
|
||||
value.displayName = value.name;
|
||||
|
||||
if (docTypeNameOccurrences[value.name] > 1) {
|
||||
value.displayName += " (" + value.alias + ")";
|
||||
}
|
||||
$scope.placeholder = function (config) {
|
||||
return _.find($scope.model.elemTypes, function (elType) {
|
||||
return elType.alias === config.ncAlias;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$scope.selectableDocTypesFor = function (config) {
|
||||
// return all doctypes that are:
|
||||
$scope.selectableElemTypesFor = function (config) {
|
||||
// return all elemTypes that are:
|
||||
// 1. either already selected for this config, or
|
||||
// 2. not selected in any other config
|
||||
return _.filter($scope.model.docTypes, function (docType) {
|
||||
return docType.alias === config.ncAlias || !_.find($scope.model.value, function(c) {
|
||||
return docType.alias === c.ncAlias;
|
||||
return _.filter($scope.model.elemTypes, function (elType) {
|
||||
return elType.alias === config.ncAlias || !_.find($scope.model.value, function (c) {
|
||||
return elType.alias === c.ncAlias;
|
||||
});
|
||||
});
|
||||
}
|
||||
$scope.canAdd = function () {
|
||||
return !$scope.model.value || _.some($scope.model.elemTypes, function (elType) {
|
||||
return !_.find($scope.model.value, function (c) {
|
||||
return elType.alias === c.ncAlias;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$scope.openElemTypeModal = function ($event, config) {
|
||||
|
||||
//we have to add the alias to the objects (they are stored as ncAlias)
|
||||
var selectedItems = _.each($scope.model.value, function (obj) {
|
||||
obj.alias = obj.ncAlias;
|
||||
return obj;
|
||||
})
|
||||
|
||||
var elemTypeSelectorOverlay = {
|
||||
view: "itempicker",
|
||||
title: selectElementTypeModalTitle,
|
||||
availableItems: $scope.selectableElemTypesFor(config),
|
||||
selectedItems: selectedItems,
|
||||
position: "target",
|
||||
event: $event,
|
||||
submit: function (model) {
|
||||
config.ncAlias = model.selectedItem.alias;
|
||||
overlayService.close();
|
||||
},
|
||||
close: function () {
|
||||
overlayService.close();
|
||||
}
|
||||
};
|
||||
|
||||
overlayService.open(elemTypeSelectorOverlay);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!$scope.model.value) {
|
||||
$scope.model.value = [];
|
||||
$scope.add();
|
||||
}
|
||||
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -141,7 +203,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
$scope.hasContentTypes = $scope.model.config.contentTypes.length > 0;
|
||||
|
||||
$scope.labels = {};
|
||||
localizationService.localizeMany(["grid_addElement", "content_createEmpty"]).then(function(data) {
|
||||
localizationService.localizeMany(["grid_addElement", "content_createEmpty"]).then(function (data) {
|
||||
$scope.labels.grid_addElement = data[0];
|
||||
$scope.labels.content_createEmpty = data[1];
|
||||
});
|
||||
@@ -179,14 +241,14 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
$scope.overlayMenu.show = false;
|
||||
$scope.overlayMenu = null;
|
||||
},
|
||||
submit: function(model) {
|
||||
if(model && model.selectedItem) {
|
||||
submit: function (model) {
|
||||
if (model && model.selectedItem) {
|
||||
$scope.addNode(model.selectedItem.alias);
|
||||
}
|
||||
$scope.overlayMenu.show = false;
|
||||
$scope.overlayMenu = null;
|
||||
},
|
||||
close: function() {
|
||||
close: function () {
|
||||
$scope.overlayMenu.show = false;
|
||||
$scope.overlayMenu = null;
|
||||
}
|
||||
@@ -218,22 +280,22 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
icon: iconHelper.convertFromLegacyIcon(node.icon)
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$scope.overlayMenu.title = $scope.overlayMenu.pasteItems.length > 0 ? $scope.labels.grid_addElement : $scope.labels.content_createEmpty;
|
||||
|
||||
$scope.overlayMenu.clickClearPaste = function($event) {
|
||||
|
||||
$scope.overlayMenu.clickClearPaste = function ($event) {
|
||||
$event.stopPropagation();
|
||||
$event.preventDefault();
|
||||
clipboardService.clearEntriesOfType("elementType", contentTypeAliases);
|
||||
$scope.overlayMenu.pasteItems = [];// This dialog is not connected via the clipboardService events, so we need to update manually.
|
||||
};
|
||||
|
||||
|
||||
if ($scope.overlayMenu.availableItems.length === 1 && $scope.overlayMenu.pasteItems.length === 0) {
|
||||
// only one scaffold type - no need to display the picker
|
||||
$scope.addNode($scope.scaffolds[0].contentTypeAlias);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$scope.overlayMenu.show = true;
|
||||
};
|
||||
|
||||
@@ -324,10 +386,10 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
if ($scope.nodes[idx].name !== name) {
|
||||
$scope.nodes[idx].name = name;
|
||||
}
|
||||
|
||||
|
||||
return name;
|
||||
};
|
||||
|
||||
|
||||
$scope.getIcon = function (idx) {
|
||||
var scaffold = $scope.getScaffold($scope.model.value[idx].ncContentTypeAlias);
|
||||
return scaffold && scaffold.icon ? iconHelper.convertFromLegacyIcon(scaffold.icon) : "icon-folder";
|
||||
@@ -335,7 +397,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
$scope.sortableOptions = {
|
||||
axis: "y",
|
||||
cursor: "move",
|
||||
handle:'.umb-nested-content__header-bar',
|
||||
handle: '.umb-nested-content__header-bar',
|
||||
distance: 10,
|
||||
opacity: 0.7,
|
||||
tolerance: "pointer",
|
||||
@@ -377,15 +439,15 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
return contentType.ncAlias === alias;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$scope.showCopy = clipboardService.isSupported();
|
||||
|
||||
|
||||
$scope.showPaste = false;
|
||||
|
||||
$scope.clickCopy = function($event, node) {
|
||||
|
||||
|
||||
$scope.clickCopy = function ($event, node) {
|
||||
|
||||
syncCurrentNode();
|
||||
|
||||
|
||||
clipboardService.copy("elementType", node.contentTypeAlias, node);
|
||||
$event.stopPropagation();
|
||||
}
|
||||
@@ -395,27 +457,27 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
if (newNode === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// generate a new key.
|
||||
newNode.key = String.CreateGuid();
|
||||
|
||||
|
||||
$scope.nodes.push(newNode);
|
||||
$scope.setDirty();
|
||||
//updateModel();// done by setting current node...
|
||||
|
||||
$scope.currentNode = newNode;
|
||||
}
|
||||
|
||||
|
||||
function checkAbilityToPasteContent() {
|
||||
$scope.showPaste = clipboardService.hasEntriesOfType("elementType", contentTypeAliases);
|
||||
}
|
||||
|
||||
|
||||
eventsService.on("clipboardService.storageUpdate", checkAbilityToPasteContent);
|
||||
|
||||
|
||||
var notSupported = [
|
||||
"Umbraco.Tags",
|
||||
"Umbraco.UploadField",
|
||||
"Umbraco.ImageCropper"
|
||||
"Umbraco.Tags",
|
||||
"Umbraco.UploadField",
|
||||
"Umbraco.ImageCropper"
|
||||
];
|
||||
|
||||
// Initialize
|
||||
@@ -495,24 +557,24 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
}
|
||||
|
||||
$scope.inited = true;
|
||||
|
||||
|
||||
checkAbilityToPasteContent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function createNode(scaffold, fromNcEntry) {
|
||||
var node = angular.copy(scaffold);
|
||||
|
||||
|
||||
node.key = fromNcEntry && fromNcEntry.key ? fromNcEntry.key : String.CreateGuid();
|
||||
|
||||
|
||||
var variant = node.variants[0];
|
||||
|
||||
for (var t = 0; t < variant.tabs.length; t++) {
|
||||
var tab = variant.tabs[t];
|
||||
|
||||
|
||||
for (var p = 0; p < tab.properties.length; p++) {
|
||||
var prop = tab.properties[p];
|
||||
|
||||
|
||||
prop.propertyAlias = prop.alias;
|
||||
prop.alias = $scope.model.alias + "___" + prop.alias;
|
||||
// Force validation to occur server side as this is the
|
||||
@@ -522,7 +584,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
mandatory: false,
|
||||
pattern: ""
|
||||
};
|
||||
|
||||
|
||||
if (fromNcEntry && fromNcEntry[prop.propertyAlias]) {
|
||||
prop.value = fromNcEntry[prop.propertyAlias];
|
||||
}
|
||||
@@ -533,7 +595,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
function convertNodeIntoNCEntry(node) {
|
||||
var obj = {
|
||||
key: node.key,
|
||||
@@ -551,16 +613,16 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
function syncCurrentNode() {
|
||||
if ($scope.realCurrentNode) {
|
||||
$scope.$broadcast("ncSyncVal", { key: $scope.realCurrentNode.key });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function updateModel() {
|
||||
syncCurrentNode();
|
||||
|
||||
|
||||
if ($scope.inited) {
|
||||
var newValues = [];
|
||||
for (var i = 0; i < $scope.nodes.length; i++) {
|
||||
@@ -582,7 +644,7 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.NestedContent.Prop
|
||||
$scope.$on("$destroy", function () {
|
||||
unsubscribe();
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
]);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th/>
|
||||
<th />
|
||||
<th>
|
||||
<localize key="contentTypeEditor_elementType">Element Type</localize>
|
||||
</th>
|
||||
@@ -22,14 +22,22 @@
|
||||
<i class="icon icon-navigation handle"></i>
|
||||
</td>
|
||||
<td>
|
||||
<select id="{{model.alias}}_doctype_select"
|
||||
ng-options="dt.alias as dt.displayName for dt in selectableDocTypesFor(config) | orderBy: 'name'"
|
||||
ng-model="config.ncAlias" required></select>
|
||||
{{ph = placeholder(config);""}}
|
||||
<div class="umb-nested-content__placeholder" ng-class="{'umb-nested-content__placeholder--selected':ph}" ng-click="openElemTypeModal($event, config)">
|
||||
<span class="umb-nested-content__placeholder-icon-holder" ng-if="ph">
|
||||
<i class="umb-nested-content__placeholder-icon {{ ph.icon }}"></i>
|
||||
</span>
|
||||
<span class="umb-nested-content__placeholder-name" ng-if="ph">
|
||||
{{ ph.name }}
|
||||
</span>
|
||||
<localize key="content_nestedContentAddElementType" ng-if="!ph">Add element type</localize>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<select id="{{model.alias}}_tab_select"
|
||||
ng-options="t for t in docTypeTabs[config.ncAlias]"
|
||||
ng-model="config.ncTabAlias" required></select>
|
||||
ng-options="t for t in elemTypeTabs[config.ncAlias]"
|
||||
ng-model="config.ncTabAlias" required></select>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" ng-model="config.nameTemplate" />
|
||||
@@ -49,15 +57,15 @@
|
||||
<i class="icon icon-help-alt medium umb-nested-content__help-icon" ng-click="showHelpText = !showHelpText"></i>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<br />
|
||||
<div class="umb-nested-content__help-text" ng-show="showHelpText">
|
||||
<p>
|
||||
<b><localize key="general_group">Group</localize>:</b><br/>
|
||||
<b><localize key="general_group">Group</localize>:</b><br />
|
||||
Select the group whose properties should be displayed. If left blank, the first group on the element type will be used.
|
||||
</p>
|
||||
<p>
|
||||
<b><localize key="template_template">Template</localize>:</b><br/>
|
||||
Enter an angular expression to evaluate against each item for its name. Use <code ng-non-bindable>{{$index}}</code> to display the item index
|
||||
<b><localize key="template_template">Template</localize>:</b><br />
|
||||
Enter an angular expression to evaluate against each item for its name. Use <code ng-non-bindable>{{$index}}</code> to display the item index
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -105,6 +105,7 @@
|
||||
var sectionPicker = {
|
||||
selection: currentSelection,
|
||||
submit: function (model) {
|
||||
vm.userGroup.sections = model.selection;
|
||||
editorService.close();
|
||||
},
|
||||
close: function () {
|
||||
@@ -168,7 +169,8 @@
|
||||
angular.copy(vm.userGroup.users, currentSelection);
|
||||
var userPicker = {
|
||||
selection: currentSelection,
|
||||
submit: function () {
|
||||
submit: function (model) {
|
||||
vm.userGroup.users = model.selection;
|
||||
editorService.close();
|
||||
},
|
||||
close: function () {
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
sections="userGroup.sections"
|
||||
content-start-node="userGroup.contentStartNode"
|
||||
media-start-node="userGroup.mediaStartNode"
|
||||
allow-remove="true"
|
||||
on-remove="model.removeSelectedItem($index, model.user.userGroups)">
|
||||
</umb-user-group-preview>
|
||||
|
||||
|
||||
@@ -359,6 +359,8 @@
|
||||
<localize key="general_add">Add</localize>
|
||||
</a>
|
||||
|
||||
<input type="hidden" ng-model="vm.newUser.userGroupsValidation" ng-required="!vm.newUser.userGroups.length" />
|
||||
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@general_message" ng-if="vm.usersViewState === 'inviteUser'" label-for="message" required="true">
|
||||
|
||||
@@ -13,7 +13,7 @@ var app = angular.module('umbraco', [
|
||||
'ngSanitize',
|
||||
|
||||
//'ngMessages',
|
||||
'tmh.dynamicLocale',
|
||||
'tmh.dynamicLocale'
|
||||
//'ngFileUpload',
|
||||
//'LocalStorageModule',
|
||||
//'chart.js'
|
||||
|
||||
@@ -51,9 +51,23 @@ module.exports = function (config) {
|
||||
exclude: [],
|
||||
|
||||
// use dolts reporter, as travis terminal does not support escaping sequences
|
||||
// possible values: 'dots', 'progress', 'junit', 'teamcity'
|
||||
// possible values: 'dots', 'progress', 'junit', 'spec'
|
||||
// ***
|
||||
// progress: Outputs a simple list like: "Executed 128 of 144 SUCCESS (0 secs / 0.814 secs)"
|
||||
// spec: Outputs a more verbose report which is more useful for debugging if one of the tests fails.
|
||||
// ***
|
||||
// CLI --reporters progress
|
||||
reporters: ['progress', 'junit'],
|
||||
|
||||
reporters: ['spec', 'junit'],
|
||||
specReporter: {
|
||||
maxLogLines: 5, // limit number of lines logged per test
|
||||
suppressErrorSummary: true, // do not print error summary
|
||||
suppressFailed: false, // do not print information about failed tests
|
||||
suppressPassed: false, // do not print information about passed tests
|
||||
suppressSkipped: true, // do not print information about skipped tests
|
||||
showSpecTiming: false // print the time elapsed for each spec
|
||||
},
|
||||
|
||||
|
||||
// web server port
|
||||
// CLI --port 9876
|
||||
@@ -102,7 +116,9 @@ module.exports = function (config) {
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-phantomjs-launcher'),
|
||||
require('karma-junit-reporter')
|
||||
require('karma-junit-reporter'),
|
||||
require('karma-spec-reporter')
|
||||
|
||||
],
|
||||
|
||||
// the default configuration
|
||||
|
||||
@@ -37,7 +37,7 @@ describe('Drop down controller tests', function () {
|
||||
$routeParams: routeParams
|
||||
});
|
||||
|
||||
//this should be the expected format based on the changes made to the sortable prevalues
|
||||
// this should be the expected format based on the changes made to the sortable prevalues
|
||||
expect(scope.model.config.items[0].value).toBe("value0");
|
||||
expect(scope.model.config.items[1].value).toBe("value1");
|
||||
expect(scope.model.config.items[2].value).toBe("value2");
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
(function () {
|
||||
|
||||
describe('truncate filter', function() {
|
||||
var $truncate;
|
||||
|
||||
var testCases = [
|
||||
{input:'test', noOfChars:5, appendDots:true, expectedResult: 'test'},
|
||||
{input:'test ', noOfChars:4, appendDots:true, expectedResult: 'test…'},
|
||||
{input:'test a long text with space', noOfChars:5, appendDots:true, expectedResult: 'test …'},
|
||||
{input:'scenarios is a long word', noOfChars:5, appendDots:true, expectedResult: 'scena…'},
|
||||
{input:'scenarios is a long word', noOfChars:10, appendDots:true, expectedResult: 'scenarios …'},
|
||||
{input:'test', noOfChars:5, appendDots:false, expectedResult: 'test'},
|
||||
{input:'test a long text with space', noOfChars:5, appendDots:false, expectedResult: 'test '},
|
||||
{input:'scenarios is a long word', noOfChars:5, appendDots:false, expectedResult: 'scena'},
|
||||
{input:'scenarios is a long word', noOfChars:10, appendDots:false, expectedResult: 'scenarios '}
|
||||
];
|
||||
|
||||
var testCasesNew = [
|
||||
{value:'test', wordwise:false, max:20, tail:'...', expectedResult: 'test'},
|
||||
{value:'LoremIpsumLoremIpsumLoremIpsum',wordwise:false, max:20, tail:null, expectedResult: 'LoremIpsumLoremIpsum…'}
|
||||
];
|
||||
|
||||
beforeEach(module('umbraco'));
|
||||
|
||||
beforeEach(inject(function($filter) {
|
||||
$truncate = $filter('truncate');
|
||||
}));
|
||||
|
||||
it('empty string as input is expected to give an empty string', function() {
|
||||
expect($truncate('', 5, true)).toBe('');
|
||||
});
|
||||
|
||||
it('null as input is expected to give an empty string', function() {
|
||||
expect($truncate(null, 5, true)).toBe('');
|
||||
});
|
||||
|
||||
it('undefined as input is expected to give an empty string', function() {
|
||||
expect($truncate(undefined, 5, true)).toBe('');
|
||||
});
|
||||
|
||||
it('null as noOfChars to result in \'test\'', function() {
|
||||
expect($truncate('test', null, true)).toBe('test');
|
||||
});
|
||||
|
||||
it('undefined as noOfChars to result in \'test\'', function() {
|
||||
expect($truncate('test', undefined, true)).toBe('test');
|
||||
});
|
||||
|
||||
it('null as appendDots to behave as false', function() {
|
||||
expect($truncate('test', 5, null)).toBe('test');
|
||||
});
|
||||
|
||||
testCases.forEach(function(test){
|
||||
|
||||
it('Expects \'' + test.input + '\' to be truncated as \''+ test.expectedResult + '\', when noOfChars=' + test.noOfChars + ', and appendDots=' + test.appendDots, function() {
|
||||
console.log($truncate(test.input, test.noOfChars, test.appendDots));
|
||||
expect($truncate(test.input, test.noOfChars, test.appendDots)).toBe(test.expectedResult);
|
||||
});
|
||||
});
|
||||
|
||||
testCasesNew.forEach(function(test){
|
||||
it('Expects \'' + test.value + '\' to be truncated as \''+ test.expectedResult + '\', when wordwise=' + test.wordwise + ', and max=' + test.max + ', and tail=' + test.tail, function() {
|
||||
expect($truncate(test.value, test.wordwise, test.max, test.tail)).toBe(test.expectedResult);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}());
|
||||
Reference in New Issue
Block a user