diff --git a/codepot/src/codepot/controllers/issue.php b/codepot/src/codepot/controllers/issue.php index af0e3196..76700abc 100644 --- a/codepot/src/codepot/controllers/issue.php +++ b/codepot/src/codepot/controllers/issue.php @@ -176,37 +176,9 @@ class Issue extends Controller } else { + /* $change_post = $this->input->post('issue_change'); - if ($change_post == 'change') - { - $change = new stdClass(); - $change->type = $this->input->post('issue_change_type'); - $change->status = $this->input->post('issue_change_status'); - $change->owner = $this->input->post('issue_change_owner'); - $change->priority = $this->input->post('issue_change_priority'); - $change->comment = $this->input->post('issue_change_comment'); - - if (!$login['sysadmin?'] && - $this->projects->projectHasMember($project->id, $login['id']) === FALSE) - { - $data['project'] = $project; - $data['message'] = sprintf ( - $this->lang->line('MSG_PROJECT_MEMBERSHIP_REQUIRED'), $projectid); - $this->load->view ($this->VIEW_ERROR, $data); - } - else if ($this->issues->change ($login['id'], $project, $id, $change) === FALSE) - { - $data['project'] = $project; - $data['message'] = 'DATABASE ERROR'; - $this->load->view ($this->VIEW_ERROR, $data); - } - else - { - redirect ("/issue/show/{$projectid}/{$hexid}"); - } - return; - } - else if ($change_post == 'undo') + if ($change_post == 'undo') { if (!$login['sysadmin?'] && $this->projects->projectHasMember($project->id, $login['id']) === FALSE) @@ -227,7 +199,7 @@ class Issue extends Controller redirect ("/issue/show/{$projectid}/{$hexid}"); } return; - } + }*/ $issue = $this->issues->get ($login['id'], $project, $id); if ($issue === FALSE) @@ -664,6 +636,61 @@ class Issue extends Controller } + function xhr_change ($projectid = '', $issueid = '') + { + $this->load->model ('ProjectModel', 'projects'); + $this->load->model ('IssueModel', 'issues'); + + $login = $this->login->getUser (); + + if ($login['id'] == '') + { + $status = 'error - anonymous user'; + } + else + { + $issueid = $this->converter->HexToAscii ($issueid); + $is_nonmember = FALSE; + + $project = $this->projects->get ($projectid); + if ($project === FALSE) + { + $status = "error - failed to get the project {$projectid}"; + } + else if ($project === NULL) + { + $status = "error - no such project {$projectid}"; + } + else if (!$login['sysadmin?'] && + $this->projects->projectHasMember($projectid, $login['id']) === FALSE && + ($is_nonmember = $this->issues->isIssueCreatedBy($projectid, $issueid, $login['id'])) === FALSE) + { + $status = "error - not a member nor a creator - {$login['id']}"; + } + else + { + $change = new stdClass(); + $change->type = $this->input->post('issue_change_type'); + $change->status = $this->input->post('issue_change_status'); + $change->owner = $this->input->post('issue_change_owner'); + $change->priority = $this->input->post('issue_change_priority'); + $change->comment = $this->input->post('issue_change_comment'); + + if ($this->issues->change ($login['id'], $project, $issueid, $change, $is_nonmember) === FALSE) + { + $status = 'error - ' . $this->issues->getErrorMessage(); + } + else + { + $status = 'ok'; + } + } + } + + print $status; + } + + function xhr_edit_comment ($projectid = '', $issueid = '') { $this->load->model ('ProjectModel', 'projects'); diff --git a/codepot/src/codepot/models/issuemodel.php b/codepot/src/codepot/models/issuemodel.php index 3d18bb24..04d9b8dc 100644 --- a/codepot/src/codepot/models/issuemodel.php +++ b/codepot/src/codepot/models/issuemodel.php @@ -313,11 +313,11 @@ class IssueModel extends Model return $issue->id; } - function change ($userid, $project, $id, $change) + function change ($userid, $project, $id, $change, $disallow_state_change) { $now = codepot_nowtodbdate(); - $this->db->trans_start (); + $this->db->trans_begin (); $this->db->where ('projectid', $project->id); $this->db->where ('id', $id); @@ -325,13 +325,54 @@ class IssueModel extends Model $query = $this->db->get ('issue_change'); if ($this->db->trans_status() === FALSE) { - $this->db->trans_complete (); + $this->errmsg = $this->db->_error_message(); + $this->db->trans_rollback (); return FALSE; } $result = $query->result(); $maxsno = (empty($result) || $result[0] == NULL)? 0: $result[0]->maxsno; $newsno = $maxsno + 1; + if ($change->comment == '' || $disallow_state_change) + { + $this->db->where ('projectid', $project->id); + $this->db->where ('id', $id); + $this->db->where ('sno', $maxsno); + $this->db->select('type,status,owner,priority'); + $query = $this->db->get ('issue_change'); + if ($this->db->trans_status() === FALSE) + { + $this->errmsg = $this->db->_error_message(); + $this->db->trans_rollback (); + return FALSE; + } + + $result = $query->result(); + if (!empty($result)) + { + $c = $result[0]; + + if ($c->type == $change->type && + $c->status == $change->status && + $c->owner == $change->owner && + $c->priority == $change->priority) + { + if ($change->comment == '') + { + $this->errmsg = 'empty comment but no state change in the input'; + $this->db->trans_rollback (); + return FALSE; + } + } + else if ($disallow_state_change) + { + $this->errmsg = 'state change disallowed'; + $this->db->trans_rollback (); + return FALSE; + } + } + } + $this->db->set ('projectid', $project->id); $this->db->set ('id', $id); $this->db->set ('sno', $newsno); @@ -345,6 +386,12 @@ class IssueModel extends Model $this->db->set ('updatedon', $now); $this->db->set ('updatedby', $userid); $this->db->insert ('issue_change'); + if ($this->db->trans_status() === FALSE) + { + $this->errmsg = $this->db->_error_message(); + $this->db->trans_rollback (); + return FALSE; + } $this->db->where ('projectid', $project->id); $this->db->where ('id', $id); @@ -355,6 +402,12 @@ class IssueModel extends Model $this->db->set ('updatedon', $now); $this->db->set ('updatedby', $userid); $this->db->update ('issue'); + if ($this->db->trans_status() === FALSE) + { + $this->errmsg = $this->db->_error_message(); + $this->db->trans_rollback (); + return FALSE; + } $this->db->set ('createdon', $now); $this->db->set ('type', 'issue'); @@ -363,10 +416,14 @@ class IssueModel extends Model $this->db->set ('userid', $userid); $this->db->set ('message', $id); $this->db->insert ('log'); + if ($this->db->trans_status() === FALSE) + { + $this->errmsg = $this->db->_error_message(); + $this->db->trans_rollback (); + return FALSE; + } - $this->db->trans_complete (); - if ($this->db->trans_status() === FALSE) return FALSE; - + $this->db->trans_commit (); return $id; } diff --git a/codepot/src/codepot/views/issue_show.php b/codepot/src/codepot/views/issue_show.php index 0a8ba77c..0580abfa 100644 --- a/codepot/src/codepot/views/issue_show.php +++ b/codepot/src/codepot/views/issue_show.php @@ -685,20 +685,61 @@ $(function () { width: '85%', buttons: { 'lang->line('OK')?>': function () { - var comment = $('#issue_change_comment'); - if (comment.val().trim().length <= 0) + if (work_in_progress) return; + + if (!!window.FormData) { - comment.addClass ('ui-state-error'); - setTimeout (function () { - comment.removeClass ('ui-state-error', 500); - }, 500); + // FormData is supported + work_in_progress = true; + + var form_data = new FormData(); + + form_data.append ('issue_change_type', $('#issue_change_type').val()); + form_data.append ('issue_change_status', $('#issue_change_status').val()); + form_data.append ('issue_change_priority', $('#issue_change_priority').val()); + form_data.append ('issue_change_owner', $('#issue_change_owner').val()); + form_data.append ('issue_change_comment', $('#issue_change_comment').val()); + + $('#issue_show_change_form').dialog('disable'); + $.ajax({ + url: codepot_merge_path('', 'id}/{$hex_issue_id}"; ?>'), + type: 'POST', + data: form_data, + mimeType: 'multipart/form-data', + contentType: false, + processData: false, + cache: false, + + success: function (data, textStatus, jqXHR) { + work_in_progress = false; + $('#issue_show_change_form').dialog('enable'); + $('#issue_show_change_form').dialog('close'); + if (data == 'ok') + { + // refresh the page to the head revision + $(location).attr ('href', codepot_merge_path('', 'id}/{$hex_issue_id}"; ?>')); + } + else + { + show_alert ('
' + codepot_htmlspecialchars(data) + '
', "lang->line('Error')?>"); + } + }, + + error: function (jqXHR, textStatus, errorThrown) { + work_in_progress = false; + $('#issue_show_change_form').dialog('enable'); + $('#issue_show_change_form').dialog('close'); + show_alert ('Failed - ' + errorThrown, "lang->line('Error')?>"); + } + }); } else { - $(this).dialog('close'); - $('#issue_change').val ('change'); - $('#issue_change_form').submit (); + show_alert ('
NOT SUPPORTED
', "lang->line('Error')?>"); } + + + }, 'lang->line('Cancel')?>': function () { $(this).dialog('close'); @@ -1035,18 +1076,16 @@ function print_issue_state ($con, $issue, $old, $issue_type_array, $issue_status $new = $issue->changes[0]; print '
'; - print '
'; - print '
'; - printf ('
%s
', codepot_dbdatetodispdate($new->updatedon)); - print '
'; - $user_icon_url = codepot_merge_path (site_url(), '/user/icon/' . $this->converter->AsciiToHex($new->updatedby)); - print " "; - print htmlspecialchars($new->updatedby); - print '
'; - - print '
'; - print '
'; + print '
'; + printf ('
%s
', codepot_dbdatetodispdate($new->updatedon)); + print '
'; + $user_icon_url = codepot_merge_path (site_url(), '/user/icon/' . $this->converter->AsciiToHex($new->updatedby)); + print " "; + print htmlspecialchars($new->updatedby); print '
'; + + print '
'; + print '
'; print '
'; print '
    '; @@ -1181,81 +1220,53 @@ function print_issue_state ($con, $issue, $old, $issue_type_array, $issue_status
    - id}/{$hex_issue_id}/", 'id="issue_change_form"')?> +
    + lang->line('Type'), 'issue_change_type'); + print form_dropdown('issue_change_type', $issue_type_array, set_value('issue_change_type', $issue->type), 'id="issue_change_type"'); - + print ' '; + print form_label ($this->lang->line('Status'), 'issue_change_status'); + print form_dropdown('issue_change_status', $issue_status_array, set_value('issue_change_status', $issue->status), 'id="issue_change_status"'); -
    - lang->line('Type'), - 'issue_change_type') - ?> - type), - 'id="issue_change_type"') - ?> + print ' '; + print form_label ($this->lang->line('Priority'), 'issue_change_priority'); + print form_dropdown ('issue_change_priority', $issue_priority_array, set_value('issue_change_priority', $issue->priority), 'id="issue_change_priority"'); - lang->line('Status'), - 'issue_change_status') - ?> - status), - 'id="issue_change_status"') - ?> + print ' '; + print form_label ($this->lang->line('Owner'), 'issue_change_owner'); + $owner_array = array (); + $found = FALSE; + foreach ($project->members as $t) + { + if ($issue->owner == $t) $found = TRUE; + $owner_array[$t] = $t; + } + if ($found === FALSE) $owner_array[$issue->owner] = $issue->owner; - lang->line('Priority'), - 'issue_change_priority') - ?> + print form_dropdown ('issue_change_owner', $owner_array, set_value('issue_change_owner', $issue->owner), 'id="issue_change_owner"'); + ?> +
    - priority), - 'id="issue_change_priority"') - ?> -
    - -
    +
    + lang->line('Comment'), 'issue_change_comment')?> + lang->line('Preview')?> +
    +
    lang->line('Owner'), 'issue_change_owner'); + $xdata = array ( + 'name' => 'issue_change_comment', + 'value' => set_value ('issue_change_comment', ''), + 'id' => 'issue_change_comment', + 'rows' => 10, + 'cols' => 80 + ); + print form_textarea ($xdata); + ?> +
    - $owner_array = array (); - $found = FALSE; - foreach ($project->members as $t) - { - if ($issue->owner == $t) $found = TRUE; - $owner_array[$t] = $t; - } - if ($found === FALSE) $owner_array[$issue->owner] = $issue->owner; +
    - print form_dropdown ( - 'issue_change_owner', - $owner_array, - set_value('issue_change_owner', $issue->owner), - 'id="issue_change_owner"'); - ?> -
    - -
    - lang->line('Comment'), 'issue_change_comment')?> - lang->line('Preview')?> -
    -
    - 'issue_change_comment', - 'value' => set_value ('issue_change_comment', ''), - 'id' => 'issue_change_comment', - 'rows' => 10, - 'cols' => 80 - ); - print form_textarea ($xdata); - ?> -
    - -
    -
    diff --git a/codepot/src/css/issue.css b/codepot/src/css/issue.css index 859df1a8..d3893355 100644 --- a/codepot/src/css/issue.css +++ b/codepot/src/css/issue.css @@ -11,7 +11,8 @@ ul.codepot-issue-horizontal-list li { float: left; } -.codepot-issue-change ul.codepot-issue-horizontal-list { +.codepot-issue-start ul.codepot-issue-horizontal-list, +.codepot-issue-change ul.codepot-issue-horizontal-list { padding: 0.3em 0 0.3em 0; } @@ -21,11 +22,12 @@ ul.codepot-issue-horizontal-list li { } .codepot-issue-change { - border-top: 1px solid #cccccc; + border-top: 1px dashed #EAEAEA; } +.codepot-issue-start-topline, .codepot-issue-change-topline { - background-color: #EEEEEE; + background-color: #F5F5F5; padding: 0.3em; -moz-border-radius: 3px;