sheercms
Version:
Sheer Cliff CMS is a simple and powerful content management system (CMS) for Node JS.
1,594 lines (1,403 loc) • 49.5 kB
JavaScript
/*
Angular Controller for the WYSIWYG Editor Dialogs
*/
var app = angular.module('app', ['angularFileUpload', 'ui.bootstrap', 'angular-data.DSCacheFactory']);
app.controller('EditorItemSelectorController', function($scope, $q, ContentService, GroupService, DialogService) {
$scope.dialog = {
message: "",
messageType: "",
disableOk: true
};
$scope.data = {
allowedStatuses: 'SMP',
items: [],
groups: [],
group: null,
selectedItem: null,
selectionLabel: "",
uploadCount: 0,
showingRecent: false,
selectFirstItem: false
};
$scope.paging = {
pageSize: 12,
pageNum: 1,
pageCount: 0,
paginate: function(num) {
loadItems($scope.data.group._id, num);
}
};
$scope.init = function(branch) {
$scope.data.selectionLabel = "Selected Item:";
$scope.editorType = getUrlParam("editor");
$scope.funcNum = getUrlParam('CKEditorFuncNum');
loadGroups(branch).then(function() {
if ($scope.data.groups && $scope.data.groups.length > 0) {
//load the items from the first group in the list
$scope.data.group = $scope.data.groups[0];
}
});
};
$scope.$watch(function(scope) {
return scope.data.group;
},
function() {
if ($scope.data.group)
loadItems($scope.data.group._id, 1);
}
);
$scope.$watch(function(scope) {
return scope.data.showingRecent;
},
function() {
if ($scope.data.group) {
if ($scope.data.showingRecent === true)
loadRecentItems($scope.data.group._id, $scope.paging.pageSize);
else
loadItems($scope.data.group._id, 1);
}
}
);
$scope.ok = function () {
var items = [];
if ($scope.data.selectedItem) {
var item = $scope.data.selectedItem;
if ($scope.editorType == 'tinymce') {
parent.tinymce.activeEditor.windowManager.getParams().result(item.url);
parent.tinymce.activeEditor.windowManager.close();
}
else {
window.opener.CKEDITOR.tools.callFunction($scope.funcNum, item.url);
window.close();
}
}
};
$scope.cancel = function () {
if ($scope.editorType == 'tinymce')
parent.tinymce.activeEditor.windowManager.close();
else
window.close();
};
$scope.upload = function() {
if ($scope.data.group) {
DialogService.showFileSelector(function (files) {
if (files && files.length > 0) {
$scope.data.uploading = true;
ContentService.upload($scope.data.group._id, files, true, onUploadProgress, onUploadError).then(function (result) {
$scope.data.uploading = false;
showRecent(true);
//loadItems($scope.data.group._id, $scope.paging.pageNum);
});
}
});
}
};
function showRecent(selectFirstItem) {
if ($scope.data.group) {
ContentService.clearCacheByGroup($scope.data.group._id);
$scope.data.selectFirstItem = selectFirstItem;
if ($scope.data.showingRecent === true)
loadRecentItems($scope.data.group._id, $scope.paging.pageSize);
else
$scope.data.showingRecent = true;
}
}
function onUploadProgress(name, index, loaded, total) {
var per = parseInt(100.0 * loaded / total);
console.log('percent: ' + per + ' ;' + name + '; ' + index);
}
function onUploadError(name, index, message) {
setMessage(message, 'alert-danger');
}
$scope.selectItem = function(item) {
if (isEnabled(item)) {
$scope.data.selectedItem = item;
}
};
$scope.unSelectItem = function(item) {
$scope.data.selectedItem = null;
};
function isEnabled(item) {
if ($scope.data.allowedStatuses === null || $scope.data.allowedStatuses.indexOf(item.status) < 0)
return false;
else
return true;
}
function loadGroups(branch) {
var d = $q.defer();
GroupService.list(branch, null).then(function(result) {
if (result && result.success === true) {
//only add groups that the user has read access to
$scope.data.groups = [];
for(var i = 0; i < result.groups.length; i++) {
var g = result.groups[i];
if (g.rights && g.rights.read == true)
$scope.data.groups.push(g);
}
} else if (result) {
setMessage(result.message, 'alert-danger', false);
} else {
setMessage('An unknown error occurred.', 'alert-danger', false);
}
d.resolve();
});
return d.promise;
}
function loadItems(groupId, pageNumber) {
$scope.paging.pageNum = pageNumber;
//load the items in this group
ContentService.getItems(groupId, pageNumber, $scope.paging.pageSize, true).then(function(data) {
setMessage(data.message, data.success == true ? "alert-success" : "alert-danger");
if (data.success && data.items) {
for(var i = 0; i < data.items.length; i++) {
var item = data.items[i];
item.statusCss = ContentService.getItemStatusCss(item.status);
item.ui = {};
item.ui.enabled = true;
if (!isEnabled(item)) {
item.ui.enabled = false;
item.ui.tooltip = "This item cannot be selected due to it's status";
}
}
$scope.data.items = data.items;
//set the paging data
$scope.paging.pageCount = Math.ceil(data.total / $scope.paging.pageSize);
$scope.paging.pageNum = pageNumber;
}
else
$scope.data.items = [];
});
};
function loadRecentItems(groupId, count, selectFirstItem) {
$scope.data.items = [];
$scope.data.showingRecent = true;
//load the items in this group
ContentService.getRecentItems(groupId, count).then(function(data) {
setMessage(data.message, data.success == true ? "alert-success" : "alert-danger");
if (data.success && data.items) {
for(var i = 0; i < data.items.length; i++) {
var item = data.items[i];
item.statusCss = ContentService.getItemStatusCss(item.status);
item.ui = {};
item.ui.enabled = true;
if (!isEnabled(item)) {
item.ui.enabled = false;
item.ui.tooltip = "This item cannot be selected due to it's status";
}
}
$scope.data.items = data.items;
if ($scope.data.selectFirstItem === true && $scope.data.items && $scope.data.items.length > 0) {
$scope.selectItem($scope.data.items[0]);
$scope.data.selectFirstItem = false;
}
//set the paging data
$scope.paging.pageNum = 1;
$scope.paging.pageCount = 1;
}
});
}
function clearMessage() {
$scope.dialog.message = "";
$scope.dialog.messageType = "";
}
function setMessage(msg, type) {
$scope.dialog.message = msg;
$scope.dialog.messageType = type;
}
function getUrlParam( paramName ) {
var reParam = new RegExp( '(?:[\?&]|&)' + paramName + '=([^&]+)', 'i' ) ;
var match = window.location.search.match(reParam) ;
return ( match && match.length > 1 ) ? match[ 1 ] : null ;
}
});
;
app.directive('paginator', function ($parse) {
return {
restrict: 'C',
scope: {
settings: '=settings'
},
template: '<div ng-if="settings.pageCount > 1">' +
' <i class="fa fa-long-arrow-left arrow-prev" ng-show="settings.pageNum > 1" ng-click="prevPage()"></i>' +
' Page<span>{{settings.pageNum}}</span>of<span>{{settings.pageCount}}</span>' +
' <i class="fa fa-long-arrow-right arrow-next" ng-show="settings.pageNum < settings.pageCount" ng-click="nextPage()"></i>' +
'</div>',
link: function (scope, element, attrs) {
/*
scope.settings = {
pageNum: 1,
pageCount: 0,
paginate: function(num)
};
*/
scope.prevPage = function() {
scope.paginate(scope.settings.pageNum - 1);
};
scope.nextPage = function() {
scope.paginate(scope.settings.pageNum + 1);
};
scope.paginate = function(num) {
if (num > 0 && num <= scope.settings.pageCount && scope.settings.paginate) {
scope.settings.pageNum = num;
scope.settings.paginate(num);
}
};
function init() {
}
init();
}
};
});;
app.service('HelperService', function($q, $http) {
var self = this;
self.splitTrim = function(s, delimiter) {
if (s && s.length > 0) {
delimiter = delimiter || ',';
var arr = s.split(delimiter);
if (arr) {
var temp = [];
for(var i = 0; i < arr.length; i++) {
temp.push(arr[i].trim());
}
return temp;
}
}
return [];
};
self.join = function(arr, delimiter) {
var s = '';
delimiter = delimiter || ',';
if (arr) {
for(var i = 0; i < arr.length; i++)
s += delimiter + arr[i];
if (s.length > 0) {
//strip the first delimiter
s = s.substr(delimiter.length);
}
}
return s;
};
self.toBoolHash = function(arr) {
var hash = {};
if (arr && arr.length > 0) {
for (var i = 0; i < arr.length; i++) {
hash[arr[i]] = true;
}
}
return hash;
};
self.endsWith = function(str, suffix) {
if (str && suffix)
return str.indexOf(suffix, str.length - suffix.length) !== -1;
else
return false;
};
self.startsWith = function(str, prefix) {
if (str && prefix)
return str.indexOf(prefix) === 0;
else
return false;
};
});;/*
Angular Service: Content
*/
app.service('ContentService', function($q, $http, $upload, $modal, DSCacheFactory) {
var self = this;
var contentCache = DSCacheFactory('contentCache', {
maxAge: 1800000, // Items added to this cache expire after 30 minutes.
cacheFlushInterval: 3600000, // This cache will clear itself every hour.
deleteOnExpire: 'aggressive', // Items will be deleted from this cache right when they expire.
storageMode: 'localStorage' // This cache will sync itself with `localStorage`.
});
self.getItems = function(groupId, page, size, useCache) {
var options = {
groupId: groupId,
page: page,
size: size,
useCache: useCache
};
return self.getContentItems(options);
};
self.getContentItems = function(options) {
var d = $q.defer();
var groupId = options.groupId || '';
var page = options.page || 1;
var size = options.size || 20;
var category = options.category || '';
var useCache = options.useCache || true;
var url = '/cms/content/items?groupId=' + groupId + '&category=' + category + '&page=' + page + '&size=' + size;
var data = null;
if (useCache)
data = contentCache.get(url);
if (data) {
d.resolve(data);
}
else {
$http({
url: url,
method: 'get',
params: {}
}).success(function (data) {
if (data && data.items && data.items.length > 0)
contentCache.put(url, data);
d.resolve(data);
}).error(function (data, status) {
d.reject(data);
});
}
return d.promise;
};
self.getRecentItems = function(groupId, count) {
var d = $q.defer();
var url = '/cms/content/recent?groupId=' + (groupId ? groupId : '') + '&count=' + count;
var data = contentCache.get(url);
if (data) {
d.resolve(data);
}
else {
$http({
url: url,
method: 'get',
params: {}
}).success(function (data) {
if (data && data.items && data.items.length > 0)
contentCache.put(url, data);
d.resolve(data);
}).error(function (data, status) {
d.reject(data);
});
}
return d.promise;
};
self.getItemList = function(itemIds, useCache) {
var d = $q.defer();
if (itemIds && itemIds.length > 0) {
var url = '/cms/content/itemlist?ids=' + itemIds.join();
var data = null;
if (useCache)
data = contentCache.get(url);
if (data) {
d.resolve(data);
}
else {
$http({
url: url,
method: 'get',
params: {}
}).success(function (data) {
contentCache.put(url, data);
d.resolve(data);
}).error(function (data, status) {
d.reject(data);
});
}
}
else {
d.resolve(null);
}
return d.promise;
};
self.getItemsByDate = function(groupId, start, end, useCache) {
var d = $q.defer();
var url = '/cms/content/items?groupId=' + (groupId ? groupId : '') + '&start=' + start + '&end=' + end;
var data = null;
if (useCache)
data = contentCache.get(url);
if (data) {
d.resolve(data);
}
else {
$http({
url: url,
method: 'get',
params: {}
}).success(function (data) {
//format the results
var obj = {
events: [],
message: "",
success: true
};
if (data) {
obj.success = data.success;
if (data.success) {
for (var i = 0; i < data.items.length; i++) {
var item = data.items[i];
var start = item.startDate || item.created;
var end = item.endDate || item.created;
var startDate = new moment(start);
var endDate = new moment(end);
var allDay = false;
//determine if this is an all day event
if (startDate.hour() === 0 && startDate.minute() === 0 && startDate.second() === 0 &&
endDate.hour() === 0 && endDate.minute() === 0 && endDate.second() === 0) {
allDay = true;
}
else if (startDate.isSame(endDate))
endDate = endDate.add('m', 30); //add 30 minutes
obj.events.push(new Event(item.contentId, item.name, allDay, startDate, endDate, item.statusClass, item.status, item.statusText));
}
contentCache.put(url, obj);
}
else
obj.message = data.message;
}
else {
obj.message = "Error loading events from server.";
obj.success = false;
}
d.resolve(obj);
}).error(function (data, status) {
d.resolve({
events: [],
message: data,
success: false
});
});
}
return d.promise;
};
self.getTags = function() {
var d = $q.defer();
$http({ url:"/cms/content/tags", method: 'get'}).success(function(data) {
d.resolve(data);
}).error(function(data, status) {
d.reject(data);
});
return d.promise;
};
self.create = function(name, groupId, typeId, templateId, startDate, endDate) {
var d = $q.defer();
$http.post("/cms/content/create", {name: name, groupId: groupId, typeId: typeId, templateId: templateId, start: startDate, end: endDate}).success(function(data) {
//clear the content cache for this parent list
clearCache(groupId);
d.resolve(data);
}).error(function(data, status) {
d.reject(data);
});
return d.promise;
};
self.changeItemDates = function(contentId, startDate, endDate, groupId) {
var d = $q.defer();
//convert the dates to fix time zone issue
var start = self.getDateNoZone(moment.utc(startDate));
var end = self.getDateNoZone(moment.utc(endDate));
$http.post("/cms/content/change-dates", {contentId: contentId, start: start, end: end}).success(function(data) {
clearCache(groupId);
d.resolve(data);
}).error(function(data, status) {
d.reject(data);
});
return d.promise;
};
self.getDateNoZone = function(mDate) {
var dt = mDate.toDate();
var _userOffset = dt.getTimezoneOffset() * 60000;
return new Date(dt.getTime() + _userOffset);
};
self.runCommand = function(cmd, options, item) {
var d = $q.defer();
if (item.templateId === "")
item.templateId = null;
var data = {
command: cmd,
options: options,
item: item,
batch: false
};
var json = JSON.stringify(data);
$http.post("/cms/content/command", {command: cmd, data:json}).success(function(data) {
clearCache(item.groupId);
d.resolve(data);
}).error(function(data, status) {
d.reject(data);
});
return d.promise;
};
self.runBatchCommand = function(cmd, options, itemIds, groupId) {
var d = $q.defer();
var data = {
command: cmd,
options: options,
ids: itemIds,
batch: true
};
var json = JSON.stringify(data);
$http.post("/cms/content/command", {command: cmd, data:json}).success(function(result) {
clearCache(groupId);
d.resolve(result);
}).error(function(result, status) {
d.reject(result);
});
return d.promise;
};
self.getContent = function(contentId, includeEditData) {
var d = $q.defer();
$http({ url:"/cms/content/get", method: 'get', params: { contentId: contentId, editData: includeEditData }}).success(function(data) {
d.resolve(data);
}).error(function(data, status) {
d.reject(data);
});
return d.promise;
};
self.upload = function(groupId, files, publish, onProgress, onError) {
var d = $q.defer();
//now initialize each api group
var index = -1;
async.eachSeries(files, function (file, done) {
index++;
console.log("Uploading file: " + file.name);
$upload.upload({
url: '/cms/content/upload',
method: 'POST',
data: { groupId: groupId, publish: publish },
file: file, // or list of files: $files for html5 only
}).progress(function(evt) {
if (onProgress)
onProgress(file.name, index, evt.loaded, evt.total);
}).success(function(data, status, headers, config) {
if (data && data.success == false && onError) {
onError(file.name, index, data.message);
}
done();
}).error(function(error) {
done(error);
});
}, function (err) {
if (err) {
console.log(err);
d.reject(err);
}
else {
// files uploaded successfully
//clear the client side cache for this groupId
clearCache(groupId);
d.resolve(true);
}
});
return d.promise;
};
self.changeMedia = function(groupId, contentId, file, onProgress, onError) {
var d = $q.defer();
console.log("Uploading file: " + file.name);
$upload.upload({
url: '/cms/content/upload',
method: 'POST',
data: { groupId: groupId, publish: false, contentId: contentId },
file: file
}).progress(function(evt) {
if (onProgress)
onProgress(file.name, 0, evt.loaded, evt.total);
}).success(function(data, status, headers, config) {
if (data && data.success !== true && onError) {
onError(file.name, 0, data.message);
d.resolve({success: false, message: data.message});
}
else {
d.resolve({success: true, message: data.message, item: data.item});
}
}).error(function(error) {
d.reject(error);
});
return d.promise;
};
self.canDesign = function(item) {
return (item.branch === 'content' && item.status !== 'D' && item.url !== null && item.url.length > 0 && item.templateId != null);
};
self.setItemsStatusCss = function(items) {
for (var i = 0; i < items.length; i++)
items[i].statusCss = self.getItemStatusCss(items[i].status);
}
self.getItemStatusCss = function(status) {
if (status == 'N')
return 'label-default';
else if (status == 'S')
return 'label-info';
else if (status == 'P')
return 'label-success';
else if (status == 'M')
return 'label-warning';
else if (status == 'D')
return 'label-danger';
else
return 'label-default';
};
self.getBranchData = function(path) {
if (path) {
if (path.indexOf('/content') > -1) {
return {
name: 'content',
text: 'Content',
views: ['list', 'calendar']
};
}
else if (path.indexOf('/media') > -1) {
return {
name: 'media',
text: 'Media',
views: ['list', 'gallery']
};
}
else if (path.indexOf('/system') > -1) {
return {
name: 'system',
text: 'System',
views: ['list']
};
}
}
else
return null;
};
self.filterContentTypes = function(group, allTypes) {
var types = [];
if (group && group.contentTypes && allTypes) {
//put all group templates into a hash
var hash = {};
for (var i = 0; i < group.contentTypes.length; i++)
hash[group.contentTypes[i]] = true;
for (var i = 0; i < allTypes.length; i++) {
var t = allTypes[i];
if (t.abstract !== true && hash[t._id] === true)
types.push(t);
}
}
return types;
};
self.clearAllCache = function() {
contentCache.removeAll();
};
self.clearCacheByGroup = function(groupId) {
clearCache(groupId);
};
function Event(id, title, allDay, start, end, className, status, statusText) {
var self = this;
self.id = id;
self.title = title;
self.allDay = allDay;
self.start = start;
self.end = end;
self.className = className;
self.status = status;
self.statusText = statusText;
}
function clearCache(groupId) {
if (groupId) {
var keys = contentCache.keys();
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (key.indexOf(groupId) > -1) {
contentCache.remove(key);
}
}
}
}
});
;
app.service('GroupService', function($q, $http, $modal, HelperService, DSCacheFactory) {
var self = this;
var groupCache = DSCacheFactory('groupCache', {
maxAge: 1800000, // Items added to this cache expire after 30 minutes.
cacheFlushInterval: 3600000, // This cache will clear itself every hour.
deleteOnExpire: 'aggressive', // Items will be deleted from this cache right when they expire.
storageMode: 'localStorage' // This cache will sync itself with `localStorage`.
});
self.list = function (branch, parentId) {
var d = $q.defer();
var branches = [];
if (branch.indexOf(',') > -1)
branches = branch.split(',');
else
branches.push(branch);
var groups = [];
async.eachSeries(branches, function (branch, done) {
try {
getGroups(branch, parentId).then(function(result) {
if (result.groups) {
for(var j = 0; j < result.groups.length; j++) {
groups.push(result.groups[j]);
}
}
done();
});
}
catch(e) {
logger.error(e);
done(e);
}
}, function (err) {
if (err)
d.resolve({success: false, message: err.message});
else
d.resolve({success: true, groups: groups});
});
return d.promise;
};
function getGroups(branch, parentId) {
var d = $q.defer();
var url = '/cms/groups/list?branch=' + branch;
var data = groupCache.get(url);
if (data) {
d.resolve(data);
}
else {
$http({
url: url,
method: 'get',
params: {}
}).success(function (data) {
if (data) {
if (data.groups) {
for(var i = 0; i < data.groups.length; i++)
data.groups[i].cats = HelperService.join(data.groups[i].categories, ', ');
}
groupCache.put(url, data);
}
d.resolve(data);
}).error(function (data, status) {
d.reject(data);
});
}
return d.promise;
}
self.getGroup = function(groupId) {
var d = $q.defer();
$http({ url:"/cms/groups/get", method: 'get', params: { groupId: groupId }}).success(function(data) {
if (data.group) {
data.group.cats = HelperService.join(data.group.categories, ', ');
}
console.log('group data: ' + JSON.stringify(data));
d.resolve(data);
}).error(function(data, status) {
d.reject(data);
});
return d.promise;
};
self.create = function(group) {
var d = $q.defer();
var json = JSON.stringify(group);
$http.post("/cms/groups/create", {data: json}).success(function(data) {
//clear the cache for this parent list
clearCache(group.branch);
d.resolve(data);
}).error(function(data, status) {
d.reject(data);
});
return d.promise;
};
self.update = function(group) {
var d = $q.defer();
//convert the categories string to an array
if (group.cats && group.cats.length > 0) {
group.categories = HelperService.splitTrim(group.cats, ',');
}
else
group.categories = [];
var json = JSON.stringify(group);
$http.post("/cms/groups/update", {data: json}).success(function(data) {
//clear the cache for this parent list
clearCache(group.branch);
d.resolve(data);
}).error(function(data, status) {
d.reject(data);
});
return d.promise;
};
self.delete = function(group) {
var d = $q.defer();
$http.post("/cms/groups/delete", {groupId: group._id}).success(function(data) {
//clear the cache for this parent list
clearCache(group.branch);
d.resolve(data);
}).error(function(data, status) {
d.reject(data);
});
return d.promise;
};
self.recalculate = function(group) {
var d = $q.defer();
$http.post("/cms/groups/recalculate", {groupId: group._id}).success(function(data) {
//clear the cache for this parent list
clearCache(group.branch);
d.resolve(data);
}).error(function(data, status) {
d.reject(data);
});
return d.promise;
};
/*
positions: [{groupId, position}]
*/
self.reorder = function(groups, branch, parentId) {
var d = $q.defer();
var arr = [];
for(var i = 0; i < groups.length; i++) {
var group = groups[i];
var p = {
groupId: group._id,
name: group.name,
position: (i + 1)
};
arr.push(p);
}
var json = JSON.stringify(arr);
$http.post("/cms/groups/reorder", {data: json}).success(function(data) {
//clear the cache for this parent list
clearCache(branch);
d.resolve(data);
}).error(function(data, status) {
d.reject(data);
});
return d.promise;
};
self.clearAllCache = function() {
groupCache.removeAll();
console.log("All group cache cleared.");
};
self.clearCache = function(branch) {
clearCache(branch);
};
function clearCache(branch) {
groupCache.remove('/cms/groups/list?branch=' + branch);
}
});
var GroupPropsDialogController = function ($scope, $modalInstance, GroupService, RoleService, group, types) {
$scope.group = null;
$scope.original = null;
$scope.canDelete = false;
$scope.perms = {
role: [],
selectedRole: null
};
$scope.dialog = {
title: "Group Properties",
message: "",
messageType: "",
tab: "general"
};
$scope.views = [
{ name: 'list', text: 'List', checked: false },
{ name: 'gallery', text: 'Gallery', checked: false },
{ name: 'calendar', text: 'Calendar', checked: false }
];
$scope.sortByOptions = [
{ text: 'Name', value: 'name'},
{ text: 'Date Created', value: 'created'},
{ text: 'Date Modified', value: 'modified'},
{ text: 'Start Date', value: 'startdate'}
];
$scope.sortDirOptions = [
{ text: 'Ascending', value: 'asc'},
{ text: 'Descending', value: 'desc'}
];
$scope.resizeModeOptions = [
{ text: 'None', value: 'none'},
{ text: 'Max', value: 'max'},
{ text: 'Crop', value: 'crop'},
{ text: 'Stretch', value: 'stretch'}
];
$scope.resizeQualityOptions = [];
$scope.types = [];
$scope.selectedTypes = [];
$scope.changeTab = function(name) {
$scope.dialog.tab = name;
}
$scope.delete = function() {
if (confirm('Are you sure you want to delete this group?')) {
setMessage("Deleting group...", "alert-info");
GroupService.delete($scope.group).then(function(result) {
if (result && result.success === true) {
$modalInstance.close(true);
}
else if (result) {
setMessage(result.message, "alert-danger");
}
else {
setMessage("Error deleting the group!", "alert-danger");
}
});
}
}
$scope.recalculate = function() {
setMessage("Recalculating the group item count...", "alert-info");
GroupService.recalculate($scope.group).then(function(result) {
if (result && result.success === true) {
setMessage("Group item count recalculated to: " + result.itemCount, "alert-info");
}
else if (result) {
setMessage(result.message, "alert-danger");
}
else {
setMessage("Error recalculating the group item count!", "alert-danger");
}
});
};
$scope.urlPatternHelp = function() {
alert('Item ID: {id}\nItem Name: {n}\nDate Year: {dy}\nDate Month: {dm}\nDate Day: {dd}\nExample: /blog/{dy}/{dm}/{n}');
};
$scope.ok = function() {
//set the allowed types
var typeIds = [];
for(var i = 0; i < $scope.selectedTypes.length; i++) {
typeIds.push($scope.selectedTypes[i]._id);
}
$scope.group.contentTypes = typeIds;
//set the views
var views = [];
for(var i = 0; i < $scope.views.length; i++) {
if ($scope.views[i].checked === true)
views.push($scope.views[i].name);
}
$scope.group.views = views;
//save the changes
setMessage("Saving group properties...", "alert-info");
GroupService.update($scope.group).then(function(result) {
if (result && result.success === true) {
$modalInstance.close(true);
}
else if (result) {
setMessage(result.message, "alert-danger");
}
else {
setMessage("Error saving the group properties!", "alert-danger");
}
});
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
$scope.addPermRole = function() {
if ($scope.perms.selectedRole) {
if (!$scope.group.perms)
$scope.group.perms = [];
//see if this role is already in the list of permissions
for(var i = 0; i < $scope.group.perms.length; i++) {
var p = $scope.group.perms[i];
if (p.role === $scope.perms.selectedRole) {
alert('This role already has permissions on this group!');
return;
}
}
//add this role to the permissions
$scope.group.perms.push(new Permission($scope.perms.selectedRole));
}
else
alert('You must select a role from the dropdown!');
};
$scope.removePerm = function(perm, index) {
if ($scope.group.perms && $scope.group.perms.length > index) {
$scope.group.perms.splice(index, 1);
}
};
function init() {
$scope.original = group;
//load the quality options
$scope.resizeQualityOptions = [];
for(var i = 0; i <= 100; i+=2)
$scope.resizeQualityOptions.push(i);
//create a copy of the group for editing
var copy = {
_id: group._id,
parentId: group.parentId,
name: group.name,
desc: group.desc,
branch: group.branch,
icon: group.icon,
itemCount: group.itemCount,
childCount: group.childCount,
contentTypes: group.contentTypes,
perms: group.perms,
urlPattern: group.urlPattern,
views: group.views,
sortBy: group.sortBy || 'name',
sortDir: group.sortDir || 'asc',
position: group.position,
created: group.created,
modified: group.modified,
mediaSettings: group.mediaSettings,
cats: group.cats,
categories: group.categories
};
$scope.group = copy;
//load only the non-abstract types with the correct branch
$scope.types = [];
if (types) {
for(var i = 0; i < types.length; i++) {
var t = types[i];
if (t.abstract !== true) {
//check the branch with the media type
if ($scope.group.branch === 'content' && (t.mediaType == null || t.mediaType === '' || t.mediaType === 'None'))
$scope.types.push(t);
else if ($scope.group.branch === 'media' && t.mediaType && t.mediaType !== '' && t.mediaType !== 'None')
$scope.types.push(t);
}
}
}
//set the selected templates
if (copy.contentTypes) {
for(var i = 0; i < copy.contentTypes.length; i++) {
//find the template object with this id
for(var j = 0; j < $scope.types.length; j++) {
if ($scope.types[j]._id == copy.contentTypes[i]) {
$scope.selectedTypes.push($scope.types[j]);
break;
}
}
}
}
//load the views array
if (copy.views && copy.views.length > 0) {
for(var i = 0; i < copy.views.length; i++) {
var name = copy.views[i];
for(var j = 0; j < $scope.views.length; j++) {
if ($scope.views[j].name == name) {
$scope.views[j].checked = true;
break;
}
}
}
}
else {
//check the list view
for(var j = 0; j < $scope.views.length; j++) {
if ($scope.views[j].name == 'list') {
$scope.views[j].checked = true;
break;
}
}
}
$scope.canDelete = (copy.itemCount === 0 && copy.childCount === 0);
loadRoles();
}
function loadRoles() {
RoleService.getRoles(true).then(function(data) {
$scope.perms.roles = [];
if (data.success === false) {
setMessage(data.message, (data.success === true ? "alert-success" : "alert-danger"), true);
}
else if (data.roles) {
for(var i = 0; i < data.roles.length; i++) {
$scope.perms.roles.push(data.roles[i].name);
}
}
});
}
function setMessage(msg, type) {
$scope.dialog.messageType = type;
$scope.dialog.message = msg;
}
function Permission(role) {
var self = this;
self.role = role;
self.create = false;
self.read = false;
self.update = false;
self.delete = false;
self.publish = false;
}
init();
};
;
app.service('DialogService', function($q, $http, $modal) {
var self = this;
/*
branch: content, media, system
title: the title of the dialog
multiple: false
statuses: NSMPD
selectedIds: [] the item IDs to pre-select
onLoadItems: (items)
onSuccess: (value)
onCancel: ()
*/
self.openItemSelector = function(options) {
//set some defaults
var settings = {
branch: 'content',
multiple: false,
title: 'Item Selector',
statuses: 'NSMP',
selectedIds: [],
groups: null, // []
onLoadItems: function() {},
onSuccess: function() {},
onCancel: function() {}
};
angular.extend(settings, options);
var modalInstance = $modal.open({
templateUrl: 'ItemSelectorDialog',
controller: ItemSelectorController,
windowClass: 'xlarge-dialog',
resolve: {
branch: function() {
return settings.branch;
},
multiple: function() {
return settings.multiple;
},
title: function() {
return settings.title;
},
statuses: function() {
return settings.statuses;
},
selectedIds: function() {
return settings.selectedIds;
},
groups: function() {
return settings.groups;
},
onLoadItems: function() {
return settings.onLoadItems;
}
}
});
modalInstance.result.then(function (value) {
if (settings.onSuccess) {
settings.onSuccess(value);
}
}, function () {
if (settings.onCancel) {
settings.onCancel();
}
});
};
/*
title: the title of the dialog
value: the existing value
statuses: NSMPD
onLoadItems: (items)
onSuccess: (value)
onCancel: ()
*/
self.openLinkSelector = function(options) {
//set some defaults
var settings = {
title: 'Link Selector',
statuses: 'NSMP',
groups: null, // []
onLoadItems: function() {},
onSuccess: function() {},
onCancel: function() {}
};
angular.extend(settings, options);
var modalInstance = $modal.open({
templateUrl: 'LinkSelectorDialog',
controller: LinkSelectorController,
windowClass: 'xlarge-dialog',
resolve: {
title: function() {
return settings.title;
},
statuses: function() {
return settings.statuses;
},
onLoadItems: function() {
return settings.onLoadItems;
},
value: function() {
return settings.value;
},
groups: function() {
return settings.groups;
}
}
});
modalInstance.result.then(function (value) {
if (settings.onSuccess) {
settings.onSuccess(value);
}
}, function () {
if (settings.onCancel) {
settings.onCancel();
}
});
};
/*
title: the title of the dialog
groupId: the ID of the item group to upload to
onClose: (uploadCount)
*/
self.openUploadMedia = function(options) {
//set some defaults
var settings = {
title: 'Upload Media',
onClose: function() {}
};
angular.extend(settings, options);
var modalInstance = $modal.open({
templateUrl: 'UploadMediaDialog',
controller: UploadMediaDialogController,
windowClass: 'large-dialog',
resolve: {
title: function() {
return settings.title;
},
groupId: function() {
return settings.groupId;
},
onClose: function() {
return settings.onClose;
}
}
});
modalInstance.result.then(function (value) {
if (settings.onClose) {
settings.onClose(value);
}
}, function () {
if (settings.onClose) {
settings.onClose(null);
}
});
};
/*
onFiles: (files)
*/
self.showFileSelector = function(onFiles) {
var fileSelector = $('<input type="file" />');
fileSelector.on("change", function(evt) {
var files = evt.target.files;
if (onFiles)
onFiles(files);
});
fileSelector.click();
};
/*
title: the title of the dialog
value: the existing value
statuses: NSMPD
onLoadItems: (items)
onSuccess: (value)
onCancel: ()
*/
self.openImageSelector = function(options) {
//set some defaults
var settings = {
title: 'Image Selector',
statuses: 'NSMP',
groups: null, // []
onLoadItems: function() {},
onSuccess: function() {},
onCancel: function() {}
};
angular.extend(settings, options);
var modalInstance = $modal.open({
templateUrl: 'ImageSelectorDialog',
controller: ImageSelectorController,
windowClass: 'xlarge-dialog',
resolve: {
value: function() {
return settings.value;
},
title: function() {
return settings.title;
},
statuses: function() {
return settings.statuses;
},
groups: function() {
return settings.groups;
},
onLoadItems: function() {
return settings.onLoadItems;
}
}
});
modalInstance.result.then(function (value) {
if (settings.onSuccess) {
settings.onSuccess(value);
}
}, function () {
if (settings.onCancel) {
settings.onCancel();
}
});
};
self.openRawValue = function(rawValue, onClose) {
var modalInstance = $modal.open({
templateUrl: 'RawValueDialog',
controller: RawValueDialogController,
resolve: {
rawValue: function () {
return rawValue;
}
}
});
modalInstance.result.then(function(value) {
if (onClose)
onClose(value);
}, function() {
//cancelled
if (onClose)
onClose(null);
});
};
/*
title: the title of the dialog
value: the existing value
onSuccess: (value)
onCancel: ()
*/
self.openIconSelector = function(options) {
//set some defaults
var settings = {
title: 'Icon Selector',
onSuccess: function() {},
onCancel: function() {}
};
angular.extend(settings, options);
var modalInstance = $modal.open({
templateUrl: 'IconSelectorDialog',
controller: IconSelectorController,
windowClass: 'xlarge-dialog',
resolve: {
title: function() {
return settings.title;
},
value: function() {
return settings.value;
}
}
});
modalInstance.result.then(function (value) {
if (settings.onSuccess) {
settings.onSuccess(value);
}
}, function () {
if (settings.onCancel) {
settings.onCancel();
}
});
};
/*
branch: content, media, system
title: the title of the dialog
onSuccess: function(group)
onCancel: function()
*/
self.openGroupSelector = function(branch, title, onSuccess, onCancel) {
var modalInstance = $modal.open({
templateUrl: 'GroupSelectorDialog',
controller: GroupSelectorDialogController,
windowClass: 'medium-dialog',
resolve: {
branch: function() {
return branch;
},
title: function() {
return title;
}
}
});
modalInstance.result.then(function (value) {
if (onSuccess) {
onSuccess(value);
}
}, function () {
if (onCancel) {
onCancel();
}
});
};
});