Skip to content

Commit

Permalink
Clear tasks button & simplified ux on tasks page (HumanSignal#186)
Browse files Browse the repository at this point in the history
* clear tasks button & simplify ux on tasks page

* fix some comments

* bug fixes and additions

* Fixes in docs.

* confirm deletion alert

Co-authored-by: Max <[email protected]>
  • Loading branch information
niklub and makseq authored Jan 19, 2020
1 parent 3330efd commit 87139b0
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 66 deletions.
14 changes: 10 additions & 4 deletions docs/source/playground/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,19 @@ order: 201
text-transform: capitalize;
}

.CodeMirror {
min-height: 500px !important;
}

h3 {
margin: 1em !important;
width: unset;
height: unset;
margin: 1em !important;
width: unset;
height: unset;
}

iframe {
border: 0;
margin: 0 !important;
}

#render-editor {
Expand All @@ -41,7 +46,8 @@ order: 201

#editor-wrap {
background-color: rgb(252,252,252);
padding: 5px;
padding: 0;
margin: 0;
display: none;
}

Expand Down
3 changes: 2 additions & 1 deletion docs/themes/htx/layout/layout.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@

<% if (page.type === "playground") { %>
<%- css('css/codemirror') %>
<script src="<%- url_for("/js/jquery.min.js") %>"></script>
<script src="<%- url_for("/js/jquery.min.js") %>"></script>
<script src="<%- url_for("/js/jquery-ui.js") %>"></script>
<script src="<%- url_for("/js/codemirror.js") %>"></script>
<script src="<%- url_for("/js/xml.js") %>"></script>
<% } %>
Expand Down
12 changes: 11 additions & 1 deletion label_studio/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from label_studio.utils.analytics import Analytics
from label_studio.utils.models import ProjectObj, MLBackend
from label_studio.utils.exceptions import ValidationError
from label_studio.utils.io import find_file
from label_studio.utils.io import find_file, delete_dir_content


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -327,6 +327,16 @@ def get_tasks(self):
"""
return self.tasks

def delete_tasks(self):
"""
Deletes all tasks & completions from filesystem, then reloads clean project
:return:
"""
delete_dir_content(self.config['output_dir'])
with io.open(self.config['input_path'], mode='w') as f:
json.dump([], f)
self.reload()

def iter_tasks(self):
sampling = self.config.get('sampling', 'sequential')
if sampling == 'sequential':
Expand Down
10 changes: 10 additions & 0 deletions label_studio/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,16 @@ def api_tasks(task_id):
return make_response(jsonify(task_data), 200)


@app.route('/api/tasks/delete', methods=['DELETE'])
@exception_treatment
def api_tasks_delete():
""" Delete all tasks & completions
"""
project = project_get_or_create()
project.delete_tasks()
return make_response(jsonify({}), 204)


@app.route('/api/projects/1/completions_ids/', methods=['GET'])
@exception_treatment
def api_all_completion_ids():
Expand Down
9 changes: 9 additions & 0 deletions label_studio/static/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,15 @@ a {

.small {
font-size: 75%;
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
}

div.task-buttons .button {
margin: 10px
}

/* editor width */
Expand Down
2 changes: 1 addition & 1 deletion label_studio/templates/setup.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ <h3>Labeling Config</h3>

<!-- Code -->
<textarea name="label_config" cols="40" rows="10" class="project-form htx-html-editor"
id="id_label_config">{{ label_config_full | safe }}</textarea>
id="id_label_config">{{ label_config_full }}</textarea>
<br>

<!-- Input values from imported data -->
Expand Down
138 changes: 79 additions & 59 deletions label_studio/templates/tasks.html
Original file line number Diff line number Diff line change
@@ -1,81 +1,101 @@
{% extends 'base.html' %}
{% block body %}

<div class="ui container">
<div class="wrapper">
<div class="ui container">
<center class="wrapper">

<!-- Statistics -->
<div class="ui one column center aligned page grid">
<div class="ui statistics">
<div class="statistic">
<span class="value">{{ task_ids|length }}</span>
<span class="label">Total tasks</span>
<!-- Statistics -->
<div class="ui two column centered grid">

<div class="column center aligned">
<div class="ui statistic">
<span class="value">{{ task_ids|length }}</span>
<span class="label">Total tasks</span>
{% if show_paths %}
<i class="small">{{ config['input_path'] }}</i>
<i class="small">{{ config['input_path'] }}</i>
{% endif %}
</div>
</div>

<div class="statistic">
<span class="value">{{ completions|length }}</span>
<span class="label">Total completions</span>
<div class="column center aligned">
<div class="ui statistic">
<span class="value">{{ completions|length }}</span>
<span class="label">Total completions</span>
{% if show_paths %}
<i class="small">{{ config['output_dir'] }}</i>
<i class="small">{{ config['output_dir'] }}</i>
{% endif %}
</div>
</div>
</div>
</div>

<br/><br/><br/>
<div class="ui one column center aligned page grid">

<a class="ui button positive" href="/" style="margin-bottom: 14px;">Start Labeling</a>
</div>
<br/><br/>
<div class="two column center aligned clearing task-buttons">
{% if task_ids|length > 0 %}
<a class="ui button positive" href="/">Start Labeling</a>
<a id="clear-tasks-button" class="ui button red">Delete All Tasks</a>
{% else %}
<a class="ui button positive" href="/import">Import Tasks</a>
{% endif %}
<br/><br/>
</div>

</div>

<!-- Table -->
<table>
<tr>
<th>Task ID</th>
<th>Completed at</th>
<th>Completion</th>
</tr>

{% for id in task_ids %}
<!-- Table -->
<table>
<tr>
<td class="text-center">
<a href="/?task_id={{ id }}">
<i class="fas fa-eye eye show-completion"></i>
</a>
&nbsp;
{{ id }}
</td>
<td>{{ completed_at[id] }}</td>
<td class="text-center">
{% if id in completions %}
<i data-task-id="{{ id }}" class="fas fa-trash-alt trash remove-completion"></i>
{% endif %}
</td>
<th>Task ID</th>
<th>Completed at</th>
<th>Completion</th>
</tr>
{% endfor %}
</table>
<br/>

{% for id in task_ids %}
<tr>
<td class="text-center">
<a href="/?task_id={{ id }}">
<i class="fas fa-eye eye show-completion"></i>
</a>
&nbsp;
{{ id }}
</td>
<td>{{ completed_at[id] }}</td>
<td class="text-center">
{% if id in completions %}
<i data-task-id="{{ id }}" class="fas fa-trash-alt trash remove-completion"></i>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<br/>
</div>
</div>
<br/><br/>
</div>


<script>
document.querySelectorAll(".remove-completion").forEach(function (test) {
test.addEventListener("click", function (event) {
var id = event.target.dataset.taskId;
var request = new XMLHttpRequest();
request.open("DELETE", "/api/tasks/" + id + "/completions/" + id + "/", true);
request.onload = function () {
window.location.reload();
};
request.send(null);
})
});

<script>
document.querySelectorAll(".remove-completion").forEach(function (test) {
test.addEventListener("click", function (event) {
var id = event.target.dataset.taskId;
var request = new XMLHttpRequest();
request.open("DELETE", "/api/tasks/" + id + "/completions/" + id + "/", true);
request.onload = function () {
window.location.reload();
document.getElementById("clear-tasks-button").onclick = function (e) {
const deletion_confirmed = confirm(
'You are going to delete all existing tasks.\nWarning! this operation cannot be undone.\nPlease confirm your action.');
if (deletion_confirmed) {
let request = new XMLHttpRequest();
request.open("DELETE", "/api/tasks/delete", true);
request.onload = function () {
window.location.reload();
};
request.send(null);
}
request.send(null);
})
})
</script>
}
</script>

{% endblock %}
6 changes: 6 additions & 0 deletions label_studio/utils/io.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import pkg_resources
import shutil
import glob

from contextlib import contextmanager
from tempfile import mkstemp, mkdtemp
Expand Down Expand Up @@ -78,3 +79,8 @@ def get_data_dir():
if not os.path.exists(data_dir):
os.makedirs(data_dir)
return data_dir


def delete_dir_content(dirpath):
for f in glob.glob(dirpath + '/*'):
os.remove(f)

0 comments on commit 87139b0

Please sign in to comment.