346 lines
17 KiB
JavaScript
346 lines
17 KiB
JavaScript
"use strict";
|
|
/**
|
|
* Created by sun chu on 02/11/2015.
|
|
*/
|
|
(function () {
|
|
'use strict';
|
|
angular.module('adminModule')
|
|
.controller('KnowledgeStyleConfigController', ['$scope', 'knowledgeArticleModel', 'systemAlertService', '$filter',
|
|
function ($scope, knowledgeArticleModel, systemAlertService, $filter) {
|
|
var state = {}, dirtyState = {}, originalTemplate = {}, originalStyle = {}, styleMetadata = {
|
|
fontSize: [
|
|
{ label: '8', value: '8px' },
|
|
{ label: '9', value: '9px' },
|
|
{ label: '10', value: '10px' },
|
|
{ label: '11', value: '11px' },
|
|
{ label: '12', value: '12px' },
|
|
{ label: '14', value: '14px' },
|
|
{ label: '16', value: '16px' },
|
|
{ label: '18', value: '18px' },
|
|
{ label: '20', value: '20px' },
|
|
{ label: '22', value: '22px' },
|
|
{ label: '24', value: '24px' },
|
|
{ label: '26', value: '26px' },
|
|
{ label: '28', value: '28px' },
|
|
{ label: '36', value: '36px' },
|
|
{ label: '48', value: '48px' },
|
|
{ label: '72', value: '72px' }
|
|
],
|
|
font: [
|
|
{ label: 'Times', value: 'times' },
|
|
{ label: 'Arial', value: 'arial' },
|
|
{ label: 'Courier', value: 'courier' }
|
|
],
|
|
element: [
|
|
'span',
|
|
'div'
|
|
]
|
|
}, standardStyles = [
|
|
{ type: 'Header 1', element: 'h1', text: '', styles: '', userStyle: false },
|
|
{ type: 'Header 2', element: 'h2', text: '', styles: '', userStyle: false },
|
|
{ type: 'Header 3', element: 'h3', text: '', styles: '', userStyle: false },
|
|
{ type: 'Header 4', element: 'h4', text: '', styles: '', userStyle: false },
|
|
{ type: 'Header 5', element: 'h5', text: '', styles: '', userStyle: false },
|
|
{ type: 'Header 6', element: 'h6', text: '', styles: '', userStyle: false },
|
|
{ type: 'Paragraph', element: 'p', text: '', styles: '', userStyle: false }
|
|
];
|
|
$scope.selectedTemplate = {};
|
|
$scope.selectedStyle = {};
|
|
$scope.selected_css = {};
|
|
$scope.additional = { style: '' };
|
|
$scope.isDirtyState = false;
|
|
function init() {
|
|
state = angular.extend(state, {
|
|
dataIsLoading: false
|
|
});
|
|
$scope.state = state;
|
|
$scope.styleMetadata = styleMetadata;
|
|
clearSelected_css();
|
|
loadAvailableTemplates();
|
|
}
|
|
function loadAvailableTemplates() {
|
|
state.dataIsLoading = true;
|
|
knowledgeArticleModel.getKnowledgeArticleTemplates().then(function (templates) {
|
|
$scope.templates = angular.copy(templates);
|
|
_.remove($scope.templates, { name: 'Decision Tree' });
|
|
}).finally(function () {
|
|
state.dataIsLoading = false;
|
|
});
|
|
}
|
|
$scope.selectTemplate = function (template) {
|
|
if (template.name === $scope.selectedTemplate.name) {
|
|
return;
|
|
}
|
|
if ($scope.isDirtyState) {
|
|
showLeaveDialog().then(function (confirmToDiscard) {
|
|
if (confirmToDiscard) {
|
|
originalTemplate = template;
|
|
setSelectedTemplate(template);
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
originalTemplate = template;
|
|
setSelectedTemplate(template);
|
|
}
|
|
};
|
|
$scope.selectStyle = function (style) {
|
|
if (style.isExpanded) {
|
|
style.isExpanded = false;
|
|
$scope.selectedStyle = {};
|
|
}
|
|
else {
|
|
$scope.selectedStyle.isExpanded = false;
|
|
$scope.selectedStyle = style;
|
|
style.isExpanded = true;
|
|
parse_css(style.styles);
|
|
formulate_css();
|
|
// save a copy for dirty check
|
|
if (!originalStyle[style.type]) {
|
|
originalStyle[style.type] = {
|
|
styles: $scope.selectedStyle.styles,
|
|
element: $scope.selectedStyle.element
|
|
};
|
|
}
|
|
}
|
|
};
|
|
$scope.deleteStyle = function (index, $event) {
|
|
$scope.selectedTemplate.templateObject.styles.splice(index, 1);
|
|
$scope.isDirtyState = true;
|
|
$event.stopPropagation();
|
|
};
|
|
$scope.addStyle = function () {
|
|
var defaultStyle = { type: '', element: 'span', text: '', styles: '', userStyle: true };
|
|
$scope.selectedTemplate.templateObject.styles.push(defaultStyle);
|
|
$scope.selectStyle(defaultStyle);
|
|
$scope.isDirtyState = true;
|
|
};
|
|
$scope.updateElement = function (element) {
|
|
$scope.selectedStyle.element = element || '';
|
|
dirtyStateCheck();
|
|
};
|
|
$scope.updateFont = function (font) {
|
|
$scope.selected_css.fontFamily.label = font ? font.label : '';
|
|
$scope.selected_css.fontFamily.value = font ? font.value : '';
|
|
formulate_css();
|
|
dirtyStateCheck();
|
|
};
|
|
$scope.updateFontSize = function (fontSize) {
|
|
$scope.selected_css.fontSize.label = fontSize ? fontSize.label : '';
|
|
$scope.selected_css.fontSize.value = fontSize ? fontSize.value : '';
|
|
formulate_css();
|
|
dirtyStateCheck();
|
|
};
|
|
$scope.updateFontWeight = function () {
|
|
$scope.selected_css.fontWeight.value = $scope.selected_css.fontWeight.bold ? 'bold' : '';
|
|
formulate_css();
|
|
dirtyStateCheck();
|
|
};
|
|
$scope.updateFontStyle = function () {
|
|
$scope.selected_css.fontStyle.value = $scope.selected_css.fontStyle.italic ? 'italic' : '';
|
|
formulate_css();
|
|
dirtyStateCheck();
|
|
};
|
|
$scope.updateTextDecoration = function () {
|
|
$scope.selected_css.textDecoration.value = '';
|
|
$scope.selected_css.textDecoration.value += $scope.selected_css.textDecoration.underline ? 'underline ' : '';
|
|
$scope.selected_css.textDecoration.value += $scope.selected_css.textDecoration.lineThrough ? 'line-through' : '';
|
|
$scope.selected_css.textDecoration.value = $scope.selected_css.textDecoration.value.trim();
|
|
formulate_css();
|
|
dirtyStateCheck();
|
|
};
|
|
$scope.update_css = function () {
|
|
formulate_css();
|
|
dirtyStateCheck();
|
|
};
|
|
$scope.saveStyles = function () {
|
|
// check to make sure style name is unique
|
|
var unique = true;
|
|
_.each($scope.selectedTemplate.templateObject.styles, function (style, index) {
|
|
if (_.find($scope.selectedTemplate.templateObject.styles.slice(index + 1), { type: style.type })) {
|
|
var msg = $filter('i18n')('config.kaStyle.nameNotUnique.message', style.type);
|
|
systemAlertService.error({
|
|
text: msg,
|
|
clear: false
|
|
});
|
|
unique = false;
|
|
}
|
|
});
|
|
if (!unique) {
|
|
return;
|
|
}
|
|
state.dataIsLoading = true;
|
|
var nonEmptyStyles = $scope.selectedTemplate.templateObject.styles.slice();
|
|
var stylesToBackend = [];
|
|
// if the style is not defined, don't send it to backend
|
|
_.remove(nonEmptyStyles, { styles: '' });
|
|
// remove the isExpanded attribute that was used only by the UI
|
|
_.each(nonEmptyStyles, function (nonEmptyStyle) {
|
|
stylesToBackend.push(_.omit(nonEmptyStyle, 'isExpanded'));
|
|
});
|
|
knowledgeArticleModel.updateTemplateStyles($scope.selectedTemplate.name, stylesToBackend)
|
|
.then(function (data) {
|
|
if (data && data.styles && data.styles.length) {
|
|
originalTemplate.templateObject.styles = data.styles;
|
|
$scope.selectedTemplate.templateObject.styles = _.cloneDeep(data.styles);
|
|
mergeWithStandardStyle($scope.selectedTemplate);
|
|
$scope.selectedStyle = {};
|
|
resetDirtyState();
|
|
}
|
|
}, function (error) {
|
|
systemAlertService.error({
|
|
text: error.data && error.data.error,
|
|
clear: false
|
|
});
|
|
}).finally(function () {
|
|
state.dataIsLoading = false;
|
|
});
|
|
};
|
|
$scope.discard = function () {
|
|
showLeaveDialog().then(function (result) {
|
|
if (result) {
|
|
setSelectedTemplate(originalTemplate);
|
|
}
|
|
});
|
|
};
|
|
function parse_css(styleString) {
|
|
clearSelected_css();
|
|
_.each(styleString.split(';'), function (style) {
|
|
var css = style.split(':');
|
|
var foundMatch = false;
|
|
_.each($scope.selected_css, function (selected_css) {
|
|
if (css[0].trim() === selected_css.name) {
|
|
if (selected_css.name === 'text-decoration') {
|
|
selected_css.value = css[1];
|
|
if (css[1].indexOf('underline') > -1) {
|
|
selected_css.underline = true;
|
|
}
|
|
if (css[1].indexOf('line-through') > -1) {
|
|
selected_css.lineThrough = true;
|
|
}
|
|
}
|
|
else if (selected_css.name === 'font-weight' && css[1].indexOf('bold') > -1) {
|
|
selected_css.value = css[1].trim();
|
|
selected_css.bold = true;
|
|
}
|
|
else if (selected_css.name === 'font-style' && css[1].indexOf('italic') > -1) {
|
|
selected_css.value = css[1].trim();
|
|
selected_css.italic = true;
|
|
}
|
|
else {
|
|
selected_css.value = css[1].trim();
|
|
}
|
|
foundMatch = true;
|
|
return;
|
|
}
|
|
});
|
|
if (!foundMatch && style && style.length) {
|
|
$scope.additional.style += style + ';';
|
|
}
|
|
});
|
|
if ($scope.selected_css.fontSize.value.length) {
|
|
$scope.selected_css.fontSize.label = $scope.selected_css.fontSize.value.replace('px', '');
|
|
}
|
|
if ($scope.selected_css.fontFamily.value.length) {
|
|
$scope.selected_css.fontFamily.label = _.find(styleMetadata.font, { value: $scope.selected_css.fontFamily.value }).label;
|
|
}
|
|
}
|
|
function formulate_css() {
|
|
$scope.selectedStyle.text = '';
|
|
$scope.selectedStyle.styles = '';
|
|
_.each($scope.selected_css, function (selected_css) {
|
|
if (selected_css.value && selected_css.value.length) {
|
|
$scope.selectedStyle.text += selected_css.value + ' ,';
|
|
$scope.selectedStyle.styles += selected_css.name + ':' + selected_css.value + ';';
|
|
}
|
|
});
|
|
if ($scope.additional.style.length) {
|
|
$scope.selectedStyle.styles += $scope.additional.style;
|
|
_.each($scope.additional.style.split(';'), function (style) {
|
|
if (style) {
|
|
var styleValue = style.split(':');
|
|
if (styleValue && styleValue[1]) {
|
|
$scope.selectedStyle.text += styleValue[1] + ' ,';
|
|
}
|
|
}
|
|
});
|
|
}
|
|
// remove trailing , and ; if any
|
|
$scope.selectedStyle.text = $scope.selectedStyle.text.replace(/ ,+$/, '');
|
|
$scope.selectedStyle.styles = $scope.selectedStyle.styles.replace(/;+$/, '');
|
|
}
|
|
function clearSelected_css() {
|
|
$scope.selected_css = {
|
|
fontWeight: { name: 'font-weight', value: '', bold: false },
|
|
fontStyle: { name: 'font-style', value: '', italic: false },
|
|
textDecoration: { name: 'text-decoration', value: '', underLine: false, lineThrough: false },
|
|
textAlign: { name: 'text-align', value: '' },
|
|
fontFamily: { name: 'font-family', value: '', label: '' },
|
|
fontSize: { name: 'font-size', value: '', label: '' },
|
|
color: { name: 'color', value: '' },
|
|
backgroundColor: { name: 'background-color', value: '' }
|
|
};
|
|
$scope.additional.style = '';
|
|
}
|
|
function mergeWithStandardStyle(template) {
|
|
// make sure all standard styles (H1-H6, P) are presented to user
|
|
// they cannot be deleted but user can leave it as undefined
|
|
_.each(standardStyles, function (standardStyle) {
|
|
var existingStandardStyle = _.find(template.templateObject.styles, { type: standardStyle.type });
|
|
if (!existingStandardStyle) {
|
|
template.templateObject.styles.push(_.cloneDeep(standardStyle));
|
|
}
|
|
else {
|
|
// this shouldn't be needed if OOB data is setup properly
|
|
existingStandardStyle.userStyle = false;
|
|
}
|
|
});
|
|
// sorting should be done in js instead at the html level, otherwise the item will move all
|
|
// over the place when user editing the type on the fly
|
|
template.templateObject.styles = _.sortBy(template.templateObject.styles, 'type');
|
|
}
|
|
function setSelectedTemplate(template) {
|
|
$scope.selectedTemplate = _.cloneDeep(template);
|
|
mergeWithStandardStyle($scope.selectedTemplate);
|
|
$scope.selectedTemplate.templateObject.styles = _.sortBy($scope.selectedTemplate.templateObject.styles, 'userStyle');
|
|
$scope.selectedStyle = {};
|
|
resetDirtyState();
|
|
}
|
|
function dirtyStateCheck() {
|
|
dirtyState[$scope.selectedStyle.type] =
|
|
!originalStyle[$scope.selectedStyle.type]
|
|
|| originalStyle[$scope.selectedStyle.type].styles !== $scope.selectedStyle.styles
|
|
|| originalStyle[$scope.selectedStyle.type].element !== $scope.selectedStyle.element;
|
|
$scope.isDirtyState = false;
|
|
_.each(dirtyState, function (dirtyStatePerStyle) {
|
|
$scope.isDirtyState = $scope.isDirtyState || dirtyStatePerStyle;
|
|
});
|
|
}
|
|
function resetDirtyState() {
|
|
$scope.isDirtyState = false;
|
|
dirtyState = {};
|
|
originalStyle = {};
|
|
}
|
|
function showLeaveDialog() {
|
|
var modal = systemAlertService.modal({
|
|
type: 'info',
|
|
title: $filter('i18n')('common.notification.dirty.title'),
|
|
text: $filter('i18n')('common.notification.dirty.loseChanges'),
|
|
buttons: [
|
|
{
|
|
text: $filter('i18n')('common.button.yes'),
|
|
data: true
|
|
},
|
|
{
|
|
text: $filter('i18n')('common.button.no'),
|
|
data: false
|
|
}
|
|
]
|
|
});
|
|
return modal.result;
|
|
}
|
|
init();
|
|
}
|
|
]);
|
|
})();
|