[opw-web] First draft of project ranking screen
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [opw-web] First draft of project ranking screen
- Date: Mon, 10 Mar 2014 04:32:38 +0000 (UTC)
commit a630bef6db0d5a14efa280eb900e877ca096f34f
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Sun Mar 9 17:57:20 2014 -0400
First draft of project ranking screen
classes/class_module.php | 1 +
lang/en-gb.php | 7 +
modules/mod_rank_projects.php | 184 ++++++++++++++++++++
schema.sql | 1 +
skins/easterngreen/html/tpl_rank_projects.html | 60 +++++++
.../easterngreen/html/tpl_rank_projects_item.html | 31 ++++
6 files changed, 284 insertions(+), 0 deletions(-)
---
diff --git a/classes/class_module.php b/classes/class_module.php
index 608e6dd..440258b 100644
--- a/classes/class_module.php
+++ b/classes/class_module.php
@@ -22,6 +22,7 @@ class module
array('name' => 'user_profile', 'access' => 'u'),
array('name' => 'view_programs', 'access' => 'g'),
array('name' => 'view_projects', 'access' => 'u'),
+ array('name' => 'rank_projects', 'access' => 'u'),
array('name' => 'program_home', 'access' => 'g'),
array('name' => 'approve_mentors', 'access' => 'a'),
array('name' => 'view_participants', 'access' => 'a'),
diff --git a/lang/en-gb.php b/lang/en-gb.php
index 79730da..4200c49 100644
--- a/lang/en-gb.php
+++ b/lang/en-gb.php
@@ -134,6 +134,13 @@ $lang_data = array(
'mentor_dl_info' => 'Mentor application deadline: [[dl_mentor]]',
'to' => 'to',
+ /* Module: rank_projects */
+ 'rank_projects' => 'Rank applications',
+ 'go' => 'Go',
+ 'no_projects_for_organization' => 'No projects were found for this organization',
+ 'applicant' => 'Applicant',
+ 'rank' => 'Rank',
+
/* Module: view_projects */
'submit_proposal' => 'Submit a proposal',
'edit_project' => 'Edit project',
diff --git a/modules/mod_rank_projects.php b/modules/mod_rank_projects.php
new file mode 100644
index 0000000..b1d8741
--- /dev/null
+++ b/modules/mod_rank_projects.php
@@ -0,0 +1,184 @@
+<?php
+/**
+* Pandora v1
+* @license GPLv3 - http://www.opensource.org/licenses/GPL-3.0
+* @copyright (c) 2012 KDE. All rights reserved.
+*/
+
+if (!defined('IN_PANDORA')) exit;
+
+// Collect some data
+$program_id = 0 + $core->variable('prg', 0);
+$organization_id = 0 + $core->variable('o', 0);
+
+$rankings_save = isset($_POST['rankings_save']);
+
+// Validate program and organization_id ID
+if ($organization_id > 0)
+{
+ $sql = "SELECT COUNT(*) AS count " .
+ "FROM {$db->prefix}organizations o " .
+ "LEFT JOIN {$db->prefix}programs prg " .
+ "ON prg.id = o.program_id " .
+ "WHERE o.id = :organization_id " .
+ "AND prg.id = :program_id " .
+ (!$user->is_admin ? "AND prg.is_active = 1" : "");
+}
+else
+{
+ $sql = "SELECT COUNT(*) AS count " .
+ "FROM {$db->prefix}programs " .
+ "WHERE id = :program_id " .
+ (!$user->is_admin ? "AND is_active = 1" : "");
+}
+
+$row = $db->query($sql,
+ array('program_id' => $program_id,
+ 'organization_id' => $organization_id),
+ true);
+
+$user->restrict($row['count'] > 0);
+
+// Get the role of the user
+$user->get_role($program_id, $role, $user_organization_id);
+
+// Non-admins can only rank their own organization
+if (!$user->is_admin)
+ $user->restrict($organization_id == $user_organization_id);
+
+// Only admins and mentors can access
+$user->restrict($role == 'm', true);
+
+if ($user->is_admin)
+ $organization_select = build_organization_select($program_id, $organization_id, false,
+ null, "organizationSelect");
+else
+ $organization_select = null;
+
+if ($organization_id > 0) {
+ $sql = "SELECT * FROM {$db->prefix}projects prj " .
+ "LEFT JOIN {$db->prefix}participants prt " .
+ "ON prj.id = prt.project_id " .
+ "WHERE prj.organization_id = ? " .
+ "AND prt.role = 's'";
+ $list_data = $db->query($sql, $organization_id);
+} else {
+ $list_data = array();
+}
+
+// See if we need to save anything
+if ($rankings_save) {
+ foreach ($list_data as &$row) {
+ $project_id = $row['project_id'];
+ $field_name = 'ranking' . $project_id;
+
+ if (isset($_POST[$field_name])) {
+ $value = trim($_POST[$field_name]);
+ if ($value === '')
+ $new_ranking = -1;
+ else
+ $new_ranking = (float)$value;
+
+ if ($new_ranking < 0)
+ $new_ranking = -1;
+
+ if (abs($new_ranking - $row['ranking']) > 0.001) {
+ $sql = "UPDATE {$db->prefix}projects " .
+ "SET ranking = :ranking " .
+ "WHERE id = :project_id";
+ $db->query($sql, array('ranking' => $new_ranking,
+ 'project_id' => $project_id));
+ $row['ranking'] = $new_ranking;
+ }
+ }
+ }
+}
+
+// Now order the rows - we do this client side for two reasons:
+// because we change values when saving, and so that we can special-case
+// negative values
+
+function compare_rankings($a, $b) {
+ $arank = $a['ranking'];
+ $brank = $b['ranking'];
+
+ if ($arank < 0)
+ return ($brank < 0) ? 0 : 1;
+
+ if ($brank < 0)
+ return ($arank < 0) ? 0 : -1;
+
+ if ($arank < $brank)
+ return -1;
+ else
+ return ($arank == $brank) ? 0 : 1;
+}
+
+usort($list_data, "compare_rankings");
+
+$skin->assign('apprej_visibility', $user->is_admin);
+
+// Set the return URL (needed when approving projects)
+$return_url = urlencode($core->request_uri());
+
+$projects_list = '';
+
+foreach ($list_data as $row)
+{
+ $project_title = htmlspecialchars($row['title']);
+ $project_desc = htmlspecialchars($row['description']);
+ $username = $row['username'];
+ $profile = $user->profile($username);
+
+ // Trim the title to 60 characters
+ if (strlen($project_title) > 60)
+ {
+ $project_title = trim(substr($project_title, 0, 60)) . '…';
+ }
+
+ // Trim the description to 150 characters
+ if (strlen($project_desc) > 150)
+ {
+ $project_desc = trim(substr($project_desc, 0, 150)) . '…';
+ }
+
+ if ($row['ranking'] < 0)
+ $ranking = '';
+ else
+ $ranking = number_format($row['ranking'], 1);
+
+ // Assign data for each project
+ $skin->assign(array(
+ 'project_title' => $project_title,
+ 'project_description' => nl2br($project_desc),
+ 'project_applicant' => $profile,
+ 'ranking' => $ranking,
+ 'rankingName' => 'ranking' . $row['project_id'],
+ 'project_url' => "?q=view_projects&prg={$program_id}&p={$row['id']}",
+ 'approve_url' => "?q=view_projects&a=approve&prg={$program_id}" .
+ "&p={$row['id']}&r={$return_url}",
+ 'reject_url' => "?q=view_projects&a=reject&prg={$program_id}" .
+ "&p={$row['id']}&r={$return_url}",
+ ));
+
+ $projects_list .= $skin->output('tpl_rank_projects_item');
+}
+
+$title = $lang->get('rank_projects');
+
+// Assign final skin data
+$skin->assign(array(
+ 'program_id' => $program_id,
+ 'view_title' => $title,
+ 'organization_select' => $organization_select,
+ 'projects_list' => $projects_list,
+ 'select_visibility' => $skin->visibility($user->is_admin),
+ 'notice_visibility' => $skin->visibility($organization_id > 0 && count($list_data) == 0),
+ 'list_visibility' => $skin->visibility(count($list_data) > 0)
+));
+
+// Output the module
+$module_title = $title;
+$module_data = $skin->output('tpl_rank_projects');
+
+?>
diff --git a/schema.sql b/schema.sql
index 4fccd07..3688929 100644
--- a/schema.sql
+++ b/schema.sql
@@ -34,6 +34,7 @@ CREATE TABLE `opw_projects` (
`organization_id` mediumint(6) unsigned,
`is_accepted` tinyint(1) NOT NULL DEFAULT -1,
`is_complete` tinyint(1) NOT NULL DEFAULT 0,
+ `ranking` float NOT NULL DEFAULT -1,
PRIMARY KEY (`id`),
FOREIGN KEY (`program_id`) REFERENCES `opw_programs`(`id`),
FOREIGN KEY (`organization_id`) REFERENCES `opw_programs`(`id`)
diff --git a/skins/easterngreen/html/tpl_rank_projects.html b/skins/easterngreen/html/tpl_rank_projects.html
new file mode 100644
index 0000000..5b2ebb2
--- /dev/null
+++ b/skins/easterngreen/html/tpl_rank_projects.html
@@ -0,0 +1,60 @@
+<a href="?q=program_home&prg=[[program_id]]" class="no-decor pull-right top-spacer">
+ <i class="icon-arrow-left"></i>
+ {{project_home}}
+</a>
+
+<h1>[[view_title]]</h1>
+<hr class="hr-head" />
+
+<div class="[[select_visibility]]">
+ [[organization_select]]
+ <button onclick='go_organization(event);' class="btn">{{go}}</button>
+ <script type="text/javascript">
+ function go_organization(e) {
+ e.preventDefault();
+ v = $('#organizationSelect').val();
+ l = document.location;
+ if (/o=\d+/.test(l))
+ new_location = ('' + document.location).replace(/o=\d+/, 'o=' + v);
+ else
+ new_location = l + '&o=' + v;
+ document.location.replace(new_location);
+ }
+ </script>
+</div>
+
+<div class="alert alert-info [[notice_visibility]]">
+ {{no_projects_for_organization}}
+</div>
+
+<div class="[[list_visibility]]">
+ <table class="table table-striped">
+ <thead>
+ <tr>
+ <th style="width:250px">
+ {{project_title}}
+ </th>
+
+ <th style="width:250px">
+ {{applicant}}
+ </th>
+
+ <th>
+ {{description}}
+ </th>
+
+ <th>
+ {{rank}}
+ </th>
+
+ <th style="width:50px;"></th>
+ </tr>
+ </thead>
+
+ <tbody>
+ [[projects_list]]
+ </tbody>
+ </table>
+
+ <button name="rankings_save" type="submit" class="btn btn-primary">{{save}}</button>
+</div>
diff --git a/skins/easterngreen/html/tpl_rank_projects_item.html
b/skins/easterngreen/html/tpl_rank_projects_item.html
new file mode 100644
index 0000000..b03c8cf
--- /dev/null
+++ b/skins/easterngreen/html/tpl_rank_projects_item.html
@@ -0,0 +1,31 @@
+<tr>
+ <td>
+ <a href="[[project_url]]">
+ [[project_title]]
+ </a>
+ </td>
+
+ <td>
+ [[project_applicant]]
+ </td>
+
+ <td>
+ [[project_description]]
+ </td>
+
+ <td>
+ <input style="width:50px;" type="text" size="4" value="[[ranking]]" name="[[rankingName]]"></input>
+ </td>
+
+ <td>
+ <div class="align-right [[apprej_visibility]]">
+ <a href="[[approve_url]]" title="{{approve}}">
+ <i class="icon-ok"></i>
+ </a>
+
+ <a href="[[reject_url]]" title="{{reject}}">
+ <i class="icon-remove"></i>
+ </a>
+ </div>
+ </td>
+</tr>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]