Add vnf, tag create & Associate Plugins 61/30461/7
authorKumar Rishabh <shailrishabh@gmail.com>
Tue, 14 Mar 2017 19:32:11 +0000 (01:02 +0530)
committerKumar Rishabh <shailrishabh@gmail.com>
Thu, 16 Mar 2017 02:38:12 +0000 (08:08 +0530)
Adds support for accessing database, plugin to create tags and
vnfs and make association between them. Also adds autocomplete feature
to vnf-tag association.

Change-Id: Id55f998df68ae5e6e6fd298c6393b3500777468a
Signed-off-by: Kumar Rishabh <shailrishabh@gmail.com>
28 files changed:
utils/test/vnfcatalogue/VNF_Catalogue/README.md
utils/test/vnfcatalogue/VNF_Catalogue/app.js
utils/test/vnfcatalogue/VNF_Catalogue/database.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/package.json
utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/global.js
utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/mode_edit.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/search_results.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/project_profile.css [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_form.css [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_projects.css
utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/style.css
utils/test/vnfcatalogue/VNF_Catalogue/public/uploads/logo.png [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/routes/add_project.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/routes/add_tag.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/routes/project_profile.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/routes/search_projects.js
utils/test/vnfcatalogue/VNF_Catalogue/routes/search_tag.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/routes/search_vnf.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/routes/vnf_tag_association.js [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/views/add_project.jade [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/views/index.jade
utils/test/vnfcatalogue/VNF_Catalogue/views/layout.jade
utils/test/vnfcatalogue/VNF_Catalogue/views/project_profile.jade [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/views/search.jade [new file with mode: 0644]
utils/test/vnfcatalogue/VNF_Catalogue/views/search_projects.jade
utils/test/vnfcatalogue/VNF_Catalogue/views/vnf_tag_association.jade [new file with mode: 0644]
utils/test/vnfcatalogue/helpers/migrate.js

index 32ad654..22d4290 100644 (file)
@@ -5,8 +5,13 @@
 
 First install the dependencies
 
-       ```npm install```
+    ```npm install```
+
+set time zone(Important)
+        Set same timezone in both nodejs server and mysql server. Something
+        similar to below can be used:
+        ``` SET GLOBAL time_zone = '+00:00'; ```
 
 Then Start the Server
 
-       ```npm start```
+    ```npm start```
index 0f842b6..4b6add2 100644 (file)
@@ -13,9 +13,17 @@ var favicon = require('serve-favicon');
 var logger = require('morgan');
 var cookieParser = require('cookie-parser');
 var bodyParser = require('body-parser');
+var validator = require('express-validator');
 
 var routes = require('./routes/index');
 var search_projects = require('./routes/search_projects');
+var project_profile = require('./routes/project_profile');
+var add_project = require('./routes/add_project');
+var add_tag = require('./routes/add_tag');
+var search_tag = require('./routes/search_tag');
+var search_vnf = require('./routes/search_vnf');
+var vnf_tag_association = require('./routes/vnf_tag_association');
+
 
 var app = express();
 
@@ -23,27 +31,35 @@ var app = express();
 app.set('views', path.join(__dirname, 'views'));
 app.set('view engine', 'jade');
 
+db_pool = require('./database').pool;
+
 // Database
-var db = require('mysql2');
+//var db = require('mysql2');
 
 // uncomment after placing your favicon in /public
 //app.use(favicon(__dirname + '/public/favicon.ico'));
 app.use(logger('dev'));
 app.use(bodyParser.json());
 app.use(bodyParser.urlencoded({ extended: false }));
+app.use(validator());
 app.use(cookieParser());
 app.use(express.static(path.join(__dirname, 'public')));
 
 // Make our db accessible to our router
 app.use(function(req,res,next){
-    req.db = db;
+    //db_pool size 50 default
+    req.db_pool = db_pool;
     next();
 });
 
 app.use('/', routes);
 app.use('/search_projects', search_projects);
-
-
+app.use('/project_profile', project_profile);
+app.use('/add_project', add_project);
+app.use('/add_tag', add_tag);
+app.use('/search_tag', search_tag);
+app.use('/search_vnf', search_vnf);
+app.use('/vnf_tag_association', vnf_tag_association);
 // Some Error handling for now #TODO Remove
 
 /// catch 404 and forwarding to error handler
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/database.js b/utils/test/vnfcatalogue/VNF_Catalogue/database.js
new file mode 100644 (file)
index 0000000..b313104
--- /dev/null
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh 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
+ *******************************************************************************/
+
+var mysql = require('mysql');
+
+var pool = mysql.createPool({
+  host: 'localhost',
+  user: 'myuser',
+  password: 'mypassword',
+  database: 'vnf_catalogue',
+  connectionLimit: 50,
+  supportBigNumbers: true,
+  multipleStatements: true,
+  dateStrings: 'date'
+});
+
+exports.pool = pool;
index 7c6a867..414b424 100644 (file)
         "jade": "~1.11.0",
         "morgan": "~1.7.0",
         "serve-favicon": "~2.3.0",
-        "mysql2": "*"
+        "mysql": "*",
+        "express-validator": "*",
+        "nodemon": "*",
+        "async": "*",
+        "multer": "*",
+        "octonode": "*"
     }
-}
\ No newline at end of file
+}
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/3rd_party/typeahead.js
new file mode 100644 (file)
index 0000000..11235e7
--- /dev/null
@@ -0,0 +1,7 @@
+/*!
+ * typeahead.js 0.10.4
+ * https://github.com/twitter/typeahead.js
+ * Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT
+ */
+
+!function(a){var b=function(){"use strict";return{isMsie:function(){return/(msie|trident)/i.test(navigator.userAgent)?navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2]:!1},isBlankString:function(a){return!a||/^\s*$/.test(a)},escapeRegExChars:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(a){return"string"==typeof a},isNumber:function(a){return"number"==typeof a},isArray:a.isArray,isFunction:a.isFunction,isObject:a.isPlainObject,isUndefined:function(a){return"undefined"==typeof a},toStr:function(a){return b.isUndefined(a)||null===a?"":a+""},bind:a.proxy,each:function(b,c){function d(a,b){return c(b,a)}a.each(b,d)},map:a.map,filter:a.grep,every:function(b,c){var d=!0;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?void 0:!1}),!!d):d},some:function(b,c){var d=!1;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?!1:void 0}),!!d):d},mixin:a.extend,getUniqueId:function(){var a=0;return function(){return a++}}(),templatify:function(b){function c(){return String(b)}return a.isFunction(b)?b:c},defer:function(a){setTimeout(a,0)},debounce:function(a,b,c){var d,e;return function(){var f,g,h=this,i=arguments;return f=function(){d=null,c||(e=a.apply(h,i))},g=c&&!d,clearTimeout(d),d=setTimeout(f,b),g&&(e=a.apply(h,i)),e}},throttle:function(a,b){var c,d,e,f,g,h;return g=0,h=function(){g=new Date,e=null,f=a.apply(c,d)},function(){var i=new Date,j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},noop:function(){}}}(),c="0.10.4",d=function(){"use strict";function a(a){return a=b.toStr(a),a?a.split(/\s+/):[]}function c(a){return a=b.toStr(a),a?a.split(/\W+/):[]}function d(a){return function(){var c=[].slice.call(arguments,0);return function(d){var e=[];return b.each(c,function(c){e=e.concat(a(b.toStr(d[c])))}),e}}}return{nonword:c,whitespace:a,obj:{nonword:d(c),whitespace:d(a)}}}(),e=function(){"use strict";function c(c){this.maxSize=b.isNumber(c)?c:100,this.reset(),this.maxSize<=0&&(this.set=this.get=a.noop)}function d(){this.head=this.tail=null}function e(a,b){this.key=a,this.val=b,this.prev=this.next=null}return b.mixin(c.prototype,{set:function(a,b){var c,d=this.list.tail;this.size>=this.maxSize&&(this.list.remove(d),delete this.hash[d.key]),(c=this.hash[a])?(c.val=b,this.list.moveToFront(c)):(c=new e(a,b),this.list.add(c),this.hash[a]=c,this.size++)},get:function(a){var b=this.hash[a];return b?(this.list.moveToFront(b),b.val):void 0},reset:function(){this.size=0,this.hash={},this.list=new d}}),b.mixin(d.prototype,{add:function(a){this.head&&(a.next=this.head,this.head.prev=a),this.head=a,this.tail=this.tail||a},remove:function(a){a.prev?a.prev.next=a.next:this.head=a.next,a.next?a.next.prev=a.prev:this.tail=a.prev},moveToFront:function(a){this.remove(a),this.add(a)}}),c}(),f=function(){"use strict";function a(a){this.prefix=["__",a,"__"].join(""),this.ttlKey="__ttl__",this.keyMatcher=new RegExp("^"+b.escapeRegExChars(this.prefix))}function c(){return(new Date).getTime()}function d(a){return JSON.stringify(b.isUndefined(a)?null:a)}function e(a){return JSON.parse(a)}var f,g;try{f=window.localStorage,f.setItem("~~~","!"),f.removeItem("~~~")}catch(h){f=null}return g=f&&window.JSON?{_prefix:function(a){return this.prefix+a},_ttlKey:function(a){return this._prefix(a)+this.ttlKey},get:function(a){return this.isExpired(a)&&this.remove(a),e(f.getItem(this._prefix(a)))},set:function(a,e,g){return b.isNumber(g)?f.setItem(this._ttlKey(a),d(c()+g)):f.removeItem(this._ttlKey(a)),f.setItem(this._prefix(a),d(e))},remove:function(a){return f.removeItem(this._ttlKey(a)),f.removeItem(this._prefix(a)),this},clear:function(){var a,b,c=[],d=f.length;for(a=0;d>a;a++)(b=f.key(a)).match(this.keyMatcher)&&c.push(b.replace(this.keyMatcher,""));for(a=c.length;a--;)this.remove(c[a]);return this},isExpired:function(a){var d=e(f.getItem(this._ttlKey(a)));return b.isNumber(d)&&c()>d?!0:!1}}:{get:b.noop,set:b.noop,remove:b.noop,clear:b.noop,isExpired:b.noop},b.mixin(a.prototype,g),a}(),g=function(){"use strict";function c(b){b=b||{},this.cancelled=!1,this.lastUrl=null,this._send=b.transport?d(b.transport):a.ajax,this._get=b.rateLimiter?b.rateLimiter(this._get):this._get,this._cache=b.cache===!1?new e(0):i}function d(c){return function(d,e){function f(a){b.defer(function(){h.resolve(a)})}function g(a){b.defer(function(){h.reject(a)})}var h=a.Deferred();return c(d,e,f,g),h}}var f=0,g={},h=6,i=new e(10);return c.setMaxPendingRequests=function(a){h=a},c.resetCache=function(){i.reset()},b.mixin(c.prototype,{_get:function(a,b,c){function d(b){c&&c(null,b),k._cache.set(a,b)}function e(){c&&c(!0)}function i(){f--,delete g[a],k.onDeckRequestArgs&&(k._get.apply(k,k.onDeckRequestArgs),k.onDeckRequestArgs=null)}var j,k=this;this.cancelled||a!==this.lastUrl||((j=g[a])?j.done(d).fail(e):h>f?(f++,g[a]=this._send(a,b).done(d).fail(e).always(i)):this.onDeckRequestArgs=[].slice.call(arguments,0))},get:function(a,c,d){var e;return b.isFunction(c)&&(d=c,c={}),this.cancelled=!1,this.lastUrl=a,(e=this._cache.get(a))?b.defer(function(){d&&d(null,e)}):this._get(a,c,d),!!e},cancel:function(){this.cancelled=!0}}),c}(),h=function(){"use strict";function c(b){b=b||{},b.datumTokenizer&&b.queryTokenizer||a.error("datumTokenizer and queryTokenizer are both required"),this.datumTokenizer=b.datumTokenizer,this.queryTokenizer=b.queryTokenizer,this.reset()}function d(a){return a=b.filter(a,function(a){return!!a}),a=b.map(a,function(a){return a.toLowerCase()})}function e(){return{ids:[],children:{}}}function f(a){for(var b={},c=[],d=0,e=a.length;e>d;d++)b[a[d]]||(b[a[d]]=!0,c.push(a[d]));return c}function g(a,b){function c(a,b){return a-b}var d=0,e=0,f=[];a=a.sort(c),b=b.sort(c);for(var g=a.length,h=b.length;g>d&&h>e;)a[d]<b[e]?d++:a[d]>b[e]?e++:(f.push(a[d]),d++,e++);return f}return b.mixin(c.prototype,{bootstrap:function(a){this.datums=a.datums,this.trie=a.trie},add:function(a){var c=this;a=b.isArray(a)?a:[a],b.each(a,function(a){var f,g;f=c.datums.push(a)-1,g=d(c.datumTokenizer(a)),b.each(g,function(a){var b,d,g;for(b=c.trie,d=a.split("");g=d.shift();)b=b.children[g]||(b.children[g]=e()),b.ids.push(f)})})},get:function(a){var c,e,h=this;return c=d(this.queryTokenizer(a)),b.each(c,function(a){var b,c,d,f;if(e&&0===e.length)return!1;for(b=h.trie,c=a.split("");b&&(d=c.shift());)b=b.children[d];return b&&0===c.length?(f=b.ids.slice(0),void(e=e?g(e,f):f)):(e=[],!1)}),e?b.map(f(e),function(a){return h.datums[a]}):[]},reset:function(){this.datums=[],this.trie=e()},serialize:function(){return{datums:this.datums,trie:this.trie}}}),c}(),i=function(){"use strict";function d(a){return a.local||null}function e(d){var e,f;return f={url:null,thumbprint:"",ttl:864e5,filter:null,ajax:{}},(e=d.prefetch||null)&&(e=b.isString(e)?{url:e}:e,e=b.mixin(f,e),e.thumbprint=c+e.thumbprint,e.ajax.type=e.ajax.type||"GET",e.ajax.dataType=e.ajax.dataType||"json",!e.url&&a.error("prefetch requires url to be set")),e}function f(c){function d(a){return function(c){return b.debounce(c,a)}}function e(a){return function(c){return b.throttle(c,a)}}var f,g;return g={url:null,cache:!0,wildcard:"%QUERY",replace:null,rateLimitBy:"debounce",rateLimitWait:300,send:null,filter:null,ajax:{}},(f=c.remote||null)&&(f=b.isString(f)?{url:f}:f,f=b.mixin(g,f),f.rateLimiter=/^throttle$/i.test(f.rateLimitBy)?e(f.rateLimitWait):d(f.rateLimitWait),f.ajax.type=f.ajax.type||"GET",f.ajax.dataType=f.ajax.dataType||"json",delete f.rateLimitBy,delete f.rateLimitWait,!f.url&&a.error("remote requires url to be set")),f}return{local:d,prefetch:e,remote:f}}();!function(c){"use strict";function e(b){b&&(b.local||b.prefetch||b.remote)||a.error("one of local, prefetch, or remote is required"),this.limit=b.limit||5,this.sorter=j(b.sorter),this.dupDetector=b.dupDetector||k,this.local=i.local(b),this.prefetch=i.prefetch(b),this.remote=i.remote(b),this.cacheKey=this.prefetch?this.prefetch.cacheKey||this.prefetch.url:null,this.index=new h({datumTokenizer:b.datumTokenizer,queryTokenizer:b.queryTokenizer}),this.storage=this.cacheKey?new f(this.cacheKey):null}function j(a){function c(b){return b.sort(a)}function d(a){return a}return b.isFunction(a)?c:d}function k(){return!1}var l,m;return l=c.Bloodhound,m={data:"data",protocol:"protocol",thumbprint:"thumbprint"},c.Bloodhound=e,e.noConflict=function(){return c.Bloodhound=l,e},e.tokenizers=d,b.mixin(e.prototype,{_loadPrefetch:function(b){function c(a){f.clear(),f.add(b.filter?b.filter(a):a),f._saveToStorage(f.index.serialize(),b.thumbprint,b.ttl)}var d,e,f=this;return(d=this._readFromStorage(b.thumbprint))?(this.index.bootstrap(d),e=a.Deferred().resolve()):e=a.ajax(b.url,b.ajax).done(c),e},_getFromRemote:function(a,b){function c(a,c){b(a?[]:f.remote.filter?f.remote.filter(c):c)}var d,e,f=this;if(this.transport)return a=a||"",e=encodeURIComponent(a),d=this.remote.replace?this.remote.replace(this.remote.url,a):this.remote.url.replace(this.remote.wildcard,e),this.transport.get(d,this.remote.ajax,c)},_cancelLastRemoteRequest:function(){this.transport&&this.transport.cancel()},_saveToStorage:function(a,b,c){this.storage&&(this.storage.set(m.data,a,c),this.storage.set(m.protocol,location.protocol,c),this.storage.set(m.thumbprint,b,c))},_readFromStorage:function(a){var b,c={};return this.storage&&(c.data=this.storage.get(m.data),c.protocol=this.storage.get(m.protocol),c.thumbprint=this.storage.get(m.thumbprint)),b=c.thumbprint!==a||c.protocol!==location.protocol,c.data&&!b?c.data:null},_initialize:function(){function c(){e.add(b.isFunction(f)?f():f)}var d,e=this,f=this.local;return d=this.prefetch?this._loadPrefetch(this.prefetch):a.Deferred().resolve(),f&&d.done(c),this.transport=this.remote?new g(this.remote):null,this.initPromise=d.promise()},initialize:function(a){return!this.initPromise||a?this._initialize():this.initPromise},add:function(a){this.index.add(a)},get:function(a,c){function d(a){var d=f.slice(0);b.each(a,function(a){var c;return c=b.some(d,function(b){return e.dupDetector(a,b)}),!c&&d.push(a),d.length<e.limit}),c&&c(e.sorter(d))}var e=this,f=[],g=!1;f=this.index.get(a),f=this.sorter(f).slice(0,this.limit),f.length<this.limit?g=this._getFromRemote(a,d):this._cancelLastRemoteRequest(),g||(f.length>0||!this.transport)&&c&&c(f)},clear:function(){this.index.reset()},clearPrefetchCache:function(){this.storage&&this.storage.clear()},clearRemoteCache:function(){this.transport&&g.resetCache()},ttAdapter:function(){return b.bind(this.get,this)}}),e}(this);var j=function(){return{wrapper:'<span class="twitter-typeahead"></span>',dropdown:'<span class="tt-dropdown-menu"></span>',dataset:'<div class="tt-dataset-%CLASS%"></div>',suggestions:'<span class="tt-suggestions"></span>',suggestion:'<div class="tt-suggestion"></div>'}}(),k=function(){"use strict";var a={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none",opacity:"1"},input:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},inputWithNoHint:{position:"relative",verticalAlign:"top"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"},suggestions:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"},ltr:{left:"0",right:"auto"},rtl:{left:"auto",right:" 0"}};return b.isMsie()&&b.mixin(a.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),b.isMsie()&&b.isMsie()<=7&&b.mixin(a.input,{marginTop:"-1px"}),a}(),l=function(){"use strict";function c(b){b&&b.el||a.error("EventBus initialized without el"),this.$el=a(b.el)}var d="typeahead:";return b.mixin(c.prototype,{trigger:function(a){var b=[].slice.call(arguments,1);this.$el.trigger(d+a,b)}}),c}(),m=function(){"use strict";function a(a,b,c,d){var e;if(!c)return this;for(b=b.split(i),c=d?h(c,d):c,this._callbacks=this._callbacks||{};e=b.shift();)this._callbacks[e]=this._callbacks[e]||{sync:[],async:[]},this._callbacks[e][a].push(c);return this}function b(b,c,d){return a.call(this,"async",b,c,d)}function c(b,c,d){return a.call(this,"sync",b,c,d)}function d(a){var b;if(!this._callbacks)return this;for(a=a.split(i);b=a.shift();)delete this._callbacks[b];return this}function e(a){var b,c,d,e,g;if(!this._callbacks)return this;for(a=a.split(i),d=[].slice.call(arguments,1);(b=a.shift())&&(c=this._callbacks[b]);)e=f(c.sync,this,[b].concat(d)),g=f(c.async,this,[b].concat(d)),e()&&j(g);return this}function f(a,b,c){function d(){for(var d,e=0,f=a.length;!d&&f>e;e+=1)d=a[e].apply(b,c)===!1;return!d}return d}function g(){var a;return a=window.setImmediate?function(a){setImmediate(function(){a()})}:function(a){setTimeout(function(){a()},0)}}function h(a,b){return a.bind?a.bind(b):function(){a.apply(b,[].slice.call(arguments,0))}}var i=/\s+/,j=g();return{onSync:c,onAsync:b,off:d,trigger:e}}(),n=function(a){"use strict";function c(a,c,d){for(var e,f=[],g=0,h=a.length;h>g;g++)f.push(b.escapeRegExChars(a[g]));return e=d?"\\b("+f.join("|")+")\\b":"("+f.join("|")+")",c?new RegExp(e):new RegExp(e,"i")}var d={node:null,pattern:null,tagName:"strong",className:null,wordsOnly:!1,caseSensitive:!1};return function(e){function f(b){var c,d,f;return(c=h.exec(b.data))&&(f=a.createElement(e.tagName),e.className&&(f.className=e.className),d=b.splitText(c.index),d.splitText(c[0].length),f.appendChild(d.cloneNode(!0)),b.parentNode.replaceChild(f,d)),!!c}function g(a,b){for(var c,d=3,e=0;e<a.childNodes.length;e++)c=a.childNodes[e],c.nodeType===d?e+=b(c)?1:0:g(c,b)}var h;e=b.mixin({},d,e),e.node&&e.pattern&&(e.pattern=b.isArray(e.pattern)?e.pattern:[e.pattern],h=c(e.pattern,e.caseSensitive,e.wordsOnly),g(e.node,f))}}(window.document),o=function(){"use strict";function c(c){var e,f,h,i,j=this;c=c||{},c.input||a.error("input is missing"),e=b.bind(this._onBlur,this),f=b.bind(this._onFocus,this),h=b.bind(this._onKeydown,this),i=b.bind(this._onInput,this),this.$hint=a(c.hint),this.$input=a(c.input).on("blur.tt",e).on("focus.tt",f).on("keydown.tt",h),0===this.$hint.length&&(this.setHint=this.getHint=this.clearHint=this.clearHintIfInvalid=b.noop),b.isMsie()?this.$input.on("keydown.tt keypress.tt cut.tt paste.tt",function(a){g[a.which||a.keyCode]||b.defer(b.bind(j._onInput,j,a))}):this.$input.on("input.tt",i),this.query=this.$input.val(),this.$overflowHelper=d(this.$input)}function d(b){return a('<pre aria-hidden="true"></pre>').css({position:"absolute",visibility:"hidden",whiteSpace:"pre",fontFamily:b.css("font-family"),fontSize:b.css("font-size"),fontStyle:b.css("font-style"),fontVariant:b.css("font-variant"),fontWeight:b.css("font-weight"),wordSpacing:b.css("word-spacing"),letterSpacing:b.css("letter-spacing"),textIndent:b.css("text-indent"),textRendering:b.css("text-rendering"),textTransform:b.css("text-transform")}).insertAfter(b)}function e(a,b){return c.normalizeQuery(a)===c.normalizeQuery(b)}function f(a){return a.altKey||a.ctrlKey||a.metaKey||a.shiftKey}var g;return g={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"},c.normalizeQuery=function(a){return(a||"").replace(/^\s*/g,"").replace(/\s{2,}/g," ")},b.mixin(c.prototype,m,{_onBlur:function(){this.resetInputValue(),this.trigger("blurred")},_onFocus:function(){this.trigger("focused")},_onKeydown:function(a){var b=g[a.which||a.keyCode];this._managePreventDefault(b,a),b&&this._shouldTrigger(b,a)&&this.trigger(b+"Keyed",a)},_onInput:function(){this._checkInputValue()},_managePreventDefault:function(a,b){var c,d,e;switch(a){case"tab":d=this.getHint(),e=this.getInputValue(),c=d&&d!==e&&!f(b);break;case"up":case"down":c=!f(b);break;default:c=!1}c&&b.preventDefault()},_shouldTrigger:function(a,b){var c;switch(a){case"tab":c=!f(b);break;default:c=!0}return c},_checkInputValue:function(){var a,b,c;a=this.getInputValue(),b=e(a,this.query),c=b?this.query.length!==a.length:!1,this.query=a,b?c&&this.trigger("whitespaceChanged",this.query):this.trigger("queryChanged",this.query)},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return this.query},setQuery:function(a){this.query=a},getInputValue:function(){return this.$input.val()},setInputValue:function(a,b){this.$input.val(a),b?this.clearHint():this._checkInputValue()},resetInputValue:function(){this.setInputValue(this.query,!0)},getHint:function(){return this.$hint.val()},setHint:function(a){this.$hint.val(a)},clearHint:function(){this.setHint("")},clearHintIfInvalid:function(){var a,b,c,d;a=this.getInputValue(),b=this.getHint(),c=a!==b&&0===b.indexOf(a),d=""!==a&&c&&!this.hasOverflow(),!d&&this.clearHint()},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},hasOverflow:function(){var a=this.$input.width()-2;return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>=a},isCursorAtEnd:function(){var a,c,d;return a=this.$input.val().length,c=this.$input[0].selectionStart,b.isNumber(c)?c===a:document.selection?(d=document.selection.createRange(),d.moveStart("character",-a),a===d.text.length):!0},destroy:function(){this.$hint.off(".tt"),this.$input.off(".tt"),this.$hint=this.$input=this.$overflowHelper=null}}),c}(),p=function(){"use strict";function c(c){c=c||{},c.templates=c.templates||{},c.source||a.error("missing source"),c.name&&!f(c.name)&&a.error("invalid dataset name: "+c.name),this.query=null,this.highlight=!!c.highlight,this.name=c.name||b.getUniqueId(),this.source=c.source,this.displayFn=d(c.display||c.displayKey),this.templates=e(c.templates,this.displayFn),this.$el=a(j.dataset.replace("%CLASS%",this.name))}function d(a){function c(b){return b[a]}return a=a||"value",b.isFunction(a)?a:c}function e(a,c){function d(a){return"<p>"+c(a)+"</p>"}return{empty:a.empty&&b.templatify(a.empty),header:a.header&&b.templatify(a.header),footer:a.footer&&b.templatify(a.footer),suggestion:a.suggestion||d}}function f(a){return/^[_a-zA-Z0-9-]+$/.test(a)}var g="ttDataset",h="ttValue",i="ttDatum";return c.extractDatasetName=function(b){return a(b).data(g)},c.extractValue=function(b){return a(b).data(h)},c.extractDatum=function(b){return a(b).data(i)},b.mixin(c.prototype,m,{_render:function(c,d){function e(){return p.templates.empty({query:c,isEmpty:!0})}function f(){function e(b){var c;return c=a(j.suggestion).append(p.templates.suggestion(b)).data(g,p.name).data(h,p.displayFn(b)).data(i,b),c.children().each(function(){a(this).css(k.suggestionChild)}),c}var f,l;return f=a(j.suggestions).css(k.suggestions),l=b.map(d,e),f.append.apply(f,l),p.highlight&&n({className:"tt-highlight",node:f[0],pattern:c}),f}function l(){return p.templates.header({query:c,isEmpty:!o})}function m(){return p.templates.footer({query:c,isEmpty:!o})}if(this.$el){var o,p=this;this.$el.empty(),o=d&&d.length,!o&&this.templates.empty?this.$el.html(e()).prepend(p.templates.header?l():null).append(p.templates.footer?m():null):o&&this.$el.html(f()).prepend(p.templates.header?l():null).append(p.templates.footer?m():null),this.trigger("rendered")}},getRoot:function(){return this.$el},update:function(a){function b(b){c.canceled||a!==c.query||c._render(a,b)}var c=this;this.query=a,this.canceled=!1,this.source(a,b)},cancel:function(){this.canceled=!0},clear:function(){this.cancel(),this.$el.empty(),this.trigger("rendered")},isEmpty:function(){return this.$el.is(":empty")},destroy:function(){this.$el=null}}),c}(),q=function(){"use strict";function c(c){var e,f,g,h=this;c=c||{},c.menu||a.error("menu is required"),this.isOpen=!1,this.isEmpty=!0,this.datasets=b.map(c.datasets,d),e=b.bind(this._onSuggestionClick,this),f=b.bind(this._onSuggestionMouseEnter,this),g=b.bind(this._onSuggestionMouseLeave,this),this.$menu=a(c.menu).on("click.tt",".tt-suggestion",e).on("mouseenter.tt",".tt-suggestion",f).on("mouseleave.tt",".tt-suggestion",g),b.each(this.datasets,function(a){h.$menu.append(a.getRoot()),a.onSync("rendered",h._onRendered,h)})}function d(a){return new p(a)}return b.mixin(c.prototype,m,{_onSuggestionClick:function(b){this.trigger("suggestionClicked",a(b.currentTarget))},_onSuggestionMouseEnter:function(b){this._removeCursor(),this._setCursor(a(b.currentTarget),!0)},_onSuggestionMouseLeave:function(){this._removeCursor()},_onRendered:function(){function a(a){return a.isEmpty()}this.isEmpty=b.every(this.datasets,a),this.isEmpty?this._hide():this.isOpen&&this._show(),this.trigger("datasetRendered")},_hide:function(){this.$menu.hide()},_show:function(){this.$menu.css("display","block")},_getSuggestions:function(){return this.$menu.find(".tt-suggestion")},_getCursor:function(){return this.$menu.find(".tt-cursor").first()},_setCursor:function(a,b){a.first().addClass("tt-cursor"),!b&&this.trigger("cursorMoved")},_removeCursor:function(){this._getCursor().removeClass("tt-cursor")},_moveCursor:function(a){var b,c,d,e;if(this.isOpen){if(c=this._getCursor(),b=this._getSuggestions(),this._removeCursor(),d=b.index(c)+a,d=(d+1)%(b.length+1)-1,-1===d)return void this.trigger("cursorRemoved");-1>d&&(d=b.length-1),this._setCursor(e=b.eq(d)),this._ensureVisible(e)}},_ensureVisible:function(a){var b,c,d,e;b=a.position().top,c=b+a.outerHeight(!0),d=this.$menu.scrollTop(),e=this.$menu.height()+parseInt(this.$menu.css("paddingTop"),10)+parseInt(this.$menu.css("paddingBottom"),10),0>b?this.$menu.scrollTop(d+b):c>e&&this.$menu.scrollTop(d+(c-e))},close:function(){this.isOpen&&(this.isOpen=!1,this._removeCursor(),this._hide(),this.trigger("closed"))},open:function(){this.isOpen||(this.isOpen=!0,!this.isEmpty&&this._show(),this.trigger("opened"))},setLanguageDirection:function(a){this.$menu.css("ltr"===a?k.ltr:k.rtl)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(1)},getDatumForSuggestion:function(a){var b=null;return a.length&&(b={raw:p.extractDatum(a),value:p.extractValue(a),datasetName:p.extractDatasetName(a)}),b},getDatumForCursor:function(){return this.getDatumForSuggestion(this._getCursor().first())},getDatumForTopSuggestion:function(){return this.getDatumForSuggestion(this._getSuggestions().first())},update:function(a){function c(b){b.update(a)}b.each(this.datasets,c)},empty:function(){function a(a){a.clear()}b.each(this.datasets,a),this.isEmpty=!0},isVisible:function(){return this.isOpen&&!this.isEmpty},destroy:function(){function a(a){a.destroy()}this.$menu.off(".tt"),this.$menu=null,b.each(this.datasets,a)}}),c}(),r=function(){"use strict";function c(c){var e,f,g;c=c||{},c.input||a.error("missing input"),this.isActivated=!1,this.autoselect=!!c.autoselect,this.minLength=b.isNumber(c.minLength)?c.minLength:1,this.$node=d(c.input,c.withHint),e=this.$node.find(".tt-dropdown-menu"),f=this.$node.find(".tt-input"),g=this.$node.find(".tt-hint"),f.on("blur.tt",function(a){var c,d,g;c=document.activeElement,d=e.is(c),g=e.has(c).length>0,b.isMsie()&&(d||g)&&(a.preventDefault(),a.stopImmediatePropagation(),b.defer(function(){f.focus()}))}),e.on("mousedown.tt",function(a){a.preventDefault()}),this.eventBus=c.eventBus||new l({el:f}),this.dropdown=new q({menu:e,datasets:c.datasets}).onSync("suggestionClicked",this._onSuggestionClicked,this).onSync("cursorMoved",this._onCursorMoved,this).onSync("cursorRemoved",this._onCursorRemoved,this).onSync("opened",this._onOpened,this).onSync("closed",this._onClosed,this).onAsync("datasetRendered",this._onDatasetRendered,this),this.input=new o({input:f,hint:g}).onSync("focused",this._onFocused,this).onSync("blurred",this._onBlurred,this).onSync("enterKeyed",this._onEnterKeyed,this).onSync("tabKeyed",this._onTabKeyed,this).onSync("escKeyed",this._onEscKeyed,this).onSync("upKeyed",this._onUpKeyed,this).onSync("downKeyed",this._onDownKeyed,this).onSync("leftKeyed",this._onLeftKeyed,this).onSync("rightKeyed",this._onRightKeyed,this).onSync("queryChanged",this._onQueryChanged,this).onSync("whitespaceChanged",this._onWhitespaceChanged,this),this._setLanguageDirection()}function d(b,c){var d,f,h,i;d=a(b),f=a(j.wrapper).css(k.wrapper),h=a(j.dropdown).css(k.dropdown),i=d.clone().css(k.hint).css(e(d)),i.val("").removeData().addClass("tt-hint").removeAttr("id name placeholder required").prop("readonly",!0).attr({autocomplete:"off",spellcheck:"false",tabindex:-1}),d.data(g,{dir:d.attr("dir"),autocomplete:d.attr("autocomplete"),spellcheck:d.attr("spellcheck"),style:d.attr("style")}),d.addClass("tt-input").attr({autocomplete:"off",spellcheck:!1}).css(c?k.input:k.inputWithNoHint);try{!d.attr("dir")&&d.attr("dir","auto")}catch(l){}return d.wrap(f).parent().prepend(c?i:null).append(h)}function e(a){return{backgroundAttachment:a.css("background-attachment"),backgroundClip:a.css("background-clip"),backgroundColor:a.css("background-color"),backgroundImage:a.css("background-image"),backgroundOrigin:a.css("background-origin"),backgroundPosition:a.css("background-position"),backgroundRepeat:a.css("background-repeat"),backgroundSize:a.css("background-size")}}function f(a){var c=a.find(".tt-input");b.each(c.data(g),function(a,d){b.isUndefined(a)?c.removeAttr(d):c.attr(d,a)}),c.detach().removeData(g).removeClass("tt-input").insertAfter(a),a.remove()}var g="ttAttrs";return b.mixin(c.prototype,{_onSuggestionClicked:function(a,b){var c;(c=this.dropdown.getDatumForSuggestion(b))&&this._select(c)},_onCursorMoved:function(){var a=this.dropdown.getDatumForCursor();this.input.setInputValue(a.value,!0),this.eventBus.trigger("cursorchanged",a.raw,a.datasetName)},_onCursorRemoved:function(){this.input.resetInputValue(),this._updateHint()},_onDatasetRendered:function(){this._updateHint()},_onOpened:function(){this._updateHint(),this.eventBus.trigger("opened")},_onClosed:function(){this.input.clearHint(),this.eventBus.trigger("closed")},_onFocused:function(){this.isActivated=!0,this.dropdown.open()},_onBlurred:function(){this.isActivated=!1,this.dropdown.empty(),this.dropdown.close()},_onEnterKeyed:function(a,b){var c,d;c=this.dropdown.getDatumForCursor(),d=this.dropdown.getDatumForTopSuggestion(),c?(this._select(c),b.preventDefault()):this.autoselect&&d&&(this._select(d),b.preventDefault())},_onTabKeyed:function(a,b){var c;(c=this.dropdown.getDatumForCursor())?(this._select(c),b.preventDefault()):this._autocomplete(!0)},_onEscKeyed:function(){this.dropdown.close(),this.input.resetInputValue()},_onUpKeyed:function(){var a=this.input.getQuery();this.dropdown.isEmpty&&a.length>=this.minLength?this.dropdown.update(a):this.dropdown.moveCursorUp(),this.dropdown.open()},_onDownKeyed:function(){var a=this.input.getQuery();this.dropdown.isEmpty&&a.length>=this.minLength?this.dropdown.update(a):this.dropdown.moveCursorDown(),this.dropdown.open()},_onLeftKeyed:function(){"rtl"===this.dir&&this._autocomplete()},_onRightKeyed:function(){"ltr"===this.dir&&this._autocomplete()},_onQueryChanged:function(a,b){this.input.clearHintIfInvalid(),b.length>=this.minLength?this.dropdown.update(b):this.dropdown.empty(),this.dropdown.open(),this._setLanguageDirection()},_onWhitespaceChanged:function(){this._updateHint(),this.dropdown.open()},_setLanguageDirection:function(){var a;this.dir!==(a=this.input.getLanguageDirection())&&(this.dir=a,this.$node.css("direction",a),this.dropdown.setLanguageDirection(a))},_updateHint:function(){var a,c,d,e,f,g;a=this.dropdown.getDatumForTopSuggestion(),a&&this.dropdown.isVisible()&&!this.input.hasOverflow()?(c=this.input.getInputValue(),d=o.normalizeQuery(c),e=b.escapeRegExChars(d),f=new RegExp("^(?:"+e+")(.+$)","i"),g=f.exec(a.value),g?this.input.setHint(c+g[1]):this.input.clearHint()):this.input.clearHint()},_autocomplete:function(a){var b,c,d,e;b=this.input.getHint(),c=this.input.getQuery(),d=a||this.input.isCursorAtEnd(),b&&c!==b&&d&&(e=this.dropdown.getDatumForTopSuggestion(),e&&this.input.setInputValue(e.value),this.eventBus.trigger("autocompleted",e.raw,e.datasetName))},_select:function(a){this.input.setQuery(a.value),this.input.setInputValue(a.value,!0),this._setLanguageDirection(),this.eventBus.trigger("selected",a.raw,a.datasetName),this.dropdown.close(),b.defer(b.bind(this.dropdown.empty,this.dropdown))},open:function(){this.dropdown.open()},close:function(){this.dropdown.close()},setVal:function(a){a=b.toStr(a),this.isActivated?this.input.setInputValue(a):(this.input.setQuery(a),this.input.setInputValue(a,!0)),this._setLanguageDirection()},getVal:function(){return this.input.getQuery()},destroy:function(){this.input.destroy(),this.dropdown.destroy(),f(this.$node),this.$node=null}}),c}();!function(){"use strict";var c,d,e;c=a.fn.typeahead,d="ttTypeahead",e={initialize:function(c,e){function f(){var f,g,h=a(this);b.each(e,function(a){a.highlight=!!c.highlight}),g=new r({input:h,eventBus:f=new l({el:h}),withHint:b.isUndefined(c.hint)?!0:!!c.hint,minLength:c.minLength,autoselect:c.autoselect,datasets:e}),h.data(d,g)}return e=b.isArray(e)?e:[].slice.call(arguments,1),c=c||{},this.each(f)},open:function(){function b(){var b,c=a(this);(b=c.data(d))&&b.open()}return this.each(b)},close:function(){function b(){var b,c=a(this);(b=c.data(d))&&b.close()}return this.each(b)},val:function(b){function c(){var c,e=a(this);(c=e.data(d))&&c.setVal(b)}function e(a){var b,c;return(b=a.data(d))&&(c=b.getVal()),c}return arguments.length?this.each(c):e(this.first())},destroy:function(){function b(){var b,c=a(this);(b=c.data(d))&&(b.destroy(),c.removeData(d))}return this.each(b)}},a.fn.typeahead=function(b){var c;return e[b]&&"initialize"!==b?(c=this.filter(function(){return!!a(this).data(d)}),e[b].apply(c,[].slice.call(arguments,1))):e.initialize.apply(this,arguments)},a.fn.typeahead.noConflict=function(){return a.fn.typeahead=c,this}}()}(window.jQuery);
\ No newline at end of file
index 3ae20d1..f610456 100644 (file)
@@ -8,20 +8,80 @@
  *******************************************************************************/\r
 \r
 $(document).ready( function() {\r
+    $('select').material_select();\r
+    $('.modal').modal();\r
     $(".button-collapse").sideNav();\r
+    $('.carousel').carousel();\r
+\r
     $('#Search').click(function() {\r
         var tags = $('#Tags').val().toLowerCase().split(/[ ,]+/);\r
         window.location.href = '/search_projects?tags=' + tags;\r
         return false;\r
     });\r
+\r
     $('#SearchSpan').click(function(){\r
         var tags = $('#Tags').val().toLowerCase().split(/[ ,]+/);\r
         window.location.href = '/search_projects?tags=' + tags;\r
         return false;\r
     });\r
+\r
     $('div.form-group-custom i.material-icons').click(function(e){\r
         var tags = $('#Tags').val().toLowerCase().split(/[ ,]+/);\r
         window.location.href = '/search_projects?tags=' + tags;\r
         return false;\r
     });\r
+\r
+    $("#add_project_button").on('click',function(){\r
+        event.preventDefault();\r
+        var vnf_name = $("#vnf_name").val() ;\r
+\r
+        var formData = new FormData($('form#add_project_form')[0]);\r
+        var license = $('#license option:selected').val();\r
+        formData.append('license', license);\r
+        var opnfv_indicator = $('#opnfv_indicator option:selected').val();\r
+        formData.append('opnfv_indicator', opnfv_indicator);\r
+\r
+        $.ajax({\r
+            url: '/add_project',\r
+            type: 'post',\r
+            //dataType: 'json',\r
+            processData: false,  // tell jQuery not to process the data\r
+            contentType: false,  // tell jQuery not to set contentType\r
+            data: formData,\r
+            success: function(data) {\r
+                    $('#modal1').modal('close');\r
+                    $('form#add_project_form').trigger('reset');\r
+                    Materialize.toast('Successfully submitted the VNF!', 3000, 'rounded');\r
+            },\r
+            error: function (error) {\r
+                if(error['responseJSON']) {\r
+                    Materialize.toast(error['responseJSON']['error'], 3000, 'rounded');\r
+                } else if(error['responseText']) {\r
+                    var response_message = JSON.parse(error['responseText']);\r
+                    Materialize.toast(response_message['error'], 3000, 'rounded');\r
+                }\r
+                //$('#modal1').modal('open');\r
+            }\r
+        });\r
+    });\r
+    $("#add_tag_button").on('click',function(){\r
+        event.preventDefault();\r
+        var tag_name = $("#tag_name").val() ;\r
+\r
+        $.ajax({\r
+            url: '/add_tag',\r
+            type: 'post',\r
+            dataType: 'json',\r
+            data: $('form#add_tag_form').serialize(),\r
+            success: function(data) {\r
+                    $('#modal2').modal('close');\r
+                    $('form#add_tag_form').trigger('reset');\r
+                    Materialize.toast('Successfully submitted the TAG!', 3000, 'rounded');\r
+            },\r
+            error: function (error) {\r
+                Materialize.toast(error['responseJSON']['error'], 3000, 'rounded');\r
+            }\r
+        });\r
+    });\r
+\r
 });\r
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/mode_edit.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/mode_edit.js
new file mode 100644 (file)
index 0000000..2047a92
--- /dev/null
@@ -0,0 +1,82 @@
+/*******************************************************************************\r
+ * Copyright (c) 2017 Kumar Rishabh and others.\r
+ *\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Apache License, Version 2.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *******************************************************************************/\r
+\r
+$(document).ready( function() {\r
+\r
+    //getVnfs : get 5 main VNFs using typeahead\r
+    var getVnfs = new Bloodhound({\r
+        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('vnf_name'),\r
+        queryTokenizer: Bloodhound.tokenizers.obj.whitespace('vnf_name'),\r
+        remote: {\r
+            url: '/search_vnf?key=%QUERY',\r
+            wildcard: '%QUERY'\r
+        },\r
+        limit: 5\r
+    });\r
+\r
+    getVnfs.initialize();\r
+    $('#scrollable-dropdown-menu #vnf_name.typeahead').typeahead(\r
+    {\r
+        hint: true,\r
+        highlight: true,\r
+        minLength: 1\r
+    },\r
+    {\r
+        name: 'vnf_name',\r
+        display: 'vnf_name',\r
+        limit: 5,\r
+        source: getVnfs.ttAdapter()\r
+    });\r
+\r
+    //getTags : get 5 main tags using typeahead\r
+    var getTags = new Bloodhound({\r
+        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('tag_name'),\r
+        queryTokenizer: Bloodhound.tokenizers.obj.whitespace('tag_name'),\r
+        remote: {\r
+            url: '/search_tag?key=%QUERY',\r
+            wildcard: '%QUERY'\r
+        },\r
+        limit: 5\r
+    });\r
+\r
+    getTags.initialize();\r
+    $('#scrollable-dropdown-menu #tag_name.typeahead').typeahead(\r
+    {\r
+        hint: true,\r
+        highlight: true,\r
+        minLength: 1\r
+    },\r
+    {\r
+        name: 'tag_name',\r
+        display: 'tag_name',\r
+        limit: 5,\r
+        source: getTags.ttAdapter()\r
+    });\r
+\r
+    $("#add_vnf_tag_association_button").on('click',function(){\r
+        event.preventDefault();\r
+        var vnf_name = $("#vnf_name").val() ;\r
+\r
+        $.ajax({\r
+            url: '/vnf_tag_association',\r
+            type: 'post',\r
+            dataType: 'json',\r
+            data: $('form#add_vnf_tag_association_form').serialize(),\r
+            success: function(data) {\r
+                    $('#modal3').modal('close');\r
+                    $('form#add_vnf_tag_association_form').trigger('reset');\r
+                    Materialize.toast('Successfully added the TAG to the VNF!', 3000, 'rounded');\r
+            },\r
+            error: function (error) {\r
+                Materialize.toast(error['responseJSON']['error'], 3000, 'rounded');\r
+            }\r
+        });\r
+    });\r
+\r
+});\r
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/search_results.js b/utils/test/vnfcatalogue/VNF_Catalogue/public/javascripts/search_results.js
new file mode 100644 (file)
index 0000000..26c28c9
--- /dev/null
@@ -0,0 +1,12 @@
+/*******************************************************************************\r
+ * Copyright (c) 2017 Kumar Rishabh and others.\r
+ *\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Apache License, Version 2.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *******************************************************************************/\r
+\r
+$(document).ready( function() {\r
+    var ob = JSON.parse(json);\r
+});\r
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/project_profile.css b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/project_profile.css
new file mode 100644 (file)
index 0000000..03527f0
--- /dev/null
@@ -0,0 +1,12 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh 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
+ *******************************************************************************/
+
+.container-custom {
+  max-width: 100% !important;
+}
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_form.css b/utils/test/vnfcatalogue/VNF_Catalogue/public/stylesheets/search_form.css
new file mode 100644 (file)
index 0000000..4598cff
--- /dev/null
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh 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
+ *******************************************************************************/
+
+input.search-input-rest
+{
+  font-weight: 400;
+  margin: 0px 0;
+  height: 30px;
+  padding: 10px 30px;
+    min-width: 90%;
+    max-width: 90%;
+  /*max-width: 500px;
+  */
+  border-radius: 5px;
+  border: 2px solid #333333;
+  box-shadow: 0 0 15px 1px rgba(0,0,0,0.50);
+  color: #333333;
+  font-size: 22px;
+}
+.material-search-custom {
+  left : -30px;
+
+  padding-left: 10px;
+}
+.form-group-custom {
+  width : 400px;
+  position: relative;
+  float: right;
+  left: -40%;
+}
+.form-control-custom {
+  padding-top: 10px;
+  padding-left: 50px;
+}
+input[type="search"]:focus:not([readonly]) {
+  transition: all 0s !important;
+  border-radius: 5px;
+  border: 2px solid #333333;
+  box-shadow: 0 0 15px 1px rgba(0,0,0,0.50);
+  color: #333333;
+}
+.gray {
+  background: rgb(249,249,249);
+}
+span.glyphicon.glyphicon-search.form-control-feedback,
+    div.form-group-custom i.material-icons {
+      top: 0.5em;
+      left: 16.0em;
+      cursor:pointer;
+      z-index: 30;
+      position: absolute;
+}
index 8875f7f..c000711 100644 (file)
@@ -7,36 +7,13 @@
  * http://www.apache.org/licenses/LICENSE-2.0
  *******************************************************************************/
 
-input[type="text"]:focus:not([readonly]) {
-  transition: all 0s !important;
-  border-radius: 5px;
-  border: 2px solid #333333;
-  box-shadow: 0 0 15px 1px rgba(0,0,0,0.50);
-  color: #333333;
-}
-.gray {
-  background: rgb(249,249,249);
-}
-.material-search-custom {
-  left : -30px;
-
-  padding-left: 10px;
-}
-.form-group-custom {
-  width : 400px;
-  position: relative;
-  float: right;
-  left: -40%;
-}
-.form-control-custom {
-  padding-top: 10px;
-  padding-left: 50px;
-}
 .card-shadow-custom {
   box-shadow: 0 2px 3px 0 rgba(0,0,0,0.50);
   border-bottom: 2px solid #8B19A2;
 }
 .row-custom {
+  display: flex;
+  flex-flow: row wrap;
   width: 100%;
   margin: 1em 1em 1em 1em;
   padding-right: 20px;
@@ -56,8 +33,7 @@ input[type="text"]:focus:not([readonly]) {
   display: inline-block;
 }
 .card-image-picture-custom {
-  margin: 1em 0em 0em 3.5em;
-  display: inline-block;
+  margin: auto;
 }
 .collection .collection-item.active {
   background-color: rgb(255,245,114);
@@ -125,8 +101,12 @@ a.a-custom-more:hover {
 span.glyphicon.glyphicon-search.form-control-feedback,
     div.form-group-custom i.material-icons {
       top: 0.5em;
-      left: 16.5em;
+      left: 16.0em;
       cursor:pointer;
       z-index: 30;
       position: absolute;
 }
+.card-image-custom {
+  display: flex;
+  flex-flow: column wrap;
+}
index 4769cfc..f5355ba 100644 (file)
@@ -152,23 +152,6 @@ form.search-form input.search-input
   color: #333333;
   font-size: 22px;
 }
-input.search-input-rest
-{
-  font-weight: 400;
-  margin: 0px 0;
-  height: 30px;
-  padding: 10px 30px;
-    min-width: 90%;
-    max-width: 90%;
-  /*max-width: 500px;
-  */
-  border-radius: 5px;
-  border: 2px solid #333333;
-  box-shadow: 0 0 15px 1px rgba(0,0,0,0.50);
-  color: #333333;
-  font-size: 22px;
-}
-
 
 form.search-form button.search-button
 {
@@ -306,7 +289,7 @@ footer
 {
   height: 100px;
 }
-input[type="text"]:focus:not([readonly]) {
+input[type="search"]:focus:not([readonly]) {
   transition: all 0s !important;
   border-radius: 5px;
   border: 2px solid #333333;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/public/uploads/logo.png b/utils/test/vnfcatalogue/VNF_Catalogue/public/uploads/logo.png
new file mode 100644 (file)
index 0000000..fe18194
Binary files /dev/null and b/utils/test/vnfcatalogue/VNF_Catalogue/public/uploads/logo.png differ
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_project.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_project.js
new file mode 100644 (file)
index 0000000..229620d
--- /dev/null
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh 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
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+var multer = require('multer');
+
+
+var storage =   multer.diskStorage({
+  destination: function (req, file, callback) {
+    callback(null, './public/uploads');
+  },
+  filename: function (req, file, callback) {
+    console.log(file);
+    console.log(req.body);
+    callback(null, file.fieldname + '-' + Date.now() + '.jpg');
+  }
+});
+
+var fileFilter = function (req, file, cb) {
+  if (file.mimetype !== 'image/png') {
+    //req.fileValidationError = 'goes wrong on the mimetype';
+    cb(null, false);
+  } else {
+    cb(null, true);
+  }
+}
+
+var upload = multer({ fileFilter: fileFilter, storage : storage}).single('file_upload');
+
+
+router.post('/', function(req, res) {
+  upload(req,res,function(err) {
+        console.log(req.body);
+        console.log(req.file)
+        if(req.file == null && req.body['file_url'] != '') {
+            response = 'File Upload error: wrong Filetype';
+            res.status(500);
+            res.end(JSON.stringify({'error': response}));
+
+        }
+        if(err) {
+            console.log(err);
+            response = 'File Upload error: ' + err;
+            console.log(response);
+            //return res.end(req.fileValidationError);
+            res.status(500);
+            res.send({'error': response});
+            return;
+        }
+
+        console.log(req.file);
+        req.body['photo_url'] = (req.file) ? req.file['filename'] : 'logo.png';
+        console.log(req.body);
+
+        req.checkBody("vnf_name", "VNF Name must not be empty").notEmpty();
+        req.checkBody("repo_url", "Repository URL must not be empty").notEmpty();
+        req.checkBody("license", "Please select a License").notEmpty();
+        req.checkBody("opnfv_indicator", "Please select an OPNFV Indicator").notEmpty();
+        req.checkBody("repo_url", "Must be a Github URL").matches('.*github\.com.*');
+
+        var errors = req.validationErrors();
+        console.log(errors);
+
+        var response = '';  for(var i = 0; i < errors.length; i++) {
+            console.log(errors[i]['msg']);
+            response = response + errors[i]['msg'] + '; ';
+        }
+
+        if(errors) {    res.status(500);
+            res.send({'error': response});
+            return;
+        }
+
+        var vnf_details = req.body;
+        delete vnf_details.file_url;
+
+        db_pool.getConnection(function(err, connection) {
+            // Use the connection
+
+          sql_query = 'INSERT INTO photo(photo_url) values(\'' + req.body['photo_url'] + '\')\;SELECT LAST_INSERT_ID() photo_id';
+          // TODO look above query prone to sql_injections
+
+          console.log(sql_query);
+          connection.query(sql_query, function (error, results, fields) {
+             console.log('hola');
+             console.log(results[1][0].photo_id);
+              //connection.query(sql_query, vnf_details, function (error, results, fields) {
+             delete vnf_details.photo_url;
+             vnf_details['photo_id'] = results[1][0].photo_id;
+             sql_query = 'INSERT INTO vnf SET ?'
+               connection.query(sql_query, vnf_details, function (error, results, fields) {
+             // And done with the connection.
+             connection.release();
+             if (error) throw error;
+
+             // Handle error after the release.
+             res.end('{"success" : "Updated Successfully", "status" : 200}');
+             return;
+               // Don't use the connection here, it has been returned to the pool.
+               });
+          });
+        });
+
+
+  });
+
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_tag.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/add_tag.js
new file mode 100644 (file)
index 0000000..511f4cc
--- /dev/null
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh 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
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+
+router.post('/', function(req, res) {
+  console.log(req.body);
+  req.checkBody("tag_name", "TAG Name must not be empty").notEmpty();
+
+  var errors = req.validationErrors();
+  console.log(errors);
+
+  var response = '';  for(var i = 0; i < errors.length; i++) {
+    console.log(errors[i]['msg']);
+    response = response + errors[i]['msg'] + '; ';
+  }
+
+  if(errors) {  res.status(500);
+    res.send({'error': response});
+    return;
+  }
+
+  var tag_details = req.body;
+
+  db_pool.getConnection(function(err, connection) {
+    // Use the connection
+    sql_query = 'INSERT INTO tag SET ?'
+    connection.query(sql_query, tag_details, function (error, results, fields) {
+        // And done with the connection.
+      res.end('{"success" : "Updated Successfully", "status" : 200}');
+      return;
+        connection.release();
+        // Handle error after the release.
+        if (error) throw error;
+        // Don't use the connection here, it has been returned to the pool.
+    });
+  });
+
+
+  res.end('{"success" : "Updated Successfully", "status" : 200}');
+  return;
+
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/project_profile.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/project_profile.js
new file mode 100644 (file)
index 0000000..be06642
--- /dev/null
@@ -0,0 +1,19 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh 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
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+
+router.get('/', function(req, res) {
+  var tags = req.param('tags');
+  console.log(tags);
+  res.render('project_profile', { title: 'Express' });
+});
+
+module.exports = router;
index 49fceeb..96f68db 100644 (file)
@@ -9,11 +9,86 @@
 
 var express = require('express');
 var router = express.Router();
+var async = require('async');
+
+
+var renderer = function(res, err, results) {
+    console.log(results);
+    res.render('search_projects', { title: 'Express', json: results });
+}
+
+var get_tags = function(result, callback) {
+    db_pool.getConnection(function(err, connection) {
+        sql_query = 'select tag_name from tag where tag_id in (select tag_id from vnf_tags where vnf_id = ' + result['vnf_id'] + ') limit 5';
+        // TODO find why it works and not above
+        connection.query(sql_query, function (error, results, fields) {
+            console.log(results);
+            result['tags'] = results;
+            callback(null, result);
+            //connection.release();
+            if (error) throw error;
+        });
+    });
+}
+
+
+var get_images = function(result, callback) {
+    db_pool.getConnection(function(err, connection) {
+        sql_query = 'select photo_url from photo where photo_id = ' + result['photo_id'];
+        // TODO find why it works here and not when declared outside the method
+        console.log(sql_query);
+        connection.query(sql_query, function (error, results, fields) {
+            console.log(results[0].photo_url);
+            result['photo_url'] = results[0].photo_url;
+            callback(null, result);
+            //connection.release();
+            if (error) throw error;
+        });
+    });
+}
+
+var sql_data = function(tags, renderer, res) {
+    var tag_array = "\'" + tags.map(function (item) { return item; }).join("\',\'") + "\'";
+    console.log(tag_array);
+    var condition = '';
+    db_pool.getConnection(function(err, connection) {
+        sql_query = 'select tag_id from tag where tag_name in (' + tag_array + ')';
+        connection.query(sql_query, function (error, results, fields) {
+            condition = 'SELECT * FROM vnf as v';
+            for (var i in results) {
+                condition += (i == 0) ? ' WHERE ' : ' AND ';
+                condition += 'v.vnf_id IN (SELECT vnf_id from vnf_tags where tag_id = ' + results[i]['tag_id'] + ')';
+            }
+
+            connection.query(condition, function (error, results, fields) {
+                    console.log(results);
+                    async.map(results, get_images, function(error, results) {
+                        async.map(results, get_tags, renderer.bind(null, res));
+                    });
+                    //connection.release();
+                    if (error) throw error;
+            });
+
+            connection.release();
+            if (error) throw error;
+        });
+    });
+
+}
 
 router.get('/', function(req, res) {
+
+  console.log(typeof(req.param('tags')));
   var tags = req.param('tags');
-  console.log(tags);
-  res.render('search_projects', { title: 'Express' });
+
+  if(tags) {
+    tags = tags.toLowerCase().split(/[ ,]+/);
+    console.log(tags);
+    sql_data(tags, renderer, res);
+  } else {
+    res.render('search_projects', { title: 'Express', json: false});
+  }
+
 });
 
 module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_tag.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_tag.js
new file mode 100644 (file)
index 0000000..cbe8cae
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh 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
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+
+/* Post Controller for Tag autocomplete form */
+router.get('/', function(req, res) {
+    tag_partial = req.param('key');
+    db_pool.getConnection(function(err, connection) {
+
+        sql_query = 'select tag_name from tag where tag_name like "%'+ tag_partial + '%" limit 5';
+        // TODO find why it works and not above
+        connection.query(sql_query, function (error, results, fields) {
+            console.log(results);
+
+            var data=[];
+            for(i = 0; i < results.length; i++) {
+                data.push(results[i].tag_name.replace(/\r?\n|\r/g, ''));
+            }
+            console.log(results);
+            connection.release();
+            res.end(JSON.stringify(results));
+
+            if (error) throw error;
+        });
+    });
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_vnf.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/search_vnf.js
new file mode 100644 (file)
index 0000000..a5cf09c
--- /dev/null
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh 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
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+
+/* Post Controller for Search Vnf autocomplete form */
+router.get('/', function(req, res) {
+    tag_partial = req.param('key');
+    db_pool.getConnection(function(err, connection) {
+
+        sql_query = 'select vnf_name from vnf where vnf_name like "%'+ tag_partial + '%" limit 5';
+        // TODO find why it works and not above
+        connection.query(sql_query, function (error, results, fields) {
+            console.log(results);
+
+            var data=[];
+            for(i = 0; i < results.length; i++) {
+                data.push(results[i].vnf_name.replace(/\r?\n|\r/g, ''));
+            }
+            console.log(results);
+            connection.release();
+            res.end(JSON.stringify(results));
+
+            if (error) throw error;
+        });
+    });
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/routes/vnf_tag_association.js b/utils/test/vnfcatalogue/VNF_Catalogue/routes/vnf_tag_association.js
new file mode 100644 (file)
index 0000000..d1a3d72
--- /dev/null
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Kumar Rishabh 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
+ *******************************************************************************/
+
+var express = require('express');
+var router = express.Router();
+
+/* Post controller for VNF_TAG Association */
+router.post('/', function(req, res) {
+  req.checkBody("tag_name", "TAG Name must not be empty").notEmpty();
+  req.checkBody("vnf_name", "VNF Name must not be empty").notEmpty();
+
+  var errors = req.validationErrors();
+  console.log(errors);
+
+  var response = '';  for(var i = 0; i < errors.length; i++) {
+    console.log(errors[i]['msg']);
+    response = response + errors[i]['msg'] + '; ';
+  }
+
+  if(errors) {  res.status(500);
+    res.send({'error': response});
+    return;
+  }
+
+  var tag_name = req.param('tag_name');
+  var vnf_name = req.param('vnf_name');
+
+  db_pool.getConnection(function(err, connection) {
+    // Use the connection
+    //sql_query = 'INSERT INTO tag SET ?'
+    sql_query = 'insert into vnf_tags(vnf_id, tag_id) values ((select vnf_id from vnf where vnf_name = \'' + vnf_name + '\'), (select tag_id from tag where tag_name = \'' + tag_name + '\'))';
+    console.log(sql_query);
+    connection.query(sql_query, function (error, results, fields) {
+        // And done with the connection.
+
+        connection.release();
+        res.end('{"success" : "Updated Successfully", "status" : 200}');
+
+        // Handle error after the release.
+        if (error) throw error;
+        // Don't use the connection here, it has been returned to the pool.
+    });
+  });
+
+  res.end('{"success" : "Updated Successfully", "status" : 200}');
+  //res.render('vnf_tag_association', { title: 'Express' });
+});
+
+module.exports = router;
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/add_project.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/add_project.jade
new file mode 100644 (file)
index 0000000..dde8cfe
--- /dev/null
@@ -0,0 +1,164 @@
+
+.search-box
+  script(src='/3rd_party/typeahead.js')
+  script(type='text/javascript', src='/javascripts/mode_edit.js')
+  .fixed-action-btn.fixed-action-btn_custom
+    a.btn-floating.btn-large.red
+      i.large.material-icons mode_edit
+    ul
+      li
+        a.btn-floating.red.tooltipped(href='#modal2', data-position='left', data-delay='50', data-tooltip='Add a TAG')
+          i.large.material-icons attach_file
+      li
+        a.btn-floating.green.tooltipped(href='#modal1', data-position='left', data-delay='50', data-tooltip='Add a VNF')
+          i.large.material-icons add
+      li
+        a.btn-floating.blue.tooltipped(href='#modal3', data-position='left', data-delay='50', data-tooltip='Add a TAG to a VNF')
+          i.large.material-icons share
+  #modal1.modal
+    .modal-content
+      h4.center
+        i.material-icons library_add
+        |         Add a VNF
+      .row
+        form#add_project_form.col.s12(action='/add_project', enctype='multipart/form-data', method='post')
+          .row.modal-form-row
+            .input-field.col.s12
+              input#vnf_name.validate(type='text', name='vnf_name')
+              label.left-align(for='vnf_name') Name
+          .row
+            .input-field.col.s12
+              input#repo_url.validate(type='text', name='repo_url')
+              label.left-align(for='repo_url') Github URL
+          .row
+            .input-field.col.s12
+              select#license
+                option(value='', name='license', disabled='', selected='') Choose the License
+                option(value='MIT') MIT
+                option(value='GPL') GPL
+                option(value='GPL_V2') GPL_V2
+                option(value='BSD') BSD
+                option(value='APACHE') APACHE
+              label License
+          .row
+            .input-field.col.s12
+              select#opnfv_indicator
+                option(value='', name='opnfv_indicator', disabled='', selected='') Choose the OPNFV Indicator
+                option(value='silver') silver
+                option(value='gold') gold
+                option(value='platinum') platinum
+              label OPNFV Indicator
+
+          .row
+            .file-field.input-field
+              .btn
+                span Photo (Optional)
+                input#file_upload(type='file', name='file_upload')
+              .file-path-wrapper
+                input.file-path.validate(type='text', name='file_url')
+
+          .row
+            .input-field.col.s12
+              input#submitter_id.validate(type='hidden', name='submitter_id', value=1)
+
+          .row
+            button#add_project_button.modal-action.modal-close.waves-effect.waves-light.btn.right
+              | Submit VNF
+              i.material-icons.right send
+  #modal2.modal
+    .modal-content
+      h4.center
+        i.material-icons library_add
+        |         Add a TAG
+      .row
+        form#add_tag_form.col.s12(action='/add_tag', method='post')
+          .row.modal-form-row
+            .input-field.col.s12
+              input#tag_name.validate(type='text', name='tag_name')
+              label.left-align(for='tag_name') Name
+          button#add_tag_button.modal-action.modal-close.waves-effect.waves-light.btn.right
+            | Submit TAG
+            i.material-icons.right send
+  #modal3.modal
+      h4.center
+        i.material-icons library_add
+        |         Add a TAG to a VNF
+      .row
+        form#add_vnf_tag_association_form.col.s12(action='/vnf_tag_association', method='post')
+
+          .row.modal-form-row.modal-form-row-custom
+            .input-field.col.s2 VNF Name
+            #scrollable-dropdown-menu.input-field.col.s4
+              input#vnf_name.typeahead(type='text', name='vnf_name')
+              //
+                label.left-align(for='tag_name') VNF Name
+            .input-field.col.s2 TAG Name
+            #scrollable-dropdown-menu.input-field.col.s4
+              input#tag_name.validate.typeahead(type='text', name='tag_name')
+              //
+                label.left-align(for='tag_name') TAG Name
+
+          button#add_vnf_tag_association_button.modal-action.modal-close.waves-effect.waves-light.btn.right
+            | Submit
+            i.material-icons.right send
+  style.
+    .select-dropdown{
+        overflow-y: auto !important;
+    }
+    .dropdown-content {
+        max-height: 200px !important;
+    }
+    .backdrop{
+       background-color: rgb(253,225,109);
+    }
+    .bg {
+    }
+    .modal-form-row-custom {
+      min-height: 200px !important;
+    }
+    #scrollable-dropdown-menu .tt-menu {
+      max-height: 150px;
+      overflow-y: auto;
+    }
+
+    .typeahead, .tt-query, .tt-hint {
+        border: 2px solid #CCCCCC;
+        border-radius: 8px 8px 8px 8px;
+        font-size: 24px;
+        height: 30px;
+        line-height: 30px;
+        outline: medium none;
+        padding: 8px 12px;
+        width: 396px;
+    }
+
+    .tt-query {
+        box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset;
+    }
+    .tt-hint {
+        color: #999999;
+    }
+    .tt-dropdown-menu {
+        background-color: #FFFFFF;
+        border: 1px solid rgba(0, 0, 0, 0.2);
+        border-radius: 8px 8px 8px 8px;
+        box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+        margin-top: 12px;
+        padding: 8px 0;
+        width: 200px;
+    }
+    .tt-suggestion {
+        font-size: 18px;
+        line-height: 24px;
+        padding: 3px 20px;
+    }
+    .tt-suggestion.tt-cursor {
+        background-color: #0097CF;
+        color: #FFFFFF;
+    }
+    .tt-suggestion p {
+        margin: 0;
+    }
+    .tt-dropdown-menu, .gist {
+        text-align: left;
+    }
index e60c3ba..bf0cd14 100644 (file)
@@ -7,10 +7,11 @@ extends layout
   which accompanies this distribution, and is available at
   http://www.apache.org/licenses/LICENSE-2.0
 block content
+  link(rel='stylesheet', href='/stylesheets/3rd_party/bootstrap.css')
   .search-box
     h1 VNF Catalogue
     form.search-form
-      input.search-input(type='text', placeholder='Search...', id='Tags')
+      input.search-input(type='search', placeholder='Search...', id='Tags')
       .space-10
       button.search-button(type='submit', value='Search', id='Search') Search
   .content.content-height-overwrite
index 89142f8..33c09e3 100644 (file)
@@ -9,7 +9,6 @@ html(lang='en')
 html
     head
         title= title
-        link(rel='stylesheet', href='/stylesheets/3rd_party/bootstrap.css')
         link(rel='stylesheet', href='/3rd_party/materialize/css/materialize.css')
         script(type='text/javascript', src='https://code.jquery.com/jquery-3.1.1.min.js')
         script(src='/javascripts/global.js')
@@ -49,5 +48,7 @@ html
                   a(href='#') Sign up
                 li.signin
                   a(href='#') Sign in
+        block search
+        block add_project
         block content
 
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/project_profile.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/project_profile.jade
new file mode 100644 (file)
index 0000000..7b37bd4
--- /dev/null
@@ -0,0 +1,84 @@
+extends layout
+
+//
+  Copyright (c) 2017 Kumar Rishabh 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
+block search
+  include search
+block content
+  .content
+    .container.container-custom
+          .carousel
+            a.carousel-item(href='#one!')
+              img(src='http://lorempixel.com/250/250/nature/1')
+            a.carousel-item(href='#two!')
+              img(src='http://lorempixel.com/250/250/nature/2')
+            a.carousel-item(href='#three!')
+              img(src='http://lorempixel.com/250/250/nature/3')
+            a.carousel-item(href='#four!')
+              img(src='http://lorempixel.com/250/250/nature/4')
+            a.carousel-item(href='#five!')
+              img(src='http://lorempixel.com/250/250/nature/5')
+            .card.card-shadow-custom.horizontal
+            .row.row-custom
+          .col.s5.card-title-div-custom
+            span.card-title.card-title-span-custom Card Title
+          .col.s5.card-title-div-custom
+            i.material-icons grade
+            span.card-title PenguinScore: 42
+          .col.s2.card-title-div-custom-right
+            form(action='#')
+              input#search_result_1(type='checkbox')
+              label(for='search_result_1') Compare
+          //
+            <div class="card-action">
+            <a href="#">This is a link</a>
+            </div>
+          .col.s4.card-image.card-image-custom
+            img.card-image-picture-custom(src='/images/logo.png')
+          .col.s8.card-stacked
+            .card-content
+              p
+                .collection.collection-custom
+                  a.collection-item(href='#!')
+                    span
+                      i.material-icons code
+                      |                             Lines Of Code: 1.03M
+                  a.collection-item(href='#!')
+                    span
+                      i.material-icons code
+                      |                             Lines Of Code: 1.03M
+                  a.collection-item(href='#!')
+                    span
+                      i.material-icons code
+                      |                             Lines Of Code: 1.03M
+                  a.collection-item(href='#!')
+                    span
+                      i.material-icons code
+                      |                             Lines Of Code: 1.03M
+            .card-action
+              | Tags:
+              .chip
+                a.a-custom(href='#!') Tag1
+              .chip
+                a.a-custom(href='#!') Tag2
+              .chip
+                a.a-custom(href='#!') Tag3
+              .chip
+                a.a-custom(href='#!') Tag4
+              .chip
+                a.a-custom(href='#!') Tag5
+              a.a-custom-more(href='#!') more
+          .divider
+          .card-action-custom.col.s12.card-action
+            | License:
+            a(href='#') MIT
+            |                     Complexity:
+            a(href='#') Atomic
+  footer
+    | © 2017 XYZ Company
+    link(rel='stylesheet', href='/stylesheets/search_projects.css')
+
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/search.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/search.jade
new file mode 100644 (file)
index 0000000..77b2488
--- /dev/null
@@ -0,0 +1,5 @@
+.search-box
+    link(rel='stylesheet', href='/stylesheets/search_form.css')
+    .form-group-custom.form-group.has-feedback
+      input.search-input-rest.form-control(type='search', placeholder='Search...', id='Tags')
+      i.material-icons search
\ No newline at end of file
index 6670d21..ac91aa6 100644 (file)
@@ -6,70 +6,78 @@ extends layout
   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
+block search
+  include search
+block add_project
+  include add_project
 block content
-  .search-box
-    .form-group-custom.form-group.has-feedback
-      input.search-input-rest.form-control(type='text', placeholder='Search...', id='Tags')
-      i.material-icons search
   .content
-    .container
-      .card.card-shadow-custom.horizontal
-        .row.row-custom
-          .col.s5.card-title-div-custom
-            span.card-title.card-title-span-custom Card Title
-          .col.s5.card-title-div-custom
-            i.material-icons grade
-            span.card-title PenguinScore: 42
-          .col.s2.card-title-div-custom-right
-            form(action='#')
-              input#search_result_1(type='checkbox')
-              label(for='search_result_1') Compare
-          //
-            <div class="card-action">
-            <a href="#">This is a link</a>
-            </div>
-          .col.s4.card-image
-            img.card-image-picture-custom(src='/images/logo.png')
-          .col.s8.card-stacked
-            .card-content
-              p
-                .collection.collection-custom
-                  a.collection-item(href='#!')
-                    span
-                      i.material-icons code
-                      |                             Lines Of Code: 1.03M
-                  a.collection-item(href='#!')
-                    span
-                      i.material-icons code
-                      |                             Lines Of Code: 1.03M
-                  a.collection-item(href='#!')
-                    span
-                      i.material-icons code
-                      |                             Lines Of Code: 1.03M
-                  a.collection-item(href='#!')
-                    span
-                      i.material-icons code
-                      |                             Lines Of Code: 1.03M
-            .card-action
-              | Tags: 
-              .chip
-                a.a-custom(href='#!') Tag1
-              .chip
-                a.a-custom(href='#!') Tag2
-              .chip
-                a.a-custom(href='#!') Tag3
-              .chip
-                a.a-custom(href='#!') Tag4
-              .chip
-                a.a-custom(href='#!') Tag5
-              a.a-custom-more(href='#!') more
-          .divider
-          .card-action-custom.col.s12.card-action
-            | License: 
-            a(href='#') MIT
-            |                     Complexity: 
-            a(href='#') Atomic
+    each key, index in json
+      .container.container-custom
+        .card.card-shadow-custom.horizontal
+          .row.row-custom
+            .col.s5.card-title-div-custom
+              span.card-title.card-title-span-custom #{key.vnf_name}
+            .col.s5.card-title-div-custom
+              i.material-icons grade
+              span.card-title PenguinScore: 42
+            .col.s2.card-title-div-custom-right
+              form(action='#')
+                input#search_result_1(type='checkbox', name='#{key.vnf_name}')
+                label(for='search_result_1') Compare
+            //
+              <div class="card-action">
+              <a href="#">This is a link</a>
+              </div>
+            .col.s4.card-image.card-image-custom
+              img.card-image-picture-custom(src='/uploads/#{key.photo_url}')
+            .col.s8.card-stacked
+              .card-content
+                p
+                  .collection.collection-custom
+                    a.collection-item(href='#!')
+                      span
+                        i.material-icons code
+                        |                             Lines Of Code: #{key.lines_of_code}
+                    a.collection-item(href='#!')
+                      span
+                        i.material-icons person
+                        |                             Number of Developers: #{key.no_of_developers}
+                    a.collection-item(href='#!')
+                      span
+                        i.material-icons star
+                        |                             Number of Stars: #{key.no_of_stars}
+                    a.collection-item(href='#!')
+                      span
+                        i.material-icons description
+                        |                             Number of Versions: #{key.versions}
+              .card-action
+                | Tags:
+                each tag, index in key.tags
+                  .chip
+                    a.a-custom(href='/search_projects?tags=#{tag.tag_name}') #{tag.tag_name}
+                //
+                  .chip
+                    a.a-custom(href='#!') tag1
+                  .chip
+                    a.a-custom(href='#!') Tag2
+                  .chip
+                    a.a-custom(href='#!') Tag3
+                  .chip
+                    a.a-custom(href='#!') Tag4
+                  .chip
+                    a.a-custom(href='#!') Tag5
+                a.a-custom-more(href='#!') more
+            .divider
+            .card-action-custom.col.s12.card-action
+              | License:
+              a(href='#') #{key.license}
+              | Complexity:
+              a(href='#') Atomic
+              | Activity:
+              a(href='#') Medium
+              | OPNFV Indicator:
+              a(href='#') #{key.opnfv_indicator}
   footer
     | © 2017 XYZ Company
     link(rel='stylesheet', href='/stylesheets/search_projects.css')
-
diff --git a/utils/test/vnfcatalogue/VNF_Catalogue/views/vnf_tag_association.jade b/utils/test/vnfcatalogue/VNF_Catalogue/views/vnf_tag_association.jade
new file mode 100644 (file)
index 0000000..c2e1160
--- /dev/null
@@ -0,0 +1,167 @@
+doctype html
+//
+  Copyright (c) 2017 Kumar Rishabh 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
+html(lang='en')
+html
+  head
+    title= title
+    //
+      link(rel='stylesheet', href='/3rd_party/materialize/css/materialize.css')
+    script(type='text/javascript', src='https://code.jquery.com/jquery-3.1.1.min.js')
+    //
+      script(src='/javascripts/global.js')
+    //
+      script(src='/3rd_party/materialize/js/materialize.js')
+    link(href='https://fonts.googleapis.com/icon?family=Material+Icons', rel='stylesheet')
+    link(rel='stylesheet', href='/stylesheets/style.css')
+    script(src='/3rd_party/typeahead.js')
+    script(src='/javascripts/mode_edit.js')
+  body
+    h4.center
+    i.material-icons library_add
+    |         Add a TAG to a VNF
+    .row
+    form#add_tag_form.col.s12(action='/add_tag', method='post')
+      .row.modal-form-row
+          .input-field.col.s6 VNF Name
+          .input-field.col.s6 TAG Name
+      .row.modal-form-row
+        #scrollable-dropdown-menu.input-field.col.s6
+          input#tag_name.typeahead(type='text', name='tag_name')
+          //
+            label.left-align(for='tag_name') VNF Name
+
+        .input-field.col.s6
+          input#tag_name.validate(type='text', name='vnf_name')
+          //
+            label.left-align(for='tag_name') TAG Name
+      .row.modal-form-row
+          .input-field.col.s6
+          .input-field.col.s6
+      .row.modal-form-row
+      button#add_tag_button.modal-action.modal-close.waves-effect.waves-light.btn.right
+        | Submit
+        i.material-icons.right send
+style.
+  #scrollable-dropdown-menu .tt-menu {
+    max-height: 150px;
+    overflow-y: auto;
+  }
+
+  .typeahead, .tt-query, .tt-hint {
+      border: 2px solid #CCCCCC;
+      border-radius: 8px 8px 8px 8px;
+      font-size: 24px;
+      height: 30px;
+      line-height: 30px;
+      outline: medium none;
+      padding: 8px 12px;
+      width: 396px;
+  }
+  .typeahead {
+      background-color: #FFFFFF;
+  }
+  .typeahead:focus {
+      border: 2px solid #0097CF;
+  }
+  .tt-query {
+      box-shadow: 0 1px 1px rgba(0, 0, 0, 0.075) inset;
+  }
+  .tt-hint {
+      color: #999999;
+  }
+  .tt-dropdown-menu {
+      background-color: #FFFFFF;
+      border: 1px solid rgba(0, 0, 0, 0.2);
+      border-radius: 8px 8px 8px 8px;
+      box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+      margin-top: 12px;
+      padding: 8px 0;
+      width: 422px;
+  }
+  .tt-suggestion {
+      font-size: 18px;
+      line-height: 24px;
+      padding: 3px 20px;
+  }
+  .tt-suggestion.tt-cursor {
+      background-color: #0097CF;
+      color: #FFFFFF;
+  }
+  .tt-suggestion p {
+      margin: 0;
+  }
+  .tt-dropdown-menu, .gist {
+      text-align: left;
+  }
+  /*
+  html {
+      overflow-y: scroll;
+  }
+  .container {
+      margin: 0 auto;
+      max-width: 750px;
+      text-align: center;
+  }
+
+  html {
+      color: #333333;
+      font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;
+      font-size: 18px;
+      line-height: 1.2;
+  }
+  .title, .example-name {
+      font-family: Prociono;
+  }
+  p {
+      margin: 0 0 10px;
+  }
+  .title {
+      font-size: 64px;
+      margin: 20px 0 0;
+  }
+  .example {
+      padding: 30px 0;
+  }
+  .example-name {
+      font-size: 32px;
+      margin: 20px 0;
+  }
+  .demo {
+      margin: 50px 0;
+      position: relative;
+  }
+  */
+  /*
+  .gist {
+      font-size: 14px;
+  }
+  .example-twitter-oss .tt-suggestion {
+      padding: 8px 20px;
+  }
+  .example-twitter-oss .tt-suggestion + .tt-suggestion {
+      border-top: 1px solid #CCCCCC;
+  }
+  .example-twitter-oss .repo-language {
+      float: right;
+      font-style: italic;
+  }
+  .example-twitter-oss .repo-name {
+      font-weight: bold;
+  }
+  .example-twitter-oss .repo-description {
+      font-size: 14px;
+  }
+  .example-sports .league-name {
+      border-bottom: 1px solid #CCCCCC;
+      margin: 0 20px 5px;
+      padding: 3px 0;
+  }
+  .example-arabic .tt-dropdown-menu {
+      text-align: right;
+  }
+  */
index ec20905..a26f6ef 100644 (file)
@@ -11,8 +11,8 @@ var knex = require('knex')({
     client: 'mysql',
     connection: {
         host     : 'localhost',
-        user     : '*',
-        password : '*',
+        user     : 'myuser',
+        password : 'mypassword',
         database : 'vnf_catalogue',
         charset  : 'utf8'
     }