Compare commits

...

281 Commits

Author SHA1 Message Date
Poornima Nayar 157c0a2479 Added Review process file 2019-09-02 10:27:29 +02:00
Poornima Nayar 3d3a836c52 fix to the documentation link in create packages opening in same window 2019-09-02 10:17:19 +02:00
Kasper Christensen 24efa54481 Loginpage: Added an id to input fields and a for attr on the la… (#6247) 2019-09-02 10:00:44 +02:00
Mads Krohn 1bf85ab1db Correctly html encode text (#6235) 2019-09-02 08:46:33 +02:00
christophnz 1d94c4b9bb Fixed returntype of IPublishedContent.Siblings<T> to be IEnumerable<T> rather than IEnumerable<IPublishedContent> 2019-08-30 14:27:13 +02:00
Poornima Nayar 13e704e36c Fix- Unable to create members in the members section using the create option in the overlay 2019-08-30 08:50:15 +02:00
Bjarne Fyrstenborg 413b266335 v8: Replace tree loader with umbLoader component (#6169) 2019-08-29 14:36:51 +02:00
Kenn Jacobsen 7cb0886b35 Prevent markdown editor from stealing input focus on enter 2019-08-29 14:32:40 +02:00
Kenn Jacobsen d0e7344e2d Prevent double click errors when editing compositions 2019-08-29 14:30:10 +02:00
Andy Butland 8fdc14f360 Added metadata indicating if document published for content picker display 2019-08-29 14:27:31 +02:00
Sean McLemon 915b24e4e4 When deciding whether to use SSL, ApplicationUrlHelper.GetApplicationUrlFromCurrentRequest() has an expression port == "443" which is always false. The variable port is set to to either "" or ":" + request.ServerVariables["SERVER_PORT"], so it might sometimes be ":443" but it will never be just "443". This code has been this way for at least a year, and I don't know if the situation it tried to handle makes any sense (using port 443 over plain HTTP, for some reason??) so I've just removed it. 2019-08-29 14:26:16 +02:00
Callum Whyte a24e5bd10c Correcting ASCII art in README (#6156) 2019-08-29 14:22:21 +02:00
Kenn Jacobsen 3457018fb4 Don't use a hardcoded "image" type in media picker value conversion 2019-08-29 14:20:03 +02:00
Kenn Jacobsen bfc87922cb Make sure the empty search result is visible for list views 2019-08-29 14:13:43 +02:00
Steve Megson 09def9f352 Migration of MarkdownEditor prevalues 2019-08-29 14:12:32 +02:00
Steve Megson 934e2066a0 #6158 - missing media folders after migration 2019-08-29 14:09:19 +02:00
stevemegson b254b4fcda V8: Indexing of grid values containing JSON (#6201) 2019-08-29 14:06:59 +02:00
jmayntzhusen 4dad427a64 Improve error messages (#6154) 2019-08-29 14:01:30 +02:00
Steve Megson 9e1424fb24 RefactorMacroColumns 2019-08-29 13:58:43 +02:00
Kenn Jacobsen ad978c60df V8: Use a standard confirm dialog when removing content type compositions (#6213) 2019-08-29 13:51:55 +02:00
Kenn Jacobsen dfe96dccde Use a pointer cursor for selectable items in mini listviews 2019-08-29 13:50:37 +02:00
Poornima Nayar 981519eac0 Added contribution guidelines file
which was otherwise leading to a 404 from the Contributing.md file (#6197)
2019-08-29 13:49:26 +02:00
Kenn Jacobsen 16ab7b70cf V8: Add confirmation when deleting content and media (#6005) 2019-08-29 13:44:38 +02:00
Sebastiaan Janssen b2093e6dfa Merge branch 'v7/dev' into v8/dev
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/views/common/overlays/itempicker/itempicker.controller.js
#	src/Umbraco.Web.UI.Client/src/views/common/overlays/itempicker/itempicker.html
#	src/Umbraco.Web.UI.Client/src/views/content/content.delete.controller.js
#	src/Umbraco.Web.UI.Client/src/views/content/delete.html
#	src/Umbraco.Web.UI.Client/src/views/media/delete.html
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.controller.js
#	src/Umbraco.Web.UI/umbraco/config/lang/da.xml
#	src/Umbraco.Web.UI/umbraco/config/lang/en.xml
#	src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml
2019-08-29 13:44:09 +02:00
Kenn Jacobsen 3f8dffee3f V7: Add confirmation when deleting content and media (#6004) 2019-08-29 13:41:34 +02:00
Kenn Jacobsen 204a9c9d53 Make sure Nested Content blueprints are listed in defined sort order 2019-08-29 13:37:45 +02:00
Kenn Jacobsen 531dee1e75 Ensure correct icon for file types in search results 2019-08-29 13:34:01 +02:00
Sebastiaan Janssen 297e054381 Merge branch 'v7/dev' into v8/dev
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js
#	src/Umbraco.Web/Search/UmbracoTreeSearcher.cs
2019-08-29 13:33:42 +02:00
Kenn Jacobsen e9eecb2031 Ensure correct icon for file types in search results 2019-08-29 13:31:18 +02:00
Sebastiaan Janssen 4f289a222f Merge remote-tracking branch 'origin/v7/7.15' into v8/dev
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js
2019-08-29 13:30:14 +02:00
Matt Brailsford e92631c623 Fixed #5907 by reloading content on bulk publish / unpublish
Fixes #5907

(cherry picked from commit 93bb75511b)
2019-08-29 13:26:41 +02:00
Matt Brailsford 93bb75511b Fixed #5907 by reloading content on bulk publish / unpublish
Fixes #5907
2019-08-29 13:25:56 +02:00
Sebastiaan Janssen 5d9e1087f4 Cherry pick 851a2a3de8 2019-08-29 13:03:48 +02:00
Sebastiaan Janssen 0308c8096e Merge branch 'v7/dev' into v8/dev
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/views/components/media/umb-media-node-info.html
2019-08-29 12:59:56 +02:00
Sebastiaan Janssen 02469f110f Merge branch 'v7/7.15' into v7/dev 2019-08-29 12:58:36 +02:00
Warren Buckley 851a2a3de8 Simplify svg check and make it a proper a href again. 2019-08-29 12:56:53 +02:00
Sebastiaan Janssen 74ccc34124 Merge branch 'v7/dev' into v8/dev
# Conflicts:
#	src/Umbraco.Core/Persistence/Factories/MediaFactory.cs
2019-08-29 12:38:35 +02:00
Cody Boucher f5a445101d use SystemDirectories.Media instead of hardcoded string media
(cherry picked from commit 2cdeb38521)
2019-08-29 12:34:21 +02:00
Cody Boucher 2cdeb38521 use SystemDirectories.Media instead of hardcoded string media 2019-08-29 12:33:31 +02:00
Sebastiaan Janssen b3834c296b Merge branch 'v7/dev' into v8/dev
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/multiurlpicker/multiurlpicker.controller.js
2019-08-29 11:57:50 +02:00
Sebastiaan Janssen 198b74f4de Merge branch 'v7/7.15' into v7/dev 2019-08-29 11:57:00 +02:00
Sebastiaan Janssen 3c7580ff7b Default for ignoreUserStartNodes should be false 2019-08-29 11:55:43 +02:00
Sebastiaan Janssen c0ad292ebb Merge branch 'v7/7.15' into v7/dev 2019-08-29 11:48:52 +02:00
Steve Megson 4ef55aa7d0 Multi Url Picker fix
(cherry picked from commit 3dc0bbeff3)
2019-08-29 11:48:04 +02:00
Steve Megson 3dc0bbeff3 Multi Url Picker fix 2019-08-29 09:34:35 +02:00
Warren Buckley b205f19f40 Merge pull request #6130 from stevemegson/v8/temp-6060
V8: Handle missing grid values in migration from 7.15
2019-08-27 14:31:52 +00:00
Warren Buckley 727c32843c Merge branch 'v8/8.1' into v8/dev
# Conflicts:
#	src/SolutionInfo.cs
2019-08-27 11:53:52 +01:00
Warren Buckley 78a63b20c7 Merge pull request #6120 from umbraco/v8/bugfix/6099-member-password-reset
Fixes: Member password reset checkbox doesn't hide "new" and "confirm" password fields. #6099
2019-08-27 10:48:27 +00:00
Claus c3e99205de fixed typo. 2019-08-26 13:29:54 +02:00
Claus 66ba6f51da Merge pull request #6147 from umbraco/v8/feature/2196-improve-tiny-load
Improve JS Asset load of TinyMCE Editor
2019-08-26 13:25:34 +02:00
elitsa 8625c8da43 Add special checks and preview for svg files media files for v8
(cherry picked from commit ac4128d89e)
2019-08-23 12:08:03 +01:00
Warren Buckley d86db3fc11 Merge pull request #6182 from umbraco/v8/bugfix/2180-secure-svg-preview
Secure svg media files preview - v8
2019-08-23 11:06:20 +00:00
elitsa ac4128d89e Add special checks and preview for svg files media files for v8 2019-08-23 10:42:00 +02:00
Steve Megson 11f2855442 Move CreateRoutes from WebFinalComponent to WebInitialComponent 2019-08-23 09:11:41 +02:00
Kenn Jacobsen d09be604d9 Allow plugin "Lang" folders to reside in nested directories 2019-08-23 08:56:42 +02:00
Sebastiaan Janssen d8355c368f Too many weird versions 2019-08-22 23:40:24 +02:00
stevemegson 703092c12c V8: Fix caching of macro results in RTE (#6010)
(cherry picked from commit 9b212121e3)
2019-08-22 23:37:06 +02:00
stevemegson 9b212121e3 V8: Fix caching of macro results in RTE (#6010) 2019-08-22 23:34:33 +02:00
Sebastiaan Janssen 88145d70fc Update nestedcontent.editor.html
forgot the "property-" prefix.

(cherry picked from commit 0aaf284f7f)
(cherry picked from commit d2649e9354)

# Conflicts:
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.editor.html
(cherry picked from commit ac6e399847)
2019-08-22 22:46:11 +02:00
Sebastiaan Janssen 320cc48132 Merge branch 'v7/dev' into v8/dev
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.editor.html
2019-08-22 22:44:05 +02:00
Sebastiaan Janssen ac6e399847 Update nestedcontent.editor.html
forgot the "property-" prefix.

(cherry picked from commit 0aaf284f7f)
(cherry picked from commit d2649e9354)

# Conflicts:
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/nestedcontent/nestedcontent.editor.html
2019-08-22 22:43:17 +02:00
Sebastiaan Janssen d2649e9354 Update nestedcontent.editor.html
forgot the "property-" prefix.

(cherry picked from commit 0aaf284f7f)
2019-08-22 22:31:36 +02:00
B. Gunnarsson 0aaf284f7f Update nestedcontent.editor.html
forgot the "property-" prefix.
2019-08-22 22:21:43 +02:00
Brynjólfur Gunnarsson a21c9420b1 added data element to nestedcontent.editor.html, tested it and it works" 2019-08-22 22:21:43 +02:00
Sebastiaan Janssen b396cc340c Cherry pick - Added trck by $index to handle duplicate names in blueprints 2019-08-22 22:06:57 +02:00
Sebastiaan Janssen 4b9ce6bb10 Merge branch 'v7/dev' into v8/dev
# Conflicts:
#	src/SolutionInfo.cs
#	src/Umbraco.Core/Configuration/UmbracoVersion.cs
#	src/Umbraco.Core/DateTimeExtensions.cs
#	src/Umbraco.Web.UI.Client/src/common/directives/components/media/umbmedianodeinfo.directive.js
#	src/Umbraco.Web.UI.Client/src/views/components/media/umb-media-node-info.html
#	src/Umbraco.Web.UI.Client/src/views/content/create.html
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html
#	src/Umbraco.Web/Profiling/WebProfilerProvider.cs
#	src/Umbraco.Web/umbraco.presentation/umbraco/webservices/legacyAjaxCalls.asmx.cs
2019-08-22 22:05:14 +02:00
Nik 55d0ca2557 Added trck by $index to handle duplicate names in blueprints
(cherry picked from commit d57ebf021c)
2019-08-22 21:51:58 +02:00
Nik d57ebf021c Added trck by $index to handle duplicate names in blueprints 2019-08-22 21:46:38 +02:00
Kenn Jacobsen a2899b21b6 Don't crash the linkpicker if only an anchor has been entered
(cherry picked from commit 1089b4b9bb)
2019-08-22 21:35:17 +02:00
Kenn Jacobsen 1089b4b9bb Don't crash the linkpicker if only an anchor has been entered 2019-08-22 21:04:12 +02:00
swcs 2428af3c40 Ability to distinguish document types with same name in Nested Content config (#6092) 2019-08-22 10:46:28 +02:00
Sebastiaan Janssen ffd5d61f9f Merge branch 'v7/7.15' into v7/dev 2019-08-21 15:25:54 +02:00
Lars-Erik Aabech 5b1f2ef95d V7: Fixes #6132, dates being blanked out on save/publish when user locale (momen… (#6138) 2019-08-21 15:21:31 +02:00
Sebastiaan Janssen 08c3b6bff5 Fix unit tests
(cherry picked from commit 82e11d7e0a)
2019-08-21 13:02:57 +01:00
Sebastiaan Janssen ccc2a0e811 Fix #5335 - Multiple Media Picker not available as macro parameter
(cherry picked from commit 1f2c4e38ac)
2019-08-21 13:02:36 +01:00
Warren Buckley 445e6d41b7 Merge pull request #6149 from umbraco/v8/feature/5335-multi-media-picker-parameter-editor
Fix #5335 - Multiple Media Picker not available as macro parameter
2019-08-21 11:15:41 +00:00
Sebastiaan Janssen 82e11d7e0a Fix unit tests 2019-08-21 12:45:06 +02:00
Elitsa Marinovska 2cc5256c00 Fixed typo in "ng-container"
(cherry picked from commit 7a7adfb61f)
2019-08-21 11:09:41 +01:00
elitsa 6f83d3c865 Add special checks and preview for svg files media files.
(cherry picked from commit defcb727f9)
2019-08-21 11:09:19 +01:00
Warren Buckley 3325627fd2 Merge pull request #6137 from umbraco/v7/bugfix/2180-secure-svg-preview
Secure svg media files preview
2019-08-21 10:07:08 +00:00
Warren Buckley bec54a0467 Remove unecessary change 2019-08-20 11:28:29 +01:00
Warren Buckley 4fc265275b Fix up unit test for RTE, it was failing as I added the Angular app.value for tinyMceAssets - this ensures we add an empty array of tinymce assets 2019-08-20 11:28:02 +01:00
Warren Buckley a95360036d Pre-loading this lang JS file does not seem to help Tiny as it does not check its already loaded & it reloads itself anyway (But the plugins work all fine & are checked by Tiny to see if they have been loaded) 2019-08-20 11:12:20 +01:00
Warren Buckley 6873c12f04 Update to main controller to load in the TinyMCE assets - assetsService deals with de-duping already loaded assets 2019-08-20 11:11:29 +01:00
Warren Buckley 0daa80efa4 Undo some of the changes as we will load it via assetService in the angular main controller & fixes the double load issue 2019-08-20 11:01:45 +01:00
Sebastiaan Janssen 1f2c4e38ac Fix #5335 - Multiple Media Picker not available as macro parameter 2019-08-19 16:01:03 +02:00
Warren Buckley b9b4721295 * Adds TinyMCE JS assets into init page load via script in default.cshtml view for Umbraco backoffice ng-app
* Add TinyMCE JS assets array via NG app.value & uses assetsService to load (if not loaded in time by main init script above)
2019-08-19 14:36:56 +01:00
Elitsa Marinovska 7a7adfb61f Fixed typo in "ng-container" 2019-08-17 23:54:49 +02:00
elitsa defcb727f9 Add special checks and preview for svg files media files. 2019-08-16 13:34:25 +02:00
Bjarne Fyrstenborg e4f19f7192 v8: Add umbLoader directive (#4987) 2019-08-16 11:52:34 +02:00
Kenn Jacobsen 0e565ddbf8 Make sure treepicker URLs are displayed for the current editor culture
(cherry picked from commit 438133ae1f)
2019-08-16 08:44:54 +02:00
Kenn Jacobsen 438133ae1f Make sure treepicker URLs are displayed for the current editor culture 2019-08-16 08:43:31 +02:00
Shannon Deminick 7ef7b23e93 Merge pull request #6121 from umbraco/v8/bugfix/5804-migration-fix
Fixes: v8.1 migration from v7 results in an error due to a unique index on cmsContent #5804
2019-08-16 16:20:24 +10:00
Shannon 6e1314ae30 Removing legacy service 2019-08-16 15:58:13 +10:00
Shannon Deminick 75ff3b26c1 Merge pull request #6125 from umbraco/v7/bugfix/2179-remove-legacy-web-service
Removing legacy service
2019-08-16 15:49:50 +10:00
Shannon 505b541040 Removing the MiniProfiler routes if solution is not in debug mode. 2019-08-16 15:39:46 +10:00
Shannon fbc12b607d Merge branch 'v7/7.15' into v7/dev 2019-08-16 15:38:19 +10:00
Shannon Deminick cb7440bbbf Merge pull request #6114 from umbraco/v7/bug/2178-disable-mini-profiler
Disable Mini Profiler
2019-08-16 15:37:05 +10:00
Shannon cd355910b3 strangely i need the fully qualified name here else i get an error, otherwise works great. 2019-08-16 15:34:49 +10:00
Andy Butland 5452ebaf6d Import and export of document type and property variations setting in packages 2019-08-15 21:57:09 +02:00
Marc Goodson cec4376d19 Update GetPagedResultsByQuery to return id of the node the audit item relates to instead of table PK
This was fixed previously in v7 - see https://github.com/umbraco/Umbraco-CMS/pull/3759

(cherry picked from commit 53c52abde5)
2019-08-15 21:19:38 +02:00
Marc Goodson 53c52abde5 Update GetPagedResultsByQuery to return id of the node the audit item relates to instead of table PK
This was fixed previously in v7 - see https://github.com/umbraco/Umbraco-CMS/pull/3759
2019-08-15 21:18:41 +02:00
skttl 0d63b13bf0 Changes mode of styleselect to All 2019-08-15 21:17:14 +02:00
Kenn Jacobsen 65b2d08997 Set media picker dirty when the value changes
(cherry picked from commit 2b7154622e)
2019-08-15 21:12:57 +02:00
Kenn Jacobsen 2b7154622e Set media picker dirty when the value changes 2019-08-15 21:12:12 +02:00
Bjarne Fyrstenborg 0baf5eab0a v8: Rename datetime picker component (#6110) 2019-08-15 21:09:58 +02:00
Kenn Jacobsen 16ac2c5589 Don't change parent protection when editing child protection
(cherry picked from commit 4743fc0e1d)
2019-08-15 21:07:19 +02:00
Kenn Jacobsen 4743fc0e1d Don't change parent protection when editing child protection 2019-08-15 21:06:21 +02:00
Kenn Jacobsen f8409be506 Use an Umbraco confirm dialog when deleting groups
(cherry picked from commit f1f9e1742e)
2019-08-15 21:05:04 +02:00
Kenn Jacobsen f1f9e1742e Use an Umbraco confirm dialog when deleting groups 2019-08-15 21:04:33 +02:00
Kenn Jacobsen 455395154a Don't reuse previously used content templates
(cherry picked from commit 3087eff147)
2019-08-15 21:01:45 +02:00
Kenn Jacobsen 3087eff147 Don't reuse previously used content templates 2019-08-15 21:00:22 +02:00
Sebastiaan Janssen 8e2eccb392 Bump version to 7.15.2 2019-08-15 13:32:09 +02:00
Sebastiaan Janssen a0af474c75 Bump version to 8.1.3 2019-08-15 13:29:14 +02:00
Kenn Jacobsen 7e8364eae4 V8: Support mixed element variance in Nested Content (#5952)
(cherry picked from commit e7a9ee8142)
2019-08-15 13:27:50 +02:00
Kenn Jacobsen e7a9ee8142 V8: Support mixed element variance in Nested Content (#5952) 2019-08-15 13:10:17 +02:00
Steve Megson 806d835a90 Handle null and missing grid values in migration 2019-08-14 21:14:48 +01:00
Jan Skovgaard 617fd9ab17 Accessibility: Open Package - Identifies back button as "Left h… (#5930) 2019-08-14 17:47:13 +02:00
Jan Skovgaard fe6df58e66 Accessibility: Media uploader widget can't be accessed via keyb… (#5944) 2019-08-14 17:40:52 +02:00
Jan Skovgaard 6bd647f8c6 Accessibility: Unable to navigate to close 'X' icon with keyboa… (#5964) 2019-08-14 17:29:26 +02:00
Jan Skovgaard 8d0df6cec3 Accessibility: Open User Details - Back icon arrow is identifie… (#5970) 2019-08-14 17:21:56 +02:00
Jan Skovgaard 5997e0ce8c Accessibility: Ensure "cancel" is clickable from move/restore d… (#5942) 2019-08-14 17:11:02 +02:00
Kenn Jacobsen 8bdd694a12 V8: Make sure to mark the current form as dirty when altering content types (#6108) 2019-08-14 16:55:32 +02:00
elitsa ee2068de56 Removing legacy service 2019-08-14 14:03:32 +02:00
Shannon dfed93a4ab Fixes dropping unique constraint indexes and oddly named FKs 2019-08-14 14:49:05 +10:00
Shannon 4e17463eb8 Merge branch 'v8/8.1' into v8/dev 2019-08-14 12:52:07 +10:00
Shannon df391c86f3 Fixes re-syncing member and media data after saving 2019-08-14 12:45:39 +10:00
Shannon 67f0a65811 Merge branch 'v8/8.1' into v8/bugfix/6099-member-password-reset 2019-08-14 12:30:02 +10:00
Shannon 9d77114d50 fixes gulp build for dev purposes - no fastdev since there's no need for it, removes inlining templates when not in prod 2019-08-14 12:28:28 +10:00
Shannon d2be30a228 converting to component 2019-08-14 12:26:49 +10:00
Shannon 9ed1101f27 whitespace changes 2019-08-14 11:16:24 +10:00
Shannon f60b91110f Fixes merge 2019-08-14 10:56:08 +10:00
Shannon db6714d3b8 Merge remote-tracking branch 'origin/v8/8.1' into v8/dev
# Conflicts:
#	src/SolutionInfo.cs
#	src/Umbraco.Web/Search/ExamineComponent.cs
2019-08-14 10:39:15 +10:00
Sebastiaan Janssen 47c8de4ca1 Merge branch 'v7/dev' into v8/dev
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js
2019-08-13 23:29:58 +02:00
Matt Brailsford 802e6d7979 Fixes #5931, show breadcrumb for new content
Could probably do with adding "Untitled" to translation file

(cherry picked from commit 249126a2b5)
2019-08-13 23:17:06 +02:00
Matt Brailsford 249126a2b5 Fixes #5931, show breadcrumb for new content
Could probably do with adding "Untitled" to translation file
2019-08-13 23:16:33 +02:00
Matt Brailsford ea591c87a2 Fixes #5932, showing "Return to ListView" for new content
(cherry picked from commit f3fc83fae6)
2019-08-13 23:11:01 +02:00
Matt Brailsford f3fc83fae6 Fixes #5932, showing "Return to ListView" for new content 2019-08-13 23:09:17 +02:00
BatJan d005af2b11 Remove unused visuallyhidden class 2019-08-13 22:59:49 +02:00
Kenn Jacobsen 3b60815e53 Fix user group deletion (#5912)
(cherry picked from commit b0b05cf785)
2019-08-13 22:55:12 +02:00
Kenn Jacobsen b0b05cf785 Fix user group deletion (#5912) 2019-08-13 22:54:19 +02:00
Bjarne Fyrstenborg d5d213cd44 Allow tree item label to shrink
(cherry picked from commit 2d56879d92)
2019-08-13 22:46:31 +02:00
Bjarne Fyrstenborg 2d56879d92 Allow tree item label to shrink 2019-08-13 22:45:09 +02:00
Sebastiaan Janssen 13d07c7ba3 Merge branch 'v7/dev' into v8/dev
# Conflicts:
#	src/Umbraco.Web/Editors/MediaTypeController.cs
2019-08-13 22:43:30 +02:00
Tom Pipe ece7178ef5 Ensure a media type correctly inherits it's selected parent
(cherry picked from commit ab63d2664c)
2019-08-13 22:41:01 +02:00
Tom Pipe ab63d2664c Ensure a media type correctly inherits it's selected parent 2019-08-13 22:40:33 +02:00
Tom Pipe f829ac4e6c Ensure a media type correctly inherits it's selected parent
(cherry picked from commit 28dd9aa081)
2019-08-13 22:38:39 +02:00
Tom Pipe 28dd9aa081 Ensure a media type correctly inherits it's selected parent 2019-08-13 22:37:59 +02:00
Sebastiaan Janssen eb8556c792 Merge branch 'v7/dev' into v8/dev 2019-08-13 22:26:16 +02:00
Sebastiaan Janssen 84e4c78bb9 Merge branch 'v7/7.15' into v7/dev 2019-08-13 22:24:21 +02:00
arkadiuszbiel 6123c0d475 Change z-index
(cherry picked from commit 3fa77dbf3d)
(cherry picked from commit 12ad9dd36b)

# Conflicts:
#	src/Umbraco.Web.UI.Client/src/less/components/notifications/umb-notifications.less
2019-08-13 22:20:52 +02:00
arkadiuszbiel 12ad9dd36b Change z-index
(cherry picked from commit 3fa77dbf3d)
2019-08-13 22:16:42 +02:00
Sebastiaan Janssen ba040674cb Merge branch 'v7/dev' into v8/dev
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/less/components/notifications/umb-notifications.less
2019-08-13 22:15:57 +02:00
arkadiuszbiel 3fa77dbf3d Change z-index 2019-08-13 22:14:53 +02:00
Sebastiaan Janssen 9fa435dbb2 Merge branch 'v7/dev' into v8/dev
# Conflicts:
#	src/Umbraco.Core/Services/NotificationService.cs
#	src/Umbraco.Web.UI.Client/src/less/tree.less
#	src/Umbraco.Web.UI.Client/src/views/common/overlays/mediaPicker/mediapicker.controller.js
#	src/Umbraco.Web/Properties/Settings.settings
#	src/Umbraco.Web/Properties/Settings1.Designer.cs
2019-08-13 22:11:34 +02:00
Nathan Woulfe 02c1e88da2 V8: Display current log level in log viewer sidebar (#6059) 2019-08-13 22:07:05 +02:00
Kenn Jacobsen 87e60ef26b V8: Support hexa in hexBgColor (#6091) 2019-08-13 21:56:11 +02:00
Kenn Jacobsen 87845ee907 V8: Allow localization of the backoffice using parent cultures… (#6090)
(cherry picked from commit 405538544f)
2019-08-13 20:28:48 +02:00
Kenn Jacobsen 405538544f V8: Allow localization of the backoffice using parent cultures… (#6090) 2019-08-13 20:26:22 +02:00
elitsa afca2e70bd Removing the MiniProfiler routes if solution is not in debug mode. 2019-08-13 14:17:14 +02:00
Peter Gregory 31d67161ab V8: Implementation of Create method for infinite editing edtior… (#6031) 2019-08-13 08:07:53 +02:00
Claus 66e3869b06 Merge pull request #6080 from umbraco/v8/feature/2190-improve-jarring-tiny-loading
AB#2190 - Improve jarring TinyMCE editor loading experience
2019-08-12 11:54:27 +02:00
swcs 600be987a7 use modifiable media path in file system composition
(cherry picked from commit fdcfc48e06)
2019-08-12 09:05:45 +02:00
swcs fdcfc48e06 use modifiable media path in file system composition 2019-08-12 09:04:32 +02:00
Shannon eb46b16800 subtle mistake in gulp change 2019-08-12 16:18:49 +10:00
Shannon Deminick 392445b53a Merge pull request #6086 from umbraco/v8/feature/more-flexi-angular-sln
Fix the gulp build to allow directives/components to exist where they need to be allowed
2019-08-12 09:36:25 +10:00
Kenn Jacobsen 7c93b8f157 Use mculture in content editor for multilingual content
(cherry picked from commit 2f84e76952)
2019-08-09 16:59:33 +02:00
Kenn Jacobsen 2f84e76952 Use mculture in content editor for multilingual content 2019-08-09 16:58:35 +02:00
Kenn Jacobsen 12a30d3ffd Always open the selected content template in infinite editing 2019-08-09 16:56:04 +02:00
Kenn Jacobsen 7e1f90fb3b Clear the content type "common" cache when deleting templates 2019-08-09 16:54:52 +02:00
Kenn Jacobsen 9865596dcc V7: Change the priority of the tree node annotations for contai… (#6083)
(cherry picked from commit 7393d9c372)
2019-08-09 16:47:14 +02:00
Kenn Jacobsen 7393d9c372 V7: Change the priority of the tree node annotations for contai… (#6083) 2019-08-09 16:44:43 +02:00
Kenn Jacobsen c87a22f347 Fix the disabled upload button in media picker (#6082)
(cherry picked from commit feb5567621)
2019-08-09 16:42:57 +02:00
Kenn Jacobsen dc44a7a3a7 Fix the disabled upload button in media picker
(cherry picked from commit 79c4d7797c)
2019-08-09 16:41:13 +02:00
Kenn Jacobsen 79c4d7797c Fix the disabled upload button in media picker 2019-08-09 16:40:08 +02:00
Kenn Jacobsen feb5567621 Fix the disabled upload button in media picker (#6082) 2019-08-09 16:36:38 +02:00
Rachel Breeze 9cab789425 V8: Accessibility improvements for page name entry (#5760)
(cherry picked from commit ab3202b560)
2019-08-09 16:27:02 +02:00
Rachel Breeze ab3202b560 V8: Accessibility improvements for page name entry (#5760) 2019-08-09 16:25:51 +02:00
Kenn Jacobsen a0cd542ba3 Fix "infinityMode" typo
(cherry picked from commit e10ce234db)
2019-08-09 16:00:54 +02:00
Kenn Jacobsen e10ce234db Fix "infinityMode" typo 2019-08-09 15:59:37 +02:00
Shannon 7f02bc7d1d fix controller glob 2019-08-09 16:55:58 +10:00
Shannon 44b6738b0d Moves main/navigation controllers to root - no more 'controller' folder 2019-08-09 16:36:10 +10:00
Shannon fbb19cba0b Updates the build so we can be more flexible with where we put angular file types in the solution 2019-08-09 16:02:05 +10:00
Shannon 84554101f2 Merge branch 'v8/dev' of https://github.com/umbraco/Umbraco-CMS into v8/dev 2019-08-09 15:54:38 +10:00
Shannon 8a3b2e038c adds note 2019-08-09 15:54:21 +10:00
Peter Keating ff595df7ca Fix notifications not sending when user has multiple of same type
When a user has multiple notifications of the same type, the user may
not receive the notification depending on the order which the
notification was setup. To fix this the notification logic has changed
from looping over users to looping over notifications.

Fixes #4713.

(cherry picked from commit 01a895bbf7)
2019-08-08 19:49:59 +02:00
Peter Keating 01a895bbf7 Fix notifications not sending when user has multiple of same type
When a user has multiple notifications of the same type, the user may
not receive the notification depending on the order which the
notification was setup. To fix this the notification logic has changed
from looping over users to looping over notifications.

Fixes #4713.
2019-08-08 19:48:39 +02:00
amitch17 296d7964ae Corrected comments to change usage examples
Corrected usage examples for entityResource.js

My first Umbraco commit! yay!
2019-08-08 18:55:38 +02:00
Steve Megson ed5effd190 Sorting of images in multiple media picker 2019-08-08 16:00:21 +02:00
Warren Buckley c6671f7f8e Apply same loading bar UI to Grid RTE & use editor INIT to hide/remove it 2019-08-08 12:35:39 +01:00
Warren Buckley 44c966bd44 Moves our Umbraco angular loader component to only hide itself once the tinymce editor has initialized 2019-08-08 11:37:18 +01:00
Kenn Jacobsen 57e58c6cf7 Fix broken button to open content type from create dialog 2019-08-08 10:03:47 +02:00
leekelleher 34e45abcc7 Added constants for Property Editor Groups 2019-08-07 20:59:03 +02:00
Kenn Jacobsen b3497011e8 Make content types with description look ok in the create dialog (#5752) 2019-08-07 20:49:14 +02:00
Søren Gregersen a398881fa1 fix: spelling error in comment :)
infinie error(s) fixed
2019-08-07 20:38:37 +02:00
Sebastiaan Janssen 2cf3a7831c Merge pull request #5999 from kjac/v8-fix-allow-remove-user-start-nodes
V8: Allow removing user start nodes
2019-08-07 20:19:48 +02:00
Gopakumar R 0138091a6c Fix for issue #5816 (#5836) 2019-08-07 20:16:18 +02:00
Kenn Jacobsen 6c0fb2f849 Fix the create context menu overflows introduced with 405e9a79 (#5754) 2019-08-07 19:56:30 +02:00
Benjamin Carleski e495faf83c Fix FIPS compliance, add FIPS tests (#5978) 2019-08-07 19:31:08 +02:00
Sebastiaan Janssen 8721423f40 Merge pull request #6016 from umbraco/v8/fix/5906-support-stored-absolute-media-url
Fix exception when stored media url is already absolute
2019-07-29 14:30:03 +02:00
Rasmus John Pedersen 49b3351c72 Fix exception when stored media url is already absolute 2019-07-29 12:59:29 +02:00
Shannon Deminick faef449750 Merge pull request #6009 from bielu/v8/dev
V8: Value Set builder shouldn't stop indexing when one field is empty in …
2019-07-29 11:36:01 +10:00
arkadiuszbiel 4a24064783 Value Set builder shouldn't stop indexing when one field is empty in value sets 2019-07-27 20:41:15 +01:00
Kenn Jacobsen 0ab84fc443 Allow removing user start nodes 2019-07-25 10:28:16 +02:00
Bjarke Berg fca74ad8d7 Merge pull request #5862 from umbraco/v8/bugfix/5789-PublishedContentQuery-Search
Fixes #5789 - PublishedContentQuery Search always searches on culture
2019-07-24 14:16:32 +02:00
Shannon 7bc7dba86d fixes timing issue 2019-07-24 21:46:19 +10:00
Sebastiaan Janssen ca75a25802 Makes checks a little more robust 2019-07-24 11:33:12 +02:00
Shannon ece31733a9 Merge branch 'v8/dev' of https://github.com/umbraco/Umbraco-CMS into v8/dev 2019-07-24 19:25:48 +10:00
Shannon 28a8027179 removes reference to old packages.umbraco.org 2019-07-24 19:25:32 +10:00
Shannon 4fa523db43 Merge branch 'v7/7.15' into v7/dev 2019-07-24 19:23:58 +10:00
Shannon 186460ac08 removes refs from old packages.umbraco.org 2019-07-24 19:23:05 +10:00
Steve Megson a97604d6c4 Handle CSV values in TagsPropertyEditor 2019-07-24 11:14:00 +02:00
Bjarke Berg 308f929f7b Refactored tests to avoid duplicate code 2019-07-24 11:13:21 +02:00
Shannon c8d7df1515 Merge branch 'v8/bugfix/5789-PublishedContentQuery-Search' of https://github.com/umbraco/Umbraco-CMS into v8/bugfix/5789-PublishedContentQuery-Search 2019-07-24 18:46:48 +10:00
Shannon 2c795662d2 Adds tests for PublishedContentQuery search 2019-07-24 18:46:14 +10:00
Kenn Jacobsen 8a43e3a87e Make sure save options are up to date with the content state 2019-07-24 10:46:00 +02:00
Bjarke Berg 210e43fcb0 Fix for build 2019-07-24 09:53:51 +02:00
Shannon Deminick beb8c7ac7c Update src/Umbraco.Web/PublishedContentQuery.cs
Co-Authored-By: Bjarke Berg <mail@bergmania.dk>
2019-07-24 17:30:29 +10:00
Shannon Deminick 2f8979bbc3 Update src/Umbraco.Web/PublishedContentQuery.cs
Co-Authored-By: Bjarke Berg <mail@bergmania.dk>
2019-07-24 17:29:00 +10:00
Shannon a8ed7f2c17 adds new method 2019-07-23 22:11:02 +10:00
Frans de Jong 1c6bf55e5d GetCurrentLoginStatus()
In the summary of MembershipHelper.GetCurrentLoginStatus() it states that null will be returned when no member is logged in but that isn't the case (anymore?).
2019-07-23 13:02:11 +02:00
Bjarke Berg c246044ac7 Merge pull request #5972 from stevemegson/v8/temp-checkboxlist
Content migration - Include CheckBoxList in ValueListPreValueMigrator
2019-07-23 12:47:13 +02:00
Shannon 5126521d37 Fixes #5789 2019-07-23 19:09:15 +10:00
Shannon 27223738c6 Merge branch 'v8/8.1' into v8/dev
# Conflicts:
#	src/Umbraco.Web/PublishedCache/NuCache/PublishedSnapshotService.cs
2019-07-23 19:05:06 +10:00
Steve Megson 968463912a Include CheckBoxList in ValueListPreValueMigrator 2019-07-21 14:47:37 +01:00
Shannon Deminick 05c6b856f9 Merge pull request #5897 from kjac/v8-fix-media-type-add-property
V8: Fix YSOD when editing media types
2019-07-19 15:57:01 +10:00
Shannon 6fe3089207 Merge branch 'v8/8.1' into v8/dev
# Conflicts:
#	src/SolutionInfo.cs
#	src/Umbraco.Web/HtmlHelperRenderExtensions.cs
#	src/Umbraco.Web/Mvc/HttpUmbracoFormRouteStringException.cs
#	src/Umbraco.Web/Mvc/ValidateUmbracoFormRouteStringAttribute.cs
2019-07-17 22:31:54 +10:00
Shannon Deminick 06b136fdf6 Merge pull request #5895 from ronaldbarendse/v8/feature/validate-umbracoformroutestring
Added attribute to validate Umbraco form route strings (ufprt)
2019-07-16 22:01:32 +10:00
Bjarke Berg c6246b5404 Merge remote-tracking branch 'origin/v8/dev' into v8/dev 2019-07-16 13:46:07 +02:00
Bjarke Berg 3062f40ef5 Missing file in project file 2019-07-16 13:43:10 +02:00
Bjarke Berg dcd0d38419 Merge remote-tracking branch 'origin/v8/8.1' into v8/dev 2019-07-16 13:41:30 +02:00
Bjarke Berg c01a8f8f13 Merge pull request #5887 from stevemegson/temp-content-migration
PR fixes 7 -> 8 migration bugs for #5852 and #5864
2019-07-16 13:37:08 +02:00
Kenn Jacobsen da71a94c39 Use IsCollectionEmpty() as per review 2019-07-16 12:45:27 +02:00
Shannon Deminick f6413af3f4 Merge pull request #5885 from hifi-phil/v8/dev
Change PropertyType.Alias to virtual
2019-07-16 20:31:58 +10:00
Bjarke Berg 2ec8281163 Merge pull request #5865 from skttl/5848-media-folders-not-showing
5848: changes innerjoin to left join, to allow folders in sql query
2019-07-16 07:24:46 +02:00
Bjarke Berg 440e649d6d Merge pull request #5861 from umbraco/v8/bugfix/cdf-upgrade-bug
Fixes issue during upgrade where umbraco can't clear cdf log files
2019-07-15 14:32:19 +02:00
Warren Buckley 47dcd37d1d Merge pull request #5784 from nathanwoulfe/5768-log-viewer-chart-naming
V8: Make log naming and colors consistent between Log Search and Log Overview
2019-07-15 11:47:20 +01:00
Kenn Jacobsen d60fc63e78 Fix YSOD when editing media types 2019-07-15 12:23:09 +02:00
Ronald Barendse b0c4042e87 Removed UmbracoAntiForgeryAdditionalDataProvider 2019-07-15 10:16:09 +02:00
Shannon da525513a3 Merge remote-tracking branch 'origin/v7/dev' into v8/dev
# Conflicts:
#	build/NuSpecs/tools/Web.config.install.xdt
#	src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.controller.js
#	src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js
#	src/Umbraco.Web/Editors/EntityController.cs
#	src/Umbraco.Web/UmbracoHelper.cs
2019-07-15 16:18:04 +10:00
Shannon Deminick 2ac5e61e44 Merge pull request #5881 from bjarnef/dev-v7-link-picker-url-anchors
v7: Fix link picker url and anchors
2019-07-15 13:02:47 +10:00
Ronald Barendse 101a8b6c78 Added ValidateUmbracoFormRouteStringAttribute to public controllers 2019-07-14 23:18:21 +02:00
Ronald Barendse f7a10e3a15 Added attribute to validate Umbraco form route strings (ufprt) 2019-07-14 23:18:06 +02:00
Steve Megson 4e0dd728a8 Fixes #5864 - migrate prevalues for Umbraco.DropDown.Flexible 2019-07-14 16:48:33 +01:00
Steve Megson 320ccf8105 Fixes #5852 - TablesForScheduledPublishing 2019-07-14 16:46:01 +01:00
hifi-phil 62f924a757 Change PropertyType.Alias to virtual
When unit testing PropertyType.Alias needs to be virtual to make it mockable. The underlying code on the set triggers IOC logic and makes it hard to test anything that uses Property Types.
2019-07-14 09:45:12 +01:00
Bjarne Fyrstenborg c47a08b553 Add overload for NiceUrl 2019-07-13 16:40:01 +02:00
Bjarne Fyrstenborg de9241bcf5 Add UmbracoHelper overload methods to get url by guid 2019-07-13 14:50:25 +02:00
Bjarne Fyrstenborg 7c03fe3c1f Adjust parameter 2019-07-13 14:49:35 +02:00
Bjarne Fyrstenborg 82eb241119 Add overload method for Udi 2019-07-13 14:49:05 +02:00
Bjarne Fyrstenborg 1073e6257c Adjust comments 2019-07-13 14:48:35 +02:00
Nathan Woulfe bc3e4847fe Merge branch '5768-log-viewer-chart-naming' of https://github.com/nathanwoulfe/umbraco-cms into 5768-log-viewer-chart-naming 2019-07-13 13:50:21 +10:00
Nathan Woulfe 1a7251909c fix empty array - was checking index against empty array, so condition was never met 2019-07-13 13:45:13 +10:00
Warren Buckley 61a18297d9 Make v8/dev now 8.2.0 2019-07-12 13:03:20 +01:00
Warren Buckley bdd413f9ee Merge branch 'v8/dev' into 5768-log-viewer-chart-naming 2019-07-12 12:30:32 +01:00
Bjarke Berg fd8ca35e63 Merge pull request #5869 from umbraco/v8/bugfix/logviewer-error-count
V8: Fixes LogViewer Error Count search result click
2019-07-12 12:56:08 +02:00
Warren Buckley fdd9aee773 Fixes LogViewer Error Count search result clickthrough to include errors & fatal without exception as well 2019-07-12 11:07:15 +01:00
skttl d31e71a838 changes innerjoin to left join, to allow folders in sql query 2019-07-12 07:33:17 +02:00
Nathan Woulfe 3c2a92d3b6 map log values into logtypedata array - removes need to add these in the correct order. 2019-07-12 14:21:28 +10:00
Nathan Woulfe cf49e6160a critical => fatal 2019-07-12 14:20:28 +10:00
Shannon ec93030e21 Merge branch 'v8/dev' of https://github.com/umbraco/Umbraco-CMS into v8/dev 2019-07-12 11:23:51 +10:00
Shannon 1d49c8626e Revert "V8: Don't show multiple open menus (take two) (#5609)"
This reverts commit 9ce996cbba.
2019-07-12 11:23:36 +10:00
Shannon 89bb94aa1a Fixes issue during upgrade where umbraco can't clear cdf log files 2019-07-12 10:57:26 +10:00
Warren Buckley 03a4b75176 Ran .\build SetUmbracoVersion 8.1.1 to bump version 2019-07-11 15:11:37 +01:00
Sebastiaan Janssen 943b54dcf7 Update 1_Bug.md 2019-07-11 11:55:01 +02:00
Warren Buckley 39bd18ec1a At some point we have upgraded Serilog.Filters.Expressions package & the signature/method name got changed to ByIncludingOnly() 2019-07-11 10:45:41 +01:00
Shannon e93ddff46b Merge branch 'nathanwoulfe-temp-5147-grid-reorder' into v8/dev 2019-07-09 11:01:11 +10:00
Nathan Woulfe 3144b51c91 fix behaviour on page load - don't add active class if sticky-bar is in viewport 2019-07-09 10:49:34 +10:00
Nathan Woulfe e92f68d040 improve variable naming 2019-07-09 10:46:29 +10:00
Nathan Woulfe 469054e9b3 No longer need scrollable-container attribute 2019-07-09 10:46:29 +10:00
Nathan Woulfe d17022d87d make it look pretty 2019-07-09 10:46:29 +10:00
Nathan Woulfe 6865629090 use position:sticky and IntersectionObserver instead of element cloning and position:fixed - much simpler. 2019-07-09 10:46:29 +10:00
Shannon a4749f201d Ensures luceneIndexer.WaitForIndexQueueOnShutdown is called even when not in MainDom 2019-07-08 23:03:20 +10:00
Shannon Deminick ad90264ef1 Merge pull request #5695 from linuselander/issue/5218
Enable removal of unpublished content from ExternalIndex
2019-07-08 19:34:25 +10:00
Shannon Deminick 9ba7e7742a Merge pull request #5801 from bielu/v8/dev
Remove last casting to LuceneIndex
2019-07-08 18:39:40 +10:00
arkadiuszbiel 6473f600c7 Remove last casting to LucenIndex 2019-07-08 08:48:49 +01:00
Nathan Woulfe 6329dfa629 Merge Andy's changes 2019-07-06 07:28:32 +10:00
Andy Butland 2cd0173534 Fixed incorrect label for "Fatal" errors on the log viewer pie chart.
Made the log viewer title variable so it either says "Log Overview For Today" or "Log Overview For Selected Time Period" (previously it said the former even if you'd adjusted the dates you were looking at.
Fixed up the selected date period display so the conjunction "to" is used between the dates when the selected time period is changed and querystring is updated.
Minor code tidy-up.
2019-07-04 14:35:06 +02:00
Nathan Woulfe a0bcfeddcc fix date range formatting on flatpickr - 'to' wasnt displayed after choosing a range 2019-07-04 11:48:02 +10:00
Nathan Woulfe c4b5483d8c make log naming and colors consistent between views 2019-07-04 11:19:10 +10:00
Linus Elander 7557c584d8 Adjusts conditions for which indexes should be affected when a node is unpublished 2019-06-19 21:41:47 +02:00
225 changed files with 3004 additions and 3436 deletions
+35
View File
@@ -0,0 +1,35 @@
# Contributing to Umbraco CMS
When youre considering creating a pull request for Umbraco CMS, we will categorize them in two different sizes, small and large.
The process for both sizes is very similar, as [explained in the contribution document](CONTRIBUTING.md#how-do-i-begin).
## Small PRs
Bug fixes and small improvements - can be recognized by seeing a small number of changes and possibly a small number of new files.
Were usually able to handle small PRs pretty quickly. A community volunteer will do the initial review and flag it for Umbraco HQ as “community tested”. If everything looks good, it will be merged pretty quickly [as per the described process](REVIEW_PROCESS.md).
### Up for grabs
Umbraco HQ will regularly mark newly created issues on the issue tracker with the `Up for grabs` tag. This means that the proposed changes are wanted in Umbraco but the HQ does not have the time to make them at this time. We encourage anyone to pick them up and help out.
If you do start working on something, make sure leave a small comment on the issue saying something like: "I'm working on this". That way other people stumbling upon the issue know they don't need to pick it up, someone already has.
## Large PRs
New features and large refactorings - can be recognized by seeing a large number of changes, plenty of new files, updates to package manager files (NuGets packages.config, NPMs packages.json, etc.).
We would love to follow the same process for larger PRs but this is not always possible due to time limitations and priorities that need to be aligned. We dont want to put up any barriers, but this document should set the correct expectations.
Please make sure to describe your idea in an issue, it helps to put in mockup screenshots or videos.
If the change makes sense for HQ to include in Umbraco CMS we will leave you some feedback on how wed like to see it being implemented.
If a larger pull request is encouraged by Umbraco HQ, the process will be similar to what is described in the [small PRs process](#small-prs) above, we strive to feedback within 14 days. Finalizing and merging the PR might take longer though as it will likely need to be picked up by the development team to make sure everything is in order. Well keep you posted on the progress.
It is highly recommended that you speak to the HQ before making large, complex changes.
### Pull request or package?
If it doesnt fit in CMS right now, we will likely encourage you to make it into a package instead. A package is a great way to check out popularity of a feature, learn how people use it, validate good usability and to fix bugs.
Eventually, a package could "graduate" to be included in the CMS.
+1 -1
View File
@@ -12,7 +12,7 @@ thoroughly. Then, proceed by filling out the rest of the details in the issue
template below. The more details you can give us, the easier it will be for us
to determine the cause of a problem.
See: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/.github/CONTRIBUTING.md
See: https://github.com/umbraco/Umbraco-CMS/blob/v8/dev/.github/CONTRIBUTING.md
-->
+25
View File
@@ -0,0 +1,25 @@
# Review process
You're an awesome person and have sent us your contribution in the form of a pull request! It's now time to relax for a bit and wait for our response.
In order to set some expectations, here's what happens next.
## Review process
You will get an initial reply within 48 hours (workdays) to acknowledge that weve seen your PR and well pick it up as soon as we can.
You will get feedback within at most 14 days after opening the PR. Youll most likely get feedback sooner though. Then there are a few possible outcomes:
- Your proposed change is awesome! We merge it in and it will be included in the next minor release of Umbraco
- If the change is a high priority bug fix, we will cherry-pick it into the next patch release as well so that we can release it as soon as possible
- Your proposed change is awesome but needs a bit more work, well give you feedback on the changes wed like to see
- Your proposed change is awesome but.. not something were looking to include at this point. Well close your PR and the related issue (well be nice about it!)
## Are you still available?
We understand you have other things to do and can't just drop everything to help us out.
So if were asking for your help to improve the PR well wait for two weeks to give you a fair chance to make changes. Well ask for an update if we dont hear back from you after that time.
If we dont hear back from you for 4 weeks, well close the PR so that it doesnt just hang around forever. Youre very welcome to re-open it once you have some more time to spend on it.
There will be times that we really like your proposed changes and well finish the final improvements wed like to see ourselves. You still get the credits and your commits will live on in the git repository.
+7 -7
View File
@@ -1,11 +1,11 @@
888
888
888 888 88888b.d88b. 88888b. 888d888 8888b. .d8888b .d88b.
888 888 888 "888 "88b 888 "88b 888P" "88b d88P" d88""88b
888 888 888 888 888 888 888 888 .d888888 888 888 888
Y88b 888 888 888 888 888 d88P 888 888 888 Y88b. Y88..88P
"Y88888 888 888 888 88888P" 888 "Y888888 "Y8888P "Y88P"
888
888
888 888 88888b.d88b. 88888b. 888d888 8888b. .d8888b .d88b.
888 888 888 "888 "88b 888 "88b 888P" "88b d88P" d88""88b
888 888 888 888 888 888 888 888 .d888888 888 888 888
Y88 88Y 888 888 888 888 d88P 888 888 888 Y88b. Y88..88P
"Y888P" 888 888 888 88888P" 888 "Y888888 "Y8888P "Y88P"
------------------------------------------------------------------
+8 -7
View File
@@ -1,12 +1,13 @@
_ _ __ __ ____ _____ _____ ____
| | | | \/ | _ \| __ \ /\ / ____/ __ \
| | | | \ / | |_) | |__) | / \ | | | | | |
| | | | |\/| | _ <| _ / / /\ \| | | | | |
| |__| | | | | |_) | | \ \ / ____ | |___| |__| |
\____/|_| |_|____/|_| \_/_/ \_\_____\____/
888
888
888 888 88888b.d88b. 88888b. 888d888 8888b. .d8888b .d88b.
888 888 888 "888 "88b 888 "88b 888P" "88b d88P" d88""88b
888 888 888 888 888 888 888 888 .d888888 888 888 888
Y88 88Y 888 888 888 888 d88P 888 888 888 Y88b. Y88..88P
"Y888P" 888 888 888 88888P" 888 "Y888888 "Y8888P "Y88P"
----------------------------------------------------
------------------------------------------------------------------
Don't forget to build!
+2 -2
View File
@@ -18,5 +18,5 @@ using System.Resources;
[assembly: AssemblyVersion("8.0.0")]
// these are FYI and changed automatically
[assembly: AssemblyFileVersion("8.1.2")]
[assembly: AssemblyInformationalVersion("8.1.2")]
[assembly: AssemblyFileVersion("8.2.0")]
[assembly: AssemblyInformationalVersion("8.2.0")]
@@ -90,7 +90,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions
// register the IFileSystem supporting the IMediaFileSystem
// THIS IS THE ONLY THING THAT NEEDS TO CHANGE, IN ORDER TO REPLACE THE UNDERLYING FILESYSTEM
// and, SupportingFileSystem.For<IMediaFileSystem>() returns the underlying filesystem
composition.SetMediaFileSystem(() => new PhysicalFileSystem("~/media"));
composition.SetMediaFileSystem(() => new PhysicalFileSystem(SystemDirectories.Media));
return composition;
}
@@ -96,7 +96,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions
var pluginLangFolders = appPlugins.Exists == false
? Enumerable.Empty<LocalizedTextServiceSupplementaryFileSource>()
: appPlugins.GetDirectories()
.SelectMany(x => x.GetDirectories("Lang"))
.SelectMany(x => x.GetDirectories("Lang", SearchOption.AllDirectories))
.SelectMany(x => x.GetFiles("*.xml", SearchOption.TopDirectoryOnly))
.Select(x => new LocalizedTextServiceSupplementaryFileSource(x, false));
@@ -96,6 +96,11 @@ namespace Umbraco.Core
/// </summary>
public const string MediaPicker = "Umbraco.MediaPicker";
/// <summary>
/// Multiple Media Picker.
/// </summary>
public const string MultipleMediaPicker = "Umbraco.MultipleMediaPicker";
/// <summary>
/// Member Picker.
/// </summary>
@@ -203,6 +208,24 @@ namespace Umbraco.Core
/// <remarks>Must be a valid <see cref="ValueTypes"/> value.</remarks>
public const string DataValueType = "umbracoDataValueType";
}
/// <summary>
/// Defines Umbraco's built-in property editor groups.
/// </summary>
public static class Groups
{
public const string Common = "Common";
public const string Lists = "Lists";
public const string Media = "Media";
public const string People = "People";
public const string Pickers = "Pickers";
public const string RichContent = "Rich Content";
}
}
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
@@ -15,7 +16,7 @@ namespace Umbraco.Core
/// <returns></returns>
public static string ToIsoString(this DateTime dt)
{
return dt.ToString("yyyy-MM-dd HH:mm:ss");
return dt.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
}
public static DateTime TruncateTo(this DateTime dt, DateTruncate truncateTo)
@@ -42,6 +42,12 @@ namespace Umbraco.Core.Logging.Viewer
bool CheckCanOpenLogs(LogTimePeriod logTimePeriod);
/// <summary>
/// Gets the current Serilog minimum log level
/// </summary>
/// <returns></returns>
string GetLogLevel();
/// <summary>
/// Returns the collection of logs
/// </summary>
@@ -1,11 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using Newtonsoft.Json;
using Serilog;
using Serilog.Events;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Formatting = Newtonsoft.Json.Formatting;
namespace Umbraco.Core.Logging.Viewer
{
@@ -89,6 +92,16 @@ namespace Umbraco.Core.Logging.Viewer
return errorCounter.Count;
}
/// <summary>
/// Get the Serilog minimum-level value from the config file.
/// </summary>
/// <returns></returns>
public string GetLogLevel()
{
var logLevel = Enum.GetValues(typeof(LogEventLevel)).Cast<LogEventLevel>().Where(Log.Logger.IsEnabled)?.Min() ?? null;
return logLevel?.ToString() ?? "";
}
public LogLevelCounts GetLogLevelCounts(LogTimePeriod logTimePeriod)
{
var counter = new CountingFilter();
@@ -1,5 +1,7 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using NPoco;
using Umbraco.Core;
using Umbraco.Core.Migrations.Expressions.Common;
using Umbraco.Core.Persistence.SqlSyntax;
@@ -27,31 +29,57 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.KeysAndIndexes
{
_context.BuildingExpression = false;
//get a list of all constraints - this will include all PK, FK and unique constraints
var tableConstraints = _context.SqlContext.SqlSyntax.GetConstraintsPerTable(_context.Database).DistinctBy(x => x.Item2).ToList();
//get a list of defined indexes - this will include all indexes, unique indexes and unique constraint indexes
var indexes = _context.SqlContext.SqlSyntax.GetDefinedIndexesDefinitions(_context.Database).DistinctBy(x => x.IndexName).ToList();
var uniqueConstraintNames = tableConstraints.Where(x => !x.Item2.InvariantStartsWith("PK_") && !x.Item2.InvariantStartsWith("FK_")).Select(x => x.Item2);
var indexNames = indexes.Select(x => x.IndexName).ToList();
// drop keys
if (DeleteLocal || DeleteForeign)
{
// table, constraint
var tableKeys = _context.SqlContext.SqlSyntax.GetConstraintsPerTable(_context.Database).DistinctBy(x => x.Item2).ToList();
if (DeleteForeign)
{
foreach (var key in tableKeys.Where(x => x.Item1 == TableName && x.Item2.StartsWith("FK_")))
//In some cases not all FK's are prefixed with "FK" :/ mostly with old upgraded databases so we need to check if it's either:
// * starts with FK OR
// * doesn't start with PK_ and doesn't exist in the list of indexes
foreach (var key in tableConstraints.Where(x => x.Item1 == TableName
&& (x.Item2.InvariantStartsWith("FK_") || (!x.Item2.InvariantStartsWith("PK_") && !indexNames.InvariantContains(x.Item2)))))
{
Delete.ForeignKey(key.Item2).OnTable(key.Item1).Do();
}
}
if (DeleteLocal)
{
foreach (var key in tableKeys.Where(x => x.Item1 == TableName && x.Item2.StartsWith("PK_")))
foreach (var key in tableConstraints.Where(x => x.Item1 == TableName && x.Item2.InvariantStartsWith("PK_")))
Delete.PrimaryKey(key.Item2).FromTable(key.Item1).Do();
// note: we do *not* delete the DEFAULT constraints
// note: we do *not* delete the DEFAULT constraints and if we wanted to we'd have to deal with that in interesting ways
// since SQL server has a specific way to handle that, see SqlServerSyntaxProvider.GetDefaultConstraintsPerColumn
}
}
// drop indexes
if (DeleteLocal)
{
var indexes = _context.SqlContext.SqlSyntax.GetDefinedIndexesDefinitions(_context.Database).DistinctBy(x => x.IndexName).ToList();
{
foreach (var index in indexes.Where(x => x.TableName == TableName))
Delete.Index(index.IndexName).OnTable(index.TableName).Do();
{
//if this is a unique constraint we need to drop the constraint, else drop the index
//to figure this out, the index must be tagged as unique and it must exist in the tableConstraints
if (index.IsUnique && uniqueConstraintNames.InvariantContains(index.IndexName))
Delete.UniqueConstraint(index.IndexName).FromTable(index.TableName).Do();
else
Delete.Index(index.IndexName).OnTable(index.TableName).Do();
}
}
}
@@ -0,0 +1,19 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes
{
class MarkdownEditorPreValueMigrator : DefaultPreValueMigrator //PreValueMigratorBase
{
public override bool CanMigrate(string editorAlias)
=> editorAlias == Constants.PropertyEditors.Aliases.MarkdownEditor;
protected override object GetPreValueValue(PreValueDto preValue)
{
if (preValue.Alias == "preview")
return preValue.Value == "1";
return base.GetPreValueValue(preValue);
}
}
}
@@ -20,7 +20,8 @@ public class PreValueMigratorComposer : ICoreComposer
.Append<DecimalPreValueMigrator>()
.Append<ListViewPreValueMigrator>()
.Append<DropDownFlexiblePreValueMigrator>()
.Append<ValueListPreValueMigrator>();
.Append<ValueListPreValueMigrator>()
.Append<MarkdownEditorPreValueMigrator>();
}
}
}
@@ -15,21 +15,17 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
{
//special trick to add the column without constraints and return the sql to add them later
AddColumn<MacroDto>("macroType", out var sqls1);
//now we need to update the new column with some values because this column doesn't allow NULL values
Update.Table(Constants.DatabaseSchema.Tables.Macro).Set(new { macroType = (int)MacroTypes.Unknown}).AllRows().Do();
//now apply constraints (NOT NULL) to new table
foreach (var sql in sqls1) Execute.Sql(sql).Do();
//special trick to add the column without constraints and return the sql to add them later
AddColumn<MacroDto>("macroSource", out var sqls2);
//populate the new macroSource column with legacy data
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroXSLT, macroType = {(int)MacroTypes.Unknown} WHERE macroXSLT IS NOT NULL").Do();
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroScriptAssembly, macroType = {(int)MacroTypes.Unknown} WHERE macroScriptAssembly IS NOT NULL").Do();
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroScriptType, macroType = {(int)MacroTypes.Unknown} WHERE macroScriptType IS NOT NULL").Do();
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroPython, macroType = {(int)MacroTypes.PartialView} WHERE macroPython IS NOT NULL").Do();
//populate the new columns with legacy data
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = '', macroType = {(int)MacroTypes.Unknown}").Do();
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroXSLT, macroType = {(int)MacroTypes.Unknown} WHERE macroXSLT != '' AND macroXSLT IS NOT NULL").Do();
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroScriptAssembly, macroType = {(int)MacroTypes.Unknown} WHERE macroScriptAssembly != '' AND macroScriptAssembly IS NOT NULL").Do();
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroScriptType, macroType = {(int)MacroTypes.Unknown} WHERE macroScriptType != '' AND macroScriptType IS NOT NULL").Do();
Execute.Sql($"UPDATE {Constants.DatabaseSchema.Tables.Macro} SET macroSource = macroPython, macroType = {(int)MacroTypes.PartialView} WHERE macroPython != '' AND macroPython IS NOT NULL").Do();
//now apply constraints (NOT NULL) to new table
foreach (var sql in sqls1) Execute.Sql(sql).Do();
foreach (var sql in sqls2) Execute.Sql(sql).Do();
//now remove these old columns
@@ -50,10 +50,10 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_1_0
var obj = JsonConvert.DeserializeObject<JObject>(value);
var allControls = obj.SelectTokens("$.sections..rows..areas..controls");
foreach (var control in allControls.SelectMany(c => c))
foreach (var control in allControls.SelectMany(c => c).OfType<JObject>())
{
var controlValue = control["value"];
if (controlValue.Type == JTokenType.String)
if (controlValue?.Type == JTokenType.String)
{
control["value"] = UpdateMediaUrls(mediaLinkPattern, controlValue.Value<string>());
}
+1 -1
View File
@@ -114,7 +114,7 @@ namespace Umbraco.Core.Models
/// Gets of sets the alias of the property type.
/// </summary>
[DataMember]
public string Alias
public virtual string Alias
{
get => _alias;
set => SetPropertyValueAndDetectChanges(SanitizeAlias(value), ref _alias, nameof(Alias));
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Xml.Linq;
using System.Xml.XPath;
@@ -575,12 +574,11 @@ namespace Umbraco.Core.Packaging
contentType.Thumbnail = infoElement.Element("Thumbnail").Value;
contentType.Description = infoElement.Element("Description").Value;
//NOTE AllowAtRoot is a new property in the package xml so we need to verify it exists before using it.
//NOTE AllowAtRoot, IsListView, IsElement and Variations are new properties in the package xml so we need to verify it exists before using it.
var allowAtRoot = infoElement.Element("AllowAtRoot");
if (allowAtRoot != null)
contentType.AllowedAsRoot = allowAtRoot.Value.InvariantEquals("true");
//NOTE IsListView is a new property in the package xml so we need to verify it exists before using it.
var isListView = infoElement.Element("IsListView");
if (isListView != null)
contentType.IsContainer = isListView.Value.InvariantEquals("true");
@@ -589,6 +587,10 @@ namespace Umbraco.Core.Packaging
if (isElement != null)
contentType.IsElement = isElement.Value.InvariantEquals("true");
var variationsElement = infoElement.Element("Variations");
if (variationsElement != null)
contentType.Variations = (ContentVariation)Enum.Parse(typeof(ContentVariation), variationsElement.Value);
//Name of the master corresponds to the parent and we need to ensure that the Parent Id is set
var masterElement = infoElement.Element("Master");
if (masterElement != null)
@@ -614,7 +616,7 @@ namespace Umbraco.Core.Packaging
var compositionContentType = importedContentTypes.ContainsKey(compositionAlias)
? importedContentTypes[compositionAlias]
: _contentTypeService.Get(compositionAlias);
var added = contentType.AddContentType(compositionContentType);
contentType.AddContentType(compositionContentType);
}
}
}
@@ -748,9 +750,14 @@ namespace Umbraco.Core.Packaging
{
Name = property.Element("Name").Value,
Description = (string)property.Element("Description"),
Mandatory = property.Element("Mandatory") != null ? property.Element("Mandatory").Value.ToLowerInvariant().Equals("true") : false,
Mandatory = property.Element("Mandatory") != null
? property.Element("Mandatory").Value.ToLowerInvariant().Equals("true")
: false,
ValidationRegExp = (string)property.Element("Validation"),
SortOrder = sortOrder
SortOrder = sortOrder,
Variations = property.Element("Variations") != null
? (ContentVariation)Enum.Parse(typeof(ContentVariation), property.Element("Variations").Value)
: ContentVariation.Nothing
};
var tab = (string)property.Element("Tab");
@@ -174,7 +174,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
totalRecords = page.TotalItems;
var items = page.Items.Select(
dto => new AuditItem(dto.Id, Enum<AuditType>.ParseOrNull(dto.Header) ?? AuditType.Custom, dto.UserId ?? Constants.Security.UnknownUserId, dto.EntityType, dto.Comment, dto.Parameters)).ToList();
dto => new AuditItem(dto.NodeId, Enum<AuditType>.ParseOrNull(dto.Header) ?? AuditType.Custom, dto.UserId ?? Constants.Security.UnknownUserId, dto.EntityType, dto.Comment, dto.Parameters)).ToList();
// map the DateStamp
for (var i = 0; i < items.Count; i++)
@@ -404,7 +404,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
if (isMedia)
{
sql
.InnerJoin<MediaVersionDto>().On<ContentVersionDto, MediaVersionDto>((left, right) => left.Id == right.Id);
.LeftJoin<MediaVersionDto>().On<ContentVersionDto, MediaVersionDto>((left, right) => left.Id == right.Id);
}
//Any LeftJoin statements need to come last
@@ -250,7 +250,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
lock (_codeIdMap)
{
if (_codeIdMap.TryGetValue(isoCode, out var id)) return id;
if (isoCode.Contains('-') && _codeIdMap.TryGetValue(isoCode.Split('-').First(), out var invariantId)) return invariantId;
}
if (throwOnNotFound)
throw new ArgumentException($"Code {isoCode} does not correspond to an existing language.", nameof(isoCode));
@@ -30,7 +30,7 @@ namespace Umbraco.Core.PropertyEditors
// defaults
Type = type;
Icon = Constants.Icons.PropertyEditor;
Group = "common";
Group = Constants.PropertyEditors.Groups.Common;
// assign properties based on the attribute, if it is found
Attribute = GetType().GetCustomAttribute<DataEditorAttribute>(false);
@@ -121,7 +121,7 @@ namespace Umbraco.Core.PropertyEditors
/// Gets or sets an optional group.
/// </summary>
/// <remarks>The group can be used for example to group the editors by category.</remarks>
public string Group { get; set; } = "common";
public string Group { get; set; } = Constants.PropertyEditors.Groups.Common;
/// <summary>
/// Gets or sets a value indicating whether the value editor is deprecated.
@@ -5,7 +5,11 @@ namespace Umbraco.Core.PropertyEditors
/// <summary>
/// Represents a property editor for label properties.
/// </summary>
[DataEditor(Constants.PropertyEditors.Aliases.Label, "Label", "readonlyvalue", Icon = "icon-readonly")]
[DataEditor(
Constants.PropertyEditors.Aliases.Label,
"Label",
"readonlyvalue",
Icon = "icon-readonly")]
public class LabelPropertyEditor : DataEditor
{
/// <summary>
@@ -757,11 +757,11 @@ namespace Umbraco.Core.Services.Implement
{
var publishedState = content.PublishedState;
if (publishedState != PublishedState.Published && publishedState != PublishedState.Unpublished)
throw new InvalidOperationException("Cannot save (un)publishing content, use the dedicated SavePublished method.");
throw new InvalidOperationException($"Cannot save (un)publishing content with name: {content.Name} - and state: {content.PublishedState}, use the dedicated SavePublished method.");
if (content.Name != null && content.Name.Length > 255)
{
throw new InvalidOperationException("Name cannot be more than 255 characters in length.");
throw new InvalidOperationException($"Content with the name {content.Name} cannot be more than 255 characters in length.");
}
var evtMsgs = EventMessagesFactory.Get();
@@ -437,7 +437,8 @@ namespace Umbraco.Core.Services.Implement
new XElement("Description", contentType.Description),
new XElement("AllowAtRoot", contentType.AllowedAsRoot.ToString()),
new XElement("IsListView", contentType.IsContainer.ToString()),
new XElement("IsElement", contentType.IsElement.ToString()));
new XElement("IsElement", contentType.IsElement.ToString()),
new XElement("Variations", contentType.Variations.ToString()));
var masterContentType = contentType.ContentTypeComposition.FirstOrDefault(x => x.Id == contentType.ParentId);
if(masterContentType != null)
@@ -487,7 +488,8 @@ namespace Umbraco.Core.Services.Implement
new XElement("SortOrder", propertyType.SortOrder),
new XElement("Mandatory", propertyType.Mandatory.ToString()),
propertyType.ValidationRegExp != null ? new XElement("Validation", propertyType.ValidationRegExp) : null,
propertyType.Description != null ? new XElement("Description", new XCData(propertyType.Description)) : null);
propertyType.Description != null ? new XElement("Description", new XCData(propertyType.Description)) : null,
new XElement("Variations", propertyType.Variations.ToString()));
genericProperties.Add(genericProperty);
}
@@ -97,8 +97,7 @@ namespace Umbraco.Core.Sync
? ":" + request.ServerVariables["SERVER_PORT"]
: "";
var useSsl = globalSettings.UseHttps || port == "443";
var ssl = useSsl ? "s" : ""; // force, whatever the first request
var ssl = globalSettings.UseHttps ? "s" : ""; // force, whatever the first request
var url = "http" + ssl + "://" + request.ServerVariables["SERVER_NAME"] + port + IOHelper.ResolveUrl(SystemDirectories.Umbraco);
return url.TrimEnd('/');
+1
View File
@@ -235,6 +235,7 @@
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\IPreValueMigrator.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\ListViewPreValueMigrator.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\MediaPickerPreValueMigrator.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\MarkdownEditorPreValueMigrator.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\NestedContentPreValueMigrator.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\PreValueMigratorCollection.cs" />
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypes\PreValueMigratorCollectionBuilder.cs" />
+19 -18
View File
@@ -12,6 +12,7 @@ using Lucene.Net.Store;
using Umbraco.Core;
using Version = Lucene.Net.Util.Version;
using Umbraco.Core.Logging;
using System.Threading;
namespace Umbraco.Examine
{
@@ -28,29 +29,27 @@ namespace Umbraco.Examine
/// </remarks>
internal static readonly Regex CultureIsoCodeFieldNameMatchExpression = new Regex("^([_\\w]+)_([a-z]{2}-[a-z0-9]{2,4})$", RegexOptions.Compiled);
private static volatile bool _isUnlocked = false;
private static readonly object IsUnlockedLocker = new object();
private static bool _isConfigured = false;
private static object _configuredInit = null;
private static object _isConfiguredLocker = new object();
/// <summary>
/// Unlocks all Lucene based indexes registered with the <see cref="IExamineManager"/>
/// Called on startup to configure each index.
/// </summary>
/// <remarks>
/// Indexing rebuilding can occur on a normal boot if the indexes are empty or on a cold boot by the database server messenger. Before
/// either of these happens, we need to configure the indexes.
/// Configures and unlocks all Lucene based indexes registered with the <see cref="IExamineManager"/>.
/// </remarks>
internal static void EnsureUnlocked(this IExamineManager examineManager, IMainDom mainDom, ILogger logger)
internal static void ConfigureIndexes(this IExamineManager examineManager, IMainDom mainDom, ILogger logger)
{
if (!mainDom.IsMainDom) return;
if (_isUnlocked) return;
lock (IsUnlockedLocker)
{
//double check
if (_isUnlocked) return;
_isUnlocked = true;
examineManager.UnlockLuceneIndexes(logger);
}
LazyInitializer.EnsureInitialized(
ref _configuredInit,
ref _isConfigured,
ref _isConfiguredLocker,
() =>
{
examineManager.ConfigureLuceneIndexes(logger, !mainDom.IsMainDom);
return null;
});
}
//TODO: We need a public method here to just match a field name against CultureIsoCodeFieldNameMatchExpression
@@ -127,7 +126,7 @@ namespace Umbraco.Examine
/// <remarks>
/// This is not thread safe, use with care
/// </remarks>
internal static void UnlockLuceneIndexes(this IExamineManager examineManager, ILogger logger)
internal static void ConfigureLuceneIndexes(this IExamineManager examineManager, ILogger logger, bool disableExamineIndexing)
{
foreach (var luceneIndexer in examineManager.Indexes.OfType<LuceneIndex>())
{
@@ -136,6 +135,8 @@ namespace Umbraco.Examine
//that could end up halting shutdown for a very long time causing overlapping appdomains and many other problems.
luceneIndexer.WaitForIndexQueueOnShutdown = false;
if (disableExamineIndexing) continue; //exit if not enabled, we don't need to unlock them if we're not maindom
//we should check if the index is locked ... it shouldn't be! We are using simple fs lock now and we are also ensuring that
//the indexes are not operational unless MainDom is true
var dir = luceneIndexer.GetLuceneDirectory();
@@ -268,7 +268,7 @@ AnotherContentFinder
public void GetDataEditors()
{
var types = _typeLoader.GetDataEditors();
Assert.AreEqual(38, types.Count());
Assert.AreEqual(39, types.Count());
}
/// <summary>
@@ -79,39 +79,6 @@ namespace Umbraco.Tests.Persistence.Repositories
}
}
[Test]
public void Can_Perform_Get_By_Invariant_Code_On_LanguageRepository()
{
var provider = TestObjects.GetScopeProvider(Logger);
using (var scope = provider.CreateScope())
{
var repository = CreateRepository(provider);
var es = new CultureInfo("es");
var esSpecific = new CultureInfo("es-ES");
var language = (ILanguage)new Language(es.Name)
{
CultureName = es.DisplayName,
FallbackLanguageId = 1
};
repository.Save(language);
language = repository.GetByIsoCode(es.Name);
var languageSpecific = repository.GetByIsoCode(esSpecific.Name);
// Assert
Assert.That(language, Is.Not.Null);
Assert.That(language.HasIdentity, Is.True);
Assert.That(language.IsoCode, Is.EqualTo(es.Name));
Assert.That(languageSpecific, Is.Not.Null);
Assert.That(languageSpecific.HasIdentity, Is.True);
Assert.That(languageSpecific.Id, Is.EqualTo(language.Id));
Assert.That(language.IsoCode, Is.EqualTo(language.IsoCode));
}
}
[Test]
public void Get_When_Id_Doesnt_Exist_Returns_Null()
{
@@ -40,7 +40,7 @@ namespace Umbraco.Tests.Routing
{
base.SetUp();
WebFinalComponent.CreateRoutes(
WebInitialComponent.CreateRoutes(
new TestUmbracoContextAccessor(),
TestObjects.GetGlobalSettings(),
new SurfaceControllerTypeCollection(Enumerable.Empty<Type>()),
+23 -5
View File
@@ -16,13 +16,31 @@ module.exports = {
//processed in the js task
js: {
preview: { files: ["./src/preview/**/*.js"], out: "umbraco.preview.js" },
installer: { files: ["./src/installer/**/*.js"], out: "umbraco.installer.js" },
controllers: { files: ["./src/{views,controllers}/**/*.controller.js"], out: "umbraco.controllers.js" },
directives: { files: ["./src/common/directives/**/*.js"], out: "umbraco.directives.js" },
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" }
security: { files: ["./src/common/interceptors/**/*.js"], out: "umbraco.interceptors.js" },
//the controllers for views
controllers: {
files: [
"./src/views/**/*.controller.js",
"./src/*.controller.js"
], out: "umbraco.controllers.js"
},
//directives/components
// - any JS file found in common / directives or common/ components
// - any JS file found inside views that has the suffix .directive.js or .component.js
directives: {
files: [
"./src/common/directives/_module.js",
"./src/{common/directives,common/components}/**/*.js",
"./src/views/**/*.{directive,component}.js"
],
out: "umbraco.directives.js"
},
},
//selectors for copying all views into the build
@@ -34,7 +52,7 @@ module.exports = {
//globs for file-watching
globs:{
views: "./src/views/**/*.html",
views: ["./src/views/**/*.html", "./src/common/directives/**/*.html", "./src/common/components/**/*.html" ],
less: "./src/less/**/*.less",
js: "./src/*.js",
lib: "./lib/**/*",
+4 -1
View File
@@ -5,6 +5,9 @@ var gulp = require('gulp');
var runSequence = require('run-sequence');
// Dev - build the files ready for development and start watchers
gulp.task('dev', function(cb) {
gulp.task('dev', function (cb) {
global.isProd = false;
runSequence(["dependencies", "js", "less", "views"], "watch", cb);
});
@@ -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('fastdev', function(cb) {
global.isProd = false;
runSequence(["dependencies", "js", "less", "views"], "watch", cb);
});
@@ -9,26 +9,28 @@ var concat = require('gulp-concat');
var wrap = require("gulp-wrap-js");
var embedTemplates = require('gulp-angular-embed-templates');
module.exports = function(files, out) {
module.exports = function (files, out) {
var task = gulp.src(files);
if (global.isProd === true) {
// check for js errors
task = task.pipe(eslint());
// outputs the lint results to the console
task = task.pipe(eslint.format());
}
// check for js errors
task = task.pipe(eslint());
// outputs the lint results to the console
task = task.pipe(eslint.format());
// sort files in stream by path or any custom sort comparator
task = task.pipe(babel())
.pipe(sort())
.pipe(embedTemplates({ basePath: "./src/", minimize:{ loose: true } }))
.pipe(concat(out))
.pipe(sort());
if (global.isProd === true) {
//in production, embed the templates
task = task.pipe(embedTemplates({ basePath: "./src/", minimize: { loose: true } }))
}
task = task.pipe(concat(out))
.pipe(wrap('(function(){\n%= body %\n})();'))
.pipe(gulp.dest(config.root + config.targets.js));
return task;
};
@@ -17,17 +17,12 @@ module.exports = function(files, out) {
];
var task = gulp.src(files)
.pipe(less());
if (global.isProd === true) {
task = task.pipe(cleanCss());
}
task = task.pipe(postcss(processors))
.pipe(less())
.pipe(cleanCss())
.pipe(postcss(processors))
.pipe(rename(out))
.pipe(gulp.dest(config.root + config.targets.css));
return task;
};
};
@@ -1239,6 +1239,11 @@
// Perform the button's action.
function doClick(button) {
// don't do anything if the editor input or button bar isn't the currently active element
if (document.activeElement !== panels.input && !panels.buttonBar.contains(document.activeElement)) {
return;
}
inputBox.focus();
if (button.textOp) {
File diff suppressed because it is too large Load Diff
@@ -21,6 +21,12 @@
$scope.page.menu.currentSection = appState.getSectionState("currentSection");
$scope.page.listViewPath = null;
$scope.page.isNew = $scope.isNew ? true : false;
if (infiniteMode) {
$scope.page.allowInfinitePublishAndClose = $scope.infiniteModel.allowPublishAndClose;
$scope.page.allowInfiniteSaveAndClose = $scope.infiniteModel.allowSaveAndClose;
}
$scope.page.buttonGroupState = "init";
$scope.page.hideActionsMenu = infiniteMode ? true : false;
$scope.page.hideChangeVariant = false;
@@ -369,12 +375,17 @@
saveMethod: args.saveMethod,
scope: $scope,
content: $scope.content,
create: $scope.page.isNew,
action: args.action,
showNotifications: args.showNotifications,
softRedirect: true
}).then(function (data) {
//success
init();
//needs to be manually set for infinite editing mode
$scope.page.isNew = false;
syncTreeNode($scope.content, data.path);
eventsService.emit("content.saved", { content: $scope.content, action: args.action });
@@ -1,7 +1,7 @@
(function () {
'use strict';
function ContentNodeInfoDirective($timeout, logResource, eventsService, userService, localizationService, dateHelper, editorService, redirectUrlsResource, overlayService) {
function ContentNodeInfoDirective($timeout, logResource, eventsService, userService, localizationService, dateHelper, editorService, redirectUrlsResource, overlayService, entityResource) {
function link(scope) {
@@ -16,8 +16,12 @@
scope.disableTemplates = Umbraco.Sys.ServerVariables.features.disabledFeatures.disableTemplates;
scope.allowChangeDocumentType = false;
scope.allowChangeTemplate = false;
scope.allTemplates = [];
function onInit() {
entityResource.getAll("Template").then(function (templates) {
scope.allTemplates = templates;
});
// set currentVariant
scope.currentVariant = _.find(scope.node.variants, (v) => v.active);
@@ -158,8 +162,12 @@
}
scope.openTemplate = function () {
var template = _.findWhere(scope.allTemplates, {alias: scope.node.template})
if (!template) {
return;
}
var templateEditor = {
id: scope.node.templateId,
id: template.id,
submit: function (model) {
editorService.close();
},
@@ -1,7 +1,7 @@
(function () {
'use strict';
function EditorContentHeader(serverValidationManager) {
function EditorContentHeader(serverValidationManager, localizationService, editorState) {
function link(scope, el, attr, ctrl) {
@@ -13,7 +13,24 @@
if (!scope.serverValidationAliasField) {
scope.serverValidationAliasField = "Alias";
}
scope.isNew = scope.content.state == "NotCreated";
localizationService.localizeMany([
scope.isNew ? "placeholders_a11yCreateItem" : "placeholders_a11yEdit",
"placeholders_a11yName"]
).then(function (data) {
scope.a11yMessage = data[0];
scope.a11yName = data[1];
if (!scope.isNew) {
scope.a11yMessage += " " + scope.content.name;
} else {
var name = editorState.current.contentTypeName;
scope.a11yMessage += " " + name;
scope.a11yName = name + " " + scope.a11yName;
}
});
scope.vm = {};
scope.vm.dropdownOpen = false;
scope.vm.currentVariant = "";
@@ -16,9 +16,7 @@
editor.moveRight = true;
editor.level = 0;
editor.styleIndex = 0;
editor.infinityMode = true;
// push the new editor to the dom
scope.editors.push(editor);
@@ -11,6 +11,11 @@ function hexBgColor() {
restrict: "A",
link: function (scope, element, attr, formCtrl) {
function setBackgroundColor(color) {
// note: can't use element.css(), it doesn't support hexa background colors
angular.element(element)[0].style.backgroundColor = "#" + color;
}
// Only add inline hex background color if defined and not "true".
if (attr.hexBgInline === undefined || (attr.hexBgInline !== undefined && attr.hexBgInline === "true")) {
@@ -26,18 +31,21 @@ function hexBgColor() {
// Get the orig color before changing it.
origColor = element.css("border-color");
}
// Validate it - test with and without the leading hash.
if (/^([0-9a-f]{3}|[0-9a-f]{6})$/i.test(newVal)) {
element.css("background-color", "#" + newVal);
// Is it a regular hex value - (#)AABBCC ?
var match = newVal.match(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i);
if (match && match.length) {
setBackgroundColor(match[1]);
return;
}
if (/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(newVal)) {
element.css("background-color", newVal);
// Is it a hexa value - (#)AABBCCDD ?
match = newVal.match(/^#?([0-9a-f]{4}|[0-9a-f]{8})$/i);
if (match && match.length) {
setBackgroundColor(match[1]);
return;
}
}
element.css("background-color", origColor);
setBackgroundColor(origColor);
});
}
}
@@ -14,6 +14,8 @@ angular.module("umbraco.directives")
// TODO: A lot of the code below should be shared between the grid rte and the normal rte
scope.isLoading = true;
var promises = [];
//To id the html textarea we need to use the datetime ticks because we can have multiple rte's per a single property alias
@@ -91,6 +93,10 @@ angular.module("umbraco.directives")
//custom initialization for this editor within the grid
editor.on('init', function (e) {
// Used this init event - as opposed to property init_instance_callback
// to turn off the loader
scope.isLoading = false;
//force overflow to hidden to prevent no needed scroll
editor.getBody().style.overflow = "hidden";
@@ -1,7 +1,7 @@
(function () {
'use strict';
function MediaNodeInfoDirective($timeout, $location, eventsService, userService, dateHelper, editorService) {
function MediaNodeInfoDirective($timeout, $location, eventsService, userService, dateHelper, editorService, mediaHelper) {
function link(scope, element, attrs, ctrl) {
@@ -28,6 +28,9 @@
// make sure dates are formatted to the user's locale
formatDatesToLocal();
// set media file extension initially
setMediaExtension();
}
function formatDatesToLocal() {
@@ -49,6 +52,10 @@
}
}
function setMediaExtension() {
scope.node.extension = mediaHelper.getFileExtension(scope.nodeUrl);
}
scope.openMediaType = function (mediaType) {
var editor = {
id: mediaType.id,
@@ -62,6 +69,16 @@
editorService.mediaTypeEditor(editor);
};
scope.openSVG = function () {
var popup = window.open('', '_blank');
var html = '<!DOCTYPE html><body><img src="' + scope.nodeUrl + '"/>' +
'<script>history.pushState(null, null,"' + $location.$$absUrl + '");</script></body>';
popup.document.open();
popup.document.write(html);
popup.document.close();
}
// watch for content updates - reload content when node is saved, published etc.
scope.$watch('node.updateDate', function(newValue, oldValue){
if(!newValue) { return; }
@@ -72,6 +89,9 @@
// Update the create and update dates
formatDatesToLocal();
//Update the media file format
setMediaExtension();
});
//ensure to unregister from all events!
@@ -1,13 +1,13 @@
/**
@ngdoc directive
@name umbraco.directives.directive:umbFlatpickr
@name umbraco.directives.directive:umbDateTimePicker
@restrict E
@scope
@description
<b>Added in Umbraco version 8.0</b>
This directive is a wrapper of the flatpickr library. Use it to render a date time picker.
For extra details about options and events take a look here: https://flatpickr.js.org/
For extra details about options and events take a look here: https://flatpickr.js.org
Use this directive to render a date time picker
@@ -15,11 +15,11 @@ Use this directive to render a date time picker
<pre>
<div ng-controller="My.Controller as vm">
<umb-flatpickr
<umb-date-time-picker
ng-model="vm.date"
options="vm.config"
on-change="vm.datePickerChange(selectedDates, dateStr, instance)">
</umb-flatpickr>
</umb-date-time-picker>
</div>
</pre>
@@ -70,12 +70,12 @@ Use this directive to render a date time picker
(function() {
'use strict';
var umbFlatpickr = {
var umbDateTimePicker = {
template: '<ng-transclude>' +
'<input type="text" ng-if="!$ctrl.options.inline" ng-model="$ctrl.ngModel" placeholder="Select Date.."></input>' +
'<div ng-if="$ctrl.options.inline"></div>' +
'</ng-transclude>',
controller: umbFlatpickrCtrl,
controller: umbDateTimePickerCtrl,
transclude: true,
bindings: {
ngModel: '<',
@@ -92,9 +92,9 @@ Use this directive to render a date time picker
}
};
function umbFlatpickrCtrl($element, $timeout, $scope, assetsService, userService) {
function umbDateTimePickerCtrl($element, $timeout, $scope, assetsService, userService) {
var ctrl = this;
var loaded = false;
var userLocale = null;
ctrl.$onInit = function() {
@@ -102,14 +102,14 @@ Use this directive to render a date time picker
// load css file for the date picker
assetsService.loadCss('lib/flatpickr/flatpickr.css', $scope).then(function () {
userService.getCurrentUser().then(function (user) {
// init date picker
userLocale = user.locale;
if (userLocale.indexOf('-') > -1) {
userLocale = userLocale.split('-')[0];
}
loaded = true;
grabElementAndRunFlatpickr();
grabElementAndRunFlatpickr();
});
});
@@ -234,7 +234,8 @@ Use this directive to render a date time picker
}
}
angular.module('umbraco.directives').component('umbFlatpickr', umbFlatpickr);
// umbFlatpickr (umb-flatpickr) is deprecated, but we keep it for backwards compatibility
angular.module('umbraco.directives').component('umbFlatpickr', umbDateTimePicker);
angular.module('umbraco.directives').component('umbDateTimePicker', umbDateTimePicker);
})();
@@ -17,6 +17,7 @@
scope.sortableOptionsGroup = {};
scope.sortableOptionsProperty = {};
scope.sortingButtonKey = "general_reorder";
scope.compositionsButtonState = "init";
function activate() {
@@ -337,6 +338,7 @@
})), function(f) {
return f !== null && f !== undefined;
});
scope.compositionsButtonState = "busy";
$q.all([
//get available composite types
availableContentTypeResource(scope.model.id, [], propAliasesExisting).then(function (result) {
@@ -356,6 +358,7 @@
]).then(function() {
//resolves when both other promises are done, now show it
editorService.open(scope.compositionsDialogModel);
scope.compositionsButtonState = "init";
});
};
@@ -532,6 +535,7 @@
// push new init tab to the scope
addInitGroup(scope.model.groups);
notifyChanged();
},
close: function() {
if(_.isEqual(oldPropertyModel, propertyModel) === false) {
@@ -588,8 +592,13 @@
}
notifyChanged();
};
function notifyChanged() {
eventsService.emit("editors.groupsBuilder.changed");
}
function addInitProperty(group) {
var addInitPropertyBool = true;
@@ -0,0 +1,75 @@
/**
@ngdoc directive
@name umbraco.directives.directive:umbLoader
@restrict E
@description
Use this directive to generate a loading indicator.
<h3>Markup example</h3>
<pre>
<div ng-controller="My.Controller as vm">
<umb-loader
ng-if="vm.loading">
</umb-loader>
<div class="content" ng-if="!vm.loading">
<p>{{content}}</p>
</div>
</div>
</pre>
<h3>Controller example</h3>
<pre>
(function () {
"use strict";
function Controller(myService) {
var vm = this;
vm.content = "";
vm.loading = true;
myService.getContent().then(function(content){
vm.content = content;
vm.loading = false;
});
}
angular.module("umbraco").controller("My.Controller", Controller);
})();
</pre>
@param {string=} position The loader position ("top", "bottom").
**/
(function() {
'use strict';
function UmbLoaderDirective() {
function link(scope, el, attr, ctrl) {
}
var directive = {
restrict: 'E',
replace: true,
templateUrl: 'views/components/umb-loader.html',
scope: {
position: "@?"
},
link: link
};
return directive;
}
angular.module('umbraco.directives').directive('umbLoader', UmbLoaderDirective);
})();
@@ -39,7 +39,7 @@ Use this directive to generate a loading indicator.
});
}
½
angular.module("umbraco").controller("My.Controller", Controller);
})();
</pre>
@@ -4,7 +4,7 @@
@restrict A
@description
Use this directive make an element sticky and follow the page when scrolling.
Use this directive make an element sticky and follow the page when scrolling. `umb-sticky-bar--active` class is applied when the element is stuck
<h3>Markup example</h3>
<pre>
@@ -12,140 +12,102 @@ Use this directive make an element sticky and follow the page when scrolling.
<div
class="my-sticky-bar"
umb-sticky-bar
scrollable-container=".container">
umb-sticky-bar>
</div>
</div>
</pre>
<h3>CSS example</h3>
<pre>
.my-sticky-bar {
padding: 15px 0;
background: #000000;
position: relative;
top: 0;
}
.my-sticky-bar.-umb-sticky-bar {
top: 100px;
}
</pre>
@param {string} scrollableContainer Set the class (".element") or the id ("#element") of the scrollable container element.
**/
(function () {
'use strict';
function StickyBarDirective($rootScope) {
function StickyBarDirective() {
/**
On initial load, the intersector fires if the grid editor is in the viewport
This flag is used to suppress the setClass behaviour on the initial load
**/
var initial = true;
/**
Toggle `umb-sticky-bar--active` class on the sticky-bar element
**/
function setClass(addClass, current) {
if (!initial) {
current.classList.toggle('umb-sticky-bar--active', addClass);
} else {
initial = false;
}
}
/**
Inserts two elements in the umbStickyBar parent element
These are used by the IntersectionObserve to calculate scroll position
**/
function addSentinels(current) {
['-top', '-bottom'].forEach(s => {
const sentinel = document.createElement('div');
sentinel.classList.add('umb-sticky-sentinel', s);
current.parentElement.appendChild(sentinel);
});
}
/**
Calls into setClass when the footer sentinel enters/exits the bottom of the container
Container is the parent element of the umbStickyBar element
**/
function observeFooter(current, container) {
const observer = new IntersectionObserver((records, observer) => {
let [target, rootBounds, intersected] = [records[0].boundingClientRect, records[0].rootBounds, records[0].intersectionRatio === 1];
if (target.bottom > rootBounds.top && intersected) {
setClass(true, current);
}
if (target.top < rootBounds.top && target.bottom < rootBounds.bottom) {
setClass(false, current);
}
}, {
threshold: [1],
root: container
});
observer.observe(current.parentElement.querySelector('.umb-sticky-sentinel.-bottom'));
}
/**
Calls into setClass when the header sentinel enters/exits the top of the container
Container is the parent element of the umbStickyBar element
**/
function observeHeader(current, container) {
const observer = new IntersectionObserver((records, observer) => {
let [target, rootBounds] = [records[0].boundingClientRect, records[0].rootBounds];
if (target.bottom < rootBounds.top) {
setClass(true, current);
}
if (target.bottom >= rootBounds.top && target.bottom < rootBounds.bottom) {
setClass(false, current);
}
}, {
threshold: [0],
root: container
});
observer.observe(current.parentElement.querySelector('.umb-sticky-sentinel.-top'));
}
function link(scope, el, attr, ctrl) {
var bar = $(el);
var scrollableContainer = null;
var clonedBar = null;
var cloneIsMade = false;
let current = el[0];
let container = current.closest('[data-element="editor-container"]');
function activate() {
if (bar.parents(".umb-property").length > 1) {
bar.addClass("nested");
return;
}
if (attr.scrollableContainer) {
scrollableContainer = bar.closest(attr.scrollableContainer);
} else {
scrollableContainer = $(window);
}
scrollableContainer.on('scroll.umbStickyBar', determineVisibility).trigger("scroll");
$(window).on('resize.umbStickyBar', determineVisibility);
scope.$on('$destroy', function () {
scrollableContainer.off('.umbStickyBar');
$(window).off('.umbStickyBar');
});
}
function determineVisibility() {
var barTop = bar[0].offsetTop;
var scrollTop = scrollableContainer.scrollTop();
if (scrollTop > barTop) {
if (!cloneIsMade) {
createClone();
clonedBar.css({
'visibility': 'visible'
});
} else {
calculateSize();
}
} else {
if (cloneIsMade) {
//remove cloned element (switched places with original on creation)
bar.remove();
bar = clonedBar;
clonedBar = null;
bar.removeClass('-umb-sticky-bar');
bar.css({
position: 'relative',
'width': 'auto',
'height': 'auto',
'z-index': 'auto',
'visibility': 'visible'
});
cloneIsMade = false;
}
}
}
function calculateSize() {
var width = bar.innerWidth();
clonedBar.css({
width: width + 10 // + 10 (5*2) because we need to add border to avoid seeing the shadow beneath. Look at the CSS.
});
}
function createClone() {
//switch place with cloned element, to keep binding intact
clonedBar = bar;
bar = clonedBar.clone();
clonedBar.after(bar);
clonedBar.addClass('-umb-sticky-bar');
clonedBar.css({
'position': 'fixed',
// if you change this z-index value, make sure the sticky editor sub headers do not
// clash with umb-dropdown (e.g. the content actions dropdown in content list view)
'z-index': 99,
'visibility': 'hidden'
});
cloneIsMade = true;
calculateSize();
}
activate();
addSentinels(current);
observeHeader(current, container);
observeFooter(current, container);
}
var directive = {
@@ -1,167 +1,172 @@
(function () {
'use strict';
'use strict';
function ChangePasswordController($scope) {
function ChangePasswordController($scope) {
function resetModel(isNew) {
//the model config will contain an object, if it does not we'll create defaults
//NOTE: We will not support doing the password regex on the client side because the regex on the server side
//based on the membership provider cannot always be ported to js from .net directly.
/*
{
hasPassword: true/false,
requiresQuestionAnswer: true/false,
enableReset: true/false,
enablePasswordRetrieval: true/false,
minPasswordLength: 10
}
*/
var vm = this;
$scope.showReset = false;
vm.$onInit = onInit;
vm.$onDestroy = onDestroy;
vm.doChange = doChange;
vm.cancelChange = cancelChange;
vm.showOldPass = showOldPass;
vm.showCancelBtn = showCancelBtn;
//set defaults if they are not available
if ($scope.config.disableToggle === undefined) {
$scope.config.disableToggle = false;
}
if ($scope.config.hasPassword === undefined) {
$scope.config.hasPassword = false;
}
if ($scope.config.enablePasswordRetrieval === undefined) {
$scope.config.enablePasswordRetrieval = true;
}
if ($scope.config.requiresQuestionAnswer === undefined) {
$scope.config.requiresQuestionAnswer = false;
}
//don't enable reset if it is new - that doesn't make sense
if (isNew === "true") {
$scope.config.enableReset = false;
}
else if ($scope.config.enableReset === undefined) {
$scope.config.enableReset = true;
}
if ($scope.config.minPasswordLength === undefined) {
$scope.config.minPasswordLength = 0;
}
//set the model defaults
if (!angular.isObject($scope.passwordValues)) {
//if it's not an object then just create a new one
$scope.passwordValues = {
newPassword: null,
oldPassword: null,
reset: null,
answer: null
};
}
else {
//just reset the values
var unsubscribe = [];
function resetModel(isNew) {
//the model config will contain an object, if it does not we'll create defaults
//NOTE: We will not support doing the password regex on the client side because the regex on the server side
//based on the membership provider cannot always be ported to js from .net directly.
/*
{
hasPassword: true/false,
requiresQuestionAnswer: true/false,
enableReset: true/false,
enablePasswordRetrieval: true/false,
minPasswordLength: 10
}
*/
vm.showReset = false;
//set defaults if they are not available
if (vm.config.disableToggle === undefined) {
vm.config.disableToggle = false;
}
if (vm.config.hasPassword === undefined) {
vm.config.hasPassword = false;
}
if (vm.config.enablePasswordRetrieval === undefined) {
vm.config.enablePasswordRetrieval = true;
}
if (vm.config.requiresQuestionAnswer === undefined) {
vm.config.requiresQuestionAnswer = false;
}
//don't enable reset if it is new - that doesn't make sense
if (isNew === "true") {
vm.config.enableReset = false;
}
else if (vm.config.enableReset === undefined) {
vm.config.enableReset = true;
}
if (vm.config.minPasswordLength === undefined) {
vm.config.minPasswordLength = 0;
}
//set the model defaults
if (!angular.isObject(vm.passwordValues)) {
//if it's not an object then just create a new one
vm.passwordValues = {
newPassword: null,
oldPassword: null,
reset: null,
answer: null
};
}
else {
//just reset the values
if (!isNew) {
//if it is new, then leave the generated pass displayed
vm.passwordValues.newPassword = null;
vm.passwordValues.oldPassword = null;
}
vm.passwordValues.reset = null;
vm.passwordValues.answer = null;
}
//the value to compare to match passwords
if (!isNew) {
vm.passwordValues.confirm = "";
}
else if (vm.passwordValues.newPassword && vm.passwordValues.newPassword.length > 0) {
//if it is new and a new password has been set, then set the confirm password too
vm.passwordValues.confirm = vm.passwordValues.newPassword;
}
if (!isNew) {
//if it is new, then leave the generated pass displayed
$scope.passwordValues.newPassword = null;
$scope.passwordValues.oldPassword = null;
}
$scope.passwordValues.reset = null;
$scope.passwordValues.answer = null;
}
//the value to compare to match passwords
if (!isNew) {
$scope.passwordValues.confirm = "";
}
else if ($scope.passwordValues.newPassword && $scope.passwordValues.newPassword.length > 0) {
//if it is new and a new password has been set, then set the confirm password too
$scope.passwordValues.confirm = $scope.passwordValues.newPassword;
}
//when the scope is destroyed we need to unsubscribe
function onDestroy() {
for (var u in unsubscribe) {
unsubscribe[u]();
}
}
function onInit() {
//listen for the saved event, when that occurs we'll
//change to changing = false;
unsubscribe.push($scope.$on("formSubmitted", function () {
if (vm.config.disableToggle === false) {
vm.changing = false;
}
}));
unsubscribe.push($scope.$on("formSubmitting", function () {
//if there was a previously generated password displaying, clear it
if (vm.changing && vm.passwordValues) {
vm.passwordValues.generatedPassword = null;
}
else if (!vm.changing) {
//we are not changing, so the model needs to be null
vm.passwordValues = null;
}
}));
resetModel(vm.isNew);
//if there is no password saved for this entity , it must be new so we do not allow toggling of the change password, it is always there
//with validators turned on.
vm.changing = vm.config.disableToggle === true || !vm.config.hasPassword;
//we're not currently changing so set the model to null
if (!vm.changing) {
vm.passwordValues = null;
}
}
function doChange() {
resetModel();
vm.changing = true;
//if there was a previously generated password displaying, clear it
vm.passwordValues.generatedPassword = null;
vm.passwordValues.confirm = null;
};
function cancelChange() {
vm.changing = false;
//set model to null
vm.passwordValues = null;
};
function showOldPass() {
return vm.config.hasPassword &&
!vm.config.allowManuallyChangingPassword &&
!vm.config.enablePasswordRetrieval && !vm.showReset;
};
// TODO: I don't think we need this or the cancel button, this can be up to the editor rendering this component
function showCancelBtn() {
return vm.config.disableToggle !== true && vm.config.hasPassword;
};
}
resetModel($scope.isNew);
//if there is no password saved for this entity , it must be new so we do not allow toggling of the change password, it is always there
//with validators turned on.
$scope.changing = $scope.config.disableToggle === true || !$scope.config.hasPassword;
//we're not currently changing so set the model to null
if (!$scope.changing) {
$scope.passwordValues = null;
}
$scope.doChange = function () {
resetModel();
$scope.changing = true;
//if there was a previously generated password displaying, clear it
$scope.passwordValues.generatedPassword = null;
$scope.passwordValues.confirm = null;
var component = {
templateUrl: 'views/components/users/change-password.html',
controller: ChangePasswordController,
controllerAs: 'vm',
bindings: {
isNew: "<",
passwordValues: "=", //TODO: Do we need bi-directional vals?
config: "=" //TODO: Do we need bi-directional vals?
//TODO: Do we need callbacks?
}
};
$scope.cancelChange = function () {
$scope.changing = false;
//set model to null
$scope.passwordValues = null;
};
var unsubscribe = [];
//listen for the saved event, when that occurs we'll
//change to changing = false;
unsubscribe.push($scope.$on("formSubmitted", function () {
if ($scope.config.disableToggle === false) {
$scope.changing = false;
}
}));
unsubscribe.push($scope.$on("formSubmitting", function () {
//if there was a previously generated password displaying, clear it
if ($scope.changing && $scope.passwordValues) {
$scope.passwordValues.generatedPassword = null;
}
else if (!$scope.changing) {
//we are not changing, so the model needs to be null
$scope.passwordValues = null;
}
}));
//when the scope is destroyed we need to unsubscribe
$scope.$on('$destroy', function () {
for (var u in unsubscribe) {
unsubscribe[u]();
}
});
$scope.showOldPass = function () {
return $scope.config.hasPassword &&
!$scope.config.allowManuallyChangingPassword &&
!$scope.config.enablePasswordRetrieval && !$scope.showReset;
};
// TODO: I don't think we need this or the cancel button, this can be up to the editor rendering this directive
$scope.showCancelBtn = function () {
return $scope.config.disableToggle !== true && $scope.config.hasPassword;
};
}
function ChangePasswordDirective() {
var directive = {
restrict: 'E',
replace: true,
templateUrl: 'views/components/users/change-password.html',
controller: 'Umbraco.Editors.Users.ChangePasswordDirectiveController',
scope: {
isNew: "=?",
passwordValues: "=",
config: "="
}
};
return directive;
}
angular.module('umbraco.directives').controller('Umbraco.Editors.Users.ChangePasswordDirectiveController', ChangePasswordController);
angular.module('umbraco.directives').directive('changePassword', ChangePasswordDirective);
angular.module('umbraco.directives').component('changePassword', component);
})();
@@ -104,21 +104,26 @@ function entityResource($q, $http, umbRequestHelper) {
*
* @param {Int} id Id of node to return the public url to
* @param {string} type Object type name
* @param {string} culture Culture
* @returns {Promise} resourcePromise object containing the url.
*
*/
getUrl: function (id, type) {
getUrl: function (id, type, culture) {
if (id === -1 || id === "-1") {
return "";
}
if (!culture) {
culture = "";
}
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"entityApiBaseUrl",
"GetUrl",
[{ id: id }, {type: type }])),
[{ id: id }, {type: type }, {culture: culture }])),
'Failed to retrieve url for id:' + id);
},
@@ -133,7 +138,7 @@ function entityResource($q, $http, umbRequestHelper) {
* ##usage
* <pre>
* //get media by id
* entityResource.getEntityById(0, "Media")
* entityResource.getById(0, "Media")
* .then(function(ent) {
* var myDoc = ent;
* alert('its here!');
@@ -172,7 +177,7 @@ function entityResource($q, $http, umbRequestHelper) {
umbRequestHelper.getApiUrl(
"entityApiBaseUrl",
"GetUrlAndAnchors",
{ id: id })),
[{ id: id }])),
'Failed to retrieve url and anchors data for id ' + id);
},
@@ -204,7 +209,7 @@ function entityResource($q, $http, umbRequestHelper) {
* ##usage
* <pre>
* //Get templates for ids
* entityResource.getEntitiesByIds( [1234,2526,28262], "Template")
* entityResource.getByIds( [1234,2526,28262], "Template")
* .then(function(templateArray) {
* var myDoc = contentArray;
* alert('they are here!');
@@ -7,64 +7,44 @@
**/
function logViewerResource($q, $http, umbRequestHelper) {
/**
* verb => 'get', 'post',
* method => API method to call
* params => additional data to send
* error => error message when things go wrong...
*/
const request = (verb, method, params, error) =>
umbRequestHelper.resourcePromise(
(verb === 'GET' ?
$http.get(umbRequestHelper.getApiUrl("logViewerApiBaseUrl", method) + (params ? params : '')) :
$http.post(umbRequestHelper.getApiUrl("logViewerApiBaseUrl", method), params)),
error);
//the factory object returned
return {
getNumberOfErrors: function (startDate, endDate) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"logViewerApiBaseUrl",
"GetNumberOfErrors")+ '?startDate='+startDate+ '&endDate='+ endDate ),
'Failed to retrieve number of errors in logs');
},
getNumberOfErrors: (startDate, endDate) =>
request('GET', 'GetNumberOfErrors', '?startDate=' + startDate + '&endDate=' + endDate, 'Failed to retrieve number of errors in logs'),
getLogLevelCounts: function (startDate, endDate) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"logViewerApiBaseUrl",
"GetLogLevelCounts")+ '?startDate='+startDate+ '&endDate='+ endDate ),
'Failed to retrieve log level counts');
},
getLogLevel: () =>
request('GET', 'GetLogLevel', null, 'Failed to retrieve log level'),
getMessageTemplates: function (startDate, endDate) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"logViewerApiBaseUrl",
"GetMessageTemplates")+ '?startDate='+startDate+ '&endDate='+ endDate ),
'Failed to retrieve log templates');
},
getLogLevelCounts: (startDate, endDate) =>
request('GET', 'GetLogLevelCounts', '?startDate=' + startDate + '&endDate=' + endDate, 'Failed to retrieve log level counts'),
getSavedSearches: function () {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"logViewerApiBaseUrl",
"GetSavedSearches")),
'Failed to retrieve saved searches');
},
getMessageTemplates: (startDate, endDate) =>
request('GET', 'GetMessageTemplates', '?startDate=' + startDate + '&endDate=' + endDate, 'Failed to retrieve log templates'),
postSavedSearch: function (name, query) {
return umbRequestHelper.resourcePromise(
$http.post(
umbRequestHelper.getApiUrl(
"logViewerApiBaseUrl",
"PostSavedSearch"), { 'name': name, 'query': query }),
'Failed to add new saved search');
},
getSavedSearches: () =>
request('GET', 'GetSavedSearches', null, 'Failed to retrieve saved searches'),
deleteSavedSearch: function (name, query) {
return umbRequestHelper.resourcePromise(
$http.post(
umbRequestHelper.getApiUrl(
"logViewerApiBaseUrl",
"DeleteSavedSearch"), { 'name': name, 'query': query }),
'Failed to delete saved search');
},
postSavedSearch: (name, query) =>
request('POST', 'PostSavedSearch', { 'name': name, 'query': query }, 'Failed to add new saved search'),
getLogs: function (options) {
deleteSavedSearch: (name, query) =>
request('POST', 'DeleteSavedSearch', { 'name': name, 'query': query }, 'Failed to delete saved search'),
getLogs: options => {
var defaults = {
pageSize: 100,
@@ -83,7 +63,6 @@ function logViewerResource($q, $http, umbRequestHelper) {
//now copy back to the options we will use
options = defaults;
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
@@ -93,15 +72,8 @@ function logViewerResource($q, $http, umbRequestHelper) {
'Failed to retrieve common log messages');
},
canViewLogs: function (startDate, endDate) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"logViewerApiBaseUrl",
"GetCanViewLogs") + '?startDate='+startDate+ '&endDate='+ endDate ),
'Failed to retrieve state if logs can be viewed');
}
canViewLogs: (startDate, endDate) =>
request('GET', 'GetCanViewLogs', '?startDate=' + startDate + '&endDate=' + endDate, 'Failed to retrieve state if logs can be viewed')
};
}
@@ -1,4 +1,4 @@
/**
* @ngdoc service
* @name umbraco.services.contentEditingHelper
@@ -53,6 +53,12 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, editorSt
}
if (args.showNotifications === undefined) {
args.showNotifications = true;
}
// needed for infinite editing to create new items
if (args.create === undefined) {
if ($routeParams.create) {
args.create = true;
}
}
if (args.softRedirect === undefined) {
//when true, the url will change but it won't actually re-route
@@ -61,6 +67,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, editorSt
args.softRedirect = false;
}
var self = this;
//we will use the default one for content if not specified
@@ -68,7 +75,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, editorSt
if (formHelper.submitForm({ scope: args.scope, action: args.action })) {
return args.saveMethod(args.content, $routeParams.create, fileManager.getFiles(), args.showNotifications)
return args.saveMethod(args.content, args.create, fileManager.getFiles(), args.showNotifications)
.then(function (data) {
formHelper.resetForm({ scope: args.scope });
@@ -484,7 +491,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, editorSt
var savedVariants = [];
if (origContent.variants) {
isContent = true;
//it's contnet so assign the variants as they exist
//it's content so assign the variants as they exist
origVariants = origContent.variants;
savedVariants = savedContent.variants;
}
@@ -510,7 +517,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, editorSt
//special case for content, don't sync this variant if it wasn't tagged
//for saving in the first place
if (!origVariant.save) {
if (isContent && !origVariant.save) {
continue;
}
@@ -261,7 +261,7 @@ When building a custom infinite editor view you can use the same components as a
*/
unbindKeyboardShortcuts();
// set flag so we know when the editor is open in "infinie mode"
// set flag so we know when the editor is open in "infinite mode"
editor.infiniteMode = true;
editors.push(editor);
@@ -331,13 +331,17 @@ When building a custom infinite editor view you can use the same components as a
* @methodOf umbraco.services.editorService
*
* @description
* Opens a media editor in infinite editing, the submit callback returns the updated content item
* Opens a content editor in infinite editing, the submit callback returns the updated content item
* @param {Object} editor rendering options
* @param {String} editor.id The id of the content item
* @param {Boolean} editor.create Create new content item
* @param {Function} editor.submit Callback function when the publish and close button is clicked. Returns the editor model object
* @param {Function} editor.close Callback function when the close button is clicked.
*
* @param {String} editor.parentId If editor.create is true, provide parentId for the creation of the content item
* @param {String} editor.documentTypeAlias If editor.create is true, provide document type alias for the creation of the content item
* @param {Boolean} editor.allowSaveAndClose If editor is being used in infinite editing allows the editor to close when the save action is performed
* @param {Boolean} editor.allowPublishAndClose If editor is being used in infinite editing allows the editor to close when the publish action is performed
*
* @returns {Object} editor object
*/
function contentEditor(editor) {
@@ -112,7 +112,7 @@
@import "components/umb-editor-navigation-item.less";
@import "components/umb-editor-sub-views.less";
@import "components/editor/subheader/umb-editor-sub-header.less";
@import "components/umb-flatpickr.less";
@import "components/umb-date-time-picker.less";
@import "components/umb-grid-selector.less";
@import "components/umb-child-selector.less";
@import "components/umb-group-builder.less";
@@ -124,6 +124,7 @@
@import "components/umb-form-check.less";
@import "components/umb-locked-field.less";
@import "components/umb-tabs.less";
@import "components/umb-loader.less";
@import "components/umb-load-indicator.less";
@import "components/umb-breadcrumbs.less";
@import "components/umb-media-grid.less";
@@ -1,8 +1,12 @@
.umb-tour__loader {
background: @white;
z-index: @zindexTourModal;
.umb-loader-wrapper.umb-tour__loader {
margin: 0;
position: fixed;
height: 5px;
z-index: @zindexTourModal;
.umb-loader {
background-color: @white;
height: 5px;
}
}
.umb-tour__pulse {
@@ -74,8 +74,11 @@
}
.umb-editor-header__back {
color: @gray-6;
margin-bottom: 1px;
background: transparent;
border: 0;
color: @gray-6;
margin: 0 0 1px 0;
padding: 0;
transition: color 0.1s ease-in-out;
}
@@ -373,14 +376,3 @@ a.umb-variant-switcher__toggle {
margin-right: auto;
padding-right: 10px;
}
/* Confirm */
.umb-editor-confirm {
background-color: @white;
padding: 20px;
position: absolute;
left: 0;
bottom: 0;
z-index: 10;
box-shadow: 0 -3px 12px 0px rgba(0,0,0,0.16);
}
@@ -32,15 +32,32 @@
border-radius: 3px;
}
.umb-editor-sub-header.-umb-sticky-bar {
box-shadow: 0 6px 3px -3px rgba(0,0,0,.16);
[umb-sticky-bar] {
transition: box-shadow 240ms;
margin-top: 0;
margin-top: 0;
margin-bottom: 0;
top: calc(@appHeaderHeight + @editorHeaderHeight);
position:sticky;
z-index: 99;
.umb-editor--infinityMode & {
top: calc(@editorHeaderHeight);
&.umb-sticky-bar--active {
box-shadow: 0 6px 3px -3px rgba(0,0,0,.16);
}
}
.umb-sticky-sentinel {
position: absolute;
left: 0;
width: 100%;
pointer-events: none;
&.-top {
top:0px;
height:1px;
}
&.-bottom {
bottom:50px;
height:10px;
}
}
@@ -17,7 +17,7 @@
z-index: @zIndexEditor;
}
.umb-editor--infinityMode {
.umb-editor--infiniteMode {
transform: none;
will-change: transform;
transition: transform 400ms ease-in-out;
@@ -1,5 +1,5 @@
.umb-notifications {
z-index: 1000;
z-index: 1100;
position: absolute;
bottom: @editorFooterHeight;
left: 0;
@@ -39,17 +39,10 @@
// Loading Animation
// ------------------------
.l {
.umb-tree-item__loader {
width: 100%;
height: 2px;
overflow: hidden;
position: absolute;
left: 0;
bottom: -1px;
div {
.umb-loader;
}
margin: 0;
}
.umb-tree-item__label {
@@ -57,19 +50,20 @@
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1 0 auto;
flex: 1 1 auto;
}
}
// active is equivilant to selected, its the item that is begin affected by the actions performed in the right-click-dialog.
.umb-tree-item.active > .umb-tree-item__inner {
border-color: @ui-selected-border;
box-shadow: 0 0 2px 0 fade(@ui-selected-border, 80%);
color: @ui-selected-type;
a {
color: @ui-selected-type;
}
border-color: @ui-selected-border;
box-shadow: 0 0 2px 0 fade(@ui-selected-border, 80%);
&::before {
content: "";
position: absolute;
@@ -79,8 +73,10 @@
bottom: 0;
border: 2px solid fade(white, 80%);
}
&:hover {
color: @ui-selected-type-hover;
a {
color: @ui-selected-type-hover;
}
@@ -88,7 +84,6 @@
}
.umb-tree-item.current > .umb-tree-item__inner {
background: @ui-active;
color:@ui-active-type;
@@ -33,12 +33,6 @@
display: none;
}
}
//loader defaults
.umb-loader {
height: 10px;
margin: 10px 10px 10px 10px;
}
.search-subtitle {
color: @gray-7;
@@ -72,8 +66,7 @@ body.touch .umb-tree {
overflow: hidden;
display: flex;
flex-wrap: nowrap;
align-items: center;
align-items: center;
border:2px solid transparent;
color: @ui-option-type;
@@ -183,7 +176,6 @@ body.touch .umb-tree {
&:hover {
background: @btnBackgroundHighlight;
}
// NOTE - We're having to repeat ourselves here due to an .sr-only class appearing in umbraco/lib/font-awesome/css/font-awesome.min.css
&.sr-only--hoverable:hover,
&.sr-only--focusable:focus {
@@ -1,12 +1,14 @@
@boxUnit: 10px;
.umb-box {
background: @white;
border-radius: 3px;
margin-bottom: 20px;
margin-bottom: @boxUnit * 2;
box-shadow: 0 1px 1px 0 rgba(0,0,0,.16);
}
.umb-box-header {
padding: 10px 20px;
padding: @boxUnit @boxUnit * 2;
border-bottom: 1px solid @gray-9;
display: flex;
align-items: center;
@@ -27,5 +29,19 @@
}
.umb-box-content {
padding: 20px;
padding: @boxUnit * 2;
}
// allow side-by-side boxes
.umb-box-row {
margin-left:-@boxUnit;
margin-right:-@boxUnit;
display:flex;
justify-content: space-around;
.umb-box {
margin-left:@boxUnit;
margin-right:@boxUnit;
flex:1;
}
}
@@ -1,4 +1,4 @@
.flatpickr-calendar.flatpickr-calendar {
.flatpickr-calendar {
border-radius: @baseBorderRadius;
box-shadow: 0 5px 10px 0 rgba(0,0,0,0.16);
}
@@ -14,15 +14,18 @@
margin: 0 0 20px 0;
position: relative;
transition: height 0.8s;
.illustration {
width: 300px;
}
&.is-small {
height: 100px;
.illustration {
width: 200px;
}
}
&.drag-over {
border: 1px dashed @gray-1;
}
@@ -35,15 +38,19 @@
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
display: flex;
flex-direction: column;
}
// file select link
.file-select {
background: transparent;
border: 0;
padding: 0;
font-size: 15px;
color: @ui-action-discreet-type;
cursor: pointer;
margin-top: 10px;
&:hover {
@@ -0,0 +1,42 @@
// Loading Animation
// ------------------------
.umb-loader {
background-color: @blue;
margin-top: 0;
margin-left: -100%;
animation-name: bounce_loadingProgressG;
animation-duration: 1s;
animation-iteration-count: infinite;
animation-timing-function: linear;
width: 100%;
height: 2px;
}
@keyframes bounce_loadingProgressG {
0% {
margin-left: -100%;
}
100% {
margin-left: 100%;
}
}
.umb-loader-wrapper {
position: absolute;
right: 0;
left: 0;
margin: 10px 0;
overflow: hidden;
}
.umb-loader-wrapper.-top {
top: 0;
bottom: auto;
}
.umb-loader-wrapper.-bottom {
top: auto;
bottom: 0;
}
@@ -264,12 +264,16 @@
flex-flow: row wrap;
}
a.umb-package-details__back-link {
.umb-package-details__back-action {
font-weight: bold;
color: @black;
padding: 0;
border: 0;
background-color: transparent;
}
.umb-package-details__back-link:hover {
.umb-package-details__back-action:focus,
.umb-package-details__back-action:hover {
color: @gray-4;
text-decoration: none;
}
@@ -295,7 +295,11 @@ input.umb-table__input {
.umb-table__row-expand {
font-size: 12px;
text-decoration: none;
color: @black;
color: @gray-4;
&:hover {
color: @black;
}
}
.umb-table__row-expand--hidden {
@@ -13,6 +13,9 @@
@import "../../lib/bootstrap/less/thumbnails.less";
@import "../../lib/bootstrap/less/media.less";
// Umbraco Components
@import "components/umb-loader.less";
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
@@ -165,45 +168,17 @@ input.ng-dirty.ng-invalid{border-color: #b94a48; color: #b94a48;}
opacity:1;
}
.umb-installer-loader {
margin: 0;
width: 0;
z-index: 777;
.umb-loader{
background-color: @white;
margin-top:0;
margin-left:-100%;
animation-name:bounce_loadingProgressG;
animation-duration:1s;
animation-iteration-count:infinite;
animation-timing-function:linear;
width:100%;
height: 5px;
}
@keyframes bounce_loadingProgressG{
0%{
margin-left:-100%;
}
100%{
margin-left:100%;
.umb-loader {
background-color: @white;
height: 5px;
}
}
//loader defaults
.umb-loader-container, .umb-loader-done{
height: 3px;
position: absolute;
bottom: 0;
left: 0;
overflow: hidden;
width: 0%;
z-index: 777;
}
.umb-loader-done{
right: 0%;
background: @white;
}
.permissions-report {
overflow:auto;
height:320px;
@@ -486,42 +486,6 @@ table thead a {
color:@green;
}
// Loading Animation
// ------------------------
.umb-loader{
background-color: @blue;
margin-top:0;
margin-left:-100%;
animation-name:bounce_loadingProgressG;
animation-duration:1s;
animation-iteration-count:infinite;
animation-timing-function:linear;
width:100%;
height:2px;
}
@keyframes bounce_loadingProgressG{
0%{
margin-left:-100%;
}
100%{
margin-left:100%;
}
}
.umb-loader-wrapper {
position: absolute;
right: 0;
left: 0;
margin: 10px 0;
overflow: hidden;
}
.umb-loader-wrapper.-bottom {
bottom: 0;
}
// Helpers
.strong {
@@ -592,13 +556,3 @@ input[type=checkbox]:checked + .input-label--small {
background-color: @green-l3;
text-decoration: none;
}
.visuallyhidden{
position: absolute !important;
clip: rect(1px, 1px, 1px, 1px);
padding:0 !important;
border:0 !important;
height: 1px !important;
width: 1px !important;
overflow: hidden;
}
@@ -165,8 +165,6 @@
.sp-replacer {
display: inline-flex;
margin-right: 18px;
border: solid 1px @gray-8;
border-radius: 3px;
}
label {
@@ -10,7 +10,7 @@
*/
function MainController($scope, $location, appState, treeService, notificationsService,
userService, historyService, updateChecker, navigationService, eventsService,
tmhDynamicLocale, localStorageService, editorService, overlayService) {
tmhDynamicLocale, localStorageService, editorService, overlayService, assetsService, tinyMceAssets) {
//the null is important because we do an explicit bool check on this in the view
$scope.authenticated = null;
@@ -21,7 +21,13 @@ function MainController($scope, $location, appState, treeService, notificationsS
$scope.search = {};
$scope.login = {};
$scope.tabbingActive = false;
// Load TinyMCE assets ahead of time in the background for the user
// To help with first load of the RTE
tinyMceAssets.forEach(function (tinyJsAsset) {
assetsService.loadJs(tinyJsAsset, $scope);
});
// There are a number of ways to detect when a focus state should be shown when using the tab key and this seems to be the simplest solution.
// For more information about this approach, see https://hackernoon.com/removing-that-ugly-focus-ring-and-keeping-it-too-6c8727fefcd2
function handleFirstTab(evt) {
@@ -1,7 +1,7 @@
(function () {
"use strict";
function CompositionsController($scope, $location, $filter) {
function CompositionsController($scope, $location, $filter, overlayService) {
var vm = this;
var oldModel = null;
@@ -56,19 +56,35 @@
if ($scope.model && $scope.model.submit) {
// check if any compositions has been removed
vm.compositionRemoved = false;
var compositionRemoved = false;
for (var i = 0; oldModel.compositeContentTypes.length > i; i++) {
var oldComposition = oldModel.compositeContentTypes[i];
if (_.contains($scope.model.compositeContentTypes, oldComposition) === false) {
vm.compositionRemoved = true;
compositionRemoved = true;
}
}
/* submit the form if there havne't been removed any composition
or the confirm checkbox has been checked */
if (!vm.compositionRemoved || vm.allowSubmit) {
$scope.model.submit($scope.model);
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);
return;
}
$scope.model.submit($scope.model);
}
}
@@ -92,16 +92,6 @@
</umb-box-content>
</umb-box>
<div ng-if="vm.compositionRemoved" class="umb-editor-confirm">
<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>
<label class="checkbox no-indent">
<input type="checkbox" ng-model="vm.allowSubmit" />
<strong>I know what I'm doing</strong>
</label>
</div>
</umb-editor-container>
<umb-editor-footer>
@@ -0,0 +1,6 @@
<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>
@@ -59,10 +59,10 @@ angular.module("umbraco").controller("Umbraco.Editors.LinkPickerController",
if (dialogOptions.currentTarget) {
// clone the current target so we don't accidentally update the caller's model while manipulating $scope.model.target
$scope.model.target = angular.copy(dialogOptions.currentTarget);
//if we have a node ID, we fetch the current node to build the form data
// if we have a node ID, we fetch the current node to build the form data
if ($scope.model.target.id || $scope.model.target.udi) {
//will be either a udi or an int
// will be either a udi or an int
var id = $scope.model.target.udi ? $scope.model.target.udi : $scope.model.target.id;
if ($scope.model.target.udi) {
@@ -93,7 +93,7 @@ angular.module("umbraco").controller("Umbraco.Editors.LinkPickerController",
});
}
} else if ($scope.model.target.url.length) {
} else if ($scope.model.target.url && $scope.model.target.url.length) {
// a url but no id/udi indicates an external link - trim the url to remove the anchor/qs
// only do the substring if there's a # or a ?
var indexOfAnchor = $scope.model.target.url.search(/(#|\?)/);
@@ -268,7 +268,7 @@ angular.module("umbraco")
// also make sure the node is not trashed
if (nodePath.indexOf($scope.startNodeId.toString()) !== -1 && node.trashed === false) {
$scope.gotoFolder({ id: $scope.lastOpenedNode, name: "Media", icon: "icon-folder" });
$scope.gotoFolder({ id: $scope.lastOpenedNode, name: "Media", icon: "icon-folder", path: node.path });
return true;
} else {
$scope.gotoFolder({ id: $scope.startNodeId, name: "Media", icon: "icon-folder" });
@@ -109,10 +109,10 @@
<input type="number" ng-switch-when="int" style="width:90px; margin-bottom: 0;" ng-model="filter.constraintValue" ng-change="vm.changeConstraintValue()" />
<span ng-switch-when="datetime">
<umb-flatpickr
<umb-date-time-picker
options="vm.datePickerConfig"
on-change="vm.datePickerChange(dateStr, filter)">
</umb-flatpickr>
</umb-date-time-picker>
</span>
</span>
@@ -18,11 +18,11 @@
</p>
<div class="control-group" ng-class="{error: vm.setPasswordForm.password.$invalid}">
<label>
<label for="umb-password">
<localize key="user_newPassword">New password</localize>
<small style="font-size: 13px;">{{vm.invitedUserPasswordModel.passwordPolicyText}}</small>
</label>
<input type="password" ng-model="vm.invitedUserPasswordModel.password" name="password" class="-full-width-input" umb-auto-focus required val-server-field="value" ng-minlength="{{vm.invitedUserPasswordModel.passwordPolicies.minPasswordLength}}" />
<input type="password" ng-model="vm.invitedUserPasswordModel.password" name="password" id="umb-password" class="-full-width-input" umb-auto-focus required val-server-field="value" ng-minlength="{{vm.invitedUserPasswordModel.passwordPolicies.minPasswordLength}}" />
<span ng-messages="inviteUserPasswordForm.password.$error" show-validation-on-submit >
<span class="help-inline" ng-message="required"><localize key="user_passwordIsBlank">Your new password cannot be blank!</localize></span>
<span class="help-inline" ng-message="minlength">Minimum {{vm.invitedUserPasswordModel.passwordPolicies.minPasswordLength}} characters</span>
@@ -31,8 +31,8 @@
</div>
<div class="control-group" ng-class="{error: vm.setPasswordForm.confirmPassword.$invalid}">
<label><localize key="user_confirmNewPassword">Confirm new password</localize></label>
<input type="password" ng-model="vm.invitedUserPasswordModel.confirmPassword" name="confirmPassword" class="-full-width-input" required val-compare="password" />
<label for="umb-confirmPassword"><localize key="user_confirmNewPassword">Confirm new password</localize></label>
<input type="password" ng-model="vm.invitedUserPasswordModel.confirmPassword" name="confirmPassword" id="umb-confirmPassword" class="-full-width-input" required val-compare="password" />
<span ng-messages="inviteUserPasswordForm.confirmPassword.$error" show-validation-on-submit >
<span class="help-inline" ng-message="required"><localize key="general_required">Required</localize></span>
<span class="help-inline" ng-message="valCompare"><localize key="user_passwordMismatch">The confirmed password doesn't match the new password!</localize></span>
@@ -152,13 +152,13 @@
<p ng-message="auth" class="text-error" role="alert">{{vm.errorMsg}}</p>
</div>
<div class="control-group" ng-class="{error: vm.loginForm.username.$invalid}">
<label>{{vm.labels.usernameLabel}}</label>
<input type="text" ng-model="vm.login" name="username" class="-full-width-input" placeholder="{{vm.labels.usernamePlaceholder}}" focus-when="{{vm.view === 'login'}}" />
<label for="umb-username">{{vm.labels.usernameLabel}}</label>
<input type="text" ng-model="vm.login" name="username" id="umb-username" class="-full-width-input" placeholder="{{vm.labels.usernamePlaceholder}}" focus-when="{{vm.view === 'login'}}" />
</div>
<div class="control-group" ng-class="{error: vm.loginForm.password.$invalid}">
<label><localize key="general_password">Password</localize></label>
<input type="password" ng-model="vm.password" name="password" class="-full-width-input" localize="placeholder" placeholder="@placeholders_password" />
<label for="umb-password"><localize key="general_password">Password</localize></label>
<input type="password" ng-model="vm.password" name="password" id="umb-password" class="-full-width-input" localize="placeholder" placeholder="@placeholders_password" />
<div class="password-toggle">
<a href="#" prevent-default ng-click="vm.togglePassword()">
<span class="password-text show"><localize key="login_showPassword">Show password</localize></span>
@@ -189,8 +189,8 @@
<form method="POST" name="vm.requestPasswordResetForm" ng-submit="vm.requestPasswordResetSubmit(email)">
<div class="control-group" ng-class="{error: requestPasswordResetForm.email.$invalid}">
<label><localize key="general_email">Email</localize></label>
<input type="email" val-email ng-model="email" name="email" class="-full-width-input" localize="placeholder" placeholder="@placeholders_email" focus-when="{{vm.view === 'request-password-reset'}}" />
<label for="umb-email"><localize key="general_email">Email</localize></label>
<input type="email" val-email ng-model="email" name="email" id="umb-email" class="-full-width-input" localize="placeholder" placeholder="@placeholders_email" focus-when="{{vm.view === 'request-password-reset'}}" />
</div>
<div class="control-group" ng-show="requestPasswordResetForm.$invalid">
@@ -220,13 +220,13 @@
<form method="POST" name="vm.setPasswordForm" ng-submit="vm.setPasswordSubmit(vm.password, vm.confirmPassword)">
<div ng-hide="vm.resetComplete" class="control-group" ng-class="{error: vm.setPasswordForm.password.$invalid}">
<label><localize key="user_newPassword">New password</localize></label>
<input type="password" ng-model="vm.password" name="password" class="-full-width-input" localize="placeholder" placeholder="@placeholders_password" focus-when="{{vm.view === 'set-password'}}" />
<label for="umb-password"><localize key="user_newPassword">New password</localize></label>
<input type="password" ng-model="vm.password" name="password" id="umb-password" class="-full-width-input" localize="placeholder" placeholder="@placeholders_password" focus-when="{{vm.view === 'set-password'}}" />
</div>
<div ng-hide="vm.resetComplete" class="control-group" ng-class="{error: vm.setPasswordForm.confirmPassword.$invalid}">
<label><localize key="user_confirmNewPassword">Confirm new password</localize></label>
<input type="password" ng-model="vm.confirmPassword" name="confirmPassword" class="-full-width-input" localize="placeholder" placeholder="@placeholders_confirmPassword" />
<label for="umb-confirmPassword"><localize key="user_confirmNewPassword">Confirm new password</localize></label>
<input type="password" ng-model="vm.confirmPassword" name="confirmPassword" id="umb-confirmPassword" class="-full-width-input" localize="placeholder" placeholder="@placeholders_confirmPassword" />
</div>
<div ng-hide="vm.resetComplete" class="control-group" ng-show="vm.setPasswordForm.$invalid">
@@ -1,25 +1,26 @@
<div class="umb-tour">
<div class="umb-loader umb-tour__loader" ng-if="loadingStep"></div>
<umb-loader class="umb-tour__loader" ng-if="loadingStep"></umb-loader>
<div class="umb-tour__pulse"></div>
<div class="umb-tour__popover shadow-depth-2" ng-class="{'umb-tour__popover--l': model.currentStep.type === 'intro' || model.currentStepIndex === model.steps.length}">
<div ng-if="!configuredView && !elementNotFound">
<!-- Regular steps -->
<umb-tour-step ng-if="model.currentStepIndex < model.steps.length" on-close="model.endTour()">
<umb-tour-step-header
title="model.currentStep.title">
</umb-tour-step-header>
<umb-tour-step-content
content="model.currentStep.content">
</umb-tour-step-content>
<umb-tour-step-footer>
<div class="flex justify-between items-center">
<div>
@@ -27,9 +28,11 @@
current-step="model.currentStepIndex + 1"
total-steps="model.steps.length">
</umb-tour-step-counter>
<div ng-if="model.allowDisable && model.currentStep.type === 'intro'" style="font-size: 13px;"><a href="" class="underline" ng-click="model.disableTour()">Don't show this tour again</a></div>
<div ng-if="model.allowDisable && model.currentStep.type === 'intro'">
<button type="button" class="underline" ng-click="model.disableTour()" style="font-size: 13px; background: transparent; border: none; padding: 0;" prevent-default>Don't show this tour again</button>
</div>
</div>
<div ng-if="model.currentStep.type !== 'intro'">
<umb-button size="xs" ng-if="!model.currentStep.event" button-style="action" type="button" action="model.nextStep()" label="Next"></umb-button>
</div>
@@ -40,7 +43,7 @@
</div>
</umb-tour-step-footer>
</umb-tour-step>
<!-- Outro step -->
@@ -64,7 +67,7 @@
<!-- Custom step view -->
<div ng-if="configuredView && !loadingStep && !elementNotFound" ng-include="configuredView"></div>
<!-- Dom element not found error -->
<div ng-if="elementNotFound && !loadingStep">
<umb-tour-step class="tc">
@@ -83,4 +86,4 @@
</div>
</div>
</div>
@@ -2,9 +2,13 @@
<div ng-if="hideClose !== true">
<button class="icon-wrong umb-tour-step__close" ng-click="close()"></button>
<button class="icon-wrong umb-tour-step__close" ng-click="close()">
<span class="sr-only">
<localize key="general_close">Close</localize>
</span>
</button>
</div>
<div ng-transclude></div>
</div>
</div>
@@ -1,6 +1,5 @@
<div
class="umb-editor-sub-header umb-editor-sub-header--{{appearance}}"
umb-sticky-bar
scrollable-container=".umb-editor-container"
ng-transclude>
</div>
@@ -3,32 +3,39 @@
<div class="flex items-center" style="height: 100%;">
<div ng-if="showBackButton === true && splitViewOpen !== true" style="margin-right: 15px;">
<a class="umb-editor-header__back" href="#" ng-click="goBack()" prevent-default>
<button type="button" class="umb-editor-header__back" ng-click="goBack()" prevent-default>
<i class="fa fa-arrow-left" aria-hidden="true"></i>
</a>
<span class="sr-only"><localize key="visuallyHiddenTexts_goBack">Go back</localize></span>
</button>
</div>
<div class="flex items-center" style="flex: 1;">
<div id="nameField" class="umb-editor-header__name-and-description" style="flex: 1 1 auto;">
<div>
<p tabindex="0" class="sr-only">
{{a11yMessage}}
</p>
</div>
<div class="umb-editor-header__name-wrapper">
<label for="headerName" class="sr-only">{{a11yName}}</label>
<ng-form name="headerNameForm">
<input
data-element="editor-name-field"
type="text"
class="umb-editor-header__name-input"
localize="placeholder"
placeholder="@placeholders_entername"
name="headerName"
ng-model="name"
ng-class="{'name-is-empty': $parent.name===null || $parent.name===''}"
ng-disabled="nameDisabled"
umb-auto-focus
val-server-field="{{serverValidationNameField}}"
required
aria-required="true"
aria-invalid="{{contentForm.headerNameForm.headerName.$invalid ? true : false}}"
autocomplete="off" maxlength="255" />
<input data-element="editor-name-field"
type="text"
class="umb-editor-header__name-input"
localize="placeholder"
placeholder="@placeholders_entername"
name="headerName"
id="headerName"
ng-model="name"
ng-class="{'name-is-empty': $parent.name===null || $parent.name===''}"
ng-disabled="nameDisabled"
umb-auto-focus
val-server-field="{{serverValidationNameField}}"
required
aria-required="true"
aria-invalid="{{contentForm.headerNameForm.headerName.$invalid ? true : false}}"
autocomplete="off" maxlength="255" />
</ng-form>
<a ng-if="content.variants.length > 0 && hideChangeVariant !== true" class="umb-variant-switcher__toggle" href="" ng-click="vm.dropdownOpen = !vm.dropdownOpen" ng-class="{'--error': vm.errorsOnOtherVariants}">
@@ -3,9 +3,10 @@
<div class="flex items-center" style="height: 100%;">
<div ng-if="showBackButton === true && splitViewOpen !== true" style="margin-right: 15px;">
<a class="umb-editor-header__back" href="#" ng-click="goBack()" prevent-default>
<button type="button" class="umb-editor-header__back" ng-click="goBack()" prevent-default>
<i class="fa fa-arrow-left" aria-hidden="true"></i>
</a>
<span class="sr-only"><localize key="visuallyHiddenTexts_goBack">Go back</localize></span>
</button>
</div>
<div class="flex items-center" style="flex: 1;">
@@ -5,7 +5,7 @@
ng-class="{'umb-editor--small': model.size === 'small',
'umb-editor--animating': model.animating,
'--notInFront': model.inFront !== true,
'umb-editor--infinityMode': model.infinityMode,
'umb-editor--infiniteMode': model.infiniteMode,
'moveRight': model.moveRight,
'umb-editor--n0': model.styleIndex === 0,
'umb-editor--n1': model.styleIndex === 1,
@@ -1,3 +1,4 @@
<div class="umb-rte"
id="{{textAreaHtmlId}}">
<div>
<umb-load-indicator ng-if="isLoading"></umb-load-indicator>
<div class="umb-rte" id="{{textAreaHtmlId}}" ng-style="{ visibility : isLoading ? 'hidden' : 'visible' }"></div>
</div>
@@ -12,9 +12,10 @@
<ul ng-if="nodeUrl" class="nav nav-stacked" style="margin-bottom: 0;">
<li>
<a href="{{nodeUrl}}" target="_blank">
<i class="icon icon-out"></i>
<span>{{nodeFileName}}</span>
<a ng-attr-href="{{node.extension !== 'svg' ? nodeUrl : undefined}}" ng-click="node.extension === 'svg' && openSVG()" target="_blank">
<i class="icon icon-out"></i>
<span>{{nodeFileName}}</span>
</a>
</li>
</ul>
@@ -15,7 +15,8 @@
<!-- NOTE: These are the 'option' elipses -->
<button data-element="tree-item-options" class="umb-options btn-reset sr-only sr-only--focusable sr-only--hoverable" ng-click="options(node, $event)" ng-if="::node.menuUrl"><i></i><i></i><i></i></button>
<div ng-show="node.loading" class="l"><div></div></div>
<umb-loader ng-show="node.loading" position="bottom" class="umb-tree-item__loader"></umb-loader>
</div>
<ul ng-class="{collapsed: !node.expanded}">
@@ -14,7 +14,8 @@
icon="icon-merge"
action="openCompositionsDialog()"
size="xs"
add-ellipsis="true">
add-ellipsis="true"
state="compositionsButtonState">
</umb-button>
<umb-button
@@ -0,0 +1,3 @@
<div class="umb-loader-wrapper" ng-class="{ '-top': position === 'top', '-bottom': position === 'bottom' }">
<div class="umb-loader"></div>
</div>
@@ -60,7 +60,7 @@
</div>
<!-- Items -->
<div class="umb-table-row"
<div class="umb-table-row cursor-pointer"
ng-repeat="child in miniListView.children"
ng-click="selectNode(child)"
ng-class="{'-selected':child.selected, 'not-allowed':!child.allowed}">
@@ -17,13 +17,17 @@
<div class="content" >
<p>
<localize key="media_dragAndDropYourFilesIntoTheArea">Drag and drop your file(s) into the area</localize>
</p>
<!-- Drag and drop illustration -->
<img class="illustration" src="assets/img/uploader/upload-illustration.svg" alt="" draggable="false" />
<!-- Select files -->
<div
<button
type="button"
prevent-default
data-element="button-uploadMedia"
class="file-select"
ngf-select
@@ -32,8 +36,8 @@
ngf-multiple="true"
ngf-pattern="{{ accept }}"
ngf-max-size="{{ maxFileSize }}">
- <localize key="media_orClickHereToUpload">or click here to choose files</localize>
</div>
-&nbsp;<localize key="media_orClickHereToUpload">or click here to choose files</localize>
</button>
</div>
</div>
@@ -104,7 +108,7 @@
ng-if="mediatypepickerOverlay.show"
model="mediatypepickerOverlay"
view="mediatypepickerOverlay.view"
position="right">
position="right">
</umb-overlay>
</div>
@@ -1,68 +1,69 @@
<div>
<div class="alert alert-success text-center" ng-hide="!passwordValues.generatedPassword">
<div class="alert alert-success text-center" ng-hide="!vm.passwordValues.generatedPassword">
<small>Password has been reset to:</small>
<br />
<strong>{{passwordValues.generatedPassword}}</strong>
<strong>{{vm.passwordValues.generatedPassword}}</strong>
</div>
<div ng-switch="changing">
<div ng-switch="vm.changing">
<div ng-switch-when="false">
<a href="" ng-click="doChange()" class="btn btn-small">
<a href="" ng-click="vm.doChange()" class="btn btn-small">
<localize key="general_changePassword">Change password</localize>
</a>
</div>
<div ng-switch-when="true">
<ng-form name="passwordForm">
<umb-control-group alias="resetPassword" label="@user_resetPassword" ng-show="config.enableReset">
<input type="checkbox" ng-model="passwordValues.reset"
<ng-form name="vm.passwordForm">
<umb-control-group alias="resetPassword" label="@user_resetPassword" ng-show="vm.config.enableReset">
<input type="checkbox" ng-model="vm.passwordValues.reset"
id="Checkbox1"
name="resetPassword"
val-server-field="resetPassword"
no-dirty-check
ng-change="showReset = !showReset" />
<span ng-messages="passwordForm.resetPassword.$error" show-validation-on-submit >
<span class="help-inline" ng-message="valServerField">{{passwordForm.resetPassword.errorMsg}}</span>
ng-change="vm.showReset = !vm.showReset" />
<span ng-messages="vm.passwordForm.resetPassword.$error" show-validation-on-submit>
<span class="help-inline" ng-message="valServerField">{{vm.passwordForm.resetPassword.errorMsg}}</span>
</span>
</umb-control-group>
</umb-control-group>
<!-- we need to show the old pass field when the provider cannot retrieve the password -->
<umb-control-group alias="oldPassword" label="@user_oldPassword" ng-if="showOldPass()" required="true">
<input type="password" name="oldPassword" ng-model="passwordValues.oldPassword"
<umb-control-group alias="oldPassword" label="@user_oldPassword" ng-if="vm.showOldPass()" required="true">
<input type="password" name="oldPassword" ng-model="vm.passwordValues.oldPassword"
class="input-block-level umb-textstring textstring"
required
val-server-field="oldPassword"
no-dirty-check />
<span ng-messages="passwordForm.oldPassword.$error" show-validation-on-submit >
<span ng-messages="vm.passwordForm.oldPassword.$error" show-validation-on-submit>
<span class="help-inline" ng-message="required">Required</span>
<span class="help-inline" ng-message="valServerField">{{passwordForm.oldPassword.errorMsg}}</span>
<span class="help-inline" ng-message="valServerField">{{vm.passwordForm.oldPassword.errorMsg}}</span>
</span>
</umb-control-group>
<umb-control-group alias="password" label="@user_newPassword" ng-if="!showReset" required="true">
<input type="password" name="password" ng-model="passwordValues.newPassword"
<umb-control-group alias="password" label="@user_newPassword" ng-if="!vm.showReset" required="true">
<input type="password" name="password" ng-model="vm.passwordValues.newPassword"
class="input-block-level umb-textstring textstring"
required
val-server-field="password"
ng-minlength="{{config.minPasswordLength}}"
ng-minlength="{{vm.config.minPasswordLength}}"
no-dirty-check />
<span ng-messages="passwordForm.password.$error" show-validation-on-submit >
<span ng-messages="vm.passwordForm.password.$error" show-validation-on-submit>
<span class="help-inline" ng-message="required">Required</span>
<span class="help-inline" ng-message="minlength">Minimum {{config.minPasswordLength}} characters</span>
<span class="help-inline" ng-message="valServerField">{{passwordForm.password.errorMsg}}</span>
<span class="help-inline" ng-message="minlength">Minimum {{vm.config.minPasswordLength}} characters</span>
<span class="help-inline" ng-message="valServerField">{{vm.passwordForm.password.errorMsg}}</span>
</span>
</umb-control-group>
<umb-control-group alias="confirmpassword" label="@user_confirmNewPassword" ng-if="!showReset" required="true">
<input type="password" name="confirmpassword" ng-model="passwordValues.confirm"
<umb-control-group alias="confirmpassword" label="@user_confirmNewPassword" ng-if="!vm.showReset" required="true">
<input type="password" name="confirmpassword" ng-model="vm.passwordValues.confirm"
class="input-block-level umb-textstring textstring"
val-compare="password"
no-dirty-check />
<span ng-messages="passwordForm.confirmpassword.$error" show-validation-on-submit >
<span ng-messages="vm.passwordForm.confirmpassword.$error" show-validation-on-submit>
<span class="help-inline" ng-message="valCompare"><localize key="user_passwordMismatch">The confirmed password doesn't match the new password!</localize></span>
</span>
</umb-control-group>
<a href="" ng-click="cancelChange()" ng-show="showCancelBtn()" class="btn btn-small">
<a href="" ng-click="vm.cancelChange()" ng-show="vm.showCancelBtn()" class="btn btn-small">
<localize key="general_cancel">Cancel</localize>
</a>
@@ -51,7 +51,10 @@ function contentCreateController($scope,
.search("create", "true")
/* when we create a new node we want to make sure it uses the same
language as what is selected in the tree */
.search("cculture", mainCulture);
.search("cculture", mainCulture)
/* when we create a new node we must make sure that any previously
used blueprint is reset */
.search("blueprintId", null);
close();
}
@@ -58,7 +58,7 @@ function ContentDeleteController($scope, $timeout, contentResource, treeService,
$location.path(location);
}
navigationService.hideMenu();
$scope.success = true;
}, function(err) {
toggleDeleting(false);
@@ -74,7 +74,11 @@ function ContentDeleteController($scope, $timeout, contentResource, treeService,
$scope.cancel = function() {
toggleDeleting(false);
navigationService.hideDialog();
$scope.close();
};
$scope.close = function () {
navigationService.hideDialog();
};
}
@@ -13,6 +13,9 @@ function ContentEditController($scope, $routeParams, contentResource) {
function scaffoldEmpty() {
return contentResource.getScaffold($routeParams.id, $routeParams.doctype);
}
function scaffoldInfiniteEmpty() {
return contentResource.getScaffold($scope.model.parentId, $scope.model.documentTypeAlias);
}
function scaffoldBlueprint() {
return contentResource.getBlueprintScaffold($routeParams.id, $routeParams.blueprintId);
}
@@ -20,11 +23,11 @@ function ContentEditController($scope, $routeParams, contentResource) {
$scope.contentId = infiniteMode ? $scope.model.id : $routeParams.id;
$scope.saveMethod = contentResource.save;
$scope.getMethod = contentResource.getById;
$scope.getScaffoldMethod = $routeParams.blueprintId ? scaffoldBlueprint : scaffoldEmpty;
$scope.getScaffoldMethod = $routeParams.blueprintId ? scaffoldBlueprint : infiniteMode ? scaffoldInfiniteEmpty : scaffoldEmpty;
$scope.page = $routeParams.page;
$scope.isNew = infiniteMode ? $scope.model.create : $routeParams.create;
//load the default culture selected in the main tree if any
$scope.culture = $routeParams.cculture ? $routeParams.cculture : ($routeParams.mculture === "true");
$scope.culture = $routeParams.cculture ? $routeParams.cculture : $routeParams.mculture;
//Bind to $routeUpdate which will execute anytime a location changes but the route is not triggered.
//This is so we can listen to changes on the cculture parameter since that will not cause a route change

Some files were not shown because too many files have changed in this diff Show More