Skip to content

Commit

Permalink
add 'reviewed by' and timestamp to interface, updating view when clicked
Browse files Browse the repository at this point in the history
minor styling adjustments

update composer.lock
  • Loading branch information
MusikAnimal committed Jun 14, 2016
1 parent 3c90f74 commit ed70ca9
Show file tree
Hide file tree
Showing 9 changed files with 1,338 additions and 170 deletions.
1,174 changes: 1,138 additions & 36 deletions composer.lock

Large diffs are not rendered by default.

27 changes: 21 additions & 6 deletions public_html/css/index.css
Expand Up @@ -77,7 +77,8 @@

.row-container {
align-items: center;
padding: 10px;
border-bottom: 1px dashed darkgrey;
padding: 20px 10px;
}

.row-div {
Expand All @@ -100,11 +101,6 @@
margin-right: 20px;
}

.compare-links-container {
padding: 10px;
border-bottom: 1px dashed darkgrey;
}

.compare-pane {
width: 47%;
margin: 2px 1%;
Expand All @@ -119,6 +115,10 @@
/*border: 1px solid blue;*/
}

.diff-div-timestamp {
white-space: nowrap;
}

.report-div {
/*border: 1px solid green;*/
}
Expand Down Expand Up @@ -154,3 +154,18 @@ h1 {
/*border: 1px solid green;*/
display: inline-block;
}

.status-div-reviewer {
margin-top: 10px;
white-space: nowrap;
}

.none {
display: none;
}

/* make anchor tags with empty href unclickable */
a[href=''] {
color: inherit;
pointer-events: none;
}
71 changes: 39 additions & 32 deletions public_html/js/index.js
@@ -1,35 +1,42 @@
function saveState( id, val ) {
buttonId = null;
unusedButtonId = null;
buttonClass = null;
unusedButtonClass = null;
if ( val == 'fixed' ) {
buttonId = '#success' + id;
unusedButtonId = '#danger' + id;
buttonClass = 'success';
unusedButtonClass = 'danger';
} else if ( val == 'false' ) {
buttonId = '#danger' + id;
unusedButtonId = '#success' + id;
unusedButtonClass = 'success';
buttonClass = 'danger';
}
$( buttonId ).removeClass( 'btn-' + buttonClass ).addClass( 'btn-' + buttonClass + '-clicked' ).blur();
$( unusedButtonId ).removeClass( 'btn-' + unusedButtonClass ).addClass( 'btn-secondary' ).prop( 'disabled', 'disabled' ).blur();
var buttonId, unusedButtonId, buttonClass, unusedButtonClass;

$.get( 'review/add',
{ id: id, val: val }
).done( function ( ret ) {
console.log( ret );
if ( ret == 'false' ) {
$( buttonId ).addClass( 'btn-' + buttonClass ).removeClass( 'btn-' + buttonClass + '-clicked' ).blur();
$( unusedButtonId ).removeClass( 'btn-secondary' ).prop( 'disabled', false ).addClass( 'btn-' + unusedButtonClass );
alert( 'There was an error in connecting to database.' );
} else if ( ret == 'Unauthorized' ) {
alert( 'You need to be logged in to be able to review.' );
$( buttonId ).addClass( 'btn-' + buttonClass ).removeClass( 'btn-' + buttonClass + '-clicked' ).blur();
$( unusedButtonId ).removeClass( 'btn-secondary' ).prop( 'disabled', false ).addClass( 'btn-' + unusedButtonClass );
}
}
);
if ( val === 'fixed' ) {
buttonId = '#success' + id;
unusedButtonId = '#danger' + id;
buttonClass = 'success';
unusedButtonClass = 'danger';
} else if ( val === 'false' ) {
buttonId = '#danger' + id;
unusedButtonId = '#success' + id;
unusedButtonClass = 'success';
buttonClass = 'danger';
}
$( buttonId ).removeClass( 'btn-' + buttonClass ).addClass( 'btn-' + buttonClass + '-clicked' ).blur();
$( unusedButtonId ).removeClass( 'btn-' + unusedButtonClass ).addClass( 'btn-secondary' ).prop( 'disabled', 'disabled' ).blur();

$.ajax({
url: 'review/add',
data: {
id: id,
val: val
},
dataType: 'json'
}).done( function ( ret ) {
if ( ret.user ) {
$reviewerNode = $( '.status-div-reviewer-' + id ).show();
$reviewerNode.find('.reviewer-link').prop( 'href', ret.userpage ).text( ret.user );
$reviewerNode.find('.reviewer-timestamp').text( ret.timestamp );
$( unusedButtonId ).removeClass( 'btn-secondary' ).prop( 'disabled', true ).addClass( 'btn-' + unusedButtonClass );
} else {
if ( ret.error === 'Unauthorized' ) {
alert( 'You need to be logged in to be able to review.' );
} else {
alert( 'There was an error in connecting to database.' );
}
$( buttonId ).addClass( 'btn-' + buttonClass ).removeClass( 'btn-' + buttonClass + '-clicked' ).blur();
$( unusedButtonId ).removeClass( 'btn-secondary' ).prop( 'disabled', false ).addClass( 'btn-' + unusedButtonClass );
}
}
);

This comment has been minimized.

Copy link
@kaldari

kaldari Jun 15, 2016

Collaborator

Nitpick: There's some inconsistent bracketing style here. I would suggest changing the style of the done() section to match that of the ajax() section, i.e. reducing the tabbing and combining the last 2 lines into 1: "});". This is the style used most commonly in MediaWiki JS code.

}
4 changes: 2 additions & 2 deletions public_html/templates/base.html
Expand Up @@ -5,8 +5,8 @@
<title>CopyPatrol</title>
{% block stylesheets %}
<link href="//tools-static.wmflabs.org/cdnjs/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css"
rel="stylesheet">
<link href="{{ siteUrl('css/index.css') }}" type="text/css" rel="stylesheet"/>
rel="stylesheet" />
<link href="{{ siteUrl('css/index.css') }}" type="text/css" rel="stylesheet" />
{% endblock %}
{% block scripts %}
<script src="//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/1.12.0/jquery.min.js"
Expand Down
190 changes: 103 additions & 87 deletions public_html/templates/index.html
@@ -1,100 +1,116 @@
{% extends "base.html" %}
{% import _self as macros %}

{% macro reviewer_node( row ) %}
<div class="status-div-reviewer{{ row.reviewed ? '': ' none' }} status-div-reviewer-{{ row.ithenticate_id }}">
Reviewed by
<span>
<a class="reviewer-link" href="{{ row.reviewed_by_url }}" target="_blank">{{ row.status_user }}</a>
</span>
<div class="reviewer-timestamp">
{{ row.review_timestamp }}
</div>
</div>
{% endmacro %}

{% block records %}
{% if records is not empty %}
{% for row in records %}
<div class="row-container container-fluid">
<div class="row-div col-sm-3 page-div">
<b><a href='{{ row.page_link }}' target="_blank"
class={{ row.page_dead ? 'text-danger' : '' }}>{{ row.page_title }}</a></b>
</div>
<div class="row-div col-sm-1 text-center diff-div">
<a href='{{ row.diff }}' target="_blank">Diff</a><br>
<small>
<span>{{ row.diff_timestamp }}</span>
</small>
</div>
<div class="row-div col-sm-2 text-center report-div">
{% if row.editor %}
<a href='{{ row.editor }}'
class={{ row.editor_page_dead ? 'text-danger' : '' }}>{{ row.editor }}</a><br>
<small>
<span><a href='{{ row.editor_talk }}'
class='{{ row.editor_talk_dead ? 'text-danger' : '' }}'
target="_blank">Talk </a>| </span>
<span><a href='{{ row.editor_contribs }}' target="_blank">Contributions</a> </span><br>
<span>Edit count: {{ row.editcount }}</span>
<div class="row-container">
<div class="container-fluid">
<div class="row-div col-sm-3 page-div">
<b><a href='{{ row.page_link }}' target="_blank"
class={{ row.page_dead ? 'text-danger' : '' }}>{{ row.page_title }}</a></b>
</div>
<div class="row-div col-sm-1 text-center diff-div">
<a href='{{ row.diff }}' target="_blank">Diff</a><br>
<small class="diff-div-timestamp">
<span>{{ row.diff_timestamp }}</span>
</small>
{% else %}
<span class=" glyphicon glyphicon-exclamation-sign"></span>
<div class="text-muted" data-toggle="tooltip" data-placement="bottom"
title="This usually means that the editor was anonymous. It may also mean that the data is not available in Labs database yet.">
Editor not found
</div>
{% endif %}
</div>
<div class="row-div col-sm-2 text-center report-div">
{% if row.editor %}
<a href='{{ row.editor }}'
class={{ row.editor_page_dead ? 'text-danger' : '' }}>{{ row.editor }}</a><br>
<small>
<span><a href='{{ row.editor_talk }}'
class='{{ row.editor_talk_dead ? 'text-danger' : '' }}'
target="_blank">Talk</a> | </span>
<span><a href='{{ row.editor_contribs }}' target="_blank">Contributions</a> </span><br>
<span>Edit count: {{ row.editcount }}</span>
</small>
{% else %}
<span class=" glyphicon glyphicon-exclamation-sign"></span>
<div class="text-muted" data-toggle="tooltip" data-placement="bottom"
title="This usually means that the editor was anonymous. It may also mean that the data is not available in Labs database yet.">
Editor not found
</div>
{% endif %}
</div>
<div class="row-div col-sm-3 text-center wikiproject-div">
{% if row.wikiprojects is not empty %}
{% for wp in row.wikiprojects %}
<span class="row-div wproject">{{ wp }}</span>
{% endfor %}
{% endif %}
</div>
<div class="row-div col-sm-2 text-center status-div">
{% if row.status == 'fixed' %}
<input type="button" id="{{ 'success' ~ row.ithenticate_id }}"
class="btn btn-success-clicked btn-block"
title="The edit was a copyright violation and has been reverted" value="Page fixed"
onclick="saveState({{ row.ithenticate_id }}, 'fixed')">
<input type="button" id="{{ 'danger' ~ row.ithenticate_id }}"
class="btn btn-secondary btn-block"
title="The edit is a false positive, nothing needs to be done" value="No action needed"
disabled>
{% elseif row.status == 'false' %}
<input type="button" id="{{ 'success' ~ row.ithenticate_id }}"
class="btn btn-success btn-block"
title="The edit was a copyright violation and has been reverted" value="Page fixed"
disabled>
<input type="button" id="{{ 'danger' ~ row.ithenticate_id }}"
class="btn btn-danger-clicked btn-block"
title="The edit is a false positive, nothing needs to be done" value="No action needed"
onclick="saveState({{ row.ithenticate_id }}, 'false')">
{% elseif row.status == NULL %}
<input type="button" id="{{ 'success' ~ row.ithenticate_id }}"
class="btn btn-success btn-outline btn-block"
title="The edit was a copyright violation and has been reverted" value="Page fixed"
onclick="saveState({{ row.ithenticate_id }}, 'fixed')">
<input type="button" id="{{ 'danger' ~ row.ithenticate_id }}"
class="btn btn-danger btn-block"
title="The edit is a false positive, nothing needs to be done" value="No action needed"
onclick="saveState({{ row.ithenticate_id }}, 'false')">
{% endif %}
{{ macros.reviewer_node( row ) }}
</div>
</div>
<div class="row-div col-sm-3 text-center wikiproject-div">
{% if row.wikiprojects is not empty %}
{% for wp in row.wikiprojects %}
<span class="row-div wproject">{{ wp }}</span>
<div class="compare-links-container">
<a class="btn btn-xs btn-primary compare-button" href='{{ r }}' target="_blank">
<span class="glyphicon glyphicon-new-window"></span>
Turnitin report
</a><br>
{% if row.copyvios is not empty %}
{% for copy in row.copyvios %}
<button class="btn btn-xs btn-primary dropdown-toggle compare-button" onclick="">
<span class="glyphicon glyphicon-chevron-down" aria-hidden="true"></span>
Compare
</button>
<a href="{{ copy }}" target="_blank">{{ copy }}</a><br/>
<div class="compare-div" id="{{ 'comp' }}">
<div class="compare-edit compare-pane">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget
dolor.
</div>
<div class="compare-website compare-pane">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget
dolor.
</div>
</div>
{% endfor %}
{% endif %}
</div>
<div class="row-div col-sm-2 text-center status-div">
{% if row.status == 'fixed' %}
<input type="button" id="{{ 'success' ~ row.ithenticate_id }}"
class="btn btn-success-clicked btn-block"
title="The edit was a copyright violation and has been reverted" value="Page fixed"
onclick="saveState({{ row.ithenticate_id }}, 'fixed')">
<input type="button" id="{{ 'danger' ~ row.ithenticate_id }}"
class="btn btn-secondary btn-block"
title="The edit is a false positive, nothing needs to be done" value="No action needed"
disabled>
{% elseif row.status == 'false' %}
<input type="button" id="{{ 'success' ~ row.ithenticate_id }}"
class="btn btn-success btn-block"
title="The edit was a copyright violation and has been reverted" value="Page fixed"
disabled>
<input type="button" id="{{ 'danger' ~ row.ithenticate_id }}"
class="btn btn-danger-clicked btn-block"
title="The edit is a false positive, nothing needs to be done" value="No action needed"
onclick="saveState({{ row.ithenticate_id }}, 'false')">
{% elseif row.status == NULL %}
<input type="button" id="{{ 'success' ~ row.ithenticate_id }}"
class="btn btn-success btn-outline btn-block"
title="The edit was a copyright violation and has been reverted" value="Page fixed"
onclick="saveState({{ row.ithenticate_id }}, 'fixed')">
<input type="button" id="{{ 'danger' ~ row.ithenticate_id }}"
class="btn btn-danger btn-block"
title="The edit is a false positive, nothing needs to be done" value="No action needed"
onclick="saveState({{ row.ithenticate_id }}, 'false')">
{% endif %}
</div>
</div>
<div class="compare-links-container">
<a class="btn btn-xs btn-primary compare-button" href='{{ r }}' target="_blank">
<span class="glyphicon glyphicon-new-window"></span>
Turnitin report
</a><br>
{% if row.copyvios is not empty %}
{% for copy in row.copyvios %}
<button class="btn btn-xs btn-primary dropdown-toggle compare-button" onclick="">
<span class="glyphicon glyphicon-chevron-down" aria-hidden="true"></span>
Compare
</button>
<a href="{{ copy }}" target="_blank">{{ copy }}</a><br/>
<div class="compare-div" id="{{ 'comp' }}">
<div class="compare-edit compare-pane">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget
dolor.
</div>
<div class="compare-website compare-pane">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget
dolor.
</div>
</div>
{% endfor %}
{% endif %}
</div>
{% endfor %}
{% endif %}
Expand Down
2 changes: 1 addition & 1 deletion src/Controllers/AuthHandler.php
Expand Up @@ -110,7 +110,7 @@ protected function handleCallback() {
$accessToken = $this->oauth->complete( $token, $verifyCode );
$user = $this->manager->getUserData( $accessToken );
$this->authManager->login( $user );
$this->flash( 'info', 'You are now succesfully logged in as ' . $user->getName() . '. Please note that
$this->flash( 'info', 'You are now successfully logged in as ' . $user->getName() . '. Please note that
this tool is set up to credit users for their reviews. Your username will be assocated with your
reviews, be publicly visible and retained indefinitely' );
} catch ( \Exception $e ) {
Expand Down
7 changes: 6 additions & 1 deletion src/Controllers/CopyPatrol.php
Expand Up @@ -108,6 +108,11 @@ protected function handleGet() {
$records[$key]['editor_page_dead'] = false;
$records[$key]['editor_talk_dead'] = false;
}
$records[$key]['reviewed'] = $record['status_user'] ? true : false;

This comment has been minimized.

Copy link
@Niharika29

Niharika29 Jun 14, 2016

Collaborator

You don't need this extra key. You can check if 'status_user' exists directly instead of adding another key and checking it.

if ( $records[$key]['reviewed'] ) {
$records[$key]['reviewed_by_url'] = $this->getUserPage( $record['status_user'] );
$records[$key]['review_timestamp'] = $this->formatTimestamp( $record['review_timestamp'] );
}
$records[$key]['wikiprojects'] = $this->wikiprojectDao->getWikiProjects( $record['page_title'] );
$records[$key]['page_title'] = $this->removeUnderscores( $record['page_title'] );
$cleanWikiprojects = array();
Expand Down Expand Up @@ -156,7 +161,7 @@ public function getReportLink( $ithenticateId ) {
*/
public function formatTimestamp( $datetime ) {
$datetime = strtotime( $datetime );
return date( 'd-m-y h:m:s', $datetime );
return date( 'Y-m-d h:m', $datetime );
}


Expand Down

0 comments on commit ed70ca9

Please sign in to comment.