First work on a (first run) wizard, also usable by plugins
This commit is contained in:
parent
75992ef837
commit
ac1e2e8ad4
14 changed files with 232 additions and 12 deletions
|
|
@ -795,6 +795,7 @@ class Server():
|
|||
"js/lib/jquery/jquery.fileupload.js",
|
||||
"js/lib/jquery/jquery.slimscroll.min.js",
|
||||
"js/lib/jquery/jquery.qrcode.min.js",
|
||||
"js/lib/jquery/jquery.bootstrap.wizard.min.js",
|
||||
"js/lib/moment-with-locales.min.js",
|
||||
"js/lib/pusher.color.min.js",
|
||||
"js/lib/detectmobilebrowser.js",
|
||||
|
|
|
|||
|
|
@ -610,7 +610,8 @@ def collect_plugin_assets(enable_gcodeviewer=True, enable_timelapse=True, prefer
|
|||
'js/app/viewmodels/terminal.js',
|
||||
'js/app/viewmodels/users.js',
|
||||
'js/app/viewmodels/log.js',
|
||||
'js/app/viewmodels/usersettings.js'
|
||||
'js/app/viewmodels/usersettings.js',
|
||||
'js/app/viewmodels/wizard.js'
|
||||
]
|
||||
if enable_gcodeviewer:
|
||||
assets["js"] += [
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ def index():
|
|||
enable_accesscontrol = userManager is not None
|
||||
preferred_stylesheet = settings().get(["devel", "stylesheet"])
|
||||
locales = dict((l.language, dict(language=l.language, display=l.display_name, english=l.english_name)) for l in LOCALES)
|
||||
first_run = settings().getBoolean(["server", "firstRun"])# and (userManager is None or not userManager.hasBeenCustomized())
|
||||
|
||||
##~~ prepare templates
|
||||
|
||||
|
|
@ -46,6 +47,7 @@ def index():
|
|||
tab=dict(div=lambda x: "tab_plugin_" + x, template=lambda x: x + "_tab.jinja2", to_entry=lambda data: (data["name"], data)),
|
||||
settings=dict(div=lambda x: "settings_plugin_" + x, template=lambda x: x + "_settings.jinja2", to_entry=lambda data: (data["name"], data)),
|
||||
usersettings=dict(div=lambda x: "usersettings_plugin_" + x, template=lambda x: x + "_usersettings.jinja2", to_entry=lambda data: (data["name"], data)),
|
||||
wizard=dict(div=lambda x: "wizard_plugin_" + x, template=lambda x: x + "_wizard.jinja2", to_entry=lambda data: (data["name"], data)),
|
||||
generic=dict(template=lambda x: x + ".jinja2", to_entry=lambda data: data)
|
||||
)
|
||||
|
||||
|
|
@ -56,6 +58,7 @@ def index():
|
|||
tab=dict(add="append", key="name"),
|
||||
settings=dict(add="custom_append", key="name", custom_add_entries=lambda missing: dict(section_plugins=(gettext("Plugins"), None)), custom_add_order=lambda missing: ["section_plugins"] + missing),
|
||||
usersettings=dict(add="append", key="name"),
|
||||
wizard=dict(add="append", key="name"),
|
||||
generic=dict(add="append", key=None)
|
||||
)
|
||||
|
||||
|
|
@ -162,6 +165,24 @@ def index():
|
|||
interface=(gettext("Interface"), dict(template="dialogs/usersettings/interface.jinja2", _div="usersettings_interface", custom_bindings=False)),
|
||||
)
|
||||
|
||||
# wizard
|
||||
|
||||
if first_run:
|
||||
def custom_insert_order(existing, missing):
|
||||
if "firstrunstart" in missing:
|
||||
missing.remove("firstrunstart")
|
||||
if "firstrunend" in missing:
|
||||
missing.remove("firstrunend")
|
||||
|
||||
return ["firstrunstart"] + existing + missing + ["firstrunend"]
|
||||
|
||||
template_sorting["wizard"] = dict(add="custom_insert", key="name", custom_insert_entries=lambda missing: dict(), custom_insert_order=custom_insert_order)
|
||||
templates["wizard"]["entries"] = dict(
|
||||
firstrunstart=(gettext("Start"), dict(template="dialogs/wizard/firstrunstart.jinja2", _div="firstrun_start")),
|
||||
firstrunend=(gettext("Finish"), dict(template="dialogs/wizard/firstrunend.jinja2", _div="firstrun_end")),
|
||||
access=(gettext("Access Control"), dict(template="dialogs/wizard/accesscontrol.jinja2", _div="firstrun_dialog", custom_bindings=True))
|
||||
)
|
||||
|
||||
# extract data from template plugins
|
||||
|
||||
template_plugins = pluginManager.get_implementations(octoprint.plugin.TemplatePlugin)
|
||||
|
|
@ -243,10 +264,13 @@ def index():
|
|||
elif template_sorting[t]["add"] == "custom_append" and "custom_add_entries" in template_sorting[t] and "custom_add_order" in template_sorting[t]:
|
||||
templates[t]["entries"].update(template_sorting[t]["custom_add_entries"](sorted_missing))
|
||||
templates[t]["order"] += template_sorting[t]["custom_add_order"](sorted_missing)
|
||||
elif template_sorting[t]["add"] == "custom_insert" and "custom_insert_entries" in template_sorting[t] and "custom_insert_order" in template_sorting[t]:
|
||||
templates[t]["entries"].update(template_sorting[t]["custom_insert_entries"](sorted_missing))
|
||||
templates[t]["order"] = template_sorting[t]["custom_insert_order"](templates[t]["order"], sorted_missing)
|
||||
|
||||
#~~ prepare full set of template vars for rendering
|
||||
|
||||
first_run = settings().getBoolean(["server", "firstRun"]) and (userManager is None or not userManager.hasBeenCustomized())
|
||||
wizard = bool(templates["wizard"]["order"])
|
||||
render_kwargs = dict(
|
||||
webcamStream=settings().get(["webcam", "stream"]),
|
||||
enableTemperatureGraph=settings().get(["feature", "temperatureGraph"]),
|
||||
|
|
@ -261,7 +285,8 @@ def index():
|
|||
uiApiKey=UI_API_KEY,
|
||||
templates=templates,
|
||||
pluginNames=plugin_names,
|
||||
locales=locales
|
||||
locales=locales,
|
||||
wizard=wizard
|
||||
)
|
||||
render_kwargs.update(plugin_vars)
|
||||
|
||||
|
|
@ -275,7 +300,7 @@ def index():
|
|||
))
|
||||
response.headers["Last-Modified"] = datetime.datetime.now()
|
||||
|
||||
if first_run:
|
||||
if wizard:
|
||||
response.headers["Cache-Control"] = "no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0"
|
||||
response.headers["Pragma"] = "no-cache"
|
||||
response.headers["Expires"] = "-1"
|
||||
|
|
|
|||
|
|
@ -191,6 +191,7 @@ default_settings = {
|
|||
"section_octoprint", "folders", "appearance", "logs", "plugin_pluginmanager", "plugin_softwareupdate"
|
||||
],
|
||||
"usersettings": ["access", "interface"],
|
||||
"wizard": ["access"],
|
||||
"generic": []
|
||||
},
|
||||
"disabled": {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
54
src/octoprint/static/js/app/viewmodels/wizard.js
Normal file
54
src/octoprint/static/js/app/viewmodels/wizard.js
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
$(function() {
|
||||
function WizardViewModel() {
|
||||
var self = this;
|
||||
|
||||
self.wizardDialog = undefined;
|
||||
|
||||
self.showDialog = function() {
|
||||
self.wizardDialog.modal({
|
||||
minHeight: function() { return Math.max($.fn.modal.defaults.maxHeight() - 80, 250); }
|
||||
}).css({
|
||||
width: 'auto',
|
||||
'margin-left': function() { return -($(this).width() /2); }
|
||||
});
|
||||
};
|
||||
|
||||
self.closeDialog = function() {
|
||||
self.wizardDialog.modal("hide");
|
||||
};
|
||||
|
||||
self.onStartup = function() {
|
||||
self.wizardDialog = $("#wizard_dialog");
|
||||
};
|
||||
|
||||
self.onAllBound = function(allViewModels) {
|
||||
if (CONFIG_WIZARD) {
|
||||
self.wizardDialog.bootstrapWizard({
|
||||
tabClass: "nav nav-list",
|
||||
nextSelector: ".button-next",
|
||||
previousSelector: ".button-previous",
|
||||
finishSelector: ".button-finish",
|
||||
onTabShow: function(tab, navigation, index) {
|
||||
var total = navigation.find("li").length;
|
||||
var current = index+1;
|
||||
|
||||
if (current >= total) {
|
||||
self.wizardDialog.find(".button-next").hide();
|
||||
self.wizardDialog.find(".button-finish").show().removeClass("disabled");
|
||||
} else {
|
||||
self.wizardDialog.find(".button-finish").hide();
|
||||
self.wizardDialog.find(".button-next").show();
|
||||
}
|
||||
}
|
||||
});
|
||||
self.showDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OCTOPRINT_VIEWMODELS.push([
|
||||
WizardViewModel,
|
||||
[],
|
||||
"#wizard_dialog"
|
||||
]);
|
||||
});
|
||||
22
src/octoprint/static/js/lib/jquery/jquery.bootstrap.wizard.min.js
vendored
Normal file
22
src/octoprint/static/js/lib/jquery/jquery.bootstrap.wizard.min.js
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*!
|
||||
* jQuery twitter bootstrap wizard plugin
|
||||
* Examples and documentation at: http://github.com/VinceG/twitter-bootstrap-wizard
|
||||
* version 1.0
|
||||
* Requires jQuery v1.3.2 or later
|
||||
* Supports Bootstrap 2.2.x, 2.3.x, 3.0
|
||||
* Dual licensed under the MIT and GPL licenses:
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.gnu.org/licenses/gpl.html
|
||||
* Authors: Vadim Vincent Gabriel (http://vadimg.com), Jason Gill (www.gilluminate.com)
|
||||
*/
|
||||
(function(e){var n=function(d,k){d=e(d);var a=this,g=[],c=e.extend({},e.fn.bootstrapWizard.defaults,k),f=null,b=null;this.rebindClick=function(h,a){h.unbind("click",a).bind("click",a)};this.fixNavigationButtons=function(){f.length||(b.find("a:first").tab("show"),f=b.find('li:has([data-toggle="tab"]):first'));e(c.previousSelector,d).toggleClass("disabled",a.firstIndex()>=a.currentIndex());e(c.nextSelector,d).toggleClass("disabled",a.currentIndex()>=a.navigationLength());e(c.backSelector,d).toggleClass("disabled",
|
||||
0==g.length);a.rebindClick(e(c.nextSelector,d),a.next);a.rebindClick(e(c.previousSelector,d),a.previous);a.rebindClick(e(c.lastSelector,d),a.last);a.rebindClick(e(c.firstSelector,d),a.first);a.rebindClick(e(c.backSelector,d),a.back);if(c.onTabShow&&"function"===typeof c.onTabShow&&!1===c.onTabShow(f,b,a.currentIndex()))return!1};this.next=function(h){if(d.hasClass("last")||c.onNext&&"function"===typeof c.onNext&&!1===c.onNext(f,b,a.nextIndex()))return!1;h=a.currentIndex();$index=a.nextIndex();$index>
|
||||
a.navigationLength()||(g.push(h),b.find('li:has([data-toggle="tab"]):eq('+$index+") a").tab("show"))};this.previous=function(h){if(d.hasClass("first")||c.onPrevious&&"function"===typeof c.onPrevious&&!1===c.onPrevious(f,b,a.previousIndex()))return!1;h=a.currentIndex();$index=a.previousIndex();0>$index||(g.push(h),b.find('li:has([data-toggle="tab"]):eq('+$index+") a").tab("show"))};this.first=function(h){if(c.onFirst&&"function"===typeof c.onFirst&&!1===c.onFirst(f,b,a.firstIndex())||d.hasClass("disabled"))return!1;
|
||||
g.push(a.currentIndex());b.find('li:has([data-toggle="tab"]):eq(0) a').tab("show")};this.last=function(h){if(c.onLast&&"function"===typeof c.onLast&&!1===c.onLast(f,b,a.lastIndex())||d.hasClass("disabled"))return!1;g.push(a.currentIndex());b.find('li:has([data-toggle="tab"]):eq('+a.navigationLength()+") a").tab("show")};this.back=function(){if(0==g.length)return null;var a=g.pop();if(c.onBack&&"function"===typeof c.onBack&&!1===c.onBack(f,b,a))return g.push(a),!1;d.find('li:has([data-toggle="tab"]):eq('+
|
||||
a+") a").tab("show")};this.currentIndex=function(){return b.find('li:has([data-toggle="tab"])').index(f)};this.firstIndex=function(){return 0};this.lastIndex=function(){return a.navigationLength()};this.getIndex=function(a){return b.find('li:has([data-toggle="tab"])').index(a)};this.nextIndex=function(){return b.find('li:has([data-toggle="tab"])').index(f)+1};this.previousIndex=function(){return b.find('li:has([data-toggle="tab"])').index(f)-1};this.navigationLength=function(){return b.find('li:has([data-toggle="tab"])').length-
|
||||
1};this.activeTab=function(){return f};this.nextTab=function(){return b.find('li:has([data-toggle="tab"]):eq('+(a.currentIndex()+1)+")").length?b.find('li:has([data-toggle="tab"]):eq('+(a.currentIndex()+1)+")"):null};this.previousTab=function(){return 0>=a.currentIndex()?null:b.find('li:has([data-toggle="tab"]):eq('+parseInt(a.currentIndex()-1)+")")};this.show=function(b){b=isNaN(b)?d.find('li:has([data-toggle="tab"]) a[href=#'+b+"]"):d.find('li:has([data-toggle="tab"]):eq('+b+") a");0<b.length&&
|
||||
(g.push(a.currentIndex()),b.tab("show"))};this.disable=function(a){b.find('li:has([data-toggle="tab"]):eq('+a+")").addClass("disabled")};this.enable=function(a){b.find('li:has([data-toggle="tab"]):eq('+a+")").removeClass("disabled")};this.hide=function(a){b.find('li:has([data-toggle="tab"]):eq('+a+")").hide()};this.display=function(a){b.find('li:has([data-toggle="tab"]):eq('+a+")").show()};this.remove=function(a){var c="undefined"!=typeof a[1]?a[1]:!1;a=b.find('li:has([data-toggle="tab"]):eq('+a[0]+
|
||||
")");c&&(c=a.find("a").attr("href"),e(c).remove());a.remove()};var l=function(d){var g=b.find('li:has([data-toggle="tab"])');d=g.index(e(d.currentTarget).parent('li:has([data-toggle="tab"])'));g=e(g[d]);if(c.onTabClick&&"function"===typeof c.onTabClick&&!1===c.onTabClick(f,b,a.currentIndex(),d,g))return!1},m=function(d){$element=e(d.target).parent();d=b.find('li:has([data-toggle="tab"])').index($element);if($element.hasClass("disabled")||c.onTabChange&&"function"===typeof c.onTabChange&&!1===c.onTabChange(f,
|
||||
b,a.currentIndex(),d))return!1;f=$element;a.fixNavigationButtons()};this.resetWizard=function(){e('a[data-toggle="tab"]',b).off("click",l);e('a[data-toggle="tab"]',b).off("shown shown.bs.tab",m);b=d.find("ul:first",d);f=b.find('li:has([data-toggle="tab"]).active',d);e('a[data-toggle="tab"]',b).on("click",l);e('a[data-toggle="tab"]',b).on("shown shown.bs.tab",m);a.fixNavigationButtons()};b=d.find("ul:first",d);f=b.find('li:has([data-toggle="tab"]).active',d);b.hasClass(c.tabClass)||b.addClass(c.tabClass);
|
||||
if(c.onInit&&"function"===typeof c.onInit)c.onInit(f,b,0);if(c.onShow&&"function"===typeof c.onShow)c.onShow(f,b,a.nextIndex());e('a[data-toggle="tab"]',b).on("click",l);e('a[data-toggle="tab"]',b).on("shown shown.bs.tab",m)};e.fn.bootstrapWizard=function(d){if("string"==typeof d){var k=Array.prototype.slice.call(arguments,1);1===k.length&&k.toString();return this.data("bootstrapWizard")[d](k)}return this.each(function(a){a=e(this);if(!a.data("bootstrapWizard")){var g=new n(a,d);a.data("bootstrapWizard",
|
||||
g);g.fixNavigationButtons()}})};e.fn.bootstrapWizard.defaults={tabClass:"nav nav-pills",nextSelector:".wizard li.next",previousSelector:".wizard li.previous",firstSelector:".wizard li.first",lastSelector:".wizard li.last",backSelector:".wizard li.back",onShow:null,onInit:null,onNext:null,onPrevious:null,onLast:null,onFirst:null,onBack:null,onTabChange:null,onTabClick:null,onTabShow:null}})(jQuery);
|
||||
|
|
@ -685,13 +685,9 @@ ul.dropdown-menu li a {
|
|||
}
|
||||
}
|
||||
|
||||
/** Settings dialog */
|
||||
#settings_dialog {
|
||||
.modal-body {
|
||||
#settings_dialog_menu {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
#settings_dialog_menu,
|
||||
#wizard_dialog_menu {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
56
src/octoprint/templates/dialogs/wizard.jinja2
Normal file
56
src/octoprint/templates/dialogs/wizard.jinja2
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<div id="wizard_dialog" class="modal hide fade large" data-backdrop="static" data-keyboard="false">
|
||||
<div class="modal-header">
|
||||
<h3><i class="icon-magic"></i> {{ _('Setup Wizard') }}</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="full-sized-box">
|
||||
<div class="tabbable row-fluid">
|
||||
<div class="span3 scrollable" id="wizard_dialog_menu">
|
||||
<ul class="nav nav-list" id="wizardTabs">
|
||||
{% for key in templates.wizard.order %}
|
||||
{% set entry, data = templates.wizard.entries[key] %}
|
||||
{% if data is none %}
|
||||
<li class="nav-header">{{ entry }}</li>
|
||||
{% else %}
|
||||
{% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- ko allowBindings: false -->{% endif %}
|
||||
<li id="{{ data._div }}_link"
|
||||
{% if "data_bind" in data %}data-bind="{{ data.data_bind }}"{% endif %}
|
||||
class="{% if "classes_link" in data %}{{ data.classes_link|join(' ') }}{% elif "classes" in data %}{{ data.classes|join(' ') }}{% endif %}"
|
||||
{% if "styles_link" in data %} style="{{ data.styles_link|join(', ') }}" {% elif "styles" in data %} style="{{ data.styles|join(', ') }}" {% endif %}
|
||||
>
|
||||
<a href="#{{ data._div }}" data-toggle="tab">{{ entry }}</a>
|
||||
</li>
|
||||
{% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- /ko -->{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content span9 scrollable" id="wizard_dialog_content">
|
||||
{% for key in templates.wizard.order %}
|
||||
{% set entry, data = templates.wizard.entries[key] %}
|
||||
{% if data is not none %}
|
||||
{% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- ko allowBindings: false -->{% endif %}
|
||||
<div id="{{ data._div }}"
|
||||
{% if "data_bind" in data %}data-bind="{{ data.data_bind }}"{% endif %}
|
||||
class="tab-pane {% if classes_content in data %}{{ data.classes_content|join(' ') }}{% elif classes in data %}{{ data.classes|join(' ') }}{% endif %}"
|
||||
{% if "styles_content" in data %} style="{{ data.styles_content|join(', ') }}" {% elif styles in data %} style="{{ data.styles|join(', ') }}" {% endif %}
|
||||
>
|
||||
{% include data.template ignore missing %}
|
||||
</div>
|
||||
{% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- /ko -->{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="pull-right">
|
||||
<button class="btn btn-primary button-next" name="next">{{ _('Next') }}</button>
|
||||
<button class="btn btn-primary button-finish" style="display: none" name="finish">{{ _('Finish') }}</button>
|
||||
</div>
|
||||
<div class="pull-left">
|
||||
<button class="btn button-previous" name="previous">{{ _('Previous') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
50
src/octoprint/templates/dialogs/wizard/accesscontrol.jinja2
Normal file
50
src/octoprint/templates/dialogs/wizard/accesscontrol.jinja2
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<h3>{{ _('Access Control') }}</h3>
|
||||
|
||||
{% trans %}<p>
|
||||
<strong>Please read the following, it is very important for your printer's health!</strong>
|
||||
</p>
|
||||
<p>
|
||||
OctoPrint by default now ships with Access Control enabled, meaning you won't be able to do anything with the
|
||||
printer unless you login first as a configured user. This is to <strong>prevent strangers - possibly with
|
||||
malicious intent - to gain access to your printer</strong> via the internet or another untrustworthy network
|
||||
and using it in such a way that it is damaged or worse (i.e. causes a fire).
|
||||
</p>
|
||||
<p>
|
||||
It looks like you haven't configured access control yet. Please <strong>set up an username and password</strong> for the
|
||||
initial administrator account who will have full access to both the printer and OctoPrint's settings, then click
|
||||
on "Keep Access Control Enabled":
|
||||
</p>{% endtrans %}
|
||||
<form class="form-horizontal">
|
||||
<div class="control-group" data-bind="css: {success: validUsername()}">
|
||||
<label class="control-label" for="first_run_username">{{ _('Username') }}</label>
|
||||
<div class="controls">
|
||||
<input type="text" class="input-medium" data-bind="value: username, valueUpdate: 'afterkeydown'">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group" data-bind="css: {success: validPassword()}">
|
||||
<label class="control-label" for="first_run_username">{{ _('Password') }}</label>
|
||||
<div class="controls">
|
||||
<input type="password" class="input-medium" data-bind="value: password, valueUpdate: 'afterkeydown'">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group" data-bind="css: {error: passwordMismatch(), success: validPassword() && !passwordMismatch()}">
|
||||
<label class="control-label" for="first_run_username">{{ _('Confirm Password') }}</label>
|
||||
<div class="controls">
|
||||
<input type="password" class="input-medium" data-bind="value: confirmedPassword, valueUpdate: 'afterkeydown'">
|
||||
<span class="help-inline" data-bind="visible: passwordMismatch()">{{ _('Passwords do not match') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% trans %}<p>
|
||||
<strong>Note:</strong> In case that your OctoPrint installation is only accessible from within a trustworthy network and you don't
|
||||
need Access Control for other reasons, you may alternatively disable Access Control. You should only
|
||||
do this if you are absolutely certain that only people you know and trust will be able to connect to it.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Do NOT underestimate the risk of an unsecured access from the internet to your printer!</strong>
|
||||
</p>{% endtrans %}
|
||||
|
||||
<div class="row-fluid">
|
||||
<a href="#" class="btn btn-danger span6" data-bind="click: disableAccessControl">{{ _('Disable Access Control') }}</a>
|
||||
<a href="#" class="btn btn-primary span6" data-bind="click: keepAccessControl, enable: validData(), css: {disabled: !validData()}">{{ _('Keep Access Control Enabled') }}</a>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<h3>{{ _('All Done!') }}</h3>
|
||||
|
||||
{% trans %}
|
||||
Your OctoPrint installation is now all set up and ready to go. Happy
|
||||
printing!
|
||||
{% endtrans %}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<h3>{{ _('Hello!') }}</h3>
|
||||
|
||||
{% trans %}
|
||||
Thank you for installing OctoPrint! This wizard will lead you through the
|
||||
final steps to get your OctoPrint instance all setup and ready to go!
|
||||
{% endtrans %}
|
||||
|
|
@ -129,6 +129,7 @@
|
|||
{% include 'dialogs/settings.jinja2' %}
|
||||
{% include 'dialogs/slicing.jinja2' %}
|
||||
{% include 'dialogs/usersettings.jinja2' %}
|
||||
{% include 'dialogs/wizard.jinja2' %}
|
||||
<!-- End of dialogs -->
|
||||
|
||||
<!-- Overlays -->
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
var CONFIG_TEMPERATURE_GRAPH = {% if enableTemperatureGraph -%} true; {% else %} false; {%- endif %}
|
||||
var CONFIG_GCODE_SIZE_THRESHOLD = {{ gcodeThreshold }};
|
||||
var CONFIG_GCODE_MOBILE_SIZE_THRESHOLD = {{ gcodeMobileThreshold }};
|
||||
var CONFIG_WIZARD = {% if wizard -%} true; {% else %} false; {%- endif %}
|
||||
|
||||
var SOCKJS_URI = "{{ url_for('index') }}" + "sockjs";
|
||||
var SOCKJS_DEBUG = CONFIG_DEBUG;
|
||||
|
|
|
|||
Loading…
Reference in a new issue