Merge branch '1.10.x' into issue/8773

# Conflicts:
#	.github/workflows/compile.yml
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/Lib/console-shim.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/Lib/jstree.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-admin-common.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-admin-settings.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-autorefresh.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-edit-asset-video.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-edit-asset.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-edit-cloudvideopart-direct.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-edit-cloudvideopart-proxied.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-edit-cloudvideopart.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-metadata-cloudvideopart.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-videoplayer-data.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-videoplayer-injectors-alt.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-videoplayer-injectors-dash.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-videoplayer-injectors-html5.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-videoplayer-injectors-smp.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-videoplayer-injectors.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Scripts/cloudmedia-videoplayer-main.js
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Styles/cloudmedia-admin-asset.css
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Styles/cloudmedia-admin-selecttask.css
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Styles/cloudmedia-admin-settings.css
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Styles/cloudmedia-edit-assets.css
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Styles/cloudmedia-edit-cloudvideopart.css
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Styles/cloudmedia-edit-jobs.css
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Styles/cloudmedia-progress.css
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Styles/cloudmedia-tabs.css
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Styles/cloudmedia-videoplayer.css
#	src/Orchard.Web/Modules/Orchard.Azure.MediaServices/Styles/menu.cloudmedia-mediaproviders.css
#	src/Orchard.Web/Modules/Orchard.DynamicForms/Scripts/LayoutEditor.js
#	src/Orchard.Web/Modules/Orchard.DynamicForms/Scripts/Lib.js
#	src/Orchard.Web/Modules/Orchard.DynamicForms/Scripts/Lib.min.js
#	src/Orchard.Web/Modules/Orchard.DynamicForms/Styles/DynamicForms-Admin.css
#	src/Orchard.Web/Modules/Orchard.DynamicForms/Styles/DynamicForms.css
#	src/Orchard.Web/Modules/Orchard.DynamicForms/packages.config
#	src/Orchard.Web/Modules/Orchard.Layouts/Scripts/LayoutEditor.js
#	src/Orchard.Web/Modules/Orchard.Layouts/Scripts/LayoutEditor.min.js
#	src/Orchard.Web/Modules/Orchard.Layouts/Scripts/Models.js
#	src/Orchard.Web/Modules/Orchard.Layouts/Styles/LayoutEditor.css
#	src/Orchard.Web/Modules/Orchard.Layouts/Styles/LayoutEditor.min.css
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-af.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-am.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ar-DZ.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ar-EG.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ar.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-az.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-bg.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-bs.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ca.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-cs.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-da.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-de-CH.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-de.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-el.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-en-AU.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-en-GB.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-en-NZ.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-eo.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-es-AR.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-es-PE.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-es.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-et.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-eu.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-fa.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-fi.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-fo.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-fr-CH.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-fr.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-gl.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-gu.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-he.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-hi-IN.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-hr.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-hu.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-hy.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-id.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-is.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-it.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ja.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ka.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-km.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ko.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-lt.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-lv.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-me-ME.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-me.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-mk.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ml.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ms.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-mt.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-nl-BE.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-nl.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-no.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-pl.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-pt-BR.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-rm.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ro.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ru.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-sk.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-sl.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-sq.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-sr-SR.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-sr.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-sv.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ta.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-th.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-tr.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-tt.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-uk.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-ur.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-vi.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-zh-CN.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-zh-HK.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars-zh-TW.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.all.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.coptic.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.ethiopian-am.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.ethiopian.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.hebrew-he.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.hebrew.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.islamic-ar.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.islamic-fa.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.islamic.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.julian.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.lang.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.mayan.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.min.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.nepali-ne.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.nepali.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.persian-fa.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.persian.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-af.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-am.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ar-DZ.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ar-EG.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ar.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-az.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-bg.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-bs.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ca.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-cs.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-da.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-de-CH.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-de.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-el.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-en-AU.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-en-GB.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-en-NZ.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-eo.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-es-AR.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-es-PE.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-es.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-et.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-eu.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-fa.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-fi.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-fo.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-fr-CH.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-fr.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-gl.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-gu.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-he.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-hi-IN.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-hr.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-hu.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-hy.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-id.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-is.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-it.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ja.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ka.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-km.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ko.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-lt.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-lv.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-me-ME.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-me.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-mk.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ml.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ms.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-mt.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-nl-BE.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-nl.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-no.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-pl.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-pt-BR.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-rm.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ro.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ru.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-sk.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-sl.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-sq.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-sr-SR.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-sr.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-sv.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ta.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-th.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-tr.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-tt.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-uk.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-ur.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-vi.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-zh-CN.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-zh-HK.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker-zh-TW.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker.ext.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker.full.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.picker.lang.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.plus.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.taiwan-zh-TW.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.taiwan.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.thai-th.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.thai.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.ummalqura-ar.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.ummalqura.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/Calendars/jquery.calendars.validation.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/TimeEntry/jquery.timeentry.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/angular-resource.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/angular-sanitize.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/angular-sortable.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/angular.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/bootstrap.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/jquery.blockui.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/jquery.colorbox.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/jquery.cookie.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/jquery.fileupload-full.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/jquery.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/jquery.plugin.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/jquery.utils.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/knockout.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/moment.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/underscore.js
#	src/Orchard.Web/Modules/Orchard.Resources/Scripts/uri.js
#	src/Orchard.Web/Modules/Orchard.Resources/Styles/Calendars/jquery.calendars.picker.full.css
#	src/Orchard.Web/Modules/Orchard.Resources/Styles/TimeEntry/jquery.timeentry.css
#	src/Orchard.Web/Modules/Orchard.Resources/Styles/bootstrap.css
#	src/Orchard.Web/Modules/Orchard.Resources/Styles/bootstrap.min.css
#	src/Orchard.Web/Modules/Orchard.Resources/Styles/font-awesome.css
#	src/Orchard.Web/Modules/Orchard.Resources/Styles/font-awesome.min.css
#	src/Orchard.Web/Modules/Orchard.Resources/Styles/jquery-datetime-editor.css
#	src/Orchard.Web/Modules/Orchard.Resources/Styles/jquery-ui.css
#	src/Orchard.Web/Modules/Orchard.Resources/Styles/jquery-ui.min.css
#	src/Orchard.Web/Modules/Orchard.Resources/Styles/jquery.colorbox.css
This commit is contained in:
Benedek Farkas 2024-04-17 10:37:23 +02:00
commit 70e13666f7
11 changed files with 195 additions and 53 deletions

View File

@ -10,25 +10,61 @@ on:
- 1.10.x
jobs:
compile:
name: Compile
compile-dotnet:
name: Compile .NET solution
defaults:
run:
shell: pwsh
runs-on: windows-latest
steps:
- name: Clone repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@v4.1.1
- name: Restore NuGet packages
run: nuget restore src/Orchard.sln
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@6fb02220983dee41ce7ae257b6f4d8f9bf5ed4ce # v2.0.0
uses: microsoft/setup-msbuild@v2
- name: Compile
run: msbuild Orchard.proj /m /v:minimal /t:Compile /p:MvcBuildViews=true /p:TreatWarningsAsErrors=true -WarnAsError
- name: Test
run: msbuild Orchard.proj /m /v:minimal /t:Test
compile-node:
name: Compile client-side assets
defaults:
run:
shell: pwsh
runs-on: windows-latest
steps:
- name: Clone repository
uses: actions/checkout@v4.1.1
- name: Setup NodeJS
uses: actions/setup-node@v4.0.2
with:
node-version: '7'
- name: Setup NPM packages
working-directory: ./src
run: |
npm install --loglevel warn
# Install gulp globally to be able to run the rebuild task, using the same version as in the project.
$gulpVersion = (Get-Content Package.json -Raw | ConvertFrom-Json).devDependencies.gulp
Start-Process npm -NoNewWindow -Wait -ArgumentList "install gulp@$gulpVersion -g --loglevel warn"
- name: Rebuild client-side assets
working-directory: ./src
run: |
gulp rebuild
git add . # To make line ending changes "disappear".
$gitStatus = (git status --porcelain)
if ($gitStatus)
{
throw ("Client-side assets are not up-to-date. Please run 'gulp rebuild' and commit the changes.`n" +
[System.String]::Join([System.Environment]::NewLine, $gitStatus))
}

View File

@ -6,8 +6,6 @@
@using Orchard.Utility.Extensions
@{
var urlPrefix = WorkContext.Resolve<ShellSettings>().RequestUrlPrefix;
Layout.Title = T("Manage Aliases").Text;
var aliasService = WorkContext.Resolve<IAliasService>();
AdminIndexOptions options = Model.Options;
@ -59,10 +57,10 @@
<tr>
<td>
<input type="hidden" value="@alias.Path" name="@Html.FieldNameFor(m => Model.AliasEntries[index].Alias.Path)" />
@Html.Link(alias.Path == String.Empty ? "/" : alias.Path, Href("~/" + urlPrefix + alias.Path))
@Html.Link(alias.Path == String.Empty ? "/" : alias.Path, Href("~/" + alias.Path))
</td>
<td>
@Html.Link(url, Href("~/" + urlPrefix + "/" + url))
@Html.Link(url, Href("~/" + url))
</td>
</tr>
}

View File

@ -6,8 +6,6 @@
@using Orchard.Utility.Extensions
@{
var urlPrefix = WorkContext.Resolve<ShellSettings>().RequestUrlPrefix;
Layout.Title = T("Manage Aliases").Text;
var aliasService = WorkContext.Resolve<IAliasService>();
AdminIndexOptions options = Model.Options;
@ -73,10 +71,10 @@
<input type="checkbox" value="true" name="@Html.FieldNameFor(m => Model.AliasEntries[index].IsChecked)" />
</td>
<td>
@Html.Link(alias.Path == String.Empty ? "/" : alias.Path, Href("~/" + urlPrefix + alias.Path))
@Html.Link(alias.Path == String.Empty ? "/" : alias.Path, Href("~/" + alias.Path))
</td>
<td>
@Html.Link(url, Href("~/" + urlPrefix + "/" + url))
@Html.Link(url, Href("~/" + url))
</td>
<td>
<ul class="action-links">

View File

@ -74,5 +74,11 @@ namespace Orchard.DynamicForms.Controllers {
return Redirect(Request.UrlReferrer.ToString());
}
public ActionResult Export(string id) =>
File(
_formService.ExportSubmissions(id),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"Export.xlsx");
}
}

View File

@ -52,6 +52,12 @@
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="DocumentFormat.OpenXml, Version=3.0.2.0, Culture=neutral, PublicKeyToken=8fb06cb64d019a17, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\DocumentFormat.OpenXml.3.0.2\lib\net46\DocumentFormat.OpenXml.dll</HintPath>
</Reference>
<Reference Include="DocumentFormat.OpenXml.Framework, Version=3.0.2.0, Culture=neutral, PublicKeyToken=8fb06cb64d019a17, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\DocumentFormat.OpenXml.Framework.3.0.2\lib\net46\DocumentFormat.OpenXml.Framework.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.4.1.0\lib\net472\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
</Reference>
@ -68,6 +74,7 @@
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
@ -96,6 +103,7 @@
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Xml.Linq" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Content Include="Assets\CSS\DynamicForms-Admin.css" />
@ -598,4 +606,4 @@
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>
</Project>

View File

@ -2,9 +2,13 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using Orchard.Collections;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
@ -21,6 +25,7 @@ using Orchard.Layouts.Models;
using Orchard.Layouts.Services;
using Orchard.Localization.Services;
using Orchard.Services;
using Orchard.Utility.Extensions;
namespace Orchard.DynamicForms.Services {
public class FormService : IFormService {
@ -38,16 +43,16 @@ namespace Orchard.DynamicForms.Services {
private readonly ICultureAccessor _cultureAccessor;
public FormService(
ILayoutSerializer serializer,
IClock clock,
IRepository<Submission> submissionRepository,
IFormElementEventHandler elementHandlers,
IContentDefinitionManager contentDefinitionManager,
IBindingManager bindingManager,
IDynamicFormEventHandler formEventHandler,
ILayoutSerializer serializer,
IClock clock,
IRepository<Submission> submissionRepository,
IFormElementEventHandler elementHandlers,
IContentDefinitionManager contentDefinitionManager,
IBindingManager bindingManager,
IDynamicFormEventHandler formEventHandler,
Lazy<IEnumerable<IElementValidator>> validators,
IDateLocalizationServices dateLocalizationServices,
IOrchardServices services,
IDateLocalizationServices dateLocalizationServices,
IOrchardServices services,
ICultureAccessor cultureAccessor) {
_serializer = serializer;
@ -152,6 +157,90 @@ namespace Orchard.DynamicForms.Services {
};
}
public Stream ExportSubmissions(string formName = null) {
var stream = new MemoryStream();
string GetColumnId(int columnNumber) {
string result = "";
do {
result = ((char)((columnNumber - 1) % 26 + (int)'A')).ToString() + result;
columnNumber = (columnNumber - 1) / 26;
} while (columnNumber != 0);
return result;
}
// Create a spreadsheet document.
var spreadsheetDocument = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook);
// Add a WorkbookPart to the document.
var workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
var worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
var sheetData = new SheetData();
worksheetPart.Worksheet = new Worksheet(sheetData);
// Add Sheets to the Workbook.
var sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild(new Sheets());
// Fetch submissions
var query = _submissionRepository.Table;
if (!String.IsNullOrWhiteSpace(formName)) {
query = query.Where(x => x.FormName == formName);
}
var submissions = new Orderable<Submission>(query).Desc(x => x.CreatedUtc).Queryable.ToArray();
foreach (var formGroup in submissions.GroupBy(s => s.FormName)) {
// Append a new worksheet and associate it with the workbook.
var sheet = new Sheet() {
Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart),
SheetId = 1,
Name = formGroup.Key
};
sheets.Append(sheet);
var data = GenerateDataTable(formGroup);
uint rowIndex = 1;
var headerRow = new Row { RowIndex = rowIndex };
sheetData.Append(headerRow);
for (int i = 0; i < data.Columns.Count; i++) {
var title = data.Columns[i].ToString().CamelFriendly();
headerRow.Append(new Cell {
CellReference = GetColumnId(i + 1) + rowIndex,
InlineString = new InlineString { Text = new Text(title) },
DataType = new EnumValue<CellValues>(CellValues.InlineString),
});
}
foreach (DataRow dataRow in data.Rows) {
rowIndex++;
var row = new Row { RowIndex = rowIndex };
sheetData.Append(row);
for (int i = 0; i < data.Columns.Count; i++) {
var value = dataRow[data.Columns[i]];
row.Append(new Cell {
CellReference = GetColumnId(i + 1) + rowIndex,
InlineString = new InlineString { Text = new Text(value.ToString()) },
DataType = new EnumValue<CellValues>(CellValues.InlineString),
});
}
}
}
workbookpart.Workbook.Save();
// Close the document.
spreadsheetDocument.Dispose();
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
public void DeleteSubmission(Submission submission) {
_submissionRepository.Delete(submission);
}
@ -191,10 +280,10 @@ namespace Orchard.DynamicForms.Services {
// Collect any remaining form values not handled by any specific element.
var requestForm = _services.WorkContext.HttpContext.Request.Form;
var blackList = new[] {"__RequestVerificationToken", "formName", "contentId"};
foreach (var key in
from string key in requestForm
where !String.IsNullOrWhiteSpace(key) && !blackList.Contains(key) && values[key] == null
var blackList = new[] { "__RequestVerificationToken", "formName", "contentId" };
foreach (var key in
from string key in requestForm
where !String.IsNullOrWhiteSpace(key) && !blackList.Contains(key) && values[key] == null
select key) {
values.Add(key, requestForm[key]);
@ -204,13 +293,14 @@ namespace Orchard.DynamicForms.Services {
}
public DataTable GenerateDataTable(IEnumerable<Submission> submissions) {
var records = submissions.Select(x => Tuple.Create(x, x.ToNameValues())).ToArray();
var records = submissions.Select(x => System.Tuple.Create(x, x.ToNameValues())).ToArray();
var columnNames = new HashSet<string>();
var dataTable = new DataTable();
foreach (var key in
from record in records
from string key in record.Item2 where !columnNames.Contains(key)
foreach (var key in
from record in records
from string key in record.Item2
where !columnNames.Contains(key)
where !String.IsNullOrWhiteSpace(key)
select key) {
columnNames.Add(key);
@ -282,7 +372,7 @@ namespace Orchard.DynamicForms.Services {
if (form.Publication == "Publish" || !contentTypeSettings.Draftable) {
_contentManager.Publish(contentItem);
}
return contentItem;
}
@ -307,8 +397,8 @@ namespace Orchard.DynamicForms.Services {
}
private static void InvokePartBindings(
ContentItem contentItem,
IEnumerable<ContentPartBindingDescriptor> lookup,
ContentItem contentItem,
IEnumerable<ContentPartBindingDescriptor> lookup,
PartBindingSettings partBindingSettings,
string value) {
@ -348,7 +438,7 @@ namespace Orchard.DynamicForms.Services {
if (field == null)
return;
var fieldBindingDescriptorsQuery =
var fieldBindingDescriptorsQuery =
from partBindingDescriptor in lookup
where partBindingDescriptor.Part.PartDefinition.Name == partBindingSettings.Name
from fieldBindingDescriptor in partBindingDescriptor.FieldBindings

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Data;
using System.IO;
using System.Web.Mvc;
using Orchard.Collections;
using Orchard.ContentManagement;
@ -20,6 +21,7 @@ namespace Orchard.DynamicForms.Services {
Submission CreateSubmission(Submission submission);
Submission GetSubmission(int id);
IPageOfItems<Submission> GetSubmissions(string formName = null, int? skip = null, int? take = null);
Stream ExportSubmissions(string formName = null);
void DeleteSubmission(Submission submission);
int DeleteSubmissions(IEnumerable<int> submissionIds);
void ReadElementValues(FormElement element, ReadElementValuesContext context);

View File

@ -13,6 +13,9 @@
dataColumns.Add(Model.Submissions.Columns[i]);
}
}
<div class="manage">
@Html.ActionLink(T("Export").Text, "Export", "SubmissionAdmin", new { id = Model.FormName, area = "Orchard.DynamicForms" }, new { @class = "button primaryAction" })
</div>
@using (Html.BeginFormAntiForgeryPost()) {
<fieldset class="bulk-actions">
<label for="publishActions">@T("Actions:")</label>

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="DocumentFormat.OpenXml" version="3.0.2" targetFramework="net48" />
<package id="DocumentFormat.OpenXml.Framework" version="3.0.2" targetFramework="net48" />
<package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net48" />
<package id="Microsoft.AspNet.Razor" version="3.2.7" targetFramework="net48" />
<package id="Microsoft.AspNet.WebPages" version="3.2.7" targetFramework="net48" />
@ -7,4 +9,4 @@
<package id="Microsoft.TypeScript.MSBuild" version="3.7.4" targetFramework="net48" developmentDependency="true" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net48" />
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net48" />
</packages>
</packages>

File diff suppressed because one or more lines are too long

View File

@ -23,22 +23,22 @@ namespace Orchard.Mvc.ViewEngines.Razor {
private object _display;
private object _layout;
public Localizer T {
public Localizer T {
get {
// first time used, create it
if(_localizer == NullLocalizer.Instance) {
if (_localizer == NullLocalizer.Instance) {
// if the Model is a shape, get localization scopes from binding sources
// e.g., Logon.cshtml in a theme, overriging Users/Logon.cshtml, needs T to
// fallback to the one in Users
var shape = Model as IShape;
if(shape != null && shape.Metadata.BindingSources.Count > 1) {
if (shape != null && shape.Metadata.BindingSources.Count > 1) {
var localizers = shape.Metadata.BindingSources.Reverse().Select(scope => LocalizationUtilities.Resolve(ViewContext, scope)).ToList();
_localizer = (text, args) => {
foreach(var localizer in localizers) {
_localizer = (text, args) => {
foreach (var localizer in localizers) {
var hint = localizer(text, args);
// if not localized using this scope, use next scope
if(hint.Text != text) {
if (hint.Text != text) {
return hint;
}
}
@ -54,7 +54,7 @@ namespace Orchard.Mvc.ViewEngines.Razor {
}
return _localizer;
}
}
}
public dynamic Display { get { return _display; } }
@ -79,7 +79,7 @@ namespace Orchard.Mvc.ViewEngines.Razor {
}
private IAuthorizer _authorizer;
public IAuthorizer Authorizer {
public IAuthorizer Authorizer {
get {
return _authorizer ?? (_authorizer = WorkContext.Resolve<IAuthorizer>());
}
@ -114,7 +114,7 @@ namespace Orchard.Mvc.ViewEngines.Razor {
}
private string[] _commonLocations;
public string[] CommonLocations { get { return _commonLocations ?? (_commonLocations = WorkContext.Resolve<ExtensionLocations>().CommonLocations); } }
public string[] CommonLocations { get { return _commonLocations ?? (_commonLocations = WorkContext.Resolve<ExtensionLocations>().CommonLocations); } }
public void RegisterImageSet(string imageSet, string style = "", int size = 16) {
// hack to fake the style "alternate" for now so we don't have to change stylesheet names when this is hooked up
@ -150,7 +150,7 @@ namespace Orchard.Mvc.ViewEngines.Razor {
base.InitHelpers();
WorkContext = ViewContext.GetWorkContext();
_display = DisplayHelperFactory.CreateHelper(ViewContext, this);
_layout = WorkContext.Layout;
}
@ -190,11 +190,10 @@ namespace Orchard.Mvc.ViewEngines.Razor {
_tenantPrefix = WorkContext.Resolve<ShellSettings>().RequestUrlPrefix ?? "";
}
if (!String.IsNullOrEmpty(_tenantPrefix)
&& path.StartsWith("~/")
&& !CommonLocations.Any(gpp=>path.StartsWith(gpp, StringComparison.OrdinalIgnoreCase))
) {
return base.Href("~/" + _tenantPrefix + path.Substring(2), pathParts);
if (!string.IsNullOrWhiteSpace(_tenantPrefix)
&& path.StartsWith("~/")
&& !CommonLocations.Any(gpp => path.StartsWith(gpp, StringComparison.OrdinalIgnoreCase))) {
return base.Href("~/" + _tenantPrefix + path.Substring(1), pathParts);
}
return base.Href(path, pathParts);