├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jscsrc ├── .jshintrc ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── app ├── elements │ ├── edit-consumer │ │ └── edit-consumer.html │ ├── element-skel │ │ └── element-skel.html │ ├── elements.html │ ├── kui-toolbar │ │ └── kui-toolbar.html │ ├── routing.html │ └── view-api-edit │ │ ├── view-api-edit.css │ │ ├── view-api-edit.css.map │ │ ├── view-api-edit.html │ │ └── view-api-edit.scss ├── favicon.ico ├── images │ └── touch │ │ ├── apple-touch-icon.png │ │ ├── chrome-touch-icon-192x192.png │ │ ├── icon-128x128.png │ │ ├── ms-icon-144x144.png │ │ └── ms-touch-icon-144x144-precomposed.png ├── index.html ├── manifest.json ├── precache.json ├── robots.txt ├── scripts │ └── app.js ├── settings.js.example ├── styles │ ├── app-theme-additional.html │ ├── app-theme.html │ └── main.css ├── sw-import.js └── test │ ├── index.html │ ├── my-greeting-basic.html │ └── my-list-basic.html ├── bower.json ├── docs └── kong-ui-wireframe.jpg ├── gulpfile.js ├── package.json └── wct.conf.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | bower_components 4 | .tmp 5 | test/bower_components/ 6 | .idea 7 | app/settings.js 8 | PRIVATE.md 9 | fixcommits.sh 10 | app/elements/settings.html 11 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "google", 3 | "disallowSpacesInAnonymousFunctionExpression": null, 4 | "excludeFiles": ["node_modules/**"] 5 | } 6 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 2, 11 | "latedef": true, 12 | "noarg": true, 13 | "quotmark": "single", 14 | "undef": true, 15 | "unused": true, 16 | "globals": { 17 | "wrap": true, 18 | "unwrap": true, 19 | "Polymer": true, 20 | "Platform": true, 21 | "page": true, 22 | "app": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing to KONG-UI 2 | 3 | 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # License 2 | 3 | Everything in this repo is BSD style license unless otherwise specified. 4 | 5 | Copyright (c) 2015 Mike Saraf. All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following disclaimer 13 | in the documentation and/or other materials provided with the 14 | distribution. 15 | * Neither the name of KONG-UI nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## KONG-UI 2 | 3 | > A web UI for [KONG](https://github.com/Mashape/kong) (not endorsed or affiliated with Kong or Mashape) 4 | 5 | # This is not ready for use at all! 6 | 7 | > Currently it only reads routes and consumers for a hard coded server. Wait for the 8 | tagged 0.1.0 release. 9 | 10 | ### TODO 11 | 12 | * Ship as a container 13 | * Tests would be cool 14 | * Support all the built-in plugins 15 | * Implement a better plugin system 16 | * Clean up UI 17 | 18 | ## Prerequisites 19 | 20 | * One or more Kong servers. 21 | 22 | ## Getting Started 23 | 24 | > These are temporary options, for version 0.1.0 it will be more practical 25 | 26 | ### Self Proxy 27 | 28 | 1. Clone repo to a dedicated linux server 29 | 2. Install httpd server 30 | 3. Setup / to go to [repo home]/app 31 | 4. Configure /bower_components to go to [repo home]/bower_components 32 | 5. Configure /admin to proxy_pass to your kong server 33 | 6. Copy [repo home]/app/settings.js.example to settings.js and edit server connection 34 | 7. in [repo home] run ```bower install``` 35 | 8. Go to app in browser 36 | 37 | ### Proxy Kong Admin through Kong (So Meta) 38 | 39 | 1. Clone repo to a dedicated linux server 40 | 2. Install httpd server 41 | 3. Setup / to go to [repo home]/app 42 | 4. In repo directory run npm install 43 | 5. In repo directory run bower install 44 | 6. Copy [repo home]/app/settings.js.example to settings.js and edit server connection 45 | 7. Using Admin API, add Admin API as an API 46 | ```Example: curl -X POST --url http://localhost:8001/apis/ -d 'name=kong_managment' -d 'target_url=http://localhost:8001/' -d 'public_dns=localhost' -d 'path=/admin' -d 'strip_path=true'``` 47 | 8. Go to app in browser 48 | 49 | ## Contributing 50 | 51 | #### Contributions After 0.1.0 are welcome! 52 | Docs, code, design stuff, bug reports, unit tests; Anything you think would improve the experience is welcome. 53 | 54 | Eventually specifics will be in [CONTRIBUTING.md](CONTRIBUTING.md) 55 | 56 | ### License 57 | 58 | See [LICENSE.md](LICENSE.md) 59 | 60 | ### Attribution 61 | 62 | Made with [Polymer](https://www.polymer-project.org/1.0/) using the [Polymer Starter Kit](https://github.com/polymerelements/polymer-starter-kit). 63 | -------------------------------------------------------------------------------- /app/elements/edit-consumer/edit-consumer.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 36 | 43 | 44 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /app/elements/element-skel/element-skel.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 19 | 22 | 23 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/elements/elements.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /app/elements/kui-toolbar/kui-toolbar.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 57 | 72 | 73 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /app/elements/routing.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 75 | -------------------------------------------------------------------------------- /app/elements/view-api-edit/view-api-edit.css: -------------------------------------------------------------------------------- 1 | :host { 2 | /*display: block;*/ 3 | width: 100%; 4 | display: flex; 5 | flex-direction: column; 6 | justify-content: flex-start; 7 | flex-wrap: nowrap; } 8 | 9 | kui-toolbar { 10 | flex-grow: 0; 11 | flex-shrink: 0; } 12 | 13 | paper-material { 14 | background-color: #fff; } 15 | 16 | #form { 17 | flex-grow: 1; 18 | flex-shrink: 0; 19 | display: flex; 20 | flex-direction: column; 21 | flex-wrap: nowrap; 22 | justify-content: flex-start; 23 | align-items: center; 24 | align-self: center; 25 | background-color: #fff; 26 | width: 90%; 27 | margin-top: 18px; 28 | padding-top: 10px; 29 | padding-bottom: 10px; 30 | padding-left: 10px; 31 | padding-right: 10px; } 32 | 33 | #form > * { 34 | width: 100%; } 35 | 36 | @media (max-width: 600px) { 37 | h1.paper-font-display1 { 38 | font-size: 24px; } } 39 | 40 | /*# sourceMappingURL=view-api-edit.css.map */ 41 | -------------------------------------------------------------------------------- /app/elements/view-api-edit/view-api-edit.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAA,KAAM;;EAEJ,KAAK,EAAE,IAAI;EAEX,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,MAAM;EACtB,eAAe,EAAE,UAAU;EAC3B,SAAS,EAAE,MAAM;;AAGnB,WAAY;EACV,SAAS,EAAE,CAAC;EACZ,WAAW,EAAE,CAAC;;AAGhB,cAAe;EACb,gBAAgB,EAAE,IAAI;;AAGxB,KAAM;EACJ,SAAS,EAAE,CAAC;EACZ,WAAW,EAAE,CAAC;EAEd,OAAO,EAAC,IAAI;EACZ,cAAc,EAAE,MAAM;EACtB,SAAS,EAAE,MAAM;EACjB,eAAe,EAAE,UAAU;EAC3B,WAAW,EAAE,MAAM;EAEnB,UAAU,EAAE,MAAM;EAClB,gBAAgB,EAAE,IAAI;EAEtB,KAAK,EAAE,GAAG;EACV,UAAU,EAAE,IAAI;EAChB,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,IAAI;EACpB,YAAY,EAAE,IAAI;EAClB,aAAa,EAAE,IAAI;;AAIrB,SAAU;EACR,KAAK,EAAE,IAAI;;AAKb,yBAA0B;EACxB,sBAAuB;IACrB,SAAS,EAAE,IAAI", 4 | "sources": ["view-api-edit.scss"], 5 | "names": [], 6 | "file": "view-api-edit.css" 7 | } -------------------------------------------------------------------------------- /app/elements/view-api-edit/view-api-edit.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 16 | 17 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/elements/view-api-edit/view-api-edit.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | /*display: block;*/ 3 | width: 100%; 4 | 5 | display: flex; 6 | flex-direction: column; 7 | justify-content: flex-start; 8 | flex-wrap: nowrap; 9 | } 10 | 11 | kui-toolbar { 12 | flex-grow: 0; 13 | flex-shrink: 0; 14 | } 15 | 16 | paper-material { 17 | background-color: #fff; 18 | } 19 | 20 | #form { 21 | flex-grow: 1; 22 | flex-shrink: 0; 23 | 24 | display:flex; 25 | flex-direction: column; 26 | flex-wrap: nowrap; 27 | justify-content: flex-start; 28 | align-items: center; 29 | 30 | align-self: center; 31 | background-color: #fff; 32 | 33 | width: 90%; 34 | margin-top: 18px; 35 | padding-top: 10px; 36 | padding-bottom: 10px; 37 | padding-left: 10px; 38 | padding-right: 10px; 39 | 40 | } 41 | 42 | #form > * { 43 | width: 100%; 44 | } 45 | 46 | 47 | 48 | @media (max-width: 600px) { 49 | h1.paper-font-display1 { 50 | font-size: 24px; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msaraf/kong-ui/18334787fcc25a65f585e6eb20843ca1ebbb6fea/app/favicon.ico -------------------------------------------------------------------------------- /app/images/touch/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msaraf/kong-ui/18334787fcc25a65f585e6eb20843ca1ebbb6fea/app/images/touch/apple-touch-icon.png -------------------------------------------------------------------------------- /app/images/touch/chrome-touch-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msaraf/kong-ui/18334787fcc25a65f585e6eb20843ca1ebbb6fea/app/images/touch/chrome-touch-icon-192x192.png -------------------------------------------------------------------------------- /app/images/touch/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msaraf/kong-ui/18334787fcc25a65f585e6eb20843ca1ebbb6fea/app/images/touch/icon-128x128.png -------------------------------------------------------------------------------- /app/images/touch/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msaraf/kong-ui/18334787fcc25a65f585e6eb20843ca1ebbb6fea/app/images/touch/ms-icon-144x144.png -------------------------------------------------------------------------------- /app/images/touch/ms-touch-icon-144x144-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msaraf/kong-ui/18334787fcc25a65f585e6eb20843ca1ebbb6fea/app/images/touch/ms-touch-icon-144x144-precomposed.png -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | KONG UI 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | -------------------------------------------------------------------------------- /app/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "KONG-UI", 3 | "short_name": "KONG-UI", 4 | "icons": [{ 5 | "src": "images/touch/icon-128x128.png", 6 | "sizes": "128x128", 7 | "type": "image/png" 8 | }, { 9 | "src": "images/touch/apple-touch-icon.png", 10 | "sizes": "152x152", 11 | "type": "image/png" 12 | }, { 13 | "src": "images/touch/ms-touch-icon-144x144-precomposed.png", 14 | "sizes": "144x144", 15 | "type": "image/png" 16 | }, { 17 | "src": "images/touch/chrome-touch-icon-192x192.png", 18 | "sizes": "192x192", 19 | "type": "image/png" 20 | }], 21 | "start_url": "/#!/", 22 | "display": "standalone" 23 | } 24 | -------------------------------------------------------------------------------- /app/precache.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /app/robots.txt: -------------------------------------------------------------------------------- 1 | # www.robotstxt.org 2 | 3 | User-agent: * 4 | Disallow: 5 | -------------------------------------------------------------------------------- /app/scripts/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | @license 3 | Copyright (c) 2015 Mike Saraf. All rights reserved. 4 | This code may only be used under the BSD style license found in the included file LICENSE.md 5 | */ 6 | 7 | (function(document) { 8 | 'use strict'; 9 | 10 | // Grab a reference to our auto-binding template 11 | var app = document.querySelector('#app'); 12 | 13 | /*-- Models --*/ 14 | 15 | app.APIModel = function() { 16 | this.id = null; 17 | this.name = ""; 18 | this.public_dns = ""; 19 | this.path = ""; 20 | this.strip_path = false; 21 | this.target_url = ""; 22 | this.preserve_host = false; 23 | this.created_at = ""; 24 | }; 25 | 26 | /*-- Common Data & State vars --*/ 27 | app.drawerSelected = 0; 28 | app.apis; 29 | app.selectedAPI; 30 | 31 | app.consumers; 32 | app.plugins; 33 | 34 | app.addAPI = function(e) { page('/apis/new'); }; 35 | app.addConsumer = function(e) { page('/addConsumer'); }; 36 | 37 | /*-- on-tap methods --*/ 38 | 39 | app.routeChange = function(e) { 40 | var route = e.currentTarget.href.replace(/.*#!/, ""); 41 | console.log("Drawer Menu Selected: " + route); 42 | page(route); 43 | }; 44 | 45 | app.apiListClick = function(e) { 46 | console.log("api clicked: " + e.currentTarget.id); 47 | // Get Item Object 48 | // Clear Editor Container 49 | // Insert new editor container 50 | // Load Item Object 51 | // Display Page 52 | this.selectedAPI = this.apis.data[e.currentTarget.id]; 53 | page("/apis/" + this.apis.data[e.currentTarget.id].name); 54 | }; 55 | 56 | app.consumerListClick = function(e) { 57 | console.log("consumer clicked: " + e.currentTarget.id); 58 | //page("/consumers/" + e.currentTarget.id); 59 | }; 60 | 61 | app.pluginListClick = function(e) { 62 | console.log("plugin clicked: " + e.currentTarget.id); 63 | //page("/plugins/" + e.currentTarget.id); 64 | }; 65 | 66 | /*-- Event Listeners --*/ 67 | window.addEventListener('WebComponentsReady', function() { 68 | // imports are loaded and elements have been registered 69 | app.$.ajaxAPI.url = app.settings.servers[0].address + "/apis"; 70 | app.$.ajaxConsumers.url = app.settings.servers[0].address + "/consumers"; 71 | app.$.ajaxPlugins.url = app.settings.servers[0].address + "/plugins"; 72 | }); 73 | 74 | /*-- Internals Below --*/ 75 | 76 | app.displayInstalledToast = function() { 77 | document.querySelector('#caching-complete').show(); 78 | }; 79 | 80 | // Listen for template bound event to know when bindings 81 | // have resolved and content has been stamped to the page 82 | app.addEventListener('dom-change', function() { 83 | console.log('Our app is ready to rock!'); 84 | 85 | 86 | 87 | }); 88 | 89 | // Main area's paper-scroll-header-panel custom condensing transformation of 90 | // the appName in the middle-container and the bottom title in the bottom-container. 91 | // The appName is moved to top and shrunk on condensing. The bottom sub title 92 | // is shrunk to nothing on condensing. 93 | addEventListener('paper-header-transform', function(e) { 94 | var appName = document.querySelector('.app-name'); 95 | var middleContainer = document.querySelector('.middle-container'); 96 | var bottomContainer = document.querySelector('.bottom-container'); 97 | var detail = e.detail; 98 | var heightDiff = detail.height - detail.condensedHeight; 99 | var yRatio = Math.min(1, detail.y / heightDiff); 100 | var maxMiddleScale = 0.50; // appName max size when condensed. The smaller the number the smaller the condensed size. 101 | var scaleMiddle = Math.max(maxMiddleScale, (heightDiff - detail.y) / (heightDiff / (1-maxMiddleScale)) + maxMiddleScale); 102 | var scaleBottom = 1 - yRatio; 103 | 104 | // Move/translate middleContainer 105 | Polymer.Base.transform('translate3d(0,' + yRatio * 100 + '%,0)', middleContainer); 106 | 107 | // Scale bottomContainer and bottom sub title to nothing and back 108 | Polymer.Base.transform('scale(' + scaleBottom + ') translateZ(0)', bottomContainer); 109 | 110 | // Scale middleContainer appName 111 | Polymer.Base.transform('scale(' + scaleMiddle + ') translateZ(0)', appName); 112 | }); 113 | 114 | // Close drawer after menu item is selected if drawerPanel is narrow 115 | app.onMenuSelect = function() { 116 | var drawerPanel = this.$.paperDrawerPanel; //document.querySelector('#paperDrawerPanel'); 117 | if (drawerPanel.narrow) { 118 | drawerPanel.closeDrawer(); 119 | } 120 | }; 121 | 122 | })(document); 123 | -------------------------------------------------------------------------------- /app/settings.js.example: -------------------------------------------------------------------------------- 1 | window.kongSettings = { 2 | servers : [ 3 | {name:"Internal API", address:"https://api.int.example.com:8001/"}, 4 | {name:"Public API", address:"https://api.example.com:8001/"}, 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /app/styles/app-theme-additional.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 142 | -------------------------------------------------------------------------------- /app/styles/app-theme.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 298 | -------------------------------------------------------------------------------- /app/styles/main.css: -------------------------------------------------------------------------------- 1 | /* 2 | @license 3 | Copyright (c) 2015 Mike Saraf. All rights reserved. 4 | This code may only be used under the BSD style license found in the included file LICENSE.md 5 | */ 6 | 7 | body { 8 | background: #ecf0f1; 9 | font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif; 10 | color: #333; 11 | } 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/sw-import.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 The Polymer Project Authors. All rights reserved. 3 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 4 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 5 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 6 | Code distributed by Google as part of the polymer project is also 7 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 8 | */ 9 | 10 | importScripts('bower_components/platinum-sw/service-worker.js'); 11 | -------------------------------------------------------------------------------- /app/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 16 | Elements Test Runner 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/test/my-greeting-basic.html: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | my-greeting-basic 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /app/test/my-list-basic.html: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | my-list-basic 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "polymer-starter-kit", 3 | "private": true, 4 | "dependencies": { 5 | "iron-elements": "PolymerElements/iron-elements#1.0.0", 6 | "paper-elements": "PolymerElements/paper-elements#1.0.1", 7 | "platinum-elements": "PolymerElements/platinum-elements#1.0.1", 8 | "neon-elements": "PolymerElements/neon-elements#1.0.0", 9 | "page": "visionmedia/page.js#~1.6.3", 10 | "iron-dropdown": "PolymerElements/iron-dropdown#~1.0.1", 11 | "iron-list": "PolymerElements/iron-list#~1.0.1" 12 | }, 13 | "devDependencies": { 14 | "web-component-tester": "*", 15 | "test-fixture": "PolymerElements/test-fixture#^1.0.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /docs/kong-ui-wireframe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msaraf/kong-ui/18334787fcc25a65f585e6eb20843ca1ebbb6fea/docs/kong-ui-wireframe.jpg -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 The Polymer Project Authors. All rights reserved. 3 | This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 4 | The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 5 | The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 6 | Code distributed by Google as part of the polymer project is also 7 | subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 8 | */ 9 | 10 | 'use strict'; 11 | 12 | // Include Gulp & Tools We'll Use 13 | var gulp = require('gulp'); 14 | var $ = require('gulp-load-plugins')(); 15 | var del = require('del'); 16 | var runSequence = require('run-sequence'); 17 | var browserSync = require('browser-sync'); 18 | var reload = browserSync.reload; 19 | var merge = require('merge-stream'); 20 | var path = require('path'); 21 | var fs = require('fs'); 22 | var glob = require('glob'); 23 | var historyApiFallback = require('connect-history-api-fallback'); 24 | 25 | var AUTOPREFIXER_BROWSERS = [ 26 | 'ie >= 10', 27 | 'ie_mob >= 10', 28 | 'ff >= 30', 29 | 'chrome >= 34', 30 | 'safari >= 7', 31 | 'opera >= 23', 32 | 'ios >= 7', 33 | 'android >= 4.4', 34 | 'bb >= 10' 35 | ]; 36 | 37 | var styleTask = function (stylesPath, srcs) { 38 | return gulp.src(srcs.map(function(src) { 39 | return path.join('app', stylesPath, src); 40 | })) 41 | .pipe($.changed(stylesPath, {extension: '.css'})) 42 | .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS)) 43 | .pipe(gulp.dest('.tmp/' + stylesPath)) 44 | .pipe($.if('*.css', $.cssmin())) 45 | .pipe(gulp.dest('dist/' + stylesPath)) 46 | .pipe($.size({title: stylesPath})); 47 | }; 48 | 49 | // Compile and Automatically Prefix Stylesheets 50 | gulp.task('styles', function () { 51 | return styleTask('styles', ['**/*.css']); 52 | }); 53 | 54 | gulp.task('elements', function () { 55 | return styleTask('elements', ['**/*.css']); 56 | }); 57 | 58 | // Lint JavaScript 59 | gulp.task('jshint', function () { 60 | return gulp.src([ 61 | 'app/scripts/**/*.js', 62 | 'app/elements/**/*.js', 63 | 'app/elements/**/*.html' 64 | ]) 65 | .pipe(reload({stream: true, once: true})) 66 | .pipe($.jshint.extract()) // Extract JS from .html files 67 | .pipe($.jshint()) 68 | .pipe($.jshint.reporter('jshint-stylish')) 69 | .pipe($.if(!browserSync.active, $.jshint.reporter('fail'))); 70 | }); 71 | 72 | // Optimize Images 73 | gulp.task('images', function () { 74 | return gulp.src('app/images/**/*') 75 | .pipe($.cache($.imagemin({ 76 | progressive: true, 77 | interlaced: true 78 | }))) 79 | .pipe(gulp.dest('dist/images')) 80 | .pipe($.size({title: 'images'})); 81 | }); 82 | 83 | // Copy All Files At The Root Level (app) 84 | gulp.task('copy', function () { 85 | var app = gulp.src([ 86 | 'app/*', 87 | '!app/test', 88 | '!app/precache.json' 89 | ], { 90 | dot: true 91 | }).pipe(gulp.dest('dist')); 92 | 93 | var bower = gulp.src([ 94 | 'bower_components/**/*' 95 | ]).pipe(gulp.dest('dist/bower_components')); 96 | 97 | var elements = gulp.src(['app/elements/**/*.html']) 98 | .pipe(gulp.dest('dist/elements')); 99 | 100 | var swBootstrap = gulp.src(['bower_components/platinum-sw/bootstrap/*.js']) 101 | .pipe(gulp.dest('dist/elements/bootstrap')); 102 | 103 | var swToolbox = gulp.src(['bower_components/sw-toolbox/*.js']) 104 | .pipe(gulp.dest('dist/sw-toolbox')); 105 | 106 | var vulcanized = gulp.src(['app/elements/elements.html']) 107 | .pipe($.rename('elements.vulcanized.html')) 108 | .pipe(gulp.dest('dist/elements')); 109 | 110 | return merge(app, bower, elements, vulcanized, swBootstrap, swToolbox) 111 | .pipe($.size({title: 'copy'})); 112 | }); 113 | 114 | // Copy Web Fonts To Dist 115 | gulp.task('fonts', function () { 116 | return gulp.src(['app/fonts/**']) 117 | .pipe(gulp.dest('dist/fonts')) 118 | .pipe($.size({title: 'fonts'})); 119 | }); 120 | 121 | // Scan Your HTML For Assets & Optimize Them 122 | gulp.task('html', function () { 123 | var assets = $.useref.assets({searchPath: ['.tmp', 'app', 'dist']}); 124 | 125 | return gulp.src(['app/**/*.html', '!app/{elements,test}/**/*.html']) 126 | // Replace path for vulcanized assets 127 | .pipe($.if('*.html', $.replace('elements/elements.html', 'elements/elements.vulcanized.html'))) 128 | .pipe(assets) 129 | // Concatenate And Minify JavaScript 130 | .pipe($.if('*.js', $.uglify({preserveComments: 'some'}))) 131 | // Concatenate And Minify Styles 132 | // In case you are still using useref build blocks 133 | .pipe($.if('*.css', $.cssmin())) 134 | .pipe(assets.restore()) 135 | .pipe($.useref()) 136 | // Minify Any HTML 137 | .pipe($.if('*.html', $.minifyHtml({ 138 | quotes: true, 139 | empty: true, 140 | spare: true 141 | }))) 142 | // Output Files 143 | .pipe(gulp.dest('dist')) 144 | .pipe($.size({title: 'html'})); 145 | }); 146 | 147 | // Vulcanize imports 148 | gulp.task('vulcanize', function () { 149 | var DEST_DIR = 'dist/elements'; 150 | 151 | return gulp.src('dist/elements/elements.vulcanized.html') 152 | .pipe($.vulcanize({ 153 | stripComments: true, 154 | inlineCss: true, 155 | inlineScripts: true 156 | })) 157 | .pipe(gulp.dest(DEST_DIR)) 158 | .pipe($.size({title: 'vulcanize'})); 159 | }); 160 | 161 | // Generate a list of files that should be precached when serving from 'dist'. 162 | // The list will be consumed by the element. 163 | gulp.task('precache', function (callback) { 164 | var dir = 'dist'; 165 | 166 | glob('{elements,scripts,styles}/**/*.*', {cwd: dir}, function(error, files) { 167 | if (error) { 168 | callback(error); 169 | } else { 170 | files.push('index.html', './', 'bower_components/webcomponentsjs/webcomponents-lite.min.js'); 171 | var filePath = path.join(dir, 'precache.json'); 172 | fs.writeFile(filePath, JSON.stringify(files), callback); 173 | } 174 | }); 175 | }); 176 | 177 | // Clean Output Directory 178 | gulp.task('clean', del.bind(null, ['.tmp', 'dist'])); 179 | 180 | // Watch Files For Changes & Reload 181 | gulp.task('serve', ['styles', 'elements', 'images'], function () { 182 | browserSync({ 183 | notify: false, 184 | logPrefix: 'PSK', 185 | snippetOptions: { 186 | rule: { 187 | match: '', 188 | fn: function (snippet) { 189 | return snippet; 190 | } 191 | } 192 | }, 193 | // Run as an https by uncommenting 'https: true' 194 | // Note: this uses an unsigned certificate which on first access 195 | // will present a certificate warning in the browser. 196 | // https: true, 197 | server: { 198 | baseDir: ['.tmp', 'app'], 199 | middleware: [ historyApiFallback() ], 200 | routes: { 201 | '/bower_components': 'bower_components' 202 | } 203 | } 204 | }); 205 | 206 | gulp.watch(['app/**/*.html'], reload); 207 | gulp.watch(['app/styles/**/*.css'], ['styles', reload]); 208 | gulp.watch(['app/elements/**/*.css'], ['elements', reload]); 209 | gulp.watch(['app/{scripts,elements}/**/*.js'], ['jshint']); 210 | gulp.watch(['app/images/**/*'], reload); 211 | }); 212 | 213 | // Build and serve the output from the dist build 214 | gulp.task('serve:dist', ['default'], function () { 215 | browserSync({ 216 | notify: false, 217 | logPrefix: 'PSK', 218 | snippetOptions: { 219 | rule: { 220 | match: '', 221 | fn: function (snippet) { 222 | return snippet; 223 | } 224 | } 225 | }, 226 | // Run as an https by uncommenting 'https: true' 227 | // Note: this uses an unsigned certificate which on first access 228 | // will present a certificate warning in the browser. 229 | // https: true, 230 | server: 'dist', 231 | middleware: [ historyApiFallback() ] 232 | }); 233 | }); 234 | 235 | // Build Production Files, the Default Task 236 | gulp.task('default', ['clean'], function (cb) { 237 | runSequence( 238 | ['copy', 'styles'], 239 | 'elements', 240 | ['jshint', 'images', 'fonts', 'html'], 241 | 'vulcanize', 242 | cb); 243 | // Note: add , 'precache' , after 'vulcanize', if your are going to use Service Worker 244 | }); 245 | 246 | // Load tasks for web-component-tester 247 | // Adds tasks for `gulp test:local` and `gulp test:remote` 248 | require('web-component-tester').gulp.init(gulp); 249 | 250 | // Load custom tasks from the `tasks` directory 251 | try { require('require-dir')('tasks'); } catch (err) {} 252 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "devDependencies": { 4 | "browser-sync": "^2.7.7", 5 | "connect-history-api-fallback": "^1.1.0", 6 | "del": "^1.1.1", 7 | "glob": "^5.0.6", 8 | "gulp": "^3.8.5", 9 | "gulp-autoprefixer": "^2.1.0", 10 | "gulp-cache": "^0.2.8", 11 | "gulp-changed": "^1.0.0", 12 | "gulp-cssmin": "^0.1.7", 13 | "gulp-flatten": "0.0.4", 14 | "gulp-if": "^1.2.1", 15 | "gulp-imagemin": "^2.2.1", 16 | "gulp-jshint": "^1.6.3", 17 | "gulp-load-plugins": "^0.10.0", 18 | "gulp-minify-html": "^1.0.2", 19 | "gulp-rename": "^1.2.0", 20 | "gulp-replace": "^0.5.3", 21 | "gulp-size": "^1.0.0", 22 | "gulp-uglify": "^1.2.0", 23 | "gulp-useref": "^1.1.2", 24 | "gulp-vulcanize": "^6.0.0", 25 | "jshint-stylish": "^2.0.0", 26 | "merge-stream": "^0.1.7", 27 | "opn": "^1.0.0", 28 | "require-dir": "^0.3.0", 29 | "run-sequence": "^1.0.2", 30 | "vulcanize": ">= 1.4.2", 31 | "web-component-tester": "^3.1.3" 32 | }, 33 | "scripts": { 34 | "test": "gulp test:local", 35 | "start": "gulp serve" 36 | }, 37 | "engines": { 38 | "node": ">=0.10.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /wct.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "suites": ["app/test"] 3 | } 4 | --------------------------------------------------------------------------------