libreqda 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- CHANGELOG.md +481 -0
- libreqda-1.2.0.dist-info/LICENSE.txt +28 -0
- libreqda-1.2.0.dist-info/METADATA +131 -0
- libreqda-1.2.0.dist-info/RECORD +255 -0
- libreqda-1.2.0.dist-info/WHEEL +4 -0
- libreqda-1.2.0.dist-info/entry_points.txt +4 -0
- scripts/babelrc +8 -0
- scripts/dist/LICENSE.txt +33 -0
- scripts/dist/RELEASE.txt +23 -0
- scripts/dist/macos/libreqda.icns +0 -0
- scripts/dist/macos/macos.spec +43 -0
- scripts/dist/macos/plist.patch +10 -0
- scripts/dist/macos/taguette.icns +0 -0
- scripts/dist/macos/taguette_console_wrapper +4 -0
- scripts/dist/macos.sh +32 -0
- scripts/dist/pyinstaller_entrypoint.py +19 -0
- scripts/dist/windows/windows-installer.iss +51 -0
- scripts/dist/windows/windows.spec +39 -0
- scripts/edugain/worker_update_edugain_idps.py +89 -0
- scripts/edugain/worker_update_edugain_idps.sh +9 -0
- scripts/make_password_reset_link.py +56 -0
- scripts/make_theme.py +99 -0
- scripts/new_db_revision.sh +8 -0
- scripts/register_user.py +76 -0
- scripts/update_pot.sh +33 -0
- scripts/update_translations.sh +17 -0
- scripts/validate.py +140 -0
- scripts/wipe_and_disable_user.py +90 -0
- taguette/__init__.py +13 -0
- taguette/access_control.py +145 -0
- taguette/convert.py +623 -0
- taguette/database/__init__.py +177 -0
- taguette/database/base.py +9 -0
- taguette/database/copy.py +433 -0
- taguette/database/models.py +920 -0
- taguette/demodata.py +688 -0
- taguette/export.py +500 -0
- taguette/extract.py +287 -0
- taguette/import_codebook.py +110 -0
- taguette/l10n/de_DE/LC_MESSAGES/taguette_javascript.mo +0 -0
- taguette/l10n/de_DE/LC_MESSAGES/taguette_main.mo +0 -0
- taguette/l10n/el_EL/LC_MESSAGES/taguette_javascript.mo +0 -0
- taguette/l10n/el_GR/LC_MESSAGES/taguette_javascript.mo +0 -0
- taguette/l10n/el_GR/LC_MESSAGES/taguette_main.mo +0 -0
- taguette/l10n/en_US/LC_MESSAGES/taguette_javascript.mo +0 -0
- taguette/l10n/en_US/LC_MESSAGES/taguette_main.mo +0 -0
- taguette/l10n/es_ES/LC_MESSAGES/taguette_javascript.mo +0 -0
- taguette/l10n/es_ES/LC_MESSAGES/taguette_main.mo +0 -0
- taguette/l10n/fr_FR/LC_MESSAGES/taguette_javascript.mo +0 -0
- taguette/l10n/fr_FR/LC_MESSAGES/taguette_main.mo +0 -0
- taguette/l10n/id_ID/LC_MESSAGES/taguette_javascript.mo +0 -0
- taguette/l10n/id_ID/LC_MESSAGES/taguette_main.mo +0 -0
- taguette/l10n/it_IT/LC_MESSAGES/taguette_javascript.mo +0 -0
- taguette/l10n/it_IT/LC_MESSAGES/taguette_main.mo +0 -0
- taguette/l10n/nl_NL/LC_MESSAGES/taguette_javascript.mo +0 -0
- taguette/l10n/nl_NL/LC_MESSAGES/taguette_main.mo +0 -0
- taguette/l10n/pt_PT/LC_MESSAGES/taguette_javascript.mo +0 -0
- taguette/l10n/pt_PT/LC_MESSAGES/taguette_main.mo +0 -0
- taguette/l10n/sv_SE/LC_MESSAGES/taguette_javascript.mo +0 -0
- taguette/l10n/sv_SE/LC_MESSAGES/taguette_main.mo +0 -0
- taguette/loki_handler.py +107 -0
- taguette/main.py +649 -0
- taguette/migrations/env.py +72 -0
- taguette/migrations/script.py.mako +24 -0
- taguette/migrations/versions/09c662cd9483_make_documents_filename_not_null.py +39 -0
- taguette/migrations/versions/1b29e68900c1_add_user_roles.py +55 -0
- taguette/migrations/versions/1b96a606551d_update_user_to_have_a_display_name.py +34 -0
- taguette/migrations/versions/2467bab602b7_add_color_column_to_tags_table.py +33 -0
- taguette/migrations/versions/382db36f20f4_add_user_disabled.py +66 -0
- taguette/migrations/versions/43d6c240309d_remove_document_groups.py +81 -0
- taguette/migrations/versions/447d636f72c5_cascades.py +40 -0
- taguette/migrations/versions/491de2dc7cd7_add_indexes.py +51 -0
- taguette/migrations/versions/4c55b3b3ff30_user_login_length.py +58 -0
- taguette/migrations/versions/61a4abcc8769_user_with_parent_for_permissions.py +40 -0
- taguette/migrations/versions/6489b5f9cfb5_increase_password_hash_size.py +34 -0
- taguette/migrations/versions/679f625e6e6a_fix_unique_tags.py +59 -0
- taguette/migrations/versions/77c4543a5b9b_add_parent_id_column_to_collection_table.py +41 -0
- taguette/migrations/versions/7c94b7a31e69_add_is_archived_column_to_projets.py +39 -0
- taguette/migrations/versions/7f56de97e3c8_change_edugain_displayname_length.py +42 -0
- taguette/migrations/versions/807c0cc0ecf6_remove_invalid_hltags.py +43 -0
- taguette/migrations/versions/80b1cc9d4c22_add_user_email.py +35 -0
- taguette/migrations/versions/91ade71ccf4d_add_user_language.py +28 -0
- taguette/migrations/versions/955db2e523d1_add_collections_tables_and_associations_.py +60 -0
- taguette/migrations/versions/a1b2c3d4e5f6_add_user_hide_code_counts.py +28 -0
- taguette/migrations/versions/b23f3b7a638e_add_user_password_change_date.py +36 -0
- taguette/migrations/versions/b7c1e2d3f4a5_add_project_compact_layout.py +28 -0
- taguette/migrations/versions/bc8e0e0677e9_rename_command_fields.py +126 -0
- taguette/migrations/versions/bce44849c2f2_lowercase_logins.py +96 -0
- taguette/migrations/versions/ca076140922f_update_user_for_external_logins.py +32 -0
- taguette/migrations/versions/d86c45d7aa8a_add_document_direction.py +127 -0
- taguette/migrations/versions/db5e31a0233d_remove_blank_highlights.py +88 -0
- taguette/migrations/versions/dd37d9027a24_unique_tags.py +68 -0
- taguette/migrations/versions/de678cef2a94_add_project_id_to_collections_and_.py +41 -0
- taguette/migrations/versions/e459991d960e_add_table_edugainidps.py +39 -0
- taguette/migrations/versions/e4cf92942271_add_index.py +29 -0
- taguette/migrations/versions/e4e090a5b511_remove_commands_document_id_fk.py +38 -0
- taguette/migrations/versions/e9a9f1c77971_add_favorite_column_to_document.py +32 -0
- taguette/migrations/versions/ecb4065de575_don_t_use_server_default_now_timezone_.py +44 -0
- taguette/migrations/versions/fbdc29566f62_edugain_fix_field_type.py +42 -0
- taguette/migrations/versions/fdc6eb54b034_add_parent_id_column_to_tags_table.py +31 -0
- taguette/static/README.md +34 -0
- taguette/static/alt_templates/.gitkeep +0 -0
- taguette/static/assets/test/logos/monsters-university-logo.png +0 -0
- taguette/static/css/custom.css +1696 -0
- taguette/static/css/fa-all.min.css +5 -0
- taguette/static/css/themed.css +3 -0
- taguette/static/css/themed.css.map +25 -0
- taguette/static/css/vendor/bootstrap-treeview.min.css +1 -0
- taguette/static/css/vendor/bootstrap.min.css +6 -0
- taguette/static/css/vendor/font/context-menu-icons.eot +0 -0
- taguette/static/css/vendor/font/context-menu-icons.ttf +0 -0
- taguette/static/css/vendor/font/context-menu-icons.woff +0 -0
- taguette/static/css/vendor/font/context-menu-icons.woff2 +0 -0
- taguette/static/css/vendor/hierarchy-select.min.css +1 -0
- taguette/static/css/vendor/introjs.min.css +2 -0
- taguette/static/css/vendor/jquery.contextMenu.min.css +16 -0
- taguette/static/favicon.ico +0 -0
- taguette/static/js/codebook-viz.js +428 -0
- taguette/static/js/collection/context-menu.js +180 -0
- taguette/static/js/collection/hierarchy-select.js +71 -0
- taguette/static/js/collection/manager.js +217 -0
- taguette/static/js/document/context-menu.js +92 -0
- taguette/static/js/document/custom-select.js +82 -0
- taguette/static/js/document/manager.js +943 -0
- taguette/static/js/document/treeview.js +593 -0
- taguette/static/js/highlight/README.md +18 -0
- taguette/static/js/highlight/crud.js +119 -0
- taguette/static/js/highlight/extracts.js +497 -0
- taguette/static/js/highlight/loader.js +109 -0
- taguette/static/js/highlight/renderer.js +405 -0
- taguette/static/js/login.js +15 -0
- taguette/static/js/permissions.js +153 -0
- taguette/static/js/polling-event.js +145 -0
- taguette/static/js/project/intro.js +524 -0
- taguette/static/js/project/manager.js +0 -0
- taguette/static/js/project/search.js +124 -0
- taguette/static/js/tag/context-menu.js +133 -0
- taguette/static/js/tag/explore-codes.js +400 -0
- taguette/static/js/tag/hierarchy-select.js +69 -0
- taguette/static/js/tag/manager.js +545 -0
- taguette/static/js/tag/treeview.js +613 -0
- taguette/static/js/taguette.js +1790 -0
- taguette/static/js/utilities.js +714 -0
- taguette/static/js/vendor/bootstrap-treeview-custum.js +421 -0
- taguette/static/js/vendor/bootstrap-treeview-custum.min.js +1 -0
- taguette/static/js/vendor/bootstrap-treeview-default.min.js +1 -0
- taguette/static/js/vendor/bootstrap.bundle.min.js +7 -0
- taguette/static/js/vendor/bootstrap.bundle.min.js.map +1 -0
- taguette/static/js/vendor/hierarchy-select.min.js +1 -0
- taguette/static/js/vendor/introjs.min.js +17 -0
- taguette/static/js/vendor/jquery-3.7.1.js +2 -0
- taguette/static/js/vendor/jquery.contextMenu.min.js +2 -0
- taguette/static/libreqda.ico +0 -0
- taguette/static/logo-h.png +0 -0
- taguette/static/logo.png +0 -0
- taguette/static/logo_blanc.png +0 -0
- taguette/static/missing.png +0 -0
- taguette/static/robots.txt +2 -0
- taguette/static/scss/components/_badge.scss +42 -0
- taguette/static/scss/components/_button.scss +169 -0
- taguette/static/scss/components/_checkbox.scss +40 -0
- taguette/static/scss/components/_context_menu.scss +28 -0
- taguette/static/scss/components/_custom_select.scss +150 -0
- taguette/static/scss/components/_dropdown.scss +43 -0
- taguette/static/scss/components/_form.scss +54 -0
- taguette/static/scss/components/_modal.scss +57 -0
- taguette/static/scss/components/_project_card.scss +163 -0
- taguette/static/scss/components/_tag.scss +308 -0
- taguette/static/scss/components/_treeview.scss +76 -0
- taguette/static/scss/custom.scss +809 -0
- taguette/static/scss/layout/_credits.scss +62 -0
- taguette/static/scss/layout/_footer.scss +6 -0
- taguette/static/scss/layout/_navigation.scss +165 -0
- taguette/static/scss/layout/_sidebar.scss +37 -0
- taguette/static/scss/themes/default/_variables.scss +103 -0
- taguette/static/scss/themes/default/theme.css +3 -0
- taguette/static/scss/themes/default/theme.css.map +26 -0
- taguette/static/scss/themes/default/theme.scss +4 -0
- taguette/static/webfonts/BadScript-OFL.txt +94 -0
- taguette/static/webfonts/BadScript.ttf +0 -0
- taguette/static/webfonts/Montserrat-Light.ttf +0 -0
- taguette/static/webfonts/Montserrat-OFL.txt +93 -0
- taguette/static/webfonts/fa-brands-400.eot +0 -0
- taguette/static/webfonts/fa-brands-400.svg +1184 -0
- taguette/static/webfonts/fa-brands-400.ttf +0 -0
- taguette/static/webfonts/fa-brands-400.woff +0 -0
- taguette/static/webfonts/fa-brands-400.woff2 +0 -0
- taguette/static/webfonts/fa-regular-400.eot +0 -0
- taguette/static/webfonts/fa-regular-400.svg +467 -0
- taguette/static/webfonts/fa-regular-400.ttf +0 -0
- taguette/static/webfonts/fa-regular-400.woff +0 -0
- taguette/static/webfonts/fa-regular-400.woff2 +0 -0
- taguette/static/webfonts/fa-solid-900.eot +0 -0
- taguette/static/webfonts/fa-solid-900.svg +2618 -0
- taguette/static/webfonts/fa-solid-900.ttf +0 -0
- taguette/static/webfonts/fa-solid-900.woff +0 -0
- taguette/static/webfonts/fa-solid-900.woff2 +0 -0
- taguette/templates/alt_templates/.gitkeep +0 -0
- taguette/templates/archived_projects.html +50 -0
- taguette/templates/auth/account.html +74 -0
- taguette/templates/auth/cilogon.login.html +89 -0
- taguette/templates/auth/email_reset_password.html +5 -0
- taguette/templates/auth/external_account.html +60 -0
- taguette/templates/auth/login.html +144 -0
- taguette/templates/auth/reset_password.html +27 -0
- taguette/templates/auth/token_needed.html +7 -0
- taguette/templates/base.html +209 -0
- taguette/templates/bug_report.html +158 -0
- taguette/templates/cookies_prompt.html +15 -0
- taguette/templates/downloads.html +127 -0
- taguette/templates/email_bug_report.txt +9 -0
- taguette/templates/email_reset_password.txt +5 -0
- taguette/templates/error.html +8 -0
- taguette/templates/export_codebook.html +20 -0
- taguette/templates/export_document.html +20 -0
- taguette/templates/export_highlights.html +47 -0
- taguette/templates/index.html +347 -0
- taguette/templates/maintenance.html +8 -0
- taguette/templates/messages.js +74 -0
- taguette/templates/modal/change_document.html +68 -0
- taguette/templates/modal/create_collection.html +100 -0
- taguette/templates/modal/create_document.html +84 -0
- taguette/templates/modal/create_highlight.html +38 -0
- taguette/templates/modal/create_tag.html +73 -0
- taguette/templates/modal/explore_codes.html +58 -0
- taguette/templates/modal/manage_collaborators.html +44 -0
- taguette/templates/modal/merge_tag.html +49 -0
- taguette/templates/new_password.html +32 -0
- taguette/templates/partials/alert.html +16 -0
- taguette/templates/partials/codebook_viz_modal.html +34 -0
- taguette/templates/partials/confirm.html +17 -0
- taguette/templates/partials/document_toolbar.html +37 -0
- taguette/templates/partials/hlinfo.html +13 -0
- taguette/templates/partials/project_card.html +44 -0
- taguette/templates/partials/project_card_archived.html +41 -0
- taguette/templates/partials/project_sidebar.html +99 -0
- taguette/templates/partials/spinner.html +11 -0
- taguette/templates/permissions.html +54 -0
- taguette/templates/project.html +288 -0
- taguette/templates/project_delete.html +17 -0
- taguette/templates/project_import.html +122 -0
- taguette/templates/project_import_codebook.html +34 -0
- taguette/templates/project_import_codebook_confirm.html +49 -0
- taguette/templates/project_new.html +31 -0
- taguette/templates/tos.html +8 -0
- taguette/templates/trans.js +7 -0
- taguette/templates/welcome.html +15 -0
- taguette/utils.py +177 -0
- taguette/validate.py +141 -0
- taguette/version_check.py +102 -0
- taguette/web/__init__.py +252 -0
- taguette/web/api.py +1835 -0
- taguette/web/base.py +864 -0
- taguette/web/export.py +338 -0
- taguette/web/views.py +1618 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Long polling
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
let lastPoll = null;
|
|
6
|
+
let polling = true;
|
|
7
|
+
let windowLastActive = new Date();
|
|
8
|
+
|
|
9
|
+
if (document.hasFocus()) {
|
|
10
|
+
windowLastActive = null; // Focused now
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
window.addEventListener('focus', function () {
|
|
14
|
+
// We are active as long as we have the focus
|
|
15
|
+
windowLastActive = null;
|
|
16
|
+
maybeResumePolling();
|
|
17
|
+
});
|
|
18
|
+
window.addEventListener('mousemove', function () {
|
|
19
|
+
if (windowLastActive !== null) {
|
|
20
|
+
// If the mouse moved over the window, and we're not focused, refresh timer
|
|
21
|
+
windowLastActive = new Date();
|
|
22
|
+
maybeResumePolling();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
window.addEventListener('blur', function () {
|
|
26
|
+
// We lost focus, start timer
|
|
27
|
+
windowLastActive = new Date();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
function maybeResumePolling() {
|
|
31
|
+
if (!polling) {
|
|
32
|
+
longPollForEvents();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function longPollForEvents() {
|
|
37
|
+
// If we've been inactive for 10min, pause polling for now
|
|
38
|
+
if (windowLastActive !== null && (new Date() - windowLastActive > 600000)) {
|
|
39
|
+
log("Browser window inactive, stop polling");
|
|
40
|
+
polling = false;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
polling = true;
|
|
45
|
+
lastPoll = Date.now();
|
|
46
|
+
getJSON(
|
|
47
|
+
`/api/project/${project_id}/events`,
|
|
48
|
+
{version: version, from: last_event}
|
|
49
|
+
)
|
|
50
|
+
.then(function (result) {
|
|
51
|
+
if (result.reload) {
|
|
52
|
+
log("Server sent signal to reload");
|
|
53
|
+
window.location.reload();
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
for (let i = 0; i < result.events.length; ++i) {
|
|
57
|
+
const event = result.events[i];
|
|
58
|
+
if (event.type === 'project_meta') {
|
|
59
|
+
setProjectMetadata({
|
|
60
|
+
project_name: event.project_name,
|
|
61
|
+
description: event.description
|
|
62
|
+
});
|
|
63
|
+
} else if (event.type === 'document_add') {
|
|
64
|
+
addDocument({
|
|
65
|
+
id: event.document_id,
|
|
66
|
+
name: event.document_name,
|
|
67
|
+
description: event.description,
|
|
68
|
+
favorite: event.favorite,
|
|
69
|
+
text_direction: event.text_direction,
|
|
70
|
+
collections: event.collections
|
|
71
|
+
});
|
|
72
|
+
} else if (event.type === 'document_delete') {
|
|
73
|
+
deleteDocument(event.document_id);
|
|
74
|
+
} else if (event.type === 'highlight_add') {
|
|
75
|
+
addHighlight({
|
|
76
|
+
id: event.highlight_id,
|
|
77
|
+
start_offset: event.start_offset,
|
|
78
|
+
end_offset: event.end_offset,
|
|
79
|
+
snippet: event.snippet,
|
|
80
|
+
tags: event.tags
|
|
81
|
+
}, event.document_id);
|
|
82
|
+
} else if (event.type === 'highlight_delete') {
|
|
83
|
+
removeHighlight(event.highlight_id, event.document_id);
|
|
84
|
+
} else if (event.type === 'tag_add') {
|
|
85
|
+
addTag({
|
|
86
|
+
id: event.tag_id,
|
|
87
|
+
path: event.tag_path,
|
|
88
|
+
description: event.description,
|
|
89
|
+
color: event.tag_color,
|
|
90
|
+
parent: event.tag_parent
|
|
91
|
+
});
|
|
92
|
+
} else if (event.type === 'tag_delete') {
|
|
93
|
+
removeTag(event.tag_id);
|
|
94
|
+
} else if (event.type === 'tag_merge') {
|
|
95
|
+
mergeTags(event.src_tag_id, event.dest_tag_id);
|
|
96
|
+
} else if (event.type === 'member_add') {
|
|
97
|
+
addMember(event.member, event.privileges);
|
|
98
|
+
} else if (event.type === 'member_remove') {
|
|
99
|
+
removeMember(event.member);
|
|
100
|
+
} else if (event.type === 'collection_add') {
|
|
101
|
+
addCollection({
|
|
102
|
+
id: event.collection_id,
|
|
103
|
+
name: event.collection_name,
|
|
104
|
+
description: event.description,
|
|
105
|
+
parent_id: event.parent_id,
|
|
106
|
+
document_ids: event.document_ids
|
|
107
|
+
});
|
|
108
|
+
} else if (event.type === 'collection_delete') {
|
|
109
|
+
removeCollection(event.collection_id);
|
|
110
|
+
} else if (event.type === 'collection_update') {
|
|
111
|
+
updateCollection({
|
|
112
|
+
id: event.collection_id,
|
|
113
|
+
name: event.collection_name,
|
|
114
|
+
description: event.description,
|
|
115
|
+
parent_id: event.parent_id,
|
|
116
|
+
document_ids: event.document_ids
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if ('tag_count_changes' in event) {
|
|
121
|
+
updateTagCount(event.tag_count_changes)
|
|
122
|
+
}
|
|
123
|
+
last_event = event.id;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Re-open connection
|
|
127
|
+
setTimeout(longPollForEvents, 1);
|
|
128
|
+
}, function (error) {
|
|
129
|
+
log("Polling failed", 'error', {error})
|
|
130
|
+
if (error instanceof ApiError && error.status === 403) {
|
|
131
|
+
showAlert(gettext("It appears that you have been logged out."));
|
|
132
|
+
window.location = '/';
|
|
133
|
+
} else if (error instanceof ApiError && error.status === 404) {
|
|
134
|
+
showAlert(gettext("You can no longer access this project."));
|
|
135
|
+
window.location = '/';
|
|
136
|
+
} else {
|
|
137
|
+
setTimeout(longPollForEvents, Math.max(1, 5000 + lastPoll - Date.now()));
|
|
138
|
+
}
|
|
139
|
+
})
|
|
140
|
+
.catch(function (error) {
|
|
141
|
+
log("Polling function error", 'error', {error})
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
longPollForEvents();
|
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
if((demo_highlights_location.length < 3)) {
|
|
2
|
+
demo_highlights_location = [[],[],[]]; //Default empty value
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
$(document).ready(function() {
|
|
6
|
+
let demoElement = null,
|
|
7
|
+
introjs_selection = null,
|
|
8
|
+
current_step = 0,
|
|
9
|
+
home_intro = introJs().setOptions({
|
|
10
|
+
exitOnOverlayClick: true,
|
|
11
|
+
exitOnEsc: true,
|
|
12
|
+
steps: [
|
|
13
|
+
{
|
|
14
|
+
title: gettext('Welcome to LibreQDA, a qualitative data analysis software (QDA) developed by the Plateforme en humanités numériques (PHuN) at Université de Sherbrooke.'),
|
|
15
|
+
intro: gettext('<p>Visit our <a href="https://gitlab.com/bin-cirst/libreqda/libre-qda" target="_blank">Gitlab repository</a></p>'),
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
element: document.querySelector('#intro-documentation'),
|
|
19
|
+
intro: gettext('<p>To consult the documentation</p>'),
|
|
20
|
+
position: 'bottom'
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
element: $('#demo-project-container .col:first')[0],
|
|
24
|
+
intro: gettext('<p>A demo project has been added to your home page.</p>'),
|
|
25
|
+
position: 'top',
|
|
26
|
+
doAction: 'create-demo-project'
|
|
27
|
+
},
|
|
28
|
+
]
|
|
29
|
+
}).
|
|
30
|
+
setOption('disableInteraction', true).
|
|
31
|
+
setOption("nextLabel", gettext('Next')).
|
|
32
|
+
setOption("prevLabel", gettext('Back')).
|
|
33
|
+
setOption("doneLabel", gettext('Continue')).
|
|
34
|
+
onbeforechange(function (targetElement) {
|
|
35
|
+
if(this._introItems[this._currentStep].doAction) {
|
|
36
|
+
switch (this._introItems[this._currentStep].doAction) {
|
|
37
|
+
case 'create-demo-project':
|
|
38
|
+
if(demoElement === null) {
|
|
39
|
+
createDemoProject();
|
|
40
|
+
}
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}).
|
|
45
|
+
onafterchange(function(targetElement) {
|
|
46
|
+
if(this._introItems[this._currentStep].doAction) {
|
|
47
|
+
switch (this._introItems[this._currentStep].doAction) {
|
|
48
|
+
case 'create-demo-project':
|
|
49
|
+
setTimeout(function(){
|
|
50
|
+
repositionIntroJS('right');
|
|
51
|
+
}, 500);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}).
|
|
56
|
+
oncomplete(function () {
|
|
57
|
+
if(demoElement !== null) {
|
|
58
|
+
demoElement.trigger('click');
|
|
59
|
+
}
|
|
60
|
+
}),
|
|
61
|
+
project_intro = introJs().setOptions({
|
|
62
|
+
showProgress: true,
|
|
63
|
+
exitOnOverlayClick: true,
|
|
64
|
+
exitOnEsc: true,
|
|
65
|
+
hidePrev: true,
|
|
66
|
+
keyboardNavigation: false,
|
|
67
|
+
showBullets: false,
|
|
68
|
+
steps: [
|
|
69
|
+
{
|
|
70
|
+
element: document.querySelector("#right-panel"),
|
|
71
|
+
title: gettext('Your documents'),
|
|
72
|
+
intro: gettext('<p>Use this tab to load files and go through them.</p>'),
|
|
73
|
+
position: 'right',
|
|
74
|
+
},
|
|
75
|
+
{ // #1
|
|
76
|
+
element: document.querySelector("#left-panel"),
|
|
77
|
+
title: gettext('Codebook'),
|
|
78
|
+
intro: gettext('<p>This tab lists all the codes that have been defined. Add new codes with the button dedicated to that purpose.</p><br><p>The total number of uses is indicated by the number on the right, and the number of documents on the left.</p>'),
|
|
79
|
+
position: 'right'
|
|
80
|
+
},
|
|
81
|
+
{ // #2
|
|
82
|
+
element: document.querySelector("#treeview-tags"),
|
|
83
|
+
title: gettext('Parent codes'),
|
|
84
|
+
intro: gettext('<p>You can define codes that include child codes under them.</p>'),
|
|
85
|
+
position: 'right'
|
|
86
|
+
},
|
|
87
|
+
{ // #3
|
|
88
|
+
element: $("[data-nodeid='1']")[0],
|
|
89
|
+
title: gettext('Child codes'),
|
|
90
|
+
intro: gettext('<p>These can be expanded or collapsed.</p>'),
|
|
91
|
+
position: 'right',
|
|
92
|
+
doAction: 'expand-tag-childrens'
|
|
93
|
+
},
|
|
94
|
+
{ // #4
|
|
95
|
+
element: $(".document-link:first")[0],
|
|
96
|
+
title: gettext('Consulting documents'),
|
|
97
|
+
intro: gettext('<p>Click on a document to view its contents. Use the star to save your bookmarks.</p>'),
|
|
98
|
+
position: 'left',
|
|
99
|
+
doAction: 'expand-first-collection'
|
|
100
|
+
},
|
|
101
|
+
{ // #5
|
|
102
|
+
element: document.querySelector("#document-highlight"), // This element doesn't exist
|
|
103
|
+
title: gettext('Coding'),
|
|
104
|
+
intro: gettext('<p>Select a portion of text with your cursor. Two buttons will appear to assign a code to the selection.</p>'),
|
|
105
|
+
position: 'bottom',
|
|
106
|
+
highlight: (typeof(demo_highlights_location[0][0]) !== 'undefined') ? demo_highlights_location[0][0] : [0,0],
|
|
107
|
+
nodes: [null, null],
|
|
108
|
+
highlight_context: [0, 0],
|
|
109
|
+
doAction: 'document-highlight' // Action to create wrapper for introjs
|
|
110
|
+
},
|
|
111
|
+
{ // #6
|
|
112
|
+
element: document.querySelector("#highlight-add-form"),
|
|
113
|
+
title: gettext("Selecting a code"),
|
|
114
|
+
intro: gettext('<p>From the menu, select one or more codes that correspond to the content of the selection and save the changes. In this case, the selection refers to reinforcing social relationships.</p>'),
|
|
115
|
+
position: 'left',
|
|
116
|
+
tagPosition: [3],
|
|
117
|
+
doAction: 'document-selecttag' // Action to create wrapper for introjs
|
|
118
|
+
},
|
|
119
|
+
{ //#14
|
|
120
|
+
element: document.querySelector("#left-panel"),
|
|
121
|
+
title: gettext('Exploring the codes'),
|
|
122
|
+
intro: gettext('<p>You can explore the text selections tagged with each code at any time during or after the coding process.</p><br><p> Show all of the selections tagged with a code from the codebook by clicking on it.</p>'),
|
|
123
|
+
position: 'right',
|
|
124
|
+
},
|
|
125
|
+
{ //#15
|
|
126
|
+
element: document.querySelector("#document-view"),
|
|
127
|
+
title: gettext('Narrowing your search'),
|
|
128
|
+
intro: gettext('<p>If there are a large number of selections shown, you can refine the results with an advanced search.</p>'),
|
|
129
|
+
position: 'left',
|
|
130
|
+
doAction: 'exploration-mode'
|
|
131
|
+
},
|
|
132
|
+
{ //#16
|
|
133
|
+
element: document.querySelector(".context-menu-root"),
|
|
134
|
+
title: gettext('Conditional selections'),
|
|
135
|
+
intro: gettext('<p>By right-clicking, you can specify conditions to either add or exclude additional codes.</p>'),
|
|
136
|
+
position: 'left',
|
|
137
|
+
which: 2,
|
|
138
|
+
doAction: 'select-condition'
|
|
139
|
+
},
|
|
140
|
+
{ //#17
|
|
141
|
+
element: document.querySelector("#document-view"),
|
|
142
|
+
title: gettext('Exploring the list'),
|
|
143
|
+
intro: gettext('<p>The labels shown with this query indicate that the selections must necessarily include the codes <i>barriers</i> and <i>skills development</i>.</p>'),
|
|
144
|
+
position: 'left',
|
|
145
|
+
doAction: 'apply-condition'
|
|
146
|
+
},
|
|
147
|
+
{ //#18
|
|
148
|
+
element: $('#document-contents .highlight-entry:first .badge')[0],
|
|
149
|
+
title: gettext('Navigating to documents'),
|
|
150
|
+
intro: gettext('<p>By clicking on the name of the document, you can return to the context.</p>'),
|
|
151
|
+
position: 'top',
|
|
152
|
+
doAction: 'select-badge'
|
|
153
|
+
},
|
|
154
|
+
{ //#19
|
|
155
|
+
element: document.querySelector('#tag-selection-return'),
|
|
156
|
+
title: gettext('Returning to the selections'),
|
|
157
|
+
intro: gettext('<p>After consulting the context, you can return to the list of selections previously identified using the advanced search.</p>'),
|
|
158
|
+
position: 'right',
|
|
159
|
+
doAction: 'reposition-after-scroll'
|
|
160
|
+
},
|
|
161
|
+
{ //#20
|
|
162
|
+
element: document.querySelector('#document-dropdown-export'),
|
|
163
|
+
title: gettext('Exporting'),
|
|
164
|
+
intro: gettext('<p>You can choose to download these selections to your computer, as needed.</p>'),
|
|
165
|
+
position: 'left',
|
|
166
|
+
},
|
|
167
|
+
{ //#22
|
|
168
|
+
title: gettext('Time to code!'),
|
|
169
|
+
intro: gettext('<p>Use LibreQDA however you wish, knowing that your data is always saved to your personal account. Feel free to further familiarize yourself with these functions by continuing to code and explore these fictional interviews about board games.</p>'),
|
|
170
|
+
position: 'left',
|
|
171
|
+
doAction: 'last'
|
|
172
|
+
},
|
|
173
|
+
]
|
|
174
|
+
}).
|
|
175
|
+
setOption('disableInteraction', true).
|
|
176
|
+
setOption('scrollTo', 'tooltip').
|
|
177
|
+
setOption("nextLabel", gettext('Next')).
|
|
178
|
+
setOption("prevLabel", gettext('Back')).
|
|
179
|
+
setOption("doneLabel", gettext('Done')).
|
|
180
|
+
onbeforechange(function(targetElement) {
|
|
181
|
+
if(this._introItems[this._currentStep] &&
|
|
182
|
+
this._introItems[this._currentStep].doAction === 'document-highlight') {
|
|
183
|
+
let dh_start = this._introItems[this._currentStep].highlight[0],
|
|
184
|
+
dh_end = this._introItems[this._currentStep].highlight[1],
|
|
185
|
+
hlContainer = document.getElementById('highlight-content');
|
|
186
|
+
|
|
187
|
+
if (hlContainer && typeof collectTextNodes === 'function') {
|
|
188
|
+
try {
|
|
189
|
+
const textNodes = collectTextNodes(hlContainer);
|
|
190
|
+
const { fullText, charMap } = buildCharMap(textNodes);
|
|
191
|
+
const startChar = getCharIndexFromUTF8Index(fullText, dh_start);
|
|
192
|
+
const endChar = getCharIndexFromUTF8Index(fullText, dh_end);
|
|
193
|
+
const startEntry = charMap[Math.max(0, startChar)];
|
|
194
|
+
const endEntry = charMap[Math.min(charMap.length - 1, Math.max(0, endChar - 1))];
|
|
195
|
+
|
|
196
|
+
if (startEntry && endEntry) {
|
|
197
|
+
this._introItems[this._currentStep].nodes = [startEntry.node, endEntry.node];
|
|
198
|
+
this._introItems[this._currentStep].highlight_context = [startEntry.offset, endEntry.offset + 1];
|
|
199
|
+
const startBlock = startEntry.node.parentElement.closest('p, li, h1, h2, h3, h4, h5, h6, .document-chunk') || hlContainer;
|
|
200
|
+
$(startBlock).addClass('intro-js-highlight');
|
|
201
|
+
}
|
|
202
|
+
} catch(e) {
|
|
203
|
+
log('document-highlight action failed:', 'warn', e);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
$(".intro-js-highlight").wrapAll("<div id='document-highlight' />");
|
|
208
|
+
this._introItems[this._currentStep].element = $("#document-highlight")[0] ||
|
|
209
|
+
hlContainer ||
|
|
210
|
+
document.getElementById('document-contents');
|
|
211
|
+
targetElement = this._introItems[this._currentStep].element;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if(targetElement) {
|
|
215
|
+
// Always submit previous step before continuing
|
|
216
|
+
if($("#highlight-add-modal").hasClass('show')) {
|
|
217
|
+
$("#highlight-add-form").submit();
|
|
218
|
+
introjs_selection = null;
|
|
219
|
+
}
|
|
220
|
+
if($("#tag-add-modal").hasClass('show')) {
|
|
221
|
+
$("#tag-add-form button[type='submit']").trigger('click');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
switch(targetElement.id) {
|
|
225
|
+
case 'tag-selection-return':
|
|
226
|
+
$('#document-contents .highlight-entry:first .badge')[0].click();
|
|
227
|
+
this._introItems[this._currentStep].element = $("#tag-selection-return")[0];
|
|
228
|
+
break;
|
|
229
|
+
|
|
230
|
+
case 'document-dropdown-export':
|
|
231
|
+
window.scrollTo({
|
|
232
|
+
top: 0,
|
|
233
|
+
behavior: 'instant'
|
|
234
|
+
});
|
|
235
|
+
$("#tag-selection-return a").click();
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
if(this._introItems[this._currentStep].doAction) {
|
|
239
|
+
switch(this._introItems[this._currentStep].doAction) {
|
|
240
|
+
case 'expand-tag-childrens':
|
|
241
|
+
$("[data-nodeid='1'] .expand-icon").trigger('click');
|
|
242
|
+
for(let i=1; i<=3; i++) {
|
|
243
|
+
$("[data-nodeid='" + i + "']").addClass('intro-js-tags-child')
|
|
244
|
+
}
|
|
245
|
+
$( ".intro-js-tags-child" ).wrapAll( "<div id='intro-js-wrapped' />");
|
|
246
|
+
// Fix duplicate elements
|
|
247
|
+
$("#intro-js-wrapped > li:eq(3)").remove();
|
|
248
|
+
// Force refresh dynamic element
|
|
249
|
+
this._introItems[this._currentStep].element = $("#intro-js-wrapped")[0];
|
|
250
|
+
break;
|
|
251
|
+
case 'expand-first-collection':
|
|
252
|
+
// Expand the first collection node to reveal documents
|
|
253
|
+
if(typeof treeview_documents !== 'undefined' && treeview_documents.length) {
|
|
254
|
+
try {
|
|
255
|
+
// Get the first node (should be a collection) and expand it
|
|
256
|
+
const allNodes = treeview_documents.treeview('getEnabled');
|
|
257
|
+
if(allNodes && allNodes.length > 0) {
|
|
258
|
+
const firstNode = allNodes[0];
|
|
259
|
+
if(firstNode && !firstNode.state.expanded) {
|
|
260
|
+
treeview_documents.treeview('expandNode', [firstNode.nodeId, {silent: false}]);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
} catch(e) {
|
|
264
|
+
// Fallback to clicking expand icon
|
|
265
|
+
$("#treeview-documents .expand-icon:first").trigger('click');
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// Force refresh dynamic element after expansion
|
|
269
|
+
this._introItems[this._currentStep].element = $(".document-link:first")[0];
|
|
270
|
+
const firstDocLink = $(".document-link:first");
|
|
271
|
+
if (firstDocLink.length) {
|
|
272
|
+
const introDocId = parseInt(firstDocLink.attr('data-document-id'));
|
|
273
|
+
if (introDocId && typeof loadDocument === 'function') {
|
|
274
|
+
loadDocument(introDocId);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
break;
|
|
278
|
+
|
|
279
|
+
case 'document-selecttag':
|
|
280
|
+
let tag_position = this._introItems[this._currentStep].tagPosition;
|
|
281
|
+
if(typeof tag_position === "undefined") {
|
|
282
|
+
tag_position = [0];
|
|
283
|
+
}
|
|
284
|
+
$(window).trigger('click');
|
|
285
|
+
$('#highlight-add-modal').removeClass('fade');
|
|
286
|
+
|
|
287
|
+
if (!introjs_selection) {
|
|
288
|
+
const hlStep = this._introItems[this._currentStep - 1];
|
|
289
|
+
if (hlStep && hlStep.nodes && hlStep.nodes[0]) {
|
|
290
|
+
selectRange(hlStep.nodes, hlStep.highlight_context);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (introjs_selection) {
|
|
294
|
+
createHighlight(introjs_selection);
|
|
295
|
+
for(let i in tag_position) {
|
|
296
|
+
$("#highlight-add-form li[data-nodeid='" + tag_position[i] + "']").trigger('click');
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
$(window).unbind('click');
|
|
301
|
+
break;
|
|
302
|
+
case 'exploration-mode':
|
|
303
|
+
$("[data-nodeid='0']:not(.node-selected)").click();
|
|
304
|
+
// Reposition
|
|
305
|
+
setTimeout(function() {
|
|
306
|
+
window.scrollTo({
|
|
307
|
+
top: 0,
|
|
308
|
+
behavior: 'instant'
|
|
309
|
+
});
|
|
310
|
+
$('.introjs-tooltipReferenceLayer').css('height', $(targetElement).outerHeight())
|
|
311
|
+
$('.introjs-helperLayer').css('height', $(targetElement).outerHeight())
|
|
312
|
+
$('.introjs-disableInteraction').css('height', $(targetElement).outerHeight())
|
|
313
|
+
}, 500);
|
|
314
|
+
break;
|
|
315
|
+
case 'select-condition':
|
|
316
|
+
let i = this._introItems[this._currentStep].which;
|
|
317
|
+
if(isNaN(i)) {
|
|
318
|
+
i = 0;
|
|
319
|
+
}
|
|
320
|
+
window.scrollTo({
|
|
321
|
+
top: 0,
|
|
322
|
+
behavior: 'instant'
|
|
323
|
+
});
|
|
324
|
+
if(!$("[data-nodeid='2']").is(':visible')) {
|
|
325
|
+
$("[data-nodeid='1'] .expand-icon").trigger('click');
|
|
326
|
+
}
|
|
327
|
+
$("[data-nodeid='2']").trigger( "contextmenu" );
|
|
328
|
+
$(".context-menu-root li:nth(" + i + ")").addClass('context-menu-hover context-menu-visible');
|
|
329
|
+
$(".context-menu-root li:nth(" + i + ") > ul").css('left', $(".context-menu-root").width() + 'px');
|
|
330
|
+
$(".context-menu-root li:nth(" + i + ") > ul > li:first").addClass('context-menu-hover context-menu-visible');
|
|
331
|
+
this._introItems[this._currentStep].element = $(".context-menu-root")[0];
|
|
332
|
+
break;
|
|
333
|
+
case 'apply-condition':
|
|
334
|
+
$(".context-menu-root li.context-menu-visible > ul > li.context-menu-hover").trigger('mouseup');
|
|
335
|
+
break;
|
|
336
|
+
case 'select-badge':
|
|
337
|
+
this._introItems[this._currentStep].element = $('#document-contents .highlight-entry:first .badge')[0];
|
|
338
|
+
break;
|
|
339
|
+
case 'reposition-after-scroll':
|
|
340
|
+
setTimeout(function() {
|
|
341
|
+
//Force scroll to bottom of page
|
|
342
|
+
window.scrollTo({
|
|
343
|
+
top: document.body.scrollHeight,
|
|
344
|
+
behavior: 'instant'
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
let elems = ['.introjs-helperLayer', '.introjs-tooltipReferenceLayer', '.introjs-disableInteraction'],
|
|
348
|
+
offset = $('#tag-selection-return').offset().top - $('.introjs-tooltipReferenceLayer').offset().top;
|
|
349
|
+
|
|
350
|
+
for (let i in elems) {
|
|
351
|
+
$(elems[i]).css('top', (parseFloat($(elems[i]).css('top')) + offset) + 'px');
|
|
352
|
+
}
|
|
353
|
+
}, 500);
|
|
354
|
+
break;
|
|
355
|
+
case 'last':
|
|
356
|
+
$('#project-sidebar').css('width', 0);
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
//Scroll to top if new document to prevent position problem with introjs
|
|
361
|
+
if(targetElement.classList.contains('document-link')) {
|
|
362
|
+
window.scrollTo({
|
|
363
|
+
top: 0,
|
|
364
|
+
behavior: 'instant'
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}).
|
|
369
|
+
onchange(function (targetElement) {
|
|
370
|
+
current_step = this._currentStep;
|
|
371
|
+
}).
|
|
372
|
+
onafterchange(function(targetElement) {
|
|
373
|
+
switch(targetElement.id) {
|
|
374
|
+
case 'document-highlight':
|
|
375
|
+
$(".intro-js-highlight").unwrap().removeClass('intro-js-highlight');
|
|
376
|
+
let node_start = this._introItems[this._currentStep].nodes[0],
|
|
377
|
+
node_end = this._introItems[this._currentStep].nodes[1],
|
|
378
|
+
text_start = this._introItems[this._currentStep].highlight_context[0],
|
|
379
|
+
text_end = this._introItems[this._currentStep].highlight_context[1];
|
|
380
|
+
console.log([[node_start, node_end], [text_start, text_end]])
|
|
381
|
+
setTimeout(function(){
|
|
382
|
+
selectRange([node_start, node_end], [text_start, text_end]);
|
|
383
|
+
repositionIntroJS('top');
|
|
384
|
+
}, 500);
|
|
385
|
+
//Force reselection of text is unselected
|
|
386
|
+
$(window).bind('click', function(e) {
|
|
387
|
+
selectRange([node_start, node_end], [text_start, text_end]);
|
|
388
|
+
});
|
|
389
|
+
break;
|
|
390
|
+
|
|
391
|
+
case 'document-dropdown-export':
|
|
392
|
+
setTimeout(function(){
|
|
393
|
+
$("#document-dropdown-export").click()
|
|
394
|
+
$('.introjs-helperLayer').css('width', $('#document-export-dropdown-menu').outerWidth() + 10)
|
|
395
|
+
$('.introjs-helperLayer').css('height', $('#document-export-dropdown-menu').outerHeight() + $('.introjs-helperLayer').outerHeight())
|
|
396
|
+
$('.introjs-disableInteraction').css('width', $('#document-export-dropdown-menu').outerWidth() + 10)
|
|
397
|
+
$('.introjs-disableInteraction').css('height', $('#document-export-dropdown-menu').outerHeight() + $('.introjs-helperLayer').outerHeight())
|
|
398
|
+
}, 500);
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
if(this._introItems[this._currentStep].doAction) {
|
|
402
|
+
switch(this._introItems[this._currentStep].doAction) {
|
|
403
|
+
case 'expand-first-collection':
|
|
404
|
+
setTimeout(function(){
|
|
405
|
+
repositionIntroJS('left');
|
|
406
|
+
}, 300);
|
|
407
|
+
break;
|
|
408
|
+
case 'select-condition':
|
|
409
|
+
setTimeout(function(){
|
|
410
|
+
repositionIntroJS('right', 275);
|
|
411
|
+
}, 500);
|
|
412
|
+
break;
|
|
413
|
+
case 'select-badge':
|
|
414
|
+
setTimeout(function(){
|
|
415
|
+
repositionIntroJS('right', 15);
|
|
416
|
+
}, 500);
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}).
|
|
421
|
+
oncomplete(function (){
|
|
422
|
+
$("#start-tutorial").remove();
|
|
423
|
+
}).
|
|
424
|
+
onexit(function () {
|
|
425
|
+
is_demo = true;
|
|
426
|
+
//Make sure everything is back as it was
|
|
427
|
+
$( ".intro-js-tags-child" ).unwrap();
|
|
428
|
+
$( ".intro-js-highlight" ).unwrap();
|
|
429
|
+
$( ".document-highlight" ).unwrap();
|
|
430
|
+
$(window).unbind('click');
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
function createDemoProject() {
|
|
434
|
+
log('Create demo project');
|
|
435
|
+
let postData = {'_xsrf': getCookie('_xsrf')};
|
|
436
|
+
postJSON('/api/create_demo_project', postData)
|
|
437
|
+
.then(function (result) {
|
|
438
|
+
if (result.html) {
|
|
439
|
+
$('#demo-project-container').prepend(result.html);
|
|
440
|
+
demoElement = $('#demo-project-container .project:first .project-card');
|
|
441
|
+
$('#demo-project-container .project.empty').remove();
|
|
442
|
+
}
|
|
443
|
+
})
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
let repositionIntroJS = (where='top', offset=0) => {
|
|
447
|
+
//Remove position classes from tooltip
|
|
448
|
+
let cls = $('.introjs-arrow').attr("class").split(/\s+/);
|
|
449
|
+
for(let c in cls) {
|
|
450
|
+
if(cls[c] !== 'introjs-arrow') {
|
|
451
|
+
$('.introjs-arrow').removeClass(cls[c]);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
cls = $('.introjs-tooltip').attr("class").split(/\s+/);
|
|
455
|
+
for(let c in cls) {
|
|
456
|
+
if(cls[c] !== 'introjs-tooltip') {
|
|
457
|
+
$('.introjs-tooltip').removeClass(cls[c]);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
//set new position
|
|
462
|
+
switch(where) {
|
|
463
|
+
case 'top':
|
|
464
|
+
let newtop = -$('.introjs-tooltip').outerHeight() + offset;
|
|
465
|
+
$('.introjs-tooltip')
|
|
466
|
+
.addClass('introjs-top-middle-aligned')
|
|
467
|
+
.css('top', newtop + 'px')
|
|
468
|
+
.css('margin-top', '-10px');
|
|
469
|
+
$('.introjs-arrow').css('display', 'inherit').addClass('bottom-middle');
|
|
470
|
+
break;
|
|
471
|
+
case 'left':
|
|
472
|
+
$('.introjs-tooltip')
|
|
473
|
+
.addClass('introjs-left-middle-aligned')
|
|
474
|
+
.css('left', -$('.introjs-tooltip').outerWidth() + 'px')
|
|
475
|
+
.css('margin-right', -offset + 'px');
|
|
476
|
+
$('.introjs-arrow').css('display', 'inherit').addClass('right');
|
|
477
|
+
break;
|
|
478
|
+
case 'right':
|
|
479
|
+
$('.introjs-tooltip')
|
|
480
|
+
.addClass('introjs-right-middle-aligned')
|
|
481
|
+
.css('left', $('.introjs-helperLayer').outerWidth() + 'px')
|
|
482
|
+
.css('margin-left', offset + 'px');
|
|
483
|
+
$('.introjs-arrow').css('display', 'inherit').addClass('left');
|
|
484
|
+
$('.introjs-disableInteraction').css('width', ($('.introjs-tooltip').offset().left - $('.introjs-disableInteraction').offset().left) + 'px');
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
showHomeIntro = () => {
|
|
489
|
+
home_intro.start();
|
|
490
|
+
},
|
|
491
|
+
selectRange = (nodes, positions) => {
|
|
492
|
+
let range=document.createRange(),
|
|
493
|
+
selection = window.getSelection();
|
|
494
|
+
range.setStart(nodes[0], positions[0]);
|
|
495
|
+
range.setEnd(nodes[1], positions[1]);
|
|
496
|
+
selection.removeAllRanges();
|
|
497
|
+
selection.addRange(range);
|
|
498
|
+
|
|
499
|
+
introjs_selection = describeSelection();
|
|
500
|
+
},
|
|
501
|
+
showProjectIntro = (step=1) => {
|
|
502
|
+
project_intro.start();
|
|
503
|
+
if(step && !isNaN(step) && step > 0) {
|
|
504
|
+
log(`IntroJS : Go to step: ${step}`)
|
|
505
|
+
project_intro.goToStepNumber(step);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
$("#a-start-demo").click(function(){
|
|
510
|
+
showHomeIntro();
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
$("#start-tutorial").click(function(){
|
|
514
|
+
showProjectIntro(current_step+1);
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
if($("#a-start-demo").length && is_demo) {
|
|
518
|
+
// In index.html template
|
|
519
|
+
showHomeIntro();
|
|
520
|
+
} else if(is_demo) {
|
|
521
|
+
// In project.html template
|
|
522
|
+
showProjectIntro();
|
|
523
|
+
}
|
|
524
|
+
});
|
|
File without changes
|