window.h = maquette.h class UiConfig extends ZeroFrame init: -> @save_visible = true @config = null # Setting currently set on the server @values = null # Entered values on the page @config_view = new ConfigView() window.onbeforeunload = => if @getValuesChanged().length > 0 return true else return null onOpenWebsocket: => @cmd("wrapperSetTitle", "Config - ZeroNet") @restart_loading = false @updateConfig() updateConfig: (cb) => @cmd "configList", [], (res) => @config = res @values = {} @config_storage = new ConfigStorage(@config) @config_view.values = @values @config_view.config_storage = @config_storage for key, item of res value = item.value @values[key] = @config_storage.formatValue(value) @projector.scheduleRender() cb?() createProjector: => @projector = maquette.createProjector() @projector.replace($("#content"), @render) @projector.replace($("#bottom-save"), @renderBottomSave) @projector.replace($("#bottom-restart"), @renderBottomRestart) getValuesChanged: => values_changed = [] for key, value of @values if @config_storage.formatValue(value) != @config_storage.formatValue(@config[key]?.value) values_changed.push({key: key, value: value}) return values_changed getValuesPending: => values_pending = [] for key, item of @config if item.pending values_pending.push(key) return values_pending saveValues: (cb) => changed_values = @getValuesChanged() for item, i in changed_values last = i == changed_values.length - 1 value = @config_storage.deformatValue(item.value, typeof(@config[item.key].default)) value_same_as_default = JSON.stringify(@config[item.key].default) == JSON.stringify(value) if value_same_as_default value = null if @config[item.key].item.valid_pattern and value match = value.match(@config[item.key].item.valid_pattern) if not match or match[0] != value message = "Invalid value of #{@config[item.key].item.title}: #{value} (does not matches #{@config[item.key].item.valid_pattern})" Page.cmd("wrapperNotification", ["error", message]) cb(false) break @saveValue(item.key, value, if last then cb else null) saveValue: (key, value, cb) => if key == "open_browser" if value value = "default_browser" else value = "False" Page.cmd "configSet", [key, value], (res) => if res != "ok" Page.cmd "wrapperNotification", ["error", res.error] cb?(true) render: => if not @config return h("div.content") h("div.content", [ @config_view.render() ]) handleSaveClick: => @save_loading = true @logStart "Save" @saveValues (success) => @save_loading = false @logEnd "Save" if success @updateConfig() Page.projector.scheduleRender() return false renderBottomSave: => values_changed = @getValuesChanged() h("div.bottom.bottom-save", {classes: {visible: values_changed.length}}, h("div.bottom-content", [ h("div.title", "#{values_changed.length} configuration item value changed"), h("a.button.button-submit.button-save", {href: "#Save", classes: {loading: @save_loading}, onclick: @handleSaveClick}, "Save settings") ])) handleRestartClick: => @restart_loading = true Page.cmd("serverShutdown", {restart: true}) Page.projector.scheduleRender() return false renderBottomRestart: => values_pending = @getValuesPending() values_changed = @getValuesChanged() h("div.bottom.bottom-restart", {classes: {visible: values_pending.length and not values_changed.length}}, h("div.bottom-content", [ h("div.title", "Some changed settings requires restart"), h("a.button.button-submit.button-restart", {href: "#Restart", classes: {loading: @restart_loading}, onclick: @handleRestartClick}, "Restart ZeroNet client") ])) window.Page = new UiConfig() window.Page.createProjector()