UI fixes in the curriculum tool see BT#6397

skala
Julio Montoya 12 years ago
parent 60f3098046
commit 6fb01d3b5d
  1. 12
      main/inc/Entity/CurriculumCategory.php
  2. 10
      main/inc/Entity/CurriculumItemRelUser.php
  3. 1
      main/inc/Entity/CurriculumRelUser.php
  4. 1
      main/template/default/tool/curriculum/category/read.tpl
  5. 17
      main/template/default/tool/curriculum/category/results.tpl
  6. 61
      main/template/default/tool/curriculum/user/get_user_items.tpl
  7. 63
      main/template/default/tool/curriculum/user/list.tpl
  8. 91
      src/ChamiloLMS/Controller/Tool/Curriculum/CurriculumCategoryController.php
  9. 25
      src/ChamiloLMS/Controller/Tool/Curriculum/CurriculumItemController.php
  10. 105
      src/ChamiloLMS/Controller/Tool/Curriculum/CurriculumUserController.php
  11. 2
      src/ChamiloLMS/Form/CurriculumItemType.php

@ -143,7 +143,6 @@ class CurriculumCategory
$this->session = $session;
}
/**
* @return mixed
*/
@ -161,18 +160,25 @@ class CurriculumCategory
$this->course = $course;
}
/**
* @return ArrayCollection
*/
public function getItems()
{
return $this->items;
}
/**
* @param CurriculumCategory $parent
*/
public function setParent(CurriculumCategory $parent = null)
{
$this->parent = $parent;
}
/**
* @return CurriculumCategory
*/
public function getParent()
{
return $this->parent;

@ -66,12 +66,17 @@ class CurriculumItemRelUser
*/
private $item;
/**
* @return mixed
*/
public function getUser()
{
return $this->user;
}
/**
* @return mixed
*/
public function getItem()
{
return $this->item;
@ -85,6 +90,9 @@ class CurriculumItemRelUser
$this->item = $item;
}
/**
* @param User $user
*/
public function setUser(User $user)
{
$this->user = $user;

@ -42,7 +42,6 @@ class CurriculumRelUser
*/
private $score;
/**
* Get id
*

@ -11,5 +11,4 @@
</li>
{% endfor %}
</ul>
{% endblock %}

@ -0,0 +1,17 @@
{% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
{% block content %}
{{ 'Results' | trans }}
<hr />
<ul>
{% for user in users %}
<li>
{{ user.complete_name }} - {{ user.score }}
<a href="{{ url('curriculum_user.controller:getUserItemsAction',
{ 'userId': user.user_id, 'course' : course.code, 'id_session' : course_session.id }) }}">
{{ 'Details' | trans }}
</a>
</li>
{% endfor %}
</ul>
{% endblock %}

@ -0,0 +1,61 @@
{% extends app.template_style ~ "/layout/layout_1_col.tpl" %}
{% macro widget_prototype(widget, remove_text) %}
{% if widget.get('prototype') %}
{% set form = widget.get('prototype') %}
{% set name = widget.get('prototype').get('description') %}
{% else %}
{% set form = widget %}
{% set name = widget.get('full_name') %}
{% endif %}
<div data-content="{{ name }}">
{{ form_widget(form) }}
</div>
{% endmacro %}
{% block content %}
<script>
$(function() {
});
</script>
<div class="row">
<div class="span10">
<h2>Trayectoria</h2>
<p>Explicaciones</p>
<p>Las respuestas a este formulario son de carácter jurado.</p>
<div id="list" class="trajectory">
{% for subcategory in categories %}
{% if subcategory.lvl == 0 %}
{# <h3> {{ subcategory.title }} </h3>
<hr /> #}
{% else %}
<h4>
{{ subcategory.title }}
{% if category_score[subcategory.id] %}
<div class="label label-success">{{ category_score[subcategory.id] }}</div>
{% endif %}
</h4>
{% endif %}
{% for item in subcategory.items %}
{# Items #}
{{ item.title }} (item) - {{ 'CurriculumMaximumItem' | trans }} {{ item.maxRepeat }}
<div class="row">
{{ form_start(form_list[item.id]) }}
<div id="items_{{ item.id }}" class="items span8" data-max="{{ item.maxRepeat }}" data-prototype="{{ form_widget(form_list[item.id].userItems.vars.prototype)|e }}" >
{% for widget in form_list[item.id].userItems.children %}
{{ _self.widget_prototype(widget, 'Remove item') }}
{% endfor %}
<ul>
</ul>
</div>
{{ form_end(form_list[item.id]) }}
</div>
{% endfor %}
{% endfor %}
</div>
</div>
</div>
{% endblock %}

@ -25,7 +25,6 @@ $(function() {
var input = $(this);
var removeForm = $('<a class="btn btn-danger" href="#"><i class="icon-minus-sign icon-large"></i></a>');
//var id = input.parent().parent().parent().parent().attr('id');
var maxRepeat = input.parent().parent().parent().parent().attr('data-max');
if (maxRepeat != 1) {
@ -33,13 +32,12 @@ $(function() {
addTagFormDeleteLink(removeForm);
}
});
// Create add buttons:
$(".items").each(function(index, value) {
var itemId = $(this).attr('id');
var lastInput = $(this).find("input:text").last();
console.log(lastInput.attr('id'));
var addButton = $('<a class="btn-add btn btn-primary" data-target="'+itemId+'"><i class="icon-plus-sign icon-large"></i></a>');
//lastInput.parent().append(addButton );
});
// When clicking in the add button:
@ -48,7 +46,15 @@ $(function() {
var maxRepeat = collectionHolder.attr('data-max');
var countInput = collectionHolder.find('input:text').length;
// Disables the add button when reached the max count
var showButtonWhenIsHidden = false;
if (countInput > maxRepeat - 2) {
showButtonWhenIsHidden = true;
}
// Disables the clicking when it's disabled
if (countInput > maxRepeat - 1) {
$(this).addClass('disabled');
return false;
}
@ -66,44 +72,62 @@ $(function() {
liItem.find('.controls').append(removeForm);
var item = collectionHolder.find('ul').append(liItem);
addTagFormDeleteLink(removeForm);
if (showButtonWhenIsHidden) {
addTagFormDeleteLink(removeForm, $(this));
} else {
addTagFormDeleteLink(removeForm);
}
event && event.preventDefault();
});
$('#saveQuestionBar').affix();
});
function addTagFormDeleteLink($tagFormLi) {
function addTagFormDeleteLink($tagFormLi, showButton) {
$tagFormLi.on('click', function(e) {
e.preventDefault();
$(this).parent().remove();
// Restore the add button.
if (showButton) {
showButton.removeClass('disabled');
}
});
}
function save(itemId) {
var form = $("#"+itemId).parent();
var serializedForm = form.serialize();
$.post('{{ url('curriculum_user.controller:saveUserItemAction', {'course' : course.code }) }}', serializedForm);
return false;
$.ajax({
'url' : '{{ url('curriculum_user.controller:saveUserItemAction', {'course' : course.code, 'id_session' : course_session.id }) }}',
'data' : serializedForm,
'async': false,
'type' : 'post'
}
);
}
function saveAll() {
var items = $("form").find(".items");
$(items).each(function(index, value) {
var itemId = $(this).attr('id')
var itemId = $(this).attr('id');
save(itemId);
});
window.location = '{{ url('index') }}';
}
</script>
<div class="row">
<div class="span10">
{% if is_granted('ROLE_ADMIN') %}
<div class="actions">
<a href="{{ url('curriculum_category.controller:indexAction', {'course' : course.code , 'id_session' : course_session.id}) }}">
{{ "Categories" | trans }}
</a>
</div>
{% if is_granted('ROLE_ADMIN') and isAllowed %}
<div class="actions">
<a href="{{ url('curriculum_category.controller:indexAction', { 'course' : course.code, 'id_session' : course_session.id }) }}">
{{ "Categories" | trans }}
</a>
<a href="{{ url('curriculum_category.controller:resultsAction', { 'course' : course.code, 'id_session' : course_session.id }) }}">
{{ "Results" | trans }}
</a>
</div>
{% endif %}
<h2>Trayectoria</h2>
@ -112,14 +136,15 @@ function saveAll() {
<div id="list" class="trajectory">
{% for subcategory in categories %}
{% if subcategory.lvl == 0 %}
<h3> {{ subcategory.title }}</h3>
<hr />
{# <h3> {{ subcategory.title }} </h3>
<hr /> #}
{% else %}
<h4> {{ subcategory.title }}</h4>
{% endif %}
{% for item in subcategory.items %}
<h5> {{ item.title }} (item) - Max {{ item.maxRepeat }}</h5>
{# Items #}
{{ item.title }} (item) - {{ 'CurriculumMaximumItem' | trans }} {{ item.maxRepeat }}
<div class="row">
{{ form_start(form_list[item.id]) }}
@ -127,15 +152,12 @@ function saveAll() {
{% for widget in form_list[item.id].userItems.children %}
{{ _self.widget_prototype(widget, 'Remove item') }}
{% endfor %}
<ul>
</ul>
</div>
<div class="span8">
<div class="btn-group">
{# form_widget(form_list[item.id].submit) #}
<!-- <a class="btn btn-success" onclick="save('items_{{ item.id }}');" data-target="items_{{ item.id }}">{{ 'Save items' | get_lang }}</a> -->
{% if item.maxRepeat > 1 %}
<a class="btn-add btn btn-primary" data-target="items_{{ item.id }}"><i class="icon-plus-sign icon-large"></i></a>
{% endif %}
@ -144,7 +166,6 @@ function saveAll() {
{{ form_end(form_list[item.id]) }}
</div>
{% endfor %}
{% endfor %}
</div>
</div>

@ -99,6 +99,8 @@ class CurriculumCategoryController extends CommonController
$this->get('template')->assign('tree', $htmlTree);
$this->get('template')->assign('links', $this->generateLinks());
$this->get('template')->assign('isAllowed', api_is_allowed_to_edit(true, true, true));
$response = $this->get('template')->render_template($this->getTemplatePath().'list.tpl');
return new Response($response, 200, array());
@ -269,6 +271,95 @@ class CurriculumCategoryController extends CommonController
return parent::deleteAction($id);
}
/**
*
* @Route("/results")
* @Method({"GET"})
*/
public function resultsAction()
{
$breadcrumbs = array(
array(
'name' => get_lang('Curriculum'),
'url' => array(
'route' => 'curriculum_user.controller:indexAction',
'routeParameters' => array(
'course' => $this->getCourse()->getCode()
)
)
),
array(
'name' => get_lang('Categories'),
'url' => array(
'route' => 'curriculum_category.controller:indexAction',
'routeParameters' => array(
'course' => $this->getCourse()->getCode()
)
)
),
array(
'name' => get_lang('Results'),
)
);
$this->setBreadcrumb($breadcrumbs);
if (!api_is_allowed_to_edit(true, true, true)) {
$this->abort('405');
}
$session = $this->getSession();
$sessionId = 0;
if ($session) {
$sessionId = $this->getSession()->getId();
}
// @todo move in a function
$users = \CourseManager::get_user_list_from_course_code(
$this->getCourse()->getCode(),
$sessionId,
null,
null,
STUDENT
);
$qb = $this->getManager()
->createQueryBuilder()
->select('node.id, u.userId, SUM(i.score) as score')
->from('Entity\CurriculumCategory', 'node')
->innerJoin('node.course', 'c')
->innerJoin('node.items', 'i')
->innerJoin('i.userItems', 'u')
->groupby('u.userId') ;
$this->setCourseParameters($qb, 'node');
$query = $qb->getQuery();
$userResults = $query->getResult();
$userResultsByUserId = array();
if (!empty($userResults)) {
foreach ($userResults as $item) {
$userResultsByUserId[$item['userId']] = $item['score'];
}
}
if (!empty($users)) {
foreach ($users as &$user) {
if (!empty($userResultsByUserId)) {
if (isset($userResultsByUserId[$user['user_id']])) {
$user['score'] = $userResultsByUserId[$user['user_id']];
} else {
$user['score'] = 0;
}
}
}
}
$template = $this->getTemplate();
$template->assign('users', $users);
$response = $template->render_template($this->getTemplatePath().'results.tpl');
return new Response($response, 200, array());
}
protected function getControllerAlias()
{
return 'curriculum_category.controller';

@ -26,6 +26,31 @@ class CurriculumItemController extends CommonController
*/
public function indexAction()
{
$breadcrumbs = array(
array(
'name' => get_lang('Curriculum'),
'url' => array(
'route' => 'curriculum_user.controller:indexAction',
'routeParameters' => array(
'course' => $this->getCourse()->getCode()
)
)
),
array(
'name' => get_lang('Categories'),
'url' => array(
'route' => 'curriculum_category.controller:indexAction',
'routeParameters' => array(
'course' => $this->getCourse()->getCode()
)
)
),
array(
'name' => get_lang('List')
)
);
$this->setBreadcrumb($breadcrumbs);
return parent::listingAction();
}

@ -51,16 +51,18 @@ class CurriculumUserController extends CommonController
$this->setBreadcrumb($breadcrumbs);
$userId = $this->getUser()->getUserId();
$qb = $this->getManager()
->createQueryBuilder()
->select('node, i')
->select('node, i, u')
->from('Entity\CurriculumCategory', 'node')
->leftJoin('node.items', 'i')
->leftJoin('i.userItems', 'u')
->innerJoin('node.course', 'c')
//->where('node.cId = :id')
//->andWhere('node.sessionId = :session_id')
//->setParameters(array('id' => $course->getId(), 'session_id' => $session->getId()))
->leftJoin('node.items', 'i')
->leftJoin('i.userItems', 'u', 'WITH', 'u.userId = :userId OR u.userId IS NULL')
//->where('u.userId = :userId or u.userId IS NULL')
//->orWhere('u.userId IS NULL')
->setParameter('userId', $userId)
->orderBy('node.root, node.lft, node.title', 'ASC');
$this->setCourseParameters($qb, 'node');
$query = $qb->getQuery();
@ -71,11 +73,15 @@ class CurriculumUserController extends CommonController
/** @var \Entity\CurriculumCategory $category */
foreach ($categories as $category) {
/** @var \Entity\CurriculumItem $item */
foreach ($category->getItems() as $item) {
$formType = new CurriculumItemRelUserCollectionType($item->getId());
$count = count($item->getUserItems());
// If there are no items for the user, then create a new one!
if ($count == 0) {
$userItem = new Entity\CurriculumItemRelUser();
@ -85,7 +91,6 @@ class CurriculumUserController extends CommonController
);
$item->setUserItems($userItemList);
}
$form = $this->get('form.factory')->create($formType, $item);
$formList[$item->getId()] = $form->createView();
}
@ -98,6 +103,7 @@ class CurriculumUserController extends CommonController
$this->get('template')->assign('categories', $categories);
$this->get('template')->assign('links', $this->generateLinks());
$this->get('template')->assign('form_list', $formList);
$this->get('template')->assign('isAllowed', api_is_allowed_to_edit(true, true, true));
$response = $this->get('template')->render_template($this->getTemplatePath().'list.tpl');
return new Response($response, 200, array());
@ -223,6 +229,91 @@ class CurriculumUserController extends CommonController
return new Response($response, 200, array());
}
/**
*
* @Route("{userId}/get-user-items")
* @Method({"GET"})
*/
public function getUserItemsAction($userId)
{
$breadcrumbs = array(
array(
'name' => get_lang('Curriculum'),
'url' => array(
'route' => 'curriculum_user.controller:indexAction',
'routeParameters' => array(
'course' => $this->getCourse()->getCode()
)
)
),
array(
'name' => get_lang('Categories'),
'url' => array(
'route' => 'curriculum_category.controller:indexAction',
'routeParameters' => array(
'course' => $this->getCourse()->getCode()
)
)
),
array(
'name' => get_lang('Results'),
'url' => array(
'route' => 'curriculum_category.controller:resultsAction',
'routeParameters' => array(
'course' => $this->getCourse()->getCode()
)
)
),
array(
'name' => get_lang('UserResults'),
)
);
$this->setBreadcrumb($breadcrumbs);
if (!api_is_allowed_to_edit()) {
return $this->abort(403);
}
$qb = $this->getManager()
->createQueryBuilder()
->select('node, i, u')
->from('Entity\CurriculumCategory', 'node')
->innerJoin('node.course', 'c')
->leftJoin('node.items', 'i')
->leftJoin('i.userItems', 'u', 'WITH', 'u.userId = :userId OR u.userId IS NULL')
->setParameter('userId', $userId)
->orderBy('node.root, node.lft, node.title', 'ASC');
$this->setCourseParameters($qb, 'node');
$query = $qb->getQuery();
$categories = $query->getResult();
foreach ($categories as $category) {
/** @var \Entity\CurriculumItem $item */
$score = 0;
foreach ($category->getItems() as $item) {
$formType = new CurriculumItemRelUserCollectionType($item->getId());
$form = $this->get('form.factory')->create($formType, $item, array('disabled' => true));
$formList[$item->getId()] = $form->createView();
foreach ($item->getUserItems() as $userItem) {
$score += $item->getScore();
}
$categoryScore[$item->getCategoryId()] = $score;
}
}
$this->get('template')->assign('categories', $categories);
$this->get('template')->assign('category_score', $categoryScore);
$this->get('template')->assign('form_list', $formList);
$this->get('template')->assign('isAllowed', api_is_allowed_to_edit(true, true, true));
$response = $this->get('template')->render_template($this->getTemplatePath().'get_user_items.tpl');
return new Response($response, 200, array());
}
/**
* @param Entity\CurriculumItemRelUser $object
* @return JsonResponse

@ -17,7 +17,7 @@ class CurriculumItemType extends AbstractType
$parentIdDisabled = true;
}*/
$builder->add('title', 'text');
$builder->add('title', 'textarea');
$builder->add('score', 'text');
$builder->add('max_repeat', 'text');

Loading…
Cancel
Save