Created
June 17, 2024 20:57
-
-
Save gregwiechec/3206a08b8ff15fd92c03e9383cb6039b to your computer and use it in GitHub Desktop.
Updating language versions with property copy and publish
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define([ | |
// Dojo | |
"dojo", "dojo/_base/declare", "dojo/on", "dojo/when", "dijit/registry", | |
// dijit | |
"dijit/layout/_LayoutWidget", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin", "dijit/form/CheckBox", | |
//epi | |
"epi/_Module", "epi/dependency", | |
// epi shell | |
"epi/shell/form/Field", "epi/shell/form/formFieldRegistry", "epi/shell/widget/dialog/Dialog", "epi/shell/DialogService", | |
"epi/shell/MetadataTransformer", | |
// epi cms | |
"epi-cms/_ContentContextMixin", "epi-cms/contentediting/ContentViewModel", "epi-cms/contentediting/ContentActionSupport" | |
], function ( | |
// Dojo | |
dojo, declare, on, when, dijitRegistry, | |
// dijit | |
_LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin, CheckBox, | |
// epi | |
_Module, dependency, | |
// epi shell | |
Field, formFieldRegistry, Dialog, dialogService, MetadataTransformer, | |
// epi cms | |
_ContentContextMixin, ContentViewModel, ContentActionSupport | |
) { | |
var factory = formFieldRegistry.get(formFieldRegistry.type.field, ""); | |
// save property values | |
function updateProperties(propertyName, selectedLanguages, commonDrafts) { | |
return new Promise((resolve) => { | |
var countUpdatedContent = 0; | |
commonDrafts.forEach((commonDraft) => { | |
var language = selectedLanguages.find(x => x.id === commonDraft.language); | |
var model = new ContentViewModel({ | |
contentLink: commonDraft.contentLink, | |
enableAutoSave: false, | |
isInQuickEditMode: true | |
}); | |
model.onContentLinkChange = function () { }; | |
model.reload(true).then(function () { | |
model.setProperty(propertyName, language.value); | |
model.save().then(function () { | |
if (language.publish) { | |
model.changeContentStatus(ContentActionSupport.saveAction.Publish).then(() => { | |
countUpdatedContent++; | |
if (commonDrafts.length === countUpdatedContent) { | |
resolve(); | |
} | |
}); | |
} else { | |
countUpdatedContent++; | |
if (commonDrafts.length === countUpdatedContent) { | |
resolve(); | |
} | |
} | |
}); | |
}); | |
}); | |
}); | |
} | |
// widget that show single language selection | |
var LanguageSelectionWidget = declare([_LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin], { | |
templateString: `<div class="epi-form-container__section__row" style="padding-bottom: 16px;"> | |
<label style="display: inline-block;"><span data-dojo-attach-point="checkboxNode"></span><span data-dojo-attach-point="labelNode" style="text-transform: capitalize;"></span></label> | |
<label style="display: inline-block; margin-left: 16px;"><span data-dojo-attach-point="publishCheckboxNode"></span><span>Publish on save</span></label> | |
<div class="dijitVisible" style="padding-top: 8px;"> | |
<div data-dojo-attach-point="widgetNode"></div> | |
</div> | |
<a href="#" data-dojo-attach-point="copyValue" class="epi-visibleLink">Copy value</a> | |
</div>`, | |
buildRendering: function () { | |
this.inherited(arguments); | |
var self = this; | |
var checkbox = new CheckBox({ | |
name: "checkBox-selection-" + this.language, | |
value: this.language, | |
checked: false, | |
onChange: (checked) => { | |
self._selected = checked; | |
self.onSelectionChanged(); | |
} | |
}, this.checkboxNode); | |
this.own(checkbox); | |
var publishCheckbox = new CheckBox({ | |
name: "checkBox-publish-" + this.language, | |
value: this.language, | |
checked: false, | |
onChange: (checked) => self._publish = checked | |
}, this.publishCheckboxNode); | |
this.own(publishCheckbox); | |
this.own(on(this.copyValue, "click", function () { | |
self._widget.set("value", self.propertyValue); | |
})); | |
//TODO: add editor to HTML | |
loadPropertyEditor(this.commonDraft, this.propertyName, this.widgetNode).then((widget) => { | |
self._widget = widget; | |
self.own(widget); | |
widget.startup(); | |
}); | |
}, | |
_setLabelAttr: { node: "labelNode", type: "innerText" }, | |
getSelection: function () { | |
return ({ | |
id: this.language, | |
selected: this._selected || false, | |
publish: this._publish || false, | |
value: this._widget.get("value") | |
}); | |
}, | |
onSelectionChanged: function() {} | |
}); | |
// load property editor from metadata | |
var metadataManager; | |
var metadataTransformer; | |
var editorFactory; | |
function loadPropertyEditor(commonDraft, propertyName, targetNode) { | |
return new Promise((resolve) => { | |
metadataManager = metadataManager || dependency.resolve("epi.shell.MetadataManager"); | |
metadataManager.getMetadataForType("EPiServer.Core.ContentData", { contentLink: commonDraft.contentLink }) | |
.then((metadata) => { | |
function propertyFilter(ownerMetadata, propertyMetadata) { | |
return propertyMetadata.name.toLowerCase() === propertyName.toLowerCase(); | |
} | |
metadataTransformer = new MetadataTransformer({ propertyFilter: propertyFilter }); | |
var useDefaultValue = true; | |
var componentDefinitions = metadataTransformer.toComponentDefinitions(metadata, "", useDefaultValue, false); | |
var editorDefinition = componentDefinitions[0].components[0]; | |
var metadataProperty = metadata.properties.find(x => x.name.toLowerCase() === propertyName.toLowerCase()); | |
editorFactory = editorFactory || dependency.resolve("epi.cms.contentediting.EditorFactory"); | |
editorDefinition.wrapperType = editorFactory.defaultWrapperType; | |
editorDefinition.editorParams = editorDefinition.settings; | |
editorDefinition.metadata = metadataProperty; | |
// we need only editor properties | |
var editor = editorFactory._getWrapperAndEditor(editorDefinition); | |
require([metadataProperty.uiType], (editorWidgetClass) => { | |
try { | |
var editorWidget = new editorWidgetClass(editor.editorParams, targetNode); | |
resolve(editorWidget); | |
} catch (exc) { | |
debugger; | |
} | |
}); | |
}); | |
}); | |
} | |
// widget used as dialog content that displays list of selections | |
var DialogContentWidget = declare([_LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin], { | |
templateString: "<div></div>", | |
metadataManager: null, | |
_selectionWidgets: null, | |
addSelection: function (commonDraft, parentWidget) { | |
var selectionContainer = document.createElement("div"); | |
this.domNode.appendChild(selectionContainer); | |
if (!this._selectionWidgets) { | |
this._selectionWidgets = []; | |
} | |
var self = this; | |
var selectionWidget = new LanguageSelectionWidget({ | |
label: this.languages[commonDraft.language] || commonDraft.language, | |
language: commonDraft.language, | |
commonDraft: commonDraft, | |
propertyName: parentWidget.name, | |
propertyValue: parentWidget.get("value") | |
}, selectionContainer); | |
this.own(on(selectionWidget, "selectionChanged", () => self.onSelectionChanged())); | |
this._selectionWidgets.push(selectionWidget); | |
this.own(selectionWidget); | |
selectionWidget.startup(); | |
}, | |
getSelectedItems: function () { | |
return this._selectionWidgets.map(x => x.getSelection()); | |
}, | |
onSelectionChanged: function() {} | |
}); | |
function selectVersions(widget, commonDrafts, languages) { | |
var customWidget = new DialogContentWidget({ | |
languages: languages | |
}); | |
return new Promise((resolve, reject) => { | |
var resolved = false; | |
var dialog = new Dialog({ | |
title: "Copy to language branches", | |
dialogClass: "epi-dialog-landscape", | |
content: customWidget, | |
confirmActionText: "Save", | |
onExecute: function () { | |
resolve(customWidget.getSelectedItems().filter(x => x.selected)); | |
}, | |
onHide: function () { | |
if (!resolved) { | |
reject(); | |
} | |
} | |
}); | |
widget.own(dialog); | |
dialog.own(customWidget); | |
dialog.own(on(customWidget, "selectionChanged", () => { | |
dialog.definitionConsumer.setItemProperty(dialog._okButtonName, "disabled", | |
customWidget.getSelectedItems().filter(x => x.selected).length === 0); | |
})); | |
dialog.startup(); | |
dialog.show(); | |
dialog.definitionConsumer.setItemProperty(dialog._okButtonName, "disabled", true); | |
setTimeout(() => { | |
commonDrafts.forEach((commonDraft) => { | |
customWidget.addSelection(commonDraft, widget); | |
}); | |
}, 100); | |
}); | |
} | |
function onCopyPropertyValueClick(widget, parent, getCurrentContent) { | |
when(getCurrentContent(), function (context) { | |
// load content versions and select distinct languages | |
var contentVersionStore = dependency.resolve("epi.storeregistry").get("epi.cms.contentversion"); | |
var languagesStore = dependency.resolve("epi.storeregistry").get("epi.cms.languagesettings"); | |
languagesStore.get(context.contentLink).then((languageSettings) => { | |
contentVersionStore.query({ contentLink: context.contentLink }).then(function(versions) { | |
var commonDrafts = versions.filter(x => x.isCommonDraft && x.language !== context.currentLanguageBranch.languageId); | |
// show select versions dialog | |
selectVersions(widget, commonDrafts, languageSettings.languages).then((selectedLanguages) => { | |
// update content | |
var selectedIds = selectedLanguages.map(x => x.id); | |
commonDrafts = commonDrafts.filter(x => selectedIds.indexOf(x.language) !== -1); | |
updateProperties(widget.name, selectedLanguages, commonDrafts).then(() => { | |
dialogService.alert({ | |
title: "Info", | |
description: "Language versions has been updated" | |
}).then(() => window.location.reload()); | |
}); | |
}).catch(() => {}); | |
}); | |
}); | |
}); | |
} | |
// create property wrapper with copy icon | |
function getPropertyWidgetWrapper(widget, parent, getCurrentContent, getCurrentContext) { | |
var wrapper = factory(widget, parent); | |
if (!widget.params.isLanguageSpecific) { | |
return wrapper; | |
} | |
// blocks are not supported | |
if (widget.name.indexOf(".") !== -1) { | |
return wrapper; | |
} | |
var languageNode = document.createElement("span"); | |
languageNode.classList.add("dijitInline", "dijitReset", "dijitIcon", "epi-iconCopy", "epi-cursor--pointer"); | |
languageNode.title = "Copy to other language versions"; | |
wrapper.labelNode.appendChild(languageNode); | |
when(getCurrentContext()).then(function (currentContext) { | |
if (currentContext && currentContext.currentMode === "create" || currentContext.currentMode === "translate") { | |
languageNode.classList.add("dijitHidden"); | |
} | |
}); | |
wrapper.own(on(languageNode, "click", function() { onCopyPropertyValueClick(widget, parent, getCurrentContent); })); | |
return wrapper; | |
} | |
return declare([_Module, _ContentContextMixin], { | |
initialize: function () { | |
this.inherited(arguments); | |
var self = this; | |
var customFactory = { | |
type: formFieldRegistry.type.field, | |
hint: "", | |
factory: function (widget, parent) { | |
return getPropertyWidgetWrapper(widget, parent, self.getCurrentContent.bind(self), self.getCurrentContext.bind(self)); | |
} | |
}; | |
formFieldRegistry.add(customFactory); | |
} | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<module > | |
<assemblies> | |
<!-- This adds the Alloy template assembly to the "default module" --> | |
<add assembly="AlloyMvcTemplates" /> | |
</assemblies> | |
<clientModule initializer="alloy.initializer"> | |
<moduleDependencies> | |
<add dependency="CMS" type="RunAfter" /> | |
</moduleDependencies> | |
</clientModule> | |
<dojo> | |
<!-- Add a mapping from alloy to ~/ClientResources/Scripts to the dojo loader configuration --> | |
<paths> | |
<add name="alloy" path="Scripts" /> | |
</paths> | |
</dojo> | |
</module> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment