-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resolution configurable is now a Vue component #420
Changes from 15 commits
374e001
a8eb69c
f629058
abfe0ad
6f1e8bb
3565f2b
2253541
60bf323
f07ebfb
fa76ab9
3c60633
979eac3
078e128
aa4daae
bd8feee
84af7a0
f6ba4b5
7dcc427
cee2c2e
9aeeec8
7523ad9
b641e98
1d96bf9
8e51e49
dc43241
79ee5f0
825bc1a
359b218
0eeec36
6b731d1
c12f7e5
26bc9f4
daa9e2b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,17 @@ | ||
define([ | ||
"jquery", | ||
"home/configurables" | ||
], function (configurables) { | ||
], function ($, configurables) { | ||
"use strict"; | ||
|
||
QUnit.module("home.configurables"); | ||
QUnit.test("instantiation", function (assert) { | ||
var resolution_class = configurables.from_tag("resolution"); | ||
var resolution = new resolution_class(); | ||
var resolution = $.extend(true, {}, configurables["resolution"]); | ||
|
||
assert.equal(resolution.tag, "resolution"); | ||
assert.equal(resolution.resolution, "Window"); | ||
|
||
resolution.resolution = "1024x768"; | ||
assert.equal(resolution.as_config_dict().resolution, "1024x768"); | ||
}); | ||
|
||
QUnit.test("view", function (assert) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in principle you can still use the view on a configurable component. |
||
var resolution_class = configurables.from_tag("resolution"); | ||
var resolution = new resolution_class(); | ||
assert.equal(resolution.value, "Window"); | ||
|
||
var view = resolution.view(); | ||
assert.notEqual(view.find("select"), null); | ||
assert.equal(view.find("option").length, | ||
resolution.resolution_options.length); | ||
resolution.value = "1024x768"; | ||
assert.equal(resolution.as_config_dict().resolution, "1024x768"); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,85 +1,53 @@ | ||
define([ | ||
"jquery", | ||
"handlebars", | ||
"utils" | ||
], function($, hb, utils) { | ||
"utils", | ||
"components/vue/dist/vue.min" | ||
], function(utils, Vue) { | ||
"use strict"; | ||
|
||
var view_template = hb.compile( | ||
'<div class="form-group">' + | ||
'<label for="resolution-model-{{index}}">Resolution</label>' + | ||
'<select class="form-control" id="resolution-model-{{ index }}">' + | ||
'{{#each options}}' + | ||
'<option value="{{this}}">{{this}}</option>' + | ||
'{{/each}}' + | ||
'</div>' | ||
); | ||
var resolution_tag = 'resolution'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Vue recommends to use a hyphen. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe resolution-component? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make sure that you use reasonable differentiation between the configurable tag (e.g. "resolution") and the component tag (which is e.g. "resolution-component") |
||
Vue.component(resolution_tag, { | ||
// Your configurable must have a "value" property | ||
props: ['value'], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. data? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. config_dict ? |
||
|
||
var ResolutionModel = function () { | ||
// Model for the resolution configurable. | ||
var self = this; | ||
this.resolution = "Window"; | ||
this.resolution_options = ["Window", "1920x1080", "1280x1024", "1280x800", "1024x768"]; | ||
|
||
self.view = function (index) { | ||
// Creates the View to add to the application entry. | ||
var widget = $(view_template({ | ||
options: self.resolution_options, | ||
index: index | ||
})); | ||
|
||
widget.find("select").change(function() { | ||
if (this.selectedIndex) { | ||
self.resolution = this.options[this.selectedIndex].value; | ||
} | ||
}); | ||
|
||
return widget; | ||
}; | ||
}; | ||
|
||
ResolutionModel.prototype.tag = "resolution"; | ||
|
||
ResolutionModel.prototype.as_config_dict = function() { | ||
// Returns the configuration dict to hand over to the API request. | ||
// e.g. | ||
// { | ||
// "resolution" : "1024x768" | ||
// } | ||
// The returned dictionary must be added to the configurable | ||
// parameter under the key given by the tag member. | ||
var resolution = this.resolution; | ||
|
||
if (resolution === 'Window') { | ||
var max_size = utils.max_iframe_size(); | ||
resolution = max_size[0]+"x"+max_size[1]; | ||
template: | ||
'<div class="form-group">' + | ||
' <label>Resolution</label>' + | ||
' <select class="form-control" v-model="sel_value">' + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. call it selected_value |
||
' <option v-for="resolution_option in resolution_options">' + | ||
' {{resolution_option}}' + | ||
' </option>' + | ||
' </select>' + | ||
'</div>', | ||
|
||
data: function() { | ||
return { | ||
sel_value: this.value, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. selected_value |
||
resolution_options: ['Window', '1920x1080', '1280x1024', '1280x800', '1024x768'] | ||
}; | ||
}, | ||
|
||
watch: { | ||
value: function() {this.sel_value = this.value;}, // model -> view update | ||
sel_value: function() {this.$emit('update:value', this.sel_value);} // view -> model update | ||
} | ||
return { | ||
"resolution": resolution | ||
}; | ||
}; | ||
|
||
// Define all your configurables here. | ||
var configurables = { | ||
ResolutionModel: ResolutionModel | ||
}; | ||
var from_tag = function (tag) { | ||
// Given a tag, lookup the appropriate configurable and | ||
// return it. If the tag matches no configurable, returns null | ||
for (var conf in configurables) { | ||
if (configurables[conf].prototype.tag === tag) { | ||
return configurables[conf]; | ||
}); | ||
|
||
// Export all your configurable models here | ||
// (must implement tag and value attributes and as_config_dict method) | ||
return { | ||
resolution: { | ||
tag: resolution_tag, | ||
value: 'Window', | ||
as_config_dict: function() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be in the model. All your interaction should be with the model, and the component is just a view that is inserted in the right place. |
||
var resolution = this.value; | ||
|
||
if (this.value === 'Window') { | ||
var max_size = utils.max_iframe_size(); | ||
resolution = max_size[0] + 'x' + max_size[1]; | ||
} | ||
|
||
return { 'resolution': resolution }; | ||
} | ||
} | ||
return null; | ||
}; | ||
|
||
var ns = { | ||
from_tag: from_tag | ||
}; | ||
|
||
return $.extend(ns, configurables); | ||
|
||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -110,7 +110,6 @@ define([ | |
.done(function(new_data) { | ||
app.app_data = new_data; | ||
|
||
this._update_configurables(app); | ||
this._update_status(app); | ||
}.bind(this)); | ||
}; | ||
|
@@ -121,15 +120,15 @@ define([ | |
// to its client-side model. | ||
app.configurables = []; | ||
|
||
app.app_data.image.configurables.forEach(function(tag) { | ||
app.app_data.image.configurables.forEach(function(conf_name) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be tag |
||
// If this returns null, the tag has not been recognized | ||
// by the client. skip it and let the server deal with the | ||
// missing data, either by using a default or throwing | ||
// an error. | ||
var ConfigurableCls = configurables.from_tag(tag); | ||
var configurable = configurables[conf_name]; | ||
|
||
if (ConfigurableCls !== null) { | ||
app.configurables.push(new ConfigurableCls()); | ||
if (configurable !== null) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's undefined, not null, if you have an element that is not there. |
||
app.configurables.push($.extend(true, {}, configurable)); | ||
} | ||
}); | ||
}; | ||
|
@@ -151,8 +150,7 @@ define([ | |
|
||
var configurables_data = {}; | ||
current_app.configurables.forEach(function(configurable) { | ||
var tag = configurable.tag; | ||
configurables_data[tag] = configurable.as_config_dict(); | ||
configurables_data[configurable.tag] = configurable.as_config_dict(); | ||
}); | ||
|
||
resources.Container.create({ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,7 +42,15 @@ define([ | |
' </ul>' + | ||
|
||
' <h4>Configuration</h4>' + | ||
' <form class="configuration"><fieldset></fieldset></form>' + | ||
' <form class="configuration">' + | ||
' <fieldset v-if="current_app.configurables.length === 0">No configurable options for this image</fieldset>' + | ||
' <fieldset v-else :disabled="current_app.is_starting()">' + | ||
' <component v-for="configurable in current_app.configurables"' + | ||
' :is="configurable.tag"' + | ||
' :value="configurable.value"' + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sync There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can use .sync in this case. it should work, we are using vue 2.3 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I said in the other comment, I tried to use |
||
' @update:value="value => configurable.value = value"></component>' + | ||
' </fieldset>' + | ||
' </form>' + | ||
' </div>' + | ||
|
||
' <!-- Start Button -->' + | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you can workaround jquery, try. otherwise keep it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I use jQuery for the
extend
method which does a deep copy of the dictionary representing the model of the configurable. Underscore provides anextend
method too but it doesn't do a deep copy of the dictionary.Instead of returning a list of dictionaries representing the models of configurables in
configurable.js
I could return a list of classes. So we get rid of this deep copy of dictionaries.