Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions jstests/tests/home/test_views.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ define([
{ model: model }
);

assert.ok(view.loading);
assert.ok(model.loading);

model.update()
.done(function() {
view.model = model;
view.loading = false;
model.loading = false;
} )
.done(function() {
assert.notOk(view.loading);
assert.notOk(model.loading);
});
});
});
18 changes: 9 additions & 9 deletions remoteappmanager/static/js/home/controller.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
/*globals: require, console*/
require([
"urlutils",
"home/models",
"home/views/application_list_view",
"home/views/application_view"
], function(
urlutils,
models,
application_list_view,
application_view) {
Expand All @@ -15,13 +13,15 @@ require([
// It is only synchronized at initial load.
var model = new models.ApplicationListModel();

var app_list_view = new application_list_view.ApplicationListView();
var app_view = new application_view.ApplicationView();

$.when(model.update()).done(function () {
app_list_view.loading = false;
new application_list_view.ApplicationListView({ // jshint ignore:line
el: '#applist',
data: function() { return { model: model }; }
});

app_list_view.model = model;
app_view.model = model;
new application_view.ApplicationView({ // jshint ignore:line
el: '#appview',
data: function() { return { model: model }; }
});

model.update();
});
142 changes: 105 additions & 37 deletions remoteappmanager/static/js/home/models.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
define([
'jquery',
'home/configurables',
'utils',
'jsapi/v1/resources'
], function ($, configurables, utils, resources) {
"jquery",
"home/configurables",
"jsapi/v1/resources",
"gamodule",
"dialogs"
], function ($, configurables, resources, gamodule, dialogs) {
"use strict";

var Status = utils.Status;
var Status = {
RUNNING: "RUNNING",
STARTING: "STARTING",
STOPPING: "STOPPING",
STOPPED: "STOPPED"
};

var available_applications_info = function () {
// Retrieve information from the various applications and
Expand Down Expand Up @@ -43,6 +49,8 @@ define([
// Should be the index of the selected app_data,
// or null if no selection.
this.selected_index = null;

this.loading = true;
};

ApplicationListModel.prototype.update = function() {
Expand All @@ -56,70 +64,130 @@ define([
).done(function (app_data) {
// app_data contains the data retrieved from the remote API

this.app_list = [];
var app_list = [];

// Add the options for some image types
app_data.forEach(function(application_data, data_idx) {
this.app_list[data_idx] = { app_data: application_data };

this._update_configurables(data_idx);
this._update_status(data_idx);
// Sort application list by names
app_data.sort(function(app1, app2) {
var app1_name = app1.image.ui_name? app1.image.ui_name: app1.image.name;
var app2_name = app2.image.ui_name? app2.image.ui_name: app2.image.name;
return app1_name < app2_name? -1: 1;
});

if (this.app_list[data_idx].status === Status.RUNNING) {
this.app_list[data_idx].delayed = false;
} else {
this.app_list[data_idx].delayed = true;
}
// Add the options for some image types
app_data.forEach(function(application_data) {
var app = {
app_data: application_data,
// Default values, will be overwritten
status: Status.STOPPED,
delayed: true,
configurables: [],
is_running: function() {return this.status === Status.RUNNING;},
is_stopped: function() {return this.status === Status.STOPPED;},
is_starting: function() {return this.status === Status.STARTING;},
is_stopping: function() {return this.status === Status.STOPPING;}
};

this._update_configurables(app);
this._update_status(app);

app.delayed = !app.is_running();
app_list.push(app);
}.bind(this));

this.app_list = app_list;
this.loading = false;
}.bind(this));
};

ApplicationListModel.prototype.update_idx = function(index) {
// Refetches and updates the entry at the given index.
var entry = this.app_list[index].app_data;
var mapping_id = entry.mapping_id;
var app = this.app_list[index];
var mapping_id = app.app_data.mapping_id;

return resources.Application.retrieve(mapping_id)
.done(function(new_data) {
this.app_list[index].app_data = new_data;
app.app_data = new_data;

this._update_configurables(index);
this._update_status(index);
this._update_configurables(app);
this._update_status(app);
}.bind(this));
};

ApplicationListModel.prototype._update_configurables = function(index) {
// Updates the configurables submodel for a given application index.
var image = this.app_list[index].app_data.image;

ApplicationListModel.prototype._update_configurables = function(app) {
// Contains the submodels for the configurables.
// It is a dictionary that maps a supported (by the image) configurable tag
// to its client-side model.
this.app_list[index].configurables = [];
app.configurables = [];

image.configurables.forEach(function(tag) {
app.app_data.image.configurables.forEach(function(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);

if (ConfigurableCls !== null) {
this.app_list[index].configurables.push(new ConfigurableCls());
app.configurables.push(new ConfigurableCls());
}
}.bind(this));
});
};

ApplicationListModel.prototype._update_status = function(index) {
var app_data = this.app_list[index].app_data;

if (app_data.container === undefined) {
this.app_list[index].status = Status.STOPPED;
ApplicationListModel.prototype._update_status = function(app) {
if (app.app_data.container === undefined) {
app.status = Status.STOPPED;
} else {
this.app_list[index].status = Status.RUNNING;
app.status = Status.RUNNING;
}
};

ApplicationListModel.prototype.start_application = function() {
var selected_index = this.selected_index;
var current_app = this.app_list[selected_index];

current_app.status = Status.STARTING;
current_app.delayed = true;

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

resources.Container.create({
mapping_id: current_app.app_data.mapping_id,
configurables: configurables_data
}).done(function() {
this.update_idx(selected_index)
.fail(function(error) {
current_app.status = Status.STOPPED;
dialogs.webapi_error_dialog(error);
});
}.bind(this)).fail(function(error) {
current_app.status = Status.STOPPED;
dialogs.webapi_error_dialog(error);
});
};

ApplicationListModel.prototype.stop_application = function(index) {
var app_stopping = this.app_list[index];
app_stopping.status = Status.STOPPING;

var url_id = app_stopping.app_data.container.url_id;

resources.Container.delete(url_id)
.done(function() {
this.update_idx(index)
.fail(function(error) {
app_stopping.status = Status.STOPPED;
dialogs.webapi_error_dialog(error);
});
}.bind(this))
.fail(function(error) {
app_stopping.status = Status.STOPPED;
dialogs.webapi_error_dialog(error);
});
};

return {
ApplicationListModel: ApplicationListModel
};
Expand Down
38 changes: 1 addition & 37 deletions remoteappmanager/static/js/home/views/application_list_view.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,13 @@
define([
'urlutils',
'utils',
"dialogs",
'../../components/vue/dist/vue.min',
"jsapi/v1/resources"
], function (urlutils, utils, dialogs, Vue, resources) {
], function (utils, Vue) {
'use strict';

var Status = utils.Status;

/* Create application_list ViewModel
(will next be wrapped in a main ViewModel which will contain the
applicationListView and the applicationView) */
var ApplicationListView = Vue.extend({
el: '#applist',

data: function() {
return {
loading: true,
model: { app_list: [], selected_index: null }
};
},

methods: {
stop_application: function(index) {
var app_stopping = this.model.app_list[index];
app_stopping.status = Status.STOPPING;

var url_id = app_stopping.app_data.container.url_id;

resources.Container.delete(url_id)
.done(function() {
this.model.update_idx(index)
.fail(function(error) {
app_stopping.status = Status.STOPPED;
dialogs.webapi_error_dialog(error);
});
}.bind(this))
.fail(function(error) {
app_stopping.status = Status.STOPPED;
dialogs.webapi_error_dialog(error);
});
}
},

filters: utils.filters
});

Expand Down
52 changes: 2 additions & 50 deletions remoteappmanager/static/js/home/views/application_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,11 @@ define([
'jquery',
"urlutils",
"utils",
"gamodule",
"dialogs",
"home/models",
'../../components/vue/dist/vue.min',
"jsapi/v1/resources"
], function ($, urlutils, utils, gamodule, dialogs, models, Vue, resources) {
'../../components/vue/dist/vue.min'

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use vue instead of vue.min

], function ($, urlutils, utils, Vue) {
"use strict";

var ga = gamodule.init();
var Status = utils.Status;

var ApplicationView = Vue.extend({
el: 'div.content-wrapper',

data: function() {
return {
model: { app_list: [], selected_index: null }
};
},

computed: {
current_app: function() {
return this.model.app_list[this.model.selected_index] || null;
Expand All @@ -44,39 +29,6 @@ define([
},

methods: {
start_application: function() {
var selected_index = this.model.selected_index;
var current_app = this.current_app;

current_app.status = Status.STARTING;
current_app.delayed = true;

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

resources.Container.create({
mapping_id: current_app.app_data.mapping_id,
configurables: configurables_data
}).done(function() {
ga("send", "event", {
eventCategory: "Application",
eventAction: "start",
eventLabel: current_app.app_data.image.name
});

this.model.update_idx(selected_index)
.fail(function(error) {
current_app.status = Status.STOPPED;
dialogs.webapi_error_dialog(error);
});
}.bind(this)).fail(function(error) {
current_app.status = Status.STOPPED;
dialogs.webapi_error_dialog(error);
});
},
get_iframe_size: function() {
return utils.max_iframe_size();
}
Expand Down
Loading