From d32f75145676bacefde0d08a14680a5984623451 Mon Sep 17 00:00:00 2001 From: Koren Lev Date: Fri, 29 Sep 2017 01:38:18 +0300 Subject: release 1.0 calipso for opnfv apex Change-Id: I3e63cd27c5f4d3756e67a07c749863a68e84dde2 Signed-off-by: Koren Lev --- ui/imports/api/accounts/methods.js | 9 +- ui/imports/api/configurations/configurations.js | 29 --- ui/imports/api/configurations/methods.js | 39 ---- .../api/configurations/server/publications.js | 21 -- .../api/connection-tests/connection-tests.js | 41 ++++ ui/imports/api/connection-tests/methods.js | 52 +++++ .../api/connection-tests/server/publications.js | 21 ++ .../monitoring-configuration.js | 7 +- ui/imports/api/environments/environments.js | 25 ++- ui/imports/api/environments/methods.js | 3 + ui/imports/api/scheduled-scans/scheduled-scans.js | 3 +- .../api/scheduled-scans/server/publications.js | 16 +- .../supported_environments.js | 18 +- ui/imports/api/user-settings/methods.js | 39 ++++ .../api/user-settings/server/publications.js | 21 ++ ui/imports/api/user-settings/user-settings.js | 29 +++ ui/imports/lib/images-for-node-type.js | 18 ++ ui/imports/startup/client/index.js | 2 +- ui/imports/startup/client/template-helpers.js | 6 + ui/imports/startup/server/register-api.js | 7 +- .../ui/components/alarm-icons/alarm-icons.html | 2 +- .../ui/components/alarm-icons/alarm-icons.js | 8 +- .../ui/components/configuration/configuration.html | 35 ---- .../ui/components/configuration/configuration.js | 123 ------------ .../ui/components/configuration/configuration.styl | 47 ----- ui/imports/ui/components/dashboard/dashboard.js | 8 +- .../detailed-node-info-box.html | 5 + .../detailed-node-info-box.styl | 8 + .../ui/components/env-aci-info/env-aci-info.html | 2 +- .../ui/components/env-aci-info/env-aci-info.js | 6 +- .../env-amqp-credentials-info.html | 4 +- .../env-amqp-credentials-info.js | 6 +- .../ui/components/env-main-info/env-main-info.html | 20 ++ .../ui/components/env-main-info/env-main-info.js | 10 + .../env-master-host-credentials-info.html | 4 +- .../env-master-host-credentials-info.js | 6 +- .../env-monitoring-info/env-monitoring-info.html | 7 + .../env-monitoring-info/env-monitoring-info.js | 3 + .../ui/components/env-nfv-info/env-nfv-info.html | 4 +- .../ui/components/env-nfv-info/env-nfv-info.js | 6 +- .../env-open-stack-db-credentials-info.html | 4 +- .../env-open-stack-db-credentials-info.js | 6 +- .../env-os-api-endpoint-info.html | 4 +- .../env-os-api-endpoint-info.js | 6 +- .../environment-dashboard/environment-dashboard.js | 8 +- .../environment-wizard/environment-wizard.js | 124 +++++++++++- .../ui/components/environment/environment.html | 51 ++--- .../ui/components/environment/environment.js | 57 ++++-- .../general-folder-node-dashboard.js | 2 +- .../graph-tooltip-window/graph-tooltip-window.js | 20 +- ui/imports/ui/components/index.styl | 2 +- ui/imports/ui/components/message/message.html | 2 +- ui/imports/ui/components/message/message.js | 7 +- .../network-graph-manager/network-graph-manager.js | 211 ++++++++++++++++----- .../ui/components/network-graph/network-graph.js | 29 ++- .../ui/components/new-scanning/new-scanning.js | 23 ++- .../scanning-request/scanning-request.js | 2 +- .../ui/components/scheduled-scan/scheduled-scan.js | 2 +- .../scheduled-scans-list/scheduled-scans-list.html | 2 +- .../ui/components/user-settings/user-settings.html | 35 ++++ .../ui/components/user-settings/user-settings.js | 123 ++++++++++++ .../ui/components/user-settings/user-settings.styl | 45 +++++ 62 files changed, 1029 insertions(+), 456 deletions(-) delete mode 100644 ui/imports/api/configurations/configurations.js delete mode 100644 ui/imports/api/configurations/methods.js delete mode 100644 ui/imports/api/configurations/server/publications.js create mode 100644 ui/imports/api/connection-tests/connection-tests.js create mode 100644 ui/imports/api/connection-tests/methods.js create mode 100644 ui/imports/api/connection-tests/server/publications.js create mode 100644 ui/imports/api/user-settings/methods.js create mode 100644 ui/imports/api/user-settings/server/publications.js create mode 100644 ui/imports/api/user-settings/user-settings.js delete mode 100644 ui/imports/ui/components/configuration/configuration.html delete mode 100644 ui/imports/ui/components/configuration/configuration.js delete mode 100644 ui/imports/ui/components/configuration/configuration.styl create mode 100644 ui/imports/ui/components/user-settings/user-settings.html create mode 100644 ui/imports/ui/components/user-settings/user-settings.js create mode 100644 ui/imports/ui/components/user-settings/user-settings.styl (limited to 'ui/imports') diff --git a/ui/imports/api/accounts/methods.js b/ui/imports/api/accounts/methods.js index 4e1c40a..f6c271c 100644 --- a/ui/imports/api/accounts/methods.js +++ b/ui/imports/api/accounts/methods.js @@ -11,6 +11,7 @@ import { SimpleSchema } from 'meteor/aldeed:simple-schema'; import * as R from 'ramda'; import { Roles } from 'meteor/alanning:roles'; import { Environments } from '/imports/api/environments/environments'; +import { UserSettings } from '/imports/api/user-settings/user-settings'; let userSchema = new SimpleSchema({ _id: { type: String }, @@ -48,6 +49,12 @@ export const insert = new ValidatedMethod({ addRole(viewEnvs, 'view-env', userId); addRole(editEnvs, 'edit-env', userId); + + let userSettings = UserSettings.schema.clean({}); + userSettings = R.merge(userSettings, { + user_id: userId, + }); + UserSettings.insert(userSettings); } }); @@ -58,7 +65,7 @@ export const update = new ValidatedMethod({ validate: userSchema .pick([ '_id', - // 'password', + // 'password', 'viewEnvs', 'viewEnvs.$', 'editEnvs', diff --git a/ui/imports/api/configurations/configurations.js b/ui/imports/api/configurations/configurations.js deleted file mode 100644 index 44cf4ee..0000000 --- a/ui/imports/api/configurations/configurations.js +++ /dev/null @@ -1,29 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / -// / -// All rights reserved. This program and the accompanying materials / -// are made available under the terms of the Apache License, Version 2.0 / -// which accompanies this distribution, and is available at / -// http://www.apache.org/licenses/LICENSE-2.0 / -///////////////////////////////////////////////////////////////////////////////////////// -import { Mongo } from 'meteor/mongo'; -import { SimpleSchema } from 'meteor/aldeed:simple-schema'; -//import * as R from 'ramda'; - -export const Configurations = new Mongo.Collection('configurations', { idGeneration: 'MONGO' }); - -let schema = { - _id: { type: { _str: { type: String, regEx: SimpleSchema.RegEx.Id } } }, - user_id: { - type: String, - }, - messages_view_backward_delta: { - type: Number, - minCount: 1, - defaultValue: '1209600000', // 14 days - } -}; - -let simpleSchema = new SimpleSchema(schema); -Configurations.schema = simpleSchema; -Configurations.attachSchema(Configurations.schema); diff --git a/ui/imports/api/configurations/methods.js b/ui/imports/api/configurations/methods.js deleted file mode 100644 index 7366e3e..0000000 --- a/ui/imports/api/configurations/methods.js +++ /dev/null @@ -1,39 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / -// / -// All rights reserved. This program and the accompanying materials / -// are made available under the terms of the Apache License, Version 2.0 / -// which accompanies this distribution, and is available at / -// http://www.apache.org/licenses/LICENSE-2.0 / -///////////////////////////////////////////////////////////////////////////////////////// -import { ValidatedMethod } from 'meteor/mdg:validated-method'; -import { Configurations } from '/imports/api/configurations/configurations'; -import * as R from 'ramda'; - -export const save = new ValidatedMethod({ - name: 'configurations.save', - validate: Configurations.simpleSchema() - .pick([ - 'messages_view_backward_delta' - ]).validator({ clean: true, filter: false }), - run({ - messages_view_backward_delta - }) { - - let userId = this.userId; - let conf = Configurations.findOne({ user_id: userId }); - - if (conf) { - Configurations.update({ _id: conf._id}, { $set: { - messages_view_backward_delta: messages_view_backward_delta - }}); - } else { - let item = Configurations.schema.clean({}); - item = R.merge(item, { - user_id: userId, - messages_view_backward_delta: messages_view_backward_delta - }); - Configurations.insert(item); - } - } -}); diff --git a/ui/imports/api/configurations/server/publications.js b/ui/imports/api/configurations/server/publications.js deleted file mode 100644 index fe9f6fd..0000000 --- a/ui/imports/api/configurations/server/publications.js +++ /dev/null @@ -1,21 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////////////// -// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / -// / -// All rights reserved. This program and the accompanying materials / -// are made available under the terms of the Apache License, Version 2.0 / -// which accompanies this distribution, and is available at / -// http://www.apache.org/licenses/LICENSE-2.0 / -///////////////////////////////////////////////////////////////////////////////////////// -import { Meteor } from 'meteor/meteor'; - -import { Configurations } from '../configurations.js'; - -Meteor.publish('configurations?user', function () { - console.log('server subscribtion: configurations?user'); - - let userId = this.userId; - - let query = { user_id: userId }; - console.log('-query: ', query); - return Configurations.find(query); -}); diff --git a/ui/imports/api/connection-tests/connection-tests.js b/ui/imports/api/connection-tests/connection-tests.js new file mode 100644 index 0000000..7acb549 --- /dev/null +++ b/ui/imports/api/connection-tests/connection-tests.js @@ -0,0 +1,41 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +import { Mongo } from 'meteor/mongo'; +import { SimpleSchema } from 'meteor/aldeed:simple-schema'; +//import * as R from 'ramda'; + +export const ConnectionTests = new Mongo.Collection('connection_tests', { idGeneration: 'MONGO' }); + +let simpleSchema = new SimpleSchema({ + _id: { type: { _str: { type: String, regEx: SimpleSchema.RegEx.Id } } }, + environment: { + type: String, + }, + + test_targets: { + type: [String], + }, + + test_configurations: { + type: [Object], + blackbox: true + }, + + submit_timestamp: { + type: String, + }, + + status: { + type: String, + defaultValue: 'request' + } +}); + +ConnectionTests.schema = simpleSchema; +ConnectionTests.attachSchema(ConnectionTests.schema); diff --git a/ui/imports/api/connection-tests/methods.js b/ui/imports/api/connection-tests/methods.js new file mode 100644 index 0000000..7badfb1 --- /dev/null +++ b/ui/imports/api/connection-tests/methods.js @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// + +import * as R from 'ramda'; +import { ValidatedMethod } from 'meteor/mdg:validated-method'; +import { ConnectionTests } from './connection-tests'; +import { getSchemaForGroupName } from '/imports/api/environments/environments'; + +export const insert = new ValidatedMethod({ + name: 'connection_tests.insert', + validate: ConnectionTests.simpleSchema() + .pick([ + 'environment', + 'test_configurations', + 'test_configurations.$', + ]).validator({ clean: true, filter: false }), + run({ + environment, + test_configurations, + }) { + let connection_test = ConnectionTests.schema.clean({}); + + test_configurations = R.filter((config) => { + let validationContext = getSchemaForGroupName(config.name).newContext(); + try { + let result = validationContext.validate(config); + return result; + } catch (_e) { + return false; + } + }, test_configurations); + + let test_targets = R.map((config) => config.name, test_configurations); + let submit_timestamp = moment().format(); + + connection_test = R.merge(connection_test, { + environment, + test_targets, + test_configurations, + submit_timestamp + }); + + let insertResult = ConnectionTests.insert(connection_test); + return insertResult; + }, +}); diff --git a/ui/imports/api/connection-tests/server/publications.js b/ui/imports/api/connection-tests/server/publications.js new file mode 100644 index 0000000..4a092b5 --- /dev/null +++ b/ui/imports/api/connection-tests/server/publications.js @@ -0,0 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +import { Meteor } from 'meteor/meteor'; +import * as R from 'ramda'; +import { ConnectionTests } from '../connection-tests.js'; + +Meteor.publish('connection_tests?_id', function (_id) { + console.log('server subscribtion to: connection_tests?_id'); + console.log('-_id: ', R.toString(_id)); + + let query = { + _id: _id, + }; + return ConnectionTests.find(query); +}); diff --git a/ui/imports/api/environments/configuration-groups/monitoring-configuration.js b/ui/imports/api/environments/configuration-groups/monitoring-configuration.js index 2b27f8a..edeaaad 100644 --- a/ui/imports/api/environments/configuration-groups/monitoring-configuration.js +++ b/ui/imports/api/environments/configuration-groups/monitoring-configuration.js @@ -51,7 +51,10 @@ export const MonitoringSchema = new SimpleSchema({ defaultValue: 'sensu' }, - rabbitmq_pass: { type: String }, + rabbitmq_pass: { + type: String, + defaultValue: 'osdna' + }, server_ip: { type: String, @@ -108,7 +111,7 @@ export const MonitoringSchema = new SimpleSchema({ ssh_password: { type: String, - defaultValue: 'calipso', + defaultValue: 'osdna', optional: true }, diff --git a/ui/imports/api/environments/environments.js b/ui/imports/api/environments/environments.js index 22e49cf..e196a69 100644 --- a/ui/imports/api/environments/environments.js +++ b/ui/imports/api/environments/environments.js @@ -180,7 +180,7 @@ let simpleSchema = new SimpleSchema({ }, distribution: { type: String, - defaultValue: 'Mirantis-8.0', + defaultValue: 'Mirantis', custom: function () { let that = this; let constsDist = Constants.findOne({ name: 'distributions' }); @@ -193,6 +193,20 @@ let simpleSchema = new SimpleSchema({ } }, }, + distribution_version: { + type: String, + custom: function () { + let that = this; + let constsDist = Constants.findOne({ name: 'distribution_versions' }); + + if (R.isNil(constsDist.data)) { return 'notAllowed'; } + let dist_versions = constsDist.data; + + if (R.isNil(R.find(R.propEq('value', that.value), dist_versions))) { + return 'notAllowed'; + } + }, + }, last_scanned: { type: String, defaultValue: '' }, @@ -219,7 +233,7 @@ let simpleSchema = new SimpleSchema({ mechanism_drivers: { type: [String], - defaultValue: ['ovs'], + defaultValue: ['OVS'], minCount: 1, custom: function () { let that = this; @@ -325,7 +339,7 @@ SimpleSchema.messages({ Environments.schema = simpleSchema; Environments.attachSchema(Environments.schema); -function getSchemaForGroupName(groupName) { +export function getSchemaForGroupName(groupName) { switch (groupName) { case 'mysql': return MysqlSchema; @@ -440,13 +454,14 @@ function extractCalcEnvSupportedRelatedValues(schemaHelper) { let dbNode = getDbNode(schemaHelper); let dist = extractValue('distribution', schemaHelper, dbNode); + let dist_version = extractValue('distribution_version', schemaHelper, dbNode); let typeDrivers = extractValue('type_drivers', schemaHelper, dbNode); let mechDrivers = extractValue('mechanism_drivers', schemaHelper, dbNode); let enable_monitoring = extractValue('enable_monitoring', schemaHelper, dbNode); let listen = extractValue('listen', schemaHelper, dbNode); - let isMonitoringSupportedRes = isMonitoringSupported(dist, typeDrivers, mechDrivers); - let isListeningSupportedRes = isListeningSupported(dist, typeDrivers, mechDrivers); + let isMonitoringSupportedRes = isMonitoringSupported(dist, dist_version, typeDrivers, mechDrivers); + let isListeningSupportedRes = isListeningSupported(dist, dist_version, typeDrivers, mechDrivers); return { enable_monitoring, diff --git a/ui/imports/api/environments/methods.js b/ui/imports/api/environments/methods.js index 6d5e73e..66d1557 100644 --- a/ui/imports/api/environments/methods.js +++ b/ui/imports/api/environments/methods.js @@ -28,6 +28,7 @@ export const insert = new ValidatedMethod({ 'configuration', 'configuration.$', 'distribution', + 'distribution_version', 'name', 'type_drivers', 'mechanism_drivers', @@ -40,6 +41,7 @@ export const insert = new ValidatedMethod({ run({ configuration, distribution, + distribution_version, name, type_drivers, mechanism_drivers, @@ -64,6 +66,7 @@ export const insert = new ValidatedMethod({ environment = R.merge(environment, { configuration, distribution, + distribution_version, name, type_drivers, mechanism_drivers, diff --git a/ui/imports/api/scheduled-scans/scheduled-scans.js b/ui/imports/api/scheduled-scans/scheduled-scans.js index 54d4565..4d06a33 100644 --- a/ui/imports/api/scheduled-scans/scheduled-scans.js +++ b/ui/imports/api/scheduled-scans/scheduled-scans.js @@ -54,7 +54,6 @@ let schema = new SimpleSchema({ }, scheduled_timestamp: { type: Date, - defaultValue: null, optional: true, } }); @@ -81,3 +80,5 @@ export const subsScheduledScansPageAmountSorted = 'scheduled_scans?page&amount&s export const subsScheduledScansPageAmountSortedCounter = `${subsScheduledScansPageAmountSorted}!counter`; export const subsScheduledScansId = 'scheduled_scans?_id'; + +export const subsScheduledScansEnv = 'scheduled_scans?env'; diff --git a/ui/imports/api/scheduled-scans/server/publications.js b/ui/imports/api/scheduled-scans/server/publications.js index 9359c20..f4c5b9b 100644 --- a/ui/imports/api/scheduled-scans/server/publications.js +++ b/ui/imports/api/scheduled-scans/server/publications.js @@ -2,10 +2,12 @@ import { Meteor } from 'meteor/meteor'; import * as R from 'ramda'; import { Counts } from 'meteor/tmeasday:publish-counts'; -import { ScheduledScans, +import { + ScheduledScans, subsScheduledScansPageAmountSorted, subsScheduledScansPageAmountSortedCounter, subsScheduledScansId, + subsScheduledScansEnv, } from '../scheduled-scans.js'; Meteor.publish(subsScheduledScansPageAmountSorted, function ( @@ -24,7 +26,7 @@ Meteor.publish(subsScheduledScansPageAmountSorted, function ( let sortParams = {}; sortParams = R.ifElse(R.isNil, R.always(sortParams), - R.assoc(R.__, sortDirection, sortParams))(sortField); + R.assoc(R.__, sortDirection, sortParams))(sortField); console.log('sort params:', sortParams); @@ -50,3 +52,13 @@ Meteor.publish(subsScheduledScansId, function (_id) { let query = { _id: _id }; return ScheduledScans.find(query); }); + +Meteor.publish(subsScheduledScansEnv, function (env) { + console.log(`server subscribtion: ${subsScheduledScansEnv}`); + console.log('-env: ', env); + + //let that = this; + + let query = { environment: env }; + return ScheduledScans.find(query); +}); diff --git a/ui/imports/api/supported_environments/supported_environments.js b/ui/imports/api/supported_environments/supported_environments.js index 55c5745..6637b74 100644 --- a/ui/imports/api/supported_environments/supported_environments.js +++ b/ui/imports/api/supported_environments/supported_environments.js @@ -14,14 +14,21 @@ export const SupportedEnvironments = new Mongo.Collection( export const subsNameSupportedEnvs = 'supported-environments'; -export function isMonitoringSupported(distribution, type_drivers, mechanism_drivers) { +export function isMonitoringSupported( + distribution, + distribution_version, + type_drivers, + mechanism_drivers +) { console.log('isMonitoringSupported'); console.log(`distribution: ${R.toString(distribution)}`); + console.log(`distribution_version: ${R.toString(distribution_version)}`); console.log(`type_drivers: ${R.toString(type_drivers)}`); console.log(`mechanism_drivers: ${R.toString(mechanism_drivers)}`); let result = SupportedEnvironments.find({ 'environment.distribution': distribution, + 'environment.distribution_version': { $in: [ distribution_version ] }, 'environment.type_drivers': type_drivers, 'environment.mechanism_drivers': { $in: mechanism_drivers }, 'features.monitoring': true @@ -31,14 +38,21 @@ export function isMonitoringSupported(distribution, type_drivers, mechanism_driv return result; } -export function isListeningSupported(distribution, type_drivers, mechanism_drivers) { +export function isListeningSupported( + distribution, + distribution_version, + type_drivers, + mechanism_drivers +) { console.log('isListeningSupported'); console.log(`distribution: ${R.toString(distribution)}`); + console.log(`distribution: ${R.toString(distribution)}`); console.log(`type_drivers: ${R.toString(type_drivers)}`); console.log(`mechanism_drivers: ${R.toString(mechanism_drivers)}`); let result = SupportedEnvironments.find({ 'environment.distribution': distribution, + 'environment.distribution_version': { $in: [ distribution_version ] }, 'environment.type_drivers': type_drivers, 'environment.mechanism_drivers': { $in: mechanism_drivers }, 'features.listening': true diff --git a/ui/imports/api/user-settings/methods.js b/ui/imports/api/user-settings/methods.js new file mode 100644 index 0000000..e948c1e --- /dev/null +++ b/ui/imports/api/user-settings/methods.js @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +import { ValidatedMethod } from 'meteor/mdg:validated-method'; +import { UserSettings } from '/imports/api/user-settings/user-settings'; +import * as R from 'ramda'; + +export const save = new ValidatedMethod({ + name: 'user-settings.save', + validate: UserSettings.simpleSchema() + .pick([ + 'messages_view_backward_delta' + ]).validator({ clean: true, filter: false }), + run({ + messages_view_backward_delta + }) { + + let userId = this.userId; + let userSettings = UserSettings.findOne({ user_id: userId }); + + if (userSettings) { + UserSettings.update({ _id: userSettings._id}, { $set: { + messages_view_backward_delta: messages_view_backward_delta + }}); + } else { + let item = UserSettings.schema.clean({}); + item = R.merge(item, { + user_id: userId, + messages_view_backward_delta: messages_view_backward_delta + }); + UserSettings.insert(item); + } + } +}); diff --git a/ui/imports/api/user-settings/server/publications.js b/ui/imports/api/user-settings/server/publications.js new file mode 100644 index 0000000..c53146c --- /dev/null +++ b/ui/imports/api/user-settings/server/publications.js @@ -0,0 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +import { Meteor } from 'meteor/meteor'; + +import { UserSettings } from '../user-settings.js'; + +Meteor.publish('user_settings?user', function () { + console.log('server subscribtion: user_settings?user'); + + let userId = this.userId; + + let query = { user_id: userId }; + console.log('-query: ', query); + return UserSettings.find(query); +}); diff --git a/ui/imports/api/user-settings/user-settings.js b/ui/imports/api/user-settings/user-settings.js new file mode 100644 index 0000000..2e553aa --- /dev/null +++ b/ui/imports/api/user-settings/user-settings.js @@ -0,0 +1,29 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2017 Koren Lev (Cisco Systems), Yaron Yogev (Cisco Systems) and others / +// / +// All rights reserved. This program and the accompanying materials / +// are made available under the terms of the Apache License, Version 2.0 / +// which accompanies this distribution, and is available at / +// http://www.apache.org/licenses/LICENSE-2.0 / +///////////////////////////////////////////////////////////////////////////////////////// +import { Mongo } from 'meteor/mongo'; +import { SimpleSchema } from 'meteor/aldeed:simple-schema'; +//import * as R from 'ramda'; + +export const UserSettings = new Mongo.Collection('user_settings', { idGeneration: 'MONGO' }); + +let schema = { + _id: { type: { _str: { type: String, regEx: SimpleSchema.RegEx.Id } } }, + user_id: { + type: String, + }, + messages_view_backward_delta: { + type: Number, + minCount: 1, + defaultValue: '1209600000', // 14 days + } +}; + +let simpleSchema = new SimpleSchema(schema); +UserSettings.schema = simpleSchema; +UserSettings.attachSchema(UserSettings.schema); diff --git a/ui/imports/lib/images-for-node-type.js b/ui/imports/lib/images-for-node-type.js index 19be6ac..d16ce00 100644 --- a/ui/imports/lib/images-for-node-type.js +++ b/ui/imports/lib/images-for-node-type.js @@ -11,6 +11,18 @@ export let imagesForNodeType = { warning: 'ic_dns_black_48dp_2x-orange.png', error: 'ic_dns_black_48dp_2x-red.png', }, + 'host_pnic': { + default: 'ic_device_hub_black_24dp_2x.png', + ok: 'ic_device_hub_black_24dp_2x-green.png', + warning: 'ic_device_hub_black_24dp_2x-orange.png', + error: 'ic_device_hub_black_24dp_2x-red.png', + }, + 'switch_pnic': { + default: 'ic_device_hub_black_24dp_2x.png', + ok: 'ic_device_hub_black_24dp_2x-green.png', + warning: 'ic_device_hub_black_24dp_2x-orange.png', + error: 'ic_device_hub_black_24dp_2x-red.png', + }, 'vconnector': { default: 'ic_settings_input_composite_black_48dp_2x.png', ok: 'ic_settings_input_composite_black_48dp_2x-green.png', @@ -48,6 +60,12 @@ export let imagesForNodeType = { warning: 'ic_keyboard_return_black_48dp_2x-orange.png', error: 'ic_keyboard_return_black_48dp_2x-red.png', }, + 'view_group-host': { + default: 'ic_tv_black_24dp_2x.png' + }, + 'view_group-switch': { + default: 'ic_zoom_out_map_black_24dp_2x.png' + }, }; export let defaultNodeTypeImage = { diff --git a/ui/imports/startup/client/index.js b/ui/imports/startup/client/index.js index 6ac478c..6439511 100644 --- a/ui/imports/startup/client/index.js +++ b/ui/imports/startup/client/index.js @@ -36,4 +36,4 @@ import '/imports/ui/components/messages-list/messages-list'; import '/imports/ui/components/message/message'; import '/imports/ui/components/dashboard/dashboard'; import '/imports/ui/components/new-scanning/new-scanning'; -import '/imports/ui/components/configuration/configuration'; +import '/imports/ui/components/user-settings/user-settings'; diff --git a/ui/imports/startup/client/template-helpers.js b/ui/imports/startup/client/template-helpers.js index 89023b6..23eaf50 100644 --- a/ui/imports/startup/client/template-helpers.js +++ b/ui/imports/startup/client/template-helpers.js @@ -30,3 +30,9 @@ Template.registerHelper('countOf', function (name) { return Counter.get(name); } }); + + +Template.registerHelper('jsonAsString', function (val) { + let str = JSON.stringify(val, null, 4); + return str; +}); diff --git a/ui/imports/startup/server/register-api.js b/ui/imports/startup/server/register-api.js index 71d6887..f0be6ce 100644 --- a/ui/imports/startup/server/register-api.js +++ b/ui/imports/startup/server/register-api.js @@ -54,7 +54,10 @@ import '../../api/accounts/methods'; import '../../api/supported_environments/server/publications'; import '../../api/supported_environments/methods'; -import '../../api/configurations/server/publications'; -import '../../api/configurations/methods'; +import '../../api/user-settings/server/publications'; +import '../../api/user-settings/methods'; + +import '../../api/connection-tests/server/publications'; +import '../../api/connection-tests/methods'; import '../../api/migrations/migrations'; diff --git a/ui/imports/ui/components/alarm-icons/alarm-icons.html b/ui/imports/ui/components/alarm-icons/alarm-icons.html index e59414e..b20ccac 100644 --- a/ui/imports/ui/components/alarm-icons/alarm-icons.html +++ b/ui/imports/ui/components/alarm-icons/alarm-icons.html @@ -74,7 +74,7 @@ {{/if }} diff --git a/ui/imports/ui/components/alarm-icons/alarm-icons.js b/ui/imports/ui/components/alarm-icons/alarm-icons.js index e86f8d8..e379007 100644 --- a/ui/imports/ui/components/alarm-icons/alarm-icons.js +++ b/ui/imports/ui/components/alarm-icons/alarm-icons.js @@ -15,7 +15,7 @@ import { Messages } from '/imports/api/messages/messages'; import { Roles } from 'meteor/alanning:roles'; import { ReactiveDict } from 'meteor/reactive-dict'; -import { Configurations } from '/imports/api/configurations/configurations'; +import { UserSettings } from '/imports/api/user-settings/user-settings'; import './alarm-icons.html'; @@ -32,9 +32,9 @@ Template.alarmIcons.onCreated(function () { }); instance.autorun(function () { - instance.subscribe('configurations?user'); - Configurations.find({user_id: Meteor.userId()}).forEach((conf) => { - instance.state.set('msgsViewBackDelta', conf.messages_view_backward_delta); + instance.subscribe('user_settings?user'); + UserSettings.find({user_id: Meteor.userId()}).forEach((userSettings) => { + instance.state.set('msgsViewBackDelta', userSettings.messages_view_backward_delta); }); }); diff --git a/ui/imports/ui/components/configuration/configuration.html b/ui/imports/ui/components/configuration/configuration.html deleted file mode 100644 index c8d81b2..0000000 --- a/ui/imports/ui/components/configuration/configuration.html +++ /dev/null @@ -1,35 +0,0 @@ - diff --git a/ui/imports/ui/components/configuration/configuration.js b/ui/imports/ui/components/configuration/configuration.js deleted file mode 100644 index a3582df..0000000 --- a/ui/imports/ui/components/configuration/configuration.js +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Template Component: Configuration - */ - -//import { Meteor } from 'meteor/meteor'; -import { Template } from 'meteor/templating'; -import { ReactiveDict } from 'meteor/reactive-dict'; -//import { SimpleSchema } from 'meteor/aldeed:simple-schema'; -import * as R from 'ramda'; - -import { save } from '/imports/api/configurations/methods'; -import { Configurations } from '/imports/api/configurations/configurations'; - -import './configuration.html'; - -/* - * Lifecycles - */ - -Template.Configuration.onCreated(function() { - let instance = this; - instance.state = new ReactiveDict(); - instance.state.setDefault({ - model: Configurations.schema.clean({}), - actionResult: 'none', - message: null, - }); - - /* - instance.autorun(function () { - let data = Template.currentData(); - - new SimpleSchema({ - }).validate(data); - }); - */ - - instance.autorun(function () { - instance.subscribe('configurations?user'); - Configurations.find({user_id: Meteor.userId()}).forEach((conf) => { - instance.state.set('model', conf); - }); - }); -}); - -/* -Template.Configuration.rendered = function() { -}; -*/ - -/* - * Events - */ - -Template.Configuration.events({ - 'click .js-submit-button': function (event, instance) { - event.preventDefault(); - let msgsViewBackDelta = Number.parseInt(instance.$('.sm-msgs-view-back-delta')[0].value); - saveForm(instance, msgsViewBackDelta); - }, - - 'input .sm-msgs-view-back-delta': function (_e, instance) { - let msgsViewBackDelta = Number.parseInt(instance.$('.sm-msgs-view-back-delta')[0].value); - let model = instance.state.get('model'); - model = R.assoc('messages_view_backward_delta', msgsViewBackDelta, model); - instance.state.set('model', model); - }, -}); - -/* - * Helpers - */ - -Template.Configuration.helpers({ - getModelField: function (fieldName) { - let instance = Template.instance(); - return R.path([fieldName], instance.state.get('model')); - }, - - getState: function (key) { - let instance = Template.instance(); - return instance.state.get(key); - }, - - isActionError: function () { - let instance = Template.instance(); - return instance.state.get('actionResult') === 'error'; - }, - - isActionSuccess: function () { - let instance = Template.instance(); - return instance.state.get('actionResult') === 'success'; - }, - - durationAsText: function (delta) { - let duration = moment.duration(delta); - let text = `${duration.years()} years, ${duration.months()} months, ${duration.days()} days, ${duration.hours()} hours and ${duration.minutes()} minutes from current time.`; - return text; - }, -}); // end: helpers - -function saveForm(instance, msgsViewBackDelta) { - instance.state.set('actionResult', 'none'); - instance.state.set('message', null); - - save.call({ - messages_view_backward_delta: msgsViewBackDelta - }, (error) => { - if (error) { - instance.state.set('actionResult', 'error'); - if (typeof error === 'string') { - instance.state.set('message', error); - } else { - instance.state.set('message', error.message); - } - - return; - } - - instance.state.set('actionResult', 'success'); - instance.state.set('message', 'record has been updated succesfuly'); - }); -} diff --git a/ui/imports/ui/components/configuration/configuration.styl b/ui/imports/ui/components/configuration/configuration.styl deleted file mode 100644 index b14ce7d..0000000 --- a/ui/imports/ui/components/configuration/configuration.styl +++ /dev/null @@ -1,47 +0,0 @@ -/* Set the component style here */ -// "Configuration" -.os-configuration - display: flex; - flex-flow: column nowrap; - margin: 20px; - - .cl-field-group - display: flex; - flex-flow: row nowrap; - align-items: center; - padding: 5px 0; - - .cl-field-label - width: 120px; - margin: 0 5px; - - .input-box - display: block; - width: 400px; - margin: 0 5px; - - .cl-input - display: block; - width: 100%; - min-height: 34px; - padding: 6px 12px; - font-size: 14px; - line-height: 1.42857143; - color: #555; - background-color: #fff; - background-image: none; - border: 1px solid #ccc; - border-radius: 4px; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - width: 400px; - - .input-hint - position: absolute; - margin: 5px 0; - - - .cl-field-desc - margin: 0 5px; - - .js-message-panel - margin-top: 20px; diff --git a/ui/imports/ui/components/dashboard/dashboard.js b/ui/imports/ui/components/dashboard/dashboard.js index fb42d70..625f8ee 100644 --- a/ui/imports/ui/components/dashboard/dashboard.js +++ b/ui/imports/ui/components/dashboard/dashboard.js @@ -23,7 +23,7 @@ import { Counts } from 'meteor/tmeasday:publish-counts'; //import { Messages } from '/imports/api/messages/messages'; import { store } from '/imports/ui/store/store'; import { setMainAppSelectedEnvironment } from '/imports/ui/actions/main-app.actions'; -import { Configurations } from '/imports/api/configurations/configurations'; +import { UserSettings } from '/imports/api/user-settings/user-settings'; import '/imports/ui/components/messages-info-box/messages-info-box'; import '/imports/ui/components/environment-box/environment-box'; @@ -62,9 +62,9 @@ Template.Dashboard.onCreated(function () { }); instance.autorun(function () { - instance.subscribe('configurations?user'); - Configurations.find({user_id: Meteor.userId()}).forEach((conf) => { - instance.state.set('msgsViewBackDelta', conf.messages_view_backward_delta); + instance.subscribe('user_settings?user'); + UserSettings.find({user_id: Meteor.userId()}).forEach((userSettings) => { + instance.state.set('msgsViewBackDelta', userSettings.messages_view_backward_delta); }); }); diff --git a/ui/imports/ui/components/detailed-node-info-box/detailed-node-info-box.html b/ui/imports/ui/components/detailed-node-info-box/detailed-node-info-box.html index f8c7221..27e2780 100644 --- a/ui/imports/ui/components/detailed-node-info-box/detailed-node-info-box.html +++ b/ui/imports/ui/components/detailed-node-info-box/detailed-node-info-box.html @@ -48,6 +48,11 @@
{{ node.admin_state_up }}
+ +
+
All Fields
+
{{ jsonAsString node }}
+
diff --git a/ui/imports/ui/components/detailed-node-info-box/detailed-node-info-box.styl b/ui/imports/ui/components/detailed-node-info-box/detailed-node-info-box.styl index d51b393..e49ea6e 100644 --- a/ui/imports/ui/components/detailed-node-info-box/detailed-node-info-box.styl +++ b/ui/imports/ui/components/detailed-node-info-box/detailed-node-info-box.styl @@ -9,6 +9,7 @@ flex: 1; display: flex; flex-flow: column nowrap; + overflow: auto; .sm-info-title color: #0a9ad7; @@ -31,3 +32,10 @@ color: black; font-weight: bold; + .sm-info-json + >.cl-label + color: black; + font-weight: bold; + + >.cl-data + white-space: pre; diff --git a/ui/imports/ui/components/env-aci-info/env-aci-info.html b/ui/imports/ui/components/env-aci-info/env-aci-info.html index 51b7afa..dc22ac4 100644 --- a/ui/imports/ui/components/env-aci-info/env-aci-info.html +++ b/ui/imports/ui/components/env-aci-info/env-aci-info.html @@ -71,7 +71,7 @@
-
+
diff --git a/ui/imports/ui/components/env-aci-info/env-aci-info.js b/ui/imports/ui/components/env-aci-info/env-aci-info.js index 7d93687..bfe8935 100644 --- a/ui/imports/ui/components/env-aci-info/env-aci-info.js +++ b/ui/imports/ui/components/env-aci-info/env-aci-info.js @@ -39,7 +39,11 @@ Template.EnvAciInfo.events({ 'click .sm-next-button': function () { let instance = Template.instance(); instance.data.onNextRequested(); - } + }, + + 'click .js-test-connection' : function (e, instance) { + instance.data.onTestConnection(); + }, }); /* diff --git a/ui/imports/ui/components/env-amqp-credentials-info/env-amqp-credentials-info.html b/ui/imports/ui/components/env-amqp-credentials-info/env-amqp-credentials-info.html index 02b923d..e925f9e 100644 --- a/ui/imports/ui/components/env-amqp-credentials-info/env-amqp-credentials-info.html +++ b/ui/imports/ui/components/env-amqp-credentials-info/env-amqp-credentials-info.html @@ -93,9 +93,9 @@
-
+
diff --git a/ui/imports/ui/components/env-amqp-credentials-info/env-amqp-credentials-info.js b/ui/imports/ui/components/env-amqp-credentials-info/env-amqp-credentials-info.js index 3e1522a..498a403 100644 --- a/ui/imports/ui/components/env-amqp-credentials-info/env-amqp-credentials-info.js +++ b/ui/imports/ui/components/env-amqp-credentials-info/env-amqp-credentials-info.js @@ -38,7 +38,11 @@ Template.EnvAmqpCredentialsInfo.events({ 'click .sm-next-button': function () { let instance = Template.instance(); instance.data.onNextRequested(); - } + }, + + 'click .js-test-connection' : function (e, instance) { + instance.data.onTestConnection(); + }, }); /* diff --git a/ui/imports/ui/components/env-main-info/env-main-info.html b/ui/imports/ui/components/env-main-info/env-main-info.html index b8b7d26..f5d5df7 100644 --- a/ui/imports/ui/components/env-main-info/env-main-info.html +++ b/ui/imports/ui/components/env-main-info/env-main-info.html @@ -69,6 +69,26 @@
+
+ + +
+ {{> SelectModel(createSelectArgs + values=model.distribution_version + key="distribution_version" + disabled=(isFieldDisabled 'distribution_version' disabled) + options=distributionVersionOptions + showNullOption=true) + }} +
+ +
+

Enter type of the distribution

+
+
+
diff --git a/ui/imports/ui/components/env-monitoring-info/env-monitoring-info.js b/ui/imports/ui/components/env-monitoring-info/env-monitoring-info.js index cbe5e47..9e15c45 100644 --- a/ui/imports/ui/components/env-monitoring-info/env-monitoring-info.js +++ b/ui/imports/ui/components/env-monitoring-info/env-monitoring-info.js @@ -43,6 +43,9 @@ Template.EnvMonitoringInfo.rendered = function() { */ Template.EnvMonitoringInfo.events({ + 'click .js-test-connection' : function (e, instance) { + instance.data.onTestConnection(); + }, }); /* diff --git a/ui/imports/ui/components/env-nfv-info/env-nfv-info.html b/ui/imports/ui/components/env-nfv-info/env-nfv-info.html index 9b820ba..0d92bcd 100644 --- a/ui/imports/ui/components/env-nfv-info/env-nfv-info.html +++ b/ui/imports/ui/components/env-nfv-info/env-nfv-info.html @@ -111,9 +111,9 @@
-
+
diff --git a/ui/imports/ui/components/env-nfv-info/env-nfv-info.js b/ui/imports/ui/components/env-nfv-info/env-nfv-info.js index 296379c..7a32ab9 100644 --- a/ui/imports/ui/components/env-nfv-info/env-nfv-info.js +++ b/ui/imports/ui/components/env-nfv-info/env-nfv-info.js @@ -39,7 +39,11 @@ Template.EnvNfvInfo.events({ 'click .sm-next-button': function () { let instance = Template.instance(); instance.data.onNextRequested(); - } + }, + + 'click .js-test-connection' : function (e, instance) { + instance.data.onTestConnection(); + }, }); /* diff --git a/ui/imports/ui/components/env-open-stack-db-credentials-info/env-open-stack-db-credentials-info.html b/ui/imports/ui/components/env-open-stack-db-credentials-info/env-open-stack-db-credentials-info.html index 13967d5..f679918 100644 --- a/ui/imports/ui/components/env-open-stack-db-credentials-info/env-open-stack-db-credentials-info.html +++ b/ui/imports/ui/components/env-open-stack-db-credentials-info/env-open-stack-db-credentials-info.html @@ -93,9 +93,9 @@
-
+
diff --git a/ui/imports/ui/components/env-open-stack-db-credentials-info/env-open-stack-db-credentials-info.js b/ui/imports/ui/components/env-open-stack-db-credentials-info/env-open-stack-db-credentials-info.js index 961e5b6..b8b80c0 100644 --- a/ui/imports/ui/components/env-open-stack-db-credentials-info/env-open-stack-db-credentials-info.js +++ b/ui/imports/ui/components/env-open-stack-db-credentials-info/env-open-stack-db-credentials-info.js @@ -38,7 +38,11 @@ Template.EnvOpenStackDbCredentialsInfo.events({ 'click .sm-next-button': function () { let instance = Template.instance(); instance.data.onNextRequested(); - } + }, + + 'click .js-test-connection' : function (e, instance) { + instance.data.onTestConnection(); + }, }); /* diff --git a/ui/imports/ui/components/env-os-api-endpoint-info/env-os-api-endpoint-info.html b/ui/imports/ui/components/env-os-api-endpoint-info/env-os-api-endpoint-info.html index 3f35b9a..26594e4 100644 --- a/ui/imports/ui/components/env-os-api-endpoint-info/env-os-api-endpoint-info.html +++ b/ui/imports/ui/components/env-os-api-endpoint-info/env-os-api-endpoint-info.html @@ -111,9 +111,9 @@
-
+
+ class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--colored js-test-connection toast js-test-connection">Test connection
diff --git a/ui/imports/ui/components/env-os-api-endpoint-info/env-os-api-endpoint-info.js b/ui/imports/ui/components/env-os-api-endpoint-info/env-os-api-endpoint-info.js index 0f503f1..0bc640b 100644 --- a/ui/imports/ui/components/env-os-api-endpoint-info/env-os-api-endpoint-info.js +++ b/ui/imports/ui/components/env-os-api-endpoint-info/env-os-api-endpoint-info.js @@ -38,7 +38,11 @@ Template.EnvOsApiEndpointInfo.events({ 'click .sm-next-button': function () { let instance = Template.instance(); instance.data.onNextRequested(); - } + }, + + 'click .js-test-connection' : function (e, instance) { + instance.data.onTestConnection(); + }, }); /* diff --git a/ui/imports/ui/components/environment-dashboard/environment-dashboard.js b/ui/imports/ui/components/environment-dashboard/environment-dashboard.js index 4fb6366..da0d631 100644 --- a/ui/imports/ui/components/environment-dashboard/environment-dashboard.js +++ b/ui/imports/ui/components/environment-dashboard/environment-dashboard.js @@ -26,7 +26,7 @@ import { calcIconForMessageLevel, lastMessageTimestamp, calcColorClassForMessage import { Counts } from 'meteor/tmeasday:publish-counts'; import { Roles } from 'meteor/alanning:roles'; //import { idToStr } from '/imports/lib/utilities'; -import { Configurations } from '/imports/api/configurations/configurations'; +import { UserSettings } from '/imports/api/user-settings/user-settings'; import { Counter } from 'meteor/natestrauser:publish-performant-counts'; import '/imports/ui/components/data-cubic/data-cubic'; @@ -167,9 +167,9 @@ Template.EnvironmentDashboard.onCreated(function() { }); instance.autorun(function () { - instance.subscribe('configurations?user'); - Configurations.find({user_id: Meteor.userId()}).forEach((conf) => { - instance.state.set('msgsViewBackDelta', conf.messages_view_backward_delta); + instance.subscribe('user_settings?user'); + UserSettings.find({user_id: Meteor.userId()}).forEach((userSettings) => { + instance.state.set('msgsViewBackDelta', userSettings.messages_view_backward_delta); }); }); diff --git a/ui/imports/ui/components/environment-wizard/environment-wizard.js b/ui/imports/ui/components/environment-wizard/environment-wizard.js index ddc97cf..bc6cc55 100644 --- a/ui/imports/ui/components/environment-wizard/environment-wizard.js +++ b/ui/imports/ui/components/environment-wizard/environment-wizard.js @@ -9,11 +9,12 @@ /* */ -import { Meteor } from 'meteor/meteor'; +//import { Meteor } from 'meteor/meteor'; import { Session } from 'meteor/session'; import { Template } from 'meteor/templating'; import { ReactiveDict } from 'meteor/reactive-dict'; import * as R from 'ramda'; +import { ConnectionTests } from '/imports/api/connection-tests/connection-tests'; import { Environments } from '/imports/api/environments/environments'; import { subsNameSupportedEnvs, @@ -39,6 +40,8 @@ import { update } from '/imports/api/environments/methods'; +import { insert as insertConnectionTests } from '/imports/api/connection-tests/methods'; + /* * Lifecycles */ @@ -54,6 +57,7 @@ Template.EnvironmentWizard.onCreated(function(){ isMessage: false, message: null, disabled: false, + connectionTestId: null }); instance.autorun(function () { @@ -77,19 +81,40 @@ Template.EnvironmentWizard.onCreated(function(){ let action = instance.state.get('action'); if (action === 'update') { Environments.find({'name': envName}) - .forEach(function (envItem) { - instance.state.set('environmentModel', R.clone(envItem)); - }); + .forEach(function (envItem) { + instance.state.set('environmentModel', R.clone(envItem)); + }); } else if (action === 'insert') { instance.state.set('environmentModel', generateNewEnv()); } }); + instance.autorun(function () { + let connectionTestId = instance.state.get('connectionTestId'); + if (R.isNil(connectionTestId)) { return; } + + instance.subscribe('connection_tests?_id', connectionTestId); + ConnectionTests.find({ _id: connectionTestId }).forEach((connTest) => { + if (connTest.status !== 'response') { + return; + } + + R.mapObjIndexed((success, groupName) => { + if (success) { + toastr.success(`${groupName} connection is OK`, { timeOut: 5000 }); + } else { + toastr.error(`${groupName} connection is DOWN`, { timeOut: 5000 }); + } + }, connTest.test_results); + }); + }); + instance.storeUnsubscribe = store.subscribe(() => { let i18n = store.getState().api.i18n; instance.state.set('i18n', i18n); }); + let i18n = store.getState().api.i18n; instance.state.set('i18n', i18n); }); @@ -135,6 +160,7 @@ Template.EnvironmentWizard.helpers({ let isMonSupportedRes = isMonitoringSupported( environmentModel.distribution, + environmentModel.distribution_version, environmentModel.type_drivers, environmentModel.mechanism_drivers ); @@ -149,6 +175,7 @@ Template.EnvironmentWizard.helpers({ let isListeningSupportedRes = isListeningSupported( environmentModel.distribution, + environmentModel.distribution_version, environmentModel.type_drivers, environmentModel.mechanism_drivers ); @@ -171,6 +198,28 @@ Template.EnvironmentWizard.helpers({ isMonitoringDisabled: isMonitoringDisabled, setModel: function (newModel) { Session.set('isDirty', true); + + if (newModel.aci_enabled) { + let monitoringGroup = getGroupInArray('Monitoring', newModel.configuration); + newModel = setConfigurationGroup('Monitoring', monitoringGroup, newModel); + } else { + newModel = removeConfigurationGroup('Monitoring', newModel); + } + + if (newModel.enable_monitoring) { + let monitoringGroup = getGroupInArray('ACI', newModel.configuration); + newModel = setConfigurationGroup('ACI', monitoringGroup, newModel); + } else { + newModel = removeConfigurationGroup('ACI', newModel); + } + + if (newModel.listen) { + let monitoringGroup = getGroupInArray('AMQP', newModel.configuration); + newModel = setConfigurationGroup('AMQP', monitoringGroup, newModel); + } else { + newModel = removeConfigurationGroup('AMQP', newModel); + } + instance.state.set('environmentModel', newModel); }, onNextRequested: activateNextTab.bind(null, 'endpoint-panel'), @@ -192,6 +241,9 @@ Template.EnvironmentWizard.helpers({ }, onNextRequested: activateNextTab.bind(null, 'db-credentials'), action: action, + onTestConnection: function () { + testConnection(instance); + }, } }, { label: 'OS DB Credentials', @@ -209,6 +261,9 @@ Template.EnvironmentWizard.helpers({ }, onNextRequested: activateNextTab.bind(null, 'master-host'), action: action, + onTestConnection: function () { + testConnection(instance); + }, } }, { label: 'Master Host Credentials', @@ -226,6 +281,9 @@ Template.EnvironmentWizard.helpers({ }, onNextRequested: activateNextTab.bind(null, 'amqp'), action: action, + onTestConnection: function () { + testConnection(instance); + }, } }, { label: 'AMQP Credentials', @@ -243,6 +301,9 @@ Template.EnvironmentWizard.helpers({ }, onNextRequested: activateNextTab.bind(null, 'aci'), action: action, + onTestConnection: function () { + testConnection(instance); + }, } }, /* { @@ -279,6 +340,9 @@ Template.EnvironmentWizard.helpers({ }, onNextRequested: activateNextTab.bind(null, 'monitoringInfo'), action: action, + onTestConnection: function () { + testConnection(instance); + }, } }, { label: 'Monitoring', @@ -296,6 +360,9 @@ Template.EnvironmentWizard.helpers({ instance.state.set('environmentModel', newModel); }, action: action, + onTestConnection: function () { + testConnection(instance); + }, } }]; }, @@ -327,14 +394,18 @@ Template.EnvironmentWizard.helpers({ */ Template.EnvironmentWizard.events({ + /* 'click .toast' : function () { toastr.success('Have fun storming the castle!', 'Open Stack server says'); }, + */ // todo: research: seems not implemented + /* 'click .fa-trash' : function () { Meteor.call('deleteRecipe', this._id); }, + */ 'click .sm-submit-button': function () { let instance = Template.instance(); @@ -391,6 +462,36 @@ function processActionResult(instance, error) { } } +function processInsertTestConnnectionResult(instance, error, itemId) { + if (error) { + instance.state.set('isError', true); + instance.state.set('isSuccess', false); + instance.state.set('isMessage', true); + + if (typeof error === 'string') { + instance.state.set('message', error); + } else { + let message = error.message; + if (error.errors) { + message = R.reduce((acc, errorItem) => { + return acc + '\n- ' + errorItem.name; + }, message, error.errors); + } + instance.state.set('message', message); + } + + return; + } + + instance.state.set('connectionTestId', itemId); + + instance.state.set('isError', false); + instance.state.set('isSuccess', true); + instance.state.set('isMessage', true); + + instance.state.set('message', 'Connection send to be tested'); +} + function getGroupInArray(groupName, array) { let group = R.find(R.propEq('name', groupName), array); return group ? group : createNewConfGroup(groupName); @@ -407,6 +508,12 @@ function setConfigurationGroup(groupName, group, model) { return newModel; } +function removeConfigurationGroup(groupName, model) { + let newConfiguration = removeGroupInArray(groupName, model.configuration); + let newModel = R.assoc('configuration', newConfiguration, model); + return newModel; +} + function doSubmit(instance) { let action = instance.state.get('action'); let environment = instance.state.get( @@ -422,6 +529,7 @@ function doSubmit(instance) { insert.call({ configuration: environment.configuration, distribution: environment.distribution, + distribution_version: environment.distribution_version, name: environment.name, type_drivers: environment.type_drivers, mechanism_drivers: environment.mechanism_drivers, @@ -450,3 +558,11 @@ function doSubmit(instance) { break; } } + +function testConnection(instance) { + let environmentModel = instance.state.get('environmentModel'); + insertConnectionTests.call({ + environment: environmentModel.name, + test_configurations: environmentModel.configuration, + }, processInsertTestConnnectionResult.bind(null, instance)); +} diff --git a/ui/imports/ui/components/environment/environment.html b/ui/imports/ui/components/environment/environment.html index 96bc48c..e12921b 100644 --- a/ui/imports/ui/components/environment/environment.html +++ b/ui/imports/ui/components/environment/environment.html @@ -24,37 +24,44 @@
- {{#if selectedNodeType }} - {{#if (getShow 'dashboard') }} -
- {{> UI.dynamic template=dashboardTemplate - data=(argsDashboard rdxSelectedNodeId) }} -
- {{/if }} - {{#if (getShow 'graph') }} - {{#if isSelectedNodeAGraph }} + {{#if isLoading }} + +
- + {{else }} -
- {{> NetworkGraphManager argsNetworkGraphManager }} + {{#if selectedNodeType }} + {{#if (getShow 'dashboard') }} +
+ {{> UI.dynamic template=dashboardTemplate + data=(argsDashboard rdxSelectedNodeId) }}
+ {{/if }} + {{#if (getShow 'graph') }} + {{#if isSelectedNodeAGraph }} - {{> GraphTooltipWindow (argsGraphTooltipWindow graphTooltipWindow) }} + - {{#if showVedgeInfoWindow }} - {{> VedgeInfoWindow (argsVedgeInfoWindow vedgeInfoWindow) }} - {{/if }} - - {{else }} +
+ {{> NetworkGraphManager argsNetworkGraphManager }} +
-
{{ rPath i18n 'components.environment.noGraphForLeafMsg' }}
+ {{> GraphTooltipWindow (argsGraphTooltipWindow graphTooltipWindow) }} + {{#if showVedgeInfoWindow }} + {{> VedgeInfoWindow (argsVedgeInfoWindow vedgeInfoWindow) }} + {{/if }} + + {{else }} + +
{{ rPath i18n 'components.environment.noGraphForLeafMsg' }}
+ + {{/if }} {{/if }} {{/if }} - {{/if }} + {{/if }}
diff --git a/ui/imports/ui/components/environment/environment.js b/ui/imports/ui/components/environment/environment.js index 1f0e723..9df6046 100644 --- a/ui/imports/ui/components/environment/environment.js +++ b/ui/imports/ui/components/environment/environment.js @@ -96,6 +96,7 @@ Template.Environment.onCreated(function () { vedgeInfoWindow: { node: null, left: 0, top: 0, show: false }, dashboardName: 'environment', collapsedSideMenu: instance.collapsedSideMenu, + isLoading: false, }); instance.currentData = new ReactiveVar(null, EJSON.equals); @@ -226,27 +227,44 @@ Template.Environment.onCreated(function () { }); - /* - (() => { - if (R.isNil(controller.params.query.selectedNodeId) && - R.isNil(selectedNodeId)) { - return; - } + /* + (() => { + if (R.isNil(controller.params.query.selectedNodeId) && + R.isNil(selectedNodeId)) { + return; + } - let srlSelectedNodeId = idToStr(selectedNodeId); - if (R.equals(controller.params.query.selectedNodeId, srlSelectedNodeId)) { - return; - } + let srlSelectedNodeId = idToStr(selectedNodeId); + if (R.equals(controller.params.query.selectedNodeId, srlSelectedNodeId)) { + return; + } - setTimeout(() => { - Router.go('environment', - { _id: controller.params._id }, - { query: { selectedNodeId: srlSelectedNodeId } }); - }, 1); + setTimeout(() => { + Router.go('environment', + { _id: controller.params._id }, + { query: { selectedNodeId: srlSelectedNodeId } }); + }, 1); + + })(); + */ - })(); - */ + let prevIdPath = null; + instance.autorun(function () { + let idPath = instance.rdxSelectedNodeIdPath.get(); + if (prevIdPath !== idPath) { + prevIdPath = idPath; + instance.state.set('isLoading', true); + } + }); + instance.autorun(function () { + let isLoading = instance.state.get('isLoading'); + if (isLoading) { + setTimeout(() => { + instance.state.set('isLoading', false); + }, 200); + } + }); }); Template.Environment.onDestroyed(function () { @@ -294,6 +312,11 @@ Template.Environment.helpers({ return instance.state.get(key); }, + isLoading: function () { + let instance = Template.instance(); + return instance.state.get('isLoading'); + }, + argsNavMenu: function (envName, mainNode) { let instance = Template.instance(); return { diff --git a/ui/imports/ui/components/general-folder-node-dashboard/general-folder-node-dashboard.js b/ui/imports/ui/components/general-folder-node-dashboard/general-folder-node-dashboard.js index f383877..5a3b309 100644 --- a/ui/imports/ui/components/general-folder-node-dashboard/general-folder-node-dashboard.js +++ b/ui/imports/ui/components/general-folder-node-dashboard/general-folder-node-dashboard.js @@ -82,7 +82,7 @@ Template.GeneralFolderNodeDashboard.helpers({ argsMainCubic: function (childrenCount) { return { header: R.path(['components', 'generalFolderNodeDashboard', 'mainCubic', 'header'] - )(store.getState().api.i18n), + )(store.getState().api.i18n), dataInfo: R.toString(childrenCount), icon: new Icon({ type: 'fa', name: 'desktop' }), }; diff --git a/ui/imports/ui/components/graph-tooltip-window/graph-tooltip-window.js b/ui/imports/ui/components/graph-tooltip-window/graph-tooltip-window.js index dbeb55c..371a983 100644 --- a/ui/imports/ui/components/graph-tooltip-window/graph-tooltip-window.js +++ b/ui/imports/ui/components/graph-tooltip-window/graph-tooltip-window.js @@ -25,6 +25,9 @@ import './graph-tooltip-window.html'; Template.GraphTooltipWindow.onCreated(function() { let instance = this; + instance.simpleState = { + gotIn: false, + }; instance.autorun(() => { new SimpleSchema({ @@ -47,14 +50,19 @@ Template.GraphTooltipWindow.rendered = function() { */ Template.GraphTooltipWindow.events({ - 'mouseout .os-graph-tooltip-window': function(_e, _instance) { - /* + 'mouseenter .os-graph-tooltip-window': function(e, instance) { + instance.simpleState.gotIn = true; + }, + + 'mouseleave .os-graph-tooltip-window': function(e, instance) { if (!instance.data.show) { return; } - e.preventDefault(); - e.stopPropagation(); - store.dispatch(closeGraphTooltipWindow()); - */ + //e.preventDefault(); + //e.stopPropagation(); + if (instance.simpleState.gotIn) { + instance.simpleState.gotIn = false; + store.dispatch(closeGraphTooltipWindow()); + } }, 'click .os-graph-tooltip-window': function(e, instance) { diff --git a/ui/imports/ui/components/index.styl b/ui/imports/ui/components/index.styl index 877d68b..11485fd 100644 --- a/ui/imports/ui/components/index.styl +++ b/ui/imports/ui/components/index.styl @@ -56,4 +56,4 @@ @import 'network-graph-manager/*'; @import 'network-graph/*'; @import 'environment-box/*'; -@import 'configuration/*'; +@import 'user-settings/*'; diff --git a/ui/imports/ui/components/message/message.html b/ui/imports/ui/components/message/message.html index d720be1..3508372 100644 --- a/ui/imports/ui/components/message/message.html +++ b/ui/imports/ui/components/message/message.html @@ -70,7 +70,7 @@ {{ getAttrDisabled }} class="sm-input-message cl-input" rows="10" - >{{ asString (getModelField 'message') }} + >{{ jsonAsString (getModelField 'message') }}
Message
diff --git a/ui/imports/ui/components/message/message.js b/ui/imports/ui/components/message/message.js index 41ea53d..10ff830 100644 --- a/ui/imports/ui/components/message/message.js +++ b/ui/imports/ui/components/message/message.js @@ -151,7 +151,7 @@ Template.Message.helpers({ sourceSystemsList: function () { return R.ifElse(R.isNil, R.always([]), R.prop('data') - )(Constants.findOne({ name: 'message_source_systems' })); + )(Constants.findOne({ name: 'message_source_systems' })); }, getAttrDisabled: function () { @@ -204,11 +204,6 @@ Template.Message.helpers({ return calcActionLabel(action); }, - asString: function (val) { - let str = JSON.stringify(val, null, 4); - return str; - }, - argsInvPropDisplay: function (env, nodeId) { return { env: env, diff --git a/ui/imports/ui/components/network-graph-manager/network-graph-manager.js b/ui/imports/ui/components/network-graph-manager/network-graph-manager.js index ed556c0..5cd4f35 100644 --- a/ui/imports/ui/components/network-graph-manager/network-graph-manager.js +++ b/ui/imports/ui/components/network-graph-manager/network-graph-manager.js @@ -14,6 +14,7 @@ import { store } from '/imports/ui/store/store'; import { activateGraphTooltipWindow } from '/imports/ui/actions/graph-tooltip-window.actions'; import { closeGraphTooltipWindow } from '/imports/ui/actions/graph-tooltip-window.actions'; //import { activateVedgeInfoWindow } from '/imports/ui/actions/vedge-info-window.actions'; +import { EJSON } from 'meteor/ejson'; import '/imports/ui/components/network-graph/network-graph'; @@ -31,7 +32,14 @@ Template.NetworkGraphManager.onCreated(function() { id_path: null, graphDataChanged: null, isReady: false, + inventoriesToFind: [], + cliquesToFind: [], + linksToFind: [], + nodesToFind: [], + graphLinks: [], + graphNodes: [], }); + instance.simpleState = { graphData: { links: [], @@ -55,10 +63,116 @@ Template.NetworkGraphManager.onCreated(function() { let id_path = instance.state.get('id_path'); instance.simpleState.graphData = generateGraphData(); + instance.state.set('graphDataChanged', null); instance.state.set('isReady', false); + instance.state.set('inventoriesToFind', []); + instance.state.set('cliquesToFind', []); + instance.state.set('linksToFind', []); + instance.state.set('nodesToFind', []); + instance.state.set('graphLinks', []); + instance.state.set('graphNodes', []); + + //instance.subscribe('attributes_for_hover_on_data'); + //subscribeToNodeAndRelatedData(id_path, instance, instance.simpleState); + instance.state.set('inventoriesToFind', [id_path]); + }); + + instance.autorun(function () { + let inventories = instance.state.get('inventoriesToFind'); + if (inventories.length <= 0) { + return; + } + + instance.subscribe('inventory?id_path', inventories[0]); + + // id_path: assumption - unique + Inventory.find({ id_path: inventories[0] }).forEach((inventory) => { + if (! inventory.clique) { + return; + } + + instance.state.set('cliquesToFind', [inventory._id]); + }); + }); + + instance.autorun(function () { + let cliques = instance.state.get('cliquesToFind'); + if (cliques.length <= 0) { + return; + } - instance.subscribe('attributes_for_hover_on_data'); - subscribeToNodeAndRelatedData(id_path, instance, instance.simpleState); + // focal point: assumption - unique per inventory node. + let mainNodeIdStr = cliques[0]._str; + instance.subscribe('cliques?focal_point', mainNodeIdStr); + + Cliques.find({ focal_point: new Mongo.ObjectID(mainNodeIdStr) }).forEach( function (cliqueItem) { + instance.state.set('linksToFind', cliqueItem.links); + }); + }); + + instance.autorun(function () { + let linksToFind = instance.state.get('linksToFind'); + if (linksToFind.length <= 0) { + return; + } + + // Find links for focal point. + instance.subscribe('links?_id-in', linksToFind); + + Links.find({ _id: {$in: linksToFind} }).forEach(function(link) { + let graphLinks = EJSON.parse(instance.state.keys['graphLinks']); + graphLinks = R.concat([link], graphLinks); + instance.state.set('graphLinks', graphLinks); + }); + }); + + instance.autorun(function () { + let graphLinks = instance.state.get('graphLinks'); + if (graphLinks.length <= 0) { + return; + } + + instance.simpleState.graphData = addLinksToGraph(graphLinks, instance.simpleState.graphData); + instance.state.set('graphDataChanged', Date.now()); + + // Find nodes for link + // todo: remove dubplicates. + let nodesIds = R.chain(link => { + return [ link['source'], link['target'] ]; + }, graphLinks); + + let nodesToFind = EJSON.parse(instance.state.keys['nodesToFind']); + nodesToFind = R.concat(nodesIds, nodesToFind); + instance.state.set('nodesToFind', nodesToFind); + }); + + instance.autorun(function () { + let nodesToFind = instance.state.get('nodesToFind'); + if (nodesToFind.length <= 0) { + return; + } + + instance.subscribe('inventory?_id-in', nodesToFind); + + Inventory.find({ _id: { $in: nodesToFind } }).forEach(function (node) { + let graphNodes = EJSON.parse(instance.state.keys['graphNodes']); + graphNodes = R.concat([node], graphNodes); + instance.state.set('graphNodes', graphNodes); + }); + + }); + + instance.autorun(function () { + let graphNodes = instance.state.get('graphNodes'); + if (graphNodes.length <= 0) { + return; + } + + instance.simpleState.graphData = addNodesToGraph(graphNodes, instance.simpleState.graphData); + + let isReady = calcIsReady(instance.simpleState.graphData); + instance.state.set('graphDataChanged', Date.now()); + instance.state.set('isReady', isReady); }); }); @@ -111,7 +225,7 @@ Template.NetworkGraphManager.helpers({ } store.dispatch( - activateGraphTooltipWindow(res.nodeName, res.attributes, x - 30, y - 10)); + activateGraphTooltipWindow(res.nodeName, res.attributes, x + 30, y - 10)); }); }, onNodeOut: function (_nodeId) { @@ -127,8 +241,8 @@ Template.NetworkGraphManager.helpers({ isDragging = false; }, onGroupOver: function () { - instance.simpleState.itemOfInterest = null; - store.dispatch(closeGraphTooltipWindow()); + //instance.simpleState.itemOfInterest = null; + //store.dispatch(closeGraphTooltipWindow()); }, onLinkOver: function (linkId, x, y) { if (isDragging) { @@ -162,46 +276,6 @@ Template.NetworkGraphManager.helpers({ } }); // end: helpers -function subscribeToNodeAndRelatedData(id_path, instance, simpleState) { - instance.subscribe('inventory?id_path', id_path); - - // id_path: assumption - unique - Inventory.find({ id_path: id_path }).forEach((inventory) => { - if (! inventory.clique) { - return; - } - - // focal point: assumption - unique per inventory node. - let mainNodeIdStr = inventory._id._str; - instance.subscribe('cliques?focal_point', mainNodeIdStr); - - Cliques.find({ focal_point: new Mongo.ObjectID(mainNodeIdStr) }).forEach( function (cliqueItem) { - - // Find links for focal point. - instance.subscribe('links?_id-in', cliqueItem.links); - - Links.find({ _id: {$in: cliqueItem.links} }).forEach(function(link) { - simpleState.graphData = addLinkToGraph(link, simpleState.graphData); - instance.state.set('graphDataChanged', Date.now()); - - // Find nodes for link - let nodesIds = [ link['source'], link['target'] ]; - instance.subscribe('inventory?_id-in', nodesIds); - - Inventory.find({ _id: { $in: nodesIds } }).forEach(function (node) { - simpleState.graphData = addNodeToGraph(node, simpleState.graphData); - let isReady = calcIsReady(simpleState.graphData); - instance.state.set('graphDataChanged', Date.now()); - instance.state.set('isReady', isReady); - - // Find nodes attributes for links nodes. - instance.subscribe('attributes_for_hover_on_data?type', node.type); - }); - }); - }); - }); -} - function generateGraphData() { return { nodes: [], @@ -210,7 +284,7 @@ function generateGraphData() { }; } -function addLinkToGraph(link, graphData) { +function genGraphLink(link) { let newLink = { sourceId: link.source, targetId: link.target, @@ -222,6 +296,24 @@ function addLinkToGraph(link, graphData) { } }; + return newLink; +} + +function addLinksToGraph(linksInfo, graphData) { + let newLinks = R.map(link => genGraphLink(link), linksInfo); + + let links = R.unionWith(R.eqBy(R.prop('_osid')), graphData.links, newLinks); + links = expandLinks(links, graphData.nodes); + + return R.merge(graphData, { + links: links + }); +} + +/* +function addLinkToGraph(link, graphData) { + let newLink = genGraphLink(link); + let links = R.unionWith(R.eqBy(R.prop('_osid')), graphData.links, [newLink]); links = expandLinks(links, graphData.nodes); @@ -229,6 +321,7 @@ function addLinkToGraph(link, graphData) { links: links }); } +*/ function expandLinks(links, nodes) { return R.map((link) => { @@ -248,7 +341,7 @@ function expandLinks(links, nodes) { }, links); } -function addNodeToGraph(node, graphData) { +function genGraphNode(node) { let newNode = { _osid: node._id, _osmeta: { @@ -268,8 +361,30 @@ function addNodeToGraph(node, graphData) { })(groupMarkers); if (groupKey) { newNode = R.assocPath(['_osmeta', 'groupId'], node[groupKey], newNode); + newNode = R.assocPath(['_osmeta', 'groupType'], groupKey, newNode); } + return newNode; +} + +function addNodesToGraph(nodesInfo, graphData) { + let newNodes = R.map((node) => genGraphNode(node), nodesInfo); + + let nodes = R.unionWith(R.eqBy(R.prop('_osid')), graphData.nodes, newNodes); + let links = expandLinks(graphData.links, nodes); + let groups = calcGroups(nodes); + + return R.merge(graphData, { + nodes: nodes, + links: links, + groups: groups, + }); +} + +/* +function addNodeToGraph(node, graphData) { + let newNode = genGraphNode(node); + let nodes = R.unionWith(R.eqBy(R.prop('_osid')), graphData.nodes, [newNode]); let links = expandLinks(graphData.links, nodes); let groups = calcGroups(nodes); @@ -280,6 +395,7 @@ function addNodeToGraph(node, graphData) { groups: groups, }); } +*/ function calcIsReady(graphData) { return R.all((link) => { @@ -302,6 +418,7 @@ function calcGroups(nodes) { leaves: [node], isExpanded: true, name: groupId, + type: node._osmeta.groupType, }; accGroups = R.append(group, accGroups); diff --git a/ui/imports/ui/components/network-graph/network-graph.js b/ui/imports/ui/components/network-graph/network-graph.js index 68b3a57..04b69e3 100644 --- a/ui/imports/ui/components/network-graph/network-graph.js +++ b/ui/imports/ui/components/network-graph/network-graph.js @@ -27,6 +27,7 @@ Template.NetworkGraph.onCreated(function() { instance.simpleState = { graphData: null }; + instance.prevForce = null; instance.autorun(function () { let data = Template.currentData(); @@ -73,11 +74,27 @@ Template.NetworkGraph.rendered = function() { instance.onDragStart, instance.onDragEnd, instance.onGroupOver, - instance.onLinkOver + instance.onLinkOver, + function onNewForce(newForce) { + if (instance.prevForce) { + instance.prevForce.stop(); + } + instance.prevForce = newForce; + } ); }); }; +Template.NetworkGraph.onDestroyed(function () { + let instance = Template.instance(); + let graphEl = instance.$('.sm-graph')[0]; + let svg = d3.select(graphEl).select('svg'); + if (instance.prevForce) { + instance.prevForce.stop(); + } + + svg.remove(); +}); /* * Events */ @@ -138,10 +155,13 @@ function renderGraph( onDragStart, onDragEnd, onGroupOver, - onLinkOver + onLinkOver, + onNewForce ) { let force = genForceCola(cola, d3, w, h); + onNewForce(force); + let drag = force.drag() .on('start', function (_d) { onDragStart(); @@ -295,7 +315,8 @@ function genSvgNodes(g, nodes, drag, onNodeOver, onNodeOut, onNodeClick, onGroup onNodeOut(d._osmeta.nodeId); }) .on('click', function (d) { - if (R.path(['_osmeta', 'type'], d) === 'view_group') { + let type = R.defaultTo('', R.path(['_osmeta', 'type'], d)); + if (R.contains(type, ['view_group-host', 'view_group-switch'])) { onGroupNodeClick(d._osmeta.nodeId); } onNodeClick(d._osmeta.nodeId); @@ -624,7 +645,7 @@ function calcClosedGroupsNodes(rejectedGroups, prevViewNodes) { return R.append({ _osid: nodeId, _osmeta: { - type: 'view_group', + type: `view_group-${group.type}`, nodeId: group._osid, }, width: 60, diff --git a/ui/imports/ui/components/new-scanning/new-scanning.js b/ui/imports/ui/components/new-scanning/new-scanning.js index 891d2b3..27b72c2 100644 --- a/ui/imports/ui/components/new-scanning/new-scanning.js +++ b/ui/imports/ui/components/new-scanning/new-scanning.js @@ -2,10 +2,11 @@ * Template Component: NewScanning */ -//import { Meteor } from 'meteor/meteor'; +import * as R from 'ramda'; import { Template } from 'meteor/templating'; import { SimpleSchema } from 'meteor/aldeed:simple-schema'; import { ReactiveDict } from 'meteor/reactive-dict'; +import { ScheduledScans, subsScheduledScansEnv } from '/imports/api/scheduled-scans/scheduled-scans'; import './new-scanning.html'; @@ -18,15 +19,24 @@ Template.NewScanning.onCreated(function() { instance.state = new ReactiveDict(); instance.state.setDefault({ env: null, + scheduledScanId: null }); - instance.autorun(function (env) { + instance.autorun(function () { let data = Template.currentData(); new SimpleSchema({ env: { type: String, optional: true }, }).validate(data); - instance.state.set('env', env); + instance.state.set('env', data.env); + }); + + instance.autorun(function () { + let env = instance.state.get('env'); + instance.subscribe(subsScheduledScansEnv, env); + ScheduledScans.find({ environment: env }).forEach((schedule) => { + instance.state.set('scheduledScanId', schedule._id); + }); }); }); @@ -55,9 +65,14 @@ Template.NewScanning.helpers({ }, argsScheduledScan: function (env) { + let instance = Template.instance(); + let scheduledScanId = instance.state.get('scheduledScanId'); + let action = R.ifElse(R.isNil, R.always('insert'), R.always('update'))(scheduledScanId); + return { - action: 'insert', + action: action, env: env, + _id: scheduledScanId, }; }, }); // end: helpers diff --git a/ui/imports/ui/components/scanning-request/scanning-request.js b/ui/imports/ui/components/scanning-request/scanning-request.js index 6e6d3e4..44b2f79 100644 --- a/ui/imports/ui/components/scanning-request/scanning-request.js +++ b/ui/imports/ui/components/scanning-request/scanning-request.js @@ -283,7 +283,7 @@ function submitItem(instance) { }, processActionResult.bind(null, instance)); break; default: - // todo + // todo break; } } diff --git a/ui/imports/ui/components/scheduled-scan/scheduled-scan.js b/ui/imports/ui/components/scheduled-scan/scheduled-scan.js index 56622dc..3970db0 100644 --- a/ui/imports/ui/components/scheduled-scan/scheduled-scan.js +++ b/ui/imports/ui/components/scheduled-scan/scheduled-scan.js @@ -466,7 +466,7 @@ function submitItem( break; default: - // todo + // todo break; } } diff --git a/ui/imports/ui/components/scheduled-scans-list/scheduled-scans-list.html b/ui/imports/ui/components/scheduled-scans-list/scheduled-scans-list.html index 2f986f5..a796562 100644 --- a/ui/imports/ui/components/scheduled-scans-list/scheduled-scans-list.html +++ b/ui/imports/ui/components/scheduled-scans-list/scheduled-scans-list.html @@ -44,7 +44,7 @@ {{ scan.environment }} {{ scan.inventory }} {{ scan.object_id }} - {{ scan.frequency }} + {{ scan.freq }} {{ scan.submit_timestamp }} + + diff --git a/ui/imports/ui/components/user-settings/user-settings.js b/ui/imports/ui/components/user-settings/user-settings.js new file mode 100644 index 0000000..953a6fb --- /dev/null +++ b/ui/imports/ui/components/user-settings/user-settings.js @@ -0,0 +1,123 @@ +/* + * Template Component: UserSettings + */ + +//import { Meteor } from 'meteor/meteor'; +import { Template } from 'meteor/templating'; +import { ReactiveDict } from 'meteor/reactive-dict'; +//import { SimpleSchema } from 'meteor/aldeed:simple-schema'; +import * as R from 'ramda'; + +import { save } from '/imports/api/user-settings/methods'; +import { UserSettings } from '/imports/api/user-settings/user-settings'; + +import './user-settings.html'; + +/* + * Lifecycles + */ + +Template.UserSettings.onCreated(function() { + let instance = this; + instance.state = new ReactiveDict(); + instance.state.setDefault({ + model: UserSettings.schema.clean({}), + actionResult: 'none', + message: null, + }); + + /* + instance.autorun(function () { + let data = Template.currentData(); + + new SimpleSchema({ + }).validate(data); + }); + */ + + instance.autorun(function () { + instance.subscribe('user_settings?user'); + UserSettings.find({user_id: Meteor.userId()}).forEach((userSettings) => { + instance.state.set('model', userSettings); + }); + }); +}); + +/* +Template.UserSettings.rendered = function() { +}; +*/ + +/* + * Events + */ + +Template.UserSettings.events({ + 'click .js-submit-button': function (event, instance) { + event.preventDefault(); + let msgsViewBackDelta = Number.parseInt(instance.$('.sm-msgs-view-back-delta')[0].value); + saveForm(instance, msgsViewBackDelta); + }, + + 'input .sm-msgs-view-back-delta': function (_e, instance) { + let msgsViewBackDelta = Number.parseInt(instance.$('.sm-msgs-view-back-delta')[0].value); + let model = instance.state.get('model'); + model = R.assoc('messages_view_backward_delta', msgsViewBackDelta, model); + instance.state.set('model', model); + }, +}); + +/* + * Helpers + */ + +Template.UserSettings.helpers({ + getModelField: function (fieldName) { + let instance = Template.instance(); + return R.path([fieldName], instance.state.get('model')); + }, + + getState: function (key) { + let instance = Template.instance(); + return instance.state.get(key); + }, + + isActionError: function () { + let instance = Template.instance(); + return instance.state.get('actionResult') === 'error'; + }, + + isActionSuccess: function () { + let instance = Template.instance(); + return instance.state.get('actionResult') === 'success'; + }, + + durationAsText: function (delta) { + let duration = moment.duration(delta); + let text = `${duration.years()} years, ${duration.months()} months, ${duration.days()} days, ${duration.hours()} hours and ${duration.minutes()} minutes from current time.`; + return text; + }, +}); // end: helpers + +function saveForm(instance, msgsViewBackDelta) { + instance.state.set('actionResult', 'none'); + instance.state.set('message', null); + + save.call({ + messages_view_backward_delta: msgsViewBackDelta + }, (error) => { + if (error) { + instance.state.set('actionResult', 'error'); + if (typeof error === 'string') { + instance.state.set('message', error); + } else { + instance.state.set('message', error.message); + } + + return; + } + + instance.state.set('actionResult', 'success'); + instance.state.set('message', 'record has been updated succesfuly'); + }); +} diff --git a/ui/imports/ui/components/user-settings/user-settings.styl b/ui/imports/ui/components/user-settings/user-settings.styl new file mode 100644 index 0000000..edf5e5c --- /dev/null +++ b/ui/imports/ui/components/user-settings/user-settings.styl @@ -0,0 +1,45 @@ +.os-user-settings + display: flex; + flex-flow: column nowrap; + margin: 20px; + + .cl-field-group + display: flex; + flex-flow: row nowrap; + align-items: center; + padding: 5px 0; + + .cl-field-label + width: 120px; + margin: 0 5px; + + .input-box + display: block; + width: 400px; + margin: 0 5px; + + .cl-input + display: block; + width: 100%; + min-height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + width: 400px; + + .input-hint + position: absolute; + margin: 5px 0; + + + .cl-field-desc + margin: 0 5px; + + .js-message-panel + margin-top: 20px; -- cgit 1.2.3-korg