V8/feature/super doctype create menu (#9174)

* WIP - added options from superdoctypecreate package

resolve merge conflict in create html file

* fiddling with the wording but it will never be perfect

* looks like ng-if should be ng-show

* Update data-elements for uniqueness (I'm not sure what these are used for!)

* pass 'iscomposition' on the querystring when choosing the 'composition' option from the menu

Why? - in the future we could hide the 'Compositions...' button when choosing to create a composition

* Remove PostCreateCollection implementation now the Create Collection is removed in this PR from the DocType Create menu

resolve merge conflict in Remove PostCreateCollection implementation now the Create Collection is removed in this PR from the DocType Create menu

* Add translations

* Put back PostSave method. It's useful.

Co-authored-by: Kenn Jacobsen <post@kennjacobsen.dk>
Co-authored-by: Nathan Woulfe <nathan@nathanw.com.au>
This commit is contained in:
Marc Goodson
2021-02-10 23:25:38 +00:00
committed by GitHub
parent e9429cfe44
commit 230bf1052c
7 changed files with 96 additions and 229 deletions

View File

@@ -511,41 +511,8 @@ function contentTypeResource($q, $http, umbRequestHelper, umbDataFormatter, loca
$http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "PostCreateContainer", { parentId: parentId, name: encodeURIComponent(name) })),
'Failed to create a folder under parent id ' + parentId);
},
/**
* @ngdoc method
* @name umbraco.resources.contentTypeResource#createCollection
* @methodOf umbraco.resources.contentTypeResource
*
* @description
* Create a collection of a content types
*
* ##usage
* <pre>
* contentTypeResource.createCollection(1244,"testcollectionname",true,"collectionItemName",true,"icon-name","icon-name")
* .then(function() {
* Do stuff..
* });
* </pre>
*
* @param {Int} parentId the ID of the parent content type underneath which to create the collection
* @param {String} collectionName the name of the collection
* @param {Boolean} collectionCreateTemplate true/false to specify whether to create a default template for the collection
* @param {String} collectionItemName the name of the collection item
* @param {Boolean} collectionItemCreateTemplate true/false to specify whether to create a default template for the collection item
* @param {String} collectionIcon the icon for the collection
* @param {String} collectionItemIcon the icon for the collection item
* @returns {Promise} resourcePromise object.
*
*/
createCollection: function (parentId, collectionName, collectionCreateTemplate, collectionItemName, collectionItemCreateTemplate, collectionIcon, collectionItemIcon) {
return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("contentTypeApiBaseUrl", "PostCreateCollection", { parentId: parentId, collectionName: collectionName, collectionCreateTemplate: collectionCreateTemplate, collectionItemName: collectionItemName, collectionItemCreateTemplate: collectionItemCreateTemplate, collectionIcon: collectionIcon, collectionItemIcon: collectionItemIcon})),
'Failed to create collection under ' + parentId);
},
},
/**
* @ngdoc method

View File

@@ -11,8 +11,7 @@ function DocumentTypesCreateController($scope, $location, navigationService, con
$scope.model = {
allowCreateFolder: $scope.currentNode.parentId === null || $scope.currentNode.nodeType === "container",
folderName: "",
creatingFolder: false,
creatingDoctypeCollection: false
creatingFolder: false
};
var disableTemplates = Umbraco.Sys.ServerVariables.features.disabledFeatures.disableTemplates;
@@ -24,12 +23,6 @@ function DocumentTypesCreateController($scope, $location, navigationService, con
$scope.model.creatingFolder = true;
};
$scope.showCreateDocTypeCollection = function () {
$scope.model.creatingDoctypeCollection = true;
$scope.model.collectionCreateTemplate = !$scope.model.disableTemplates;
$scope.model.collectionItemCreateTemplate = !$scope.model.disableTemplates;
};
$scope.createContainer = function () {
if (formHelper.submitForm({ scope: $scope, formCtrl: $scope.createFolderForm })) {
@@ -58,55 +51,7 @@ function DocumentTypesCreateController($scope, $location, navigationService, con
});
}
};
$scope.createCollection = function () {
if (formHelper.submitForm({ scope: $scope, formCtrl: this.createDoctypeCollectionForm, statusMessage: "Creating Doctype Collection..." })) {
// see if we can find matching icons
var collectionIcon = "icon-folders", collectionItemIcon = "icon-document";
iconHelper.getIcons().then(function (icons) {
for (var i = 0; i < icons.length; i++) {
// for matching we'll require a full match for collection, partial match for item
if (icons[i].substring(5) == $scope.model.collectionName.toLowerCase()) {
collectionIcon = icons[i];
} else if (icons[i].substring(5).indexOf($scope.model.collectionItemName.toLowerCase()) > -1) {
collectionItemIcon = icons[i];
}
}
contentTypeResource.createCollection(node.id, $scope.model.collectionName, $scope.model.collectionCreateTemplate, $scope.model.collectionItemName, $scope.model.collectionItemCreateTemplate, collectionIcon, collectionItemIcon)
.then(function (collectionData) {
navigationService.hideMenu();
$location.search('create', null);
$location.search('notemplate', null);
formHelper.resetForm({ scope: $scope, formCtrl: this.createDoctypeCollectionForm });
var section = appState.getSectionState("currentSection");
// redirect to the item id
$location.path("/" + section + "/documenttypes/edit/" + collectionData.containerId);
}, function (err) {
formHelper.resetForm({ scope: $scope, formCtrl: this.createDoctypeCollectionForm, hasErrors: true });
$scope.error = err;
//show any notifications
if (Utilities.isArray(err.data.notifications)) {
for (var i = 0; i < err.data.notifications.length; i++) {
notificationsService.showNotification(err.data.notifications[i]);
}
}
});
});
}
};
};
// Disabling logic for creating document type with template if disableTemplates is set to true
if (!disableTemplates) {
@@ -125,6 +70,22 @@ function DocumentTypesCreateController($scope, $location, navigationService, con
navigationService.hideMenu();
};
$scope.createComposition = function () {
$location.search('create', null);
$location.search('notemplate', null);
$location.search('iscomposition', null);
$location.path("/settings/documenttypes/edit/" + node.id).search("create", "true").search("notemplate", "true").search("iscomposition", "true");
navigationService.hideMenu();
};
$scope.createElement = function () {
$location.search('create', null);
$location.search('notemplate', null);
$location.search('iselement', null);
$location.path("/settings/documenttypes/edit/" + node.id).search("create", "true").search("notemplate", "true").search("iselement", "true");
navigationService.hideMenu();
};
$scope.close = function() {
const showMenu = true;
navigationService.hideDialog(showMenu);

View File

@@ -1,16 +1,15 @@
<div ng-controller="Umbraco.Editors.DocumentTypes.CreateController">
<div class="umbracoDialog umb-dialog-body with-footer" ng-cloak>
<div class="umb-pane" ng-show="!model.creatingFolder && !model.creatingDoctypeCollection">
<div class="umb-pane" ng-show="!model.creatingFolder">
<h5><localize key="create_createUnder">Create an item under</localize> {{currentNode.name}}</h5>
<ul class="umb-actions umb-actions-child">
<li data-element="action-documentType" class="umb-action" ng-hide="model.disableTemplates">
<button type="button" ng-click="createDocType()" class="umb-action-link umb-outline btn-reset" umb-auto-focus>
<i class="large icon icon-item-arrangement" aria-hidden="true"></i>
<i class="large icon icon-document" aria-hidden="true"></i>
<span class="menu-label">
<localize key="content_documentType">Document type</localize>
<localize key="create_documentTypeWithTemplate">Document Type with Template</localize>
<small><localize key="create_documentTypeWithTemplateDescription">The data definition for a content page that can be created by editors in the content tree and is directly accessible via a URL.</localize></small>
</span>
</button>
</li>
@@ -18,24 +17,38 @@
<button type="button" ng-click="createComponent()" class="umb-action-link umb-outline btn-reset">
<i class="large icon icon-item-arrangement" aria-hidden="true"></i>
<span class="menu-label">
<localize ng-if="model.disableTemplates === false" key="create_documentTypeWithoutTemplate"></localize>
<localize ng-if="model.disableTemplates === true" key="content_documentType">Document type></localize>
<localize key="create_documentType">Document Type</localize>
<small><localize key="create_documentTypeDescription">The data definition for a content component that can be created by editors in the content tree and be picked on other pages but has no direct URL.</localize></small>
</span>
</button>
</li>
<li data-element="action-documentTypeCollection" class="umb-action">
<button type="button" ng-click="showCreateDocTypeCollection()" class="umb-action-link umb-outline btn-reset">
<i class="large icon icon-thumbnail-list" aria-hidden="true"></i>
<li data-element="action-documentTypeWithIsElementTypeChecked" class="umb-action">
<button type="button" ng-click="createElement()" class="umb-action-link umb-outline btn-reset" umb-auto-focus>
<i class="large icon icon-science" aria-hidden="true"></i>
<span class="menu-label">
Document Type Collection...
<!--<localize key="content_documentType_collection">Document Type Collection</localize>-->
<localize key="create_elementType">Element Type</localize>
<small><localize key="create_elementTypeDescription">Defines the schema for a repeating set of properties, for example, in a 'Block List' or 'Nested Content' property editor.</localize></small>
</span>
</button>
</li>
<li data-element="action-documentTypeWithoutTemplateForComposition" class="umb-action">
<button type="button" ng-click="createComposition()" class="umb-action-link umb-outline btn-reset">
<i class="large icon icon-defrag" aria-hidden="true"></i>
<span class="menu-label">
<localize key="create_composition">Composition</localize>
<small><localize key="create_compositionDescription">Defines a re-usable set of properties that can be included in the definition of multiple other Document Types. For example, a set of 'Common Page Settings'.</localize></small>
</span>
</button>
</li>
<li data-element="action-folder" ng-if="model.allowCreateFolder" class="umb-action">
<button type="button" ng-click="showCreateFolder()" class="umb-action-link umb-outline btn-reset">
<i class="large icon icon-folder" aria-hidden="true"></i>
<span class="menu-label"><localize key="general_folder"></localize>...</span>
<span class="menu-label">
<localize key="create_folder">Folder</localize>
<small>
<localize key="create_folderDescription">Used to organise the Document Types, Compositions and Element Types created in this Document Type tree.</localize>
</small>
</span>
</button>
</li>
</ul>
@@ -43,8 +56,8 @@
<div class="umb-pane" ng-show="model.creatingFolder">
<form novalidate name="createFolderForm"
ng-submit="createContainer()"
val-form-manager>
ng-submit="createContainer()"
val-form-manager>
<div ng-show="error">
<div class="alert alert-error">
@@ -61,59 +74,11 @@
</form>
</div>
<div class="umb-pane" ng-if="model.creatingDoctypeCollection">
<small>
A Document Type collection is a fast way to create two Document Types in one task.
The Item Document Type will automatically be
allowed under the Parent Document Type.
</small>
<p>&nbsp;</p>
<form novalidate name="createDoctypeCollectionForm"
ng-submit="createCollection()"
val-form-manager>
<div ng-show="error">
<div class="alert alert-error">
<div><strong>{{error.errorMsg}}</strong></div>
<div>{{error.data.message}}</div>
</div>
</div>
<umb-control-group>
<label for="collectionName" class="control-label">Name of the Parent Document Type</label>
<input type="text" name="collectionName" id="collectionName" ng-model="model.collectionName" maxlength="255" class="umb-textstring textstring input-block-level" umb-auto-focus required />
<umb-checkbox ng-if="model.disableTemplates === false"
name="collectionCreateTemplate"
model="model.collectionCreateTemplate"
text="Create template for the Parent Document Type">
</umb-checkbox>
</umb-control-group>
<umb-control-group>
<label for="collectionItemName" class="control-label">Name of the Item Document Type</label>
<input type="text" name="collectionItemName" id="collectionItemName" ng-model="model.collectionItemName" maxlength="255" class="umb-textstring textstring input-block-level" required />
<umb-checkbox ng-if="model.disableTemplates === false"
name="collectionItemCreateTemplate"
model="model.collectionItemCreateTemplate"
text="Create template for the Item Document Type">
</umb-checkbox>
</umb-control-group>
<div class="mt3">
<button type="submit" class="btn btn-primary"><localize key="general_create">Create</localize></button>
</div>
</form>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-if="!model.creatingFolder">
<button class="btn btn-info" ng-click="close(true)">
<localize key="buttons_somethingElse">Do something else</localize>
</button>
</div>
</div>
<div class="umb-dialog-footer btn-toolbar umb-btn-toolbar" ng-if="!model.creatingFolder">
<button class="btn btn-info" ng-click="close(true)">
<localize key="buttons_somethingElse">Do something else</localize>
</button>
</div>
</div>

View File

@@ -350,6 +350,16 @@
<key alias="noMediaTypesWithNoSettingsAccess">Det valgte medie i træet tillader ikke at medier oprettes under det.</key>
<key alias="noMediaTypesEditPermissions">Rediger tilladelser for denne medietype.</key>
<key alias="documentTypeWithoutTemplate">Dokumenttype uden skabelon</key>
<key alias="documentTypeWithTemplate">Dokumenttype med skabelon</key>
<key alias="documentTypeWithTemplateDescription">Definerer en indholdsside, der kan oprettes af redaktørerne i indholdstræet, og som er kan tilgås direkte på en URL.</key>
<key alias="documentType">Dokumenttype</key>
<key alias="documentTypeDescription">Definerer en indholdskomponent, der kan oprettes af redaktørerne i indholdstræet og benyttes i sammenhæng med andet indhold, men som ikke kan tilgås direkte på en URL.</key>
<key alias="elementType">Element-type</key>
<key alias="elementTypeDescription">Definerer skabelonen for et sæt at egenskaber, der kan anvendes som skema i avancerede felter som f.eks. 'Block List' eller 'Nested Content'.</key>
<key alias="composition">Komposition</key>
<key alias="compositionDescription">Definerer et sæt genbrugbare egenskaber, der kan inkluderes i definitionen af andre dokumenttyper - f.eks. et sæt 'Almindelige side-data'.</key>
<key alias="folder">Mappe</key>
<key alias="folderDescription">Benyttes til at organisere dokumenttyper, element-typer og kompositioner i dokumenttype-træet.</key>
<key alias="newFolder">Ny mappe</key>
<key alias="newDataType">Ny datatype</key>
<key alias="newJavascriptFile">Ny JavaScript-fil</key>

View File

@@ -371,6 +371,16 @@
<key alias="noMediaTypesWithNoSettingsAccess">The selected media in the tree doesn't allow for any other media to be created below it.</key>
<key alias="noMediaTypesEditPermissions">Edit permissions for this media type</key>
<key alias="documentTypeWithoutTemplate">Document Type without a template</key>
<key alias="documentTypeWithTemplate">Document Type with Template</key>
<key alias="documentTypeWithTemplateDescription">The data definition for a content page that can be created by editors in the content tree and is directly accessible via a URL.</key>
<key alias="documentType">Document Type</key>
<key alias="documentTypeDescription">The data definition for a content component that can be created by editors in the content tree and be picked on other pages but has no direct URL.</key>
<key alias="elementType">Element Type</key>
<key alias="elementTypeDescription">Defines the schema for a repeating set of properties, for example, in a 'Block List' or 'Nested Content' property editor.</key>
<key alias="composition">Composition</key>
<key alias="compositionDescription">Defines a re-usable set of properties that can be included in the definition of multiple other Document Types. For example, a set of 'Common Page Settings'.</key>
<key alias="folder">Folder</key>
<key alias="folderDescription">Used to organise the Document Types, Compositions and Element Types created in this Document Type tree.</key>
<key alias="newFolder">New folder</key>
<key alias="newDataType">New data type</key>
<key alias="newJavascriptFile">New JavaScript file</key>

View File

@@ -378,6 +378,16 @@
<key alias="noMediaTypesWithNoSettingsAccess">The selected media in the tree doesn't allow for any other media to be created below it.</key>
<key alias="noMediaTypesEditPermissions">Edit permissions for this media type</key>
<key alias="documentTypeWithoutTemplate">Document Type without a template</key>
<key alias="documentTypeWithTemplate">Document Type with Template</key>
<key alias="documentTypeWithTemplateDescription">The data definition for a content page that can be created by editors in the content tree and is directly accessible via a URL.</key>
<key alias="documentType">Document Type</key>
<key alias="documentTypeDescription">The data definition for a content component that can be created by editors in the content tree and be picked on other pages but has no direct URL.</key>
<key alias="elementType">Element Type</key>
<key alias="elementTypeDescription">Defines the schema for a repeating set of properties, for example, in a 'Block List' or 'Nested Content' property editor.</key>
<key alias="composition">Composition</key>
<key alias="compositionDescription">Defines a re-usable set of properties that can be included in the definition of multiple other Document Types. For example, a set of 'Common Page Settings'.</key>
<key alias="folder">Folder</key>
<key alias="folderDescription">Used to organise the Document Types, Compositions and Element Types created in this Document Type tree.</key>
<key alias="newFolder">New folder</key>
<key alias="newDataType">New data type</key>
<key alias="newJavascriptFile">New JavaScript file</key>

View File

@@ -282,91 +282,35 @@ namespace Umbraco.Web.Editors
: Request.CreateNotificationValidationErrorResponse(result.Exception.Message);
}
public CreatedContentTypeCollectionResult PostCreateCollection(int parentId, string collectionName, bool collectionCreateTemplate, string collectionItemName, bool collectionItemCreateTemplate, string collectionIcon, string collectionItemIcon)
{
// create item doctype
var itemDocType = new ContentType(parentId);
itemDocType.Name = collectionItemName;
itemDocType.Alias = collectionItemName.ToSafeAlias(true);
itemDocType.Icon = collectionItemIcon;
// create item doctype template
if (collectionItemCreateTemplate)
{
var template = CreateTemplateForContentType(itemDocType.Alias, itemDocType.Name);
itemDocType.SetDefaultTemplate(template);
}
// save item doctype
Services.ContentTypeService.Save(itemDocType);
// create collection doctype
var collectionDocType = new ContentType(parentId);
collectionDocType.Name = collectionName;
collectionDocType.Alias = collectionName.ToSafeAlias(true);
collectionDocType.Icon = collectionIcon;
collectionDocType.IsContainer = true;
collectionDocType.AllowedContentTypes = new List<ContentTypeSort>()
{
new ContentTypeSort(itemDocType.Id, 0)
};
// create collection doctype template
if (collectionCreateTemplate)
{
var template = CreateTemplateForContentType(collectionDocType.Alias, collectionDocType.Name);
collectionDocType.SetDefaultTemplate(template);
}
// save collection doctype
Services.ContentTypeService.Save(collectionDocType);
// test if the parent exist and then allow the collection underneath
var parentCt = Services.ContentTypeService.Get(parentId);
if (parentCt != null)
{
var allowedCts = parentCt.AllowedContentTypes.ToList();
allowedCts.Add(new ContentTypeSort(collectionDocType.Id, allowedCts.Count()));
parentCt.AllowedContentTypes = allowedCts;
Services.ContentTypeService.Save(parentCt);
}
return new CreatedContentTypeCollectionResult
{
CollectionId = collectionDocType.Id,
ContainerId = itemDocType.Id
};
}
public DocumentTypeDisplay PostSave(DocumentTypeSave contentTypeSave)
{
//Before we send this model into this saving/mapping pipeline, we need to do some cleanup on variations.
//If the doc type does not allow content variations, we need to update all of it's property types to not allow this either
//else we may end up with ysods. I'm unsure if the service level handles this but we'll make sure it is updated here
//Before we send this model into this saving/mapping pipeline, we need to do some cleanup on variations.
//If the doc type does not allow content variations, we need to update all of it's property types to not allow this either
//else we may end up with ysods. I'm unsure if the service level handles this but we'll make sure it is updated here
if (!contentTypeSave.AllowCultureVariant)
{
foreach(var prop in contentTypeSave.Groups.SelectMany(x => x.Properties))
foreach (var prop in contentTypeSave.Groups.SelectMany(x => x.Properties))
{
prop.AllowCultureVariant = false;
}
}
var savedCt = PerformPostSave<DocumentTypeDisplay, DocumentTypeSave, PropertyTypeBasic>(
contentTypeSave: contentTypeSave,
getContentType: i => Services.ContentTypeService.Get(i),
saveContentType: type => Services.ContentTypeService.Save(type),
beforeCreateNew: ctSave =>
contentTypeSave: contentTypeSave,
getContentType: i => Services.ContentTypeService.Get(i),
saveContentType: type => Services.ContentTypeService.Save(type),
beforeCreateNew: ctSave =>
{
//create a default template if it doesn't exist -but only if default template is == to the content type
//create a default template if it doesn't exist -but only if default template is == to the content type
if (ctSave.DefaultTemplate.IsNullOrWhiteSpace() == false && ctSave.DefaultTemplate == ctSave.Alias)
{
var template = CreateTemplateForContentType(ctSave.Alias, ctSave.Name);
// If the alias has been manually updated before the first save,
// make sure to also update the first allowed template, as the
// name will come back as a SafeAlias of the document type name,
// not as the actual document type alias.
// For more info: http://issues.umbraco.org/issue/U4-11059
// If the alias has been manually updated before the first save,
// make sure to also update the first allowed template, as the
// name will come back as a SafeAlias of the document type name,
// not as the actual document type alias.
// For more info: http://issues.umbraco.org/issue/U4-11059
if (ctSave.DefaultTemplate != template.Alias)
{
var allowedTemplates = ctSave.AllowedTemplates.ToArray();
@@ -375,7 +319,7 @@ namespace Umbraco.Web.Editors
ctSave.AllowedTemplates = allowedTemplates;
}
//make sure the template alias is set on the default and allowed template so we can map it back
//make sure the template alias is set on the default and allowed template so we can map it back
ctSave.DefaultTemplate = template.Alias;
}