23503eb4ba
- Use ng-cloak for hide template parts while loading. - Set html lang attribute dynamically (Fixes #1546) - Clean up: Rename 'dashboard' to 'home'. - Show duration of speech in minutes. (Fixes #1882) - Save agenda specific stuff for customslides. (Fixes #1887) - Remove title from QuickEdit from. - Checkbox for item.closed is now visible for manager only. - Agenda list view: Show list of speakers link also for normal users. - Improve slide templates: Show agenda item number and subtitle. - Fixed agenda title for motions and assignments. (Don't load motions and assignmetn in agenda app.) - Added missing seach template.
205 lines
7.5 KiB
JavaScript
205 lines
7.5 KiB
JavaScript
(function () {
|
|
|
|
'use strict';
|
|
|
|
angular.module('OpenSlidesApp.agenda', ['OpenSlidesApp.users'])
|
|
|
|
.factory('Speaker', [
|
|
'DS',
|
|
function(DS) {
|
|
return DS.defineResource({
|
|
name: 'agenda/speaker',
|
|
relations: {
|
|
belongsTo: {
|
|
'users/user': {
|
|
localField: 'user',
|
|
localKey: 'user_id',
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
])
|
|
|
|
.factory('Agenda', [
|
|
'$http',
|
|
'DS',
|
|
'Speaker',
|
|
'jsDataModel',
|
|
'Projector',
|
|
'gettextCatalog',
|
|
function($http, DS, Speaker, jsDataModel, Projector, gettextCatalog) {
|
|
var name = 'agenda/item';
|
|
return DS.defineResource({
|
|
name: name,
|
|
useClass: jsDataModel,
|
|
methods: {
|
|
getResourceName: function () {
|
|
return name;
|
|
},
|
|
getContentObject: function () {
|
|
return DS.get(this.content_object.collection, this.content_object.id);
|
|
},
|
|
getContentResource: function () {
|
|
return DS.definitions[this.content_object.collection];
|
|
},
|
|
getTitle: function () {
|
|
var title;
|
|
try {
|
|
title = this.getContentObject().getAgendaTitle();
|
|
} catch (e) {
|
|
// when the content object is not in the DS store.
|
|
title = this.title;
|
|
}
|
|
if (this.item_number) {
|
|
title = this.item_number + ' · ' + title;
|
|
}
|
|
return title;
|
|
},
|
|
getAgendaTitle: function () {
|
|
return this.title;
|
|
},
|
|
getListViewTitle: function () {
|
|
var title;
|
|
try {
|
|
title = this.getContentObject().getAgendaListViewTitle();
|
|
} catch (e) {
|
|
// when the content object is not in the DS store
|
|
title = this.list_view_title;
|
|
}
|
|
if (this.item_number) {
|
|
title = this.item_number + ' · ' + title;
|
|
}
|
|
return title;
|
|
},
|
|
// override project function of jsDataModel factory
|
|
project: function() {
|
|
return $http.post(
|
|
'/rest/core/projector/1/prune_elements/',
|
|
[{name: this.content_object.collection, id: this.content_object.id}]
|
|
);
|
|
},
|
|
// override isProjected function of jsDataModel factory
|
|
isProjected: function () {
|
|
var projector = Projector.get(1);
|
|
if (typeof projector === 'undefined') return false;
|
|
var self = this;
|
|
var predicate = function (element) {
|
|
return element.name == self.content_object.collection &&
|
|
typeof element.id !== 'undefined' &&
|
|
element.id == self.content_object.id;
|
|
};
|
|
return typeof _.findKey(projector.elements, predicate) === 'string';
|
|
},
|
|
// project list of speakers
|
|
projectListOfSpeakers: function() {
|
|
return $http.post(
|
|
'/rest/core/projector/1/prune_elements/',
|
|
[{name: 'agenda/list-of-speakers', id: this.id}]
|
|
);
|
|
},
|
|
// check if list of speakers is projected
|
|
isListOfSpeakersProjected: function () {
|
|
// Returns true if there is a projector element with the
|
|
// name 'agenda/list-of-speakers' and the same id.
|
|
var projector = Projector.get(1);
|
|
if (typeof projector === 'undefined') return false;
|
|
var self = this;
|
|
var predicate = function (element) {
|
|
return element.name == 'agenda/list-of-speakers' &&
|
|
typeof element.id !== 'undefined' &&
|
|
element.id == self.id;
|
|
};
|
|
return typeof _.findKey(projector.elements, predicate) === 'string';
|
|
}
|
|
},
|
|
relations: {
|
|
hasMany: {
|
|
'core/tag': {
|
|
localField: 'tags',
|
|
localKeys: 'tags_id',
|
|
},
|
|
'agenda/speaker': {
|
|
localField: 'speakers',
|
|
foreignKey: 'item_id',
|
|
}
|
|
}
|
|
},
|
|
beforeInject: function (resource, instance) {
|
|
Speaker.ejectAll({where: {item_id: {'==': instance.id}}});
|
|
}
|
|
});
|
|
}
|
|
])
|
|
|
|
.factory('AgendaTree', [
|
|
function () {
|
|
return {
|
|
getTree: function (items) {
|
|
// Sort items after there weight
|
|
items.sort(function(itemA, itemB) {
|
|
return itemA.weight - itemB.weight;
|
|
});
|
|
|
|
// Build a dict with all children (dict-value) to a specific
|
|
// item id (dict-key).
|
|
var itemChildren = {};
|
|
|
|
_.each(items, function (item) {
|
|
if (item.parent_id) {
|
|
// Add item to his parent. If it is the first child, then
|
|
// create a new list.
|
|
try {
|
|
itemChildren[item.parent_id].push(item);
|
|
} catch (error) {
|
|
itemChildren[item.parent_id] = [item];
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
// Recursive function that generates a nested list with all
|
|
// items with there children
|
|
function getChildren(items) {
|
|
var returnItems = [];
|
|
_.each(items, function (item) {
|
|
returnItems.push({
|
|
item: item,
|
|
children: getChildren(itemChildren[item.id]),
|
|
id: item.id,
|
|
});
|
|
});
|
|
return returnItems;
|
|
}
|
|
|
|
// Generates the list of root items (with no parents)
|
|
var parentItems = items.filter(function (item) {
|
|
return !item.parent_id;
|
|
});
|
|
return getChildren(parentItems);
|
|
},
|
|
|
|
// Returns a list of all items as a flat tree the attribute parentCount
|
|
getFlatTree: function(items) {
|
|
var tree = this.getTree(items);
|
|
var flatItems = [];
|
|
|
|
function generateFatTree(tree, parentCount) {
|
|
_.each(tree, function (item) {
|
|
item.item.parentCount = parentCount;
|
|
flatItems.push(item.item);
|
|
generateFatTree(item.children, parentCount + 1);
|
|
});
|
|
}
|
|
generateFatTree(tree, 0);
|
|
return flatItems;
|
|
},
|
|
};
|
|
}
|
|
])
|
|
|
|
// Make sure that the Agenda resource is loaded.
|
|
.run(['Agenda', function(Agenda) {}]);
|
|
|
|
}());
|