diff options
Diffstat (limited to 'ui/imports/ui/components/clique-constraint')
3 files changed, 460 insertions, 0 deletions
diff --git a/ui/imports/ui/components/clique-constraint/clique-constraint.html b/ui/imports/ui/components/clique-constraint/clique-constraint.html new file mode 100644 index 0000000..0583872 --- /dev/null +++ b/ui/imports/ui/components/clique-constraint/clique-constraint.html @@ -0,0 +1,96 @@ +<!-- +######################################################################################## +# 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="CliqueConstraint"> + <div class="os-clique-constraint 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 }} > + {{#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-focal-point-type cl-field-group"> + <label class="cl-field-label">Focal Point Type</label> + <select name="focalPointType" class="sm-input-focal-point-type cl-input" + {{ getAttrDisabled }} > + {{#each objectType in objectTypesList }} + <option value="{{ objectType.value }}" + {{ getAttrSelected objectType.value (getModelField 'focal_point_type') }} + >{{ objectType.label }}</option> + {{/each }} + </select> + <div class="cl-field-desc">Focal Point Type</div> + </div> + + <div class="sm-field-group-constraints cl-field-group"> + <label class="cl-field-label">Constraints</label> + <select name="constraints" + class="sm-input-constraints cl-input" + multiple + size="3" + {{ getAttrDisabled }} > + {{#each objectType in objectTypesList }} + <option value="{{ constraint.value }}" + {{ getAttrSelectedMultiple objectType.value (getModelField 'constraints') }} + >{{ objectType.label }}</option> + {{/each }} + </select> + <div class="cl-field-desc">Constraints</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/clique-constraint/clique-constraint.js b/ui/imports/ui/components/clique-constraint/clique-constraint.js new file mode 100644 index 0000000..75623eb --- /dev/null +++ b/ui/imports/ui/components/clique-constraint/clique-constraint.js @@ -0,0 +1,329 @@ +///////////////////////////////////////////////////////////////////////////////////////// +// 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: CliqueConstraint + */ + +//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 { CliqueConstraints } from '/imports/api/clique-constraints/clique-constraints'; +//import { Environments } from '/imports/api/environments/environments'; +import { Constants } from '/imports/api/constants/constants'; +import { insert, remove, update } from '/imports/api/clique-constraints/methods'; +import { parseReqId } from '/imports/lib/utilities'; + +import './clique-constraint.html'; + +/* + * Lifecycles + */ + +Template.CliqueConstraint.onCreated(function() { + let instance = this; + instance.state = new ReactiveDict(); + instance.state.setDefault({ + id: null, + //env: null, + action: 'insert', + isError: false, + isSuccess: false, + isMessage: false, + message: null, + disabled: false, + notifications: {}, + model: {}, + pageHeader: 'Clique Constraint' + }); + + instance.autorun(function () { + let controller = Iron.controller(); + let params = controller.getParams(); + let query = params.query; + + new SimpleSchema({ + action: { type: String, allowedValues: ['insert', 'view', 'remove', 'update'] }, + id: { type: String, optional: true } + }).validate(query); + + switch (query.action) { + case 'insert': + initInsertView(instance, query); + break; + + case 'view': + initViewView(instance, query); + break; + + case 'update': + initUpdateView(instance, query); + break; + + case 'remove': + initRemoveView(instance, query); + break; + + default: + throw 'unimplemented action'; + } + }); +}); + +/* +Template.CliqueConstraint.rendered = function() { +}; +*/ + +/* + * Events + */ + +Template.CliqueConstraint.events({ + 'submit .sm-item-form': function(event, instance) { + event.preventDefault(); + + let _id = instance.state.get('id'); + //let env = instance.$('.sm-input-env')[0].value; + let focalPointType = instance.$('.sm-input-focal-point-type')[0].value; + let constraints = R.map(R.prop('value'), + instance.$('.sm-input-constraints')[0].selectedOptions); + + submitItem(instance, + _id, + //env, + focalPointType, + constraints + ); + } +}); + +/* + * Helpers + */ + +Template.CliqueConstraint.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); + }, + + objectTypesList: function () { + return R.ifElse(R.isNil, R.always([]), R.prop('data') + )(Constants.findOne({ name: 'object_types_for_links' })); + }, + + /* + envsList: function () { + return Environments.find({}); + }, + */ + + 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); + } +}); + + +function initInsertView(instance, query) { + instance.state.set('action', query.action); + instance.state.set('model', CliqueConstraints.schema.clean({ + })); + + subscribeToOptionsData(instance); + //instance.subscribe('link_types?env', query.env); +} + +function initViewView(instance, query) { + let reqId = parseReqId(query.id); + + instance.state.set('action', query.action); + instance.state.set('id', reqId); + + subscribeToOptionsData(instance); + + instance.subscribe('clique_constraints?_id', reqId.id); + + CliqueConstraints.find({ _id: reqId.id }).forEach((model) => { + instance.state.set('model', model); + }); +} + +function initUpdateView(instance, query) { + let reqId = parseReqId(query.id); + + instance.state.set('action', query.action); + instance.state.set('id', reqId); + + subscribeToOptionsData(instance); + instance.subscribe('clique_constraints?_id', reqId.id); + + CliqueConstraints.find({ _id: reqId.id }).forEach((model) => { + instance.state.set('model', model); + }); +} + +function initRemoveView(instance, query) { + initViewView(instance, query); +} + +function subscribeToOptionsData(instance) { +// instance.subscribe('environments_config'); + instance.subscribe('link_types'); + instance.subscribe('constants'); +} + +function submitItem( + instance, + id, + focal_point_type, + constraints + ) { + + let action = instance.state.get('action'); + + instance.state.set('isError', false); + instance.state.set('isSuccess', false); + instance.state.set('isMessage', false); + instance.state.set('message', null); + + switch (action) { + case 'insert': + insert.call({ + focal_point_type: focal_point_type, + constraints: constraints, + }, processActionResult.bind(null, instance)); + break; + + case 'update': + update.call({ + _id: id.id, + focal_point_type: focal_point_type, + constraints: constraints, + }, processActionResult.bind(null, instance)); + break; + + case 'remove': + remove.call({ + _id: id.id + }, processActionResult.bind(null, instance)); + break; + + default: + // todo + break; + } +} + +function processActionResult(instance, error) { + let action = instance.state.get('action'); + + 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 { + instance.state.set('message', error.message); + } + + return; + } + + instance.state.set('isError', false); + instance.state.set('isSuccess', true); + instance.state.set('isMessage', true); + + switch (action) { + case 'insert': + instance.state.set('message', 'Record had been added successfully'); + instance.state.set('disabled', true); + break; + + case 'remove': + instance.state.set('message', 'Record had been removed successfully'); + instance.state.set('disabled', true); + break; + + case 'update': + instance.state.set('message', 'Record had been updated successfully'); + break; + } + + Router.go('/clique-constraints-list'); +} + +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/clique-constraint/clique-constraint.styl b/ui/imports/ui/components/clique-constraint/clique-constraint.styl new file mode 100644 index 0000000..72d2348 --- /dev/null +++ b/ui/imports/ui/components/clique-constraint/clique-constraint.styl @@ -0,0 +1,35 @@ +.os-clique-constraint + 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; + + .js-message-panel + margin-top: 20px; + |