diff --git a/.babelrc b/.babelrc
new file mode 100644
index 000000000..9390834ba
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,3 @@
+{
+ presets: ['env', 'es2015']
+}
diff --git a/jstests/tests/user/test_application_list_view.js b/jstests/tests/user/test_application_list_view.js
index 1d4a6b351..3ce38a967 100644
--- a/jstests/tests/user/test_application_list_view.js
+++ b/jstests/tests/user/test_application_list_view.js
@@ -1,14 +1,14 @@
var Vue = require("vuejs");
-var models = require("user/models");
-var applicationListView = require("user/views/application_list_view");
+var ApplicationListModel = require("user/ApplicationListModel");
+var ApplicationListView = require("user/vue-components/ApplicationListView");
require("filters");
QUnit.module("user.app_list_view");
QUnit.test("rendering list", function (assert) {
var done = assert.async();
- var model = new models.ApplicationListModel();
- var appListView = new applicationListView.ApplicationListView({
+ var model = new ApplicationListModel();
+ var appListView = new ApplicationListView({
data: function() { return { model: model }; }
}).$mount();
@@ -39,8 +39,8 @@ QUnit.test("rendering list", function (assert) {
QUnit.test("rendering nothing in the list", function (assert) {
var done = assert.async();
- var model = new models.ApplicationListModel();
- var appListView = new applicationListView.ApplicationListView({
+ var model = new ApplicationListModel();
+ var appListView = new ApplicationListView({
data: function() { return { model: model }; }
}).$mount();
@@ -67,8 +67,8 @@ QUnit.test("rendering nothing in the list", function (assert) {
QUnit.test("search form", function (assert) {
var done = assert.async();
- var model = new models.ApplicationListModel();
- var appListView = new applicationListView.ApplicationListView({
+ var model = new ApplicationListModel();
+ var appListView = new ApplicationListView({
data: function() { return { model: model }; }
}).$mount();
diff --git a/jstests/tests/user/test_application_view.js b/jstests/tests/user/test_application_view.js
index 62c657dd3..c8279b76f 100644
--- a/jstests/tests/user/test_application_view.js
+++ b/jstests/tests/user/test_application_view.js
@@ -1,14 +1,14 @@
var Vue = require("vuejs");
-var models = require("user/models");
-var applicationView = require("user/views/application_view");
+var ApplicationListModel = require("user/ApplicationListModel");
+var ApplicationView = require("user/vue-components/ApplicationView");
require("filters");
QUnit.module("user.app_view");
QUnit.test("rendering form", function (assert) {
var done = assert.async();
- var model = new models.ApplicationListModel();
- var appView = new applicationView.ApplicationView({
+ var model = new ApplicationListModel();
+ var appView = new ApplicationView({
data: function() { return { model: model }; }
}).$mount();
@@ -40,8 +40,8 @@ QUnit.test("rendering form", function (assert) {
QUnit.test("rendering iframe", function (assert) {
var done = assert.async();
- var model = new models.ApplicationListModel();
- var appView = new applicationView.ApplicationView({
+ var model = new ApplicationListModel();
+ var appView = new ApplicationView({
data: function() { return { model: model }; }
}).$mount();
diff --git a/jstests/tests/user/test_configurables.js b/jstests/tests/user/test_configurables.js
index f6b7ce7c7..78d379d09 100644
--- a/jstests/tests/user/test_configurables.js
+++ b/jstests/tests/user/test_configurables.js
@@ -1,8 +1,9 @@
-var configurables = require("user/configurables");
+var configurables = require("user/configurables/configurables");
+var Resolution = require("user/configurables/Resolution");
QUnit.module("user.configurables");
QUnit.test("instantiation", function (assert) {
- var resolutionConf = new configurables.resolution.model();
+ var resolutionConf = new configurables.resolution();
assert.equal(resolutionConf.tag, "resolution");
assert.deepEqual(resolutionConf.configDict, { resolution: "Window" });
@@ -14,7 +15,7 @@ QUnit.test("instantiation", function (assert) {
QUnit.test("view", function (assert) {
var propsData = { configDict: { resolution: "Window" } };
- var component = new configurables.resolution.component({propsData: propsData}).$mount();
+ var component = new Resolution({propsData: propsData}).$mount();
assert.notEqual(component.$el.querySelector("select"), null);
assert.equal(component.$el.querySelector("select").children.length, 5);
diff --git a/jstests/tests/user/test_models.js b/jstests/tests/user/test_models.js
index 84bb684ec..f04db2bb2 100644
--- a/jstests/tests/user/test_models.js
+++ b/jstests/tests/user/test_models.js
@@ -1,8 +1,8 @@
-var models = require("user/models");
+var ApplicationListModel = require("user/ApplicationListModel");
-QUnit.module("user.models");
+QUnit.module("user.ApplicationListModel");
QUnit.test("instantiation", function (assert) {
- var model = new models.ApplicationListModel();
+ var model = new ApplicationListModel();
assert.equal(model.appList.length, 0);
assert.equal(model.selectedIndex, null);
diff --git a/package.json b/package.json
index 25440cabf..e22e5f195 100644
--- a/package.json
+++ b/package.json
@@ -22,8 +22,12 @@
"babel-core": "^6.24.1",
"babel-loader": "^7.0.0",
"babel-preset-env": "^1.4.0",
+ "babel-preset-es2015": "^6.24.1",
+ "css-loader": "^0.28.1",
"jshint": "*",
"node-qunit-phantomjs": "*",
+ "vue-loader": "^12.0.4",
+ "vue-template-compiler": "^2.3.3",
"webpack": "2.5.1"
}
}
diff --git a/remoteappmanager/static/js/admin/vue-components/AccountingView.js b/remoteappmanager/static/js/admin/vue-components/AccountingView.js
deleted file mode 100644
index de35a1916..000000000
--- a/remoteappmanager/static/js/admin/vue-components/AccountingView.js
+++ /dev/null
@@ -1,127 +0,0 @@
-let resources = require("admin-resources");
-let NewAccountingDialog = require("./accounting/NewAccountingDialog");
-
-module.exports = {
- components: {
- 'new-accounting-dialog': NewAccountingDialog
- },
-
- template:
- `
- Accounting for user {{ $route.params.id }}
-
-
- Error: {{communicationError}}
-
-
-
-
-
-
- Do you want to remove accounting
- {{ removeAccountingDialog.accountingToRemove }}?
-
-
-
- `,
-
- data: function () {
- return {
- table: {
- headers: [
- "ID", "Image", "Workspace", "Vol. source", "Vol. target", "Readonly"
- ],
- rows: [],
- globalActions: [{
- label: "Create New Entry",
- callback: () => { this.newAccountingDialog.show = true; }
- }],
- rowActions: [{
- label: "Remove",
- callback: this.removeAction
- }]
- },
-
- newAccountingDialog: {
- show: false,
- userId: this.$route.params.id
- },
-
- removeAccountingDialog: {
- show: false,
- accountingToRemove: null
- },
-
- communicationError: null
- };
- },
-
- mounted: function () {
- this.updateTable();
- },
-
- methods: {
- updateTable: function() {
- this.communicationError = null;
- resources.Accounting.items({filter: JSON.stringify({user_id: this.$route.params.id })})
- .done((identifiers, items) => {
- this.table.rows = [];
- identifiers.forEach((id) => {
- let item = items[id];
- this.table.rows.push([
- id,
- item.image_name,
- item.allow_home,
- item.volume_source,
- item.volume_target,
- item.volume_mode === "ro"
- ]);
- });
- })
- .fail(() => {
- this.communicationError = "The request could not be executed successfully";
- });
- },
-
- newAccountingCreated: function() {
- this.newAccountingDialog.show = false;
- this.updateTable();
- },
-
- removeAction: function(row) {
- this.removeAccountingDialog.accountingToRemove = row[0];
- this.removeAccountingDialog.show = true;
- },
-
- closeRemoveAccountingDialog: function() {
- this.removeAccountingDialog.show = false;
- this.removeAccountingDialog.accountingToRemove = null;
- },
-
- removeAccounting: function () {
- resources.Accounting.delete(this.removeAccountingDialog.accountingToRemove)
- .done(() => {
- this.closeRemoveAccountingDialog();
- this.updateTable();
- })
- .fail(() => {
- this.closeRemoveAccountingDialog();
- this.communicationError = "The request could not be executed successfully";
- });
- }
- }
-};
-
diff --git a/remoteappmanager/static/js/admin/vue-components/AccountingView.vue b/remoteappmanager/static/js/admin/vue-components/AccountingView.vue
new file mode 100644
index 000000000..3a74f1069
--- /dev/null
+++ b/remoteappmanager/static/js/admin/vue-components/AccountingView.vue
@@ -0,0 +1,131 @@
+
+
+ Accounting for user {{ $route.params.id }}
+
+
+ Error: {{communicationError}}
+
+
+
+
+
+
+
+
+ Do you want to remove accounting
+ {{ removeAccountingDialog.accountingToRemove }}?
+
+
+
+
+
+
+
diff --git a/remoteappmanager/static/js/admin/vue-components/ApplicationsView.js b/remoteappmanager/static/js/admin/vue-components/ApplicationsView.js
deleted file mode 100644
index c0d6cc2ed..000000000
--- a/remoteappmanager/static/js/admin/vue-components/ApplicationsView.js
+++ /dev/null
@@ -1,130 +0,0 @@
-let resources = require("admin-resources");
-let NewApplicationDialog = require("./applications/NewApplicationDialog");
-
-module.exports = {
- components: {
- 'new-application-dialog': NewApplicationDialog
- },
-
- template:
- `
-
-
- Error: {{communicationError}}
-
-
-
-
-
-
- Do you want to remove Application
- {{removeApplicationDialog.applicationToRemove.name}}
- ({{removeApplicationDialog.applicationToRemove.id}})
-
-
- `,
-
- data: function () {
- return {
- table: {
- headers: ["ID", "Image"],
- rows: [],
- globalActions: [{
- label: "Create New Entry",
- callback: () => { this.newApplicationDialog.show = true; }
- }],
- rowActions: [{
- label: "Remove",
- callback: this.removeAction
- }]
- },
-
- newApplicationDialog: {
- show: false
- },
-
- removeApplicationDialog: {
- show: false,
- applicationToRemove: {
- id: null,
- name: ""
- }
- },
-
- communicationError: null
- };
- },
-
- mounted: function () {
- this.updateTable();
- },
-
- methods: {
- updateTable: function() {
- this.communicationError = null;
- resources.Application.items()
- .done((identifiers, items) => {
- this.table.rows = [];
- identifiers.forEach((id) => {
- let item = items[id];
- this.table.rows.push([
- id,
- item.image_name
- ]);
- });
- })
- .fail(() => {
- this.communicationError = "The request could not be executed successfully";
- });
- },
-
- newApplicationCreated: function() {
- this.newApplicationDialog.show = false;
- this.updateTable();
- },
-
- newApplicationDialogClosed: function() {
- this.newApplicationDialog.show = false;
- },
-
- removeAction: function(row) {
- this.removeApplicationDialog.applicationToRemove = {
- id: row[0],
- name: row[1]
- };
- this.removeApplicationDialog.show = true;
- },
-
- removeApplication: function () {
- resources.Application.delete(this.removeApplicationDialog.applicationToRemove.id)
- .done(() => {
- this.closeRemoveApplicationDialog();
- this.updateTable();
- })
- .fail(() => {
- this.closeRemoveApplicationDialog();
- this.communicationError = "The request could not be executed successfully";
- });
- },
- closeRemoveApplicationDialog: function() {
- this.removeApplicationDialog.show = false;
- this.removeApplicationDialog.applicationToRemove = {
- name: "",
- id: null
- };
- }
- }
-};
-
diff --git a/remoteappmanager/static/js/admin/vue-components/ApplicationsView.vue b/remoteappmanager/static/js/admin/vue-components/ApplicationsView.vue
new file mode 100644
index 000000000..088c46203
--- /dev/null
+++ b/remoteappmanager/static/js/admin/vue-components/ApplicationsView.vue
@@ -0,0 +1,133 @@
+
+
+
+
+ Error: {{communicationError}}
+
+
+
+
+
+
+
+ Do you want to remove Application
+ {{removeApplicationDialog.applicationToRemove.name}}
+ ({{removeApplicationDialog.applicationToRemove.id}})
+
+
+
+
+
+
diff --git a/remoteappmanager/static/js/admin/vue-components/ContainersView.js b/remoteappmanager/static/js/admin/vue-components/ContainersView.js
deleted file mode 100644
index 6869d1e78..000000000
--- a/remoteappmanager/static/js/admin/vue-components/ContainersView.js
+++ /dev/null
@@ -1,90 +0,0 @@
-let resources = require("admin-resources");
-
-module.exports = {
- template:
- `
-
- Error: {{communicationError}}
-
-
-
-
- Do you want to stop container {{ stopContainerDialog.containerToStop }}?
-
- `,
-
- data: function () {
- return {
- table: {
- headers: ["URL ID", "User", "Image", "Docker ID", "Mapping ID"],
- rows: [],
- rowActions: [{
- label: "Stop",
- callback: this.stopAction
- }]
- },
- stopContainerDialog: {
- show: false,
- containerToStop: null
- },
- communicationError: null
- };
- },
-
- mounted: function () {
- this.updateTable();
- },
-
- methods: {
- updateTable: function() {
- this.communicationError = null;
- resources.Container.items()
- .done((identifiers, items) => {
- this.table.rows = [];
- identifiers.forEach((id) => {
- let item = items[id];
- this.table.rows.push([
- id,
- item.user,
- item.image_name,
- item.docker_id,
- item.mapping_id
- ]);
- });
- })
- .fail(() => {
- this.communicationError = "The request could not be executed successfully";
- });
- },
-
- stopAction: function(row) {
- this.stopContainerDialog.containerToStop = row[0];
- this.stopContainerDialog.show = true;
- },
-
- stopContainer: function () {
- resources.Container.delete(this.stopContainerDialog.containerToStop)
- .done(() => {
- this.updateTable();
- this.closeStopContainerDialog();
- })
- .fail(() => {
- this.closeStopContainerDialog();
- this.communicationError = "The request could not be executed successfully";
- });
- },
-
- closeStopContainerDialog: function() {
- this.stopContainerDialog.show = false;
- this.stopContainerDialog.containerToStop = null;
- }
- }
-};
diff --git a/remoteappmanager/static/js/admin/vue-components/ContainersView.vue b/remoteappmanager/static/js/admin/vue-components/ContainersView.vue
new file mode 100644
index 000000000..40bff6f28
--- /dev/null
+++ b/remoteappmanager/static/js/admin/vue-components/ContainersView.vue
@@ -0,0 +1,93 @@
+
+
+
+ Error: {{communicationError}}
+
+
+
+
+ Do you want to stop container {{ stopContainerDialog.containerToStop }}?
+
+
+
+
+
diff --git a/remoteappmanager/static/js/admin/vue-components/MainView.js b/remoteappmanager/static/js/admin/vue-components/MainView.js
deleted file mode 100644
index daf4eba75..000000000
--- a/remoteappmanager/static/js/admin/vue-components/MainView.js
+++ /dev/null
@@ -1,65 +0,0 @@
-let resources = require("admin-resources");
-
-module.exports = {
- template:
- `
-
-
-
-
-
- Error: {{communicationError}}
-
-
-
-
-
Total users
-
{{ num_total_users }}
-
-
-
Number of applications
-
{{ num_applications }}
-
-
-
-
Active users
-
{{ num_active_users }}
-
-
-
Running containers
-
{{ num_running_containers }}
-
-
-
-
-
-
`,
-
- data: function() {
- return {
- communicationError: null,
- realm: "",
- num_total_users: "",
- num_applications: "",
- num_active_users: "",
- num_running_containers: ""
- };
- },
-
- mounted: function() {
- resources.Stats.retrieve()
- .done((rep) => {
- this.realm = rep.realm;
- this.num_total_users = rep.num_total_users;
- this.num_applications = rep.num_applications;
- this.num_active_users = rep.num_active_users;
- this.num_running_containers = rep.num_running_containers;
- })
- .fail(() => {
- this.communicationError = "The request could not be executed successfully";
- });
- }
-};
diff --git a/remoteappmanager/static/js/admin/vue-components/MainView.vue b/remoteappmanager/static/js/admin/vue-components/MainView.vue
new file mode 100644
index 000000000..883f3083b
--- /dev/null
+++ b/remoteappmanager/static/js/admin/vue-components/MainView.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+ Error: {{communicationError}}
+
+
+
+
+
Total users
+
{{ num_total_users }}
+
+
+
Number of applications
+
{{ num_applications }}
+
+
+
+
Active users
+
{{ num_active_users }}
+
+
+
Running containers
+
{{ num_running_containers }}
+
+
+
+
+
+
+
+
+
diff --git a/remoteappmanager/static/js/admin/vue-components/UsersView.js b/remoteappmanager/static/js/admin/vue-components/UsersView.js
deleted file mode 100644
index 1b3403b83..000000000
--- a/remoteappmanager/static/js/admin/vue-components/UsersView.js
+++ /dev/null
@@ -1,127 +0,0 @@
-let resources = require("admin-resources");
-let NewUserDialog = require("./users/NewUserDialog");
-
-module.exports = {
- components: {
- 'new-user-dialog': NewUserDialog,
- },
-
- template:
- `
-
- Error: {{communicationError}}
-
-
-
-
-
- Do you want to remove User {{removeUserDialog.userToRemove.name}}
- ({{removeUserDialog.userToRemove.id}})
-
- `,
-
- data: function () {
- return {
- table: {
- headers: ["ID", "Username"],
- rows: [],
- globalActions: [{
- label: "Create New Entry",
- callback: () => { this.newUserDialog.show = true; }
- }],
- rowActions: [{
- label: "Policies",
- callback: this.showPolicyAction,
- type: "info"
- }, {
- label: "Remove",
- callback: this.removeAction
- }]
- },
- users: [],
- newUserDialog: {
- show: false
- },
- removeUserDialog: {
- show: false,
- userToRemove: {
- id: null,
- name: ""
- }
- },
- communicationError: null
- };
- },
-
- mounted: function () {
- this.updateTable();
- },
-
- methods: {
- updateTable: function() {
- this.communicationError = null;
- resources.User.items()
- .done((identifiers, items) => {
- this.table.rows = [];
- identifiers.forEach((id) => {
- let item = items[id];
- this.table.rows.push([
- id,
- item.name
- ]);
- });
- })
- .fail(() => {
- this.communicationError = "The request could not be executed successfully";
- });
- },
-
- newUserCreated: function() {
- this.newUserDialog.show = false;
- this.updateTable();
- },
-
- showPolicyAction: function(row) {
- this.$router.push({
- name: 'user_accounting',
- params: { id: row[0] }
- });
- },
-
- removeAction: function(row) {
- this.removeUserDialog.userToRemove.id = row[0];
- this.removeUserDialog.userToRemove.name = row[1];
- this.removeUserDialog.show = true;
- },
-
- closeRemoveUserDialog: function() {
- this.removeUserDialog.show = false;
- this.removeUserDialog.userToRemove = {
- id: null,
- name: ""
- };
- },
-
- removeUser: function () {
- resources.User.delete(this.removeUserDialog.userToRemove.id)
- .done(() => {
- this.closeRemoveUserDialog();
- this.updateTable();
- })
- .fail(() => {
- this.closeRemoveUserDialog();
- });
- }
- }
-};
diff --git a/remoteappmanager/static/js/admin/vue-components/UsersView.vue b/remoteappmanager/static/js/admin/vue-components/UsersView.vue
new file mode 100644
index 000000000..c115973f0
--- /dev/null
+++ b/remoteappmanager/static/js/admin/vue-components/UsersView.vue
@@ -0,0 +1,130 @@
+
+
+
+ Error: {{communicationError}}
+
+
+
+
+
+ Do you want to remove User {{removeUserDialog.userToRemove.name}}
+ ({{removeUserDialog.userToRemove.id}})
+
+
+
+
+
diff --git a/remoteappmanager/static/js/admin/vue-components/accounting/NewAccountingDialog.js b/remoteappmanager/static/js/admin/vue-components/accounting/NewAccountingDialog.js
deleted file mode 100644
index 87374dd34..000000000
--- a/remoteappmanager/static/js/admin/vue-components/accounting/NewAccountingDialog.js
+++ /dev/null
@@ -1,150 +0,0 @@
-let resources = require("admin-resources");
-
-module.exports = {
- template:
- `
-
-
- `,
-
- props: ['show', "userId"],
-
- data: function () {
- return {
- formstate: {},
- crossValidationError: false,
- communicationError: null,
- model: {
- image_name: '',
- allow_home: false,
- volume_source: '',
- volume_target: '',
- volume_readonly: false,
- volume_source_target: []
- }
- };
- },
-
- methods: {
- close: function () {
- this.$emit('closed');
- },
-
- fieldClassName: function (field) {
- if (!field) {
- return '';
- }
- if ((field.$dirty || field.$submitted) && field.$invalid) {
- return 'has-error';
- } else {
- return '';
- }
- },
-
- createNewAccounting: function () {
- let model = this.model;
- let formstate = this.formstate;
-
- if (formstate.$invalid) {
- return;
- }
- if ((model.volume_source.length === 0 && model.volume_target.length !== 0) ||
- (model.volume_source.length !== 0 && model.volume_target.length === 0)) {
- this.crossValidationError = true;
- return;
- }
-
- let rep = {
- user_id: this.userId,
- image_name: this.model.image_name,
- allow_home: this.model.allow_home,
- volume_source: this.model.volume_source,
- volume_target: this.model.volume_target,
- volume_mode: (model.volume_readonly ? "ro" : "rw")
- };
-
- resources.Accounting.create(rep)
- .done(() => {
- this.$emit('created');
- })
- .fail(() => {
- this.communicationError = "The request could not be executed successfully";
- });
- },
-
- reset: function () {
- Object.assign(this.$data, this.$options.data());
- },
-
- validatePath: function(value) {
- return (value.length === 0 || value[0] === '/');
- }
- },
-
- watch: {
- "show": function (value) {
- if (value) {
- this.reset();
- }
- },
- "model.volume_source": function() {
- delete this.formstate.volume_source.$error.volumesInconsistent;
- delete this.formstate.volume_target.$error.volumesInconsistent;
- },
- "model.volume_target": function() {
- delete this.formstate.volume_source.$error.volumesInconsistent;
- delete this.formstate.volume_target.$error.volumesInconsistent;
- }
- }
-};
diff --git a/remoteappmanager/static/js/admin/vue-components/accounting/NewAccountingDialog.vue b/remoteappmanager/static/js/admin/vue-components/accounting/NewAccountingDialog.vue
new file mode 100644
index 000000000..bae46a615
--- /dev/null
+++ b/remoteappmanager/static/js/admin/vue-components/accounting/NewAccountingDialog.vue
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+
+
diff --git a/remoteappmanager/static/js/admin/vue-components/applications/NewApplicationDialog.js b/remoteappmanager/static/js/admin/vue-components/applications/NewApplicationDialog.js
deleted file mode 100644
index 2c8e2ed2f..000000000
--- a/remoteappmanager/static/js/admin/vue-components/applications/NewApplicationDialog.js
+++ /dev/null
@@ -1,80 +0,0 @@
-let resources = require("admin-resources");
-
-module.exports = {
- template:
- `
-
-
-
-
- Image Name
-
-
- Image Name cannot be empty
-
-
-
-
-
- `,
-
- props: ['show'],
-
- data: function () {
- return {
- formstate: {},
- communicationError: null,
- model: {
- name: ''
- }
- };
- },
-
- methods: {
- close: function () {
- this.$emit('closed');
- },
-
- fieldClassName: function (field) {
- if (!field) {
- return '';
- }
- if ((field.$touched || field.$submitted) && field.$invalid) {
- return 'has-error';
- } else {
- return '';
- }
- },
-
- createNewApplication: function () {
- if (!this.formstate.$valid) {
- return;
- }
- resources.Application.create({image_name: this.model.name})
- .done(() => {
- this.$emit('created');
- })
- .fail(() => {
- this.communicationError = "The request could not be executed successfully";
- });
- },
-
- reset: function () {
- Object.assign(this.$data, this.$options.data());
- }
- },
-
- watch: {
- "show": function (value) {
- if (value) {
- this.reset();
- }
- }
- }
-};
diff --git a/remoteappmanager/static/js/admin/vue-components/applications/NewApplicationDialog.vue b/remoteappmanager/static/js/admin/vue-components/applications/NewApplicationDialog.vue
new file mode 100644
index 000000000..fee1b5c01
--- /dev/null
+++ b/remoteappmanager/static/js/admin/vue-components/applications/NewApplicationDialog.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+ Image Name
+
+
+ Image Name cannot be empty
+
+
+
+
+
+
+
+
+
diff --git a/remoteappmanager/static/js/admin/vue-components/users/NewUserDialog.js b/remoteappmanager/static/js/admin/vue-components/users/NewUserDialog.js
deleted file mode 100644
index 832a24265..000000000
--- a/remoteappmanager/static/js/admin/vue-components/users/NewUserDialog.js
+++ /dev/null
@@ -1,76 +0,0 @@
-let resources = require("admin-resources");
-
-module.exports = {
- template:
- `
-
-
-
-
- User Name
-
-
- User Name cannot be empty
-
-
-
-
-
- `,
-
- props: ['show'],
-
- data: function () {
- return {
- formstate: {},
- model: {
- name: ''
- }
- };
- },
-
- methods: {
- close: function () {
- this.$emit('closed');
- },
-
- fieldClassName: function (field) {
- if (!field) {
- return '';
- }
- if ((field.$touched || field.$submitted) && field.$invalid) {
- return 'has-error';
- } else {
- return '';
- }
- },
-
- createNewUser: function () {
- if (!this.formstate.$valid) {
- return;
- }
- resources.User.create({name: this.model.name})
- .done(() => {
- this.$emit('created');
- })
- .fail(() => {
- this.$emit("closed");
- });
- },
-
- reset: function () {
- Object.assign(this.$data, this.$options.data());
- }
- },
-
- watch: {
- "show": function (value) {
- if (value) {
- this.reset();
- }
- }
- }
-};
diff --git a/remoteappmanager/static/js/admin/vue-components/users/NewUserDialog.vue b/remoteappmanager/static/js/admin/vue-components/users/NewUserDialog.vue
new file mode 100644
index 000000000..c1dfe41a7
--- /dev/null
+++ b/remoteappmanager/static/js/admin/vue-components/users/NewUserDialog.vue
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+ User Name
+
+
+ User Name cannot be empty
+
+
+
+
+
+
+
+
+
diff --git a/remoteappmanager/static/js/user/models.js b/remoteappmanager/static/js/user/ApplicationListModel.js
similarity index 97%
rename from remoteappmanager/static/js/user/models.js
rename to remoteappmanager/static/js/user/ApplicationListModel.js
index b5a279afa..3f2f86c1b 100644
--- a/remoteappmanager/static/js/user/models.js
+++ b/remoteappmanager/static/js/user/ApplicationListModel.js
@@ -1,6 +1,6 @@
let $ = require("jquery");
let resources = require("user-resources");
-let configurables = require("./configurables");
+let configurables = require("./configurables/configurables");
let Status = {
RUNNING: "RUNNING",
@@ -123,7 +123,7 @@ class ApplicationListModel {
// by the client. skip it and let the server deal with the
// missing data, either by using a default or throwing
// an error.
- let ConfigurableCls = configurables[tag].model;
+ let ConfigurableCls = configurables[tag];
if (ConfigurableCls !== undefined) {
app.configurables.push(new ConfigurableCls());
@@ -200,6 +200,4 @@ class ApplicationListModel {
}
}
-module.exports = {
- ApplicationListModel
-};
+module.exports = ApplicationListModel;
diff --git a/remoteappmanager/static/js/user/configurables.js b/remoteappmanager/static/js/user/configurables.js
deleted file mode 100644
index f248fe2d6..000000000
--- a/remoteappmanager/static/js/user/configurables.js
+++ /dev/null
@@ -1,59 +0,0 @@
-let Vue = require("vuejs");
-let utils = require("utils");
-
-let resolutionTag = 'resolution';
-const resolutionComponent = Vue.component(resolutionTag + '-component', {
- // Your configurable must have a "configDict" property from the model
- props: ['configDict'],
-
- template:
- `
- Resolution
-
-
- {{resolutionOption}}
-
-
-
`,
-
- data: function() {
- return {
- resolution: this.configDict.resolution,
- resolutionOptions: ['Window', '1920x1080', '1280x1024', '1280x800', '1024x768']
- };
- },
-
- watch: {
- configDict: function() { this.resolution = this.configDict.resolution; }, // model -> view update
- resolution: function() { this.$emit('update:configDict', { resolution: this.resolution }); } // view -> model update
- }
-});
-
-// Your configurable class must implement a tag and default configDict
-class ResolutionModel {
- constructor() {
- this.tag = resolutionTag;
- this.configDict = { resolution: 'Window' };
- }
-
- asConfigDict() {
- let resolution = this.configDict.resolution;
-
- if (resolution === 'Window') {
- let maxSize = utils.maxIframeSize();
- resolution = maxSize[0] + 'x' + maxSize[1];
- }
-
- return { resolution: resolution };
- }
-}
-
-let outputConfigurables = {};
-
-// Export all your configurable models here
-outputConfigurables[resolutionTag] = {
- model: ResolutionModel,
- component: resolutionComponent
-};
-
-module.exports = outputConfigurables;
\ No newline at end of file
diff --git a/remoteappmanager/static/js/user/configurables/Resolution.vue b/remoteappmanager/static/js/user/configurables/Resolution.vue
new file mode 100644
index 000000000..793e9f467
--- /dev/null
+++ b/remoteappmanager/static/js/user/configurables/Resolution.vue
@@ -0,0 +1,32 @@
+
+
+ Resolution
+
+
+ {{resolutionOption}}
+
+
+
+
+
+
diff --git a/remoteappmanager/static/js/user/configurables/configurables.js b/remoteappmanager/static/js/user/configurables/configurables.js
new file mode 100644
index 000000000..348ed97c4
--- /dev/null
+++ b/remoteappmanager/static/js/user/configurables/configurables.js
@@ -0,0 +1,30 @@
+let utils = require("utils");
+
+require("./Resolution");
+
+
+// Your configurable class must implement a tag and default configDict
+class ResolutionModel {
+ constructor() {
+ this.tag = 'resolution';
+ this.configDict = { resolution: 'Window' };
+ }
+
+ asConfigDict() {
+ let resolution = this.configDict.resolution;
+
+ if (resolution === 'Window') {
+ let maxSize = utils.maxIframeSize();
+ resolution = maxSize[0] + 'x' + maxSize[1];
+ }
+
+ return { resolution: resolution };
+ }
+}
+
+let outputConfigurables = {};
+
+// Export all your configurable models here respecting the tag (here resolution)
+outputConfigurables.resolution = ResolutionModel;
+
+module.exports = outputConfigurables;
diff --git a/remoteappmanager/static/js/user/main.js b/remoteappmanager/static/js/user/main.js
index 4f752b0db..d68d942e4 100644
--- a/remoteappmanager/static/js/user/main.js
+++ b/remoteappmanager/static/js/user/main.js
@@ -1,20 +1,20 @@
let gamodule = require("gamodule");
-let models = require("./models");
-let applicationListView = require("./views/application_list_view");
-let applicationView = require("./views/application_view");
+let ApplicationListModel = require("./ApplicationListModel");
+let ApplicationListView = require("./vue-components/ApplicationListView");
+let ApplicationView = require("./vue-components/ApplicationView");
require("filters");
// This model keeps the retrieved content from the REST query locally.
// It is only synchronized at initial load.
-let model = new models.ApplicationListModel();
+let model = new ApplicationListModel();
// Initialize views
-let appListView = new applicationListView.ApplicationListView({
+let appListView = new ApplicationListView({
el: '#applist',
data: function() { return { model: model }; }
});
-let appView = new applicationView.ApplicationView({
+let appView = new ApplicationView({
el: '#appview',
data: function() { return { model: model }; }
});
diff --git a/remoteappmanager/static/js/user/views/application_list_view.js b/remoteappmanager/static/js/user/views/application_list_view.js
deleted file mode 100644
index 0b2973d3f..000000000
--- a/remoteappmanager/static/js/user/views/application_list_view.js
+++ /dev/null
@@ -1,105 +0,0 @@
-let Vue = require("vuejs");
-require("toolkit");
-
-const ApplicationListView = Vue.extend({
- template:
- `
- `,
-
- data: function() {
- return {
- 'searchInput': '',
- stoppingError: { show: false, appName: '', code: '', message: '' }
- };
- },
-
- computed: {
- visibleList: function() {
- return this.model.appList.filter((app) => {
- let appName = this.$options.filters.appName(app.appData.image).toLowerCase();
- return appName.indexOf(this.searchInput.toLowerCase()) !== -1;
- });
- }
- },
-
- methods: {
- stopApplication: function(index) {
- let stoppingAppName = this.$options.filters.appName(
- this.model.appList[index].appData.image);
- this.model.stopApplication(index).fail((error) => {
- this.stoppingError.code = error.code;
- this.stoppingError.message = error.message;
- this.stoppingError.appName = stoppingAppName;
- this.stoppingError.show = true;
- });
- },
- closeDialog: function() {
- this.stoppingError.show = false;
- },
- indexOf: function(app) {
- return this.model.appList.indexOf(app);
- }
- }
-});
-
-module.exports = {
- ApplicationListView
-};
diff --git a/remoteappmanager/static/js/user/views/application_view.js b/remoteappmanager/static/js/user/views/application_view.js
deleted file mode 100644
index 416fbd959..000000000
--- a/remoteappmanager/static/js/user/views/application_view.js
+++ /dev/null
@@ -1,148 +0,0 @@
-let Vue = require("vuejs");
-let urlUtils = require("urlutils");
-let utils = require("utils");
-require("toolkit");
-
-const ApplicationView = Vue.extend({
- template:
- `
-
-
-
-
- Code: {{startingError.code}}
- {{startingError.message}}
-
-
-
-
-
-
-
-
-
-
Description
-
{{ currentApp.appData.image.description }}
-
-
Policy
-
-
-
-
- Workspace accessible
-
-
- Workspace not accessible
-
-
-
-
- Volume mounted: {{ appPolicy.volume_source }} → {{ appPolicy.volume_target }} ({{ appPolicy.volume_mode }})
-
-
- No volumes mounted
-
-
-
-
Configuration
-
-
-
-
-
-
-
-
-
-
-
- `,
-
- data: function() {
- return {
- startingError: { show: false, appName: '', code: '', message: '' }
- };
- },
-
- computed: {
- currentApp: function() {
- return this.model.appList[this.model.selectedIndex] || null;
- },
- appPolicy: function() {
- return this.currentApp.appData.image.policy;
- },
- appSource: function() {
- let url = urlUtils.pathJoin(
- window.apidata.base_url,
- 'containers',
- this.currentApp.appData.container.url_id
- );
- let output = this.currentApp.delayed ? url : url + '/';
-
- this.currentApp.delayed = false;
-
- return output;
- }
- },
-
- methods: {
- startApplication: function() {
- let startingApp = this.currentApp;
- let startingAppName = this.$options.filters.appName(startingApp.appData.image);
- this.model.startApplication()
- .done(() => {
- this.$emit('startApplication', startingApp);
- })
- .fail((error) => {
- this.startingError.code = error.code;
- this.startingError.message = error.message;
- this.startingError.appName = startingAppName;
- this.startingError.show = true;
- });
- },
- closeDialog: function() {
- this.startingError.show = false;
- },
- getIframeSize: function() {
- return utils.maxIframeSize();
- },
- focusIframe: function() {
- let iframe = this.$el.querySelector('iframe');
- if(iframe !== null) {
- iframe.focus();
- }
- }
- },
-
- updated: function() { this.focusIframe(); }
-});
-
-module.exports = {
- ApplicationView
-};
diff --git a/remoteappmanager/static/js/user/vue-components/ApplicationListView.vue b/remoteappmanager/static/js/user/vue-components/ApplicationListView.vue
new file mode 100644
index 000000000..67bb9b41e
--- /dev/null
+++ b/remoteappmanager/static/js/user/vue-components/ApplicationListView.vue
@@ -0,0 +1,102 @@
+
+
+
+
+
diff --git a/remoteappmanager/static/js/user/vue-components/ApplicationView.vue b/remoteappmanager/static/js/user/vue-components/ApplicationView.vue
new file mode 100644
index 000000000..6e3fa4254
--- /dev/null
+++ b/remoteappmanager/static/js/user/vue-components/ApplicationView.vue
@@ -0,0 +1,147 @@
+
+
+
+
+
+
+ Code: {{startingError.code}}
+ {{startingError.message}}
+
+
+
+
+
+
+
+
+
+
Description
+
{{ currentApp.appData.image.description }}
+
+
Policy
+
+
+
+
+ Workspace accessible
+
+
+ Workspace not accessible
+
+
+
+
+ Volume mounted: {{ appPolicy.volume_source }} → {{ appPolicy.volume_target }} ({{ appPolicy.volume_mode }})
+
+
+ No volumes mounted
+
+
+
+
Configuration
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/remoteappmanager/static/js/vue/toolkit/AdminLTEBox.js b/remoteappmanager/static/js/vue/toolkit/AdminLTEBox.js
deleted file mode 100644
index 32791c257..000000000
--- a/remoteappmanager/static/js/vue/toolkit/AdminLTEBox.js
+++ /dev/null
@@ -1,17 +0,0 @@
-module.exports = {
- props: {
- title: {
- type: String,
- default: "Box"
- }
- },
- template:
- ` `
-};
diff --git a/remoteappmanager/static/js/vue/toolkit/AdminLTEBox.vue b/remoteappmanager/static/js/vue/toolkit/AdminLTEBox.vue
new file mode 100644
index 000000000..9a190e6be
--- /dev/null
+++ b/remoteappmanager/static/js/vue/toolkit/AdminLTEBox.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/remoteappmanager/static/js/vue/toolkit/ConfirmDialog.js b/remoteappmanager/static/js/vue/toolkit/ConfirmDialog.js
deleted file mode 100644
index d5e32fdff..000000000
--- a/remoteappmanager/static/js/vue/toolkit/ConfirmDialog.js
+++ /dev/null
@@ -1,30 +0,0 @@
-module.exports = {
- props: {
- title: {
- type: String,
- default: "Confirm"
- },
- closeCallback: {
- type: Function,
- default: undefined
- },
- okCallback: {
- type: Function,
- default: function() {}
- }
- },
- template: `
-
- `
-};
diff --git a/remoteappmanager/static/js/vue/toolkit/ConfirmDialog.vue b/remoteappmanager/static/js/vue/toolkit/ConfirmDialog.vue
new file mode 100644
index 000000000..fde0248bf
--- /dev/null
+++ b/remoteappmanager/static/js/vue/toolkit/ConfirmDialog.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
diff --git a/remoteappmanager/static/js/vue/toolkit/DataTable.js b/remoteappmanager/static/js/vue/toolkit/DataTable.js
deleted file mode 100644
index a676cbbf6..000000000
--- a/remoteappmanager/static/js/vue/toolkit/DataTable.js
+++ /dev/null
@@ -1,43 +0,0 @@
-module.exports = {
- props: [
- "headers", "rows", "globalActions", "rowActions"
- ],
- methods: {
- isBoolean: function(value) {
- return typeof(value) === "boolean";
- },
- buttonClassFromType: function(value = "danger") {
- let cls = {"btn": true};
- cls["btn-" + value] = true;
- return cls;
- }
- },
- template:
- `
-
- {{action.label}}
-
-
-
-
- {{header}}
- Actions
-
-
-
-
-
-
- {{value}}
-
-
- {{action.label}}
-
-
-
-
-
`
-};
diff --git a/remoteappmanager/static/js/vue/toolkit/DataTable.vue b/remoteappmanager/static/js/vue/toolkit/DataTable.vue
new file mode 100644
index 000000000..4556c1109
--- /dev/null
+++ b/remoteappmanager/static/js/vue/toolkit/DataTable.vue
@@ -0,0 +1,47 @@
+
+
+
+ {{action.label}}
+
+
+
+
+ {{header}}
+ Actions
+
+
+
+
+
+
+ {{value}}
+
+
+ {{action.label}}
+
+
+
+
+
+
+
+
diff --git a/remoteappmanager/static/js/vue/toolkit/ModalDialog.js b/remoteappmanager/static/js/vue/toolkit/ModalDialog.js
deleted file mode 100644
index 6da7b4a59..000000000
--- a/remoteappmanager/static/js/vue/toolkit/ModalDialog.js
+++ /dev/null
@@ -1,12 +0,0 @@
-module.exports = {
- template: `
-
- `
-};
\ No newline at end of file
diff --git a/remoteappmanager/static/js/vue/toolkit/ModalDialog.vue b/remoteappmanager/static/js/vue/toolkit/ModalDialog.vue
new file mode 100644
index 000000000..3e8d4c195
--- /dev/null
+++ b/remoteappmanager/static/js/vue/toolkit/ModalDialog.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/webpackfile-test.js b/webpackfile-test.js
index 8fc547ae8..b7521aa0f 100644
--- a/webpackfile-test.js
+++ b/webpackfile-test.js
@@ -14,7 +14,7 @@ module.exports = {
},
resolve: {
- extensions: ["*", ".js"],
+ extensions: ["*", ".js", ".vue"],
alias: {
lodash: path.resolve(components, "lodash/dist/lodash"),
jquery: path.resolve(components, "admin-lte/plugins/jQuery/jquery-2.2.3.min"),
@@ -44,10 +44,13 @@ module.exports = {
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
- loader: 'babel-loader',
- options: {
- presets: ['env']
- }
+ loader: 'babel-loader'
+ }
+ },
+ {
+ test: /\.vue$/,
+ use: {
+ loader: 'vue-loader'
}
}
]
diff --git a/webpackfile.js b/webpackfile.js
index ace1900ae..5f718d566 100644
--- a/webpackfile.js
+++ b/webpackfile.js
@@ -14,7 +14,7 @@ module.exports = {
},
resolve: {
- extensions: ["*", ".js"],
+ extensions: ["*", ".js", ".vue"],
alias: {
lodash: path.resolve(components, "lodash/dist/lodash"),
jquery: path.resolve(components, "admin-lte/plugins/jQuery/jquery-2.2.3.min"),
@@ -39,10 +39,13 @@ module.exports = {
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
- loader: 'babel-loader',
- options: {
- presets: ['env']
- }
+ loader: 'babel-loader'
+ }
+ },
+ {
+ test: /\.vue$/,
+ use: {
+ loader: 'vue-loader'
}
}
]