├── .editorconfig ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── EXTENDING.md ├── LICENSE ├── README.md ├── cyclotron-site ├── README.md ├── app │ ├── assets │ │ ├── favicon.ico │ │ └── img │ │ │ ├── browsers │ │ │ ├── chrome_64x64.png │ │ │ ├── firefox_64x64.png │ │ │ ├── internet-explorer-tile_64x64.png │ │ │ └── safari_64x64.png │ │ │ ├── favicon128.png │ │ │ ├── favicon16.png │ │ │ ├── favicon32.png │ │ │ ├── favicon64.png │ │ │ └── logo.svg │ ├── index.pug │ ├── partials │ │ ├── 404.pug │ │ ├── 410.pug │ │ ├── 500.pug │ │ ├── analytics.pug │ │ ├── browserCompat.pug │ │ ├── dashboard.pug │ │ ├── dashboardAnalytics.pug │ │ ├── dashboardHistory.pug │ │ ├── dashboardSidebar.pug │ │ ├── editor │ │ │ ├── dataSource.pug │ │ │ ├── dataSources.pug │ │ │ ├── delete.pug │ │ │ ├── details.pug │ │ │ ├── encryptString.pug │ │ │ ├── guiEditor.pug │ │ │ ├── hash.pug │ │ │ ├── inlineArray.pug │ │ │ ├── jsonEditor.pug │ │ │ ├── objectArray.pug │ │ │ ├── page.pug │ │ │ ├── pages.pug │ │ │ ├── parameter.pug │ │ │ ├── parameters.pug │ │ │ ├── propertySet.pug │ │ │ ├── pushDashboard.pug │ │ │ ├── script.pug │ │ │ ├── scripts.pug │ │ │ ├── stringArray.pug │ │ │ ├── style.pug │ │ │ ├── styles.pug │ │ │ └── widget.pug │ │ ├── export.pug │ │ ├── footer.pug │ │ ├── header.pug │ │ ├── help.pug │ │ ├── help │ │ │ ├── 3rdparty.pug │ │ │ ├── about.pug │ │ │ ├── analytics.pug │ │ │ ├── api.pug │ │ │ ├── browserCompat.pug │ │ │ ├── collapseMenu.pug │ │ │ ├── cyclotrondata.pug │ │ │ ├── dashboards.pug │ │ │ ├── dataSources.pug │ │ │ ├── datasources │ │ │ │ ├── cloudwatch.pug │ │ │ │ ├── cyclotronData.pug │ │ │ │ ├── elasticsearch.pug │ │ │ │ ├── graphite.pug │ │ │ │ ├── influxdb.pug │ │ │ │ ├── javascript.pug │ │ │ │ ├── json.pug │ │ │ │ ├── mock.pug │ │ │ │ ├── prometheus.pug │ │ │ │ └── splunk.pug │ │ │ ├── encryptedStrings.pug │ │ │ ├── examples.pug │ │ │ ├── hotkeys.pug │ │ │ ├── javascriptApi.pug │ │ │ ├── json.pug │ │ │ ├── layout.pug │ │ │ ├── pages.pug │ │ │ ├── parameters.pug │ │ │ ├── permissions.pug │ │ │ ├── propertyTable.pug │ │ │ ├── quickstart.pug │ │ │ ├── scripts.pug │ │ │ ├── styles.pug │ │ │ └── widgets.pug │ │ ├── home.pug │ │ ├── login.pug │ │ ├── newUserMessage.pug │ │ ├── revisionDiff.pug │ │ ├── sidebarAccordion.pug │ │ ├── sidebarAccordionGroup.pug │ │ ├── viewPermissionDenied.pug │ │ ├── widget.pug │ │ └── widgetError.pug │ ├── scripts │ │ ├── common │ │ │ ├── app.coffee │ │ │ ├── controller.genericErrorModal.coffee │ │ │ ├── controller.login.coffee │ │ │ ├── directives │ │ │ │ ├── directives.fullscreen.coffee │ │ │ │ ├── directives.requiresAuth.coffee │ │ │ │ ├── directives.requiresLogin.coffee │ │ │ │ └── directives.spinjs.coffee │ │ │ ├── mixins.coffee │ │ │ └── services │ │ │ │ ├── services.aceService.js │ │ │ │ ├── services.analytics.coffee │ │ │ │ ├── services.commonConfigService.coffee │ │ │ │ ├── services.cryptoService.coffee │ │ │ │ ├── services.dashboardService.coffee │ │ │ │ ├── services.focusService.coffee │ │ │ │ ├── services.loadService.coffee │ │ │ │ ├── services.logService.coffee │ │ │ │ └── services.userService.coffee │ │ ├── config │ │ │ └── sample.configService.coffee │ │ ├── dashboards │ │ │ ├── controller.dashboard.coffee │ │ │ ├── dataSources │ │ │ │ ├── dataSources.cloudwatch.coffee │ │ │ │ ├── dataSources.cyclotronData.coffee │ │ │ │ ├── dataSources.elasticsearch.coffee │ │ │ │ ├── dataSources.factory.coffee │ │ │ │ ├── dataSources.graphite.coffee │ │ │ │ ├── dataSources.influxdb.coffee │ │ │ │ ├── dataSources.javascript.coffee │ │ │ │ ├── dataSources.json.coffee │ │ │ │ ├── dataSources.mock.coffee │ │ │ │ ├── dataSources.prometheus.coffee │ │ │ │ └── dataSources.splunk.coffee │ │ │ ├── directives │ │ │ │ ├── directives.dashboard.coffee │ │ │ │ ├── directives.dashboardPage.coffee │ │ │ │ ├── directives.dashboardSidebar.coffee │ │ │ │ ├── directives.dashboardWidget.coffee │ │ │ │ ├── directives.datetimepicker.coffee │ │ │ │ ├── directives.sidebarAccordion.coffee │ │ │ │ ├── directives.widget.coffee │ │ │ │ ├── directives.widgetBody.coffee │ │ │ │ └── directives.widgetError.coffee │ │ │ └── services │ │ │ │ ├── services.cyclotronDataService.coffee │ │ │ │ ├── services.dashboardOverridesService.coffee │ │ │ │ ├── services.dataService.coffee │ │ │ │ ├── services.downloadService.coffee │ │ │ │ ├── services.layoutService.coffee │ │ │ │ └── services.parameterService.coffee │ │ ├── ie8.coffee │ │ └── mgmt │ │ │ ├── controller.analytics.coffee │ │ │ ├── controller.dashboardAnalytics.coffee │ │ │ ├── controller.dashboardHistory.coffee │ │ │ ├── controller.dataSourceEditor.coffee │ │ │ ├── controller.deleteDashboard.coffee │ │ │ ├── controller.encryptString.coffee │ │ │ ├── controller.export.coffee │ │ │ ├── controller.genericErrorModal.coffee │ │ │ ├── controller.guiEditor.coffee │ │ │ ├── controller.help.coffee │ │ │ ├── controller.home.coffee │ │ │ ├── controller.pageEditor.coffee │ │ │ ├── controller.pushDashboard.coffee │ │ │ ├── directives │ │ │ ├── directives.c3chart.coffee │ │ │ ├── directives.collapseMenu.coffee │ │ │ ├── directives.editor.propertySet.coffee │ │ │ ├── directives.editor.view.hash.coffee │ │ │ ├── directives.editor.view.inlineArray.coffee │ │ │ ├── directives.editor.view.objectArray.coffee │ │ │ ├── directives.editor.view.stringArray.coffee │ │ │ ├── directives.error.coffee │ │ │ ├── directives.focusOn.coffee │ │ │ ├── directives.jsonedit.coffee │ │ │ ├── directives.metricsGraphics.coffee │ │ │ ├── directives.newUserMessage.coffee │ │ │ └── directives.propertyTable.coffee │ │ │ └── services │ │ │ ├── services.exportService.coffee │ │ │ └── services.tagService.coffee │ ├── styles │ │ ├── _widgets.less │ │ ├── common │ │ │ ├── alertify.theme.less │ │ │ ├── login.less │ │ │ ├── main.less │ │ │ └── variables.less │ │ ├── dashboards │ │ │ ├── _sidebar.less │ │ │ └── dashboard.less │ │ ├── mgmt │ │ │ ├── analytics.less │ │ │ ├── dashboardHistory.less │ │ │ ├── errors.less │ │ │ ├── export.less │ │ │ ├── guiEditor.less │ │ │ ├── header.less │ │ │ ├── help.less │ │ │ └── home.less │ │ └── themes │ │ │ ├── charcoal.less │ │ │ ├── dark.less │ │ │ ├── dark2.less │ │ │ ├── darkmetro.less │ │ │ ├── gto.less │ │ │ ├── light.less │ │ │ └── lightborderless.less │ └── widgets │ │ ├── annotationChart │ │ ├── _annotationChart.less │ │ ├── addAnnotation.pug │ │ ├── annotationChart.pug │ │ ├── annotationChartWidget.coffee │ │ └── help.pug │ │ ├── chart │ │ ├── _chart.less │ │ ├── chart.pug │ │ ├── chartWidget.coffee │ │ ├── directives.highchart.coffee │ │ └── help.pug │ │ ├── clock │ │ ├── _clock.less │ │ ├── clock.pug │ │ ├── clockWidget.coffee │ │ └── help.pug │ │ ├── header │ │ ├── _header.less │ │ ├── directives.headerParameter.coffee │ │ ├── header.pug │ │ ├── headerParameter.pug │ │ ├── headerWidget.coffee │ │ └── help.pug │ │ ├── html │ │ ├── _html.less │ │ ├── directives.htmlRepeater.coffee │ │ ├── help.pug │ │ ├── html.pug │ │ └── htmlWidget.coffee │ │ ├── iframe │ │ ├── _iframe.less │ │ ├── directives.iframerefresh.coffee │ │ ├── help.pug │ │ ├── iframe.pug │ │ └── iframeWidget.coffee │ │ ├── image │ │ ├── _image.less │ │ ├── directives.fancyImage.coffee │ │ ├── help.pug │ │ ├── image.pug │ │ └── imageWidget.coffee │ │ ├── javascript │ │ ├── _javascript.less │ │ ├── directives.jsContainer.coffee │ │ ├── help.pug │ │ ├── javascript.pug │ │ └── javascriptWidget.coffee │ │ ├── json │ │ ├── _json.less │ │ ├── help.pug │ │ ├── json.pug │ │ └── jsonWidget.coffee │ │ ├── linkedWidget │ │ └── help.pug │ │ ├── number │ │ ├── _number.less │ │ ├── directives.theNumber.coffee │ │ ├── help.pug │ │ ├── number.pug │ │ └── numberWidget.coffee │ │ ├── qrcode │ │ ├── _qrcode.less │ │ ├── directives.qrcode.coffee │ │ ├── help.pug │ │ ├── qrcode.pug │ │ └── qrcodeWidget.coffee │ │ ├── stoplight │ │ ├── _stoplight.less │ │ ├── directives.trafficlight.coffee │ │ ├── help.pug │ │ ├── stoplight.pug │ │ └── stoplightWidget.coffee │ │ ├── table │ │ ├── _table.less │ │ ├── directives.tableColumn.coffee │ │ ├── directives.tableFixedHeader.coffee │ │ ├── directives.tableRow.coffee │ │ ├── directives.tableRule.coffee │ │ ├── help.pug │ │ ├── table.pug │ │ └── tableWidget.coffee │ │ ├── tableau │ │ ├── _tableau.less │ │ ├── directives.tableauPlaceholder.coffee │ │ ├── help.pug │ │ ├── tableau.pug │ │ └── tableauWidget.coffee │ │ ├── treemap │ │ ├── _treemap.less │ │ ├── directives.treemap.coffee │ │ ├── help.pug │ │ ├── treemap.pug │ │ └── treemapWidget.coffee │ │ └── youtube │ │ ├── _youtube.less │ │ ├── help.pug │ │ ├── youtube.pug │ │ └── youtubeWidget.coffee ├── bower.json ├── gulpfile.coffee ├── nginx.conf ├── package-lock.json ├── package.json ├── test │ ├── karma-unit.conf.coffee │ └── unit │ │ ├── dashboardService-spec.coffee │ │ ├── dataService-spec.coffee │ │ ├── layoutService-spec.coffee │ │ ├── mixins-compile-spec.coffee │ │ ├── mixins-executeFunctionByName-spec.coffee │ │ ├── mixins-flattenObject-spec.coffee │ │ ├── mixins-jseval-spec.coffee │ │ ├── mixins-jsexec-spec.coffee │ │ ├── mixins-slugify-spec.coffee │ │ ├── mixins-spec.coffee │ │ ├── mixins-valsub-spec.coffee │ │ └── mixins-varsub-spec.coffee └── vendor │ ├── bootstrap │ ├── LICENSE │ ├── README.md │ ├── _alerts.less │ ├── _badges.less │ ├── _breadcrumbs.less │ ├── _button-groups.less │ ├── _buttons.less │ ├── _carousel.less │ ├── _close.less │ ├── _code.less │ ├── _component-animations.less │ ├── _dropdowns.less │ ├── _forms.less │ ├── _glyphicons.less │ ├── _grid.less │ ├── _input-groups.less │ ├── _jumbotron.less │ ├── _labels.less │ ├── _list-group.less │ ├── _media.less │ ├── _mixins.less │ ├── _modals.less │ ├── _navbar.less │ ├── _navs.less │ ├── _normalize.less │ ├── _pager.less │ ├── _pagination.less │ ├── _panels.less │ ├── _popovers.less │ ├── _print.less │ ├── _progress-bars.less │ ├── _responsive-utilities.less │ ├── _scaffolding.less │ ├── _tables.less │ ├── _theme.less │ ├── _thumbnails.less │ ├── _tooltip.less │ ├── _type.less │ ├── _utilities.less │ ├── _variables.less │ ├── _wells.less │ └── bootstrap.less │ ├── lesselements │ ├── LICENSE │ ├── README.md │ └── _elements.less │ └── modernizr │ ├── LICENSE │ ├── README.md │ └── modernizr.js └── cyclotron-svc ├── .gitignore ├── README.md ├── app.js ├── config ├── elasticsearch-datasources-template.json ├── elasticsearch-events-template.json ├── elasticsearch-pageviews-template.json └── sample.config.js ├── elastic-migration.js ├── elastic.js ├── examples ├── example-annotation-chart.json ├── example-chart-columnbar.json ├── example-chart-drilldown.json ├── example-chart-line.json ├── example-chart-pie.json ├── example-clock.json ├── example-datasource-graphite.json ├── example-datasource-javascript.json ├── example-datasource-json.json ├── example-filters-sort.json ├── example-header.json ├── example-html.json ├── example-iframe.json ├── example-image.json ├── example-json-widget.json ├── example-london.json ├── example-number.json ├── example-portal.json ├── example-qrcode.json ├── example-stoplight.json ├── example-table-basic.json ├── example-table-rules.json ├── example-treemap.json └── example-youtube.json ├── init.d └── cyclotron-svc ├── middleware ├── cors.js └── session.js ├── mongo.js ├── package-lock.json ├── package.json ├── pdfexport.js ├── routes ├── api.analytics-elasticsearch.js ├── api.analytics.js ├── api.crypto.js ├── api.dashboards.js ├── api.data.js ├── api.exports.js ├── api.js ├── api.ldap.js ├── api.proxy.js ├── api.revisions.js ├── api.statistics-elasticsearch.js ├── api.statistics.js ├── api.tags.js ├── api.users.js └── auth.js └── swagger.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | indent_size = 4 13 | max_line_length = off 14 | trim_trailing_whitespace = false 15 | 16 | [*.json] 17 | indent_size = 2 18 | max_line_length = off 19 | trim_trailing_whitespace = false 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Bower 2 | bower_components 3 | 4 | # Build 5 | _public 6 | 7 | # Karma: Coverage 8 | coverage/ 9 | coverage-PhantomJS* 10 | 11 | # Maven 12 | log/ 13 | target/ 14 | 15 | # Node.js 16 | npm-debug.log 17 | node_modules 18 | 19 | # Sublime Text 20 | *.sublime-* 21 | /bin 22 | 23 | # Eclipse 24 | .classpath 25 | .project 26 | .metadata 27 | .settings/ 28 | 29 | # Intellij 30 | .idea/ 31 | *.iml 32 | *.iws 33 | 34 | # Mac 35 | .DS_Store 36 | 37 | *.diff 38 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Cyclotron 2 | 3 | If you'd like to contribute a feature or bug fix, you can [fork](https://help.github.com/articles/fork-a-repo/) Cyclotron, commit your changes, & [send a pull request](https://help.github.com/articles/using-pull-requests/). 4 | 5 | Refer to [EXTENDING.md](EXTENDING.md) for technical information about adding Data Sources, Widgets, etc. 6 | 7 | ## Issues 8 | 9 | Please search the issue tracker before submitting a new issue, in case your issue has already been reported or fixed. 10 | 11 | When opening an issue, please include as much information as possible, including the version of the code, browser version, any JavaScript errors, etc. 12 | 13 | ## Tests 14 | 15 | Before submitting a pull request that makes changes to the website, please rerun the automated tests to ensure they still work: 16 | 17 | gulp test 18 | 19 | Pull requests to add more tests are always welcome! 20 | 21 | ## Coding Guidelines 22 | 23 | In addition to the following guidelines, please follow the established code style and formatting: 24 | 25 | - **Spacing**:
26 | Use four spaces for indentation. No tabs. 27 | 28 | - **Naming**:
29 | Keep variable & method names concise & descriptive.
30 | 31 | - **Quotes**:
32 | Single-quoted strings are preferred to double-quoted strings; however, please use a double-quoted string if the value contains a single-quote character to avoid unnecessary escaping. 33 | 34 | - **Comments**:
35 | Cyclotron-svc uses /* */ for comments rather than //. Cyclotron-site is written in CoffeeScript, so it uses # for comments. 36 | 37 | - **CoffeeScript**:
38 | Cyclotron-site is written in CoffeeScript, and as such uses many of its conventions. However, optional elements like parentheses and return statements should be included when omitting them may lead to confusion. 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2018 the original author or authors. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /cyclotron-site/app/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpediaGroup/cyclotron/0228db71d84a3138a9ffddb50d8f4f8ff37cc5ab/cyclotron-site/app/assets/favicon.ico -------------------------------------------------------------------------------- /cyclotron-site/app/assets/img/browsers/chrome_64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpediaGroup/cyclotron/0228db71d84a3138a9ffddb50d8f4f8ff37cc5ab/cyclotron-site/app/assets/img/browsers/chrome_64x64.png -------------------------------------------------------------------------------- /cyclotron-site/app/assets/img/browsers/firefox_64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpediaGroup/cyclotron/0228db71d84a3138a9ffddb50d8f4f8ff37cc5ab/cyclotron-site/app/assets/img/browsers/firefox_64x64.png -------------------------------------------------------------------------------- /cyclotron-site/app/assets/img/browsers/internet-explorer-tile_64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpediaGroup/cyclotron/0228db71d84a3138a9ffddb50d8f4f8ff37cc5ab/cyclotron-site/app/assets/img/browsers/internet-explorer-tile_64x64.png -------------------------------------------------------------------------------- /cyclotron-site/app/assets/img/browsers/safari_64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpediaGroup/cyclotron/0228db71d84a3138a9ffddb50d8f4f8ff37cc5ab/cyclotron-site/app/assets/img/browsers/safari_64x64.png -------------------------------------------------------------------------------- /cyclotron-site/app/assets/img/favicon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpediaGroup/cyclotron/0228db71d84a3138a9ffddb50d8f4f8ff37cc5ab/cyclotron-site/app/assets/img/favicon128.png -------------------------------------------------------------------------------- /cyclotron-site/app/assets/img/favicon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpediaGroup/cyclotron/0228db71d84a3138a9ffddb50d8f4f8ff37cc5ab/cyclotron-site/app/assets/img/favicon16.png -------------------------------------------------------------------------------- /cyclotron-site/app/assets/img/favicon32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpediaGroup/cyclotron/0228db71d84a3138a9ffddb50d8f4f8ff37cc5ab/cyclotron-site/app/assets/img/favicon32.png -------------------------------------------------------------------------------- /cyclotron-site/app/assets/img/favicon64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpediaGroup/cyclotron/0228db71d84a3138a9ffddb50d8f4f8ff37cc5ab/cyclotron-site/app/assets/img/favicon64.png -------------------------------------------------------------------------------- /cyclotron-site/app/index.pug: -------------------------------------------------------------------------------- 1 | doctype 2 | html(lang='en', ng-app='cyclotronApp', ng-strict-di='') 3 | head 4 | title(ng-bind='$root.page_title') 5 | meta(http-equiv='X-UA-Compatible', content='IE=edge,chrome=1') 6 | meta(charset='utf-8') 7 | meta(name='viewport', content='width=device-width, initial-scale=1.0') 8 | meta(name='description', content='Cyclotron') 9 | meta(name='keywords', content='Cyclotron dashboards dashboard Expedia') 10 | meta(name='author', content='Dave Bauman ') 11 | meta(http-equiv='ClearType', content='on') 12 | 13 | link(rel='icon', type='image/png' href='/img/favicon16.png' sizes='16x16') 14 | link(rel='icon', type='image/png' href='/img/favicon32.png' sizes='32x32') 15 | link(rel='stylesheet', href='/css/vendor.css') 16 | link(rel='stylesheet', href='/css/app.common.css') 17 | 18 | 19 | //- Application Scripts 20 | script(src='/js/vendor.js') 21 | script(src='/js/app.common.js') 22 | script(src='/js/conf/configService.js') 23 | 24 | 25 | body.ng-cloak 26 | include partials/browserCompat 27 | 28 | section#appcontents(ui-view) 29 | 30 | 31 | 34 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/404.pug: -------------------------------------------------------------------------------- 1 | .modal-header 2 | h3.modal-title 3 | i.fa.fa-exclamation-triangle 4 | | Dashboard Not Found 5 | 6 | .modal-body 7 | p The Dashboard you're looking for does not exist. 8 | | Double-check the URL, or go to the home page and search for it. 9 | 10 | .modal-footer 11 | button.btn.btn-primary(ng-click='goHome()') 12 | i.fa.fa-home 13 | span Home 14 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/410.pug: -------------------------------------------------------------------------------- 1 | .modal-header 2 | h3.modal-title 3 | i.fa.fa-trash-o 4 | | Deleted Dashboard 5 | 6 | .modal-body 7 | p The Dashboard you're looking for has been deleted. 8 | | It can be undeleted in the Dashboard Editor. 9 | 10 | .modal-footer 11 | button.btn(ng-click='goEditor()') 12 | i.fa.fa-pencil-square-o 13 | span Edit 14 | button.btn.btn-primary(ng-click='goHome()') 15 | i.fa.fa-home 16 | span Home 17 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/500.pug: -------------------------------------------------------------------------------- 1 | .modal-header 2 | h3.modal-title 3 | i.fa.fa-exclamation-triangle 4 | | Internal Server Error 5 | 6 | .modal-body 7 | div(ng-show='hasError') 8 | p Something went wrong: 9 | p {{ errorMessage }} 10 | div(ng-hide='hasError') 11 | p Something went wrong. 12 | 13 | p Please try again, or contact support for assistance. 14 | 15 | .modal-footer 16 | button.btn(ng-click='reload()') 17 | i.fa.fa-refresh 18 | span Reload 19 | button.btn.btn-primary(ng-click='goHome()') 20 | i.fa.fa-home 21 | span Home 22 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/browserCompat.pug: -------------------------------------------------------------------------------- 1 | #browserError.hidden 2 | h1 Incompatible Browser 3 | p. 4 | Sorry, the browser you are using is not currently supported. This website 5 | uses modern web development capabilities that are not compatible with your 6 | current browser. 7 | p. 8 | Please upgrade to the latest version of your preferred browser. 9 | 10 | table 11 | tr 12 | td 13 | a(href='//www.mozilla.org/en-US/firefox/new/', title='Firefox') 14 | img(src='/img/browsers/firefox_64x64.png') 15 | td 16 | a(href='//www.google.com/chrome/browser/', title='Chrome') 17 | img(src='/img/browsers/chrome_64x64.png') 18 | td 19 | a(href='//www.apple.com/safari/', title='Safari') 20 | img(src='/img/browsers/safari_64x64.png') 21 | td 22 | a(href='//microsoft.com/ie', title='Internet Explorer 11') 23 | img(src='/img/browsers/internet-explorer-tile_64x64.png') 24 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/dashboard.pug: -------------------------------------------------------------------------------- 1 | 2 | .dashboard.dashboard-page-background(ng-class='{ "has-sidebar": dashboard.sidebar.showDashboardSidebar }') 3 | 4 | .click-cover 5 | 6 | include dashboardSidebar 7 | 8 | .dashboard-controls(ng-hide='dashboard.showDashboardControls == false') 9 | i.fa.fa-chevron-left(ng-click='moveBack()', ng-class='{ disabled: !canMoveBack() }', title='Go to the previous page') 10 | i.fa.fa-pause(ng-click='pause()', ng-show='!paused', title='Pause Dashboard page rotation') 11 | i.fa.fa-play(ng-click='play()', ng-show='paused', ng-class='{ disabled: !canMoveForward() }', title='Start Dashboard page rotation') 12 | a.fa.fa-download(ng-href='{{ exportUrl }}', target='_blank', title='Export the Dashboard') 13 | i.fa.fa-star-o(requires-auth, ng-if='!isLiked', ng-click='toggleLike()', title='Star this Dashboard') 14 | i.fa.fa-star(requires-auth, ng-if='isLiked', ng-click='toggleLike()', title='Unstar this Dashboard') 15 | i.fa.fa-chevron-right(ng-click='moveForward()', ng-class='{ disabled: !canMoveForward() }', title='Go to the next page') 16 | 17 | .dashboard-pages 18 | dashboard-page(ng-repeat='page in currentPage', 19 | dashboard='dashboard', page='page', page-number='{{ currentPageIndex }}', 20 | page-overrides='dashboardOverrides.pages[currentPageIndex]') 21 | 22 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/dataSource.pug: -------------------------------------------------------------------------------- 1 | .editor-view-header 2 | h3 {{ getDataSourceName(dataSource) }} 3 | 4 | .editor-view-header-buttons 5 | button#editor-dataSource-remove.btn.btn-default(type='button', ng-click='removeDataSource(dataSourceIndex); goToSubState("edit.dataSources", editor.dashboard.dataSources)', title='Remove') 6 | i.fa.fa-times 7 | span Remove Data Source 8 | 9 | 10 | .form-group 11 | label(title='{{ dashboardProperties.dataSources.properties.type.description }}') Type 12 | select.form-control(ng-model='dataSource.type', title='{{ dashboardProperties.dataSources.properties.type.description }}', 13 | ng-options='optionKey as (optionValue.label || optionKey) for (optionKey, optionValue) in dashboardProperties.dataSources.options') 14 | 15 | .bg-info(ng-if='dataSourceMessage()', ng-bind-html='dataSourceMessage()') 16 | 17 | .bg-danger(ng-if='isDuplicateDataSourceName(dataSource)') 18 | | The Data Source name must be unique to the Dashboard. 19 | 20 | .editor-property-set(model='dataSource', definition='combinedDataSourceProperties(dataSource)', ng-if='dataSource.type') 21 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/dataSources.pug: -------------------------------------------------------------------------------- 1 | .editor-view-header 2 | h3 Data Sources 3 | 4 | .editor-view-header-buttons 5 | button#editor-dataSources-add.btn.btn-primary(type='button', ng-click='newDataSource()', title='Add New Data Source') 6 | i.fa.fa-plus 7 | span Add Data Source 8 | 9 | editor-view-object-array(model='editor.dashboard.dataSources', label='Data Source', 10 | substate='edit.dataSource', headingfn='getDataSourceName(item)') 11 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/delete.pug: -------------------------------------------------------------------------------- 1 | .login-modal 2 | .modal-header 3 | h3.modal-title Delete Dashboard 4 | 5 | .modal-body 6 | p Are you sure you want to delete this dashboard: 7 | 8 | p 9 | strong {{ dashboardName }} 10 | 11 | .modal-footer 12 | button.btn(ng-click='$dismiss("cancel")') Cancel 13 | button.btn.btn-primary(ng-click='$close("ok")') Delete 14 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/encryptString.pug: -------------------------------------------------------------------------------- 1 | .modal-header 2 | h3.modal-title Encrypt String 3 | 4 | .modal-body 5 | p This dialog encrypts a plaintext string. The encrypted form can be copied and used in certain Data Source properties. 6 | p 7 | p This encryption is one-way, and the original value cannot be retrieved from Cyclotron. Store it externally if needed. 8 | p 9 | form(ng-submit='encrypt()') 10 | 11 | p 12 | input.superwide(type='value', ng-model='fields.value', placeholder='Original String') 13 | div.centered 14 | p 15 | button.btn.btn-primary#editor-encrypt-encrypt(ng-click='encrypt()') Encrypt 16 | p 17 | input.superwide(type='value', ng-model='fields.encryptedValue', placeholder='Encrypted String') 18 | 19 | //- Hidden input for ng-submit to work 20 | input(type='submit', style='position: absolute; left: -9999px') 21 | 22 | .modal-footer 23 | button.btn#editor-encrypt-cancel(ng-click='cancel()') Close 24 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/hash.pug: -------------------------------------------------------------------------------- 1 | .well.well-sm 2 | .form-group#editor-hash-item(ng-repeat='hashItem in hashItems track by $index') 3 | input#editor-hash-key.form-control.inline(ng-model='hashItem.key', ng-change='updateHashKey(hashItem)', placeholder='key') 4 | input#editor-hash-value.form-control.inline(ng-model='hashItem.value', ng-change='updateHashValue(hashItem)', placeholder='value') 5 | i#editor-hash-remove.inline-delete-icon.fa.fa-times(ng-click='removeHashItem(hashItem)', title='Remove this item') 6 | 7 | .horizontal-add.button-group 8 | button#editor-hash-add.btn.btn-default(type='button', ng-click='addHashValue()', title='Add {{ label }}') 9 | i.fa.fa-plus 10 | span Add {{ label }} 11 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/inlineArray.pug: -------------------------------------------------------------------------------- 1 | uib-accordion(close-others='true') 2 | uib-accordion-group(ng-repeat='item in model', heading='{{ definition.singleLabel }} {{ $index }}') 3 | 4 | div(ng-transclude='parent') 5 | 6 | .button-group 7 | button#editor-list-remove.btn.btn-default(type='button', ng-click='removeItem($index)', title='Remove') 8 | i.fa.fa-times 9 | span Remove {{ definition.singleLabel }} 10 | 11 | p.text-muted(ng-if='model.length == 0') 12 | | There are no {{ definition.singleLabel }}s 13 | 14 | .horizontal-add.button-group 15 | button#editor-list-add.btn.btn-default(type='button', ng-click='addNewObject()', title='Add New {{ definition.singleLabel }}') 16 | i.fa.fa-plus 17 | span Add {{ definition.singleLabel }} 18 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/jsonEditor.pug: -------------------------------------------------------------------------------- 1 | .editor-view-header 2 | h3 JSON Editor 3 | 4 | .editor-view-header-buttons 5 | a#editor-jsonEditor-return(ng-show='$state.name=="edit.json"', ng-click='returnFromJsonEditor()') 6 | button.btn.btn-default 7 | i.fa.fa-reply 8 | | Return 9 | 10 | .editor-json 11 | div(jsonedit, model='editor.selectedItem') 12 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/objectArray.pug: -------------------------------------------------------------------------------- 1 | div 2 | ul.list-group(dnd-list='model') 3 | li.list-group-item(ng-repeat='item in model', 4 | dnd-draggable='item' 5 | dnd-moved='model.splice($index, 1)' 6 | dnd-effect-allowed='move') 7 | 8 | .clearfix 9 | span.icon 10 | i.fa.fa-bars 11 | 12 | span.object-array-name(ng-click='goToSubState(substate, item, $index)', title='Edit this {{ label }}') 13 | | {{ headingfn({item: item, index: $index, label: label}) }} 14 | 15 | span.button-group.pull-right 16 | 17 | button#clone.btn.btn-default(type='button', ng-click='cloneItem($index)', title='Clone {{ label }}') 18 | i.fa.fa-copy 19 | span Clone 20 | 21 | button#remove.btn.btn-default(type='button', ng-click='removeItem($index)', title='Remove {{ label }}') 22 | i.fa.fa-times 23 | span Remove 24 | 25 | div(ng-transclude='parent') 26 | 27 | p.text-muted(ng-if='model.length == 0') 28 | | There are no {{ label }}s in this Dashboard 29 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/page.pug: -------------------------------------------------------------------------------- 1 | .editor-view-header 2 | h3 {{ getPageName(editor.selectedPage, editor.selectedPageIndex) }} 3 | 4 | .editor-view-header-buttons 5 | button#editor-widgets-add.btn.btn-primary(type='button', ng-click='newWidget(null, editor.selectedPageIndex)', title='Add New Widget') 6 | i.fa.fa-plus 7 | span Add Widget 8 | 9 | button#editor-page-remove.btn.btn-default(type='button', ng-click='removePage(editor.selectedPageIndex); goToSubState("edit.pages", editor.dashboard.pages)', title='Remove') 10 | i.fa.fa-times 11 | span Remove Page 12 | div 13 | .form-group 14 | label Widgets 15 | 16 | editor-view-object-array(model='editor.selectedPage.widgets', label='Widget', 17 | substate='edit.widget', headingfn='getWidgetName(item, index)') 18 | 19 | .editor-property-set(model='editor.selectedPage', excludes='pageExcludes', definition='dashboardProperties.pages.properties') 20 | 21 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/pages.pug: -------------------------------------------------------------------------------- 1 | .editor-view-header 2 | h3 Pages 3 | 4 | .editor-view-header-buttons 5 | button#editor-pages-add.btn.btn-primary(type='button', ng-click='newPage()', title='Add New Page') 6 | i.fa.fa-plus 7 | span Add Page 8 | 9 | editor-view-object-array(model='editor.dashboard.pages', label='Page', 10 | substate='edit.page', headingfn='getPageName(item, index)') 11 | 12 | div 13 | span.label.label-default(ng-repeat='widget in item.widgets') {{ widget.widget }} 14 | span.label.label-warning(ng-hide='item.widgets') No Widgets 15 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/parameter.pug: -------------------------------------------------------------------------------- 1 | .editor-view-header 2 | h3 {{ getParameterName(editor.selectedItem, editor.selectedItemIndex) }} 3 | 4 | .editor-view-header-buttons 5 | button.btn.btn-default(type='button', ng-click='removeParameter(editor.selectedItemIndex); goToSubState("edit.parameters", editor.dashboard.parameters)', title='Remove') 6 | i.fa.fa-times 7 | span Remove Parameter 8 | 9 | .editor-property-set(dashboard='editor.dashboard', model='editor.selectedItem', definition='dashboardProperties.parameters.properties') 10 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/parameters.pug: -------------------------------------------------------------------------------- 1 | .editor-view-header 2 | h3 Parameters 3 | 4 | .editor-view-header-buttons 5 | button.btn.btn-primary(type='button', ng-click='newParameter()', title='Add New Parameter') 6 | i.fa.fa-plus 7 | span Add Parameter 8 | 9 | editor-view-object-array(model='editor.dashboard.parameters', label='Parameter', 10 | substate='edit.parameter', headingfn='getParameterName(item, index, label)') 11 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/pushDashboard.pug: -------------------------------------------------------------------------------- 1 | .modal-header 2 | h3.modal-title Push Dashboard 3 | 4 | .modal-body 5 | p Select a Cyclotron environment to push this Dashboard to. If the Dashboard already exists in 6 | | that environment, it will be overwritten. 7 | 8 | form(ng-submit='push()') 9 | .push-dashboard.well.well-sm 10 | select#editor-push-environment(ng-model='fields.pushLocation', ng-options='environment.name for environment in environmentsForPush', ng-change='updateFocus()') 11 | 12 | div(ng-if='fields.pushLocation.requiresAuth === true') 13 | input(type='text', ng-model='fields.username', focus-on='focusUsername', placeholder='Username') 14 | input(type='password', ng-model='fields.password', focus-on='focusPassword', placeholder='Password') 15 | 16 | //- Hidden input for ng-submit to work 17 | input(type='submit', style='position: absolute; left: -9999px') 18 | 19 | .modal-footer 20 | button.btn#editor-push-cancel(ng-click='cancel()') Cancel 21 | button.btn.btn-primary#editor-push-push(ng-click='push()') Push 22 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/script.pug: -------------------------------------------------------------------------------- 1 | .editor-view-header 2 | h3 {{ getScriptOrStyleName(editor.selectedItem, editor.selectedItemIndex, 'Script') }} 3 | 4 | .editor-view-header-buttons 5 | button#editor-script-remove.btn.btn-default(type='button', ng-click='removeScript(editor.selectedItemIndex); goToSubState("edit.scripts", editor.dashboard.scripts)', title='Remove') 6 | i.fa.fa-times 7 | span Remove Script 8 | 9 | 10 | .editor-property-set(model='editor.selectedItem', definition='dashboardProperties.scripts.properties') 11 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/scripts.pug: -------------------------------------------------------------------------------- 1 | .editor-view-header 2 | h3 Scripts 3 | 4 | .editor-view-header-buttons 5 | button#editor-scripts-add.btn.btn-primary(type='button', ng-click='newScript()', title='Add New Script') 6 | i.fa.fa-plus 7 | span Add Script 8 | 9 | editor-view-object-array(model='editor.dashboard.scripts', label='Script', 10 | substate='edit.script', headingfn='getScriptOrStyleName(item, index, label)') 11 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/stringArray.pug: -------------------------------------------------------------------------------- 1 | .well.well-sm 2 | .form-group#editor-array-item(ng-repeat='v in model track by $index') 3 | 4 | select.form-control(ng-show='definition.options', ng-model='v', ng-change='updateArrayValue($index, v)', title='{{ definition.description }}' 5 | ng-options='optionValue.value as optionKey for (optionKey, optionValue) in definition.options') 6 | option(value='') 7 | 8 | input.form-control(ng-hide='definition.options', ng-model='v', ng-change='updateArrayValue($index, v)', placeholder='{{ definition.placeholder }}') 9 | 10 | i#editor-array-remove.inline-delete-icon.fa.fa-times(ng-click='removeArrayValue($index)', title='Remove this value') 11 | 12 | .horizontal-add.button-group 13 | button#editor-array-add.btn.btn-default(type='button', ng-click='addArrayValue()', title='Add {{ label }}') 14 | i.fa.fa-plus 15 | span Add {{ label }} 16 | 17 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/style.pug: -------------------------------------------------------------------------------- 1 | .editor-view-header 2 | h3 {{ getScriptOrStyleName(editor.selectedItem, editor.selectedItemIndex, 'Style') }} 3 | 4 | .editor-view-header-buttons 5 | button#editor-style-remove.btn.btn-default(type='button', ng-click='removeStyle(editor.selectedItemIndex); goToSubState("edit.styles", editor.dashboard.styles)', title='Remove') 6 | i.fa.fa-times 7 | span Remove Style 8 | 9 | editor-property-set(model='editor.selectedItem', definition='dashboardProperties.styles.properties') 10 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/styles.pug: -------------------------------------------------------------------------------- 1 | .editor-view-header 2 | h3 Styles 3 | 4 | .editor-view-header-buttons 5 | button#editor-styles-add.btn.btn-primary(type='button', ng-click='newStyle()', title='Add New Style') 6 | i.fa.fa-plus 7 | span Add Style 8 | 9 | editor-view-object-array(model='editor.dashboard.styles', label='Style', 10 | substate='edit.style', headingfn='getScriptOrStyleName(item, index, label)') 11 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/editor/widget.pug: -------------------------------------------------------------------------------- 1 | .editor-view-header 2 | h3 {{ getWidgetName(editor.selectedItem, editor.selectedItemIndex) }} 3 | 4 | .editor-view-header-buttons 5 | button#editor-widget-remove.btn.btn-default(type='button', ng-click='removeWidget(editor.selectedItemIndex); goToSubState("edit.page", editor.selectedPage, editor.selectedPageIndex)', title='Remove') 6 | i.fa.fa-times 7 | span Remove Widget 8 | 9 | .form-group 10 | label(title='{{ dashboardProperties.pages.properties.widgets.properties.widget.description }}') Widget Type 11 | 12 | select.form-control(ng-model='editor.selectedItem.widget', 13 | ng-change='selectWidget()' 14 | title='{{ dashboardProperties.pages.properties.widgets.properties.widget }}', 15 | ng-options='optionKey as (optionValue.label || optionKey) for (optionKey, optionValue) in widgets') 16 | 17 | .editor-property-set(dashboard='editor.dashboard', model='editor.selectedItem', definition='combinedWidgetProperties(editor.selectedItem)') 18 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/export.pug: -------------------------------------------------------------------------------- 1 | 2 | .export-page.container-fluid 3 | include header 4 | 5 | .row.header 6 | .well.well-sm 7 | .button-bar 8 | a(ng-href='/{{ dashboardName }}') 9 | button.btn.btn-default 10 | i.fa.fa-angle-left 11 | | Return to Dashboard 12 | 13 | h1 Export Dashboard 14 | form.row.well.well-sm 15 | .col-md-3.col-md-offset-1 16 | .form-group 17 | label.control-label Dashboard Name 18 | input.form-control(type='text', ng-model='dashboardName', placeholder='Dashboard Name', required) 19 | 20 | .form-group 21 | label.control-label Format 22 | select.form-control(ng-options='format.label for format in exportFormats', ng-model='exportFormat') 23 | 24 | .form-group 25 | button.btn.btn-primary(type='submit', ng-click='export()', ng-disabled='exporting') Export 26 | 27 | .col-md-6 28 | .form-group 29 | label.control-label Dashboard Parameters 30 | editor-view-hash(model='parameters') 31 | 32 | .row 33 | .col-md-7.col-md-offset-1 34 | .results(ng-if='exportStatus') 35 | 36 | .pull-left 37 | i.fa.fa-refresh(ng-show='exportStatus.status == "running"') 38 | i.fa.fa-check.text-success(ng-show='exportStatus.status == "complete"') 39 | span Status: {{ exportStatus.status }} 40 | 41 | .pull-right {{ exportStatus.duration / 1000 }} seconds 42 | 43 | div(ng-show='exportStatus.png.length > 0') 44 | h5 Images 45 | .resultType(ng-repeat='png in exportStatus.png') 46 | a(ng-href='{{ png }}', target='_blank') 47 | i.fa.fa-file-image-o 48 | span Page {{ $index + 1 }} 49 | 50 | div(ng-show='exportStatus.pdf.length > 0') 51 | h5 PDF 52 | 53 | .resultType(ng-repeat='pdf in exportStatus.pdf') 54 | a(ng-href='{{ pdf }}', target='_blank') 55 | i.fa.fa-file-pdf-o 56 | 57 | .row.footer 58 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/footer.pug: -------------------------------------------------------------------------------- 1 | p 2 | //-li © 2014 Expedia, Inc. 3 | span v{{ cyclotronVersion }} 4 | span.separator(ng-if='changelogLink') | 5 | a(ng-if='changelogLink', ng-href='{{ changelogLink }}') Changelog 6 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/header.pug: -------------------------------------------------------------------------------- 1 | .row.cyclotron-header 2 | h1(ui-sref='home' ui-sref-opts='{reload: true}') 3 | img.logo(src='/img/logo.svg', alt='Logo') 4 | | Cyclotron 5 | .links 6 | //-a.home(ui-sref='home', title='Return to Home') 7 | i.fa.fa-home 8 | a.new(ng-href='/edit/', target='_self', title='Create a new Dashboard') 9 | i.fa.fa-file-o 10 | a.documentation(ui-sref='help', target='_blank' title='Documentation for Cyclotron') 11 | i.fa.fa-question-circle 12 | a.analytics(ng-if='analyticsEnabled()', ui-sref='analytics', title='Analytics for Cyclotron') 13 | i.fa.fa-bar-chart 14 | a.login(requires-auth, ng-click='login()', ng-if='!isLoggedIn()', title='Login') 15 | i.fa.fa-unlock 16 | span.dropdown(requires-auth, ng-if='isLoggedIn()') 17 | a.user.dropdown-toggle(title='{{ userTooltip() }}', data-toggle='dropdown') 18 | i.fa.fa-user(ng-if='!currentUser().emailHash') 19 | img(ng-if='currentUser().emailHash', ng-src='{{ userGravatar() }}') 20 | ul.dropdown-menu(role='menu') 21 | li.dropdown-header(role='presentation') 22 | a {{ currentUser().name }} 23 | li(ng-if='isAdmin()') 24 | a.admin(title='Admin') Is Admin 25 | i.fa.fa-key 26 | li.divider(ng-if='isAdmin()', role='presentation') 27 | a 28 | li 29 | a.logout(ng-click='logout()', title='Logout') Logout 30 | i.fa.fa-lock 31 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help.pug: -------------------------------------------------------------------------------- 1 | 2 | .help-page.container-fluid 3 | include header 4 | 5 | .row 6 | .sidebar.col-sm-4 7 | h2 Documentation 8 | form.search(ng-submit='feelingLucky()') 9 | .form-group 10 | .input-group 11 | input.form-control(type='text', ng-model='search', placeholder='Search') 12 | span.input-group-addon 13 | i.fa.fa-search 14 | collapse-menu(items='menu', filter='search', initial-selection='q', select-item='selectItem(item)') 15 | 16 | .col-sm-8 17 | section.help-content 18 | 19 | div(ng-include='selectedItem.path', ng-if='selectedItem.path != null') 20 | 21 | .no-help(ng-if='selectedItem.path == null') 22 | i.fa.fa-exclamation-triangle 23 | | No help is available for this topic 24 | 25 | .row.footer 26 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/api.pug: -------------------------------------------------------------------------------- 1 | h3 API 2 | 3 | p. 4 | Cyclotron has a REST-ful API that you can consume to perform CRUD operations on 5 | the Dashboard definitions. 6 | 7 | p This instance of Cyclotron is configured to use the following service: 8 | 9 | p 10 | strong 11 | a(href='{{config.restServiceUrl}}/', target='_blank') {{ config.restServiceUrl }}/ 12 | 13 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/browserCompat.pug: -------------------------------------------------------------------------------- 1 | h3 Browser Compatibility 2 | 3 | p 4 | | Cyclotron is compatible with recent versions of web browsers: Firefox, Chrome, Internet Explorer, Safari, etc. It performs browser feature detection 5 | | to check for specific features that are (generally) required to work as designed. It is possible to bypass this test, as detailed below. 6 | 7 | p Internet Explorer 10 and up should be compatible, but Internet Explorer 8 and below are explicitly not supported. 8 | 9 | h4 Bypassing the Browser Check 10 | 11 | .bg-warning 12 | i.fa.fa-exclamation 13 | .inner While this may allow Cyclotron to run in older browsers, it does not guarantee that all features will work. Unsupported browsers have not been tested and issues will not be fixed. Circumventing the browser compatibility check is done at your own risk. 14 | 15 | p The browser compatibility check can be skipped by appending this option to the url: 16 | 17 | pre.code 18 | a(href="/?browsercheck=false") ?browsercheck=false 19 | 20 | p This does not work in Internet Explorer 8 and older, as these browsers are unable to run the browser check. 21 | 22 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/collapseMenu.pug: -------------------------------------------------------------------------------- 1 | ul.nav.nav-pills.nav-stacked 2 | li(ng-repeat='section in items | filter:filter', ng-class='{active: section.selected == true}') 3 | a(ng-click='selectSection(section)') 4 | i.fa.fa-angle-right.text-muted(ng-show="section.selected != true") 5 | i.fa.fa-angle-down.text-muted(ng-show="section.selected == true") 6 | | {{ section.name }} 7 | 8 | ul.nav.nav-pills.nav-stacked.indent(ng-if='section.expanded == true || isFiltered') 9 | li(ng-repeat='child in section.children | filter:filter', ng-class='{active: child.selected == true}') 10 | a(ng-click='selectChild(child, section)') 11 | | {{ child.name }} 12 | 13 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/dashboards.pug: -------------------------------------------------------------------------------- 1 | h3 Dashboards 2 | 3 | p In Cyclotron, Dashboards consist of one or more Pages, each of which has one or more Widgets. A Dashboard has 4 | | several top-level properties, many of which are inherited by Pages and Widgets. Setting a property at the 5 | | Dashboard-level can be more efficient than setting it directly on every Widget. Inherited properties can be 6 | | overridden by the Page and/or Widget, as well. 7 | 8 | p In the Dashboard Editor, these properties are found under the Details tab, although 9 | em pages 10 | |, 11 | em dataSources 12 | |, 13 | em scripts 14 | |, etc. are located in their own tab in the Editor. 15 | 16 | h4 Properties 17 | 18 | property-table(properties='config.dashboard.properties') 19 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/datasources/cyclotronData.pug: -------------------------------------------------------------------------------- 1 | h3 CyclotronData Data Source 2 | 3 | p The CyclotronData Data Source loads data from a CyclotronData bucket. The bucket must already exist or an error will be displayed. For more details, refer to the documentation on CyclotronData 4 | 5 | P Please note that it may be necessary to set the optional 6 | em url 7 | | property in the Data Source in order to connect to the correct Cyclotron instance. 8 | | This property lists other Cyclotron servers. 9 | | By default, this Data Source loads data from the current Cyclotron server. 10 | 11 | property-table(properties='config.dashboard.properties.dataSources.options.cyclotronData.properties') 12 | 13 | h4 Pre-Processor 14 | 15 | p The CyclotronData Data Source supports an optional pre-processor function that will be called before 16 | | the Data Source executes. For more details, see the main Data Sources page. 17 | 18 | h4 Post-Processor 19 | 20 | p The CyclotronData Data Source supports an optional post-processor function that will be called after 21 | | data is loaded. For more details, see the main Data Sources page. 22 | 23 | h3 Examples 24 | 25 | p Examples of the CyclotronData Data Source are available on the 26 | a(href='/example-datasource-cyclotrondata') example-datasource-cyclotrondata 27 | | dashboard 28 | 29 | h4 Basic Configuration 30 | p This is the most basic configuration, using a random GUID. 31 | pre.code. 32 | { 33 | "key": "6B4BA5A6-DFF4-11E5-8D51-4FBBDC50F6B1", 34 | "type": "cyclotronData" 35 | } 36 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/datasources/graphite.pug: -------------------------------------------------------------------------------- 1 | h3 Graphite Data Source 2 | 3 | p The Graphite Data Source connects to any Graphite server and uses the /render API to extract raw values. 4 | | It can output one or more targets, which can use the full list of 5 | a(href='http://graphite.readthedocs.org/en/latest/functions.html', target='_blank') Graphite functions 6 | | . 7 | 8 | P Please note that it may be necessary to set the optional 9 | em proxy 10 | | property in the Data Source in order to access web sites or services in other domains. 11 | | This property lists other Cyclotron servers which may have the required connectivity. 12 | | By default, this Data Source uses the current Cyclotron environment to proxy the request. 13 | 14 | p Examples of the Graphite Data Source are available on the 15 | a(href='/example-datasource-graphite') example-datasource-graphite 16 | | dashboard 17 | 18 | property-table(properties='config.dashboard.properties.dataSources.options.graphite.properties') 19 | 20 | h4 Pre-Processor 21 | 22 | p The Graphite Data Source supports an optional pre-processor function that will be called before 23 | | the Data Source executes. For more details, see the main Data Sources page. 24 | 25 | h4 Post-Processor 26 | 27 | p The Graphite Data Source supports an optional post-processor function that will be called after 28 | | data is loaded. For more details, see the main Data Sources page. 29 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/datasources/influxdb.pug: -------------------------------------------------------------------------------- 1 | h3 InfluxDB Data Source 2 | 3 | p 4 | a(href='https://docs.influxdata.com/influxdb', target='_blank') InfluxDB 5 | | is an open source time series database built from the ground up to handle high write and query loads. 6 | | This Data Source supports querying InfluxDB for metrics using 7 | a(href='https://docs.influxdata.com/influxdb/v1.1/query_language/spec/', target='_blank') InfluxQL. 8 | 9 | P Please note that it may be necessary to set the optional 10 | em proxy 11 | | property in the Data Source in order to access web sites or services in other domains. 12 | | This property lists other Cyclotron servers which may have the required connectivity. 13 | | By default, this Data Source uses the current Cyclotron environment to proxy the request. 14 | 15 | property-table(properties='config.dashboard.properties.dataSources.options.influxdb.properties') 16 | 17 | h4 Pre-Processor 18 | 19 | p The InfluxDB Data Source supports an optional pre-processor function that will be called before 20 | | the Data Source executes. For more details, see the main Data Sources page. 21 | 22 | h4 Post-Processor 23 | 24 | p The InfluxDB Data Source supports an optional post-processor function that will be called after 25 | | data is loaded. For more details, see the main Data Sources page. 26 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/datasources/json.pug: -------------------------------------------------------------------------------- 1 | h3 JSON Data Source 2 | 3 | p The JSON Data Source simply loads JSON data from a web URL. Cyclotron implements a reverse-proxy to 4 | | avoid cross-origin resource sharing (CORS) issues. Under the covers it uses the 5 | a(href='https://github.com/mikeal/request', target='_blank') Request library 6 | | , and the full list of options can be set in Cyclotron for more advanced requests. 7 | 8 | P Please note that it may be necessary to set the optional 9 | em proxy 10 | | property in the Data Source in order to access web sites or services in other domains. 11 | | This property lists other Cyclotron servers which may have the required connectivity. 12 | | By default, this Data Source uses the current Cyclotron environment to proxy the request. 13 | 14 | p Examples of the JSON Data Source are available on the 15 | a(href='/example-datasource-json') example-datasource-json 16 | | dashboard 17 | 18 | property-table(properties='config.dashboard.properties.dataSources.options.json.properties') 19 | 20 | h4 Pre-Processor 21 | 22 | p The JSON Data Source supports an optional pre-processor function that will be called before 23 | | the Data Source executes. For more details, see the main Data Sources page. 24 | 25 | h4 Post-Processor 26 | 27 | p The JSON Data Source supports an optional post-processor function that will be called after 28 | | data is loaded. For more details, see the main Data Sources page. 29 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/datasources/mock.pug: -------------------------------------------------------------------------------- 1 | h3 Mock Data Source 2 | p 3 | | The Mock Data Source generates sample data for demonstration/testing purposes. 4 | | It has several modes which can be selected by the 5 | em format 6 | | property. The possible formats are: 7 | 8 | table 9 | tr 10 | th Format 11 | th Description 12 | tr 13 | td object 14 | td Default format 15 | tr 16 | td pie 17 | td Designed for pie charts, with percents that sum to 100% 18 | tr 19 | td ducati 20 | td Mock real-time data source that automatically updates if 21 | em refresh 22 | | is enabled 23 | 24 | p 25 | 26 | property-table(properties='config.dashboard.properties.dataSources.options.mock.properties') 27 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/datasources/prometheus.pug: -------------------------------------------------------------------------------- 1 | h3 Prometheus Data Source 2 | 3 | p The Prometheus Data Source connects to any Prometheus server and uses the built-in API to extract raw values. 4 | | It can output one or more targets, which can use the full list of 5 | a(href='http://graphite.readthedocs.org/en/latest/functions.html', target='_blank') Graphite functions 6 | | . 7 | 8 | P Please note that it may be necessary to set the optional 9 | em proxy 10 | | property in the Data Source in order to access web sites or services in other domains. 11 | | This property lists other Cyclotron servers which may have the required connectivity. 12 | | By default, this Data Source uses the current Cyclotron environment to proxy the request. 13 | 14 | p Examples of the Graphite Data Source are available on the 15 | a(href='/example-datasource-graphite') example-datasource-graphite 16 | | dashboard 17 | 18 | property-table(properties='config.dashboard.properties.dataSources.options.graphite.properties') 19 | 20 | h4 Pre-Processor 21 | 22 | p The Graphite Data Source supports an optional pre-processor function that will be called before 23 | | the Data Source executes. For more details, see the main Data Sources page. 24 | 25 | h4 Post-Processor 26 | 27 | p The Graphite Data Source supports an optional post-processor function that will be called after 28 | | data is loaded. For more details, see the main Data Sources page. 29 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/datasources/splunk.pug: -------------------------------------------------------------------------------- 1 | h3 Splunk Data Source 2 | 3 | p The Splunk Data Source runs Splunk jobs synchronously via its API and returns the results. This 4 | | Data Source is compatible with the 5 | a(href='http://docs.splunk.com/Documentation/Splunk/6.2.4/RESTUM/RESTusing', target='_blank') Splunk 6 API 6 | | , and may not work with old versions. 7 | 8 | p Examples of the Splunk Data Source are available on the 9 | a(href='/example-datasource-splunk') example-datasource-splunk 10 | | dashboard 11 | 12 | property-table(properties='config.dashboard.properties.dataSources.options.splunk.properties') 13 | 14 | h4 Pre-Processor 15 | 16 | p The Splunk Data Source supports an optional pre-processor function that will be called before 17 | | the Data Source executes. For more details, see the main Data Sources page. 18 | 19 | h4 Post-Processor 20 | 21 | p The Splunk Data Source supports an optional post-processor function that will be called after 22 | | data is loaded. For more details, see the main Data Sources page. 23 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/examples.pug: -------------------------------------------------------------------------------- 1 | h3 Examples 2 | 3 | p There are many example Dashboards available with the tag 4 | a(href='/?q=cyclotron-examples') 5 | strong cyclotron-examples 6 | |. Each Widget's help page also includes relevent snippets of the examples. 7 | 8 | p Under the covers, the Cyclotron editor constructors the Dashboard definition in JSON. Here's a brief example: 9 | pre.code. 10 | { 11 | "description": "This is an example", 12 | "name": "example-dashboard", 13 | "pages": [{ 14 | "duration": 60, 15 | "frequency": 1, 16 | "layout": { 17 | "gridColumns": 2, 18 | "gridRows": 2 19 | }, 20 | "widgets": [{ 21 | "widget": "clock" 22 | }] 23 | }], 24 | "theme": "dark" 25 | } 26 | 27 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/hotkeys.pug: -------------------------------------------------------------------------------- 1 | h3 Hotkeys 2 | 3 | p. 4 | The following hotkeys are enabled: 5 | 6 | h4 Dashboard Editor 7 | dl.dl-horizontal 8 | dt Ctrl-S / Command-S 9 | dd Save current Dashboard 10 | 11 | h4 Dashboard Viewer 12 | dl.dl-horizontal 13 | dt Left/Page-Up 14 | dd Rotate page backwards 15 | dt Right/Page-Down 16 | dd Rotate page forwards 17 | dt Space 18 | dd Toggle pause/resume of automatic dashboard rotation 19 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/json.pug: -------------------------------------------------------------------------------- 1 | h3 JSON 2 | 3 | p. 4 | Dashboards are defined entirely in JSON, making it easy to copy/paste, store in a version control system, etc. When rendering the Dashboard in the browser, the same JSON Dashboard definition is loaded and parsed. 5 | p. 6 | Cyclotron provides an editor that makes it easier to create and edit Dashboards without directly editing the JSON definition. However, each page in the editor has a direct link to the corresponding JSON for that page, and the entire Dashboard JSON is available from the Details page. 7 | p. 8 | Examples presented in the documentation are given in JSON for convenience, but they translate very easily to the Editor. If needed, the JSON examples can be pasted into the JSON editor, and then viewed through the primary editor. 9 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/pages.pug: -------------------------------------------------------------------------------- 1 | h3 Pages 2 | 3 | p In Cyclotron, Dashboards are composed of Pages. A Page is a full-screen display of one or more Widgets. 4 | | Each Dashboard can have one or more Pages. 5 | p 6 | | To add a Page to a Dashboard, first click on the Pages section of the Dashboard Editor, and click 7 | strong.no-wrap 8 | i.fa.fa-plus 9 | | Add Page 10 | | at the top of the editor. Click on the new Page to open its editor. 11 | 12 | p The order of Pages is significant: the first Page will be loaded by default when the Dashboard loads. Dashboard 13 | | controls allow the user to scroll forwards or backwards through the pages in a linear fashion. The Pages page 14 | | allows easy reordering of the list of Pages in the Dashboard. 15 | 16 | h4 Page Name 17 | p 18 | | The 19 | em name 20 | | is displayed in the URL when viewing this page. It is optional—a default name 21 | | will be generated from the page number (e.g. 22 | em /page-1) 23 | | if this property is omitted. If the first page does not have a 24 | em name 25 | | , the URL will simply refer to the Dashboard without a page name or number, since the first page is the default. 26 | 27 | h4 Common Properties 28 | 29 | p These properties apply to each Page. Several of them are overrides for Dashboard properties, from which 30 | | a Page will inherit if the properties are not overridden at the Page level. 31 | 32 | property-table(properties='config.dashboard.properties.pages.properties') 33 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/propertyTable.pug: -------------------------------------------------------------------------------- 1 | table 2 | tr 3 | th Property 4 | th Description 5 | th Type 6 | th Required 7 | tr(ng-repeat='(key, property) in properties') 8 | td {{ key }} 9 | td {{ property.description }} 10 | td {{ property.editorMode || property.type }} 11 | td 12 | i.fa.fa-check(ng-show='property.required') 13 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/styles.pug: -------------------------------------------------------------------------------- 1 | h3 Styles 2 | 3 | p The 4 | em styles 5 | | property is an optional list of CSS styles to apply to the Dashboard. 6 | | Each item in the array either points to an externally-hosted CSS file, or it contains inline CSS. 7 | | In both cases, the list of CSS styles will be executed top-down when the dashboard loads. Specifically, these styles 8 | | applied after the Cyclotron, 3rd-party, and theme styles have been loaded loaded. 9 | 10 | p This example shows two styles: the first is an external CSS file, and the second is an inline style: 11 | 12 | pre.code. 13 | "styles": [{ 14 | "path": "http://mrmrs.io/btns/css/btns.min.css" 15 | }, { 16 | "text": "button.custom-button { color: black !important; }" 17 | }] 18 | 19 | h4 Overriding Styles 20 | 21 | p There are several potential pitfalls to applying custom styles. Cyclotron comes with several baseline 22 | | styles and a "CSS Reset", which attempts to normalize styles across all browsers. On top of this, 23 | | each Dashboard Theme applies additional styles. Due to 24 | a(href='http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/') CSS precedence and inheritance 25 | | rules, it can be 26 | | tricky to correctly override Theme styles with custom styles. 27 | 28 | p The easiest (and ugliest) solution is generally to add "!important" to the end of each custom style, as this generally trumps 29 | | other styles. Alternatively, inspect the element to be styled in the browser's developer tools, 30 | | and write the custom style in a more-specific fashion to trump the theme styles. Using an ID for a parent DIV is generally effective. 31 | 32 | h4 Properties 33 | property-table(properties='config.dashboard.properties.styles.properties') 34 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/help/widgets.pug: -------------------------------------------------------------------------------- 1 | h3 Widgets 2 | 3 | p. 4 | These are the standard Widget properties which can be set regardless of the Widget type. Refer to the documentation for each Widget 5 | for details on the Widget-specific properties. 6 | 7 | p. 8 | To add a Widget to a Dashboard, first a new Page must be added. Click on any Page and select the Add Widget button at the top 9 | of the editor. Click on the new Widget to open its editor, then the Widget Type can be selected from the dropdown. Once a Widget 10 | Type is selected, the editor will automatically show relevent properties for that specific Type. 11 | 12 | p. 13 | The Widget Type can be changed later, and 14 | the editor will refresh with an updated list of availabile properties. Note that any properties that aren't applicable for the current 15 | type will be hidden in the editor. (They can be edited or removed directly in the JSON editor) 16 | 17 | h4 Common Properties 18 | 19 | p These properties are common to each Widget. Several of them are overrides for Dashboard or Page properties, from which 20 | | a Widget will inherit if the properties are not overridden at the Widget level. 21 | 22 | property-table(properties='config.dashboard.properties.pages.properties.widgets.properties') 23 | 24 | h4 Widgets 25 | 26 | p Select the individual Widget names in the menu to see documentation specific to each Widget type. 27 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/login.pug: -------------------------------------------------------------------------------- 1 | .login-modal 2 | .modal-header 3 | h3.modal-title Login 4 | 5 | .modal-body 6 | .login-message(ng-if='loginMessage') {{ loginMessage }} 7 | 8 | form(ng-submit='login()') 9 | input(type='text', ng-model='credentials.username', required, focus-on='focusUsername', placeholder='Username') 10 | input(type='password', ng-model='credentials.password', required, focus-on='focusPassword', placeholder='Password') 11 | 12 | //- Hidden input for ng-submit to work 13 | input(type='submit', style='position: absolute; left: -9999px') 14 | 15 | p.modal-error.bg-danger(ng-if='loginError') 16 | i.fa.fa-exclamation 17 | span Invalid username or password. Please try again. 18 | 19 | .modal-footer 20 | button.btn(ng-click='cancel()') Cancel 21 | button.btn.btn-primary(ng-click='login()', ng-disabled='!canLogin()') Login 22 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/newUserMessage.pug: -------------------------------------------------------------------------------- 1 | .new-user-message(ng-if='canDisplay()') 2 | i.fa.left(class='{{ iconClass }}') 3 | i.fa.fa-times.right(ng-click='dismiss()') 4 | .inner 5 | p(ng-bind-html='message') 6 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/revisionDiff.pug: -------------------------------------------------------------------------------- 1 | .revisionDiff-modal 2 | .modal-header 3 | h3.modal-title Diff Rev {{ rev1 }} to Rev {{ rev2 }} 4 | 5 | .modal-body 6 | .revision-controls 7 | i.fa.fa-angle-double-left.btn-link(ng-if='rev1 > 1', ng-click='previous()', title='Compare Previous Revision') 8 | 9 | label From rev 10 | select(ng-model='rev1', ng-options='revision.rev as revision.rev for revision in revisions') 11 | 12 | label to rev 13 | select(ng-model='rev2', ng-options='revision.rev as revision.rev for revision in revisions') 14 | 15 | i.fa.fa-angle-double-right.btn-link(ng-if='rev2 < dashboard.rev', ng-click='next()', title='Compare Next Revision') 16 | 17 | .diff(ng-bind-html='diff') 18 | 19 | .modal-footer 20 | button.btn(ng-click='$dismiss("ok")') OK 21 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/sidebarAccordion.pug: -------------------------------------------------------------------------------- 1 | .panel-group(ng-transclude='') 2 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/sidebarAccordionGroup.pug: -------------------------------------------------------------------------------- 1 | .panel.panel-default 2 | .panel-heading(ng-click='toggleOpen()') 3 | h4.panel-title 4 | a.accordion-toggle(accordion-transclude='heading') 5 | span(ng-class='{"text-muted": isDisabled}') {{heading}} 6 | 7 | .panel-collapse(uib-collapse='!isOpen') 8 | .panel-body(ng-style='styles', ng-transclude='') 9 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/viewPermissionDenied.pug: -------------------------------------------------------------------------------- 1 | .modal-header 2 | h3.modal-title Permission Denied 3 | 4 | .modal-body 5 | p This Dashboard has 6 | strong View Permissions 7 | | that prevent you from being able to view or edit it. 8 | 9 | p This is managed by the owner of this Dashboard. Please contact: 10 | ul 11 | li(ng-repeat='editor in dashboardEditors') {{ editor.displayName }} 12 | a(href='mailto:{{ editor.mail }}?subject=Cyclotron:%20Access%20to%20Dashboard:%20{{ dashboardName }}') ({{ editor.mail }}) 13 | 14 | .modal-footer 15 | button.btn.btn-primary(ng-click='goHome()') 16 | i.fa.fa-home 17 | span Home 18 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/widget.pug: -------------------------------------------------------------------------------- 1 | .widget-control-bar 2 | i.widget-control.widget-helptext.fa.fa-question-circle(ng-if='widgetContext.helpText', uib-tooltip='{{ ::widgetContext.helpText }}', tooltip-placement='auto-right', tooltip-trigger='outsideClick') 3 | .widget-control.widget-dropdown-menu.btn-group(ng-if='showDropdown()', uib-dropdown='') 4 | i.fa.fa-caret-down(uib-dropdown-toggle='') 5 | ul.dropdown-menu-right(uib-dropdown-menu='', role='menu') 6 | li(role='menuitem') 7 | a(ng-click='exportData("csv")') 8 | i.fa.fa-file-o 9 | | Export data as CSV 10 | li(role='menuitem') 11 | a(ng-click='exportData("json")') 12 | i.fa.fa-file-code-o 13 | | Export data as JSON 14 | li(role='menuitem') 15 | a(ng-click='exportData("xlsx")') 16 | i.fa.fa-file-excel-o 17 | | Export data as Excel 18 | i.widget-control.widget-fullscreen.fa.fa-expand(ng-if='widgetContext.allowFullscreen', title='Click to view fullscreen') 19 | 20 | .dashboard-widget(class='{{ widgetClass }}', ng-include='widgetTemplateUrl') 21 | -------------------------------------------------------------------------------- /cyclotron-site/app/partials/widgetError.pug: -------------------------------------------------------------------------------- 1 | 2 | .widget-error-container 3 | .fa.fa-exclamation(title='{{ errorMessage }}') 4 | .widget-reload(ng-click='reload()') 5 | i.fa.fa-refresh 6 | | Reload 7 | .widget-error-message(title='{{ errorMessage }}') 8 | | {{ shortErrorMessage }} 9 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/common/controller.genericErrorModal.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # GenericErrorModalController controller -- for modal dialog 19 | # 20 | cyclotronApp.controller 'GenericErrorModalController', ($scope, $uibModalInstance, $state) -> 21 | 22 | $scope.goHome = -> 23 | $uibModalInstance.dismiss() 24 | $state.go('home') 25 | 26 | $scope.reload = -> 27 | $uibModalInstance.dismiss() 28 | $state.reload() 29 | 30 | 31 | $scope.goEditor = -> 32 | $uibModalInstance.dismiss() 33 | $state.go('edit.details', { dashboardName: $scope.originalDashboardName}) 34 | 35 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/common/controller.login.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # Login controller -- for login modal dialog 19 | # 20 | cyclotronApp.controller 'LoginController', ($scope, $uibModalInstance, $localForage, configService, focusService, userService) -> 21 | 22 | $scope.credentials = {} 23 | $scope.loginError = false 24 | $scope.loggingIn = false 25 | 26 | $scope.loginMessage ?= configService.authentication.loginMessage 27 | 28 | # Load cached username 29 | if userService.cachedUsername? 30 | $scope.credentials.username = userService.cachedUsername 31 | focusService.focus 'focusPassword', $scope 32 | else 33 | focusService.focus 'focusUsername', $scope 34 | 35 | $scope.canLogin = -> 36 | return !_.isEmpty($scope.credentials.username) && !_.isEmpty($scope.credentials.password) && !$scope.loggingIn 37 | 38 | $scope.login = -> 39 | return if $scope.loggingIn 40 | $scope.loginError = false 41 | $scope.loggingIn = true 42 | loginPromise = userService.login $scope.credentials.username, $scope.credentials.password 43 | 44 | loginPromise.then (session) -> 45 | $scope.credentials.password = '' 46 | $uibModalInstance.close(session) 47 | 48 | loginPromise.catch (error) -> 49 | $scope.loginError = true 50 | $scope.loggingIn = false 51 | $scope.credentials.password = '' 52 | focusService.focus 'focusPassword', $scope 53 | 54 | $scope.cancel = -> 55 | $uibModalInstance.dismiss('cancel') 56 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/common/directives/directives.fullscreen.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # Directive that adds the fullscreen class to parent elements 18 | cyclotronDirectives.directive 'fullscreen', -> 19 | { 20 | restrict: 'CA' 21 | link: (scope, element, attrs) -> 22 | $(element).parents().addClass 'fullscreen' 23 | return 24 | } 25 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/common/directives/directives.requiresAuth.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # Directive that hides an element unless authentication is enabled 18 | cyclotronDirectives.directive 'requiresAuth', (userService) -> 19 | { 20 | restrict: 'CA' 21 | link: (scope, element, attrs) -> 22 | $(element).hide() unless userService.authEnabled 23 | } 24 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/common/directives/directives.requiresLogin.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # Directive that hides an element unless authentication 18 | # is enabled and the user is logged in 19 | cyclotronDirectives.directive 'requiresLogin', (userService) -> 20 | { 21 | restrict: 'CA' 22 | link: (scope, element, attrs) -> 23 | $(element).hide() unless userService.authEnabled and userService.isLoggedIn() 24 | 25 | scope.$watch userService.isLoggedIn, -> 26 | if userService.authEnabled and userService.isLoggedIn() 27 | $(element).show() 28 | else 29 | $(element).hide() 30 | } 31 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/common/services/services.aceService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | /* 18 | * Service for initialization of Ace. 19 | * Will run after all vendor files are loaded (e.g. Ace is already defined) 20 | */ 21 | cyclotronServices.factory('aceService', function () { 22 | 23 | /* Configure ACE editor */ 24 | ace.require('ace/ext/language_tools'); 25 | ace.config.set('workerPath', '/js'); 26 | 27 | return {} 28 | }) 29 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/common/services/services.cryptoService.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronServices.factory 'cryptoService', ($http, $q, configService) -> 18 | 19 | { 20 | # Encrypt a string and return the encrypted form 21 | encrypt: (value) -> 22 | deferred = $q.defer() 23 | 24 | q = $http.post(configService.restServiceUrl + '/crypto/encrypt', { value: value }) 25 | q.success (result) -> 26 | deferred.resolve('!{' + result + '}') 27 | 28 | q.error (error) -> 29 | alertify.error 'Cannot connect to cyclotron-svc (encrypt)', 2500 30 | deferred.reject(error) 31 | 32 | deferred.promise 33 | } 34 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/common/services/services.focusService.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2016-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronServices.factory 'focusService', ($timeout) -> 18 | { 19 | focus: (name, scope) -> 20 | $timeout -> 21 | scope.$broadcast 'focusOn', name 22 | } 23 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/common/services/services.loadService.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronServices.factory 'loadService', (configService, $rootScope) -> 18 | { 19 | setTitle: (title) -> 20 | $rootScope.page_title = title 21 | 22 | removeLoadedCss: -> 23 | $('.loadServiceAsset.temporary').remove() 24 | 25 | loadCssUrl: (url, permanent = false) -> 26 | link = document.createElement("link") 27 | link.type = "text/css" 28 | link.rel = "stylesheet" 29 | link.href = url 30 | link.className = 'loadServiceAsset' 31 | if !permanent then link.className += ' temporary' 32 | 33 | document.getElementsByTagName("head")[0].appendChild(link) 34 | 35 | # loadCssFile: Helper that loads a CSS file 36 | 37 | loadCssInline: (css, permanent = false) -> 38 | style = document.createElement("style") 39 | style.type = 'text/css' 40 | style.className = 'loadServiceAsset' 41 | if !permanent then style.className += ' temporary' 42 | 43 | if style.styleSheet 44 | style.styleSheet.cssText = css 45 | else 46 | style.appendChild document.createTextNode(css) 47 | 48 | document.head.appendChild(style) 49 | } 50 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/common/services/services.logService.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronServices.factory 'logService', ($window, configService) -> 18 | 19 | now = -> $window.moment().format 'HH:mm:ss' 20 | 21 | getString = (obj) -> 22 | if _.isObject obj 23 | JSON.stringify(obj) 24 | else 25 | obj 26 | 27 | # Logs any number of arguments prefixed with the time 28 | writeLog = (args) -> 29 | $window.console.log '[' + now() + '] ' + _.map(args, getString).join ' ' 30 | 31 | writeError = (args) -> 32 | $window.console.error '[' + now() + '] ' + _.map(args, getString).join ' ' 33 | 34 | service = { 35 | debug: -> 36 | args = Array.prototype.slice.call arguments 37 | args.unshift 'DEBUG:' 38 | writeLog args 39 | 40 | info: -> 41 | args = Array.prototype.slice.call arguments 42 | args.unshift 'INFO:' 43 | writeLog args 44 | 45 | error: -> 46 | args = Array.prototype.slice.call arguments 47 | args.unshift 'ERROR:' 48 | writeError args 49 | } 50 | 51 | if configService.logging?.enableDebug == false 52 | service.debug = -> return 53 | 54 | return service 55 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/dashboards/dataSources/dataSources.cyclotronData.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # CyclotronData Data Source 19 | # 20 | # Retrieves data from a CyclotronData bucket. Does not use a proxy. 21 | # 22 | cyclotronDataSources.factory 'cyclotrondataDataSource', ($q, $http, configService, dataSourceFactory) -> 23 | 24 | runner = (options) -> 25 | 26 | q = $q.defer() 27 | 28 | # Runner Failure 29 | errorCallback = (error, status) -> 30 | if error == '' && status == 0 31 | # CORS error 32 | error = 'Cross-Origin Resource Sharing error with the server.' 33 | 34 | q.reject error 35 | 36 | # Successful Result 37 | successCallback = (result) -> 38 | q.resolve 39 | '0': 40 | data: result.data 41 | columns: null 42 | 43 | # Do the request, wiring up success/failure handlers 44 | key = _.jsExec options.key 45 | url = (_.jsExec(options.url) || configService.restServiceUrl) + '/data/' + encodeURIComponent(key) + '/data' 46 | 47 | req = $http.get url 48 | 49 | # Add callback handlers to promise 50 | req.then successCallback 51 | req.error errorCallback 52 | 53 | return q.promise 54 | 55 | dataSourceFactory.create 'CyclotronData', runner 56 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/dashboards/directives/directives.dashboardWidget.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'dashboardWidget', (layoutService) -> 18 | { 19 | restrict: 'AC' 20 | 21 | link: (scope, element, attrs) -> 22 | $element = $(element) 23 | $parent = $element.parent() 24 | 25 | scope.$watch 'widget', (widget) -> 26 | 27 | # Wire-up fullscreen button if available 28 | if widget.allowFullscreen 29 | $parent.find('.widget-fullscreen').on 'click', -> 30 | $element.fullScreen(true) 31 | return 32 | 33 | scope.$watch 'layout', (layout) -> 34 | return unless layout? 35 | 36 | # Set the border width if overloaded (otherwise keep theme default) 37 | if layout.borderWidth? 38 | $element.css('border-width', layout.borderWidth + 'px') 39 | 40 | return 41 | 42 | } 43 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/dashboards/directives/directives.widgetBody.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'widgetBody', ($timeout) -> 18 | { 19 | restrict: 'C' 20 | 21 | link: (scope, element, attrs) -> 22 | $widgetBody = $(element) 23 | $widget = $widgetBody.parent() 24 | 25 | sizer = -> 26 | $title = $widget.find '.title' 27 | $footer = $widget.find '.widget-footer' 28 | widgetBodyHeight = $widget.outerHeight() - $title.outerHeight() - $footer.outerHeight() 29 | widgetBodyHeight -= parseInt($widgetBody.css('marginTop')) + parseInt($widgetBody.css('marginBottom')) 30 | $widgetBody.height Math.floor(widgetBodyHeight) 31 | 32 | if scope.widgetLayout? 33 | scope.widgetLayout.widgetBodyHeight = widgetBodyHeight 34 | 35 | # Update on window resizing 36 | $widget.add('.title, .widget-footer').on 'resize', _.debounce(-> 37 | scope.$apply -> 38 | sizer() 39 | , 120, { leading: false, maxWait: 500 }) 40 | 41 | # Run now & again in 100ms 42 | sizer() 43 | timer = $timeout sizer, 100 44 | 45 | scope.$on '$destroy', -> 46 | $timeout.cancel timer 47 | $widget.off 'resize' 48 | 49 | return 50 | } 51 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/dashboards/services/services.downloadService.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2016-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronServices.factory 'downloadService', ($http, $q, $localForage, $window, analyticsService, configService, logService) -> 18 | 19 | exports = { 20 | 21 | download: (name, format, data) -> 22 | # Post data to /export/data endpoint, get back a URL to the file 23 | # Then download the file 24 | $http.post(configService.restServiceUrl + '/export/data', { name, format, data }) 25 | .then (result) -> 26 | $window.location = result.data.url 27 | alertify.log('Downloaded Widget Data', 2500) 28 | .catch (error) -> 29 | alertify.error 'Error downloading Widget data', 2500 30 | 31 | } 32 | 33 | return exports 34 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/ie8.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # Remove ng-cloak class so the browser incompatibility div is displayed 18 | body = document.getElementsByTagName('body')[0] 19 | body.removeAttribute('class') 20 | 21 | # Remove hidden class on #browserError div 22 | browserError = document.getElementById('browserError') 23 | browserError.removeAttribute('class') 24 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/controller.dataSourceEditor.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # Gui Editor - Data Source controller. 19 | # 20 | cyclotronApp.controller 'DataSourceEditorController', ($scope, $state, $stateParams, configService, dashboardService) -> 21 | 22 | # Store some configuration settings for the Editor 23 | $scope.dashboardProperties = configService.dashboard.properties 24 | $scope.allDataSources = configService.dashboard.properties.dataSources.options 25 | 26 | $scope.$watch 'editor.selectedItemIndex', -> 27 | $scope.dataSourceIndex = $scope.editor.selectedItemIndex 28 | $scope.dataSource = $scope.editor.selectedItem 29 | 30 | $scope.combinedDataSourceProperties = (dataSource) -> 31 | general = _.omit configService.dashboard.properties.dataSources.properties, 'type' 32 | 33 | if dataSource.type? and $scope.allDataSources[dataSource.type]? 34 | specific = $scope.allDataSources[dataSource.type].properties 35 | return _.defaults specific, general 36 | else 37 | return {} 38 | 39 | $scope.dataSourceMessage = -> 40 | $scope.allDataSources[$scope.dataSource.type]?.message 41 | 42 | return 43 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/controller.deleteDashboard.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # Delete Dashboard controller -- for modal dialog 19 | # 20 | cyclotronApp.controller 'DeleteDashboardController', ($scope, $uibModalInstance, dashboardName) -> 21 | 22 | $scope.dashboardName = dashboardName 23 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/controller.encryptString.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # EncryptString controller -- for modal dialog 19 | # 20 | cyclotronApp.controller 'EncryptStringController', ($scope, $uibModalInstance, cryptoService, configService) -> 21 | 22 | $scope.fields = {} 23 | 24 | $scope.encrypt = -> 25 | return if _.isEmpty $scope.fields.value 26 | cryptoService.encrypt($scope.fields.value).then (result) -> 27 | $scope.fields.encryptedValue = result 28 | 29 | $scope.cancel = -> 30 | $uibModalInstance.dismiss('cancel') 31 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/controller.genericErrorModal.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # GenericErrorModalController controller -- for modal dialog 19 | # 20 | cyclotronApp.controller 'GenericErrorModalController', ($scope, $uibModalInstance, $state) -> 21 | 22 | $scope.goHome = -> 23 | $uibModalInstance.dismiss() 24 | $state.go('home') 25 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/controller.help.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # Help controller -- for viewing help pages 19 | # 20 | cyclotronApp.controller 'HelpController', ($scope, $location, configService) -> 21 | 22 | $scope.config = configService 23 | 24 | $scope.menu = configService.help 25 | 26 | $scope.selectItem = (item) -> 27 | $scope.selectedItem = item 28 | $location.search 'q', item.name 29 | 30 | $scope.feelingLucky = -> 31 | $scope.$broadcast 'feelingLucky' 32 | 33 | $scope.findItem = (name) -> 34 | $scope.$broadcast 'findItem', { name: name } 35 | 36 | # Initialization 37 | q = $location.search().q 38 | if q? then $scope.q = q 39 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/controller.pageEditor.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # Gui Editor - Page controller. 19 | # 20 | cyclotronApp.controller 'PageEditorController', ($scope, $stateParams, configService, dashboardService) -> 21 | 22 | $scope.pageExcludes = ['widgets'] 23 | 24 | $scope.$watch 'editor.selectedItemIndex', (pageIndex) -> 25 | $scope.editor.selectedPage = $scope.editor.selectedItem 26 | 27 | $scope.newWidget = (widgetName, pageIndex) -> 28 | dashboardService.addWidget $scope.editor.dashboard, widgetName, pageIndex 29 | 30 | return 31 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/directives/directives.c3chart.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'c3chart', -> 18 | { 19 | restrict: 'EAC' 20 | scope: 21 | data: '=' 22 | options: '=' 23 | 24 | link: (scope, element) -> 25 | 26 | $element = $(element) 27 | scope.width = $element.width() 28 | 29 | # Generate random element ID 30 | if _.isEmpty $element.prop('id') 31 | scope.id = 'c3-' + uuid.v4() 32 | $element.prop 'id', scope.id 33 | 34 | redraw = -> 35 | return unless scope.data? and scope.data.length > 0 36 | 37 | options = 38 | bindto: '#' + scope.id 39 | data: 40 | json: scope.data 41 | size: 42 | height: 200 43 | 44 | # Apply passed options 45 | _.merge options, scope.options 46 | 47 | c3.generate options 48 | 49 | scope.$watch 'data', -> 50 | redraw() 51 | 52 | scope.$watch 'options', -> 53 | redraw() 54 | 55 | } 56 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/directives/directives.editor.view.inlineArray.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'editorViewInlineArray', -> 18 | { 19 | restrict: 'EAC' 20 | scope: 21 | model: '=' 22 | definition: '=' 23 | factory: '&' 24 | headingfn: '&' 25 | 26 | templateUrl: '/partials/editor/inlineArray.html' 27 | transclude: true 28 | 29 | controller: ($scope) -> 30 | 31 | $scope.removeItem = (index) -> 32 | $scope.model.splice(index, 1) 33 | 34 | $scope.addNewObject = -> 35 | $scope.model = [] unless $scope.model? 36 | if $scope.definition.sample? 37 | $scope.model.push _.cloneDeep($scope.definition.sample) 38 | else 39 | $scope.model.push {} 40 | 41 | } 42 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/directives/directives.editor.view.stringArray.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'editorViewStringArray', -> 18 | { 19 | restrict: 'EAC' 20 | scope: 21 | label: '@' 22 | model: '=' 23 | definition: '=' 24 | 25 | templateUrl: '/partials/editor/stringArray.html' 26 | 27 | controller: ($scope) -> 28 | 29 | $scope.addArrayValue = -> 30 | $scope.model = [] unless $scope.model? 31 | $scope.model.push '' 32 | 33 | $scope.updateArrayValue = (index, value) -> 34 | $scope.model[index] = value 35 | 36 | $scope.removeArrayValue = (index) -> 37 | $scope.model.splice(index, 1) 38 | 39 | link: (scope, element, attrs) -> 40 | 41 | scope.label ?= 'Item' 42 | return 43 | 44 | } 45 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/directives/directives.error.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'error', -> 18 | { 19 | restrict: 'CA' 20 | link: (scope, element, attrs) -> 21 | $('body').addClass('errorPage') 22 | } 23 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/directives/directives.focusOn.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2016-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # Listens for focus events and sets focuses on a particular element 19 | # For use with the focusService 20 | # 21 | cyclotronDirectives.directive 'focusOn', -> 22 | { 23 | restrict: 'AC', 24 | link: (scope, element, attrs) -> 25 | scope.$on 'focusOn', (event, name) -> 26 | element[0].focus() if attrs.focusOn == name 27 | } 28 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/directives/directives.jsonedit.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'jsonedit', -> 18 | { 19 | restrict: 'EAC' 20 | scope: 21 | model: '=' 22 | replace: true 23 | template: '
' 24 | 25 | controller: ($scope, dashboardService) -> 26 | 27 | $scope.aceLoaded = (editor) -> 28 | editor.setOptions { 29 | maxLines: Infinity 30 | minLines: 10 31 | enableBasicAutocompletion: true 32 | } 33 | editor.focus() 34 | 35 | # Settings for the JSON Editor 36 | $scope.aceOptions = 37 | useWrapMode : true 38 | showGutter: true 39 | showPrintMargin: false 40 | mode: 'json' 41 | theme: 'chrome' 42 | onLoad: $scope.aceLoaded 43 | 44 | $scope.jsonValue = dashboardService.toString $scope.model 45 | 46 | $scope.$watch 'jsonValue', (json) -> 47 | # Catch parse errors due to incomplete objects 48 | try 49 | if $scope.model? 50 | _.replaceInside $scope.model, dashboardService.parse(json) 51 | else 52 | $scope.model = dashboardService.parse(json) 53 | } 54 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/directives/directives.newUserMessage.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'newUserMessage', -> 18 | { 19 | restrict: 'E' 20 | scope: { } 21 | templateUrl: 'partials/newUserMessage.html' 22 | 23 | link: (scope, element, attrs) -> 24 | return 25 | 26 | controller: ($scope, $timeout, configService, logService, userService) -> 27 | 28 | $scope.message = configService.newUser.welcomeMessage 29 | $scope.iconClass = configService.newUser.iconClass 30 | 31 | $scope.canDisplay = -> 32 | configService.newUser.enableMessage and userService.isNewUser 33 | 34 | $scope.dismiss = -> 35 | userService.notNewUser() 36 | 37 | # Automatically remove New User quality after a fixed period of time on the site 38 | # This won't hide the message if it's currently displayed 39 | duration = configService.newUser.autoDecayDuration 40 | if _.isNumber duration 41 | t = $timeout _.partial(userService.notNewUser, false), duration * 1000 42 | 43 | } 44 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/directives/directives.propertyTable.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'propertyTable', -> 18 | { 19 | restrict: 'EAC' 20 | scope: 21 | properties: '=' 22 | templateUrl: 'partials/help/propertyTable.html' 23 | 24 | link: (scope, element, attrs) -> 25 | return 26 | } 27 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/services/services.exportService.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronServices.factory 'exportService', ($http, configService) -> 18 | 19 | { 20 | # List of all tags 21 | exportAsync: (dashboardName, format, params, callback) -> 22 | uri = configService.restServiceUrl + '/export/' + dashboardName + '/' + format 23 | if params? && _.keys(params).length > 0 24 | paramStrings = _.map _.pairs(params), (pair) -> 25 | pair[0] + '=' + pair[1] 26 | uri += '?' + paramStrings.join('&') 27 | 28 | $http.post(uri).success (result) -> 29 | if _.isFunction(callback) then callback(result) 30 | 31 | getStatus: (statusUrl, callback) -> 32 | $http.get(statusUrl).success (result) -> 33 | if _.isFunction(callback) then callback(result) 34 | } 35 | -------------------------------------------------------------------------------- /cyclotron-site/app/scripts/mgmt/services/services.tagService.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronServices.factory 'tagService', ($http, configService) -> 18 | 19 | { 20 | # List of all tags 21 | getTags: (callback) -> 22 | q = $http.get(configService.restServiceUrl + '/tags') 23 | q.success (tags) -> callback(tags) if _.isFunction(callback) 24 | q.error -> alertify.error 'Cannot connect to cyclotron-svc (getTags)', 2500 25 | 26 | 27 | # List of autocomplete hints suggested when searching 28 | getSearchHints: (callback) -> 29 | q = $http.get(configService.restServiceUrl + '/searchhints') 30 | q.success (searchhints) -> callback(searchhints) if _.isFunction(callback) 31 | q.error -> alertify.error 'Cannot connect to cyclotron-svc (getSearchHints)', 2500 32 | } 33 | -------------------------------------------------------------------------------- /cyclotron-site/app/styles/_widgets.less: -------------------------------------------------------------------------------- 1 | /* Import all Widget styles */ 2 | @import "../widgets/annotationChart/_annotationChart.less"; 3 | @import "../widgets/chart/_chart.less"; 4 | @import "../widgets/clock/_clock.less"; 5 | @import "../widgets/header/_header.less"; 6 | @import "../widgets/html/_html.less"; 7 | @import "../widgets/iframe/_iframe.less"; 8 | @import "../widgets/image/_image.less"; 9 | @import "../widgets/javascript/_javascript.less"; 10 | @import "../widgets/json/_json.less"; 11 | @import "../widgets/number/_number.less"; 12 | @import "../widgets/qrcode/_qrcode.less"; 13 | @import "../widgets/stoplight/_stoplight.less"; 14 | @import "../widgets/table/_table.less"; 15 | @import "../widgets/tableau/_tableau.less"; 16 | @import "../widgets/treemap/_treemap.less"; 17 | @import "../widgets/youtube/_youtube.less"; 18 | -------------------------------------------------------------------------------- /cyclotron-site/app/styles/common/login.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | @import "../../../vendor/lesselements/_elements.less"; 18 | @import "../common/variables.less"; 19 | 20 | .login-modal { 21 | input:invalid { 22 | box-shadow: none; 23 | } 24 | 25 | .login-message { 26 | margin-bottom: 1.5rem; 27 | font-size: 0.9rem; 28 | } 29 | } 30 | 31 | .modal-error { 32 | padding: 0.5rem; 33 | margin-top: 1rem; 34 | } 35 | -------------------------------------------------------------------------------- /cyclotron-site/app/styles/mgmt/errors.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | .error { 18 | position: absolute; 19 | overflow: hidden; 20 | top: 40px; 21 | left: 40px; 22 | margin: 4px 20px; 23 | color: White; 24 | font-family: "Courier New", Courier, monospace; 25 | font-size: 2.5em; 26 | text-align: left; 27 | 28 | @media only screen and (max-width: 500px) { font-size: 1.3em; } 29 | 30 | p { 31 | background-color: Black; 32 | padding: 4px; 33 | } 34 | 35 | a { 36 | color: White; 37 | text-decoration: none; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/annotationChart/_annotationChart.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | .annotation-chart-widget { 18 | overflow-y: hidden; 19 | overflow-x: hidden; 20 | height: 100%; 21 | box-sizing: border-box; 22 | 23 | * { 24 | user-select: none; 25 | outline:none; 26 | box-sizing: border-box; 27 | } 28 | 29 | .the-chart { 30 | width: 100%; 31 | height: 100%; 32 | margin: 0; 33 | padding: 0; 34 | } 35 | 36 | /* Overrides to Google styles */ 37 | .google-visualization-atl .border { 38 | border: none; 39 | } 40 | 41 | .google-visualization-atl .annotationsTdContainer { 42 | border-left: 0px; 43 | } 44 | 45 | .google-visualization-atl .border { 46 | //border: 1px solid #808080; 47 | background-color: @widgetBackgroundColor; 48 | } 49 | 50 | .annotation-editor { 51 | position: absolute; 52 | top: 0; 53 | right: 10px; 54 | 55 | .popover.bottom > .arrow { 56 | left: unset; 57 | right: 3.5rem !important; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/annotationChart/addAnnotation.pug: -------------------------------------------------------------------------------- 1 | div 2 | p {{ annotations.verb }} annotation for {{ selectedPoint.x }}: 3 | 4 | p.form-group 5 | label Title 6 | input(type='text', ng-model='annotations.newAnnotationTitle', placeholder='Annotation Title') 7 | p.form-group 8 | label Text 9 | input(type='text', ng-model='annotations.newAnnotationText', placeholder='Annotation Text') 10 | 11 | p.form-group 12 | button.btn.btn-primary(ng-click='saveAnnotation()') Save 13 | 14 | button.btn.btn-danger.pull-right(ng-click='deleteAnnotation()') Delete 15 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/annotationChart/annotationChart.pug: -------------------------------------------------------------------------------- 1 | .annotation-chart-widget(ng-controller='AnnotationChartWidget') 2 | h1.title(ng-if='::widget.title') {{ widgetTitle() }} 3 | 4 | .annotation-editor(ng-if='selectedPoint') 5 | button.btn.btn-link(type='button', 6 | uib-popover-template='"/widgets/annotationChart/addAnnotation.html"', 7 | popover-title='Annotations', 8 | popover-placement='auto bottom', 9 | popover-is-open='annotations.popoverOpen') 10 | | {{ annotations.verb }} Annotation 11 | 12 | .widget-body 13 | 14 | .widget-loading(spinjs, ng-if='isLoading()') 15 | .widget-error(ng-if='widgetContext.dataSourceError == true && !isLoading()') 16 | .widget-nodata(ng-if='widgetContext.nodata && !isLoading()') 17 | .fa.fa-exclamation-triangle 18 | span {{ widgetContext.nodata }} 19 | 20 | .the-chart(google-chart='google-chart', chart='chartObject', 21 | agc-on-error='handleError(message)', 22 | agc-on-select='selectItem(selectedItem)', 23 | agc-on-range-change='rangeChange(start, end)', 24 | ng-if='!noDataOrError() && chartObject.data') 25 | 26 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/chart/_chart.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | .chart-widget { 18 | overflow-y: hidden; 19 | overflow-x: hidden; 20 | height: 100%; 21 | } 22 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/chart/chart.pug: -------------------------------------------------------------------------------- 1 | .chart-widget(ng-controller='ChartWidget') 2 | h1.title(ng-if='::widget.title') {{ widgetTitle() }} 3 | 4 | .widget-body 5 | .widget-loading(spinjs, ng-if='isLoading()') 6 | .widget-error(ng-if='widgetContext.dataSourceError == true && !isLoading()') 7 | .widget-nodata(ng-if='widgetContext.nodata && !isLoading()') 8 | .fa.fa-exclamation-triangle 9 | span {{ widgetContext.nodata }} 10 | 11 | .highchart(ng-if='!widgetContext.nodata && !widgetContext.dataSourceError', 12 | chart='highchart', theme='widget.theme', addshift='widget.addShiftPoints') 13 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/clock/_clock.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | .clock-widget { 18 | font-size: 24pt; 19 | font-weight: 300; 20 | text-align: center; 21 | padding: 14px; 22 | overflow: auto; 23 | height: 100%; 24 | } 25 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/clock/clock.pug: -------------------------------------------------------------------------------- 1 | div.clock-widget(ng-controller='ClockWidget') 2 | h1.title(ng-if='::widget.title') {{ widgetTitle() }} 3 | .widget-body 4 | .widget-error(ng-if='widgetContext.dataSourceError') 5 | .the-number(number-count='1', is-horizontal='"false"', ng-if='widgetContext.dataSourceError == false') 6 | h1.big {{ currentTime }} 7 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/clock/clockWidget.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # Clock Widget 19 | # 20 | cyclotronApp.controller 'ClockWidget', ($scope, $interval, configService) -> 21 | # Override the widget feature of exporting data, since there is no data 22 | $scope.widgetContext.allowExport = false 23 | 24 | $scope.format = configService.widgets.clock.properties.format.default 25 | $scope.timezone = null 26 | 27 | # Load user-specified format if defined 28 | if !_.isEmpty($scope.widget.format) 29 | $scope.format = _.jsExec $scope.widget.format 30 | 31 | # Load user-specified time-zone if defined 32 | if !_.isEmpty($scope.widget.timezone) 33 | if moment.tz.zone($scope.widget.timezone) 34 | $scope.timezone = _.jsExec $scope.widget.timezone 35 | else 36 | $scope.widgetContext.dataSourceError = true 37 | $scope.widgetContext.dataSourceErrorMessage = '"' + _.jsExec $scope.widget.timezone + '" is not a valid time zone' 38 | 39 | # Schedule an update every second 40 | $scope.updateTime = -> 41 | temp = moment() 42 | if $scope.timezone? 43 | temp = temp.tz($scope.timezone) 44 | $scope.currentTime = temp.format $scope.format 45 | 46 | $scope.updateTime() 47 | $scope.interval = $interval $scope.updateTime, 1000 48 | 49 | # 50 | # Cleanup 51 | # 52 | $scope.$on '$destroy', -> 53 | if $scope.interval? 54 | $interval.cancel $scope.interval 55 | $scope.interval = null 56 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/clock/help.pug: -------------------------------------------------------------------------------- 1 | h3 Clock Widget 2 | p 3 | | The Clock Widget simply shows the current date and time, which is updated every second. 4 | h4 Properties 5 | p. 6 | This widget has 'Format' text box. Enter the format in which you want to see the time. 7 | e.g: 'dddd' in the 'Format' text box gives you only day(Monday or Tuesday etc). 8 | p For more formats, refer 9 | a(href='http://momentjs.com/docs/#/displaying/') this 10 | 11 | property-table(properties='config.widgets.clock.properties') 12 | 13 | 14 | h3 Examples 15 | 16 | h4 Basic usage 17 | p 18 | pre.code. 19 | { 20 | "widget": "clock" 21 | } 22 | h4 With only Day entered 23 | p 24 | pre.code. 25 | { 26 | "format":"ddd", 27 | "widget": "clock" 28 | } 29 | h4 With nothing entered 30 | p 31 | pre.code. 32 | { 33 | "format":"", 34 | "widget": "clock" 35 | } -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/header/header.pug: -------------------------------------------------------------------------------- 1 | div.header-widget(ng-controller='HeaderWidget') 2 | .title(ng-if='showTitle') 3 | a.logo(ng-href='{{ headerTitle.link }}', ng-class='{ actionable: headerTitle.link }') 4 | img(ng-src='{{ headerTitle.logoUrl }}', ng-show='headerTitle.logoUrl', ng-style='{ "height": headerTitle.logoSize }') 5 | a.title(ng-href='{{ headerTitle.link }}', ng-class='{ actionable: headerTitle.link }') 6 | h1(ng-style='{ "font-size": headerTitle.titleSize }') 7 | 8 | span {{ title }} 9 | span.page-name.separator(ng-if='headerTitle.showPageName') {{ headerTitle.pageNameSeparator }} 10 | span.page-name(ng-if='headerTitle.showPageName') {{ page.name }} 11 | 12 | .parameters(ng-if='showParameters && parameters.length > 0') 13 | .header-parameter(ng-repeat='parameter in parameters', dashboard='dashboard', parameter-definition='parameter') 14 | button.btn.btn-link(ng-if='showUpdateButton', ng-click='updateButtonClick()') {{ updateButtonLabel }} 15 | .custom-box(ng-show='showCustomHtml', ng-bind-html='customHtml()') 16 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/header/headerParameter.pug: -------------------------------------------------------------------------------- 1 | .parameter(ng-switch='parameter.editorType') 2 | div(ng-switch-when='dropdown') 3 | label {{ parameter.displayName }}: 4 | select(ng-hide='loading', ng-model='parameter.value', ng-change='updateParameter()', ng-options='item.value as item.name for item in dataSourceData') 5 | i.fa.fa-cog.fa-spin(ng-show='loading') 6 | div.links(ng-switch-when='links') 7 | label {{ parameter.displayName }}: 8 | a.btn.btn-link(ng-hide='loading', ng-repeat='item in dataSourceData', ng-click='selectValue(item.value)', ng-class='{selected: parameter.value == item.value}') {{ item.name }} 9 | i.fa.fa-cog.fa-spin(ng-show='loading') 10 | div(ng-switch-when='checkbox') 11 | label 12 | input(type='checkbox', ng-model='parameter.value', ng-change='updateParameter()') 13 | | {{ parameter.displayName }} 14 | div(ng-switch-when='datetime') 15 | label {{ parameter.displayName }}: 16 | span(datetimepicker, options='parameter.datetimeOptions', ng-model='parameter.value', ng-change='updateParameter()') 17 | div(ng-switch-when='date') 18 | label {{ parameter.displayName }}: 19 | span(datetimepicker, options='parameter.datetimeOptions', ng-model='parameter.value', ng-change='updateParameter()') 20 | div(ng-switch-when='time') 21 | label {{ parameter.displayName }}: 22 | span(datetimepicker, options='parameter.datetimeOptions', ng-model='parameter.value', ng-change='updateParameter()') 23 | div(ng-switch-default) 24 | label {{ parameter.displayName }}: 25 | input(type='text', ng-model='parameter.value', ng-blur='updateParameter()') 26 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/html/_html.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | .html-widget { 18 | overflow-y: auto; 19 | overflow-x: auto; 20 | height: 100%; 21 | } 22 | 23 | .widget-noscroll .html-widget { 24 | overflow-y: hidden; 25 | overflow-x: hidden; 26 | } 27 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/html/directives.htmlRepeater.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'htmlRepeater', ($compile, layoutService) -> 18 | { 19 | restrict: 'A' 20 | 21 | link: (scope, element, attrs) -> 22 | 23 | scope.$watch attrs.htmlRepeater, (htmlStrings) -> 24 | template = '' 25 | 26 | _.each htmlStrings, (html) -> 27 | template += html 28 | 29 | compiledValue = $compile(template)(scope) 30 | 31 | # Replace the current contents with the newly compiled element 32 | element.contents().remove() 33 | element.append(compiledValue) 34 | 35 | return 36 | } 37 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/html/html.pug: -------------------------------------------------------------------------------- 1 | //- Embedded Html Widget 2 | .html-widget(ng-controller='HtmlWidget') 3 | 4 | h1.title(ng-if='::widget.title') {{ widgetTitle() }} 5 | 6 | .widget-body 7 | .widget-loading(spinjs, ng-if='isLoading()') 8 | .widget-error(ng-if='widgetContext.dataSourceError == true && !isLoading()') 9 | .widget-nodata(ng-if='widgetContext.nodata && !isLoading()') 10 | .fa.fa-exclamation-triangle 11 | span {{ widgetContext.nodata }} 12 | 13 | div(ng-if='!noDataOrError()', html-repeater='htmlStrings') 14 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/iframe/_iframe.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | .iframe-widget { 18 | height: 100%; 19 | .box-sizing(border-box); 20 | 21 | > iframe { 22 | .box-sizing(border-box); 23 | display: block; 24 | width: 100%; 25 | height: 100%; 26 | border: 0px; 27 | } 28 | 29 | } 30 | 31 | .widget-noscroll .iframe-widget { 32 | > iframe { 33 | overflow-y: hidden; 34 | overflow-x: hidden; 35 | } 36 | 37 | > iframe::-webkit-scrollbar { 38 | display: none; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/iframe/directives.iframerefresh.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'iframerefresh', ($interval) -> 18 | { 19 | restrict: 'A' 20 | link: (scope, element, attrs) -> 21 | 22 | refresh = parseInt(attrs.iframerefresh) 23 | 24 | if !isNaN(refresh) 25 | intervalFn = -> $(element).attr('src', (i, val) -> val) 26 | intervalPromise = $interval intervalFn, 1000 * attrs.iframerefresh, 0, false 27 | 28 | scope.$on '$destroy', -> 29 | $interval.cancel intervalPromise 30 | 31 | } 32 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/iframe/help.pug: -------------------------------------------------------------------------------- 1 | h3 iframe Widget 2 | p. 3 | The iframe Widget embeds a web site inside a Cyclotron dashboard. It uses an iframe tag (hence the name), 4 | so the target website is loaded completely within the confines of the widget. 5 | 6 | p. 7 | Please note that currently, Cyclotron does not have the ability to provide authentication to the website. 8 | Pages requiring a login (e.g. Jira) can be used, but they will only work correctly if the browser viewing 9 | the dashboard has logged into the website. Otherwise, the widget will most likely show a login screen. 10 | 11 | p 12 | | By default, iframe widgets will have scroll bars if their content is too large for the widget size. This can be suppressed by setting the 13 | em noscroll 14 | | property to true. 15 | 16 | 17 | h4 Properties 18 | p. 19 | These are the properties specific to this widget. 20 | General Cyclotron widget properties are not repeated here (e.g. layout properties). 21 | 22 | property-table(properties='config.widgets.iframe.properties') 23 | 24 | 25 | h3 Examples 26 | 27 | h4 Basic Usage 28 | 29 | p This is the minimum set of properties needed for this widget. 30 | pre.code. 31 | "widgets": [{ 32 | "url": "http://www.expedia.com", 33 | "widget": "iframe" 34 | }] 35 | 36 | 37 | h4 Fullscreen iframe 38 | 39 | p. 40 | This dashboard has a single row/column, which is filled with the iframe. The page margin and widget padding is removed 41 | with style: "fullscreen", which gives the illusion that the target site is loaded directly. 42 | pre.code. 43 | { 44 | "duration": 20, 45 | "name": "example-fullscreen-iframe", 46 | "pages": [{ 47 | "layout": { 48 | "gridColumns": 1, 49 | "gridRows": 1 50 | }, 51 | "widgets": [{ 52 | "gridHeight": 1, 53 | "gridWidth": 1, 54 | "noscroll": true, 55 | "url": "http://www.expedia.com", 56 | "widget": "iframe" 57 | } 58 | ] 59 | } 60 | ], 61 | "style": "fullscreen", 62 | "theme": "dark" 63 | } 64 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/iframe/iframe.pug: -------------------------------------------------------------------------------- 1 | //- iframe Widget 2 | .iframe-widget(ng-controller='IframeWidget') 3 | iframe(ng-src='{{ getUrl() }}', 4 | frameborder='0', 5 | marginheight='0', 6 | marginwidth='0', 7 | width='100%', 8 | height='100%', 9 | scrolling='auto', 10 | webkitAllowFullScreen, 11 | mozAllowFullScreen, 12 | allowFullScreen, 13 | iframerefresh='{{ widget.refresh }}') 14 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/iframe/iframeWidget.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # Iframe Widget 19 | # 20 | cyclotronApp.controller 'IframeWidget', ($scope) -> 21 | # Override the widget feature of exporting data, since there is no data 22 | $scope.widgetContext.allowExport = false 23 | 24 | $scope.getUrl = -> 25 | return '' if _.isEmpty($scope.widget.url) 26 | 27 | url = $scope.widget.url 28 | 29 | if url.indexOf('http') != 0 30 | url = 'http://' + url 31 | 32 | return $scope.$sce.trustAsResourceUrl(url) 33 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/image/_image.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | .image-widget { 18 | height: 100%; 19 | 20 | a, div { 21 | display: block; 22 | height: 100%; 23 | width: 100%; 24 | } 25 | 26 | a { 27 | border-bottom: 0; 28 | > div { 29 | cursor: pointer; 30 | } 31 | } 32 | 33 | .box-sizing(border-box); 34 | } 35 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/image/directives.fancyImage.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'fancyImage', ($interval) -> 18 | { 19 | restrict: 'A' 20 | scope: 21 | image: '=' 22 | link: (scope, element, attrs) -> 23 | $element = $(element) 24 | 25 | scope.$watch 'image', (image) -> 26 | 27 | $element.css { 28 | 'background-image': 'url(' + image.url + ')' 29 | 'background-size': image.backgroundSize || 'cover' 30 | 'background-repeat': image.backgroundRepeat || 'no-repeat' 31 | 'background-position': image.backgroundPosition || 'center' 32 | } 33 | 34 | if image.backgroundColor? 35 | $element.css 'background-color', image.backgroundColor 36 | 37 | if image.filters? 38 | $element.css 'filter', image.filters 39 | 40 | } 41 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/image/image.pug: -------------------------------------------------------------------------------- 1 | .image-widget(ng-controller='ImageWidget') 2 | h1.title(ng-if='::widget.title') {{ widgetTitle() }} 3 | 4 | .widget-body 5 | a(ng-if='link', ng-href='{{ link }}', target='{{ linkTarget() }}') 6 | div(fancy-image, image='currentImage', title='{{ currentImage.tooltip }}') 7 | 8 | div(ng-if='!link', fancy-image, image='currentImage', title='{{ currentImage.tooltip }}') 9 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/image/imageWidget.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronApp.controller 'ImageWidget', ($scope, $interval) -> 18 | # Override the widget feature of exporting data, since there is no data 19 | $scope.widgetContext.allowExport = false 20 | 21 | $scope.duration = $scope.widget.duration * 1000 22 | 23 | $scope.urlIndex = -1 24 | 25 | $scope.loadCurrentImage = -> 26 | $scope.currentImage = _.compile $scope.widget.images?[$scope.urlIndex] 27 | if $scope.currentImage.url? and $scope.currentImage.url.indexOf('http') != 0 28 | $scope.currentImage.url = 'http://' + $scope.currentImage.url 29 | 30 | $scope.link = $scope.currentImage.link 31 | 32 | $scope.linkTarget = -> 33 | if $scope.dashboard.openLinksInNewWindow == false then '_self' else '_blank' 34 | 35 | $scope.rotate = -> 36 | $scope.urlIndex = $scope.urlIndex + 1 37 | if $scope.urlIndex >= $scope.widget.images.length 38 | $scope.urlIndex = 0 39 | 40 | $scope.loadCurrentImage() 41 | 42 | $scope.rotate() 43 | 44 | # Configure rotation 45 | if $scope.duration > 0 and $scope.widget.images.length > 1 46 | $scope.rotateInterval = $interval $scope.rotate, $scope.duration 47 | 48 | # 49 | # Cleanup 50 | # 51 | $scope.$on '$destroy', -> 52 | if $scope.rotateInterval? 53 | $interval.cancel $scope.rotateInterval 54 | $scope.rotateInterval = null 55 | 56 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/javascript/_javascript.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | .javascript-widget { 18 | overflow-y: hidden; 19 | overflow-x: hidden; 20 | height: 100%; 21 | 22 | h1 { 23 | margin-bottom: 10px; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/javascript/javascript.pug: -------------------------------------------------------------------------------- 1 | div.javascript-widget(ng-controller='JavascriptWidget') 2 | h1.title(ng-if='::widget.title') {{ widgetTitle() }} 3 | 4 | .widget-loading(spinjs, ng-if='isLoading()') 5 | .widget-error(ng-if='widgetContext.dataSourceError == true && !isLoading()') 6 | 7 | .js-container(data='widgetContext.data', refresh='widget.refresh', js-object='jsObject') 8 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/json/_json.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | .json-widget { 18 | /* Padding messes up the auto-sizing calculations */ 19 | padding: 0 !important; 20 | 21 | overflow-y: auto; 22 | overflow-x: hidden; 23 | height: 100%; 24 | width: 100%; 25 | position: relative; 26 | 27 | .widget-body { 28 | position: relative; 29 | } 30 | 31 | .ace_editor { 32 | height: 100% !important; 33 | width: 100% !important; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/json/help.pug: -------------------------------------------------------------------------------- 1 | h3 JSON Widget 2 | p. 3 | The JSON Widget displays formatted JSON data from a Data Source. 4 | This can be useful when you want to see the raw response from an API. 5 | 6 | h4 Properties 7 | 8 | property-table(properties='config.widgets.json.properties') 9 | 10 | 11 | h3 Examples 12 | 13 | h4 Basic usage 14 | p 15 | pre.code. 16 | { 17 | "dataSource": "datasource_0", 18 | "widget": "json" 19 | } 20 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/json/json.pug: -------------------------------------------------------------------------------- 1 | div.json-widget(ng-controller='JsonWidget') 2 | h1.title(ng-if='::widget.title') {{ widgetTitle() }} 3 | .widget-body 4 | .widget-loading(spinjs, ng-if='isLoading()') 5 | .widget-error(ng-if='widgetContext.dataSourceError == true && !isLoading()') 6 | .widget-nodata(ng-if='widgetContext.nodata && !isLoading()') 7 | .fa.fa-exclamation-triangle 8 | span {{ widgetContext.nodata }} 9 | 10 | div(ui-ace='aceOptions', ng-model='jsonData') 11 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/linkedWidget/help.pug: -------------------------------------------------------------------------------- 1 | h3 Linked Widget 2 | p. 3 | The Linked Widget allows a Widget to be re-used within the same Dashboard. A typical use-case is displaying the same Header on multiple pages. Using a Linked Widget allows the Header configuration to be defined once, but used multiple times. 4 | 5 | p. 6 | Any instances of a Linked Widget are isolated from each other and the source Widget. Functionally, it is identical to copy/pasting the JSON configuration of a Widget. 7 | 8 | h4 Widget Overrides 9 | 10 | p. 11 | It is possible to override any of the properties of the source Widget. The source Widget's properties are merged with those of the Linked Widget, with any properties of the Linked Widget taking precedence. 12 | 13 | p. 14 | All of the possible properties are not available in the Dashboard Editor, but they can be set via JSON. 15 | 16 | h4 Properties 17 | p. 18 | These are the properties specific to this widget. 19 | General Cyclotron widget properties are not repeated here (e.g. layout properties). 20 | 21 | property-table(properties='config.widgets.linkedWidget.properties') 22 | 23 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/number/_number.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | @footerHeight: 1.4rem; 18 | 19 | .number-widget { 20 | /* Padding messes up the auto-sizing calculations */ 21 | padding: 0 !important; 22 | 23 | overflow-y: auto; 24 | overflow-x: hidden; 25 | height: 100%; 26 | width: 100%; 27 | position: relative; 28 | 29 | .the-number { 30 | > h1 { color: @color; } 31 | 32 | > span { 33 | white-space: nowrap; 34 | } 35 | 36 | &.orientation-vertical { 37 | > h1 { 38 | display: inline; 39 | } 40 | } 41 | 42 | &.orientation-horizontal { 43 | float: left; 44 | display: block; 45 | padding: 6px; 46 | min-width: 5rem; 47 | } 48 | 49 | &.auto-sized { 50 | box-sizing: border-box; 51 | text-align: center; 52 | float: left; 53 | &.orientation-horizontal { 54 | padding: 0; 55 | } 56 | } 57 | } 58 | 59 | img { 60 | height: 2em; 61 | vertical-align: baseline; 62 | } 63 | 64 | .widget-footer { 65 | height: @footerHeight; 66 | white-space: nowrap; 67 | } 68 | 69 | .widget-footer { 70 | z-index: 10; 71 | background: @widgetBackgroundColor; 72 | } 73 | } 74 | 75 | .widget-noscroll .number-widget { 76 | overflow-y: hidden; 77 | overflow-x: hidden; 78 | } 79 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/number/number.pug: -------------------------------------------------------------------------------- 1 | .number-widget(ng-controller='NumberWidget') 2 | 3 | h1.title(ng-if='::widget.title') {{ widgetTitle() }} 4 | 5 | .widget-body 6 | .widget-loading(spinjs, ng-if='isLoading()') 7 | .widget-error(ng-if='widgetContext.dataSourceError == true && !isLoading()') 8 | .widget-nodata(ng-if='widgetContext.nodata && !isLoading()') 9 | .fa.fa-exclamation-triangle 10 | span {{ widgetContext.nodata }} 11 | 12 | .the-number(ng-if='!noDataOrError()', 13 | ng-repeat='number in numbers', 14 | number-count='numberCount', 15 | index='$index', auto-size='widget.autoSize', 16 | is-horizontal='isHorizontal', 17 | class='{{ getClass(number) }}', 18 | ng-click='onClickEvent(number)') 19 | span(ng-if='number.prefix') {{ number.prefix }} 20 | h1.big(title='{{ number.tooltip }}',ng-style='{color: number.color || "inherit"}') {{ number.number }} 21 | i(ng-if='number.icon', title='{{ number.iconTooltip }}', class='fa {{ number.icon }}', ng-style='{color: number.iconColor || "inherit"}') 22 | span(ng-if='number.suffix') {{ number.suffix }} 23 | 24 | 25 | .widget-footer(ng-if='widget.link') 26 | a.link(ng-href='{{ getUrl() }}', target='{{ linkTarget() }}') 27 | i.fa.fa-external-link 28 | | {{ widget.link }} 29 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/qrcode/_qrcode.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | .qrcode-widget { 18 | overflow-y: auto; 19 | overflow-x: hidden; 20 | height: 100%; 21 | width: 100%; 22 | position: relative; 23 | 24 | .qrcode { 25 | margin: auto; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/qrcode/directives.qrcode.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'qrcode', -> 18 | { 19 | restrict: 'C' 20 | scope: 21 | options: '=' 22 | 23 | link: (scope, element, attrs) -> 24 | $element = $(element) 25 | $widget = $element.parent().parent() 26 | 27 | makeCode = _.throttle -> 28 | options = _.clone scope.options 29 | options.correctLevel = QRCode.CorrectLevel.H 30 | 31 | size = Math.min $widget.width(), $widget.height() 32 | if options.maxSize? 33 | size = Math.min size, options.maxSize 34 | 35 | options.width = size 36 | options.height = size 37 | element.css 'width', size + 'px' 38 | element.css 'height', size + 'px' 39 | element.css 'margin-top', ($widget.height() - size) / 2 + 'px' 40 | 41 | element.empty() 42 | new QRCode(element[0], options) 43 | , 75 44 | 45 | scope.$watch 'options', (options) -> 46 | makeCode() 47 | 48 | # Update on window resizing 49 | resizeFunction = _.debounce makeCode, 100, { leading: false, maxWait: 300 } 50 | $widget.on 'resize', resizeFunction 51 | 52 | # 53 | # Cleanup 54 | # 55 | scope.$on '$destroy', -> 56 | $widget.off 'resize', resizeFunction 57 | return 58 | } 59 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/qrcode/help.pug: -------------------------------------------------------------------------------- 1 | h3 QRCode Widget 2 | p. 3 | The QR Code Widget generates a QR code out of the current Dashboard URL or some arbitrary text content. 4 | When using text content, the text can either be hardcoded or loaded from the first row of a Data Source. 5 | 6 | p 7 | | When using a Data Source, only the first row of the result set will be used. Ideally, the Data 8 | | Source would only return one row, but the 9 | em filters/sortBy 10 | | properties can be used to manipulate the result, removing unwanted rows and ordering the correct row 11 | | at the front (ascending). For example, if a Data Source returns daily data for the past month, sorting 12 | | by "-date" would order by date descending, causing the row with the most recent data to appear first. 13 | 14 | h4 Properties 15 | p. 16 | These are the properties specific to this widget. 17 | General Cyclotron widget properties are not repeated here (e.g. layout properties). 18 | 19 | property-table(properties='config.widgets.qrcode.properties') 20 | 21 | h3 Examples 22 | 23 | h4 Hard-coded QR Code 24 | 25 | p This widget generates a QR code from a hard-coded string. 26 | p This example is available on the 27 | a(href='/example-qrcode') example-qrcode 28 | | dashboard 29 | pre.code. 30 | { 31 | "text": "Hello World", 32 | "widget": "qrcode" 33 | } 34 | 35 | h4 Current Dashboard URL 36 | 37 | p This widget generates a QR code with the current URL. 38 | p This example is available on the 39 | a(href='/example-qrcode') example-qrcode 40 | | dashboard 41 | pre.code. 42 | { 43 | "useUrl": true, 44 | "widget": "qrcode" 45 | } 46 | 47 | h4 Data Source-based QR Code 48 | 49 | p This widget uses a dynamic value from a Data Source to generate the QR code. 50 | | If the Data Source automatically refreshes, the QR code will update automatically. 51 | p This example is available on the 52 | a(href='/example-qrcode') example-qrcode 53 | | dashboard 54 | pre.code. 55 | { 56 | "dataSource": "datasource_0", 57 | "text": "#{value}", 58 | "widget": "qrcode" 59 | } 60 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/qrcode/qrcode.pug: -------------------------------------------------------------------------------- 1 | .qrcode-widget(ng-controller='QRCodeWidget') 2 | 3 | .widget-loading(spinjs, ng-if='isLoading()') 4 | .widget-error(ng-if='widgetContext.dataSourceError == true && !isLoading()') 5 | .widget-nodata(ng-if='widgetContext.nodata && !isLoading()') 6 | .fa.fa-exclamation-triangle 7 | span {{ widgetContext.nodata }} 8 | 9 | .qrcode(ng-if='!noDataOrError() && !isLoading()', options='options') 10 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/stoplight/stoplight.pug: -------------------------------------------------------------------------------- 1 | 2 | .stoplight-widget(ng-controller='StoplightWidget') 3 | h1.title(ng-if='::widget.title') {{ widgetTitle() }} 4 | 5 | .widget-body 6 | .widget-loading(spinjs, ng-if='isLoading()') 7 | .widget-error(ng-if='widgetContext.dataSourceError == true && !isLoading()') 8 | .widget-nodata(ng-if='widgetContext.nodata && !isLoading()') 9 | .fa.fa-exclamation-triangle 10 | span {{ widgetContext.nodata }} 11 | 12 | .trafficlight(ng-if='!widgetContext.loading && !widgetContext.dataSourceError', active-color='activeColor', ng-class='{transparent: widgetContext.nodata}', title='{{ tooltip }}') 13 | .protector 14 | .protector 15 | .protector 16 | .trafficlight-inner 17 | .light.red 18 | .light.yellow 19 | .light.green 20 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/table/directives.tableColumn.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'tableColumn', -> 18 | { 19 | restrict: 'CA' 20 | link: (scope, element, attrs) -> 21 | border = scope.column.border 22 | if border? 23 | if border.indexOf('left') >= 0 24 | $(element).css 'border-left-width', '1px' 25 | if border.indexOf('right') >= 0 26 | $(element).css 'border-right-width', '1px' 27 | } 28 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/table/directives.tableRow.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'tableRow', -> 18 | { 19 | restrict: 'CA' 20 | link: (scope, element, attrs) -> 21 | $element = $(element) 22 | $widgetBody = $element.parents '.widget-body' 23 | 24 | if scope.widget.rowHeight? 25 | $element.height scope.widget.rowHeight + 'px' 26 | } 27 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/table/directives.tableRule.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'tableRule', -> 18 | { 19 | restrict: 'CA' 20 | link: (scope, element, attrs) -> 21 | $element = $(element) 22 | rules = scope.row.__matchingRules 23 | 24 | # Apply matching CSS styles 25 | _.each rules, (rule) -> 26 | # Apply all properties (keys) of each rule in turn. 27 | _.each _.keys(rule), (key) -> 28 | return if key == 'columns' or key == 'rule' or key == 'text' 29 | 30 | value = rule[key] 31 | 32 | if _.isNullOrUndefined(rule.columnsAffected) 33 | # Set entire row 34 | $element.css(key, _.compile(value, scope.row)) 35 | else if not _.isNullOrUndefined scope.column 36 | if scope.column.name in rule.columnsAffected 37 | # Replace #value, then compile 38 | value = _.valSub(value, scope.row[scope.column.name]) 39 | value = _.compile(value, scope.row) 40 | 41 | # Set single columns 42 | $element.css(key, value) 43 | } 44 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/tableau/_tableau.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | .tableau-widget { 18 | overflow-y: auto; 19 | overflow-x: auto; 20 | height: 100%; 21 | } 22 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/tableau/directives.tableauPlaceholder.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | cyclotronDirectives.directive 'tableauWidget', -> 18 | { 19 | restrict: 'CA' 20 | 21 | link: ($scope, element, $attrs) -> 22 | $element = $(element) 23 | $scope.actualHeight = $element.height() 24 | $scope.actualWidth = $element.width() 25 | #$viz = $element.find('.tableauViz') 26 | #$viz.attr('height', actualHeight) 27 | #$viz.attr('width', actualWidth) 28 | } 29 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/tableau/help.pug: -------------------------------------------------------------------------------- 1 | h3 Tableau Widget 2 | p 3 | | The Tableau Widget embeds a Tableau view into a Cyclotron widget. This is a simple 4 | | wrapper for the functionality described in 5 | a(href='http://onlinehelp.tableausoftware.com/v7.0/server/en-us/embed.htm') this page. 6 | 7 | 8 | h4 Properties 9 | p. 10 | These are the properties specific to this widget. 11 | General Cyclotron widget properties are not repeated here (e.g. layout properties). 12 | 13 | property-table(properties='config.widgets.tableau.properties') 14 | 15 | h3 Examples 16 | 17 | h4 Basic Usage 18 | 19 | pre.code. 20 | { 21 | "params": { 22 | "host_url": "http%3A%2F%2Ftableau%3A8000%2F", 23 | "name": "Hadoop_Usage_Disk_and_Query/HadoopDiskUsageDashboard", 24 | "site_root": "", 25 | "tabs": "no", 26 | "toolbar": "no" 27 | }, 28 | "widget": "tableau" 29 | } 30 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/tableau/tableau.pug: -------------------------------------------------------------------------------- 1 | .tableau-widget(ng-controller='TableauWidget') 2 | script(src='http://public.tableau.com/javascripts/api/viz_v1.js') 3 | .tableauPlaceholder(style='height: {{ actualHeight }}, width: {{ actualWidth }}') 4 | object.tableauViz(height='{{ actualHeight }}', width='{{ actualWidth }}', style='display:none;') 5 | param(ng-repeat='param in params', name='{{ param.name }}', value='{{ param.value }}') 6 | 7 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/tableau/tableauWidget.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # 18 | # Tableau Widget 19 | # 20 | # Displays a tableau dashboard. 21 | # 22 | 23 | cyclotronApp.controller 'TableauWidget', ($scope) -> 24 | # Override the widget feature of exporting data, since there is no data 25 | $scope.widgetContext.allowExport = false 26 | $scope.params = [] 27 | 28 | if !_.isUndefined($scope.widget.params) 29 | $scope.params = _.map _.keys($scope.widget.params), (key) -> 30 | { 31 | name: key, 32 | value: $scope.widget.params[key] 33 | } 34 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/treemap/treemap.pug: -------------------------------------------------------------------------------- 1 | div.treemap-widget(ng-controller='TreemapWidget') 2 | 3 | h1.title(ng-if='::widget.title') {{ widgetTitle() }} 4 | 5 | .widget-body 6 | .widget-loading(spinjs, ng-if='isLoading()') 7 | .widget-error(ng-if='widgetContext.dataSourceError == true && !isLoading()') 8 | .widget-nodata(ng-if='widgetContext.nodata && !isLoading()') 9 | .fa.fa-exclamation-triangle 10 | span {{ widgetContext.nodata }} 11 | 12 | .treemap(ng-if='!noDataOrError() && treeData', data='treeData', 13 | label-property='labelProperty', 14 | value-property='valueProperty', 15 | value-description='valueDescription', 16 | value-format='valueFormat', 17 | color-property='colorProperty', 18 | color-description='colorDescription', 19 | color-format='colorFormat' 20 | color-stops='colorStops', 21 | show-legend='showLegend', 22 | legend-height='legendHeight') 23 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/youtube/_youtube.less: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | .youtube-widget { 18 | height: 100%; 19 | 20 | .box-sizing(border-box); 21 | } 22 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/youtube/help.pug: -------------------------------------------------------------------------------- 1 | h3 YouTube Widget 2 | p. 3 | The YouTube Widget is used to display one or more videos in a Dashboard Widget. It supports comma-separated lists of videos, or YouTube Playlists. By default, it will automatically begin playing when the Widget is loaded, and loop the video on completion. 4 | 5 | p. 6 | In order to display videos or playlists, the video ID or playlist ID is needed. These can be found in the respective YouTube URLs. Playlist IDs always start with "PL". 7 | 8 | h4 Properties 9 | p. 10 | These are the properties specific to this widget. 11 | General Cyclotron widget properties are not repeated here (e.g. layout properties). 12 | 13 | property-table(properties='config.widgets.youtube.properties') 14 | 15 | h3 Examples 16 | 17 | h4 Basic Usage 18 | 19 | p At its most basic, this Widget displays an YouTube video: 20 | pre.code. 21 | "widgets": [{ 22 | "videoId": "uxpDa-c-4Mc", 23 | "widget": "youtube" 24 | }] 25 | 26 | h4 Fullscreen Playback 27 | 28 | p In order to display a video full-size on a Dashboard page without the standard border, set the "fullscreen" style on the Page: 29 | pre.code. 30 | "pages": [{ 31 | "layout": { 32 | "gridColumns": 1, 33 | "gridRows": 1 34 | }, 35 | "style": "fullscreen", 36 | "widgets": [{ 37 | "videoId": "uxpDa-c-4Mc", 38 | "widget": "youtube" 39 | }] 40 | }] 41 | 42 | h4 Multiple Videos 43 | 44 | p Multiple videos can be played in sequence by providing a comma-separated list of IDs: 45 | pre.code. 46 | "widgets": [{ 47 | "videoId": "cS-hFKC_RKI,pnN2BNrSrXY,72__Mdioty8", 48 | "widget": "youtube" 49 | }] 50 | 51 | h4 Playlists 52 | 53 | p If a playlist ID is provided, the entire playlist will start playing. Note that playlist IDs always start with "PL": 54 | pre.code. 55 | "widgets": [{ 56 | "videoId": "PLdgCSoJzrmKGadxAc1WHfukyzxFII2_-u", 57 | "widget": "youtube" 58 | }] 59 | -------------------------------------------------------------------------------- /cyclotron-site/app/widgets/youtube/youtube.pug: -------------------------------------------------------------------------------- 1 | .youtube-widget(ng-controller='YoutubeWidget') 2 | h1.title(ng-if='::widget.title') {{ widgetTitle() }} 3 | 4 | .widget-body 5 | iframe(ng-src='{{ getUrl() }}', 6 | type="text/html" 7 | frameborder='0', 8 | marginheight='0', 9 | marginwidth='0', 10 | width='100%', 11 | height='100%') 12 | 13 | -------------------------------------------------------------------------------- /cyclotron-site/nginx.conf: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | # Cyclotron Nginx configuration 18 | # 19 | # For more information on configuration, see: 20 | # * Official English Documentation: http://nginx.org/en/docs/ 21 | # * Official Russian Documentation: http://nginx.org/ru/docs/ 22 | 23 | server { 24 | # Default server for port 777 25 | listen 777 default_server; 26 | 27 | gzip on; 28 | gzip_types text/plain text/css text/xml application/xml application/x-javascript text/javascript; 29 | 30 | root /opt/app/cyclotron-site/_public; 31 | 32 | client_max_body_size 0; 33 | 34 | location ~* ^/api/(.*)$ { 35 | rewrite ^/api/(.*)$ /$1 break; 36 | proxy_pass http://localhost:8077; 37 | proxy_redirect off; 38 | proxy_set_header Host $host; 39 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 40 | 41 | client_max_body_size 0; 42 | } 43 | 44 | location / { 45 | try_files $uri /index.html; 46 | add_header Pragma "no-cache"; 47 | add_header Cache-Control "public, must-revalidate"; 48 | 49 | add_header "Access-Control-Allow-Origin" $http_origin; 50 | add_header "Access-Control-Allow-Methods" "GET, OPTIONS"; 51 | } 52 | 53 | location ~* \.(?:ico|gif|jpe?g|png|otf|eot|svg|ttf|woff)$ { 54 | # Some basic cache-control for static files to be sent to the browser 55 | expires 1d; 56 | add_header Pragma public; 57 | add_header Cache-Control public; 58 | } 59 | 60 | location ~* \.(?:js|css)$ { 61 | add_header Pragma "no-cache"; 62 | add_header Cache-Control "public, must-revalidate"; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /cyclotron-site/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cyclotron-site", 3 | "description": "Cyclotron: website", 4 | "version": "2.0.4", 5 | "author": "Dave Bauman ", 6 | "license": "MIT", 7 | "private": true, 8 | "engines": { 9 | "node": ">= 0.10" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/ExpediaInceCommercePlatform/cyclotron" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/ExpediaInceCommercePlatform/cyclotron/issues" 17 | }, 18 | "scripts": { 19 | "start": "npx gulp server", 20 | "build": "npx gulp build", 21 | "test": "npx gulp test", 22 | "clean": "npx gulp clean" 23 | }, 24 | "devDependencies": { 25 | "coffeescript": "~1.7", 26 | "del": "~3.0.0", 27 | "gulp": "~4.0", 28 | "gulp-bower": "0.0.15", 29 | "gulp-clean-css": "~3.10.0", 30 | "gulp-coffee": "~3.0.2", 31 | "gulp-coffeelint": "~0.6.0", 32 | "gulp-concat": "~2.6.1", 33 | "gulp-concat-css": "~3.1.0", 34 | "gulp-connect": "^5.6.1", 35 | "gulp-css-url-adjuster": "~0.2.3", 36 | "gulp-filter": "~5.1.0", 37 | "gulp-flatten": "~0.4.0", 38 | "gulp-less": "~4.0.1", 39 | "gulp-ng-annotate": "~0.5.2", 40 | "gulp-order2": "^2.0.5", 41 | "gulp-output": "~0.0.1", 42 | "gulp-plumber": "~1.2.0", 43 | "gulp-pug": "^4.0.1", 44 | "gulp-rename": "~1.4.0", 45 | "gulp-uglify": "~3.0.1", 46 | "jasmine-core": "~3.2.1", 47 | "karma": "~3.1.4", 48 | "karma-chrome-launcher": "~2.2.0", 49 | "karma-coffee-preprocessor": "~1.0.1", 50 | "karma-coverage": "~1.1.1", 51 | "karma-firefox-launcher": "~1.1.0", 52 | "karma-jasmine": "~1.1.0", 53 | "karma-jasmine-matchers": "~3.8.3", 54 | "karma-nested-reporter": "~0.1.6", 55 | "lodash": "^4.17.15", 56 | "main-bower-files": "^2.13.3", 57 | "merge-stream": "~1.0.1" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /cyclotron-site/test/unit/mixins-valsub-spec.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | # Copyright (c) 2013-2018 the original author or authors. 3 | # 4 | # Licensed under the MIT License (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.opensource.org/licenses/mit-license.php 9 | # 10 | # Unless required by applicable law or agreed to in writing, 11 | # software distributed under the License is distributed on an 12 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | # either express or implied. See the License for the specific 14 | # language governing permissions and limitations under the License. 15 | ### 16 | 17 | describe 'Unit: _.valSub', -> 18 | it 'should return undefined if given undefined', -> 19 | expect(_.valSub(undefined)).toBeUndefined() 20 | 21 | it 'should return null if given null', -> 22 | expect(_.valSub(null)).toBeNull() 23 | 24 | it 'should return the value of the object if null', -> 25 | expect(_.valSub("string", null)).toBe "string" 26 | 27 | it 'should return a number if given a number', -> 28 | expect(_.valSub(99, {})).toBe 99 29 | 30 | it 'should return empty string if given an empty string', -> 31 | expect(_.valSub('', {})).toBeEmptyString() 32 | 33 | it 'should return an unchanged string if it has no #value', -> 34 | expect(_.valSub('hello', {})).toBe 'hello' 35 | 36 | it 'should replace #values at the end of the string', -> 37 | expect(_.valSub('hello #value', 'Dave')).toBe 'hello Dave' 38 | 39 | it 'should replace #values at the beginning of the string', -> 40 | expect(_.valSub('#value is great', 'Dave')).toBe 'Dave is great' 41 | 42 | it 'should replace two #values in the string', -> 43 | expect(_.valSub('#value is #value', 'to be zen')).toBe 'to be zen is to be zen' 44 | 45 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2015 Twitter, Inc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/README.md: -------------------------------------------------------------------------------- 1 | Bootstrap is a sleek, intuitive, and powerful front-end framework for faster and easier web development, created by Mark Otto and Jacob Thornton, and maintained by the core team with the massive support and involvement of the community. 2 | 3 | To get started, check out http://getbootstrap.com! 4 | 5 | ---- 6 | 7 | This included version of Bootstrap has been modified slightly to incorporate Cyclotron-specific styles. The code is from the 3.x branch, but the specific version is unclear. 8 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_alerts.less: -------------------------------------------------------------------------------- 1 | // 2 | // Alerts 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base styles 7 | // ------------------------- 8 | 9 | .alert { 10 | padding: @alert-padding; 11 | margin-bottom: @line-height-computed; 12 | border: 1px solid transparent; 13 | border-radius: @alert-border-radius; 14 | 15 | // Headings for larger alerts 16 | h4 { 17 | margin-top: 0; 18 | // Specified for the h4 to prevent conflicts of changing @headings-color 19 | color: inherit; 20 | } 21 | // Provide class for links that match alerts 22 | .alert-link { 23 | font-weight: @alert-link-font-weight; 24 | } 25 | 26 | // Improve alignment and spacing of inner content 27 | > p, 28 | > ul { 29 | margin-bottom: 0; 30 | } 31 | > p + p { 32 | margin-top: 5px; 33 | } 34 | } 35 | 36 | // Dismissable alerts 37 | // 38 | // Expand the right padding and account for the close button's positioning. 39 | 40 | .alert-dismissable { 41 | padding-right: (@alert-padding + 20); 42 | 43 | // Adjust close link position 44 | .close { 45 | position: relative; 46 | top: -2px; 47 | right: -21px; 48 | color: inherit; 49 | } 50 | } 51 | 52 | // Alternate styles 53 | // 54 | // Generate contextual modifier classes for colorizing the alert. 55 | 56 | .alert-success { 57 | .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text); 58 | } 59 | .alert-info { 60 | .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text); 61 | } 62 | .alert-warning { 63 | .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text); 64 | } 65 | .alert-danger { 66 | .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text); 67 | } 68 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_badges.less: -------------------------------------------------------------------------------- 1 | // 2 | // Badges 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base classes 7 | .badge { 8 | display: inline-block; 9 | min-width: 10px; 10 | padding: 3px 7px; 11 | font-size: @font-size-small; 12 | font-weight: @badge-font-weight; 13 | color: @badge-color; 14 | line-height: @badge-line-height; 15 | vertical-align: baseline; 16 | white-space: nowrap; 17 | text-align: center; 18 | background-color: @badge-bg; 19 | border-radius: @badge-border-radius; 20 | 21 | // Empty badges collapse automatically (not available in IE8) 22 | &:empty { 23 | display: none; 24 | } 25 | 26 | // Quick fix for badges in buttons 27 | .btn & { 28 | position: relative; 29 | top: -1px; 30 | } 31 | .btn-xs & { 32 | top: 0; 33 | padding: 1px 5px; 34 | } 35 | } 36 | 37 | // Hover state, but only for links 38 | a.badge { 39 | &:hover, 40 | &:focus { 41 | color: @badge-link-hover-color; 42 | text-decoration: none; 43 | cursor: pointer; 44 | } 45 | } 46 | 47 | // Account for counters in navs 48 | a.list-group-item.active > .badge, 49 | .nav-pills > .active > a > .badge { 50 | color: @badge-active-color; 51 | background-color: @badge-active-bg; 52 | } 53 | .nav-pills > li > a > .badge { 54 | margin-left: 3px; 55 | } 56 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_breadcrumbs.less: -------------------------------------------------------------------------------- 1 | // 2 | // Breadcrumbs 3 | // -------------------------------------------------- 4 | 5 | 6 | .breadcrumb { 7 | padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal; 8 | margin-bottom: @line-height-computed; 9 | list-style: none; 10 | background-color: @breadcrumb-bg; 11 | border-radius: @border-radius-base; 12 | 13 | > li { 14 | display: inline-block; 15 | 16 | + li:before { 17 | content: "@{breadcrumb-separator}\00a0"; // Unicode space added since inline-block means non-collapsing white-space 18 | padding: 0 5px; 19 | color: @breadcrumb-color; 20 | } 21 | } 22 | 23 | > .active { 24 | color: @breadcrumb-active-color; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_close.less: -------------------------------------------------------------------------------- 1 | // 2 | // Close icons 3 | // -------------------------------------------------- 4 | 5 | 6 | .close { 7 | float: right; 8 | font-size: (@font-size-base * 1.5); 9 | font-weight: @close-font-weight; 10 | line-height: 1; 11 | color: @close-color; 12 | text-shadow: @close-text-shadow; 13 | .opacity(.2); 14 | 15 | &:hover, 16 | &:focus { 17 | color: @close-color; 18 | text-decoration: none; 19 | cursor: pointer; 20 | .opacity(.5); 21 | } 22 | 23 | // Additional properties for button version 24 | // iOS requires the button element instead of an anchor tag. 25 | // If you want the anchor version, it requires `href="#"`. 26 | button& { 27 | padding: 0; 28 | cursor: pointer; 29 | background: transparent; 30 | border: 0; 31 | -webkit-appearance: none; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_code.less: -------------------------------------------------------------------------------- 1 | // 2 | // Code (inline and block) 3 | // -------------------------------------------------- 4 | 5 | 6 | // Inline and block code styles 7 | code, 8 | kbd, 9 | pre, 10 | samp { 11 | font-family: @font-family-monospace; 12 | } 13 | 14 | // Inline code 15 | code { 16 | padding: 2px 4px; 17 | font-size: 90%; 18 | color: @code-color; 19 | background-color: @code-bg; 20 | white-space: nowrap; 21 | border-radius: @border-radius-base; 22 | } 23 | 24 | // User input typically entered via keyboard 25 | kbd { 26 | padding: 2px 4px; 27 | font-size: 90%; 28 | color: @kbd-color; 29 | background-color: @kbd-bg; 30 | border-radius: @border-radius-small; 31 | box-shadow: inset 0 -1px 0 rgba(0,0,0,.25); 32 | } 33 | 34 | // Blocks of code 35 | pre { 36 | display: block; 37 | padding: ((@line-height-computed - 1) / 2); 38 | margin: 0 0 (@line-height-computed / 2); 39 | font-size: (@font-size-base - 1); // 14px to 13px 40 | line-height: @line-height-base; 41 | word-break: break-all; 42 | word-wrap: break-word; 43 | color: @pre-color; 44 | background-color: @pre-bg; 45 | border: 1px solid @pre-border-color; 46 | border-radius: @border-radius-base; 47 | 48 | // Account for some code outputs that place code tags in pre tags 49 | code { 50 | padding: 0; 51 | font-size: inherit; 52 | color: inherit; 53 | white-space: pre-wrap; 54 | background-color: transparent; 55 | border-radius: 0; 56 | } 57 | } 58 | 59 | // Enable scrollable blocks of code 60 | .pre-scrollable { 61 | max-height: @pre-scrollable-max-height; 62 | overflow-y: scroll; 63 | } 64 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_component-animations.less: -------------------------------------------------------------------------------- 1 | // 2 | // Component animations 3 | // -------------------------------------------------- 4 | 5 | // Heads up! 6 | // 7 | // We don't use the `.opacity()` mixin here since it causes a bug with text 8 | // fields in IE7-8. Source: https://github.com/twitter/bootstrap/pull/3552. 9 | 10 | .fade { 11 | opacity: 0; 12 | .transition(opacity .15s linear); 13 | &.in { 14 | opacity: 1; 15 | } 16 | } 17 | 18 | .collapse { 19 | display: none; 20 | &.in { 21 | display: block; 22 | } 23 | } 24 | .collapsing { 25 | position: relative; 26 | height: 0; 27 | overflow: hidden; 28 | .transition(height .35s ease); 29 | } 30 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_grid.less: -------------------------------------------------------------------------------- 1 | // 2 | // Grid system 3 | // -------------------------------------------------- 4 | 5 | 6 | // Container widths 7 | // 8 | // Set the container width, and override it for fixed navbars in media queries. 9 | 10 | .container { 11 | .container-fixed(); 12 | 13 | @media (min-width: @screen-sm-min) { 14 | width: @container-sm; 15 | } 16 | @media (min-width: @screen-md-min) { 17 | width: @container-md; 18 | } 19 | @media (min-width: @screen-lg-min) { 20 | width: @container-lg; 21 | } 22 | } 23 | 24 | 25 | // Fluid container 26 | // 27 | // Utilizes the mixin meant for fixed width containers, but without any defined 28 | // width for fluid, full width layouts. 29 | 30 | .container-fluid { 31 | .container-fixed(); 32 | } 33 | 34 | 35 | // Row 36 | // 37 | // Rows contain and clear the floats of your columns. 38 | 39 | .row { 40 | .make-row(); 41 | } 42 | 43 | 44 | // Columns 45 | // 46 | // Common styles for small and large grid columns 47 | 48 | .make-grid-columns(); 49 | 50 | 51 | // Extra small grid 52 | // 53 | // Columns, offsets, pushes, and pulls for extra small devices like 54 | // smartphones. 55 | 56 | .make-grid(xs); 57 | 58 | 59 | // Small grid 60 | // 61 | // Columns, offsets, pushes, and pulls for the small device range, from phones 62 | // to tablets. 63 | 64 | @media (min-width: @screen-sm-min) { 65 | .make-grid(sm); 66 | } 67 | 68 | 69 | // Medium grid 70 | // 71 | // Columns, offsets, pushes, and pulls for the desktop device range. 72 | 73 | @media (min-width: @screen-md-min) { 74 | .make-grid(md); 75 | } 76 | 77 | 78 | // Large grid 79 | // 80 | // Columns, offsets, pushes, and pulls for the large desktop device range. 81 | 82 | @media (min-width: @screen-lg-min) { 83 | .make-grid(lg); 84 | } 85 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_jumbotron.less: -------------------------------------------------------------------------------- 1 | // 2 | // Jumbotron 3 | // -------------------------------------------------- 4 | 5 | 6 | .jumbotron { 7 | padding: @jumbotron-padding; 8 | margin-bottom: @jumbotron-padding; 9 | color: @jumbotron-color; 10 | background-color: @jumbotron-bg; 11 | 12 | h1, 13 | .h1 { 14 | color: @jumbotron-heading-color; 15 | } 16 | p { 17 | margin-bottom: (@jumbotron-padding / 2); 18 | font-size: @jumbotron-font-size; 19 | font-weight: 200; 20 | } 21 | 22 | .container & { 23 | border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container 24 | } 25 | 26 | .container { 27 | max-width: 100%; 28 | } 29 | 30 | @media screen and (min-width: @screen-sm-min) { 31 | padding-top: (@jumbotron-padding * 1.6); 32 | padding-bottom: (@jumbotron-padding * 1.6); 33 | 34 | .container & { 35 | padding-left: (@jumbotron-padding * 2); 36 | padding-right: (@jumbotron-padding * 2); 37 | } 38 | 39 | h1, 40 | .h1 { 41 | font-size: (@font-size-base * 4.5); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_labels.less: -------------------------------------------------------------------------------- 1 | // 2 | // Labels 3 | // -------------------------------------------------- 4 | 5 | .label { 6 | display: inline; 7 | padding: .2em .6em .3em; 8 | font-size: 75%; 9 | font-weight: bold; 10 | line-height: 1; 11 | color: @label-color; 12 | text-align: center; 13 | white-space: nowrap; 14 | vertical-align: baseline; 15 | border-radius: .25em; 16 | 17 | // Add hover effects, but only for links 18 | &[href] { 19 | &:hover, 20 | &:focus { 21 | color: @label-link-hover-color; 22 | text-decoration: none; 23 | cursor: pointer; 24 | } 25 | } 26 | 27 | // Empty labels collapse automatically (not available in IE8) 28 | &:empty { 29 | display: none; 30 | } 31 | 32 | // Quick fix for labels in buttons 33 | .btn & { 34 | position: relative; 35 | top: -1px; 36 | } 37 | } 38 | 39 | // Colors 40 | // Contextual variations (linked labels get darker on :hover) 41 | 42 | .label-default { 43 | .label-variant(@label-default-bg); 44 | } 45 | 46 | .label-primary { 47 | .label-variant(@label-primary-bg); 48 | } 49 | 50 | .label-success { 51 | .label-variant(@label-success-bg); 52 | } 53 | 54 | .label-info { 55 | .label-variant(@label-info-bg); 56 | } 57 | 58 | .label-warning { 59 | .label-variant(@label-warning-bg); 60 | } 61 | 62 | .label-danger { 63 | .label-variant(@label-danger-bg); 64 | } 65 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_media.less: -------------------------------------------------------------------------------- 1 | // Media objects 2 | // Source: http://stubbornella.org/content/?p=497 3 | // -------------------------------------------------- 4 | 5 | 6 | // Common styles 7 | // ------------------------- 8 | 9 | // Clear the floats 10 | .media, 11 | .media-body { 12 | overflow: hidden; 13 | zoom: 1; 14 | } 15 | 16 | // Proper spacing between instances of .media 17 | .media, 18 | .media .media { 19 | margin-top: 15px; 20 | } 21 | .media:first-child { 22 | margin-top: 0; 23 | } 24 | 25 | // For images and videos, set to block 26 | .media-object { 27 | display: block; 28 | } 29 | 30 | // Reset margins on headings for tighter default spacing 31 | .media-heading { 32 | margin: 0 0 5px; 33 | } 34 | 35 | 36 | // Media image alignment 37 | // ------------------------- 38 | 39 | .media { 40 | > .pull-left { 41 | margin-right: 10px; 42 | } 43 | > .pull-right { 44 | margin-left: 10px; 45 | } 46 | } 47 | 48 | 49 | // Media list variation 50 | // ------------------------- 51 | 52 | // Undo default ul/ol styles 53 | .media-list { 54 | padding-left: 0; 55 | list-style: none; 56 | } 57 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_pager.less: -------------------------------------------------------------------------------- 1 | // 2 | // Pager pagination 3 | // -------------------------------------------------- 4 | 5 | 6 | .pager { 7 | padding-left: 0; 8 | margin: @line-height-computed 0; 9 | list-style: none; 10 | text-align: center; 11 | &:extend(.clearfix all); 12 | li { 13 | display: inline; 14 | > a, 15 | > span { 16 | display: inline-block; 17 | padding: 5px 14px; 18 | background-color: @pager-bg; 19 | border: 1px solid @pager-border; 20 | border-radius: @pager-border-radius; 21 | } 22 | 23 | > a:hover, 24 | > a:focus { 25 | text-decoration: none; 26 | background-color: @pager-hover-bg; 27 | } 28 | } 29 | 30 | .next { 31 | > a, 32 | > span { 33 | float: right; 34 | } 35 | } 36 | 37 | .previous { 38 | > a, 39 | > span { 40 | float: left; 41 | } 42 | } 43 | 44 | .disabled { 45 | > a, 46 | > a:hover, 47 | > a:focus, 48 | > span { 49 | color: @pager-disabled-color; 50 | background-color: @pager-bg; 51 | cursor: not-allowed; 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_pagination.less: -------------------------------------------------------------------------------- 1 | // 2 | // Pagination (multiple pages) 3 | // -------------------------------------------------- 4 | .pagination { 5 | display: inline-block; 6 | padding-left: 0; 7 | margin: @line-height-computed 0; 8 | border-radius: @border-radius-base; 9 | 10 | > li { 11 | display: inline; // Remove list-style and block-level defaults 12 | > a, 13 | > span { 14 | position: relative; 15 | float: left; // Collapse white-space 16 | padding: @padding-base-vertical @padding-base-horizontal; 17 | line-height: @line-height-base; 18 | text-decoration: none; 19 | color: @pagination-color; 20 | background-color: @pagination-bg; 21 | border: 1px solid @pagination-border; 22 | margin-left: -1px; 23 | } 24 | &:first-child { 25 | > a, 26 | > span { 27 | margin-left: 0; 28 | .border-left-radius(@border-radius-base); 29 | } 30 | } 31 | &:last-child { 32 | > a, 33 | > span { 34 | .border-right-radius(@border-radius-base); 35 | } 36 | } 37 | } 38 | 39 | > li > a, 40 | > li > span { 41 | &:hover, 42 | &:focus { 43 | color: @pagination-hover-color; 44 | background-color: @pagination-hover-bg; 45 | border-color: @pagination-hover-border; 46 | } 47 | } 48 | 49 | > .active > a, 50 | > .active > span { 51 | &, 52 | &:hover, 53 | &:focus { 54 | z-index: 2; 55 | color: @pagination-active-color; 56 | background-color: @pagination-active-bg; 57 | border-color: @pagination-active-border; 58 | cursor: default; 59 | } 60 | } 61 | 62 | > .disabled { 63 | > span, 64 | > span:hover, 65 | > span:focus, 66 | > a, 67 | > a:hover, 68 | > a:focus { 69 | color: @pagination-disabled-color; 70 | background-color: @pagination-disabled-bg; 71 | border-color: @pagination-disabled-border; 72 | cursor: not-allowed; 73 | } 74 | } 75 | } 76 | 77 | // Sizing 78 | // -------------------------------------------------- 79 | 80 | // Large 81 | .pagination-lg { 82 | .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large); 83 | } 84 | 85 | // Small 86 | .pagination-sm { 87 | .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small); 88 | } 89 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_print.less: -------------------------------------------------------------------------------- 1 | // 2 | // Basic print styles 3 | // -------------------------------------------------- 4 | // Source: https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css 5 | 6 | @media print { 7 | 8 | * { 9 | text-shadow: none !important; 10 | color: #000 !important; // Black prints faster: h5bp.com/s 11 | background: transparent !important; 12 | box-shadow: none !important; 13 | } 14 | 15 | a, 16 | a:visited { 17 | text-decoration: underline; 18 | } 19 | 20 | a[href]:after { 21 | content: " (" attr(href) ")"; 22 | } 23 | 24 | abbr[title]:after { 25 | content: " (" attr(title) ")"; 26 | } 27 | 28 | // Don't show links for images, or javascript/internal links 29 | a[href^="javascript:"]:after, 30 | a[href^="#"]:after { 31 | content: ""; 32 | } 33 | 34 | pre, 35 | blockquote { 36 | border: 1px solid #999; 37 | page-break-inside: avoid; 38 | } 39 | 40 | thead { 41 | display: table-header-group; // h5bp.com/t 42 | } 43 | 44 | tr, 45 | img { 46 | page-break-inside: avoid; 47 | } 48 | 49 | img { 50 | max-width: 100% !important; 51 | } 52 | 53 | p, 54 | h2, 55 | h3 { 56 | orphans: 3; 57 | widows: 3; 58 | } 59 | 60 | h2, 61 | h3 { 62 | page-break-after: avoid; 63 | } 64 | 65 | // Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245 66 | // Once fixed, we can just straight up remove this. 67 | select { 68 | background: #fff !important; 69 | } 70 | 71 | // Bootstrap components 72 | .navbar { 73 | display: none; 74 | } 75 | .table { 76 | td, 77 | th { 78 | background-color: #fff !important; 79 | } 80 | } 81 | .btn, 82 | .dropup > .btn { 83 | > .caret { 84 | border-top-color: #000 !important; 85 | } 86 | } 87 | .label { 88 | border: 1px solid #000; 89 | } 90 | 91 | .table { 92 | border-collapse: collapse !important; 93 | } 94 | .table-bordered { 95 | th, 96 | td { 97 | border: 1px solid #ddd !important; 98 | } 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_progress-bars.less: -------------------------------------------------------------------------------- 1 | // 2 | // Progress bars 3 | // -------------------------------------------------- 4 | 5 | 6 | // Bar animations 7 | // ------------------------- 8 | 9 | // WebKit 10 | @-webkit-keyframes progress-bar-stripes { 11 | from { background-position: 40px 0; } 12 | to { background-position: 0 0; } 13 | } 14 | 15 | // Spec and IE10+ 16 | @keyframes progress-bar-stripes { 17 | from { background-position: 40px 0; } 18 | to { background-position: 0 0; } 19 | } 20 | 21 | 22 | 23 | // Bar itself 24 | // ------------------------- 25 | 26 | // Outer container 27 | .progress { 28 | overflow: hidden; 29 | height: @line-height-computed; 30 | margin-bottom: @line-height-computed; 31 | background-color: @progress-bg; 32 | border-radius: @border-radius-base; 33 | .box-shadow(inset 0 1px 2px rgba(0,0,0,.1)); 34 | } 35 | 36 | // Bar of progress 37 | .progress-bar { 38 | float: left; 39 | width: 0%; 40 | height: 100%; 41 | font-size: @font-size-small; 42 | line-height: @line-height-computed; 43 | color: @progress-bar-color; 44 | text-align: center; 45 | background-color: @progress-bar-bg; 46 | .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15)); 47 | .transition(width .6s ease); 48 | } 49 | 50 | // Striped bars 51 | .progress-striped .progress-bar { 52 | #gradient > .striped(); 53 | background-size: 40px 40px; 54 | } 55 | 56 | // Call animation for the active one 57 | .progress.active .progress-bar { 58 | .animation(progress-bar-stripes 2s linear infinite); 59 | } 60 | 61 | 62 | 63 | // Variations 64 | // ------------------------- 65 | 66 | .progress-bar-success { 67 | .progress-bar-variant(@progress-bar-success-bg); 68 | } 69 | 70 | .progress-bar-info { 71 | .progress-bar-variant(@progress-bar-info-bg); 72 | } 73 | 74 | .progress-bar-warning { 75 | .progress-bar-variant(@progress-bar-warning-bg); 76 | } 77 | 78 | .progress-bar-danger { 79 | .progress-bar-variant(@progress-bar-danger-bg); 80 | } 81 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_thumbnails.less: -------------------------------------------------------------------------------- 1 | // 2 | // Thumbnails 3 | // -------------------------------------------------- 4 | 5 | 6 | // Mixin and adjust the regular image class 7 | .thumbnail { 8 | display: block; 9 | padding: @thumbnail-padding; 10 | margin-bottom: @line-height-computed; 11 | line-height: @line-height-base; 12 | background-color: @thumbnail-bg; 13 | border: 1px solid @thumbnail-border; 14 | border-radius: @thumbnail-border-radius; 15 | .transition(all .2s ease-in-out); 16 | 17 | > img, 18 | a > img { 19 | &:extend(.img-responsive); 20 | margin-left: auto; 21 | margin-right: auto; 22 | } 23 | 24 | // Add a hover state for linked versions only 25 | a&:hover, 26 | a&:focus, 27 | a&.active { 28 | border-color: @link-color; 29 | } 30 | 31 | // Image captions 32 | .caption { 33 | padding: @thumbnail-caption-padding; 34 | color: @thumbnail-caption-color; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_utilities.less: -------------------------------------------------------------------------------- 1 | // 2 | // Utility classes 3 | // -------------------------------------------------- 4 | 5 | 6 | // Floats 7 | // ------------------------- 8 | 9 | .clearfix { 10 | .clearfix(); 11 | } 12 | .center-block { 13 | .center-block(); 14 | } 15 | .pull-right { 16 | float: right !important; 17 | } 18 | .pull-left { 19 | float: left !important; 20 | } 21 | 22 | 23 | // Toggling content 24 | // ------------------------- 25 | 26 | // Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1 27 | .hide { 28 | display: none !important; 29 | } 30 | .show { 31 | display: block !important; 32 | } 33 | .invisible { 34 | visibility: hidden; 35 | } 36 | .text-hide { 37 | .text-hide(); 38 | } 39 | 40 | 41 | // Hide from screenreaders and browsers 42 | // 43 | // Credit: HTML5 Boilerplate 44 | 45 | .hidden { 46 | display: none !important; 47 | visibility: hidden !important; 48 | } 49 | 50 | 51 | // For Affix plugin 52 | // ------------------------- 53 | 54 | .affix { 55 | position: fixed; 56 | } 57 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/_wells.less: -------------------------------------------------------------------------------- 1 | // 2 | // Wells 3 | // -------------------------------------------------- 4 | 5 | 6 | // Base class 7 | .well { 8 | min-height: 20px; 9 | padding: 19px; 10 | margin-bottom: 20px; 11 | background-color: @well-bg; 12 | border: 1px solid @well-border; 13 | border-radius: @border-radius-base; 14 | .box-shadow(inset 0 1px 1px rgba(0,0,0,.05)); 15 | blockquote { 16 | border-color: #ddd; 17 | border-color: rgba(0,0,0,.15); 18 | } 19 | } 20 | 21 | // Sizes 22 | .well-lg { 23 | padding: 24px; 24 | border-radius: @border-radius-large; 25 | } 26 | .well-sm { 27 | padding: 9px; 28 | border-radius: @border-radius-small; 29 | } 30 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/bootstrap/bootstrap.less: -------------------------------------------------------------------------------- 1 | // Core variables and mixins 2 | @import "_variables.less"; 3 | @import "_mixins.less"; 4 | 5 | // Reset 6 | @import "_normalize.less"; 7 | //@import "_print.less"; 8 | 9 | // Core CSS 10 | //@import "_scaffolding.less"; 11 | @import "_type.less"; 12 | @import "_code.less"; 13 | @import "_grid.less"; 14 | @import "_tables.less"; 15 | @import "_forms.less"; 16 | @import "_buttons.less"; 17 | 18 | // Components 19 | @import "_component-animations.less"; 20 | //@import "_glyphicons.less"; 21 | @import "_dropdowns.less"; 22 | @import "_button-groups.less"; 23 | @import "_input-groups.less"; 24 | @import "_navs.less"; 25 | @import "_navbar.less"; 26 | @import "_breadcrumbs.less"; 27 | @import "_pagination.less"; 28 | @import "_pager.less"; 29 | @import "_labels.less"; 30 | @import "_badges.less"; 31 | @import "_jumbotron.less"; 32 | @import "_thumbnails.less"; 33 | @import "_alerts.less"; 34 | @import "_progress-bars.less"; 35 | @import "_media.less"; 36 | @import "_list-group.less"; 37 | @import "_panels.less"; 38 | @import "_wells.less"; 39 | @import "_close.less"; 40 | 41 | // Components w/ JavaScript 42 | @import "_modals.less"; 43 | @import "_tooltip.less"; 44 | @import "_popovers.less"; 45 | @import "_carousel.less"; 46 | 47 | // Utility classes 48 | @import "_utilities.less"; 49 | @import "_responsive-utilities.less"; 50 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/lesselements/LICENSE: -------------------------------------------------------------------------------- 1 | This work is dedicated to the public domain and is free for all uses, commercial or otherwise. No form of credit required. 2 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/lesselements/README.md: -------------------------------------------------------------------------------- 1 | LESS Elements 2 | "A set of basic mixins for the LESS CSS pre-processor. Most of these mixins focus on consolidating cross-browser prefixes into single, concise declarations. LESS Elements is not an extensive mixin library — just the essentials." 3 | 4 | http://lesselements.com/ 5 | 6 | Downloaded from https://github.com/dmitryf/elements/blob/master/elements.less -------------------------------------------------------------------------------- /cyclotron-site/vendor/modernizr/LICENSE: -------------------------------------------------------------------------------- 1 | Modernizr 3.3.1 (Custom Build) | MIT 2 | -------------------------------------------------------------------------------- /cyclotron-site/vendor/modernizr/README.md: -------------------------------------------------------------------------------- 1 | Modernizr 2 | "Modernizr is a JavaScript library that detects HTML5 and CSS3 features in the user’s browser." 3 | http://modernizr.com/ 4 | 5 | Downloaded custom build (URL available in comment) -------------------------------------------------------------------------------- /cyclotron-svc/.gitignore: -------------------------------------------------------------------------------- 1 | # Configuration 2 | config/config.js 3 | 4 | # Root CAs 5 | config/*.crt 6 | config/*.pem 7 | 8 | # Exports 9 | export/* 10 | 11 | -------------------------------------------------------------------------------- /cyclotron-svc/README.md: -------------------------------------------------------------------------------- 1 | # Cyclotron-svc 2 | 3 | This folder contains the REST API for Cyclotron. It is a [Node.js](http://nodejs.org/) application, built with [Express](http://expressjs.com/). Data is stored in [MongoDB](http://www.mongodb.org/) using the [Mongoose](http://mongoosejs.com/) library. 4 | 5 | ## Installation 6 | 7 | Refer to the installation instructions in the parent [README.md](../README.md). 8 | 9 | ## Configuration 10 | 11 | The service configuration is located in `config/config.js`. This file is missing by default, but there are sample templates in the same folder which can be copied and used. The service will not start without the config file in place. 12 | 13 | The available configuration properties are documented in `config/sample.config.js'. This config file can be used as-is to connect to a local MongoDB server, or used as a starting point for a new configuration. 14 | 15 | ## Deployment 16 | 17 | Deploying Cyclotron on a server is dependent on the OS. The primary concern is running the web service as a daemon instead of a user account. Included in the `cyclotron-svc/init.d/` folder is a sample sysvinit script which can be used in many flavors of Linux. 18 | 19 | 1. Install Node.js and npm 20 | 21 | 2. Install the cyclotron-svc files onto the server, for example: `/opt/app/cyclotron-svc` 22 | 23 | 3. Create the configuration file in `/opt/app/cyclotron-svc/config/` 24 | 25 | 4. Copy the `cyclotron-svc/init.d/cyclotron-svc` script to `/etc/init.d/cyclotron-svc` 26 | 27 | 5. Install forever globally via npm: 28 | 29 | npm install -g forever 30 | 31 | Forever is used to restart the service if it crashes. 32 | 33 | 6. Install PhantomJS and CasperJS globally via npm: 34 | 35 | npm install -g phantomjs 36 | npm install -g casperjs 37 | 38 | These packages are used to export Dashboards to PDFs. 39 | 40 | 7. Create the `log/` and `export/` folder and grant permissions 41 | 42 | 8. Start the service via init.d: 43 | 44 | sudo service cyclotron-svc start 45 | 46 | 9. Enable auto-run on system start: 47 | 48 | sudo chkconfig cyclotron-svc on 49 | 50 | These steps may vary for different operating systems. 51 | -------------------------------------------------------------------------------- /cyclotron-svc/config/elasticsearch-events-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "template": "-events-*", 3 | "settings": { 4 | "number_of_shards": 2, 5 | "number_of_replicas": 1 6 | }, 7 | "aliases": { 8 | "-events": {} 9 | }, 10 | "mappings": { 11 | "event": { 12 | "properties": { 13 | "date": { 14 | "type": "date" 15 | }, 16 | "visitId": { 17 | "type": "string", 18 | "index": "not_analyzed" 19 | }, 20 | "uid": { 21 | "type": "string", 22 | "index": "not_analyzed" 23 | }, 24 | "user": { 25 | "properties": { 26 | "_id": { 27 | "type": "string", 28 | "index": "not_analyzed" 29 | }, 30 | "sAMAccountName": { 31 | "type": "string", 32 | "index": "not_analyzed" 33 | }, 34 | "name": { 35 | "type": "string", 36 | "index": "not_analyzed" 37 | } 38 | } 39 | }, 40 | "dashboard": { 41 | "properties": { 42 | "_id": { 43 | "type": "string", 44 | "index": "not_analyzed" 45 | }, 46 | "name": { 47 | "type": "string", 48 | "index": "not_analyzed" 49 | } 50 | } 51 | }, 52 | "eventType": { 53 | "type": "string", 54 | "index": "not_analyzed" 55 | }, 56 | "details": { 57 | "properties": { 58 | "dashboardName": { 59 | "type": "string", 60 | "index": "not_analyzed" 61 | } 62 | } 63 | } 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /cyclotron-svc/examples/example-clock.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataSources": [], 3 | "description": "Example of the Clock widget", 4 | "disableAnalytics": true, 5 | "name": "example-clock", 6 | "pages": [{ 7 | "layout": { 8 | "gridColumns": 2, 9 | "gridRows": 2 10 | }, 11 | "widgets": [{ 12 | "format": "", 13 | "name": "Default", 14 | "timezone": "", 15 | "title": "Clock With Default Timezone", 16 | "widget": "clock" 17 | }, { 18 | "format": "HH:mm:ss", 19 | "layout": {}, 20 | "timezone": "America/Los_Angeles", 21 | "title": "Clock With Timezone America/Los_Angeles", 22 | "widget": "clock" 23 | }, { 24 | "format": "YYYY-MM-DD", 25 | "timezone": "Asia/Kolkata", 26 | "title": "Clock With Timezone Asia/Kolkata", 27 | "widget": "clock" 28 | }] 29 | }], 30 | "parameters": [], 31 | "theme": "dark" 32 | } 33 | -------------------------------------------------------------------------------- /cyclotron-svc/examples/example-iframe.json: -------------------------------------------------------------------------------- 1 | { 2 | "allowFullscreen": false, 3 | "dataSources": [], 4 | "description": "Example of using the iframe widget to display websites.", 5 | "disableAnalytics": true, 6 | "name": "example-iframe", 7 | "pages": [{ 8 | "layout": { 9 | "gridColumns": 2, 10 | "gridRows": 2 11 | }, 12 | "widgets": [{ 13 | "url": "http://www.expedia.com", 14 | "widget": "iframe", 15 | "gridHeight": 1, 16 | "gridWidth": 2 17 | }, { 18 | "url": "http://www.hotels.com", 19 | "widget": "iframe" 20 | }, { 21 | "url": "http://www.trivago.com", 22 | "widget": "iframe" 23 | }] 24 | }], 25 | "parameters": [], 26 | "theme": "lightborderless", 27 | "style": "fullscreen" 28 | } 29 | -------------------------------------------------------------------------------- /cyclotron-svc/examples/example-json-widget.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataSources": [{ 3 | "format": "object", 4 | "name": "mock", 5 | "query": "SOURCE=mock", 6 | "type": "mock" 7 | }, { 8 | "name": "worldpop", 9 | "type": "json", 10 | "url": "http://pastebin.com/raw.php?i=bCYyj12n" 11 | }], 12 | "description": "Examples of using the JSON Widget", 13 | "disableAnalytics": true, 14 | "name": "example-json-widget", 15 | "pages": [{ 16 | "layout": { 17 | "gridColumns": 2, 18 | "gridRows": 2 19 | }, 20 | "name": "JSON Widgets", 21 | "widgets": [{ 22 | "dataSource": "mock", 23 | "title": "Mock Data", 24 | "widget": "json" 25 | }, { 26 | "dataSource": "mock", 27 | "theme": "dark", 28 | "title": "Mock Data (Dark)", 29 | "widget": "json" 30 | }, { 31 | "dataSource": "worldpop", 32 | "title": "World Population", 33 | "widget": "json" 34 | }, { 35 | "dataSource": "worldpop", 36 | "theme": "dark", 37 | "title": "World Population (Dark)", 38 | "widget": "json" 39 | }] 40 | }], 41 | "scripts": [], 42 | "theme": "light" 43 | } -------------------------------------------------------------------------------- /cyclotron-svc/examples/example-qrcode.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataSources": [{ 3 | "name": "datasource_0", 4 | "processor": "p = function() {\n return [{ value: \"Hello World\" }];\n}", 5 | "type": "javascript" 6 | }, { 7 | "name": "datasource_1", 8 | "processor": "p = function() {\n return [{ value: moment().format() }];\n}", 9 | "refresh": 5, 10 | "type": "javascript" 11 | }], 12 | "description": "Examples of using the QRCode widget to create QR Codes.", 13 | "disableAnalytics": true, 14 | "name": "example-qrcode", 15 | "pages": [{ 16 | "frequency": 1, 17 | "layout": { 18 | "gridColumns": 3, 19 | "gridRows": 3 20 | }, 21 | "widgets": [{ 22 | "text": "Hello World", 23 | "title": "Hello World", 24 | "widget": "qrcode" 25 | }, { 26 | "maxSize": 75, 27 | "text": "Hello World", 28 | "title": "Max Size", 29 | "widget": "qrcode" 30 | }, { 31 | "dataSource": "datasource_0", 32 | "maxSize": 150, 33 | "text": "#{value}", 34 | "title": "Data Source", 35 | "widget": "qrcode" 36 | }, { 37 | "dataSource": "datasource_1", 38 | "maxSize": 150, 39 | "text": "#{value}", 40 | "title": "Time", 41 | "widget": "qrcode" 42 | }, { 43 | "title": "Current URL", 44 | "useUrl": true, 45 | "widget": "qrcode" 46 | }, { 47 | "colorDark": "#252", 48 | "text": "Now in Colors", 49 | "title": "Colored", 50 | "widget": "qrcode" 51 | }, { 52 | "colorLight": "#fce", 53 | "text": "Now in Colors", 54 | "title": "Colored 2", 55 | "widget": "qrcode" 56 | }] 57 | }], 58 | "theme": "light" 59 | } 60 | -------------------------------------------------------------------------------- /cyclotron-svc/examples/example-youtube.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataSources": [], 3 | "description": "Examples of the YouTube widget", 4 | "disableAnalytics": true, 5 | "name": "example-youtube", 6 | "pages": [{ 7 | "layout": { 8 | "gridColumns": 1, 9 | "gridRows": 1 10 | }, 11 | "name": "Single Video", 12 | "style": "fullscreen", 13 | "widgets": [{ 14 | "videoId": "MlrzLYqIsE8", 15 | "widget": "youtube" 16 | }] 17 | }, { 18 | "layout": { 19 | "gridColumns": 1, 20 | "gridRows": 2 21 | }, 22 | "name": "Two Videos", 23 | "widgets": [{ 24 | "videoId": "MlrzLYqIsE8", 25 | "widget": "youtube" 26 | }, { 27 | "videoId": "iPWbVDj_mTE", 28 | "widget": "youtube" 29 | }] 30 | }, { 31 | "layout": { 32 | "gridColumns": 2, 33 | "gridRows": 1 34 | }, 35 | "name": "Lists", 36 | "widgets": [{ 37 | "layout": {}, 38 | "title": "Comma-Separated List", 39 | "videoId": "cS-hFKC_RKI,pnN2BNrSrXY,72__Mdioty8", 40 | "widget": "youtube" 41 | }, { 42 | "title": "Playlist", 43 | "videoId": "PLdgCSoJzrmKGadxAc1WHfukyzxFII2_-u", 44 | "widget": "youtube" 45 | }] 46 | }], 47 | "parameters": [] 48 | } 49 | -------------------------------------------------------------------------------- /cyclotron-svc/init.d/cyclotron-svc: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # 3 | # Cyclotron-svc daemon script 4 | # chkconfig: 2345 50 50 5 | # 6 | 7 | . /etc/rc.d/init.d/functions 8 | 9 | SERVICENAME="cyclotron-svc" 10 | USER="cyclotron-svc" 11 | DAEMON="node" 12 | ROOT_DIR="/opt/app/cyclotron-svc" 13 | SERVER="$ROOT_DIR/app.js" 14 | LOG_ROOT="$ROOT_DIR/log" 15 | LOG_FILE="$LOG_ROOT/app.log" 16 | LOCK_ROOT="/var/lock/subsys" 17 | LOCK_FILE="$LOCK_ROOT/$SERVICENAME" 18 | 19 | mkdir -p $LOG_ROOT 20 | mkdir -p $LOCK_ROOT 21 | 22 | function startService { 23 | if [ ! -f "$LOCK_FILE" ] ; then 24 | echo -n $"Starting $SERVICENAME: " 25 | cd $ROOT_DIR 26 | daemon --user="$USER" forever start --workingDir $ROOT_DIR -a -o $LOG_FILE -l $LOG_ROOT/forever.log --minUptime 1000 --spinSleepTime 2000 $SERVER 27 | RETVAL=$? 28 | echo 29 | [ $RETVAL -eq 0 ] && touch $LOCK_FILE 30 | else 31 | echo "$SERVICENAME is already running." 32 | RETVAL=1 33 | fi 34 | } 35 | 36 | function stopService { 37 | echo -n $"Stopping $SERVICENAME: " 38 | cd $ROOT_DIR 39 | daemon --user="$USER" forever stop $SERVER && echo_success || echo_failure 40 | RETVAL=$? 41 | echo 42 | rm -f $LOCK_FILE 43 | } 44 | 45 | function main { 46 | RETVAL=0 47 | case "$1" in 48 | start) 49 | startService 50 | ;; 51 | stop) 52 | stopService 53 | ;; 54 | restart) 55 | stopService && startService 56 | ;; 57 | *) 58 | echo "Usage: $0 {start|stop|restart}" 59 | RETVAL=1 60 | ;; 61 | esac 62 | 63 | exit $RETVAL 64 | } 65 | 66 | main $1 67 | -------------------------------------------------------------------------------- /cyclotron-svc/middleware/cors.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | /* CORS middleware */ 18 | exports.allowCrossDomain = function(req, res, next) { 19 | res.header('Access-Control-Allow-Origin', req.headers.origin || '*'); 20 | res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); 21 | res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); 22 | res.header('Cache-Control', 'no-store'); 23 | res.header('Pragma', 'no-cache'); 24 | res.header('Expires', '0'); 25 | 26 | /* intercept OPTIONS method */ 27 | if ('OPTIONS' == req.method) { 28 | res.status(200); 29 | res.send(); 30 | } 31 | else { 32 | next(); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /cyclotron-svc/middleware/session.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2018 the original author or authors. 3 | * 4 | * Licensed under the MIT License (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 13 | * either express or implied. See the License for the specific 14 | * language governing permissions and limitations under the License. 15 | */ 16 | 17 | /* Session middleware 18 | * 19 | * If `session` is provided in the query string, the session key will be used to 20 | * load a Session object from the database. The Session will be attached to the 21 | * request. 22 | * 23 | * If an invalid session key is provided, error 401 will be returned. 24 | */ 25 | var auth = require('../routes/auth.js'); 26 | 27 | exports.sessionLoader = function(req, res, next) { 28 | /* If ?session= provided, attempt to load it into req.session and req.user */ 29 | if (req.query.session != undefined) { 30 | auth.validateSession(req.query.session) 31 | .then(function (session) { 32 | req.session = session; 33 | req.user = session.user; 34 | next(); 35 | }) 36 | .catch(function () { 37 | res.status(401).send('Authentication failed: session key provided but not valid.'); 38 | }) 39 | } else { 40 | next(); 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /cyclotron-svc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cyclotron-svc", 3 | "description": "Cyclotron: REST API", 4 | "version": "2.0.4", 5 | "author": "Dave Bauman ", 6 | "license": "MIT", 7 | "private": true, 8 | "engines": { 9 | "node": ">= 0.10" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/ExpediaInceCommercePlatform/cyclotron" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/ExpediaInceCommercePlatform/cyclotron/issues" 17 | }, 18 | "scripts": { 19 | "start": "node app.js" 20 | }, 21 | "dependencies": { 22 | "aws4": "^1.8.0", 23 | "bluebird": "2.3.6", 24 | "body-parser": "^1.18.3", 25 | "compression": "^1.7.3", 26 | "elasticsearch": "^11.0.1", 27 | "errorhandler": "^1.5.0", 28 | "express": "^4.16.3", 29 | "highland": "^3.0.0-beta.2", 30 | "ip": "0.3.0", 31 | "json2csv": "^3.6.3", 32 | "json2xls": "^0.1.2", 33 | "jsondiffpatch": "0.1.41", 34 | "ldapjs": "1.0.1", 35 | "lodash": "^4.17.15", 36 | "moment": "^2.22.2", 37 | "mongoose": "~4.5.1", 38 | "morgan": "^1.9.1", 39 | "node-uuid": "~1.4.3", 40 | "passport": "~0.2.2", 41 | "passport-ldapauth": "1.0.0", 42 | "request": "^2.88.0", 43 | "serve-static": "^1.13.2", 44 | "shortid": "2.2.13", 45 | "ssl-root-cas": "^1.2.2", 46 | "swagger-ui-dist": "^3.24.0" 47 | }, 48 | "devDependencies": { 49 | "del": "^3.0.0" 50 | } 51 | } 52 | --------------------------------------------------------------------------------