Renormalize

This commit is contained in:
Stephan
2018-07-04 09:03:59 +02:00
parent b3696c29cc
commit e8aa6701ef
5 changed files with 3391 additions and 3391 deletions

View File

@@ -1,66 +1,66 @@
using System.Collections.Generic;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Dtos;
namespace Umbraco.Core.Persistence.Factories
{
internal static class DictionaryItemFactory
{
#region Implementation of IEntityFactory<DictionaryItem,DictionaryDto>
public static IDictionaryItem BuildEntity(DictionaryDto dto)
{
var item = new DictionaryItem(dto.Parent, dto.Key);
try
{
item.DisableChangeTracking();
item.Id = dto.PrimaryKey;
item.Key = dto.UniqueId;
// reset dirty initial properties (U4-1946)
item.ResetDirtyProperties(false);
return item;
}
finally
{
item.EnableChangeTracking();
}
}
public static DictionaryDto BuildDto(IDictionaryItem entity)
{
return new DictionaryDto
{
UniqueId = entity.Key,
Key = entity.ItemKey,
Parent = entity.ParentId,
PrimaryKey = entity.Id,
LanguageTextDtos = BuildLanguageTextDtos(entity)
};
}
#endregion
private static List<LanguageTextDto> BuildLanguageTextDtos(IDictionaryItem entity)
{
var list = new List<LanguageTextDto>();
foreach (var translation in entity.Translations)
{
var text = new LanguageTextDto
{
LanguageId = translation.LanguageId,
UniqueId = translation.Key,
Value = translation.Value
};
if (translation.HasIdentity)
text.PrimaryKey = translation.Id;
list.Add(text);
}
return list;
}
}
}
using System.Collections.Generic;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence.Dtos;
namespace Umbraco.Core.Persistence.Factories
{
internal static class DictionaryItemFactory
{
#region Implementation of IEntityFactory<DictionaryItem,DictionaryDto>
public static IDictionaryItem BuildEntity(DictionaryDto dto)
{
var item = new DictionaryItem(dto.Parent, dto.Key);
try
{
item.DisableChangeTracking();
item.Id = dto.PrimaryKey;
item.Key = dto.UniqueId;
// reset dirty initial properties (U4-1946)
item.ResetDirtyProperties(false);
return item;
}
finally
{
item.EnableChangeTracking();
}
}
public static DictionaryDto BuildDto(IDictionaryItem entity)
{
return new DictionaryDto
{
UniqueId = entity.Key,
Key = entity.ItemKey,
Parent = entity.ParentId,
PrimaryKey = entity.Id,
LanguageTextDtos = BuildLanguageTextDtos(entity)
};
}
#endregion
private static List<LanguageTextDto> BuildLanguageTextDtos(IDictionaryItem entity)
{
var list = new List<LanguageTextDto>();
foreach (var translation in entity.Translations)
{
var text = new LanguageTextDto
{
LanguageId = translation.LanguageId,
UniqueId = translation.Key,
Value = translation.Value
};
if (translation.HasIdentity)
text.PrimaryKey = translation.Id;
list.Add(text);
}
return list;
}
}
}

View File

@@ -1,464 +1,464 @@
/**
* @ngdoc controller
* @name Umbraco.Editors.DocumentType.EditController
* @function
*
* @description
* The controller for the content type editor
*/
(function () {
"use strict";
function DocumentTypesEditController($scope, $routeParams, $injector, contentTypeResource, dataTypeResource, editorState, contentEditingHelper, formHelper, navigationService, iconHelper, contentTypeHelper, notificationsService, $filter, $q, localizationService, overlayHelper, eventsService) {
var vm = this;
var evts = [];
var disableTemplates = Umbraco.Sys.ServerVariables.features.disabledFeatures.disableTemplates;
var documentTypeId = $routeParams.id;
var create = $routeParams.create;
var noTemplate = $routeParams.notemplate;
var infiniteMode = $scope.model && $scope.model.infiniteMode;
vm.save = save;
vm.close = close;
vm.currentNode = null;
vm.contentType = {};
vm.labels = {};
vm.submitButtonKey = "buttons_save";
vm.generateModelsKey = "buttons_saveAndGenerateModels";
vm.page = {};
vm.page.loading = false;
vm.page.saveButtonState = "init";
vm.page.navigation = [];
var labelKeys = [
"general_design",
"general_listView",
"general_rights",
"treeHeaders_templates",
"main_sections",
"shortcuts_navigateSections",
"shortcuts_addTab",
"shortcuts_addProperty",
"shortcuts_addEditor",
"shortcuts_editDataType",
"shortcuts_toggleListView",
"shortcuts_toggleAllowAsRoot",
"shortcuts_addChildNode",
"shortcuts_addTemplate"
];
onInit();
function onInit() {
// get init values from model when in infinite mode
if(infiniteMode) {
documentTypeId = $scope.model.id;
create = $scope.model.create;
noTemplate = $scope.model.notemplate;
vm.submitButtonKey = "buttons_saveAndClose";
vm.generateModelsKey = "buttons_generateModelsAndClose";
}
}
localizationService.localizeMany(labelKeys).then(function (values) {
// navigation
vm.labels.design = values[0];
vm.labels.listview = values[1];
vm.labels.permissions = values[2];
vm.labels.templates = values[3];
// keyboard shortcuts
vm.labels.sections = values[4];
vm.labels.navigateSections = values[5];
vm.labels.addTab = values[6];
vm.labels.addProperty = values[7];
vm.labels.addEditor = values[8];
vm.labels.editDataType = values[9];
vm.labels.toggleListView = values[10];
vm.labels.allowAsRoot = values[11];
vm.labels.addChildNode = values[12];
vm.labels.addTemplate = values[13];
var buttons = [
{
"name": vm.labels.design,
"alias": "design",
"icon": "icon-document-dashed-line",
"view": "views/documenttypes/views/design/design.html",
"active": true
},
{
"name": vm.labels.listview,
"alias": "listView",
"icon": "icon-list",
"view": "views/documenttypes/views/listview/listview.html"
},
{
"name": vm.labels.permissions,
"alias": "permissions",
"icon": "icon-keychain",
"view": "views/documenttypes/views/permissions/permissions.html"
},
{
"name": vm.labels.templates,
"alias": "templates",
"icon": "icon-layout",
"view": "views/documenttypes/views/templates/templates.html"
}
];
vm.page.keyboardShortcutsOverview = [
{
"name": vm.labels.sections,
"shortcuts": [
{
"description": vm.labels.navigateSections,
"keys": [{ "key": "1" }, { "key": "4" }],
"keyRange": true
}
]
},
{
"name": vm.labels.design,
"shortcuts": [
{
"description": vm.labels.addTab,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "t" }]
},
{
"description": vm.labels.addProperty,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "p" }]
},
{
"description": vm.labels.addEditor,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "e" }]
},
{
"description": vm.labels.editDataType,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "d" }]
}
]
},
{
"name": vm.labels.listview,
"shortcuts": [
{
"description": vm.labels.toggleListView,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "l" }]
}
]
},
{
"name": vm.labels.permissions,
"shortcuts": [
{
"description": vm.labels.allowAsRoot,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "r" }]
},
{
"description": vm.labels.addChildNode,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "c" }]
}
]
},
{
"name": vm.labels.templates,
"shortcuts": [
{
"description": vm.labels.addTemplate,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "t" }]
}
]
}
];
loadButtons(buttons);
});
contentTypeHelper.checkModelsBuilderStatus().then(function (result) {
vm.page.modelsBuilder = result;
if (result) {
//Models builder mode:
vm.page.defaultButton = {
alias: "save",
hotKey: "ctrl+s",
hotKeyWhenHidden: true,
labelKey: vm.submitButtonKey,
letter: "S",
type: "submit",
handler: function () { vm.save(); }
};
vm.page.subButtons = [{
alias: "saveAndGenerateModels",
hotKey: "ctrl+g",
hotKeyWhenHidden: true,
labelKey: vm.generateModelsKey,
letter: "G",
handler: function () {
vm.page.saveButtonState = "busy";
saveInternal().then(function (result) {
vm.page.saveButtonState = "busy";
localizationService.localize("modelsBuilder_buildingModels").then(function (headerValue) {
localizationService.localize("modelsBuilder_waitingMessage").then(function (msgValue) {
notificationsService.info(headerValue, msgValue);
});
});
contentTypeHelper.generateModels().then(function (result) {
// generateModels() returns the dashboard content
if (!result.lastError) {
//re-check model status
contentTypeHelper.checkModelsBuilderStatus().then(function (statusResult) {
vm.page.modelsBuilder = statusResult;
});
//clear and add success
vm.page.saveButtonState = "init";
localizationService.localize("modelsBuilder_modelsGenerated").then(function (value) {
notificationsService.success(value);
});
} else {
vm.page.saveButtonState = "error";
localizationService.localize("modelsBuilder_modelsExceptionInUlog").then(function (value) {
notificationsService.error(value);
});
}
}, function () {
vm.page.saveButtonState = "error";
localizationService.localize("modelsBuilder_modelsGeneratedError").then(function (value) {
notificationsService.error(value);
});
});
});
}
}];
}
});
if (create) {
vm.page.loading = true;
//we are creating so get an empty data type item
contentTypeResource.getScaffold(documentTypeId)
.then(function (dt) {
init(dt);
vm.page.loading = false;
});
}
else {
loadDocumentType();
}
function loadDocumentType() {
vm.page.loading = true;
contentTypeResource.getById(documentTypeId).then(function (dt) {
init(dt);
// we don't need to sync the tree in infinite mode
if(!infiniteMode) {
syncTreeNode(vm.contentType, dt.path, true);
}
vm.page.loading = false;
});
}
function loadButtons(buttons) {
angular.forEach(buttons,
function (val, index) {
if (disableTemplates === true && val.alias === "templates") {
buttons.splice(index, 1);
}
});
vm.page.navigation = buttons;
}
/* ---------- SAVE ---------- */
function save() {
//return the saveInternal method but catch rejections since this is the upper most caller
return saveInternal().catch(angular.noop);
}
/** This internal save method performs the actual saving and returns a promise, not to be bound to any buttons but used by other bound methods */
function saveInternal() {
// only save if there is no overlays open
if (overlayHelper.getNumberOfOverlays() === 0) {
vm.page.saveButtonState = "busy";
// reformat allowed content types to array if id's
vm.contentType.allowedContentTypes = contentTypeHelper.createIdArray(vm.contentType.allowedContentTypes);
return contentEditingHelper.contentEditorPerformSave({
saveMethod: contentTypeResource.save,
scope: $scope,
content: vm.contentType,
//We do not redirect on failure for doc types - this is because it is not possible to actually save the doc
// type when server side validation fails - as opposed to content where we are capable of saving the content
// item if server side validation fails
redirectOnFailure: false,
// we need to rebind... the IDs that have been created!
rebindCallback: function (origContentType, savedContentType) {
vm.contentType.id = savedContentType.id;
vm.contentType.groups.forEach(function (group) {
if (!group.name) return;
var k = 0;
while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name)
k++;
if (k == savedContentType.groups.length) {
group.id = 0;
return;
}
var savedGroup = savedContentType.groups[k];
if (!group.id) group.id = savedGroup.id;
group.properties.forEach(function (property) {
if (property.id || !property.alias) return;
k = 0;
while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias)
k++;
if (k == savedGroup.properties.length) {
property.id = 0;
return;
}
var savedProperty = savedGroup.properties[k];
property.id = savedProperty.id;
});
});
}
}).then(function (data) {
//success
// we don't need to sync the tree in infinite mode
if(!infiniteMode) {
syncTreeNode(vm.contentType, data.path);
}
// emit event
var args = { documentType: vm.contentType };
eventsService.emit("editors.documentType.saved", args);
vm.page.saveButtonState = "success";
if(infiniteMode && $scope.model.submit) {
$scope.model.documentTypeAlias = vm.contentType.alias;
$scope.model.submit($scope.model);
}
return $q.resolve(data);
}, function (err) {
//error
if (err) {
editorState.set($scope.content);
}
else {
localizationService.localize("speechBubbles_validationFailedHeader").then(function (headerValue) {
localizationService.localize("speechBubbles_validationFailedMessage").then(function (msgValue) {
notificationsService.error(headerValue, msgValue);
});
});
}
vm.page.saveButtonState = "error";
return $q.reject(err);
});
}
else {
return $q.reject();
}
}
function init(contentType) {
// set all tab to inactive
if (contentType.groups.length !== 0) {
angular.forEach(contentType.groups, function (group) {
angular.forEach(group.properties, function (property) {
// get data type details for each property
getDataTypeDetails(property);
});
});
}
// insert template on new doc types
if (!noTemplate && contentType.id === 0) {
contentType.defaultTemplate = contentTypeHelper.insertDefaultTemplatePlaceholder(contentType.defaultTemplate);
contentType.allowedTemplates = contentTypeHelper.insertTemplatePlaceholder(contentType.allowedTemplates);
}
// convert icons for content type
convertLegacyIcons(contentType);
//set a shared state
editorState.set(contentType);
vm.contentType = contentType;
}
function convertLegacyIcons(contentType) {
// make array to store contentType icon
var contentTypeArray = [];
// push icon to array
contentTypeArray.push({ "icon": contentType.icon });
// run through icon method
iconHelper.formatContentTypeIcons(contentTypeArray);
// set icon back on contentType
contentType.icon = contentTypeArray[0].icon;
}
function getDataTypeDetails(property) {
if (property.propertyState !== "init") {
dataTypeResource.getById(property.dataTypeId)
.then(function (dataType) {
property.dataTypeIcon = dataType.icon;
property.dataTypeName = dataType.name;
});
}
}
/** Syncs the content type to it's tree node - this occurs on first load and after saving */
function syncTreeNode(dt, path, initialLoad) {
navigationService.syncTree({ tree: "documenttypes", path: path.split(","), forceReload: initialLoad !== true }).then(function (syncArgs) {
vm.currentNode = syncArgs.node;
});
}
function close() {
if($scope.model.close) {
$scope.model.close($scope.model);
}
}
evts.push(eventsService.on("app.refreshEditor", function (name, error) {
loadDocumentType();
}));
//ensure to unregister from all events!
$scope.$on('$destroy', function () {
for (var e in evts) {
eventsService.unsubscribe(evts[e]);
}
});
}
angular.module("umbraco").controller("Umbraco.Editors.DocumentTypes.EditController", DocumentTypesEditController);
})();
/**
* @ngdoc controller
* @name Umbraco.Editors.DocumentType.EditController
* @function
*
* @description
* The controller for the content type editor
*/
(function () {
"use strict";
function DocumentTypesEditController($scope, $routeParams, $injector, contentTypeResource, dataTypeResource, editorState, contentEditingHelper, formHelper, navigationService, iconHelper, contentTypeHelper, notificationsService, $filter, $q, localizationService, overlayHelper, eventsService) {
var vm = this;
var evts = [];
var disableTemplates = Umbraco.Sys.ServerVariables.features.disabledFeatures.disableTemplates;
var documentTypeId = $routeParams.id;
var create = $routeParams.create;
var noTemplate = $routeParams.notemplate;
var infiniteMode = $scope.model && $scope.model.infiniteMode;
vm.save = save;
vm.close = close;
vm.currentNode = null;
vm.contentType = {};
vm.labels = {};
vm.submitButtonKey = "buttons_save";
vm.generateModelsKey = "buttons_saveAndGenerateModels";
vm.page = {};
vm.page.loading = false;
vm.page.saveButtonState = "init";
vm.page.navigation = [];
var labelKeys = [
"general_design",
"general_listView",
"general_rights",
"treeHeaders_templates",
"main_sections",
"shortcuts_navigateSections",
"shortcuts_addTab",
"shortcuts_addProperty",
"shortcuts_addEditor",
"shortcuts_editDataType",
"shortcuts_toggleListView",
"shortcuts_toggleAllowAsRoot",
"shortcuts_addChildNode",
"shortcuts_addTemplate"
];
onInit();
function onInit() {
// get init values from model when in infinite mode
if(infiniteMode) {
documentTypeId = $scope.model.id;
create = $scope.model.create;
noTemplate = $scope.model.notemplate;
vm.submitButtonKey = "buttons_saveAndClose";
vm.generateModelsKey = "buttons_generateModelsAndClose";
}
}
localizationService.localizeMany(labelKeys).then(function (values) {
// navigation
vm.labels.design = values[0];
vm.labels.listview = values[1];
vm.labels.permissions = values[2];
vm.labels.templates = values[3];
// keyboard shortcuts
vm.labels.sections = values[4];
vm.labels.navigateSections = values[5];
vm.labels.addTab = values[6];
vm.labels.addProperty = values[7];
vm.labels.addEditor = values[8];
vm.labels.editDataType = values[9];
vm.labels.toggleListView = values[10];
vm.labels.allowAsRoot = values[11];
vm.labels.addChildNode = values[12];
vm.labels.addTemplate = values[13];
var buttons = [
{
"name": vm.labels.design,
"alias": "design",
"icon": "icon-document-dashed-line",
"view": "views/documenttypes/views/design/design.html",
"active": true
},
{
"name": vm.labels.listview,
"alias": "listView",
"icon": "icon-list",
"view": "views/documenttypes/views/listview/listview.html"
},
{
"name": vm.labels.permissions,
"alias": "permissions",
"icon": "icon-keychain",
"view": "views/documenttypes/views/permissions/permissions.html"
},
{
"name": vm.labels.templates,
"alias": "templates",
"icon": "icon-layout",
"view": "views/documenttypes/views/templates/templates.html"
}
];
vm.page.keyboardShortcutsOverview = [
{
"name": vm.labels.sections,
"shortcuts": [
{
"description": vm.labels.navigateSections,
"keys": [{ "key": "1" }, { "key": "4" }],
"keyRange": true
}
]
},
{
"name": vm.labels.design,
"shortcuts": [
{
"description": vm.labels.addTab,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "t" }]
},
{
"description": vm.labels.addProperty,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "p" }]
},
{
"description": vm.labels.addEditor,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "e" }]
},
{
"description": vm.labels.editDataType,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "d" }]
}
]
},
{
"name": vm.labels.listview,
"shortcuts": [
{
"description": vm.labels.toggleListView,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "l" }]
}
]
},
{
"name": vm.labels.permissions,
"shortcuts": [
{
"description": vm.labels.allowAsRoot,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "r" }]
},
{
"description": vm.labels.addChildNode,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "c" }]
}
]
},
{
"name": vm.labels.templates,
"shortcuts": [
{
"description": vm.labels.addTemplate,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "t" }]
}
]
}
];
loadButtons(buttons);
});
contentTypeHelper.checkModelsBuilderStatus().then(function (result) {
vm.page.modelsBuilder = result;
if (result) {
//Models builder mode:
vm.page.defaultButton = {
alias: "save",
hotKey: "ctrl+s",
hotKeyWhenHidden: true,
labelKey: vm.submitButtonKey,
letter: "S",
type: "submit",
handler: function () { vm.save(); }
};
vm.page.subButtons = [{
alias: "saveAndGenerateModels",
hotKey: "ctrl+g",
hotKeyWhenHidden: true,
labelKey: vm.generateModelsKey,
letter: "G",
handler: function () {
vm.page.saveButtonState = "busy";
saveInternal().then(function (result) {
vm.page.saveButtonState = "busy";
localizationService.localize("modelsBuilder_buildingModels").then(function (headerValue) {
localizationService.localize("modelsBuilder_waitingMessage").then(function (msgValue) {
notificationsService.info(headerValue, msgValue);
});
});
contentTypeHelper.generateModels().then(function (result) {
// generateModels() returns the dashboard content
if (!result.lastError) {
//re-check model status
contentTypeHelper.checkModelsBuilderStatus().then(function (statusResult) {
vm.page.modelsBuilder = statusResult;
});
//clear and add success
vm.page.saveButtonState = "init";
localizationService.localize("modelsBuilder_modelsGenerated").then(function (value) {
notificationsService.success(value);
});
} else {
vm.page.saveButtonState = "error";
localizationService.localize("modelsBuilder_modelsExceptionInUlog").then(function (value) {
notificationsService.error(value);
});
}
}, function () {
vm.page.saveButtonState = "error";
localizationService.localize("modelsBuilder_modelsGeneratedError").then(function (value) {
notificationsService.error(value);
});
});
});
}
}];
}
});
if (create) {
vm.page.loading = true;
//we are creating so get an empty data type item
contentTypeResource.getScaffold(documentTypeId)
.then(function (dt) {
init(dt);
vm.page.loading = false;
});
}
else {
loadDocumentType();
}
function loadDocumentType() {
vm.page.loading = true;
contentTypeResource.getById(documentTypeId).then(function (dt) {
init(dt);
// we don't need to sync the tree in infinite mode
if(!infiniteMode) {
syncTreeNode(vm.contentType, dt.path, true);
}
vm.page.loading = false;
});
}
function loadButtons(buttons) {
angular.forEach(buttons,
function (val, index) {
if (disableTemplates === true && val.alias === "templates") {
buttons.splice(index, 1);
}
});
vm.page.navigation = buttons;
}
/* ---------- SAVE ---------- */
function save() {
//return the saveInternal method but catch rejections since this is the upper most caller
return saveInternal().catch(angular.noop);
}
/** This internal save method performs the actual saving and returns a promise, not to be bound to any buttons but used by other bound methods */
function saveInternal() {
// only save if there is no overlays open
if (overlayHelper.getNumberOfOverlays() === 0) {
vm.page.saveButtonState = "busy";
// reformat allowed content types to array if id's
vm.contentType.allowedContentTypes = contentTypeHelper.createIdArray(vm.contentType.allowedContentTypes);
return contentEditingHelper.contentEditorPerformSave({
saveMethod: contentTypeResource.save,
scope: $scope,
content: vm.contentType,
//We do not redirect on failure for doc types - this is because it is not possible to actually save the doc
// type when server side validation fails - as opposed to content where we are capable of saving the content
// item if server side validation fails
redirectOnFailure: false,
// we need to rebind... the IDs that have been created!
rebindCallback: function (origContentType, savedContentType) {
vm.contentType.id = savedContentType.id;
vm.contentType.groups.forEach(function (group) {
if (!group.name) return;
var k = 0;
while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name)
k++;
if (k == savedContentType.groups.length) {
group.id = 0;
return;
}
var savedGroup = savedContentType.groups[k];
if (!group.id) group.id = savedGroup.id;
group.properties.forEach(function (property) {
if (property.id || !property.alias) return;
k = 0;
while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias)
k++;
if (k == savedGroup.properties.length) {
property.id = 0;
return;
}
var savedProperty = savedGroup.properties[k];
property.id = savedProperty.id;
});
});
}
}).then(function (data) {
//success
// we don't need to sync the tree in infinite mode
if(!infiniteMode) {
syncTreeNode(vm.contentType, data.path);
}
// emit event
var args = { documentType: vm.contentType };
eventsService.emit("editors.documentType.saved", args);
vm.page.saveButtonState = "success";
if(infiniteMode && $scope.model.submit) {
$scope.model.documentTypeAlias = vm.contentType.alias;
$scope.model.submit($scope.model);
}
return $q.resolve(data);
}, function (err) {
//error
if (err) {
editorState.set($scope.content);
}
else {
localizationService.localize("speechBubbles_validationFailedHeader").then(function (headerValue) {
localizationService.localize("speechBubbles_validationFailedMessage").then(function (msgValue) {
notificationsService.error(headerValue, msgValue);
});
});
}
vm.page.saveButtonState = "error";
return $q.reject(err);
});
}
else {
return $q.reject();
}
}
function init(contentType) {
// set all tab to inactive
if (contentType.groups.length !== 0) {
angular.forEach(contentType.groups, function (group) {
angular.forEach(group.properties, function (property) {
// get data type details for each property
getDataTypeDetails(property);
});
});
}
// insert template on new doc types
if (!noTemplate && contentType.id === 0) {
contentType.defaultTemplate = contentTypeHelper.insertDefaultTemplatePlaceholder(contentType.defaultTemplate);
contentType.allowedTemplates = contentTypeHelper.insertTemplatePlaceholder(contentType.allowedTemplates);
}
// convert icons for content type
convertLegacyIcons(contentType);
//set a shared state
editorState.set(contentType);
vm.contentType = contentType;
}
function convertLegacyIcons(contentType) {
// make array to store contentType icon
var contentTypeArray = [];
// push icon to array
contentTypeArray.push({ "icon": contentType.icon });
// run through icon method
iconHelper.formatContentTypeIcons(contentTypeArray);
// set icon back on contentType
contentType.icon = contentTypeArray[0].icon;
}
function getDataTypeDetails(property) {
if (property.propertyState !== "init") {
dataTypeResource.getById(property.dataTypeId)
.then(function (dataType) {
property.dataTypeIcon = dataType.icon;
property.dataTypeName = dataType.name;
});
}
}
/** Syncs the content type to it's tree node - this occurs on first load and after saving */
function syncTreeNode(dt, path, initialLoad) {
navigationService.syncTree({ tree: "documenttypes", path: path.split(","), forceReload: initialLoad !== true }).then(function (syncArgs) {
vm.currentNode = syncArgs.node;
});
}
function close() {
if($scope.model.close) {
$scope.model.close($scope.model);
}
}
evts.push(eventsService.on("app.refreshEditor", function (name, error) {
loadDocumentType();
}));
//ensure to unregister from all events!
$scope.$on('$destroy', function () {
for (var e in evts) {
eventsService.unsubscribe(evts[e]);
}
});
}
angular.module("umbraco").controller("Umbraco.Editors.DocumentTypes.EditController", DocumentTypesEditController);
})();

View File

@@ -1,272 +1,272 @@
/**
* @ngdoc controller
* @name Umbraco.Editors.Media.EditController
* @function
*
* @description
* The controller for the media editor
*/
function mediaEditController($scope, $routeParams, $q, appState, mediaResource, entityResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, treeService, formHelper, umbModelMapper, editorState, umbRequestHelper, $http, eventsService) {
var evts = [];
var nodeId = null;
var create = false;
var infiniteMode = $scope.model && $scope.model.infiniteMode;
// when opening the editor through infinite editing get the
// node id from the model instead of the route param
if(infiniteMode && $scope.model.id) {
nodeId = $scope.model.id;
} else {
nodeId = $routeParams.id;
}
// when opening the editor through infinite editing get the
// create option from the model instead of the route param
if(infiniteMode) {
create = $scope.model.create;
} else {
create = $routeParams.create;
}
//setup scope vars
$scope.currentSection = appState.getSectionState("currentSection");
$scope.currentNode = null; //the editors affiliated node
$scope.page = {};
$scope.page.loading = false;
$scope.page.menu = {};
$scope.page.menu.currentSection = appState.getSectionState("currentSection");
$scope.page.menu.currentNode = null; //the editors affiliated node
$scope.page.listViewPath = null;
$scope.page.saveButtonState = "init";
$scope.page.submitButtonLabel = "Save";
/** Syncs the content item to it's tree node - this occurs on first load and after saving */
function syncTreeNode(content, path, initialLoad) {
if (!$scope.content.isChildOfListView) {
navigationService.syncTree({ tree: "media", path: path.split(","), forceReload: initialLoad !== true }).then(function (syncArgs) {
$scope.page.menu.currentNode = syncArgs.node;
});
}
else if (initialLoad === true) {
//it's a child item, just sync the ui node to the parent
navigationService.syncTree({ tree: "media", path: path.substring(0, path.lastIndexOf(",")).split(","), forceReload: initialLoad !== true });
//if this is a child of a list view and it's the initial load of the editor, we need to get the tree node
// from the server so that we can load in the actions menu.
umbRequestHelper.resourcePromise(
$http.get(content.treeNodeUrl),
'Failed to retrieve data for child node ' + content.id).then(function (node) {
$scope.page.menu.currentNode = node;
});
}
}
if (create) {
$scope.page.loading = true;
mediaResource.getScaffold(nodeId, $routeParams.doctype)
.then(function (data) {
$scope.content = data;
editorState.set($scope.content);
// We don't get the info tab from the server from version 7.8 so we need to manually add it
//contentEditingHelper.addInfoTab($scope.content.tabs);
init($scope.content);
$scope.page.loading = false;
});
}
else {
$scope.page.loading = true;
loadMedia()
.then(function(){
$scope.page.loading = false;
});
}
function init(content) {
// prototype content and info apps
var contentApp = {
"name": "Content",
"alias": "content",
"icon": "icon-document",
"view": "views/media/apps/content/content.html"
};
var infoApp = {
"name": "Info",
"alias": "info",
"icon": "icon-info",
"view": "views/media/apps/info/info.html"
};
var listview = {
"name": "Child items",
"alias": "childItems",
"icon": "icon-list",
"view": "views/media/apps/listview/listview.html"
};
$scope.content.apps = [];
if($scope.content.contentTypeAlias === "Folder") {
// add list view app
$scope.content.apps.push(listview);
// remove the list view tab
angular.forEach($scope.content.tabs, function(tab, index){
if(tab.alias === "Contents") {
tab.hide = true;
}
});
} else {
$scope.content.apps.push(contentApp);
}
$scope.content.apps.push(infoApp);
// set first app to active
$scope.content.apps[0].active = true;
// setup infinite mode
if(infiniteMode) {
$scope.page.submitButtonLabel = "Save and Close";
}
}
$scope.save = function () {
if (!$scope.busy && formHelper.submitForm({ scope: $scope })) {
$scope.busy = true;
$scope.page.saveButtonState = "busy";
mediaResource.save($scope.content, create, fileManager.getFiles())
.then(function(data) {
formHelper.resetForm({ scope: $scope });
contentEditingHelper.handleSuccessfulSave({
scope: $scope,
savedContent: data,
redirectOnSuccess: !infiniteMode,
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
});
editorState.set($scope.content);
$scope.busy = false;
// when don't want to sync the tree when the editor is open in infinite mode
if(!infiniteMode) {
syncTreeNode($scope.content, data.path);
}
init($scope.content);
$scope.page.saveButtonState = "success";
// close the editor if it's infinite mode
if(infiniteMode && $scope.model.submit) {
$scope.model.mediaNode = $scope.content;
$scope.model.submit($scope.model);
}
}, function(err) {
contentEditingHelper.handleSaveError({
err: err,
redirectOnError: !infiniteMode,
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data)
});
editorState.set($scope.content);
$scope.busy = false;
$scope.page.saveButtonState = "error";
});
}else{
$scope.busy = false;
}
};
function loadMedia() {
return mediaResource.getById(nodeId)
.then(function (data) {
$scope.content = data;
if (data.isChildOfListView && data.trashed === false) {
$scope.page.listViewPath = ($routeParams.page)
? "/media/media/edit/" + data.parentId + "?page=" + $routeParams.page
: "/media/media/edit/" + data.parentId;
}
editorState.set($scope.content);
//in one particular special case, after we've created a new item we redirect back to the edit
// route but there might be server validation errors in the collection which we need to display
// after the redirect, so we will bind all subscriptions which will show the server validation errors
// if there are any and then clear them so the collection no longer persists them.
serverValidationManager.executeAndClearAllSubscriptions();
if(!infiniteMode) {
syncTreeNode($scope.content, data.path, true);
}
if ($scope.content.parentId && $scope.content.parentId != -1) {
//We fetch all ancestors of the node to generate the footer breadcrump navigation
entityResource.getAncestors(nodeId, "media")
.then(function (anc) {
$scope.ancestors = anc;
});
}
// We don't get the info tab from the server from version 7.8 so we need to manually add it
//contentEditingHelper.addInfoTab($scope.content.tabs);
init($scope.content);
$scope.page.loading = false;
$q.resolve($scope.content);
});
}
$scope.close = function() {
if($scope.model.close) {
$scope.model.close($scope.model);
}
};
evts.push(eventsService.on("editors.mediaType.saved", function(name, args) {
// if this media item uses the updated media type we need to reload the media item
if(args && args.mediaType && args.mediaType.key === $scope.content.contentType.key) {
loadMedia();
}
}));
//ensure to unregister from all events!
$scope.$on('$destroy', function () {
for (var e in evts) {
eventsService.unsubscribe(evts[e]);
}
});
}
angular.module("umbraco").controller("Umbraco.Editors.Media.EditController", mediaEditController);
/**
* @ngdoc controller
* @name Umbraco.Editors.Media.EditController
* @function
*
* @description
* The controller for the media editor
*/
function mediaEditController($scope, $routeParams, $q, appState, mediaResource, entityResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, fileManager, treeService, formHelper, umbModelMapper, editorState, umbRequestHelper, $http, eventsService) {
var evts = [];
var nodeId = null;
var create = false;
var infiniteMode = $scope.model && $scope.model.infiniteMode;
// when opening the editor through infinite editing get the
// node id from the model instead of the route param
if(infiniteMode && $scope.model.id) {
nodeId = $scope.model.id;
} else {
nodeId = $routeParams.id;
}
// when opening the editor through infinite editing get the
// create option from the model instead of the route param
if(infiniteMode) {
create = $scope.model.create;
} else {
create = $routeParams.create;
}
//setup scope vars
$scope.currentSection = appState.getSectionState("currentSection");
$scope.currentNode = null; //the editors affiliated node
$scope.page = {};
$scope.page.loading = false;
$scope.page.menu = {};
$scope.page.menu.currentSection = appState.getSectionState("currentSection");
$scope.page.menu.currentNode = null; //the editors affiliated node
$scope.page.listViewPath = null;
$scope.page.saveButtonState = "init";
$scope.page.submitButtonLabel = "Save";
/** Syncs the content item to it's tree node - this occurs on first load and after saving */
function syncTreeNode(content, path, initialLoad) {
if (!$scope.content.isChildOfListView) {
navigationService.syncTree({ tree: "media", path: path.split(","), forceReload: initialLoad !== true }).then(function (syncArgs) {
$scope.page.menu.currentNode = syncArgs.node;
});
}
else if (initialLoad === true) {
//it's a child item, just sync the ui node to the parent
navigationService.syncTree({ tree: "media", path: path.substring(0, path.lastIndexOf(",")).split(","), forceReload: initialLoad !== true });
//if this is a child of a list view and it's the initial load of the editor, we need to get the tree node
// from the server so that we can load in the actions menu.
umbRequestHelper.resourcePromise(
$http.get(content.treeNodeUrl),
'Failed to retrieve data for child node ' + content.id).then(function (node) {
$scope.page.menu.currentNode = node;
});
}
}
if (create) {
$scope.page.loading = true;
mediaResource.getScaffold(nodeId, $routeParams.doctype)
.then(function (data) {
$scope.content = data;
editorState.set($scope.content);
// We don't get the info tab from the server from version 7.8 so we need to manually add it
//contentEditingHelper.addInfoTab($scope.content.tabs);
init($scope.content);
$scope.page.loading = false;
});
}
else {
$scope.page.loading = true;
loadMedia()
.then(function(){
$scope.page.loading = false;
});
}
function init(content) {
// prototype content and info apps
var contentApp = {
"name": "Content",
"alias": "content",
"icon": "icon-document",
"view": "views/media/apps/content/content.html"
};
var infoApp = {
"name": "Info",
"alias": "info",
"icon": "icon-info",
"view": "views/media/apps/info/info.html"
};
var listview = {
"name": "Child items",
"alias": "childItems",
"icon": "icon-list",
"view": "views/media/apps/listview/listview.html"
};
$scope.content.apps = [];
if($scope.content.contentTypeAlias === "Folder") {
// add list view app
$scope.content.apps.push(listview);
// remove the list view tab
angular.forEach($scope.content.tabs, function(tab, index){
if(tab.alias === "Contents") {
tab.hide = true;
}
});
} else {
$scope.content.apps.push(contentApp);
}
$scope.content.apps.push(infoApp);
// set first app to active
$scope.content.apps[0].active = true;
// setup infinite mode
if(infiniteMode) {
$scope.page.submitButtonLabel = "Save and Close";
}
}
$scope.save = function () {
if (!$scope.busy && formHelper.submitForm({ scope: $scope })) {
$scope.busy = true;
$scope.page.saveButtonState = "busy";
mediaResource.save($scope.content, create, fileManager.getFiles())
.then(function(data) {
formHelper.resetForm({ scope: $scope });
contentEditingHelper.handleSuccessfulSave({
scope: $scope,
savedContent: data,
redirectOnSuccess: !infiniteMode,
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data)
});
editorState.set($scope.content);
$scope.busy = false;
// when don't want to sync the tree when the editor is open in infinite mode
if(!infiniteMode) {
syncTreeNode($scope.content, data.path);
}
init($scope.content);
$scope.page.saveButtonState = "success";
// close the editor if it's infinite mode
if(infiniteMode && $scope.model.submit) {
$scope.model.mediaNode = $scope.content;
$scope.model.submit($scope.model);
}
}, function(err) {
contentEditingHelper.handleSaveError({
err: err,
redirectOnError: !infiniteMode,
rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data)
});
editorState.set($scope.content);
$scope.busy = false;
$scope.page.saveButtonState = "error";
});
}else{
$scope.busy = false;
}
};
function loadMedia() {
return mediaResource.getById(nodeId)
.then(function (data) {
$scope.content = data;
if (data.isChildOfListView && data.trashed === false) {
$scope.page.listViewPath = ($routeParams.page)
? "/media/media/edit/" + data.parentId + "?page=" + $routeParams.page
: "/media/media/edit/" + data.parentId;
}
editorState.set($scope.content);
//in one particular special case, after we've created a new item we redirect back to the edit
// route but there might be server validation errors in the collection which we need to display
// after the redirect, so we will bind all subscriptions which will show the server validation errors
// if there are any and then clear them so the collection no longer persists them.
serverValidationManager.executeAndClearAllSubscriptions();
if(!infiniteMode) {
syncTreeNode($scope.content, data.path, true);
}
if ($scope.content.parentId && $scope.content.parentId != -1) {
//We fetch all ancestors of the node to generate the footer breadcrump navigation
entityResource.getAncestors(nodeId, "media")
.then(function (anc) {
$scope.ancestors = anc;
});
}
// We don't get the info tab from the server from version 7.8 so we need to manually add it
//contentEditingHelper.addInfoTab($scope.content.tabs);
init($scope.content);
$scope.page.loading = false;
$q.resolve($scope.content);
});
}
$scope.close = function() {
if($scope.model.close) {
$scope.model.close($scope.model);
}
};
evts.push(eventsService.on("editors.mediaType.saved", function(name, args) {
// if this media item uses the updated media type we need to reload the media item
if(args && args.mediaType && args.mediaType.key === $scope.content.contentType.key) {
loadMedia();
}
}));
//ensure to unregister from all events!
$scope.$on('$destroy', function () {
for (var e in evts) {
eventsService.unsubscribe(evts[e]);
}
});
}
angular.module("umbraco").controller("Umbraco.Editors.Media.EditController", mediaEditController);

View File

@@ -1,419 +1,419 @@
/**
* @ngdoc controller
* @name Umbraco.Editors.MediaType.EditController
* @function
*
* @description
* The controller for the media type editor
*/
(function () {
"use strict";
function MediaTypesEditController($scope, $routeParams, mediaTypeResource, dataTypeResource, editorState, contentEditingHelper, formHelper, navigationService, iconHelper, contentTypeHelper, notificationsService, $filter, $q, localizationService, overlayHelper, eventsService) {
var vm = this;
var evts = [];
var mediaTypeId = $routeParams.id;
var create = $routeParams.create;
var infiniteMode = $scope.model && $scope.model.infiniteMode;
vm.save = save;
vm.close = close;
vm.currentNode = null;
vm.contentType = {};
vm.page = {};
vm.page.loading = false;
vm.page.saveButtonState = "init";
vm.labels = {};
vm.saveButtonKey = "buttons_save";
vm.generateModelsKey = "buttons_saveAndGenerateModels";
onInit();
function onInit() {
// get init values from model when in infinite mode
if(infiniteMode) {
mediaTypeId = $scope.model.id;
create = $scope.model.create;
vm.saveButtonKey = "buttons_saveAndClose";
vm.generateModelsKey = "buttons_generateModelsAndClose";
}
}
var labelKeys = [
"general_design",
"general_listView",
"general_rights",
"main_sections",
"shortcuts_navigateSections",
"shortcuts_addTab",
"shortcuts_addProperty",
"shortcuts_addEditor",
"shortcuts_editDataType",
"shortcuts_toggleListView",
"shortcuts_toggleAllowAsRoot",
"shortcuts_addChildNode"
];
localizationService.localizeMany(labelKeys).then(function (values) {
// navigation
vm.labels.design = values[0];
vm.labels.listview = values[1];
vm.labels.permissions = values[2];
// keyboard shortcuts
vm.labels.sections = values[3];
vm.labels.navigateSections = values[4];
vm.labels.addTab = values[5];
vm.labels.addProperty = values[6];
vm.labels.addEditor = values[7];
vm.labels.editDataType = values[8];
vm.labels.toggleListView = values[9];
vm.labels.allowAsRoot = values[10];
vm.labels.addChildNode = values[11];
vm.page.navigation = [
{
"name": vm.labels.design,
"icon": "icon-document-dashed-line",
"view": "views/mediatypes/views/design/design.html",
"active": true
},
{
"name": vm.labels.listview,
"icon": "icon-list",
"view": "views/mediatypes/views/listview/listview.html"
},
{
"name": vm.labels.permissions,
"icon": "icon-keychain",
"view": "views/mediatypes/views/permissions/permissions.html"
}
];
vm.page.keyboardShortcutsOverview = [
{
"name": vm.labels.sections,
"shortcuts": [
{
"description": vm.labels.navigateSections,
"keys": [{ "key": "1" }, { "key": "3" }],
"keyRange": true
}
]
},
{
"name": vm.labels.design,
"shortcuts": [
{
"description": vm.labels.addTab,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "t" }]
},
{
"description": vm.labels.addProperty,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "p" }]
},
{
"description": vm.labels.addEditor,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "e" }]
},
{
"description": vm.labels.editDataType,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "d" }]
}
]
},
{
"name": vm.labels.listview,
"shortcuts": [
{
"description": vm.labels.toggleListView,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "l" }]
}
]
},
{
"name": vm.labels.permissions,
"shortcuts": [
{
"description": vm.labels.allowAsRoot,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "r" }]
},
{
"description": vm.labels.addChildNode,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "c" }]
}
]
}
];
});
contentTypeHelper.checkModelsBuilderStatus().then(function (result) {
vm.page.modelsBuilder = result;
if (result) {
//Models builder mode:
vm.page.defaultButton = {
hotKey: "ctrl+s",
hotKeyWhenHidden: true,
labelKey: vm.saveButtonKey,
letter: "S",
type: "submit",
handler: function () { vm.save(); }
};
vm.page.subButtons = [{
hotKey: "ctrl+g",
hotKeyWhenHidden: true,
labelKey: vm.generateModelsKey,
letter: "G",
handler: function () {
vm.page.saveButtonState = "busy";
vm.save().then(function (result) {
vm.page.saveButtonState = "busy";
localizationService.localize("modelsBuilder_buildingModels").then(function (headerValue) {
localizationService.localize("modelsBuilder_waitingMessage").then(function(msgValue) {
notificationsService.info(headerValue, msgValue);
});
});
contentTypeHelper.generateModels().then(function (result) {
if (result.success) {
//re-check model status
contentTypeHelper.checkModelsBuilderStatus().then(function (statusResult) {
vm.page.modelsBuilder = statusResult;
});
//clear and add success
vm.page.saveButtonState = "init";
localizationService.localize("modelsBuilder_modelsGenerated").then(function(value) {
notificationsService.success(value);
});
} else {
vm.page.saveButtonState = "error";
localizationService.localize("modelsBuilder_modelsExceptionInUlog").then(function(value) {
notificationsService.error(value);
});
}
}, function () {
vm.page.saveButtonState = "error";
localizationService.localize("modelsBuilder_modelsGeneratedError").then(function(value) {
notificationsService.error(value);
});
});
});
}
}];
}
});
if (create) {
vm.page.loading = true;
//we are creating so get an empty data type item
mediaTypeResource.getScaffold(mediaTypeId)
.then(function(dt) {
init(dt);
vm.page.loading = false;
});
}
else {
loadMediaType();
}
function loadMediaType() {
vm.page.loading = true;
mediaTypeResource.getById(mediaTypeId).then(function(dt) {
init(dt);
if(!infiniteMode) {
syncTreeNode(vm.contentType, dt.path, true);
}
vm.page.loading = false;
});
}
/* ---------- SAVE ---------- */
function save() {
// only save if there is no overlays open
if(overlayHelper.getNumberOfOverlays() === 0) {
var deferred = $q.defer();
vm.page.saveButtonState = "busy";
// reformat allowed content types to array if id's
vm.contentType.allowedContentTypes = contentTypeHelper.createIdArray(vm.contentType.allowedContentTypes);
contentEditingHelper.contentEditorPerformSave({
saveMethod: mediaTypeResource.save,
scope: $scope,
content: vm.contentType,
//We do not redirect on failure for doc types - this is because it is not possible to actually save the doc
// type when server side validation fails - as opposed to content where we are capable of saving the content
// item if server side validation fails
redirectOnFailure: false,
// we need to rebind... the IDs that have been created!
rebindCallback: function (origContentType, savedContentType) {
vm.contentType.id = savedContentType.id;
vm.contentType.groups.forEach(function (group) {
if (!group.name) return;
var k = 0;
while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name)
k++;
if (k == savedContentType.groups.length) {
group.id = 0;
return;
}
var savedGroup = savedContentType.groups[k];
if (!group.id) group.id = savedGroup.id;
group.properties.forEach(function (property) {
if (property.id || !property.alias) return;
k = 0;
while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias)
k++;
if (k == savedGroup.properties.length) {
property.id = 0;
return;
}
var savedProperty = savedGroup.properties[k];
property.id = savedProperty.id;
});
});
}
}).then(function (data) {
//success
if(!infiniteMode) {
syncTreeNode(vm.contentType, data.path);
}
// emit event
var args = { mediaType: vm.contentType };
eventsService.emit("editors.mediaType.saved", args);
vm.page.saveButtonState = "success";
if(infiniteMode && $scope.model.submit) {
$scope.model.submit();
}
deferred.resolve(data);
}, function (err) {
//error
if (err) {
editorState.set($scope.content);
}
else {
localizationService.localize("speechBubbles_validationFailedHeader").then(function (headerValue) {
localizationService.localize("speechBubbles_validationFailedMessage").then(function (msgValue) {
notificationsService.error(headerValue, msgValue);
});
});
}
vm.page.saveButtonState = "error";
deferred.reject(err);
});
return deferred.promise;
}
}
function init(contentType) {
// set all tab to inactive
if (contentType.groups.length !== 0) {
angular.forEach(contentType.groups, function (group) {
angular.forEach(group.properties, function (property) {
// get data type details for each property
getDataTypeDetails(property);
});
});
}
// convert icons for content type
convertLegacyIcons(contentType);
//set a shared state
editorState.set(contentType);
vm.contentType = contentType;
}
function convertLegacyIcons(contentType) {
// make array to store contentType icon
var contentTypeArray = [];
// push icon to array
contentTypeArray.push({ "icon": contentType.icon });
// run through icon method
iconHelper.formatContentTypeIcons(contentTypeArray);
// set icon back on contentType
contentType.icon = contentTypeArray[0].icon;
}
function getDataTypeDetails(property) {
if (property.propertyState !== "init") {
dataTypeResource.getById(property.dataTypeId)
.then(function(dataType) {
property.dataTypeIcon = dataType.icon;
property.dataTypeName = dataType.name;
});
}
}
/** Syncs the content type to it's tree node - this occurs on first load and after saving */
function syncTreeNode(dt, path, initialLoad) {
navigationService.syncTree({ tree: "mediatypes", path: path.split(","), forceReload: initialLoad !== true }).then(function(syncArgs) {
vm.currentNode = syncArgs.node;
});
}
function close() {
if(infiniteMode && $scope.model.close) {
$scope.model.close();
}
}
evts.push(eventsService.on("app.refreshEditor", function(name, error) {
loadMediaType();
}));
//ensure to unregister from all events!
$scope.$on('$destroy', function () {
for (var e in evts) {
eventsService.unsubscribe(evts[e]);
}
});
}
angular.module("umbraco").controller("Umbraco.Editors.MediaTypes.EditController", MediaTypesEditController);
})();
/**
* @ngdoc controller
* @name Umbraco.Editors.MediaType.EditController
* @function
*
* @description
* The controller for the media type editor
*/
(function () {
"use strict";
function MediaTypesEditController($scope, $routeParams, mediaTypeResource, dataTypeResource, editorState, contentEditingHelper, formHelper, navigationService, iconHelper, contentTypeHelper, notificationsService, $filter, $q, localizationService, overlayHelper, eventsService) {
var vm = this;
var evts = [];
var mediaTypeId = $routeParams.id;
var create = $routeParams.create;
var infiniteMode = $scope.model && $scope.model.infiniteMode;
vm.save = save;
vm.close = close;
vm.currentNode = null;
vm.contentType = {};
vm.page = {};
vm.page.loading = false;
vm.page.saveButtonState = "init";
vm.labels = {};
vm.saveButtonKey = "buttons_save";
vm.generateModelsKey = "buttons_saveAndGenerateModels";
onInit();
function onInit() {
// get init values from model when in infinite mode
if(infiniteMode) {
mediaTypeId = $scope.model.id;
create = $scope.model.create;
vm.saveButtonKey = "buttons_saveAndClose";
vm.generateModelsKey = "buttons_generateModelsAndClose";
}
}
var labelKeys = [
"general_design",
"general_listView",
"general_rights",
"main_sections",
"shortcuts_navigateSections",
"shortcuts_addTab",
"shortcuts_addProperty",
"shortcuts_addEditor",
"shortcuts_editDataType",
"shortcuts_toggleListView",
"shortcuts_toggleAllowAsRoot",
"shortcuts_addChildNode"
];
localizationService.localizeMany(labelKeys).then(function (values) {
// navigation
vm.labels.design = values[0];
vm.labels.listview = values[1];
vm.labels.permissions = values[2];
// keyboard shortcuts
vm.labels.sections = values[3];
vm.labels.navigateSections = values[4];
vm.labels.addTab = values[5];
vm.labels.addProperty = values[6];
vm.labels.addEditor = values[7];
vm.labels.editDataType = values[8];
vm.labels.toggleListView = values[9];
vm.labels.allowAsRoot = values[10];
vm.labels.addChildNode = values[11];
vm.page.navigation = [
{
"name": vm.labels.design,
"icon": "icon-document-dashed-line",
"view": "views/mediatypes/views/design/design.html",
"active": true
},
{
"name": vm.labels.listview,
"icon": "icon-list",
"view": "views/mediatypes/views/listview/listview.html"
},
{
"name": vm.labels.permissions,
"icon": "icon-keychain",
"view": "views/mediatypes/views/permissions/permissions.html"
}
];
vm.page.keyboardShortcutsOverview = [
{
"name": vm.labels.sections,
"shortcuts": [
{
"description": vm.labels.navigateSections,
"keys": [{ "key": "1" }, { "key": "3" }],
"keyRange": true
}
]
},
{
"name": vm.labels.design,
"shortcuts": [
{
"description": vm.labels.addTab,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "t" }]
},
{
"description": vm.labels.addProperty,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "p" }]
},
{
"description": vm.labels.addEditor,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "e" }]
},
{
"description": vm.labels.editDataType,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "d" }]
}
]
},
{
"name": vm.labels.listview,
"shortcuts": [
{
"description": vm.labels.toggleListView,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "l" }]
}
]
},
{
"name": vm.labels.permissions,
"shortcuts": [
{
"description": vm.labels.allowAsRoot,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "r" }]
},
{
"description": vm.labels.addChildNode,
"keys": [{ "key": "alt" }, { "key": "shift" }, { "key": "c" }]
}
]
}
];
});
contentTypeHelper.checkModelsBuilderStatus().then(function (result) {
vm.page.modelsBuilder = result;
if (result) {
//Models builder mode:
vm.page.defaultButton = {
hotKey: "ctrl+s",
hotKeyWhenHidden: true,
labelKey: vm.saveButtonKey,
letter: "S",
type: "submit",
handler: function () { vm.save(); }
};
vm.page.subButtons = [{
hotKey: "ctrl+g",
hotKeyWhenHidden: true,
labelKey: vm.generateModelsKey,
letter: "G",
handler: function () {
vm.page.saveButtonState = "busy";
vm.save().then(function (result) {
vm.page.saveButtonState = "busy";
localizationService.localize("modelsBuilder_buildingModels").then(function (headerValue) {
localizationService.localize("modelsBuilder_waitingMessage").then(function(msgValue) {
notificationsService.info(headerValue, msgValue);
});
});
contentTypeHelper.generateModels().then(function (result) {
if (result.success) {
//re-check model status
contentTypeHelper.checkModelsBuilderStatus().then(function (statusResult) {
vm.page.modelsBuilder = statusResult;
});
//clear and add success
vm.page.saveButtonState = "init";
localizationService.localize("modelsBuilder_modelsGenerated").then(function(value) {
notificationsService.success(value);
});
} else {
vm.page.saveButtonState = "error";
localizationService.localize("modelsBuilder_modelsExceptionInUlog").then(function(value) {
notificationsService.error(value);
});
}
}, function () {
vm.page.saveButtonState = "error";
localizationService.localize("modelsBuilder_modelsGeneratedError").then(function(value) {
notificationsService.error(value);
});
});
});
}
}];
}
});
if (create) {
vm.page.loading = true;
//we are creating so get an empty data type item
mediaTypeResource.getScaffold(mediaTypeId)
.then(function(dt) {
init(dt);
vm.page.loading = false;
});
}
else {
loadMediaType();
}
function loadMediaType() {
vm.page.loading = true;
mediaTypeResource.getById(mediaTypeId).then(function(dt) {
init(dt);
if(!infiniteMode) {
syncTreeNode(vm.contentType, dt.path, true);
}
vm.page.loading = false;
});
}
/* ---------- SAVE ---------- */
function save() {
// only save if there is no overlays open
if(overlayHelper.getNumberOfOverlays() === 0) {
var deferred = $q.defer();
vm.page.saveButtonState = "busy";
// reformat allowed content types to array if id's
vm.contentType.allowedContentTypes = contentTypeHelper.createIdArray(vm.contentType.allowedContentTypes);
contentEditingHelper.contentEditorPerformSave({
saveMethod: mediaTypeResource.save,
scope: $scope,
content: vm.contentType,
//We do not redirect on failure for doc types - this is because it is not possible to actually save the doc
// type when server side validation fails - as opposed to content where we are capable of saving the content
// item if server side validation fails
redirectOnFailure: false,
// we need to rebind... the IDs that have been created!
rebindCallback: function (origContentType, savedContentType) {
vm.contentType.id = savedContentType.id;
vm.contentType.groups.forEach(function (group) {
if (!group.name) return;
var k = 0;
while (k < savedContentType.groups.length && savedContentType.groups[k].name != group.name)
k++;
if (k == savedContentType.groups.length) {
group.id = 0;
return;
}
var savedGroup = savedContentType.groups[k];
if (!group.id) group.id = savedGroup.id;
group.properties.forEach(function (property) {
if (property.id || !property.alias) return;
k = 0;
while (k < savedGroup.properties.length && savedGroup.properties[k].alias != property.alias)
k++;
if (k == savedGroup.properties.length) {
property.id = 0;
return;
}
var savedProperty = savedGroup.properties[k];
property.id = savedProperty.id;
});
});
}
}).then(function (data) {
//success
if(!infiniteMode) {
syncTreeNode(vm.contentType, data.path);
}
// emit event
var args = { mediaType: vm.contentType };
eventsService.emit("editors.mediaType.saved", args);
vm.page.saveButtonState = "success";
if(infiniteMode && $scope.model.submit) {
$scope.model.submit();
}
deferred.resolve(data);
}, function (err) {
//error
if (err) {
editorState.set($scope.content);
}
else {
localizationService.localize("speechBubbles_validationFailedHeader").then(function (headerValue) {
localizationService.localize("speechBubbles_validationFailedMessage").then(function (msgValue) {
notificationsService.error(headerValue, msgValue);
});
});
}
vm.page.saveButtonState = "error";
deferred.reject(err);
});
return deferred.promise;
}
}
function init(contentType) {
// set all tab to inactive
if (contentType.groups.length !== 0) {
angular.forEach(contentType.groups, function (group) {
angular.forEach(group.properties, function (property) {
// get data type details for each property
getDataTypeDetails(property);
});
});
}
// convert icons for content type
convertLegacyIcons(contentType);
//set a shared state
editorState.set(contentType);
vm.contentType = contentType;
}
function convertLegacyIcons(contentType) {
// make array to store contentType icon
var contentTypeArray = [];
// push icon to array
contentTypeArray.push({ "icon": contentType.icon });
// run through icon method
iconHelper.formatContentTypeIcons(contentTypeArray);
// set icon back on contentType
contentType.icon = contentTypeArray[0].icon;
}
function getDataTypeDetails(property) {
if (property.propertyState !== "init") {
dataTypeResource.getById(property.dataTypeId)
.then(function(dataType) {
property.dataTypeIcon = dataType.icon;
property.dataTypeName = dataType.name;
});
}
}
/** Syncs the content type to it's tree node - this occurs on first load and after saving */
function syncTreeNode(dt, path, initialLoad) {
navigationService.syncTree({ tree: "mediatypes", path: path.split(","), forceReload: initialLoad !== true }).then(function(syncArgs) {
vm.currentNode = syncArgs.node;
});
}
function close() {
if(infiniteMode && $scope.model.close) {
$scope.model.close();
}
}
evts.push(eventsService.on("app.refreshEditor", function(name, error) {
loadMediaType();
}));
//ensure to unregister from all events!
$scope.$on('$destroy', function () {
for (var e in evts) {
eventsService.unsubscribe(evts[e]);
}
});
}
angular.module("umbraco").controller("Umbraco.Editors.MediaTypes.EditController", MediaTypesEditController);
})();

File diff suppressed because it is too large Load Diff