Permalink
Browse files

Delete gradeable feature (#2031)

* delete gradeable feature

* resolved permission error

* allowed deletion of checkpoint and numeric gradeable. Also some minor wording tweaks

* add update database commands
  • Loading branch information...
tushargr authored and bmcutler committed Jun 1, 2018
1 parent edcf29f commit 09a2c9247980238763d3e3d71d46fe3796d9068a
@@ -116,5 +116,10 @@
# Remove developer group
os.system("""PGPASSWORD='{}' psql --host={} --username={} --dbname={} -c 'ALTER TABLE users DROP CONSTRAINT users_user_group_check'""".format(*variables))
os.system("""PGPASSWORD='{}' psql --host={} --username={} --dbname={} -c 'ALTER TABLE users ADD CONSTRAINT users_user_group_check CHECK ((user_group >= 1) AND (user_group <= 4))'""".format(*variables))

# To allow delete gradeable
os.system("""PGPASSWORD='{}' psql --host={} --username={} --dbname={} -c 'ALTER TABLE ONLY peer_assign DROP CONSTRAINT peer_assign_g_id_fkey'""".format(*variables))
os.system("""PGPASSWORD='{}' psql --host={} --username={} --dbname={} -c 'ALTER TABLE ONLY peer_assign ADD CONSTRAINT peer_assign_g_id_fkey FOREIGN KEY (g_id) REFERENCES gradeable(g_id) ON UPDATE CASCADE ON DELETE CASCADE'""".format(*variables))

# add user/database
print("\n")
@@ -60,6 +60,7 @@ private function navigationPage() {
}
}
$this->core->getOutput()->renderOutput('Navigation', 'showGradeables', $sections_to_lists);
$this->core->getOutput()->renderOutput('Navigation', 'deleteGradeableForm');
}
/**
@@ -11,6 +11,7 @@
use app\models\GradeableComponent;
use app\models\GradeableComponentMark;
use \DateTime;
use app\libraries\FileUtils;
class AdminGradeableController extends AbstractController {
public function run() {
@@ -33,6 +34,9 @@ public function run() {
case 'quick_link':
$this->quickLink();
break;
case 'delete_gradeable':
$this->deleteGradeable();
break;
default:
$this->viewPage();
break;
@@ -564,18 +568,44 @@ private function modifyGradeable($edit_gradeable) {
"course" => $course,
"gradeable" => $_POST['gradeable_id']);
if (file_put_contents($config_build_file, json_encode($config_build_data, JSON_PRETTY_PRINT)) === false) {
die("Failed to write file {$config_build_file}");
}
$this->returnToNav();
}
private function deleteGradeable() {
$g_id = $_REQUEST['id'];
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] != $this->core->getCsrfToken()) {
die("Invalid CSRF Token");
$this->returnToNav();
}
if (!$this->core->getUser()->accessAdmin()) {
die("Only admins can delete gradeable");
$this->returnToNav();
}
$this->core->getQueries()->deleteGradeable($g_id);
// FIXME/TODO: How to implement delete gradeable...
//$config_build_data = array("semester" => $semester,
// "course" => $course,
// "no_build" => true);
$course_path = $this->core->getConfig()->getCoursePath();
$semester=$this->core->getConfig()->getSemester();
$course = $this->core->getConfig()->getCourse();
$file = FileUtils::joinPaths($course_path,"config","form","form_".$g_id.".json");
if ((file_exists($file)) && (!unlink($file))){
die("Cannot delete form_{$g_id}.json");
}
$config_build_file = "/var/local/submitty/to_be_built/".$semester."__".$course."__".$g_id.".json";
$config_build_data = array("semester" => $semester,
"course" => $course,
"no_build" => true);
if (file_put_contents($config_build_file, json_encode($config_build_data, JSON_PRETTY_PRINT)) === false) {
die("Failed to write file {$config_build_file}");
}
$this->returnToNav();
}
@@ -756,6 +756,14 @@ public function getNumUsersWhoViewedGrade($g_id) {
return intval($this->course_db->row()['cnt']);
}
public function getNumUsersGraded($g_id) {
$this->course_db->query("
SELECT COUNT(*) as cnt FROM gradeable_data
WHERE g_id = ?", array($g_id));
return intval($this->course_db->row()['cnt']);
}
//gets ids of students with non null registration section and null rotating section
public function getRegisteredUsersWithNoRotatingSection(){
$this->course_db->query("
@@ -2104,4 +2112,11 @@ public function checkStudentActiveInCourse($user_id, $course, $semester) {
return $this->submitty_db->row()['active'];
}
/**
* @param string $g_id
*/
public function deleteGradeable($g_id) {
$this->course_db->query("DELETE FROM gradeable WHERE g_id=?", array($g_id));
}
}
@@ -2,6 +2,7 @@
namespace app\views;
use \app\libraries\GradeableType;
use app\models\Gradeable;
use app\libraries\FileUtils;
class NavigationView extends AbstractView {
@@ -252,7 +253,45 @@ public function showGradeables($sections_to_list) {
$gradeable_title = '<label>'.$g_data->getName().'</label><a class="external" href="'.$g_data->getInstructionsURL().'" target="_blank"><i style="margin-left: 10px;" class="fa fa-external-link"></i></a>';
}
else{
$gradeable_title = '<label>'.$g_data->getName().'</label>';
if ($g_data->getType() == GradeableType::ELECTRONIC_FILE) {
# no_team_flag is true if there are no teams else false. Note deleting a gradeable is not allowed is no_team_flag is false.
$no_teams_flag=true;
$all_teams = $this->core->getQueries()->getTeamsByGradeableId($gradeable);
if (!empty($all_teams)) {
$no_teams_flag=false;
}
# no_submission_flag is true if there are no submissions for assignement else false. Note deleting a gradeable is not allowed is no_submission_flag is false.
$no_submission_flag=true;
$semester = $this->core->getConfig()->getSemester();
$course = $this->core->getConfig()->getCourse();
$submission_path = "/var/local/submitty/courses/".$semester."/".$course."/"."submissions/".$gradeable;
if(is_dir($submission_path)) {
$no_submission_flag=false;
}
if(($no_submission_flag == true) && ($no_teams_flag == true)) {
$form_action=$this->core->buildUrl(array('component' => 'admin', 'page' => 'admin_gradeable', 'action' => 'delete_gradeable', 'id' => $gradeable ));
$gradeable_title = <<<HTML
<label>{$g_data->getName()}</label>&nbsp;
<i class="fa fa-times" style="color:red; cursor:pointer;" aria-hidden="true" onclick='newDeleteGradeableForm("{$form_action}","{$g_data->getName()}");'></i>
HTML;
}
else {
$gradeable_title = '<label>'.$g_data->getName().'</label>';
}
}
else if(($g_data->getType() == GradeableType::NUMERIC_TEXT) || (($g_data->getType() == GradeableType::CHECKPOINTS))) {
if(($this->core->getQueries()->getNumUsersGraded($gradeable)) == 0) {
$form_action=$this->core->buildUrl(array('component' => 'admin', 'page' => 'admin_gradeable', 'action' => 'delete_gradeable', 'id' => $gradeable ));
$gradeable_title = <<<HTML
<label>{$g_data->getName()}</label>&nbsp;
<i class="fa fa-times" style="color:red; cursor:pointer;" aria-hidden="true" onclick='newDeleteGradeableForm("{$form_action}","{$g_data->getName()}");'></i>
HTML;
}
else {
$gradeable_title = '<label>'.$g_data->getName().'</label>';
}
}
}
if ($g_data->getType() == GradeableType::ELECTRONIC_FILE){
$display_date = ($title == "FUTURE" || $title == "BETA") ? "<span style=\"font-size:smaller;\">(opens ".$g_data->getOpenDate()->format("m/d/Y{$time}")."</span>)" : "<span style=\"font-size:smaller;\">(due ".$g_data->getDueDate()->format("m/d/Y{$time}")."</span>)";
@@ -653,6 +692,28 @@ public function showGradeables($sections_to_list) {
$return .= <<<HTML
</table>
</div>
HTML;
return $return;
}
public function deleteGradeableForm() {
$return = <<<HTML
<div class="popup-form" id="delete-gradeable-form" style="width:550px; margin-left:-250px;">
<h2>Delete Gradeable</h2>
<p>&emsp;</p>
<p>Note: A gradeable can only be deleted if it has no formed student teams and it has no student submission files and it has no TA grading data.
</p><br />
<form name="delete-confirmation" method="post" action="">
<input type="hidden" name="csrf_token" value="{$this->core->getCsrfToken()}" />
Are you sure you want to delete
<div name="delete-gradeable-message">
</div><br />
<div style="float:right; width:auto;">
<a onclick="$('#delete-gradeable-form').css('display', 'none')" class="btn btn-danger">Cancel</a>
<input class="btn btn-primary" type="submit" value="Delete">
</div>
</form>
</div>
HTML;
return $return;
}
@@ -923,7 +923,7 @@ ALTER TABLE ONLY late_days
--

ALTER TABLE ONLY peer_assign
ADD CONSTRAINT peer_assign_g_id_fkey FOREIGN KEY (g_id) REFERENCES gradeable(g_id) ON UPDATE CASCADE;
ADD CONSTRAINT peer_assign_g_id_fkey FOREIGN KEY (g_id) REFERENCES gradeable(g_id) ON UPDATE CASCADE ON DELETE CASCADE;


--
@@ -157,6 +157,15 @@ function newClassListForm() {
$('[name="upload"]', form).val(null);
}

function newDeleteGradeableForm(form_action, gradeable_name) {
$('.popup-form').css('display', 'none');
var form = $("#delete-gradeable-form");
$('[name="delete-gradeable-message"]', form).html('');
$('[name="delete-gradeable-message"]', form).append('<b>'+gradeable_name+'</b>');
$('[name="delete-confirmation"]', form).attr('action', form_action);
form.css("display", "block");
}

function copyToClipboard(code) {
var download_info = JSON.parse($('#download_info_json_id').val());
var required_emails = [];

0 comments on commit 09a2c92

Please sign in to comment.