aboutsummaryrefslogtreecommitdiffstats
path: root/ui/imports/ui/components/messages-list
diff options
context:
space:
mode:
Diffstat (limited to 'ui/imports/ui/components/messages-list')
-rw-r--r--ui/imports/ui/components/messages-list/messages-list.html103
-rw-r--r--ui/imports/ui/components/messages-list/messages-list.js291
-rw-r--r--ui/imports/ui/components/messages-list/messages-list.styl37
3 files changed, 431 insertions, 0 deletions
diff --git a/ui/imports/ui/components/messages-list/messages-list.html b/ui/imports/ui/components/messages-list/messages-list.html
new file mode 100644
index 0000000..646b2e9
--- /dev/null
+++ b/ui/imports/ui/components/messages-list/messages-list.html
@@ -0,0 +1,103 @@
+<!--
+########################################################################################
+# 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 #
+########################################################################################
+ -->
+<template name="MessagesList">
+<div class="os-messages-list cards white">
+ <div class="sm-table-section">
+ <h3>Messages</h3>
+ <table class="sm-messages-table table">
+ <thead>
+ <tr>
+ <th><a class="sm-table-header"
+ data-is-sortable="true"
+ data-sort-field="environment"
+ >Environment<span><i class="{{ fieldSortClass 'environment' }}"></i></span></a></th>
+ <th><a class="sm-table-header"
+ data-is-sortable="true"
+ data-sort-field="viewed"
+ >Viewed<span><i class="{{ fieldSortClass 'viewed' }}"></i></span></a></th>
+ <th><a class="sm-table-header">Display Context</a></th>
+ <th><a class="sm-table-header">Message</a></th>
+ <th><a class="sm-table-header"
+ data-is-sortable="true"
+ data-sort-field="source_system"
+ >Source System<span><i class="{{ fieldSortClass 'source_system' }}"></i></span></a></th>
+ <th><a class="sm-table-header"
+ data-is-sortable="true"
+ data-sort-field="level"
+ >Level<span><i class="{{ fieldSortClass 'level' }}"></i></span></a></th>
+ <th><a class="sm-table-header"
+ data-is-sortable="true"
+ data-sort-field="timestamp"
+ >Timestamp<span><i class="{{ fieldSortClass 'timestamp' }}"></i></span></a></th>
+ <th><a class="sm-table-header"
+ data-is-sortable="true"
+ data-sort-field="related_object_type"
+ >Related Object Type<span><i class="{{ fieldSortClass 'related_object_type' }}"></i></span></a></th>
+ <th><a class="sm-table-header">Related Object</a></th>
+ <th><a class="sm-table-header"
+ data-is-sortable="true"
+ data-sort-field="scan_id"
+ >Scan ID<span><i class="{{ fieldSortClass 'scan_id' }}"></i></span></a></th>
+ <th><a class="sm-table-header">Actions</a></th>
+ </tr> </thead>
+ <tbody>
+ {{#each message in messages }}
+ <tr>
+ <td>{{ message.environment }}</td>
+ <td>{{ message.viewed }}</td>
+ <td>
+ <a class="cl-link sm-display-context-link"
+ data-env-name="{{ message.environment }}"
+ data-item-id="{{ message.display_context }}">Link to node</a>
+ </td>
+ <td>{{ message.message }}</td>
+ <td>{{ message.source_system }}</td>
+ <td>{{ message.level }}</td>
+ <td>{{ message.timestamp }}</td>
+ <td>{{ message.related_object_type }}</td>
+ <td>
+ {{#if message.related_object }}
+ {{> InventoryPropertiesDisplay (argsInvPropDisplay message.environment message.related_object) }}
+ {{/if }}
+ </td>
+ <td>
+ <a class="cl-link sm-scan-id-link"
+ data-scan-id="{{ toIsoFormatStr message.scan_id }}"
+ >{{ message.scan_id }}
+ </a>
+ </td>
+ <td>
+ <div class="sm-action-bar">
+ <a href="{{pathFor route='message'
+ query=(asHash id=(idToStr message._id) action='view') }}"
+ ><i class="cl-action-icon fa fa-eye" area-hidden="true"></i></a>
+
+ <!--a href="{{pathFor route='message'
+ query=(asHash id=(idToStr message._id) action='update') }}"
+ ><i class="cl-action-icon fa fa-pencil" area-hidden="true"></i></a-->
+
+ <!--a href="{{pathFor route='message'
+ query=(asHash id=(idToStr message._id) action='remove') }}"
+ ><i class="cl-action-icon fa fa-trash-o" area-hidden="true"></i></a-->
+ </div>
+ </td>
+ </tr>
+ {{/each }}
+ </tbody>
+ </table>
+ </div>
+
+ <div class="sm-pager-section">
+ {{> Pager (argsPager currentPage amountPerPage totalMessages) }}
+ </div>
+
+</div>
+</template>
diff --git a/ui/imports/ui/components/messages-list/messages-list.js b/ui/imports/ui/components/messages-list/messages-list.js
new file mode 100644
index 0000000..d0f2730
--- /dev/null
+++ b/ui/imports/ui/components/messages-list/messages-list.js
@@ -0,0 +1,291 @@
+/////////////////////////////////////////////////////////////////////////////////////////
+// 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 /
+/////////////////////////////////////////////////////////////////////////////////////////
+/*
+ * Template Component: MessagesList
+ */
+
+//import { Meteor } from 'meteor/meteor';
+import * as R from 'ramda';
+import { Template } from 'meteor/templating';
+import { Counter } from 'meteor/natestrauser:publish-performant-counts';
+import { ReactiveDict } from 'meteor/reactive-dict';
+import { SimpleSchema } from 'meteor/aldeed:simple-schema';
+//import { Messages } from '/imports/api/messages/messages';
+import { Environments } from '/imports/api/environments/environments';
+import { idToStr } from '/imports/lib/utilities';
+
+import '/imports/ui/components/pager/pager';
+import '/imports/ui/components/inventory-properties-display/inventory-properties-display';
+
+import './messages-list.html';
+
+/*
+ * Lifecycles
+ */
+
+Template.MessagesList.onCreated(function() {
+ var instance = this;
+
+ instance.state = new ReactiveDict();
+ instance.state.setDefault({
+ env: null,
+ page: 1,
+ amountPerPage: 10,
+ sortField: null,
+ sortDirection: null,
+ messsages: [],
+ });
+
+ instance.autorun(function () {
+ //let data = Template.currentData();
+
+ var controller = Iron.controller();
+ var params = controller.getParams();
+ var query = params.query;
+
+ new SimpleSchema({
+ }).validate(query);
+
+ instance.subscribe('environments_config');
+ instance.subscribe('messages/count');
+ });
+
+ instance.autorun(function () {
+ let amountPerPage = instance.state.get('amountPerPage');
+ let page = instance.state.get('page');
+ let sortField = instance.state.get('sortField');
+ let sortDirection = instance.state.get('sortDirection');
+
+ Meteor.apply('messages/get?level&env&page&amountPerPage&sortField&sortDirection', [
+ null, null, page, amountPerPage, sortField, sortDirection
+ ], {
+ wait: false
+ }, function (err, res) {
+ if (err) {
+ console.error(R.toString(err));
+ return;
+ }
+
+ instance.state.set('messages', res);
+ });
+ });
+});
+
+/*
+Template.MessagesList.rendered = function() {
+};
+*/
+
+/*
+ * Events
+ */
+
+Template.MessagesList.events({
+ 'click .sm-display-context-link': function (event, _instance) {
+ event.preventDefault();
+ let envName = event.target.dataset.envName;
+ let nodeId = event.target.dataset.itemId;
+
+ let environment = Environments.findOne({ name: envName });
+
+ Meteor.apply('inventoryFindNode?env&id', [
+ environment.name,
+ nodeId,
+ ], {
+ wait: false
+ }, function (err, resp) {
+ if (err) {
+ console.error(R.toString(err));
+ return;
+ }
+
+ if (R.isNil(resp.node)) {
+ console.error('error finding node related to message', R.toString(nodeId));
+ return;
+ }
+
+ Router.go('environment', {
+ _id: idToStr(environment._id)
+ }, {
+ query: {
+ selectedNodeId: idToStr(resp.node._id)
+ }
+ });
+
+ });
+
+ },
+
+ 'click .sm-scan-id-link': function (event, _instance) {
+ event.preventDefault();
+ let scanStartTimeStamp = moment(event.target.dataset.scanId).toDate();
+
+ Meteor.apply('scansFind?start-timestamp-before', [
+ scanStartTimeStamp
+ ], {
+ wait: false
+ }, function (err, resp) {
+ if (err) {
+ console.error(R.toString(err));
+ return;
+ }
+
+ if (R.isNil(resp.scan)) {
+ console.error('error finding scan related to message', R.toString(scanStartTimeStamp));
+ return;
+ }
+
+ Router.go('scanning-request', {
+ _id: idToStr(resp.scan._id)
+ }, {
+ query: {
+ env: idToStr(resp.environment._id),
+ id: idToStr(resp.scan._id),
+ action: 'view'
+ }
+ });
+
+ });
+ },
+
+ 'click .sm-table-header': function (event, instance) {
+ event.preventDefault();
+ let isSortable = event.target.dataset.isSortable;
+ if (! isSortable ) { return; }
+
+ let sortField = event.target.dataset.sortField;
+ let currentSortField = instance.state.get('sortField');
+ let currentSortDirection = instance.state.get('sortDirection');
+
+ if (sortField === currentSortField) {
+ let sortDirection = null;
+ if (currentSortDirection === null) {
+ sortDirection = -1;
+ } else if (currentSortDirection === -1) {
+ sortDirection = 1;
+ } else if (currentSortDirection === 1) {
+ sortField = null;
+ sortDirection = null;
+ } else {
+ sortField = null;
+ sortDirection = null;
+ }
+
+ instance.state.set('sortField', sortField);
+ instance.state.set('sortDirection', sortDirection);
+
+ } else {
+ instance.state.set('sortField', sortField);
+ instance.state.set('sortDirection', -1);
+ }
+ },
+});
+
+/*
+ * Helpers
+ */
+
+Template.MessagesList.helpers({
+ messages: function () {
+ let instance = Template.instance();
+ return instance.state.get('messages');
+ },
+
+ currentPage: function () {
+ let instance = Template.instance();
+ return instance.state.get('page');
+ },
+
+ amountPerPage: function () {
+ let instance = Template.instance();
+ return instance.state.get('amountPerPage');
+ },
+
+ totalMessages: function () {
+ return Counter.get(`messages/count`);
+ },
+
+ toIsoFormatStr: function (date) {
+ if (R.isNil(date)) {
+ return '';
+ }
+
+ let str = moment(date).format();
+ return str;
+ },
+
+ argsPager: function (currentPage, amountPerPage, totalMessages) {
+ let instance = Template.instance();
+ let totalPages = Math.ceil(totalMessages / amountPerPage);
+
+ return {
+ disableNext: currentPage * amountPerPage > totalMessages,
+ disablePrev: currentPage == 1,
+ totalPages: totalPages,
+ currentPage: currentPage,
+ onReqNext: function () {
+ console.log('next');
+ let page = (currentPage * amountPerPage > totalMessages) ? currentPage : currentPage + 1;
+ instance.state.set('page', page);
+ },
+ onReqPrev: function () {
+ console.log('prev');
+ let page = (currentPage == 1) ? currentPage : currentPage - 1;
+ instance.state.set('page', page);
+ },
+ onReqFirst: function () {
+ console.log('req first');
+ instance.state.set('page', 1);
+ },
+ onReqLast: function () {
+ console.log('req last');
+ instance.state.set('page', totalPages);
+ },
+ onReqPage: function (pageNumber) {
+ console.log('req page');
+ let page;
+ if (pageNumber <= 1) {
+ page = 1;
+ } else if (pageNumber > Math.ceil(totalMessages / amountPerPage)) {
+ page = totalPages;
+ } else {
+ page = pageNumber;
+ }
+
+ instance.state.set('page', page);
+ },
+ };
+ },
+
+ fieldSortClass: function (fieldName) {
+ let instance = Template.instance();
+ let classes = 'fa fa-sort';
+ if (fieldName === instance.state.get('sortField')) {
+ let sortDirection = instance.state.get('sortDirection');
+ if (sortDirection === -1) {
+ classes = 'fa fa-sort-desc';
+ } else if (sortDirection === 1) {
+ classes = 'fa fa-sort-asc';
+ }
+ }
+
+ return classes;
+ },
+
+ argsInvPropDisplay: function (env, nodeId) {
+ return {
+ env: env,
+ nodeId: nodeId,
+ displayFn: (node) => {
+ if (R.isNil(node)) { return ''; }
+ return `${node.object_name} - ${node.type}`;
+ }
+ };
+ },
+}); // end: helpers
diff --git a/ui/imports/ui/components/messages-list/messages-list.styl b/ui/imports/ui/components/messages-list/messages-list.styl
new file mode 100644
index 0000000..adc9500
--- /dev/null
+++ b/ui/imports/ui/components/messages-list/messages-list.styl
@@ -0,0 +1,37 @@
+.os-messages-list
+ display: flex;
+ flex-flow: column nowrap;
+ margin: 20px;
+
+ .cl-action-icon,
+ .card.fa.cl-action-icon
+ font-size: 16px !important;
+
+ .sm-messages-table
+ th
+ color: spark-blue
+
+ a
+ color: spark-blue;
+ cursor: pointer;
+ i.fa
+ padding: 0px 3px;
+ font-size: small;
+
+ .sm-action-bar
+ display: flex;
+
+ a
+ color: spark-blue;
+ margin: 0px 5px;
+ cursor: pointer;
+
+ .cl-action-icon
+ color: gray
+
+ .sm-pager-section
+ display: flex;
+ justify-content: center;
+
+ .cl-link
+ cursor: pointer