Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
87df38e
Install vue with bower instead of NPM
martinRenou Apr 18, 2017
d7a09a7
Replace the old ApplicationListView by a Vue ViewModel
martinRenou Apr 18, 2017
4c08083
Delete unused handlebars helpers
martinRenou Apr 18, 2017
14fc736
Create ApplicationListView template
martinRenou Apr 18, 2017
051d193
Fixed imports
martinRenou Apr 18, 2017
b25d692
Fix import
martinRenou Apr 18, 2017
60ffdfb
Started to adapt the controller to the new Application list ViewModel
martinRenou Apr 18, 2017
1cbd133
Changed data representation of the model
martinRenou Apr 24, 2017
b625942
Adapt controller with the new model data representation
martinRenou Apr 24, 2017
a9cf5a0
Adapt ApplicationListView with the new model data representation
martinRenou Apr 24, 2017
0440ef5
Adapt ApplicationView with the new model data representation
martinRenou Apr 24, 2017
31ddfaf
Fixed little issues
martinRenou Apr 24, 2017
27928b2
Add comment
martinRenou Apr 24, 2017
6760912
Add stop button
martinRenou Apr 24, 2017
e3f334e
Fix linter tests
martinRenou Apr 24, 2017
c17ef68
Fix model tests
martinRenou Apr 24, 2017
5554651
Fix view tests
martinRenou Apr 24, 2017
88b2ca1
Try to fix selenium test (DOM elements has been changed)
martinRenou Apr 24, 2017
7143e94
Use minified version of Vue
martinRenou Apr 24, 2017
adee7bd
Try to fix selenium tests
martinRenou Apr 24, 2017
c5891a3
Fix selenium tests
martinRenou Apr 24, 2017
7c82057
Fix selenium test
martinRenou Apr 24, 2017
08c22a7
Fix selenium tests
martinRenou Apr 24, 2017
ed7ae38
Fixed init path
stefanoborini Apr 24, 2017
3acffe7
Fix indentation of the bower file
martinRenou Apr 25, 2017
d4c982c
Now assign the model to the ApplicationListView at instantiation
martinRenou Apr 25, 2017
a15b9d3
Use shorthands for vue attributes
martinRenou Apr 25, 2017
5d5ccd9
The stop-button hover event is now triggered with pure CSS
martinRenou Apr 25, 2017
93a48cd
Clear unused code
martinRenou Apr 25, 2017
48eb4a8
Use filters for icon and application name
martinRenou Apr 25, 2017
0c35794
Configurables is now a list, fixing the issue of Vue adding a __ob__ …
martinRenou Apr 25, 2017
11eaf35
Try to fix focus selenium test
martinRenou Apr 25, 2017
3f52280
Fix jstests
martinRenou Apr 25, 2017
88e398f
Use if else-if
martinRenou Apr 25, 2017
1bea069
Undo last commit
martinRenou Apr 25, 2017
a8d6dfb
Fix issue with unknown "this"
martinRenou Apr 25, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"dependencies": {
"bootstrap": "components/bootstrap#~3.1",
"font-awesome": "~4.5",
"ionicons" : "~2.0.1",
"ionicons": "~2.0.1",
"jquery": "components/jquery#~2.0",
"moment": "~2.7",
"requirejs": "~2.1",
Expand All @@ -24,7 +24,8 @@
"handlebars": "~4.0.5",
"underscore": "~1.8.3",
"html5shiv": "~3.7.3",
"respond": "~1.4.2"
"respond": "~1.4.2",
"vue": "^2.2.6"
},
"devDependencies": {
"blanket": "^1.1.7"
Expand Down
11 changes: 5 additions & 6 deletions jstests/tests/home/test_models.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
define([
"home/models"
"home/models"
], function (models) {
"use strict";

QUnit.module("home.models");
QUnit.test("instantiation", function (assert) {
var model = new models.ApplicationListModel();
assert.equal(model.app_data.length, 0);
assert.equal(model.app_list.length, 0);
model.update().done(function() {
assert.equal(model.app_data.length, 2);
assert.equal(model.app_data[0].image.configurables[0], "resolution");
assert.notEqual(model.configurables[0].resolution, null);
assert.equal(model.configurables[0].resolution.resolution, "Window");
assert.equal(model.app_list.length, 2);
assert.equal(model.app_list[0].app_data.image.configurables[0], "resolution");
assert.equal(model.app_list[0].configurables[0].resolution, "Window");
});
});
});
Expand Down
21 changes: 13 additions & 8 deletions jstests/tests/home/test_views.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
define([
"home/models",
"home/views/application_list_view",
"home/views/application_list_view",
"jquery"
], function (models, application_list_view, $) {
"use strict";
QUnit.module("home.views");
QUnit.test("rendering", function (assert) {
assert.expect(2);

var model = new models.ApplicationListModel();
var view = new application_list_view.ApplicationListView(model);
var view = new application_list_view.ApplicationListView(
{ model: model }
);

assert.ok(view.loading);

model.update()
.done(function() { view.render(); } )
.done(function() {
var applist = $("#applist");
assert.equal(applist.children().length, 2);
})
view.model = model;
view.loading = false;
} )
.done(function() {
model.app_data[0].image.ui_name = "Hello";
view.update_entry(0);
assert.notOk(view.loading);
});
});
});
11 changes: 6 additions & 5 deletions jstests/testsuite.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
moment: "../components/moment/moment",
"jsapi/v1/resources": "../../../jstests/tests/home/mock_jsapi",
handlebars: "../components/handlebars/handlebars.amd.min",
underscore: "../components/underscore/underscore-min"
underscore: "../components/underscore/underscore-min",
vue: "../components/vue/dist/vue"
},
shim: {
bootstrap: {
Expand All @@ -18,8 +19,8 @@
}
});

require([
"init",
require([
"home/init",
"tests/home/test_configurables.js",
"tests/home/test_models.js",
"tests/home/test_views.js",
Expand All @@ -31,9 +32,9 @@
prefix: "/"
};
init.handlebars();

QUnit.load();
QUnit.start();
});
});
}());

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
},
"dependencies": {
"bower": "*",
"configurable-http-proxy": "git://github.com/jupyterhub/configurable-http-proxy.git#2.0.1",
"vue": "^2.2.6"
"configurable-http-proxy": "git://github.com/jupyterhub/configurable-http-proxy.git#2.0.1"
},
"devDependencies": {
"jshint": "*",
Expand Down
10 changes: 9 additions & 1 deletion remoteappmanager/static/css/remoteappmanager.css
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ body {
}

.stop-button {
display: block;
display: none;
position: absolute;
top: 10px;
left: 15px;
Expand All @@ -148,6 +148,14 @@ body {
color: rgba(255, 255, 255, 0.7);
}

/* When the mouse is on the img or the stop-button -> display stop-button */
li a img:hover + .stop-button {
display: block;
}
li a .stop-button:hover {
display: block;
}

.truncate {
overflow: hidden;
text-overflow: ellipsis;
Expand Down
105 changes: 47 additions & 58 deletions remoteappmanager/static/js/home/controller.js
Original file line number Diff line number Diff line change
@@ -1,102 +1,94 @@
/*globals: require, console*/
require([
"jquery",
"urlutils",
"home/init",
"jquery",
"urlutils",
"dialogs",
"gamodule",
"home/models",
"home/models",
"home/views/application_list_view",
"home/views/application_view",
"jsapi/v1/resources",
"handlebars",
"init"
"jsapi/v1/resources"
], function(
$,
urlutils,
dialogs,
gamodule,
models,
init,
$,
urlutils,
dialogs,
gamodule,
models,
application_list_view,
application_view,
resources,
hb,
init) {
application_view,
resources) {
"use strict";

var ga = gamodule.init();
init.handlebars();

var Status = models.Status;

// This model keeps the retrieved content from the REST query locally.
// It is only synchronized at initial load.
var model = new models.ApplicationListModel();
var app_list_view = new application_list_view.ApplicationListView(model);
var app_list_view = new application_list_view.ApplicationListView(
{ model: model }
);
var app_view = new application_view.ApplicationView(model);

app_list_view.entry_clicked = function (index) {
model.selected_index = index;
app_list_view.update_selected();
// Temporary solution, when ApplicationView will be a Vue Object the render
// will be automatically triggered
app_list_view.selected_app_callback = function () {
app_view.render(false, 200);
};

app_list_view.stop_button_clicked = function(index) {
if (model.status[index] === models.Status.STOPPING) {

// Temporary solution, when ApplicationView will be a Vue Object the render
// will be automatically triggered
app_list_view.stop_application_callback = function(index) {
if (model.app_list[index].status === Status.STOPPING) {
return;
}
model.status[index] = models.Status.STOPPING;
var app_info = model.app_data[index];
model.app_list[index].status = Status.STOPPING;

var app_info = model.app_list[index].app_data;
var url_id = app_info.container.url_id;

app_list_view.update_entry(index);

resources.Container.delete(url_id)
.done(function () {
model.update_idx(index)
.done(function() {
app_list_view.update_entry(index);
app_view.render(true);
})
.fail(function(error) {
model.status[index] = models.Status.STOPPED;
app_list_view.update_entry(index);
model.app_list[index].status = Status.STOPPED;
app_view.render(true);
dialogs.webapi_error_dialog(error);
});
})
.fail(
function (error) {
model.status[index] = models.Status.STOPPED;
app_list_view.update_entry(index);
model.app_list[index].status = Status.STOPPED;
app_view.render(true);
dialogs.webapi_error_dialog(error);
});
};

app_view.start_button_clicked = function (index) {
// The container is not running. This is a start button.
var mapping_id = model.app_data[index].mapping_id;
var image_name = model.app_data[index].image.name;
var mapping_id = model.app_list[index].app_data.mapping_id;
var image_name = model.app_list[index].app_data.image.name;

if (model.status[index] === models.Status.STARTING) {
if (model.app_list[index].status === Status.STARTING) {
return;
}
model.status[index] = models.Status.STARTING;

model.app_list[index].status = Status.STARTING;
app_view.render(false, null);
app_list_view.update_entry(index);

var configurables_data = {};
var configurables = model.configurables[index];
configurables_data = {};

Object.getOwnPropertyNames(configurables).forEach(
function(val, idx, array) { // jshint ignore:line
var configurable = configurables[val];
var tag = configurable.tag;
configurables_data[tag] = configurable.as_config_dict();
}
);

model.app_list[index].configurables.forEach(function(configurable) {
var tag = configurable.tag;
configurables_data[tag] = configurable.as_config_dict();
});

resources.Container.create({
mapping_id: mapping_id,
configurables: configurables_data
Expand All @@ -109,27 +101,24 @@ require([

model.update_idx(index)
.always(function() {
app_list_view.update_entry(index);
app_list_view.update_selected();
app_view.render(true, 200);
})
.fail(function(error) {
model.status[index] = models.Status.STOPPED;
app_list_view.update_entry(index);
model.app_list[index].status = Status.STOPPED;
app_view.render(true, 200);
dialogs.webapi_error_dialog(error);
});
}).fail(function(error) {
model.status[index] = models.Status.STOPPED;
app_list_view.update_entry(index);
app_list_view.update_selected();
model.app_list[index].status = Status.STOPPED;
app_view.render(true, 200);
dialogs.webapi_error_dialog(error);
});
};

$.when(model.update()).done(function () {
app_list_view.render();
$.when(model.update()).done(function () {
app_list_view.loading = false;
app_list_view.model = model;

app_view.render(false, 200);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ define([
"urlutils"
], function(hb, urlutils) {
"use strict";

return {
handlebars : function() {
hb.registerHelper('icon_src', function(app_data) {
Expand Down
Loading