Commit 25be2490 authored by Robin Tissot's avatar Robin Tissot
Browse files

Simplifies onboarding code a lot to make it easier to add help in the future.

parent 37d72953
......@@ -16,23 +16,6 @@ var partVM = new Vue({
comparedTranscriptions: [],
intro : introJs()
},
mounted(){
if(onboarding =="True" && !onboarding_edit) {
this.$nextTick(function () {
this.show = {
source: true,
segmentation: true,
visualisation: true,
diplomatic: true
};
let timer = setTimeout(function (){
this.show_onboarding();
}.bind(this),
2000);
});
}
},
computed: {
imageSize() {
return this.part.image.size[0]+'x'+this.part.image.size[1];
......@@ -197,18 +180,6 @@ var partVM = new Vue({
methods: {
show_onboarding(){
this.intro.setOptions({steps: steps_edit});
this.intro.start();
this.intro.onexit(function () {
userProfile.set('onboarding_edit',true);
exitonboarding();
});
this.intro.oncomplete(function () {
userProfile.set('onboarding_edit',true);
exitonboarding();
window.location.href= models_url;
});
},
resetZoom() {
this.zoom.reset();
......
......@@ -81,7 +81,6 @@ class CreateDocument(LoginRequiredMixin, SuccessMessageMixin, DocumentMixin, Cre
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['metadata_form'] = self.get_metadata_formset()
context['onboarding'] = self.request.user.onboarding
return context
def post(self, request, *args, **kwargs):
......@@ -115,7 +114,6 @@ class UpdateDocument(LoginRequiredMixin, SuccessMessageMixin, DocumentMixin, Upd
if 'metadata_form' not in kwargs:
context['metadata_form'] = self.get_metadata_formset(instance=self.object)
context['share_form'] = DocumentShareForm(instance=self.object, request=self.request)
context['onboarding'] = self.request.user.onboarding
return context
def post(self, request, *args, **kwargs):
......@@ -149,8 +147,6 @@ class DocumentImages(LoginRequiredMixin, DocumentMixin, DetailView):
context['process_form'] = DocumentProcessForm(self.object, self.request.user)
context['import_form'] = ImportForm(self.object, self.request.user)
context['export_form'] = ExportForm(self.object, self.request.user)
context['onboarding'] = self.request.user.onboarding
return context
......@@ -251,7 +247,6 @@ class EditPart(LoginRequiredMixin, DetailView):
# so we need context['object'] = document
context['object'] = self.object.document
context['document'] = self.object.document
context['onboarding'] = self.request.user.onboarding
context['part'] = self.object
return context
......@@ -289,7 +284,6 @@ class ModelsList(LoginRequiredMixin, ListView):
if self.document:
context['document'] = self.document
context['object'] = self.document # legacy
context['onboarding'] = self.request.user.onboarding
return context
......
var onboarding_document = userProfile.get('onboarding_document');
var onboarding_images = userProfile.get('onboarding_images');
var onboarding_edit = userProfile.get('onboarding_edit');
var onboarding_trans = userProfile.get('onboarding_trans');
var onboarding_models = userProfile.get('onboarding_models');
/*
Just set ONBOARDING_PAGE in the page before the scripts block.super eg:
//document_form
var document_intro = introJs();
document_intro.setOptions({
'doneLabel':'Next page',
steps: [
{
element: '#nav-doc-tab',
intro: 'Update Document description (Name, Text direction or metadata).',
position: 'bottom',
},
{
element: '#nav-img-tab',
intro: 'Upload images and changes their orders, import and export transcriptions, launch mass automatic segmentation or transcription.',
position: 'bottom',
},
{
element: '#nav-edit-tab',
intro: 'Panels to update transcriptions, baselines and masks.',
position: 'bottom',
},
{
element: '#nav-models-tab',
intro: 'Handle Transcription and Segmentation models related to this document.',
position: 'bottom'
},
]
});
const ONBOARDING_PAGE = 'onboarding_document_form';
//document_edit
steps_edit = [
{
element: '#document-transcriptions',
intro: 'Here you can select which transcription to display. You may have several transcriptions for a given page,<br> for instance a manual one and one created automatically, or two different editions that you have imported.\n',
position: 'bottom',
},
{
element: '#toggle-panels',
intro: 'Show/hide panels',
position: 'bottom',
},
{
element: '#part-edit',
intro: 'Here you can edit your document, by adding or correcting lines and regions, and by entering or correcting transcriptions',
position: 'top',
},
{
element: '#segmentation-panel',
intro: 'In this pane you can manually segment the image or correct the segmentation. You can draw regions or lines onto the image, or change existing lines or regions,<br> and you can also add categories to the different regions and lines (‘main text’, ‘marginal gloss’, ‘page number’ etc.)',
position: 'right',
},
{
element: '#transcription-panel',
intro: 'In this pane you can enter or correct a transcription line-by-line.<br> Clicking on a line of text will bring up a window showing the image of that line, and a box where you can enter or correct the transcription.',
position: 'right',
},
{
element: '#diplomatic-panel',
intro: 'This shows another form for entering transcription.<br> Here you can enter and work with multiple lines at a time, for instance copying and pasting a block of text from another source.\n.',
position: 'left',
},
];
*/
// document_images
var document_images_intro = introJs();
document_images_intro.setOptions('doneLabel', 'Next page');
document_images_intro.setOptions({
steps: [
{
element: '#import-selected',
intro: 'Import document part. <br> accepted formats : IIIF, Pagexml, Alto.',
position: 'bottom'
},
{
element: '#document-export',
intro: 'Import document part. <br> accepted formats : Text, Pagexml, Alto.',
position: 'bottom'
},
{
element: '#train-selected',
intro: 'Train a Segmentation or Transcription model',
position: 'bottom'
},
{
element: '#binarize-selected',
intro: 'Binarize the color of selected images.',
position: 'bottom'
},
{
element: '#segment-selected',
intro: 'Segment selected images.',
position: 'bottom'
},
{
element: '#transcribe-selected',
intro: 'Transcribe automatically the selected images.',
position: 'left'
},
{
element: "#cards-container",
intro: 'This shows all the images for your manuscript. You can select one or multiple images for training, segmentation, transcribing, or export. Clicking on the [fas fa-edit] icon allows you to edit the segmentation and text. The [fa-align-left] icon shows you if the page has been segmented (green = yes, black = no, ‘pulsing’ green = segmentation in progress). The blue progress bar shows the amount of text that has been entered.\n',
position: 'top'
}
]
});
if (typeof ONBOARDING_PAGE !== 'undefined') {
var onboarding_page_done = userProfile.get(ONBOARDING_PAGE) || false;
// models list
var models_intro = introJs();
models_intro.setOptions('doneLabel', 'Next page');
models_intro.setOptions({
steps: [{
element: '#models-table',
intro: 'Here you manage Transcription and Segmentation models related to this document.',
position: 'bottom'
}]
});
if (!onboarding_page_done) {
var intro = introJs().setOptions({'skipLabel': "Skip"});
intro.oncomplete(function() {
userProfile.set(ONBOARDING_PAGE, true);
})
intro.onexit(function(aa) {
if (!userProfile.get(ONBOARDING_PAGE, true)) {
if (confirm("Are you sure you want to avoid further help?")) {
exitOnboarding();
}
}
});
// transcription modal
steps_trans = [
{
element: '#modal-img-container',
intro: "This shows the transcription pane where you can enter or correct a transcription line-by-line.<br>" +
" Clicking on a line of text will bring up a window showing the image of that line, and a box where you can enter or correct the transcription.\n",
position: 'top'
},
{
element: '#trans-input-container',
intro: "Here you can select which transcriptions to show in the transcription pane for comparison.",
position: 'top'
}
];
//document_form
if (ONBOARDING_PAGE == 'onboarding_document_form') {
intro.setOptions({
steps: [
{
element: '#nav-doc-tab',
intro: 'Update Document description (Name, Text direction or metadata).',
position: 'bottom',
},
{
element: '#nav-img-tab',
intro: 'Upload images and changes their orders, import and export transcriptions, launch mass automatic segmentation or transcription.',
position: 'bottom',
},
{
element: '#nav-edit-tab',
intro: 'Panels to update transcriptions, baselines and masks.',
position: 'bottom',
},
{
element: '#nav-models-tab',
intro: 'Handle Transcription and Segmentation models related to this document.',
position: 'bottom'
},
]
});
function exitonboarding() {
if(userProfile.get('onboarding_document') == userProfile.get('onboarding_images') == userProfile.get('onboarding_edit') == userProfile.get('onboarding_trans') == userProfile.get('onboarding_models') == true)
{
} else if (ONBOARDING_PAGE == 'onboarding_images') {
intro.setOptions({
steps: [
{
element: '#import-selected',
intro: 'Import images, segmentation and/or transcriptions. <br> accepted formats : IIIF, Pagexml, Alto.',
position: 'bottom'
},
{
element: '#document-export',
intro: 'Export segmentation and/or transcriptions. <br> accepted formats : Text, Pagexml, Alto.',
position: 'bottom'
},
{
element: '#train-selected',
intro: 'Train a Segmentation or Transcription model.',
position: 'bottom'
},
{
element: '#binarize-selected',
intro: 'Binarize the color of selected images.',
position: 'bottom'
},
{
element: '#segment-selected',
intro: 'Segment selected images.',
position: 'bottom'
},
{
element: '#transcribe-selected',
intro: 'Transcribe automatically the selected images.',
position: 'left'
},
{
element: "#cards-container",
intro: 'This shows all the images for your manuscript. You can select one or multiple images for training, segmentation, transcribing, or export. Clicking on the [fas fa-edit] icon allows you to edit the segmentation and text. The [fa-align-left] icon shows you if the page has been segmented (green = yes, black = no, ‘pulsing’ green = segmentation in progress). The blue progress bar shows the amount of text that has been entered.\n',
position: 'top'
}
]
});
$.ajax({
type: 'PUT',
url: '/api/user/onboarding/',
contentType: "application/json; charset=utf-8",
data: JSON.stringify({
onboarding: "False",
})
} else if (ONBOARDING_PAGE == 'onboarding_edit') {
intro.setOptions({
steps: [
// {
// element: '#document-transcriptions',
// intro: 'Here you can select which transcription to display. You may have several transcriptions for a given page,<br> for instance a manual one and one created automatically, or two different editions that you have imported.',
// position: 'bottom',
// },
{
element: '#seg-panel-btn',
intro: 'In this panel you can manually segment the image or correct the segmentation. You can draw regions or lines onto the image, or change existing lines or regions,<br> and you can also add categories to the different regions and lines (‘main text’, ‘marginal gloss’, ‘page number’ etc.)',
position: 'left',
},
{
element: '#trans-panel-btn',
intro: 'In this pane you can enter or correct a transcription line-by-line.<br> Clicking on a line of text will bring up a window showing the image of that line, and a box where you can enter or correct the transcription.',
position: 'left',
},
{
element: '#diplo-panel-btn',
intro: 'This shows another form for entering transcription.<br> Here you can enter and work with multiple lines at a time, for instance copying and pasting a block of text from another source.\n.',
position: 'left',
},
]
});
} else if (ONBOARDING_PAGE == 'onboarding_models') {
intro.setOptions({
doneLabel: null,
steps: [{
element: '#models-table',
intro: 'Here you manage Transcription and Segmentation models related to this document.',
position: 'bottom'
}]
});
}
document.addEventListener('DOMContentLoaded', function() {
intro.start();
});
}
}
function exitOnboarding() {
$.ajax({
type: 'PUT',
url: '/api/user/onboarding/',
contentType: "application/json; charset=utf-8",
data: JSON.stringify({
onboarding: "False",
})
});
}
......@@ -114,8 +114,10 @@
{% include 'includes/messages.html' %}
<script src="{% static 'js/profile.js' %}"></script>
<script src="{% static 'vendor/introjs/intro.js' %}"></script>
{% if user.onboarding %}
<script src="{% static 'js/onboarding.js' %}"></script>
{% endif %}
{% endif %}
{% endblock scripts %}
</body>
</html>
......@@ -166,40 +166,12 @@
{% endblock %}
{% block scripts %}
<script type="text/javascript">
{% if user.onboarding %}
const ONBOARDING_PAGE = 'onboarding_document_form';
{% endif %}
</script>
{{ block.super }}
<script src="{% static 'js/document_form.js' %}"></script>
<script src="{% static 'js/help.js' %}"></script>
{% if object %}
<script type="text/javascript">
var images_url = "{% url 'document-images' pk=object.pk %}";
</script>
{% else %}
<script type="text/javascript">
var images_url = "#";
</script>
{% endif %}
<script type="text/javascript">
const onboarding = "{{ onboarding }}";
if (onboarding== "True" && !onboarding_document)
{
document_intro.start();
document_intro.onexit(function() {
userProfile.set('onboarding_document',true);
exitonboarding();
});
document_intro.oncomplete(function() {
userProfile.set('onboarding_document',true);
exitonboarding();
window.location.href = images_url;
});
}
</script>
{% endblock %}
......@@ -112,45 +112,29 @@
{% endblock %}
{% block scripts %}
{{ block.super }}
<script type="text/javascript">
'use strict';
const DOCUMENT_ID = {{ document.pk }};
const onboarding = "{{ onboarding }}";
$(document).ready(function() {
// join the ws room
msgSocket.addEventListener('open', function(ev) {
msgSocket.send('{"type": "join-room", "object_cls": "document", "object_pk": {{ document.pk }}}');
});
});
'use strict';
const DOCUMENT_ID = {{ document.pk }};
const ONBOARDING_PAGE = 'onboarding_images';
</script>
{% compress js file document_images %}
<script src="{% static 'vendor/dropzone/dropzone.min.js' %}"></script>
<script src="{% static 'vendor/jquery/jquery-ui.min.js' %}"></script>
<script src="{% static 'js/image_cards.js' %}"></script>
<script src="{% static 'js/lazyload.js' %}"></script>
<script src="{% static 'js/help.js' %}"></script>
{% endcompress %}
{{ block.super }}
<script type="text/javascript">
if (onboarding== "True" && !onboarding_images)
{
document_images_intro.start();
document_images_intro.onexit(function() {
userProfile.set('onboarding_images',true);
exitonboarding();
});
document_images_intro.oncomplete(function() {
var edit_url = "{% url 'document-part-edit' pk=document.pk %}";
userProfile.set('onboarding_images',true);
exitonboarding();
window.location.href = edit_url;
});
'use strict';
}
$(document).ready(function() {
// join the ws room
msgSocket.addEventListener('open', function(ev) {
msgSocket.send('{"type": "join-room", "object_cls": "document", "object_pk": {{ document.pk }}}');
});
});
</script>
{% compress js file document_images %}
<script src="{% static 'vendor/dropzone/dropzone.min.js' %}"></script>
<script src="{% static 'vendor/jquery/jquery-ui.min.js' %}"></script>
<script src="{% static 'js/image_cards.js' %}"></script>
<script src="{% static 'js/lazyload.js' %}"></script>
<script src="{% static 'js/help.js' %}"></script>
{% endcompress %}
{% endblock %}
......@@ -64,24 +64,28 @@
{% block extra_nav %}
<div class="nav-item ml-auto" id="toggle-panels">
<button type="button"
id="source-panel-btn"
@click="togglePanel"
data-target="source"
class="open-panel nav-item btn"
v-bind:class="[ show.source ? 'btn-primary' : 'btn-secondary' ]"
title="{% trans "Source Image" %}"><i class="click-through fas fa-eye"></i></button>
<button type="button"
id="seg-panel-btn"
@click="togglePanel"
data-target="segmentation"
class="open-panel nav-item btn"
v-bind:class="[ show.segmentation ? 'btn-primary' : 'btn-secondary' ]"
title="{% trans "Segmentation" %}"><i class="click-through fas fa-align-left"></i></button>
<button type="button"
id="trans-panel-btn"
@click="togglePanel"
data-target="visualisation"
class="open-panel nav-item btn"
v-bind:class="[ show.visualisation ? 'btn-primary' : 'btn-secondary' ]"
title="{% trans "Transcription" %}"><i class="click-through fas fa-language"></i></button>
<button type="button"
id="diplo-panel-btn"
@click="togglePanel"
data-target="diplomatic"
class="open-panel nav-item btn"
......@@ -611,19 +615,23 @@
</a>
{% endif %}
</div>
</div>
{% endblock %}
</div>
{% endblock %}
{% block scripts %}
{{ block.super }}
<script type="text/javascript">
const READ_DIRECTION = '{{document.read_direction}}';
const TEXT_DIRECTION = '{{document.main_script.text_direction}}';
const DOCUMENT_ID = '{{document.id}}';
var PART_ID = {{part.id}}; // can be changed with next & previous pages
const onboarding = "{{ onboarding }}";
var models_url = "{% url 'document-models' document_pk=document.pk %}";
</script>
{% block scripts %}
<script type="text/javascript">
const READ_DIRECTION = '{{document.read_direction}}';
const TEXT_DIRECTION = '{{document.main_script.text_direction}}';
const DOCUMENT_ID = '{{document.id}}';
var PART_ID = {{part.id}}; // can be changed with next & previous pages
{% if user.onboarding %}
const ONBOARDING_PAGE = "onboarding_edit";
{% endif %}
var models_url = "{% url 'document-models' document_pk=document.pk %}";
</script>
{{ block.super }}
<script type="text/javascript">
'use strict';
......
......@@ -35,13 +35,13 @@
<i class="fas fa-save"></i>
</button>
{% endif %}
{% if model.file %}
<a href="{{ model.file.url }}" class="btn btn-sm btn-primary" title="{% trans "Download" %}" role="button">
<i class="fas fa-file-download"></i>
</a>
{% endif %}
{% if model.owner == request.user and not model.training %}
<form method="POST" class="inline-form" action="{% url 'model-delete' model.pk %}?next={{request.path}}">
{% csrf_token %}
......@@ -54,7 +54,7 @@
</tr>
{% for version in model.history %}
<tr id="model-version-{{version.revision}}" class="versions-{{model.pk}} collapse">
<td title="{% trans "Model name" %}" class="pl-5">{{ version.name }} (epoch #{{version.training_epoch}})</td>
<td></td>
<td title="{% trans "Accuracy" %}">{{ version.accuracy_percent|floatformat:1 }}%</td>
......@@ -62,7 +62,7 @@
<td>
<a href="{{ version.file.url }}">
<button type="button" class="btn btn-sm btn-primary" title="{% trans "Download" %}">
<i class="fas fa-file-download"></i>
<i class="fas fa-file-download"></i>
</button>
</td>
</tr>
......@@ -72,6 +72,13 @@
{% endblock %}
{% block scripts %}
<script type="text/javascript">
'use strict';
{% if user.onboarding %}
const ONBOARDING_PAGE = "onboarding_models";
{% endif %}
</script>
{{ block.super }}
<script type="text/javascript">