WIP: New skill list based in passed skills see BT#13587

pull/2487/head
Julio 7 years ago
parent a7a1cb02d7
commit b03c03f51e
  1. 247
      main/inc/lib/skill.lib.php
  2. 34
      main/social/my_skills_report.php
  3. 60
      main/template/default/skill/drh_report.tpl
  4. 26
      main/template/default/skill/student_boss_report.tpl
  5. 17
      main/template/default/skill/student_report.tpl

@ -3,6 +3,7 @@
use Chamilo\UserBundle\Entity\User;
use Chamilo\UserBundle\Entity\Repository\UserRepository;
use Fhaculty\Graph\Vertex;
/**
* Class SkillProfile
@ -97,7 +98,7 @@ class SkillProfile extends Model
Database::delete(
$this->table_rel_profile,
array(
'profile_id' => $id
'profile_id' => $id,
)
);
@ -222,15 +223,15 @@ class SkillRelSkill extends Model
}
/**
* @param int $skill_id
* @param int $skillId
* @return array
*/
public function getDirectParents($skill_id)
public function getDirectParents($skillId)
{
$skill_id = intval($skill_id);
$skillId = (int) $skillId;
$sql = 'SELECT parent_id as skill_id
FROM '.$this->table.'
WHERE skill_id = '.$skill_id.' ';
WHERE skill_id = '.$skillId.' ';
$result = Database::query($sql);
$skill = Database::store_result($result, 'ASSOC');
$skill = isset($skill[0]) ? $skill[0] : null;
@ -324,9 +325,9 @@ class SkillRelSkill extends Model
'where' => array(
'skill_id = ? AND parent_id = ?' => array(
$skill_id,
$parent_id
)
)
$parent_id,
),
),
)
);
@ -365,9 +366,9 @@ class SkillRelGradebook extends Model
'where' => array(
'gradebook_id = ? AND skill_id = ?' => array(
$gradebookId,
$skillId
)
)
$skillId,
),
),
)
);
if (!empty($result)) {
@ -391,9 +392,9 @@ class SkillRelGradebook extends Model
'where' => array(
'skill_id = ? AND gradebook_id = ? ' => array(
$skill_id,
$gradebookId
)
)
$gradebookId,
),
),
),
'first'
);
@ -443,7 +444,7 @@ class SkillRelGradebook extends Model
foreach ($gradebooks_to_add as $gradebook_id) {
$attributes = array(
'skill_id' => $skill_id,
'gradebook_id' => $gradebook_id
'gradebook_id' => $gradebook_id,
);
$this->save($attributes);
}
@ -532,7 +533,7 @@ class SkillRelUser extends Model
$courseId = intval($courseId);
$sessionId = $sessionId ? intval($sessionId) : null;
$whereConditions = array(
'user_id = ? ' => intval($userId)
'user_id = ? ' => intval($userId),
);
if ($courseId > 0) {
@ -544,7 +545,7 @@ class SkillRelUser extends Model
'skill_id',
$this->table,
array(
'where' => $whereConditions
'where' => $whereConditions,
),
'all'
);
@ -566,12 +567,12 @@ class SkillRelUser extends Model
intval($userId),
intval($skillId),
intval($courseId),
$sessionId ? intval($sessionId) : null
)
$sessionId ? intval($sessionId) : null,
),
);
return Database::select('*', $this->table, array(
'where' => $where
'where' => $where,
), 'first');
}
@ -589,7 +590,7 @@ class Skill extends Model
'access_url_id',
'short_code',
'icon',
'criteria'
'criteria',
);
public $required = array('name');
@ -628,6 +629,10 @@ class Skill extends Model
public function get($id)
{
$result = parent::get($id);
if (empty($result)) {
return [];
}
$path = api_get_path(WEB_UPLOAD_PATH).'badges/';
if (!empty($result['icon'])) {
@ -653,7 +658,6 @@ class Skill extends Model
$result['icon_big'] = $iconSmall;
$result['icon_small'] = $iconBig;
$result['icon_mini'] = $iconMini;
$result['img_mini'] = Display::img($iconBig, $result['name'], ['width' => ICON_SIZE_MEDIUM]);
$result['img_big'] = Display::img($iconBig, $result['name']);
$result['img_small'] = Display::img($iconSmall, $result['name']);
@ -687,6 +691,9 @@ class Skill extends Model
}
$html .= '<ul class="list-unstyled list-badges">';
foreach ($skills as $skill) {
if (isset($skill['data'])) {
$skill = $skill['data'];
}
$html .= '<li class="thumbnail">';
$item = $skill[$imageSize];
$item .= '<div class="caption">
@ -887,7 +894,7 @@ class Skill extends Model
$skillRelSkill = new SkillRelSkill();
$skills = $skillRelSkill->getSkillParents($skillId, true);
foreach ($skills as &$skill) {
$skill['data'] = self::get($skill['skill_id']);
$skill['data'] = $this->get($skill['skill_id']);
}
return $skills;
}
@ -901,12 +908,22 @@ class Skill extends Model
{
$skillRelSkill = new SkillRelSkill();
$skills = $skillRelSkill->getDirectParents($skillId, true);
foreach ($skills as &$skill) {
$skill['data'] = self::get($skill['skill_id']);
$skill_info2 = $skillRelSkill->getSkillInfo($skill['skill_id']);
$skill['data']['parent_id'] = $skill_info2['parent_id'];
if (!empty($skills)) {
foreach ($skills as &$skill) {
$skillData = $this->get($skill['skill_id']);
if (empty($skillData)) {
continue;
}
$skill['data'] = $skillData;
$skill_info2 = $skillRelSkill->getSkillInfo($skill['skill_id']);
$parentId = isset($skill_info2['parent_id']) ? isset($skill_info2['parent_id']) : 0;
$skill['data']['parent_id'] = $parentId;
}
return $skills;
}
return $skills;
return [];
}
/**
@ -989,7 +1006,7 @@ class Skill extends Model
'skill_id' => $skill_gradebook['skill_id'],
'acquired_skill_at' => api_get_utc_datetime(),
'course_id' => intval($courseId),
'session_id' => $sessionId ? intval($sessionId) : null
'session_id' => $sessionId ? intval($sessionId) : null,
);
$skill_rel_user->save($params);
@ -1068,7 +1085,9 @@ class Skill extends Model
* Get user's skills
*
* @param int $userId User's id
* @param bool $get_skill_data
* @param bool $getSkillData
* @param int $courseId
* @param int $sessionId
*
* @return array
*/
@ -1103,7 +1122,6 @@ class Skill extends Model
$result = Database::query($sql);
$skills = Database::store_result($result, 'ASSOC');
$uploadPath = api_get_path(WEB_UPLOAD_PATH);
$skillList = array();
if (!empty($skills)) {
foreach ($skills as $skill) {
@ -1120,6 +1138,63 @@ class Skill extends Model
return $skillList;
}
public function checkParents($skills, $skillParents = [])
{
foreach ($skills as $resultData) {
if (isset($resultData['data'])) {
$resultData['id'] = $resultData['data']['id'];
}
if (isset($resultData['skill_id']) && empty($resultData['skill_id'])) {
break;
}
$parents = $this->get_parents($resultData['id']);
var_dump($parents);
if (!empty($parents)) {
$skillParents[$resultData['id']][] = $this->checkParents($parents, $skillParents);
var_dump($skillParents);
exit;
foreach ($parents as $parentData) {
//$skillParents[$parentData['id']]['passed'] = in_array($parentData['id'], array_keys($skills));
// $skillParents[$parentData['parent_id']][$parentData['id']][$resultData['id']][] = $resultData;
}
foreach ($parents as $parent) {
// $parents = $this->get_parents($parent['parent_id']);
//$skillParents[$parent['parent_id']] = $this->checkParents($parents, $skillParents);
}
} else {
}
}
return $skillParents;
}
/**
* @param Vertex $vertex
* @return string
*/
public function processVertex(Vertex $vertex)
{
$subTable = '<table class="table table-bordered">';
foreach ($vertex->getVerticesEdgeTo() as $subVertex) {
$data = $subVertex->getAttribute('graphviz.data');
$label = $this->processSkillList([$data], 'mini', false);
$subTable .= '<tr >';
$subTable .= '<td >';
$subTable .= $label;
$subTable .= $this->processVertex($subVertex);
$subTable .= '</td>';
$subTable .= '</tr >';
}
$subTable .= '</table >';
return $subTable;
}
/**
* @param int $userId
* @param int $courseId
@ -1132,18 +1207,19 @@ class Skill extends Model
$skills = $this->getUserSkills($userId, true, $courseId, $sessionId);
$courseTempList = [];
$skillParents = [];
$tableRows = [];
//$skillParents = $this->checkParents($skills);
$skillParents = [];
foreach ($skills as $resultData) {
$parents = $this->get_parents($resultData['id']);
foreach ($parents as $parentData) {
if ($parentData['id'] == 1 || $parentData['parent_id'] == 1) {
continue;
}
$skillParents[$parentData['id']]['passed'] = in_array($parentData['id'], array_keys($skills));
$skillParents[$parentData['id']][] = $resultData;
$parentData['passed'] = in_array($parentData['id'], array_keys($skills));
$skillParents[$resultData['id']][$parentData['id']] = $parentData;
}
}
foreach ($skills as $resultData) {
$courseId = $resultData['course_id'];
if (!empty($courseId)) {
if (isset($courseTempList[$courseId])) {
@ -1156,10 +1232,10 @@ class Skill extends Model
$tableRow = array(
'skill_badge' => $resultData['img_mini'],
'skill_name' => Skill::translateName($resultData['name']),
'skill_name' => self::translateName($resultData['name']),
'achieved_at' => api_get_local_time($resultData['acquired_skill_at']),
'course_image' => '',
'course_name' => ''
'course_name' => '',
);
if (!empty($courseInfo)) {
@ -1168,7 +1244,6 @@ class Skill extends Model
}
$tableRows[] = $tableRow;
}
$allowLevels = api_get_configuration_value('skill_levels_names');
$tableResult = '<div class="table-responsive">
@ -1180,47 +1255,55 @@ class Skill extends Model
</thead>
<tbody>
<tr><td>';
//$allowLevels = [];
if (!empty($skillParents)) {
if (empty($allowLevels)) {
$tableResult .= $this->processSkillList($skills);
} else {
$table = new HTML_Table(['class' => 'table table-bordered']);
if (!empty($skillParents)) {
$column = 0;
$skillAdded = [];
foreach ($skillParents as $parentId => $data) {
if (in_array($parentId, $skillAdded)) {
continue;
}
$parentName = '';
if ($data['passed']) {
$parentInfo = $skills[$parentId];
$parentName = $this->processSkillList([$parentInfo], 'mini', false);
$graph = new \Fhaculty\Graph\Graph();
$graph->setAttribute('graphviz.graph.rankdir', 'LR');
foreach ($skillParents as $skillId => $parentList) {
$old = null;
foreach ($parentList as $parent) {
if ($graph->hasVertex($parent['id'])) {
$current = $graph->getVertex($parent['id']);
} else {
$current = $graph->createVertex($parent['id']);
$current->setAttribute('graphviz.data', $parent['data']);
}
$table->setHeaderContents(0, $column, $parentName);
$row = 1;
$skillsToShow = [];
foreach ($data as $skillData) {
if ($skillData['id'] == $parentId) {
continue;
if (!empty($old)) {
if ($graph->hasVertex($old['id'])) {
$nextVertex = $graph->getVertex($old['id']);
} else {
$nextVertex = $graph->createVertex($old['id']);
$nextVertex->setAttribute('graphviz.data', $old['data']);
}
if (empty($skillData['id'])) {
continue;
if (!$nextVertex->hasEdgeTo($current)) {
$nextVertex->createEdgeTo($current);
}
$skillAdded[] = $skillData['id'];
$skillsToShow[] = $skillData;
}
$table->setCellContents(
$row,
$column,
$this->processSkillList($skillsToShow, 'mini', false)
);
$row++;
$column++;
$old = $parent;
}
}
$tableResult .= $table->toHtml();
$table = '<table class ="table table-bordered">';
$root = $graph->getVertex(1);
$table .= '<tr>';
/** @var \Fhaculty\Graph\Vertex $vertex */
foreach ($root->getVerticesEdgeTo() as $vertex) {
$data = $vertex->getAttribute('graphviz.data');
$label = $this->processSkillList([$data], 'mini', false);
$table .= '<td >';
$table .= $label;
$table .= $this->processVertex($vertex);
$table .= '</td>';
}
$table .= '</tr></table>';
$tableResult .= $table;
}
} else {
$tableResult .= get_lang('WithoutAchievedSkills');
@ -1235,7 +1318,7 @@ class Skill extends Model
return [
'skills' => $tableRows,
'table' => $tableResult
'table' => $tableResult,
];
}
@ -1271,7 +1354,7 @@ class Skill extends Model
$skills[1] = array(
'id' => '1',
'name' => get_lang('Root'),
'parent_id' => '0'
'parent_id' => '0',
);
$skillInfo = $this->getSkillInfo($skill_id);
@ -1382,7 +1465,7 @@ class Skill extends Model
'name' => get_lang('SkillRootName'),
'id' => 'root',
'children' => $refs['root']['children'],
'data' => array()
'data' => array(),
);
}
@ -1423,7 +1506,7 @@ class Skill extends Model
}
$simple_tree[] = array(
'name' => $element['name'],
'children' => $children
'children' => $children,
);
}
}
@ -1612,7 +1695,7 @@ class Skill extends Model
$whereConditions = array(
'user_id = ? ' => intval($userId),
'AND skill_id = ? ' => intval($skillId)
'AND skill_id = ? ' => intval($skillId),
);
if ($courseId > 0) {
@ -1624,7 +1707,7 @@ class Skill extends Model
'COUNT(1) AS qty',
$this->table_skill_rel_user,
array(
'where' => $whereConditions
'where' => $whereConditions,
),
'first'
);
@ -1658,8 +1741,8 @@ class Skill extends Model
$skillRelProfileTable,
array(
'where' => array(
'skill_id = ?' => $id
)
'skill_id = ?' => $id,
),
),
'first'
);
@ -1955,7 +2038,7 @@ class Skill extends Model
foreach ($result as $item) {
$skills[] = [
'name' => self::translateName($item['name']),
'acquired_skill_at' => $item['acquired_skill_at']
'acquired_skill_at' => $item['acquired_skill_at'],
];
}
@ -1975,6 +2058,10 @@ class Skill extends Model
return isset($GLOBALS[$camelCase]) ? $GLOBALS[$camelCase] : $name;
}
/**
* @param string $code
* @return mixed|string
*/
public static function translateCode($code)
{
if (empty($code)) {

@ -38,7 +38,7 @@ if ($isStudent) {
$tpl->assign('skill_table', $result['table']);
$tplPath = 'skill/student_report.tpl';
} elseif ($isStudentBoss) {
$selectedStudent = isset($_REQUEST['student']) ? intval($_REQUEST['student']) : 0;
$selectedStudent = isset($_REQUEST['student']) ? (int) $_REQUEST['student'] : 0;
$tableRows = array();
$followedStudents = UserManager::getUsersFollowedByStudentBoss($userId);
@ -60,10 +60,10 @@ if ($isStudent) {
while ($resultData = Database::fetch_assoc($result)) {
$tableRow = array(
'completeName' => $followedStudents[$selectedStudent]['completeName'],
'skillName' => Skill::translateName($resultData['name']),
'achievedAt' => api_format_date($resultData['acquired_skill_at'], DATE_FORMAT_NUMBER),
'courseImage' => Display::return_icon(
'complete_name' => $followedStudents[$selectedStudent]['completeName'],
'skill_name' => Skill::translateName($resultData['name']),
'achieved_at' => api_format_date($resultData['acquired_skill_at'], DATE_FORMAT_NUMBER),
'course_image' => Display::return_icon(
'course.png',
null,
null,
@ -71,7 +71,7 @@ if ($isStudent) {
null,
true
),
'courseName' => $resultData['title']
'course_name' => $resultData['title']
);
$imageSysPath = sprintf("%s%s/course-pic.png", api_get_path(SYS_COURSE_PATH), $resultData['directory']);
@ -92,8 +92,8 @@ if ($isStudent) {
}
$tplPath = 'skill/student_boss_report.tpl';
$tpl->assign('followedStudents', $followedStudents);
$tpl->assign('selectedStudent', $selectedStudent);
$tpl->assign('followed_students', $followedStudents);
$tpl->assign('selected_student', $selectedStudent);
} elseif ($isDRH) {
$selectedCourse = isset($_REQUEST['course']) ? intval($_REQUEST['course']) : null;
$selectedSkill = isset($_REQUEST['skill']) ? intval($_REQUEST['skill']) : 0;
@ -144,9 +144,9 @@ if ($isStudent) {
}
foreach ($tableRows as &$row) {
$row['completeName'] = api_get_person_name($row['firstname'], $row['lastname']);
$row['achievedAt'] = api_format_date($row['acquired_skill_at'], DATE_FORMAT_NUMBER);
$row['courseImage'] = Display::return_icon(
$row['complete_name'] = api_get_person_name($row['firstname'], $row['lastname']);
$row['achieved_at'] = api_format_date($row['acquired_skill_at'], DATE_FORMAT_NUMBER);
$row['course_image'] = Display::return_icon(
'course.png',
null,
null,
@ -167,20 +167,22 @@ if ($isStudent) {
$courseImageThumb->send_image($thumbSysPath);
}
$row['courseImage'] = $thumbWebPath;
$row['course_image'] = $thumbWebPath;
}
}
$tplPath = 'skill/drh_report.tpl';
$tpl->assign('action', $action);
$tpl->assign('courses', $courses);
$tpl->assign('skills', $skills);
$tpl->assign('selectedCourse', $selectedCourse);
$tpl->assign('selectedSkill', $selectedSkill);
$tpl->assign('reportTitle', $reportTitle);
$tpl->assign('selected_course', $selectedCourse);
$tpl->assign('selected_skill', $selectedSkill);
$tpl->assign('report_title', $reportTitle);
}
if (empty($tableRows)) {
Display::addFlash(Display::return_message(get_lang('NoResults')));
}
$tpl->assign('rows', $tableRows);
$templateName = $tpl->get_template($tplPath);
$contentTemplate = $tpl->fetch($templateName);

@ -1,14 +1,17 @@
{% if allow_skill_tool %}
<div class="btn-group">
<a class="btn btn-default" href="{{ _p.web_main }}social/skills_wheel.php">{{ 'SkillsWheel' | get_lang }}</a>
<a class="btn btn-default" href="{{ _p.web_main }}social/skills_wheel.php">
{{ 'SkillsWheel' | get_lang }}
</a>
{% if allow_drh_skills_management %}
<a class="btn btn-default" href="{{ _p.web_main }}admin/skills_wheel.php">{{ 'ManageSkills' | get_lang }}</a>
<a class="btn btn-default" href="{{ _p.web_main }}admin/skills_wheel.php">
{{ 'ManageSkills' | get_lang }}
</a>
{% endif %}
</div>
{% endif %}
<h1 class="page-header">{{ 'Skills' | get_lang }}</h1>
<div class="row">
<div class="col-md-6">
<form class="form-inline" method="post" action="{{ _p.web_self }}">
@ -16,10 +19,12 @@
<select name="course" id="course">
<option value="0">{{ 'Select' | get_lang }}</option>
{% for course in courses %}
<option value="{{ course.id }}" {{ (course.id == selectedCourse) ? 'selected' : '' }}>{{ course.title }}</option>
<option value="{{ course.id }}" {{ (course.id == selected_course) ? 'selected' : '' }}>{{ course.title }}</option>
{% endfor %}
</select>
<button type="submit" class="btn btn-default">{{ 'Filter' | get_lang }}</button>
<button type="submit" class="btn btn-default">
{{ 'Filter' | get_lang }}
</button>
</form>
</div>
<div class="col-md-6">
@ -28,16 +33,19 @@
<select name="skill" id="skill">
<option value="0">{{ 'Select' | get_lang }}</option>
{% for skill in skills %}
<option value="{{ skill.id }}" {{ (skill.id == selectedSkill) ? 'selected' : '' }}>{{ skill.name }}</option>
<option value="{{ skill.id }}" {{ (skill.id == selected_skill) ? 'selected' : '' }}>
{{ skill.name }}
</option>
{% endfor %}
</select>
<button type="submit" class="btn btn-default"><em class="fa fa-filter"></em>{{ 'Filter' | get_lang }}</button>
<button type="submit" class="btn btn-default"><em class="fa fa-filter"></em>
{{ 'Filter' | get_lang }}
</button>
</form>
</div>
</div>
<h2 class="page-header">{{ reportTitle }} <small>{{ reportSubTitle }}</small></h2>
<h2 class="page-header">{{ report_title }}</h2>
{% if rows %}
<table class="table">
<thead>
@ -56,25 +64,21 @@
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
{% if action == 'filterByCourse' %}
<td><img src="{{ row.courseImage }}" alt="{{ row.c_name }}"> {{ row.c_name }}</td>
<td>{{ row.skill_name }}</td>
<td>{{ row.completeName }}</td>
<td>{{ row.achievedAt }}</td>
{% elseif action == 'filterBySkill' %}
<td>{{ row.skill_name }}</td>
<td>{{ row.completeName }}</td>
<td>{{ row.achievedAt }}</td>
<td><img src="{{ row.courseImage }}" alt="{{ row.c_name }}"> {{ row.c_name }}</td>
{% endif %}
</tr>
{% endfor %}
{% for row in rows %}
<tr>
{% if action == 'filterByCourse' %}
<td><img src="{{ row.courseImage }}" alt="{{ row.c_name }}"> {{ row.c_name }}</td>
<td>{{ row.skill_name }}</td>
<td>{{ row.complete_name }}</td>
<td>{{ row.achieved_at }}</td>
{% elseif action == 'filterBySkill' %}
<td>{{ row.skill_name }}</td>
<td>{{ row.complete_name }}</td>
<td>{{ row.achieved_at }}</td>
<td><img src="{{ row.course_image }}" alt="{{ row.c_name }}"> {{ row.c_name }}</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="alert alert-info">
{{ 'NoResults' | get_lang }}
</div>
{% endif %}

@ -12,8 +12,10 @@
<label>{{ 'Students' | get_lang }}</label>
<select name="student" id="student">
<option value="0">{{ 'Select' | get_lang }}</option>
{% for student in followedStudents %}
<option value="{{ student.user_id }}" {{ (student.user_id == selectedStudent) ? 'selected' : '' }}>{{ student.completeName }}</option>
{% for student in followed_students %}
<option value="{{ student.user_id }}" {{ (student.user_id == selected_student) ? 'selected' : '' }}>
{{ student.completeName }}
</option>
{% endfor %}
</select>
<button type="submit" class="btn btn-primary">{{ 'Search' | get_lang }}</button>
@ -30,18 +32,14 @@
</tr>
</thead>
<tbody>
{% for row in rows %}
<tr>
<td>{{ row.completeName }}</td>
<td>{{ row.skillName }}</td>
<td>{{ row.achievedAt }}</td>
<td><img src="{{ row.courseImage }}" alt="{{ row.courseName }}"> {{ row.courseName }}</td>
</tr>
{% endfor %}
{% for row in rows %}
<tr>
<td>{{ row.complete_name }}</td>
<td>{{ row.skill_name }}</td>
<td>{{ row.achieved_at }}</td>
<td><img src="{{ row.course_image }}" alt="{{ row.course_name }}"> {{ row.course_name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="alert alert-info">
{{ 'NoResults' | get_lang }}
</div>
{% endif %}

@ -1,12 +1,13 @@
{% if allow_skill_tool %}
<div class="btn-group">
<a class="btn btn-default" href="{{ _p.web_main }}social/skills_wheel.php">{{ 'SkillsWheel' | get_lang }}</a>
<a class="btn btn-default" href="{{ _p.web_main }}social/skills_wheel.php">
{{ 'SkillsWheel' | get_lang }}
</a>
</div>
{% endif %}
<h1 class="page-header">{{ 'SkillsAcquired' | get_lang }}</h1>
{% if rows %}
<h1 class="page-header">{{ 'SkillsAcquired' | get_lang }}</h1>
<table class="table">
<thead>
<tr>
@ -23,7 +24,10 @@
<td>{{ row.skill_name }}</td>
<td>{{ row.achieved_at }}</td>
{% if row.course_name %}
<td><img src="{{ row.course_image }}" alt="{{ row.course_name }}" width="32"> {{ row.course_name }}</td>
<td>
<img src="{{ row.course_image }}" alt="{{ row.course_name }}" width="32">
{{ row.course_name }}
</td>
{% else %}
<td> - </td>
{% endif %}
@ -31,12 +35,7 @@
{% endfor %}
</tbody>
</table>
{% if skill_table %}
{{ skill_table }}
{% endif %}
{% else %}
<div class="alert alert-info">
{{ 'NoResults' | get_lang }}
</div>
{% endif %}

Loading…
Cancel
Save