UNPKG

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
/* 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(); } }); }; });