├── .babelrc ├── .eslintrc ├── .gitignore ├── .meteor ├── .finished-upgraders ├── .gitignore ├── .id ├── packages ├── platforms ├── release └── versions ├── LICENSE ├── README.md ├── build_docker_compose.sh ├── client ├── configs │ ├── context.js │ └── startup.js ├── main.js ├── modules │ ├── accounts │ │ ├── actions │ │ │ ├── accounts.js │ │ │ └── index.js │ │ ├── components │ │ │ ├── creating_user.jsx │ │ │ └── sign_in.jsx │ │ ├── configs │ │ │ └── accounts.js │ │ ├── containers │ │ │ ├── creating_user.js │ │ │ └── sign_in.js │ │ ├── index.js │ │ └── routes.jsx │ ├── admin │ │ ├── actions │ │ │ ├── admin.js │ │ │ ├── databases.js │ │ │ └── index.js │ │ ├── components │ │ │ ├── admin.import.styl │ │ │ ├── databases │ │ │ │ ├── database_form.jsx │ │ │ │ ├── database_item.jsx │ │ │ │ └── databases.jsx │ │ │ ├── dialog_delete.jsx │ │ │ ├── share_charts.jsx │ │ │ ├── share_dashboards.jsx │ │ │ ├── user_item.jsx │ │ │ └── users_list.jsx │ │ ├── containers │ │ │ ├── databases │ │ │ │ ├── database_form.js │ │ │ │ └── databases.js │ │ │ ├── share_charts.js │ │ │ ├── share_dashboards.js │ │ │ └── users_list.js │ │ ├── index.js │ │ └── routes.jsx │ ├── core │ │ ├── actions │ │ │ ├── core.js │ │ │ └── index.js │ │ ├── components │ │ │ ├── context_menu │ │ │ │ ├── color_values.jsx │ │ │ │ ├── context_menu.jsx │ │ │ │ └── format_number.jsx │ │ │ ├── core.import.styl │ │ │ ├── export_to_image │ │ │ │ ├── export_images_menu_item.jsx │ │ │ │ ├── image_renderer.jsx │ │ │ │ └── single_image_renderer.jsx │ │ │ ├── layout.jsx │ │ │ ├── material-ui-container.jsx │ │ │ ├── notifications │ │ │ │ ├── dialog_basic.jsx │ │ │ │ ├── dialog_important.jsx │ │ │ │ ├── dialog_interaction.jsx │ │ │ │ └── snackbar_message.jsx │ │ │ └── partial │ │ │ │ ├── agg_func_icon_menu.jsx │ │ │ │ ├── chart_constructor_block.jsx │ │ │ │ ├── check_role.jsx │ │ │ │ ├── database_drop_down.jsx │ │ │ │ ├── documents_button.jsx │ │ │ │ ├── drop_field.jsx │ │ │ │ ├── emptyLoading.jsx │ │ │ │ ├── generateLinks.js │ │ │ │ ├── helpdesk_button.jsx │ │ │ │ ├── loading.jsx │ │ │ │ ├── navigation.jsx │ │ │ │ └── sidebar.jsx │ │ ├── containers │ │ │ ├── check_role.js │ │ │ ├── context_menu │ │ │ │ ├── color_values.js │ │ │ │ └── format_number.js │ │ │ ├── database_drop_down.js │ │ │ ├── drop_field.js │ │ │ ├── export_to_image │ │ │ │ └── image_renderer.js │ │ │ ├── navigation.js │ │ │ ├── notifications │ │ │ │ ├── dialog_important.js │ │ │ │ ├── dialog_interaction.js │ │ │ │ └── snackbar_message.js │ │ │ └── sidebar.js │ │ └── index.js │ ├── home │ │ ├── actions │ │ │ ├── dashboard.js │ │ │ └── index.js │ │ ├── components │ │ │ ├── charts │ │ │ │ ├── handle_dashboards.jsx │ │ │ │ ├── handle_users.jsx │ │ │ │ ├── item.jsx │ │ │ │ └── list.jsx │ │ │ ├── dashboards │ │ │ │ ├── chart_footer.jsx │ │ │ │ ├── chart_header.jsx │ │ │ │ ├── dashboard.jsx │ │ │ │ ├── data_visualisation.jsx │ │ │ │ ├── handle_charts.jsx │ │ │ │ ├── item.jsx │ │ │ │ ├── list.jsx │ │ │ │ ├── presentation_mode │ │ │ │ │ ├── chart_viewer.jsx │ │ │ │ │ └── nav_button.jsx │ │ │ │ └── simple_table.jsx │ │ │ ├── handle_users │ │ │ │ ├── handle_users_menu_item.jsx │ │ │ │ └── user_menu_item.jsx │ │ │ ├── home.import.styl │ │ │ └── home.jsx │ │ ├── containers │ │ │ ├── charts │ │ │ │ ├── handle_dashboards.js │ │ │ │ ├── handle_users.js │ │ │ │ ├── handle_users_menu_item.js │ │ │ │ └── list.js │ │ │ ├── dashboards │ │ │ │ ├── chart_viewer.js │ │ │ │ ├── current_dashboard.js │ │ │ │ ├── dashboard.js │ │ │ │ ├── data_visualisation.js │ │ │ │ ├── handle_charts.js │ │ │ │ ├── handle_users_menu_item.js │ │ │ │ └── list.js │ │ │ └── home.js │ │ ├── index.js │ │ └── routes.jsx │ ├── publishing │ │ ├── components │ │ │ ├── chart.jsx │ │ │ ├── handle_publications_button.jsx │ │ │ ├── iframe_dialog.jsx │ │ │ ├── iframe_generator.jsx │ │ │ ├── publishing.import.styl │ │ │ └── share_layout.jsx │ │ ├── containers │ │ │ ├── chart.js │ │ │ └── iframe_dialog.js │ │ ├── index.js │ │ └── routes.jsx │ └── workplace │ │ ├── actions │ │ ├── charts.js │ │ ├── collection_fields.js │ │ ├── console.js │ │ ├── index.js │ │ ├── pivot.js │ │ ├── preview.js │ │ ├── tests │ │ │ └── collection_fields.js │ │ ├── workplace.js │ │ └── workplace_state.js │ │ ├── components │ │ ├── collection_fields │ │ │ ├── add_object_item.jsx │ │ │ ├── collection_fields.jsx │ │ │ ├── joining_collections.jsx │ │ │ ├── object_item.jsx │ │ │ └── object_tree.jsx │ │ ├── collection_list │ │ │ ├── collection_list.jsx │ │ │ └── collections.jsx │ │ ├── constructors │ │ │ ├── chart-constructor.jsx │ │ │ ├── constructor.jsx │ │ │ ├── constructor_block.jsx │ │ │ ├── constructor_block_field_item.jsx │ │ │ └── start_constructor.jsx │ │ ├── filters │ │ │ ├── boolean_filter.jsx │ │ │ ├── date_filter.jsx │ │ │ ├── filter.jsx │ │ │ └── filter_button.jsx │ │ ├── pivotview │ │ │ ├── pivot_table.jsx │ │ │ └── pivot_table_header.jsx │ │ ├── preview │ │ │ ├── chart_canvas.jsx │ │ │ ├── chart_sidebar.jsx │ │ │ ├── chart_type_button.jsx │ │ │ ├── data_type_menu.jsx │ │ │ ├── data_visualisation.jsx │ │ │ ├── expression_field.jsx │ │ │ ├── grouping_button.jsx │ │ │ ├── preview.jsx │ │ │ ├── preview_header.jsx │ │ │ ├── preview_header_col.jsx │ │ │ ├── preview_pagination.jsx │ │ │ ├── preview_toolbar.jsx │ │ │ ├── save_chart_form.jsx │ │ │ └── simple_table.jsx │ │ ├── sidebar │ │ │ ├── toggle_sidebar_state_tab.jsx │ │ │ └── workplace_sidebar.jsx │ │ ├── sql_editor │ │ │ ├── sql_button.jsx │ │ │ └── sql_editor.jsx │ │ ├── workplace.import.styl │ │ └── workplace.jsx │ │ ├── containers │ │ ├── collection_fields.js │ │ ├── collections_list │ │ │ ├── collections.js │ │ │ └── collections_list.js │ │ ├── constructors │ │ │ ├── chart-constructor.js │ │ │ └── constructor.js │ │ ├── joining_collections.js │ │ ├── object_tree.js │ │ ├── preview │ │ │ ├── chart_sidebar.js │ │ │ ├── data_visualisation.js │ │ │ ├── pivot_table.js │ │ │ ├── preview.js │ │ │ ├── preview_header.js │ │ │ ├── preview_toolbar.js │ │ │ └── save_chart_form.js │ │ └── workplace.js │ │ ├── index.js │ │ └── routes.jsx ├── single_components │ ├── chart_icons │ │ ├── BarIcon.jsx │ │ ├── BooleanTypeIcon.jsx │ │ ├── DoughnutIcon.jsx │ │ ├── IconWrapper.jsx │ │ ├── LineIcon.jsx │ │ ├── NumberTypeIcon.jsx │ │ ├── PieIcon.jsx │ │ ├── PolarAreaIcon.jsx │ │ ├── RadarIcon.jsx │ │ ├── SaveAsIcon.jsx │ │ ├── SaveIcon.jsx │ │ └── ScatterIcon.jsx │ ├── form_fields │ │ ├── drop_down.jsx │ │ ├── filter_field.jsx │ │ ├── formsy_multi_select.jsx │ │ ├── formsy_text_input.jsx │ │ ├── like_filter_info_btn.jsx │ │ └── text_input.jsx │ ├── get_chart.js │ └── notificator.js └── stylesheets │ ├── grid.css │ ├── main.styl │ ├── react-treeview.css │ └── stylus │ ├── general.import.styl │ ├── mixins.import.styl │ └── variables.import.styl ├── config ├── docker │ ├── README.txt │ ├── databazel │ │ └── Dockerfile │ ├── docker-compose.yml │ └── quasar │ │ └── Dockerfile ├── etc_nginx_sites-enabled_your_domain.conf ├── mup.json ├── quasar.json └── settings.json ├── databazel.sh ├── deploy-quasar.sh ├── deploy.sh ├── docs ├── OVERVIEW.md └── PRODUCTION-DEPLOYMENT.md ├── lib ├── chart_constructor.js ├── collectionHelpers │ ├── charts.js │ ├── dashboards.js │ └── users.js ├── collections.js ├── colors.js ├── common_functions.js ├── constants.js ├── data_processing.js ├── downloads.js ├── echarts_themes │ └── macarons.js ├── i18n │ ├── en.i18n.json │ └── index.js ├── schemas │ ├── charts.js │ ├── chartsLocations.js │ ├── dashboards.js │ └── index.js └── sql_parser.js ├── package.json ├── public ├── favicons │ ├── android-chrome-144x144.png │ ├── android-chrome-192x192.png │ ├── android-chrome-36x36.png │ ├── android-chrome-48x48.png │ ├── android-chrome-72x72.png │ ├── android-chrome-96x96.png │ ├── apple-touch-icon-114x114.png │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-144x144.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-57x57.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-72x72.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon-precomposed.png │ ├── apple-touch-icon.png │ ├── browserconfig.xml │ ├── favicon-16x16.png │ ├── favicon-194x194.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ ├── favicon.ico │ ├── manifest.json │ ├── mstile-144x144.png │ ├── mstile-150x150.png │ ├── mstile-310x150.png │ ├── mstile-310x310.png │ ├── mstile-70x70.png │ └── safari-pinned-tab.svg └── images │ ├── background-min.jpg │ ├── background.jpg │ ├── backgroundNew.jpg │ └── backgroundNew.svg └── server ├── configs ├── accounts.js ├── index.js └── startup.js ├── hooks ├── charts.js ├── dashboards.js └── index.js ├── lib ├── email │ ├── email_templates │ │ ├── enrolmentLetter.jsx │ │ ├── itemShareLetter.jsx │ │ └── parts │ │ │ ├── charts.jsx │ │ │ └── mainLayout.jsx │ ├── getItemShareLetterOptions.js │ └── stylesheets │ │ ├── charts.js │ │ └── mainLayout.js └── quasar.js ├── main.js ├── methods ├── accounts.js ├── charts.js ├── chartsLocations.js ├── dashboard.js ├── exportCsv.js ├── index.js ├── quasar.js └── users.js └── publications ├── charts.js ├── chartsLocations.js ├── dashboards.js ├── index.js └── users.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2", "react"], 3 | "plugins": ["react-require", "babel-root-slash-import"] 4 | } 5 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "meteor", 4 | "react", 5 | "jsx-a11y" 6 | ], 7 | "extends": [ 8 | "airbnb", 9 | "plugin:meteor/recommended", 10 | "plugin:react/recommended" 11 | ], 12 | "rules": { 13 | "import/no-unresolved": 0, 14 | "meteor/eventmap-params": [ 15 | 2, { "templateInstanceParamName": "instance" } 16 | ], 17 | "no-param-reassign": [ 18 | "error", { "props": false } 19 | ], 20 | "no-underscore-dangle": [ 21 | "error", { "allow": ["__", "_id"] } 22 | ], 23 | "no-use-before-define": [ 24 | "error", { "functions": false, "classes": true } 25 | ], 26 | "react/display-name": 0, 27 | "new-cap": [ 28 | "error", { "capIsNewExceptions": ["OneOf", "Maybe"] } 29 | ] 30 | } 31 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /node_modules 3 | .idea/ -------------------------------------------------------------------------------- /.meteor/.finished-upgraders: -------------------------------------------------------------------------------- 1 | # This file contains information which helps Meteor properly upgrade your 2 | # app when you run 'meteor update'. You should check it into version control 3 | # with your project. 4 | 5 | notices-for-0.9.0 6 | notices-for-0.9.1 7 | 0.9.4-platform-file 8 | notices-for-facebook-graph-api-2 9 | 1.2.0-standard-minifiers-package 10 | 1.2.0-meteor-platform-split 11 | 1.2.0-cordova-changes 12 | 1.2.0-breaking-changes 13 | 1.3.0-split-minifiers-package 14 | -------------------------------------------------------------------------------- /.meteor/.gitignore: -------------------------------------------------------------------------------- 1 | local 2 | dev_bundle 3 | -------------------------------------------------------------------------------- /.meteor/.id: -------------------------------------------------------------------------------- 1 | # This file contains a token that is unique to your project. 2 | # Check it into your repository along with the rest of this directory. 3 | # It can be used for purposes such as: 4 | # - ensuring you don't accidentally deploy one app on top of another 5 | # - providing package authors with aggregated statistics 6 | 7 | xv3qcrsrs757nkku4n 8 | -------------------------------------------------------------------------------- /.meteor/packages: -------------------------------------------------------------------------------- 1 | # Meteor packages used by this project, one per line. 2 | # Check this file (and the other files in this directory) into your repository. 3 | # 4 | # 'meteor add' and 'meteor remove' will edit this file for you, 5 | # but you can also edit it by hand. 6 | 7 | meteor-base # Packages every Meteor app needs to have 8 | mobile-experience # Packages for a great mobile UX 9 | mongo # The database Meteor supports right now 10 | reactive-var # Reactive variable for tracker 11 | jquery # Helpful client-side library 12 | tracker # Meteor's client-side reactive programming library 13 | 14 | standard-minifier-css # CSS minifier run for production mode 15 | standard-minifier-js # JS minifier run for production mode 16 | es5-shim # ECMAScript 5 compatibility for older browsers. 17 | ecmascript # Enable ECMAScript2015+ syntax in app code 18 | 19 | kadira:flow-router 20 | reactive-dict 21 | stylus 22 | universe:i18n 23 | http 24 | meteorhacks:async 25 | check 26 | aldeed:simple-schema 27 | aldeed:collection2 28 | accounts-password 29 | dburles:collection-helpers 30 | matb33:collection-hooks 31 | email 32 | meteorhacks:kadira 33 | -------------------------------------------------------------------------------- /.meteor/platforms: -------------------------------------------------------------------------------- 1 | server 2 | browser 3 | -------------------------------------------------------------------------------- /.meteor/release: -------------------------------------------------------------------------------- 1 | METEOR@1.3.2.4 2 | -------------------------------------------------------------------------------- /.meteor/versions: -------------------------------------------------------------------------------- 1 | accounts-base@1.2.7 2 | accounts-password@1.1.8 3 | aldeed:collection2@2.9.1 4 | aldeed:collection2-core@1.1.1 5 | aldeed:schema-deny@1.0.1 6 | aldeed:schema-index@1.0.1 7 | aldeed:simple-schema@1.5.3 8 | allow-deny@1.0.4 9 | autoupdate@1.2.9 10 | babel-compiler@6.6.4 11 | babel-runtime@0.1.8 12 | base64@1.0.8 13 | binary-heap@1.0.8 14 | blaze@2.1.7 15 | blaze-tools@1.0.8 16 | boilerplate-generator@1.0.8 17 | caching-compiler@1.0.4 18 | callback-hook@1.0.8 19 | check@1.2.1 20 | dburles:collection-helpers@1.0.4 21 | ddp@1.2.5 22 | ddp-client@1.2.7 23 | ddp-common@1.2.5 24 | ddp-rate-limiter@1.0.4 25 | ddp-server@1.2.6 26 | deps@1.0.12 27 | diff-sequence@1.0.5 28 | ecmascript@0.4.3 29 | ecmascript-runtime@0.2.10 30 | ejson@1.0.11 31 | email@1.0.12 32 | es5-shim@4.5.10 33 | fastclick@1.0.11 34 | geojson-utils@1.0.8 35 | hot-code-push@1.0.4 36 | html-tools@1.0.9 37 | htmljs@1.0.9 38 | http@1.1.5 39 | id-map@1.0.7 40 | jquery@1.11.8 41 | kadira:flow-router@2.12.1 42 | launch-screen@1.0.11 43 | livedata@1.0.18 44 | localstorage@1.0.9 45 | logging@1.0.12 46 | matb33:collection-hooks@0.8.1 47 | mdg:validation-error@0.2.0 48 | meteor@1.1.14 49 | meteor-base@1.0.4 50 | meteorhacks:async@1.0.0 51 | meteorhacks:kadira@2.30.0 52 | meteorhacks:meteorx@1.4.1 53 | minifier-css@1.1.11 54 | minifier-js@1.1.11 55 | minimongo@1.0.16 56 | mobile-experience@1.0.4 57 | mobile-status-bar@1.0.12 58 | modules@0.6.1 59 | modules-runtime@0.6.3 60 | mongo@1.1.7 61 | mongo-id@1.0.4 62 | mongo-livedata@1.0.12 63 | npm-bcrypt@0.8.7 64 | npm-mongo@1.4.43 65 | observe-sequence@1.0.11 66 | ordered-dict@1.0.7 67 | promise@0.6.7 68 | raix:eventemitter@0.1.3 69 | random@1.0.9 70 | rate-limit@1.0.4 71 | reactive-dict@1.1.7 72 | reactive-var@1.0.9 73 | reload@1.1.8 74 | retry@1.0.7 75 | routepolicy@1.0.10 76 | service-configuration@1.0.9 77 | sha@1.0.7 78 | spacebars@1.0.11 79 | spacebars-compiler@1.0.11 80 | srp@1.0.8 81 | standard-minifier-css@1.0.6 82 | standard-minifier-js@1.0.6 83 | stylus@2.511.5 84 | tracker@1.0.13 85 | ui@1.0.11 86 | underscore@1.0.8 87 | universe:i18n@1.6.0 88 | universe:utilities@2.3.2 89 | url@1.0.9 90 | webapp@1.2.8 91 | webapp-hashing@1.0.9 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://s3-eu-west-1.amazonaws.com/jssolutions/databazel/imgs/databazel_logo_big.jpg) 2 | 3 | ![](https://s3-eu-west-1.amazonaws.com/jssolutions/databazel/imgs/bg_databazel.png) 4 | 5 | # THE KEY FEATURES 6 | 7 | Databazel natively connects to MongoDB and present the results in a visual dashboard reporting interface, without requiring any additional development on your end. 8 | 9 | No ETL. We believe you should keep data where it is and use tools that are smart enough to visualize data directly from MongoDB without building ETL. 10 | 11 | Our solution is completely web-based so all you need to get started is a web browser! 12 | 13 | Real-time analytics for your database. 14 | 15 | You can share the created charts with your teammates. 16 | 17 | [Overview](https://github.com/JSSolutions/Databazel/blob/master/docs/OVERVIEW.md) 18 | 19 | # Start application 20 | 21 | ## Config settings.json 22 | 23 | ``` 24 | 25 | "gMail": { 26 | "_comment": "Enter login, password, host and port - was used https://www.mailgun.com/", 27 | "login": "login", 28 | "password": "password", 29 | "host": "host", 30 | "port": "port" 31 | } 32 | 33 | ``` 34 | 35 | Run 36 | 37 | `sh databazel.sh` 38 | 39 | ## Default user 40 | 41 | Email: `admin@admin.com` 42 | Password: `admin` 43 | 44 | # License 45 | 46 | The source code for Databazel is made available under the [AGPL v3.0](http://www.gnu.org/licenses/agpl-3.0.html) General Public License (a commercial license is also available from [Apiko Software OU](https://jssolutionsdev.com/) ). 47 | 48 | ------------- 49 | 50 | Made by [![Custom Software Development Company](https://s3-eu-west-1.amazonaws.com/jssolutions/github/jss_xs.png)](http://jssolutionsdev.com/?github=Databazel) - [Custom Software Development Company](http://jssolutionsdev.com/?github=Databazel) 51 | -------------------------------------------------------------------------------- /build_docker_compose.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | . ~/.nvm/nvm.sh && echo "nvm installed" || curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.0/install.sh | bash 4 | 5 | nvm install 0.10.46 6 | npm install npm -g 7 | cd ./node_modules && npm remove * && cd ../ || echo 'node_modules are not installed' 8 | 9 | npm cache clear 10 | npm install --production 11 | 12 | meteor build ../build --architecture os.linux.x86_64 13 | 14 | cd ../ 15 | 16 | mkdir composed_app && cd composed_app || echo 'composed_app folder exists' && cd composed_app 17 | mkdir databazel_app || echo 'databazel_app folder exists' 18 | 19 | cp -af ../databazel/config/docker/* ./databazel_app 20 | 21 | cp -f ../build/databazel.tar.gz ./databazel_app/databazel 22 | 23 | tar --exclude='databazel_app/mongo_data' -cvzf databazel_app.tar.gz databazel_app 24 | -------------------------------------------------------------------------------- /client/configs/context.js: -------------------------------------------------------------------------------- 1 | import * as Collections from '/lib/collections'; 2 | import { Meteor } from 'meteor/meteor'; 3 | import { FlowRouter } from 'meteor/kadira:flow-router'; 4 | import { ReactiveDict } from 'meteor/reactive-dict'; 5 | import { Tracker } from 'meteor/tracker'; 6 | import Notificator from '../single_components/notificator'; 7 | import MainLayout from '../modules/core/components/material-ui-container.jsx'; 8 | 9 | FlowRouter.notFound = { 10 | action() { 11 | FlowRouter.go('home'); 12 | }, 13 | }; 14 | const LocalState = new ReactiveDict(); 15 | 16 | export default function () { 17 | return { 18 | Meteor, 19 | FlowRouter, 20 | Collections, 21 | LocalState, 22 | Tracker, 23 | MainLayout, 24 | Notificator: new Notificator(LocalState), 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /client/configs/startup.js: -------------------------------------------------------------------------------- 1 | import { Meteor } from 'meteor/meteor'; 2 | import injectTapEventPlugin from 'react-tap-event-plugin'; 3 | 4 | Meteor.startup(() => { 5 | injectTapEventPlugin(); 6 | }); 7 | -------------------------------------------------------------------------------- /client/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'mantra-core'; 2 | import initContext from './configs/context'; 3 | import workplace from './modules/workplace'; 4 | import accounts from './modules/accounts'; 5 | import home from './modules/home'; 6 | import core from './modules/core'; 7 | import admin from './modules/admin'; 8 | import publishing from './modules/publishing'; 9 | 10 | const context = initContext(); 11 | const app = createApp(context); 12 | 13 | app.loadModule(workplace); 14 | app.loadModule(home); 15 | app.loadModule(accounts); 16 | app.loadModule(admin); 17 | app.loadModule(core); 18 | app.loadModule(publishing); 19 | app.init(); 20 | -------------------------------------------------------------------------------- /client/modules/accounts/actions/accounts.js: -------------------------------------------------------------------------------- 1 | import { Accounts } from 'meteor/accounts-base'; 2 | 3 | export default { 4 | signIn({ Meteor, LocalState, FlowRouter }, email, password) { 5 | Meteor.loginWithPassword(email, password, (err) => { 6 | if (err && err.reason) { 7 | LocalState.set('LOGIN_ERROR', err.reason); 8 | } else { 9 | FlowRouter.go('home'); 10 | } 11 | }); 12 | }, 13 | inviteUser({ Meteor, LocalState, FlowRouter }, email) { 14 | Meteor.call('accounts.inviteUser', email, (err) => { 15 | if (err && err.reason) { 16 | LocalState.set('CREATING_USER_ERROR', err.reason); 17 | } else { 18 | FlowRouter.go('home'); 19 | } 20 | }); 21 | }, 22 | resetPassword({ FlowRouter, LocalState }, newPassword, token) { 23 | Accounts.resetPassword(token, newPassword, (err) => { 24 | if (err && err.reason) { 25 | LocalState.set('CREATING_USER_ERROR', err.reason); 26 | } else { 27 | FlowRouter.go('home'); 28 | } 29 | }); 30 | }, 31 | }; 32 | -------------------------------------------------------------------------------- /client/modules/accounts/actions/index.js: -------------------------------------------------------------------------------- 1 | import accounts from './accounts'; 2 | 3 | export default { 4 | accounts, 5 | }; 6 | -------------------------------------------------------------------------------- /client/modules/accounts/configs/accounts.js: -------------------------------------------------------------------------------- 1 | import { Accounts } from 'meteor/accounts-base'; 2 | import { FlowRouter } from 'meteor/kadira:flow-router'; 3 | 4 | Accounts.onEnrollmentLink((token) => { 5 | FlowRouter.go('accounts.resetPassword', { token }); 6 | }); 7 | -------------------------------------------------------------------------------- /client/modules/accounts/containers/creating_user.js: -------------------------------------------------------------------------------- 1 | import { useDeps, composeWithTracker, composeAll } from 'mantra-core'; 2 | import CreatingUser from '../components/creating_user.jsx'; 3 | 4 | export const composer = ({ context }, onData) => { 5 | const { LocalState, FlowRouter } = context(); 6 | const creatingUserError = LocalState.get('CREATING_USER_ERROR'); 7 | const token = FlowRouter.getParam('token'); 8 | onData(null, { creatingUserError, token }); 9 | }; 10 | 11 | export const depsMapper = (context, actions) => ({ 12 | inviteUser: actions.accounts.inviteUser, 13 | resetPassword: actions.accounts.resetPassword, 14 | context: () => context, 15 | }); 16 | 17 | export default composeAll( 18 | composeWithTracker(composer), 19 | useDeps(depsMapper) 20 | )(CreatingUser); 21 | -------------------------------------------------------------------------------- /client/modules/accounts/containers/sign_in.js: -------------------------------------------------------------------------------- 1 | import { useDeps, composeWithTracker, composeAll } from 'mantra-core'; 2 | import SignIn from '../components/sign_in.jsx'; 3 | 4 | export const composer = ({ context }, onData) => { 5 | const { LocalState } = context(); 6 | const loginError = LocalState.get('LOGIN_ERROR'); 7 | onData(null, { loginError }); 8 | }; 9 | 10 | export const depsMapper = (context, actions) => ({ 11 | signIn: actions.accounts.signIn, 12 | context: () => context, 13 | }); 14 | 15 | export default composeAll( 16 | composeWithTracker(composer), 17 | useDeps(depsMapper) 18 | )(SignIn); 19 | -------------------------------------------------------------------------------- /client/modules/accounts/index.js: -------------------------------------------------------------------------------- 1 | import routes from './routes.jsx'; 2 | import actions from './actions'; 3 | 4 | export default { 5 | routes, 6 | actions, 7 | }; 8 | -------------------------------------------------------------------------------- /client/modules/accounts/routes.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { mount } from 'react-mounter'; 3 | import SignIn from './containers/sign_in'; 4 | import CreatingUser from './containers/creating_user'; 5 | 6 | export default function (injectDeps, { FlowRouter, MainLayout }) { 7 | const MainLayoutCtx = injectDeps(MainLayout); 8 | const accountRoutes = FlowRouter.group({ 9 | prefix: '/accounts', 10 | name: 'accounts', 11 | }); 12 | 13 | accountRoutes.route('/sign-in', { 14 | name: 'accounts.signIn', 15 | action() { 16 | mount(MainLayoutCtx, { 17 | content: () => , 18 | }); 19 | }, 20 | }); 21 | 22 | accountRoutes.route('/reset-password/:token', { 23 | name: 'accounts.resetPassword', 24 | action() { 25 | mount(MainLayoutCtx, { 26 | content: () => , 27 | }); 28 | }, 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /client/modules/admin/actions/admin.js: -------------------------------------------------------------------------------- 1 | import { _ } from 'meteor/underscore'; 2 | 3 | export default { 4 | deleteUser({ Meteor, LocalState }, userId) { 5 | Meteor.call('users.deleteUser', userId, (err) => { 6 | if (err && err.reason) LocalState.set('DELETING_USER_ERROR', err.reason); 7 | }); 8 | }, 9 | shareDashboards({ Meteor }, { userId, selectedDashboards, currentDashboards }) { 10 | const removedFrom = _.difference(selectedDashboards, currentDashboards)[0]; 11 | const addedTo = _.difference(currentDashboards, selectedDashboards)[0]; 12 | Meteor.call('dashboard.handleSharingToUser', 13 | { entityId: addedTo || removedFrom, userId, isSharing: !!addedTo }); 14 | }, 15 | shareCharts({ Meteor }, { userId, selectedCharts, currentCharts }) { 16 | const removedFrom = _.difference(selectedCharts, currentCharts)[0]; 17 | const addedTo = _.difference(currentCharts, selectedCharts)[0]; 18 | Meteor.call('chart.handleSharingToUser', 19 | { entityId: addedTo || removedFrom, userId, isSharing: !!addedTo, fromDashboard: false }); 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /client/modules/admin/actions/databases.js: -------------------------------------------------------------------------------- 1 | import i18n from 'meteor/universe:i18n'; 2 | 3 | export default { 4 | createDatabase({ Meteor, Notificator }, mountName, uri, cb) { 5 | Meteor.call('quasar.createMount', mountName, uri, (err) => { 6 | if (err) Notificator.important(err.reason || 'Quasar error'); 7 | cb(err); 8 | }); 9 | }, 10 | deleteDatabase({ Notificator, Meteor }, mountName, cb) { 11 | Notificator.interaction(`${i18n.__('confirm_delete_database')}`, { 12 | confirmLabel: i18n.__('delete'), 13 | confirmFunction() { 14 | Meteor.call('quasar.deleteMount', mountName, (err) => { 15 | if (err) Notificator.important(err.reason || 'Quasar error'); 16 | else cb(); 17 | }); 18 | }, 19 | title: i18n.__('delete'), 20 | }); 21 | }, 22 | updateDatabase({ Notificator, Meteor }, database, newDatabase, cb) { 23 | const confirmFunction = () => { 24 | Meteor.call('quasar.updateMount', database, newDatabase, (err) => { 25 | if (err) { 26 | Notificator.important(err.reason || 'Quasar error'); 27 | Meteor.call('quasar.createMount', database.mountName, database.mongoUrl, () => cb(err)); 28 | } else { 29 | Meteor.call('charts.updateChartMount', database, newDatabase, () => cb(err)); 30 | } 31 | }); 32 | }; 33 | 34 | Notificator.interaction(`${i18n.__('confirm_update_database')}`, { 35 | confirmFunction, 36 | cancelFunction: () => cb(true), 37 | confirmLabel: i18n.__('update'), 38 | title: i18n.__('warning'), 39 | }); 40 | }, 41 | }; 42 | -------------------------------------------------------------------------------- /client/modules/admin/actions/index.js: -------------------------------------------------------------------------------- 1 | import admin from './admin'; 2 | import databases from './databases'; 3 | 4 | export default { 5 | admin, 6 | databases, 7 | }; 8 | -------------------------------------------------------------------------------- /client/modules/admin/components/admin.import.styl: -------------------------------------------------------------------------------- 1 | .databases-list 2 | max-width 600px 3 | margin auto 4 | position relative 5 | 6 | .database-form 7 | padding 0 18px 25px 18px 8 | 9 | .edit-database-form 10 | padding 0 18px 11 | position relative 12 | .form 13 | width calc(100% - 38px) 14 | 15 | .database-loading 16 | width 100% 17 | height 100% 18 | position absolute 19 | top 0 20 | background-color rgba(255, 255, 255, .6) 21 | -------------------------------------------------------------------------------- /client/modules/admin/components/databases/database_form.jsx: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | import Formsy from 'formsy-react'; 3 | import FormsyText from 'formsy-material-ui/lib/FormsyText'; 4 | import i18n from 'meteor/universe:i18n'; 5 | 6 | const styles = { 7 | mountName: { 8 | width: '120px', 9 | marginRight: '18px', 10 | }, 11 | mongoUrl: { 12 | width: 'calc(100% - 138px)', 13 | }, 14 | error: { 15 | position: 'absolute', 16 | top: '70px', 17 | }, 18 | }; 19 | 20 | class AddDatabaseForm extends React.Component { 21 | componentDidMount() { 22 | this.refs.mountName.focus(); 23 | } 24 | render() { 25 | const { database } = this.props; 26 | return ( 27 | this.props.submit(model)} 30 | noValidate 31 | > 32 | 41 | 55 |