diff options
Diffstat (limited to 'ui/imports/ui/components/message')
-rw-r--r-- | ui/imports/ui/components/message/message.html | 168 | ||||
-rw-r--r-- | ui/imports/ui/components/message/message.js | 257 | ||||
-rw-r--r-- | ui/imports/ui/components/message/message.styl | 41 |
3 files changed, 466 insertions, 0 deletions
diff --git a/ui/imports/ui/components/message/message.html b/ui/imports/ui/components/message/message.html new file mode 100644 index 0000000..d720be1 --- /dev/null +++ b/ui/imports/ui/components/message/message.html @@ -0,0 +1,168 @@ +<!-- +######################################################################################## +# 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="Message"> +<div class="os-message cards white"> + {{#if notificationsExists}} + <div class="sm-notification-panel alert alert-danger"> + {{#each note in notifications }} + <div>{{ note }}</div> + {{/each }} + </div> + {{/if}} + + <h3>{{ getState 'pageHeader' }}</h3> + + <div class="sm-form-container"> + <form role="form" class="sm-item-form form-horizontal"> + + <div class="sm-field-group-id cl-field-group"> + <label class="cl-field-label">Id</label> + <input name="id" + disabled="disabled" + value="{{ getModelField '_id' }}" + class="sm-input-id cl-input" type="text" placeholder="Id" /> + <div class="cl-field-id">Id</div> + </div> + + <div class="sm-field-group-env cl-field-group"> + <label class="cl-field-label">Environment</label> + <select name="env" class="sm-input-env cl-input" + {{ getAttrDisabled }} > + <option value="" selected disabled hidden></option> + {{#each env in envsList }} + <option value="{{ env.name }}" + {{ getAttrSelected env.name (getModelField 'environment') }} + >{{ env.name }}</option> + {{/each }} + </select> + <div class="cl-field-desc">Environment</div> + </div> + + <div class="sm-field-group-viewed cl-field-group"> + <label class="cl-field-label">Viewed</label> + <input name="viewed" + {{ getAttrDisabled }} + value="{{ getModelField 'viewed' }}" + class="sm-input-viewed cl-input" type="text" placeholder="" /> + <div class="cl-field-desc">Viewed</div> + </div> + + <div class="sm-field-group-display-context cl-field-group"> + <label class="cl-field-label">Display Context</label> + <input name="display_context" + {{ getAttrDisabled }} + value="{{ getModelField 'display_context' }}" + class="sm-input-viewed cl-input" type="text" placeholder="Display context" /> + <div class="cl-field-desc">Display context</div> + </div> + + <div class="sm-field-group-message cl-field-group"> + <label class="cl-field-label">Message</label> + <textarea name="message" + {{ getAttrDisabled }} + class="sm-input-message cl-input" + rows="10" + >{{ asString (getModelField 'message') }}</textarea> + <div class="cl-field-desc">Message</div> + </div> + + <div class="sm-field-group-source-system cl-field-group"> + <label class="cl-field-label">Source System</label> + <select name="source-system" class="sm-input-source-system cl-input" + {{ getAttrDisabled }} > + <option value="" selected disabled hidden></option> + {{#each sourceSystem in sourceSystemsList }} + <option value="{{ sourceSystem.value }}" + {{ getAttrSelected sourceSystem.label (getModelField 'source_system') }} + >{{ sourceSystem.label }}</option> + {{/each }} + </select> + <div class="cl-field-desc">Source system</div> + </div> + + <div class="sm-field-group-level cl-field-group"> + <label class="cl-field-label">Level</label> + <input name="level" + {{ getAttrDisabled }} + value="{{ getModelField 'level' }}" + class="sm-input-level cl-input" + type="text" + placeholder="Level" /> + <div class="cl-field-desc">Level</div> + </div> + + <div class="sm-field-group-timestamp cl-field-group"> + <label class="cl-field-label">Timestamp</label> + <input name="timestamp" + {{ getAttrDisabled }} + value="{{ getModelField 'timestamp' }}" + class="sm-input-level cl-input" + type="text" + placeholder="Timestamp" /> + <div class="cl-field-desc">Timestamp</div> + </div> + + <div class="sm-field-group-related-object-type cl-field-group"> + <label class="cl-field-label">Related Object Type</label> + <input name="related_object_type" + {{ getAttrDisabled }} + value="{{ getModelField 'related_object_type' }}" + class="sm-input-related-object-type cl-input" + type="text" + placeholder="Related object type" /> + <div class="cl-field-desc">Related object type</div> + </div> + + <div class="sm-field-group-related-object cl-field-group"> + <label class="cl-field-label">Related Object</label> + <input name="related_object" + {{ getAttrDisabled }} + value="{{ getModelField 'related_object' }}" + class="sm-input-related-object cl-input" + type="text" + placeholder="Related object" /> + {{#if (getModelField 'related_object') }} + {{> InventoryPropertiesDisplay (argsInvPropDisplay (getModelField 'environment') (getModelField 'related_object')) }}. + {{/if }} + <div class="cl-field-desc">Related object</div> + </div> + + <div class="sm-field-group-scanid cl-field-group"> + <label class="cl-field-label">Scan ID</label> + <input name="scanid" + {{ getAttrDisabled }} + value="{{ getModelField 'scan_id' }}" + class="sm-input-level cl-input" + type="text" + placeholder="Scan ID" /> + <div class="cl-field-desc">Scan ID</div> + </div> + + {{#if isUpdateableAction }} + <button type="submit" + class="js-submit-button mdl-button mdl-js-button mdl-button--raised + mdl-js-ripple-effect mdl-button--colored" + >{{ actionLabel }}</button> + {{/if }} + + </form> + + {{#if (getState 'isMessage') }} + <div class="js-message-panel alert {{#if (getState 'isError')}}alert-danger{{/if}} + {{#if (getState 'isSuccess')}}alert-success{{/if}}" + role="alert"> + {{ getState 'message' }} + </div> + {{/if }} + + </div> +</div> +</template> diff --git a/ui/imports/ui/components/message/message.js b/ui/imports/ui/components/message/message.js new file mode 100644 index 0000000..41ea53d --- /dev/null +++ b/ui/imports/ui/components/message/message.js @@ -0,0 +1,257 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// 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: Message + */ + +//import { Meteor } from 'meteor/meteor'; +import * as R from 'ramda'; +import { Template } from 'meteor/templating'; +import { ReactiveDict } from 'meteor/reactive-dict'; +import { SimpleSchema } from 'meteor/aldeed:simple-schema'; +import { Messages } from '/imports/api/messages/messages'; +import { Constants } from '/imports/api/constants/constants'; +import { Environments } from '/imports/api/environments/environments'; +import { idToStr } from '/imports/lib/utilities'; +//import { insert, update, remove } from '/imports/api/clique-types/methods'; +import { parseReqId } from '/imports/lib/utilities'; +//import { store } from '/imports/ui/store/store'; +//import { setCurrentNode } from '/imports/ui/actions/navigation'; + +import './message.html'; + +/* + * Lifecycles + */ + +Template.Message.onCreated(function() { + let instance = this; + instance.state = new ReactiveDict(); + instance.state.setDefault({ + id: null, + action: 'insert', + isError: false, + isSuccess: false, + isMessage: false, + message: null, + disabled: false, + notifications: {}, + model: {}, + pageHeader: 'Message' + }); + + instance.autorun(function () { + let data = Template.currentData(); + + new SimpleSchema({ + action: { type: String, allowedValues: ['view'] }, + id: { type: String, optional: true } + }).validate(data); + + switch (data.action) { + /* + case 'insert': + initInsertView(instance, data); + break; + */ + + case 'view': + initViewView(instance, data); + break; + + /* + case 'update': + initUpdateView(instance, data); + break; + + case 'remove': + initRemoveView(instance, data); + break; + */ + + default: + throw 'unimplemented action'; + } + }); +}); + +/* +Template.Message.rendered = function() { +}; +*/ + +/* + * Events + */ + +Template.Message.events({ + 'click .sm-field-group-display-context': function (event, instance) { + event.preventDefault(); + + let model = instance.state.get('model'); + let environment = Environments.findOne({ name: model.environment }); + let nodeId = model.display_context; + + 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) + } + }); + + }); + + }, + +}); + +/* + * Helpers + */ + +Template.Message.helpers({ + isUpdateableAction() { + let instance = Template.instance(); + let action = instance.state.get('action'); + + return R.contains(action, ['insert', 'update', 'remove']); + }, + + getState: function (key) { + let instance = Template.instance(); + return instance.state.get(key); + }, + + envsList: function () { + return Environments.find({}); + }, + + sourceSystemsList: function () { + return R.ifElse(R.isNil, R.always([]), R.prop('data') + )(Constants.findOne({ name: 'message_source_systems' })); + }, + + getAttrDisabled: function () { + let instance = Template.instance(); + let result = {}; + let action = instance.state.get('action'); + + if (R.contains(action, ['view', 'remove'])) { + result = R.assoc('disabled', true, result); + } + + return result; + }, + + getModel: function () { + let instance = Template.instance(); + return instance.state.get('model'); + }, + + getModelField: function (fieldName) { + let instance = Template.instance(); + return R.path([fieldName], instance.state.get('model')); + }, + + getAttrSelected: function (optionValue, modelValue) { + let result = {}; + + if (optionValue === modelValue) { + result = R.assoc('selected', 'selected', result); + } + + return result; + }, + + getAttrSelectedMultiple: function (optionValue, modelValues) { + let result = {}; + + if (R.isNil(modelValues)) { return result; } + + if (R.contains(optionValue, modelValues)) { + result = R.assoc('selected', 'selected', result); + } + + return result; + }, + + actionLabel: function () { + let instance = Template.instance(); + let action = instance.state.get('action'); + return calcActionLabel(action); + }, + + asString: function (val) { + let str = JSON.stringify(val, null, 4); + return str; + }, + + argsInvPropDisplay: function (env, nodeId) { + return { + env: env, + nodeId: nodeId, + displayFn: (node) => { + if (R.isNil(node)) { return ''; } + return `${node.object_name} - ${node.type}`; + } + }; + }, +}); // end - helpers + + +function initViewView(instance, data) { + let reqId = parseReqId(data.id); + + instance.state.set('action', data.action); + //instance.state.set('env', query.env); + instance.state.set('id', reqId); + + subscribeToOptionsData(instance); + instance.subscribe('messages?_id', reqId.id); + + Messages.find({ _id: reqId.id }).forEach((model) => { + instance.state.set('model', model); + }); + +} + +function subscribeToOptionsData(instance) { + instance.subscribe('environments_config'); + instance.subscribe('constants'); +} + +function calcActionLabel(action) { + switch (action) { + case 'insert': + return 'Add'; + case 'remove': + return 'Remove'; + case 'update': + return 'Update'; + default: + return 'Submit'; + } +} diff --git a/ui/imports/ui/components/message/message.styl b/ui/imports/ui/components/message/message.styl new file mode 100644 index 0000000..6003eb1 --- /dev/null +++ b/ui/imports/ui/components/message/message.styl @@ -0,0 +1,41 @@ +.os-message + 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; + + .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; + margin: 0 5px; + + .cl-field-desc + margin: 0 5px; + + input[disabled] + pointer-events: none + + .js-message-panel + margin-top: 20px; + + .sm-field-group-display-context + cursor: pointer; + |